[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]