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

ruby-changes:68579

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:09:57 +0900 (JST)
Subject: [ruby-changes:68579] d1c9ca86c1 (master): Port print_int, movsx. Implement putself.

https://git.ruby-lang.org/ruby.git/commit/?id=d1c9ca86c1

From d1c9ca86c191ef92d9bcd1242aeb7eaa35381e6c Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Fri, 18 Sep 2020 12:20:43 -0400
Subject: Port print_int, movsx. Implement putself.

---
 ujit_asm.c       | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ujit_asm.h       |  1 +
 ujit_asm_tests.c | 26 ++++++++++++++++++++++
 ujit_compile.c   | 19 +++++++++++++---
 ujit_utils.c     | 44 ++++++++++++++-----------------------
 ujit_utils.h     |  1 +
 6 files changed, 127 insertions(+), 31 deletions(-)

diff --git a/ujit_asm.c b/ujit_asm.c
index 55dc517bdb..8a9cc7f287 100644
--- a/ujit_asm.c
+++ b/ujit_asm.c
@@ -1163,6 +1163,73 @@ void mov(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L1163
     }
 }
 
+/// movsx - Move with sign extension (signed integers)
+void movsx(codeblock_t* cb, x86opnd_t dst, x86opnd_t src)
+{
+    assert (dst.type == OPND_REG);
+    assert (src.type == OPND_REG || src.type == OPND_MEM);
+    assert (src.num_bits < dst.num_bits);
+
+    //cb.writeASM("movsx", dst, src);
+
+    if (src.num_bits == 8)
+    {
+        cb_write_rm(cb, dst.num_bits == 16, dst.num_bits == 64, dst, src, 0xFF, 2, 0x0F, 0xBE);
+    }
+    else if (src.num_bits == 16)
+    {
+        cb_write_rm(cb, dst.num_bits == 16, dst.num_bits == 64, dst, src, 0xFF, 2, 0x0F, 0xBF);
+    }
+    else if (src.num_bits == 32)
+    {
+        cb_write_rm(cb, false, true, dst, src, 0xFF, 1, 0x63);
+    }
+    else
+    {
+        assert (false);
+    }
+}
+
+/*
+/// movzx - Move with zero extension (unsigned values)
+void movzx(codeblock_t* cb, x86opnd_t dst, x86opnd_t src)
+{
+    cb.writeASM("movzx", dst, src);
+
+    size_t dstSize;
+    if (dst.isReg)
+        dstSize = dst.reg.size;
+    else
+        assert (false, "movzx dst must be a register");
+
+    size_t srcSize;
+    if (src.isReg)
+        srcSize = src.reg.size;
+    else if (src.isMem)
+        srcSize = src.mem.size;
+    else
+        assert (false);
+
+    assert (
+        srcSize < dstSize,
+        "movzx: srcSize >= dstSize"
+    );
+
+    if (srcSize is 8)
+    {
+        cb.writeRMInstr!('r', 0xFF, 0x0F, 0xB6)(dstSize is 16, dstSize is 64, dst, src);
+    }
+    else if (srcSize is 16)
+    {
+        cb.writeRMInstr!('r', 0xFF, 0x0F, 0xB7)(dstSize is 16, dstSize is 64, dst, src);
+    }
+    else
+    {
+        assert (false, "invalid src operand size for movxz");
+    }
+}
+*/
+
 // neg - Integer negation (multiplication by -1)
 void neg(codeblock_t* cb, x86opnd_t opnd)
 {
diff --git a/ujit_asm.h b/ujit_asm.h
index 595e20eed1..2ed00b1723 100644
--- a/ujit_asm.h
+++ b/ujit_asm.h
@@ -268,6 +268,7 @@ void jmp_rm(codeblock_t* cb, x86opnd_t opnd); https://github.com/ruby/ruby/blob/trunk/ujit_asm.h#L268
 void jmp32(codeblock_t* cb, int32_t offset);
 void lea(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 void mov(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
+void movsx(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 void neg(codeblock_t* cb, x86opnd_t opnd);
 void nop(codeblock_t* cb, size_t length);
 void not(codeblock_t* cb, x86opnd_t opnd);
diff --git a/ujit_asm_tests.c b/ujit_asm_tests.c
index 406253ba26..5de7978858 100644
--- a/ujit_asm_tests.c
+++ b/ujit_asm_tests.c
@@ -218,6 +218,32 @@ void run_tests() https://github.com/ruby/ruby/blob/trunk/ujit_asm_tests.c#L218
     cb_set_pos(cb, 0); mov(cb, mem_opnd(8, RSP, 0), imm_opnd(-3)); check_bytes(cb, "C60424FD");
     cb_set_pos(cb, 0); mov(cb, mem_opnd(64, RDI, 8), imm_opnd(1)); check_bytes(cb, "48C7470801000000");
 
+    // movsx
+    /*
+    test(
+        delegate void (CodeBlock cb) { cb.movsx(X86Opnd(AX), X86Opnd(AL)); },
+        "660FBEC0"
+    );
+    test(
+        delegate void (CodeBlock cb) { cb.movsx(X86Opnd(EDX), X86Opnd(AL)); },
+        "0FBED0"
+    );
+    test(
+        delegate void (CodeBlock cb) { cb.movsx(X86Opnd(RAX), X86Opnd(BL)); },
+        "480FBEC3"
+    );
+    test(
+        delegate void (CodeBlock cb) { cb.movsx(X86Opnd(ECX), X86Opnd(AX)); },
+        "0FBFC8"
+    );
+    test(
+        delegate void (CodeBlock cb) { cb.movsx(X86Opnd(R11), X86Opnd(CL)); },
+        "4C0FBED9"
+    );
+    */
+    cb_set_pos(cb, 0); movsx(cb, R10, mem_opnd(32, RSP, 12)); check_bytes(cb, "4C6354240C");
+    cb_set_pos(cb, 0); movsx(cb, RAX, mem_opnd(8, RSP, 0)); check_bytes(cb, "480FBE0424");
+
     // neg
     cb_set_pos(cb, 0); neg(cb, RAX); check_bytes(cb, "48F7D8");
 
diff --git a/ujit_compile.c b/ujit_compile.c
index 30657f88bf..84bafe52bd 100644
--- a/ujit_compile.c
+++ b/ujit_compile.c
@@ -165,6 +165,7 @@ ujit_compile_insn(rb_iseq_t *iseq, unsigned int insn_idx, unsigned int* next_uji https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L165
         st_data_t st_gen_fn;
         if (!rb_st_lookup(gen_fns, opcode, &st_gen_fn))
         {
+            //print_str(cb, insn_name(opcode));
             break;
         }
 
@@ -194,6 +195,8 @@ ujit_compile_insn(rb_iseq_t *iseq, unsigned int insn_idx, unsigned int* next_uji https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L195
         return NULL;
     }
 
+    //print_int(cb, imm_opnd(num_instrs));
+
     // Write the adjusted SP back into the CFP
     if (ctx.stack_diff != 0)
     {
@@ -216,6 +219,7 @@ ujit_compile_insn(rb_iseq_t *iseq, unsigned int insn_idx, unsigned int* next_uji https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L219
 
 void gen_nop(codeblock_t* cb, ctx_t* ctx)
 {
+    // Do nothing
 }
 
 void gen_pop(codeblock_t* cb, ctx_t* ctx)
@@ -253,7 +257,15 @@ void gen_putobject_int2fix(codeblock_t* cb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L257
     mov(cb, stack_top, imm_opnd(INT2FIX(cst_val)));
 }
 
-// TODO: implement putself
+void gen_putself(codeblock_t* cb, ctx_t* ctx)
+{
+    // Load self from CFP
+    mov(cb, RAX, mem_opnd(64, RDI, 24));
+
+    // Write it on the stack
+    x86opnd_t stack_top = ctx_stack_push(ctx, 1);
+    mov(cb, stack_top, RAX);
+}
 
 void gen_getlocal_wc0(codeblock_t* cb, ctx_t* ctx)
 {
@@ -274,9 +286,9 @@ void gen_getlocal_wc0(codeblock_t* cb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L286
 
 static void ujit_init()
 {
-    // 4MB ought to be enough for anybody
+    // 64MB ought to be enough for anybody
     cb = &block;
-    cb_init(cb, 4000000);
+    cb_init(cb, 64 * 1024 * 1024);
 
     // Initialize the codegen function table
     gen_fns = rb_st_init_numtable();
@@ -288,5 +300,6 @@ static void ujit_init() https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L300
     st_insert(gen_fns, (st_data_t)BIN(putobject), (st_data_t)&gen_putobject);
     st_insert(gen_fns, (st_data_t)BIN(putobject_INT2FIX_0_), (st_data_t)&gen_putobject_int2fix);
     st_insert(gen_fns, (st_data_t)BIN(putobject_INT2FIX_1_), (st_data_t)&gen_putobject_int2fix);
+    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);
 }
diff --git a/ujit_utils.c b/ujit_utils.c
index 35fe8f4f8c..5e535685a1 100644
--- a/ujit_utils.c
+++ b/ujit_utils.c
@@ -33,43 +33,31 @@ void pop_regs(codeblock_t* cb) https://github.com/ruby/ruby/blob/trunk/ujit_utils.c#L33
     pop(cb, RAX);
 }
 
-static void print_str_fn(const char* str)
+static void print_int_cfun(int64_t val)
 {
-    printf("%s", str);
+    printf("%lld\n", val);
 }
 
-/*
-void printInt(CodeBlock as, X86Opnd opnd)
+void print_int(codeblock_t* cb, x86opnd_t opnd)
 {
-    extern (C) void printIntFn(int64_t v)
-    {
-        writefln("%s", v);
-    }
-
-    size_t opndSz;
-    if (opnd.isImm)
-        opndSz = 64;
-    else if (opnd.isGPR)
-        opndSz = opnd.reg.size;
-    else if (opnd.isMem)
-        opndSz = opnd.mem.size;
-    else
-        assert (false);
-
-    as.pushRegs();
+    push_regs(cb);
 
-    if (opndSz < 64)
-        as.movsx(cargRegs[0].opnd(64), opnd);
+    if (opnd.num_bits < 64 && opnd.type != OPND_IMM)
+        movsx(cb, RDI, opnd);
     else
-        as.mov(cargRegs[0].opnd(64), opnd);
+        mov(cb, RDI, opnd);
 
     // Call the print function
-    as.ptr(scrRegs[0], &printIntFn);
-    as.call(scrRegs[0]);
+    mov(cb, RAX, const_ptr_opnd(&print_int_cfun));
+    call(cb, RAX);
 
-    as.popRegs();
+    pop_regs(cb);
+}
+
+static void print_str_cfun(const char* str)
+{
+    printf("%s\n", str);
 }
-*/
 
 // Print a constant string to stdout
 void print_str(codeblock_t* cb, const char* str)
@@ -89,7 +77,7 @@ void print_str(codeblock_t* cb, const char* str) https://github.com/ruby/ruby/blob/trunk/ujit_utils.c#L77
     cb_write_byte(cb, 0);
 
     // Call the print function
-    mov(cb, RAX, const_ptr_opnd(&print_str_fn));
+    mov(cb, RAX, const_ptr_opnd(&print_str_cfun));
     call(cb, RAX);
 
     pop_regs(cb);
diff --git a/ujit_utils.h b/ujit_utils.h
index eaaba4288d..5244d59734 100644
--- a/ujit_utils.h
+++ b/ujit_utils.h
@@ -8,6 +8,7 @@ https://github.com/ruby/ruby/blob/trunk/ujit_utils.h#L8
 
 void push_regs(codeblock_t* cb);
 void pop_regs(codeblock_t* cb);
+void print_int(codeblock_t* cb, x86opnd_t opnd);
 void print_str(codeblock_t* cb, const char* str);
 
 #endif // #ifndef UJIT_UTILS_H
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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