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

ruby-changes:68569

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:08:42 +0900 (JST)
Subject: [ruby-changes:68569] 090255456a (master): Ported neg, and, or instructions

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

From 090255456aa137f28cc254c609ff95fb7fd3d71b Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Mon, 14 Sep 2020 16:59:39 -0400
Subject: Ported neg, and, or instructions

---
 ujit_asm.c       | 143 +++++++++++++++++++++++++++++++++++++++++++++++--------
 ujit_asm.h       |   5 +-
 ujit_asm_tests.c |  26 ++++++----
 ujit_compile.c   |  41 +++++++++++++---
 4 files changed, 178 insertions(+), 37 deletions(-)

diff --git a/ujit_asm.c b/ujit_asm.c
index 67e739f8ad..ce0e9fb2fe 100644
--- a/ujit_asm.c
+++ b/ujit_asm.c
@@ -746,6 +746,22 @@ void cb_write_jcc(codeblock_t* cb, const char* mnem, uint8_t op0, uint8_t op1, s https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L746
     cb_write_int(cb, 0, 32);
 }
 
+// Encode a conditional move instruction
+/*
+void writeCmov(CodeBlock cb, const char mnem, ubyte opcode1, X86Reg dst, X86Opnd src)
+{
+    //cb.writeASM(mnem, dst, src);
+
+    assert (src.isReg || src.isMem);
+    assert (dst.size >= 16, "invalid dst reg size in cmov");
+
+    auto szPref = dst.size is 16;
+    auto rexW = dst.size is 64;
+
+    cb.writeRMInstr!('r', 0xFF, 0x0F, opcode1)(szPref, rexW, X86Opnd(dst), src);
+}
+*/
+
 // add - Integer addition
 void add(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
 {
@@ -765,6 +781,25 @@ void add(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L781
     );
 }
 
+/// and - Bitwise AND
+void and(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
+{
+    cb_write_rm_multi(
+        cb,
+        "and",
+        0x20, // opMemReg8
+        0x21, // opMemRegPref
+        0x22, // opRegMem8
+        0x23, // opRegMemPref
+        0x80, // opMemImm8
+        0x83, // opMemImmSml
+        0x81, // opMemImmLrg
+        0x04, // opExtImm
+        opnd0,
+        opnd1
+    );
+}
+
 /// call - Call to label with 32-bit offset
 void call_label(codeblock_t* cb, size_t label_idx)
 {
@@ -787,6 +822,40 @@ void call(codeblock_t* cb, x86opnd_t opnd) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L822
     cb_write_rm(cb, false, false, NO_OPND, opnd, 2, 1, 0xFF);
 }
 
+/*
+/// cmovcc - Conditional move
+alias cmova = writeCmov!("cmova", 0x47);
+alias cmovae = writeCmov!("cmovae", 0x43);
+alias cmovb = writeCmov!("cmovb", 0x42);
+alias cmovbe = writeCmov!("cmovbe", 0x46);
+alias cmovc = writeCmov!("cmovc", 0x42);
+alias cmove = writeCmov!("cmove", 0x44);
+alias cmovg = writeCmov!("cmovg", 0x4F);
+alias cmovge = writeCmov!("cmovge", 0x4D);
+alias cmovl = writeCmov!("cmovl", 0x4C);
+alias cmovle = writeCmov!("cmovle", 0x4E);
+alias cmovna = writeCmov!("cmovna", 0x46);
+alias cmovnae = writeCmov!("cmovnae", 0x42);
+alias cmovnb = writeCmov!("cmovnb", 0x43);
+alias cmovnbe = writeCmov!("cmovnbe", 0x47);
+alias cmovnc = writeCmov!("cmovnc", 0x43);
+alias cmovne = writeCmov!("cmovne", 0x45);
+alias cmovnge = writeCmov!("cmovng", 0x4E);
+alias cmovnge = writeCmov!("cmovnge", 0x4C);
+alias cmovnl = writeCmov!("cmovnl", 0x4D);
+alias cmovnle = writeCmov!("cmovnle", 0x4F);
+alias cmovno = writeCmov!("cmovno", 0x41);
+alias cmovnp = writeCmov!("cmovnp", 0x4B);
+alias cmovns = writeCmov!("cmovns", 0x49);
+alias cmovnz = writeCmov!("cmovnz", 0x45);
+alias cmovo = writeCmov!("cmovno", 0x40);
+alias cmovp = writeCmov!("cmovp", 0x4A);
+alias cmovpe = writeCmov!("cmovpe", 0x4A);
+alias cmovpo = writeCmov!("cmovpo", 0x4B);
+alias cmovs = writeCmov!("cmovs", 0x48);
+alias cmovz = writeCmov!("cmovz", 0x44);
+*/
+
 /// cmp - Compare and set flags
 void cmp(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
 {
@@ -1094,6 +1163,19 @@ void mov(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L1163
     }
 }
 
+// neg - Integer negation (multiplication by -1)
+void neg(codeblock_t* cb, x86opnd_t opnd)
+{
+    write_rm_unary(
+        cb,
+        "neg",
+        0xF6, // opMemReg8
+        0xF7, // opMemRegPref
+        0x03,  // opExt
+        opnd
+    );
+}
+
 // nop - Noop, one or multiple bytes long
 void nop(codeblock_t* cb, size_t length)
 {
@@ -1174,45 +1256,49 @@ void not(codeblock_t* cb, x86opnd_t opnd) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L1256
     );
 }
 
-/*
 /// or - Bitwise OR
-alias or = writeRMMulti!(
-    "or",
-    0x08, // opMemReg8
-    0x09, // opMemRegPref
-    0x0A, // opRegMem8
-    0x0B, // opRegMemPref
-    0x80, // opMemImm8
-    0x83, // opMemImmSml
-    0x81, // opMemImmLrg
-    0x01  // opExtImm
-);
-*/
+void or(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
+{
+    cb_write_rm_multi(
+        cb,
+        "or",
+        0x08, // opMemReg8
+        0x09, // opMemRegPref
+        0x0A, // opRegMem8
+        0x0B, // opRegMemPref
+        0x80, // opMemImm8
+        0x83, // opMemImmSml
+        0x81, // opMemImmLrg
+        0x01, // opExtImm
+        opnd0,
+        opnd1
+    );
+}
 
-/// push - Push a register on the stack
-void push(codeblock_t* cb, x86opnd_t reg)
+/// pop - Pop a register off the stack
+void pop(codeblock_t* cb, x86opnd_t reg)
 {
     assert (reg.num_bits == 64);
 
-    //cb.writeASM("push", reg);
+    //cb.writeASM("pop", reg);
 
     if (rex_needed(reg))
         cb_write_rex(cb, false, 0, 0, reg.reg.reg_no);
 
-    cb_write_opcode(cb, 0x50, reg);
+    cb_write_opcode(cb, 0x58, reg);
 }
 
-/// pop - Pop a register off the stack
-void pop(codeblock_t* cb, x86opnd_t reg)
+/// push - Push a register on the stack
+void push(codeblock_t* cb, x86opnd_t reg)
 {
     assert (reg.num_bits == 64);
 
-    //cb.writeASM("pop", reg);
+    //cb.writeASM("push", reg);
 
     if (rex_needed(reg))
         cb_write_rex(cb, false, 0, 0, reg.reg.reg_no);
 
-    cb_write_opcode(cb, 0x58, reg);
+    cb_write_opcode(cb, 0x50, reg);
 }
 
 /// ret - Return from call, popping only the return address
@@ -1299,3 +1385,18 @@ void sub(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L1385
         opnd1
     );
 }
+
+/*
+/// xor - Exclusive bitwise OR
+alias xor = writeRMMulti!(
+    "xor",
+    0x30, // opMemReg8
+    0x31, // opMemRegPref
+    0x32, // opRegMem8
+    0x33, // opRegMemPref
+    0x80, // opMemImm8
+    0x83, // opMemImmSml
+    0x81, // opMemImmLrg
+    0x06  // opExtImm
+);
+*/
diff --git a/ujit_asm.h b/ujit_asm.h
index af8f0d7fc7..569c310381 100644
--- a/ujit_asm.h
+++ b/ujit_asm.h
@@ -193,6 +193,7 @@ void cb_link_labels(codeblock_t* cb); https://github.com/ruby/ruby/blob/trunk/ujit_asm.h#L193
 
 // Encode individual instructions into a code block
 void add(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
+void and(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
 void call_label(codeblock_t* cb, size_t label_idx);
 void call(codeblock_t* cb, x86opnd_t opnd);
 void cmp(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
@@ -234,10 +235,12 @@ void jmp(codeblock_t* cb, size_t label_idx); https://github.com/ruby/ruby/blob/trunk/ujit_asm.h#L235
 void jmp_rm(codeblock_t* cb, x86opnd_t opnd);
 void lea(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 void mov(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);
-void push(codeblock_t* cb, x86opnd_t reg);
+void or(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
 void pop(codeblock_t* cb, x86opnd_t reg);
+void push(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);
diff --git a/ujit_asm_tests.c b/ujit_asm_tests.c
index 4ada3a9ecd..e163404d05 100644
--- a/ujit_asm_tests.c
+++ b/ujit_asm_tests.c
@@ -30,7 +30,7 @@ void check_bytes(codeblock_t* cb, const char* bytes) https://github.com/ruby/ruby/blob/trunk/ujit_asm_tests.c#L30
 
         if (cb_byte != byte)
         {
-            fprintf(stderr, "incorrect encoding at position %ld, got %X, expected %X\n",
+            fprintf(stderr, "incorrect encoding at position %ld, got %02X, expected %02X\n",
                 i,
                 (int)cb_byte,
                 (int)byte
@@ -47,8 +47,6 @@ void run_tests() https://github.com/ruby/ruby/blob/trunk/ujit_asm_tests.c#L47
     codeblock_t cb_obj;
     codeblock_t* cb = &cb_obj;
     cb_init(cb, 4096);
-    cb_write_prologue(cb);
-    cb_write_epilogue(cb);
 
     // add
     /*
@@ -82,6 +80,9 @@ void run_tests() https://github.com/ruby/ruby/blob/trunk/ujit_asm_tests.c#L80
     cb_set_pos(cb, 0); add(cb, ECX, imm_opnd(8)); check_bytes(cb, "83C108");
     cb_set_pos(cb, 0); add(cb, ECX, imm_opnd(255)); check_bytes(cb, "81C1FF000000");
 
+    // and
+    cb_set_pos(cb, 0); and(cb, EBP, R12D); check_bytes(cb, "4421E5");
+
     // call
     {
         cb_set_pos(cb, 0);
@@ -212,6 +213,10 @@ void run_tests() https://github.com/ruby/ruby/blob/trunk/ujit_asm_tests.c#L213
     );
     */
     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");
+
+    // neg
+    cb_set_pos(cb, 0); neg(cb, RAX); check_bytes(cb, "48F7D8");
 
     // nop
     cb_set_pos(cb, 0); nop(cb, 1); check_bytes(cb, "90");
@@ -295,12 +300,7 @@ void run_tests() https://github.com/ruby/ruby/blob/trunk/ujit_asm_tests.c#L300
     */
 
     // or
-    /*
-    test(
-        delegate void (CodeBlock cb) { cb.or(X86Opnd(EDX), X86Opnd(ESI)); },
-        "09F2"
-    );
-    */
+    cb_set_pos(cb, 0); or(cb, EDX, ESI); check_bytes(cb, "09F2");
 
     // pop
     cb_set_pos(cb, 0); pop(cb, RAX); check_bytes(cb, "58");
@@ -346,6 +346,14 @@ void run_tests() https://github.com/ruby/ruby/blob/trunk/ujit_asm_tests.c#L346
     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");
 
+    /*
+    // xor
+    test(
+        delegate void (CodeBlock cb (... truncated)

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

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