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

ruby-changes:68565

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:08:41 +0900 (JST)
Subject: [ruby-changes:68565] 566d4abee5 (master): Added shift instructions

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

From 566d4abee5e8e59ce6e080f28a25b7c3431c5b3b Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Thu, 10 Sep 2020 14:31:45 -0400
Subject: Added shift instructions

---
 compile.c        |  18 ++++++---
 ujit_asm.c       | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 ujit_asm.h       |   4 ++
 ujit_asm_tests.c |  29 ++++++++++++---
 4 files changed, 150 insertions(+), 12 deletions(-)

diff --git a/compile.c b/compile.c
index 49263002e3..a1983eaecb 100644
--- a/compile.c
+++ b/compile.c
@@ -866,14 +866,20 @@ rb_iseq_translate_threaded_code(rb_iseq_t *iseq) https://github.com/ruby/ruby/blob/trunk/compile.c#L866
     unsigned int i;
     VALUE *encoded = (VALUE *)iseq->body->iseq_encoded;
 
-    for (i = 0; i < iseq->body->iseq_size; /* */ ) {
-	int insn = (int)iseq->body->iseq_encoded[i];
-	int len = insn_len(insn);
-	encoded[i] = (VALUE)table[insn];
+    for (i = 0; i < iseq->body->iseq_size; /* */ )
+    {
+    	int insn = (int)iseq->body->iseq_encoded[i];
+    	int len = insn_len(insn);
+    	encoded[i] = (VALUE)table[insn];
+
+        if (insn == BIN(pop))
+            encoded[i] = (VALUE)native_pop_code;
+
+        const char* name = insn_name(insn);
+        printf("%s\n", name);
 
-        if (insn == BIN(pop)) encoded[i] = (VALUE)native_pop_code;
 
-	i += len;
+    	i += len;
     }
     FL_SET((VALUE)iseq, ISEQ_TRANSLATED);
 #endif
diff --git a/ujit_asm.c b/ujit_asm.c
index 15b0dc5d05..a7c673ef92 100644
--- a/ujit_asm.c
+++ b/ujit_asm.c
@@ -588,6 +588,56 @@ void cb_write_rm_multi( https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L588
     }
 }
 
+// Encode a single-operand shift instruction
+void cb_write_shift(
+    codeblock_t* cb,
+    const char* mnem,
+    uint8_t opMemOnePref,
+    uint8_t opMemClPref,
+    uint8_t opMemImmPref,
+    uint8_t opExt,
+    x86opnd_t opnd0,
+    x86opnd_t opnd1)
+{
+    // Write a disassembly string
+    //cb.writeASM(mnem, opnd0, opnd1);
+
+    // Check the size of opnd0
+    size_t opndSize;
+    if (opnd0.type == OPND_REG || opnd0.type == OPND_MEM)
+        opndSize = opnd0.num_bits;
+    else
+        assert (false && "shift: invalid first operand");
+
+    assert (opndSize == 16 || opndSize == 32 || opndSize == 64);
+    bool szPref = opndSize == 16;
+    bool rexW = opndSize == 64;
+
+    if (opnd1.type == OPND_IMM)
+    {
+        if (opnd1.imm == 1)
+        {
+            cb_write_rm(cb, szPref, rexW, NO_OPND, opnd0, opExt, 1, opMemOnePref);
+        }
+        else
+        {
+            assert (opnd1.num_bits <= 8);
+            cb_write_rm(cb, szPref, rexW, NO_OPND, opnd0, opExt, 1, opMemImmPref);
+            cb_write_byte(cb, (uint8_t)opnd1.imm);
+        }
+    }
+    /*
+    else if (opnd1.isReg && opnd1.reg == CL)
+    {
+        cb.writeRMInstr!('l', opExt, opMemClPref)(szPref, rexW, opnd0, X86Opnd.NONE);
+    }
+    */
+    else
+    {
+        assert (false);
+    }
+}
+
 // add - Integer addition
 void add(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
 {
@@ -893,6 +943,65 @@ void ret(codeblock_t* cb) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L943
     cb_write_byte(cb, 0xC3);
 }
 
+// sal - Shift arithmetic left
+void sal(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
+{
+    cb_write_shift(
+        cb,
+        "sal",
+        0xD1, // opMemOnePref,
+        0xD3, // opMemClPref,
+        0xC1, // opMemImmPref,
+        0x04,
+        opnd0,
+        opnd1
+    );
+}
+
+/// sar - Shift arithmetic right (signed)
+void sar(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
+{
+    cb_write_shift(
+        cb,
+        "sar",
+        0xD1, // opMemOnePref,
+        0xD3, // opMemClPref,
+        0xC1, // opMemImmPref,
+        0x07,
+        opnd0,
+        opnd1
+    );
+}
+// shl - Shift logical left
+void shl(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
+{
+    cb_write_shift(
+        cb,
+        "shl",
+        0xD1, // opMemOnePref,
+        0xD3, // opMemClPref,
+        0xC1, // opMemImmPref,
+        0x04,
+        opnd0,
+        opnd1
+    );
+}
+
+/// shr - Shift logical right (unsigned)
+void shr(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
+{
+    cb_write_shift(
+        cb,
+        "shr",
+        0xD1, // opMemOnePref,
+        0xD3, // opMemClPref,
+        0xC1, // opMemImmPref,
+        0x05,
+        opnd0,
+        opnd1
+    );
+}
+
 /// sub - Integer subtraction
 void sub(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
 {
@@ -906,7 +1015,7 @@ void sub(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L1015
         0x80, // opMemImm8
         0x83, // opMemImmSml
         0x81, // opMemImmLrg
-        0x05,  // opExtImm
+        0x05, // opExtImm
         opnd0,
         opnd1
     );
diff --git a/ujit_asm.h b/ujit_asm.h
index bc93b1e360..714bfa2f31 100644
--- a/ujit_asm.h
+++ b/ujit_asm.h
@@ -194,6 +194,10 @@ void nop(codeblock_t* cb, size_t length); https://github.com/ruby/ruby/blob/trunk/ujit_asm.h#L194
 void push(codeblock_t* cb, x86opnd_t reg);
 void pop(codeblock_t* cb, x86opnd_t reg);
 void ret(codeblock_t* cb);
+void sal(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
+void sar(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
+void shl(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
+void shr(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
 void sub(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
 
 #endif
diff --git a/ujit_asm_tests.c b/ujit_asm_tests.c
index 3e2c28cca9..cbb115eec7 100644
--- a/ujit_asm_tests.c
+++ b/ujit_asm_tests.c
@@ -156,15 +156,34 @@ void run_tests() https://github.com/ruby/ruby/blob/trunk/ujit_asm_tests.c#L156
     // ret
     cb_set_pos(cb, 0); ret(cb); check_bytes(cb, "C3");
 
-    // sub
-    cb_set_pos(cb, 0); sub(cb, EAX, imm_opnd(1)); check_bytes(cb, "83E801");
-    cb_set_pos(cb, 0); sub(cb, RAX, imm_opnd(2)); check_bytes(cb, "4883E802");
-
-
+    // sal
+    /*
+    test(
+        delegate void (CodeBlock cb) { cb.sal(X86Opnd(CX), X86Opnd(1)); },
+        "66D1E1"
+    );
+    */
+    cb_set_pos(cb, 0); sal(cb, ECX, imm_opnd(1)); check_bytes(cb, "D1E1");
+    cb_set_pos(cb, 0); sal(cb, EBP, imm_opnd(5)); check_bytes(cb, "C1E505");
+    cb_set_pos(cb, 0); sal(cb, mem_opnd(32, RSP, 68), imm_opnd(1)); check_bytes(cb, "D1642444");
 
+    // sar
+    cb_set_pos(cb, 0); sar(cb, EDX, imm_opnd(1)); check_bytes(cb, "D1FA");
 
+    // shr
+    cb_set_pos(cb, 0); shr(cb, R14, imm_opnd(7)); check_bytes(cb, "49C1EE07");
 
+    /*
+    // sqrtsd
+    test(
+        delegate void (CodeBlock cb) { cb.sqrtsd(X86Opnd(XMM2), X86Opnd(XMM6)); },
+        "F20F51D6"
+    );
+    */
 
+    // sub
+    cb_set_pos(cb, 0); sub(cb, EAX, imm_opnd(1)); check_bytes(cb, "83E801");
+    cb_set_pos(cb, 0); sub(cb, RAX, imm_opnd(2)); check_bytes(cb, "4883E802");
 
     printf("Assembler tests done\n");
 }
-- 
cgit v1.2.1


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

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