ruby-changes:68588
From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:09:58 +0900 (JST)
Subject: [ruby-changes:68588] e3cd43e2bc (master): Implemented opt_minus in MicroJIT
https://git.ruby-lang.org/ruby.git/commit/?id=e3cd43e2bc From e3cd43e2bc44fdd358f8ea1c373125ce4320f972 Mon Sep 17 00:00:00 2001 From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...> Date: Fri, 2 Oct 2020 12:12:28 -0400 Subject: Implemented opt_minus in MicroJIT --- ujit_asm.h | 8 ++++++++ ujit_asm_tests.c | 3 +++ ujit_compile.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/ujit_asm.h b/ujit_asm.h index baeadc75b0..a52a9691df 100644 --- a/ujit_asm.h +++ b/ujit_asm.h @@ -225,6 +225,14 @@ x86opnd_t const_ptr_opnd(void* ptr); https://github.com/ruby/ruby/blob/trunk/ujit_asm.h#L225 offsetof(struct_type, member_name) \ ) +// Struct member operand with an array index +#define member_opnd_idx(base_reg, struct_type, member_name, idx) mem_opnd( \ + 8 * sizeof(((struct_type*)0)->member_name), \ + base_reg, \ + (offsetof(struct_type, member_name) + \ + sizeof(((struct_type*)0)->member_name) * idx) \ +) + // Code block methods uint8_t* alloc_exec_mem(size_t mem_size); void cb_init(codeblock_t* cb, uint8_t* mem_block, size_t mem_size); diff --git a/ujit_asm_tests.c b/ujit_asm_tests.c index afc724f634..0c3417880b 100644 --- a/ujit_asm_tests.c +++ b/ujit_asm_tests.c @@ -321,6 +321,9 @@ void run_tests() https://github.com/ruby/ruby/blob/trunk/ujit_asm_tests.c#L321 cb_set_pos(cb, 0); test(cb, mem_opnd(8, RDX, 8), imm_opnd(255)); check_bytes(cb, "F64208FF"); cb_set_pos(cb, 0); test(cb, DX, imm_opnd(0xFFFF)); check_bytes(cb, "66F7C2FFFF"); cb_set_pos(cb, 0); test(cb, mem_opnd(16, RDX, 8), imm_opnd(0xFFFF)); check_bytes(cb, "66F74208FFFF"); + cb_set_pos(cb, 0); test(cb, mem_opnd(8, RSI, 0), imm_opnd(1)); check_bytes(cb, "F60601"); + cb_set_pos(cb, 0); test(cb, mem_opnd(8, RSI, 16), imm_opnd(1)); check_bytes(cb, "F6461001"); + cb_set_pos(cb, 0); test(cb, mem_opnd(8, RSI, -16), imm_opnd(1)); check_bytes(cb, "F646F001"); // xor cb_set_pos(cb, 0); xor(cb, EAX, EAX); check_bytes(cb, "31C0"); diff --git a/ujit_compile.c b/ujit_compile.c index 9ed6624efc..98bc545b82 100644 --- a/ujit_compile.c +++ b/ujit_compile.c @@ -387,11 +387,58 @@ void gen_setlocal_wc0(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L387 mov(cb, mem_opnd(64, RDX, offs), RCX); } +void gen_opt_minus(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) +{ + // Create a size-exit to fall back to the interpreter + // Note: we generate the side-exit before popping operands from the stack + uint8_t* side_exit = ujit_side_exit(ocb, ctx, ctx->pc); + + // TODO: make a helper function for this + // Make sure that minus isn't redefined for integers + mov(cb, RAX, const_ptr_opnd(ruby_current_vm_ptr)); + test( + cb, + member_opnd_idx(RAX, rb_vm_t, redefined_flag, BOP_MINUS), + imm_opnd(INTEGER_REDEFINED_OP_FLAG) + ); + jnz_ptr(cb, side_exit); + + // Get the operands and destination from the stack + x86opnd_t arg1 = ctx_stack_pop(ctx, 1); + x86opnd_t arg0 = ctx_stack_pop(ctx, 1); + + // If not fixnums, fall back + test(cb, arg0, imm_opnd(RUBY_FIXNUM_FLAG)); + jz_ptr(cb, side_exit); + test(cb, arg1, imm_opnd(RUBY_FIXNUM_FLAG)); + jz_ptr(cb, side_exit); + + // Subtract arg0 - arg1 and test for overflow + mov(cb, RAX, arg0); + sub(cb, RAX, arg1); + jo_ptr(cb, side_exit); + add(cb, RAX, imm_opnd(1)); + + /* + print_int(cb, arg0); + print_int(cb, arg1); + print_int(cb, RAX); + print_str(cb, ""); + */ + + // Push the output on the stack + x86opnd_t dst = ctx_stack_push(ctx, 1); + mov(cb, dst, RAX); +} + void gen_opt_send_without_block(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) { // Create a size-exit to fall back to the interpreter uint8_t* side_exit = ujit_side_exit(ocb, ctx, ctx->pc); + + + /* struct rb_call_data * cd = (struct rb_call_data *)ctx_get_arg(ctx, 0); int32_t argc = (int32_t)vm_ci_argc(cd->ci); const struct rb_callcache *cc = cd->cc; @@ -406,12 +453,14 @@ void gen_opt_send_without_block(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L453 //fprintf(stderr, "simple call\n"); } - - - mov(cb, RAX, const_ptr_opnd(cd)); x86opnd_t ptr_to_cc = member_opnd(RAX, struct rb_call_data, cc); mov(cb, RAX, ptr_to_cc); + */ + + + + /* x86opnd_t ptr_to_klass = mem_opnd(64, RAX, offsetof(struct rb_callcache, klass)); @@ -478,5 +527,6 @@ rb_ujit_init(void) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L527 st_insert(gen_fns, (st_data_t)BIN(putself), (st_data_t)&gen_putself); st_insert(gen_fns, (st_data_t)BIN(getlocal_WC_0), (st_data_t)&gen_getlocal_wc0); st_insert(gen_fns, (st_data_t)BIN(setlocal_WC_0), (st_data_t)&gen_setlocal_wc0); + st_insert(gen_fns, (st_data_t)BIN(opt_minus), (st_data_t)&gen_opt_minus); st_insert(gen_fns, (st_data_t)BIN(opt_send_without_block), (st_data_t)&gen_opt_send_without_block); } -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/