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

ruby-changes:68570

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:09:42 +0900 (JST)
Subject: [ruby-changes:68570] 1879a123ca (master): Added cmp, not. Generate code for nop instruction.

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

From 1879a123caeb9caced2eeb2bb7a7a91a4a8e1930 Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Mon, 14 Sep 2020 11:54:25 -0400
Subject: Added cmp, not. Generate code for nop instruction.

---
 ujit_asm.c       |  66 ++++++++++++++++++++++++++++-
 ujit_asm.h       |   4 ++
 ujit_asm_tests.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ujit_compile.c   |  29 ++++++++++---
 4 files changed, 216 insertions(+), 7 deletions(-)

diff --git a/ujit_asm.c b/ujit_asm.c
index 2cebc8caa6..6b6c586045 100644
--- a/ujit_asm.c
+++ b/ujit_asm.c
@@ -548,10 +548,11 @@ void cb_write_rm( https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L548
     }
 
     // Add the displacement size
-    if (rm_opnd.type == OPND_MEM && rm_opnd.mem.disp != 0)
+    if (rm_opnd.type == OPND_MEM)
     {
         size_t dsize = disp_size(rm_opnd);
-        cb_write_int(cb, rm_opnd.mem.disp, dsize);
+        if (dsize > 0)
+            cb_write_int(cb, rm_opnd.mem.disp, dsize);
     }
 }
 
@@ -791,6 +792,39 @@ void call(codeblock_t* cb, x86opnd_t opnd) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L792
     cb_write_rm(cb, false, false, NO_OPND, opnd, 2, 1, 0xFF);
 }
 
+/// cmp - Compare and set flags
+void cmp(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
+{
+    cb_write_rm_multi(
+        cb,
+        "cmp",
+        0x38, // opMemReg8
+        0x39, // opMemRegPref
+        0x3A, // opRegMem8
+        0x3B, // opRegMemPref
+        0x80, // opMemImm8
+        0x83, // opMemImmSml
+        0x81, // opMemImmLrg
+        0x07, // opExtImm
+        opnd0,
+        opnd1
+    );
+}
+
+/// cdq - Convert doubleword to quadword
+void cdq(codeblock_t* cb)
+{
+    //cb.writeASM("cdq");
+    cb_write_byte(cb, 0x99);
+}
+
+/// cqo - Convert quadword to octaword
+void cqo(codeblock_t* cb)
+{
+    //cb.writeASM("cqo");
+    cb_write_bytes(cb, 2, 0x48, 0x99);
+}
+
 // dec - Decrement integer by 1
 void dec(codeblock_t* cb, x86opnd_t opnd)
 {
@@ -1132,6 +1166,34 @@ void nop(codeblock_t* cb, size_t length) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L1166
     }
 }
 
+// not - Bitwise NOT
+void not(codeblock_t* cb, x86opnd_t opnd)
+{
+    write_rm_unary(
+        cb,
+        "not",
+        0xF6, // opMemReg8
+        0xF7, // opMemRegPref
+        0x02, // opExt
+        opnd
+    );
+}
+
+/*
+/// or - Bitwise OR
+alias or = writeRMMulti!(
+    "or",
+    0x08, // opMemReg8
+    0x09, // opMemRegPref
+    0x0A, // opRegMem8
+    0x0B, // opRegMemPref
+    0x80, // opMemImm8
+    0x83, // opMemImmSml
+    0x81, // opMemImmLrg
+    0x01  // opExtImm
+);
+*/
+
 /// push - Push a register on the stack
 void push(codeblock_t* cb, x86opnd_t reg)
 {
diff --git a/ujit_asm.h b/ujit_asm.h
index da249abf65..d0de30628e 100644
--- a/ujit_asm.h
+++ b/ujit_asm.h
@@ -196,6 +196,9 @@ void cb_write_epilogue(codeblock_t* cb); https://github.com/ruby/ruby/blob/trunk/ujit_asm.h#L196
 void add(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);
+void cdq(codeblock_t* cb);
+void cqo(codeblock_t* cb);
 void dec(codeblock_t* cb, x86opnd_t opnd);
 void inc(codeblock_t* cb, x86opnd_t opnd);
 void ja(codeblock_t* cb, size_t label_idx);
@@ -233,6 +236,7 @@ void jmp_rm(codeblock_t* cb, x86opnd_t opnd); https://github.com/ruby/ruby/blob/trunk/ujit_asm.h#L236
 void lea(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 void mov(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 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 pop(codeblock_t* cb, x86opnd_t reg);
 void ret(codeblock_t* cb);
diff --git a/ujit_asm_tests.c b/ujit_asm_tests.c
index 4d2ed9cff4..4ada3a9ecd 100644
--- a/ujit_asm_tests.c
+++ b/ujit_asm_tests.c
@@ -93,6 +93,44 @@ void run_tests() https://github.com/ruby/ruby/blob/trunk/ujit_asm_tests.c#L93
     cb_set_pos(cb, 0); call(cb, RAX); check_bytes(cb, "FFD0");
     cb_set_pos(cb, 0); call(cb, mem_opnd(64, RSP, 8)); check_bytes(cb, "FF542408");
 
+    /*
+    // cmovcc
+    test(
+        delegate void (CodeBlock cb) { cb.cmovg(ESI, X86Opnd(EDI)); },
+        "0F4FF7"
+    );
+    test(
+        delegate void (CodeBlock cb) { cb.cmovg(ESI, X86Opnd(32, RBP, 12)); },
+        "0F4F750C"
+    );
+    test(
+        delegate void (CodeBlock cb) { cb.cmovl(EAX, X86Opnd(ECX)); },
+        "0F4CC1"
+    );
+    test(
+        delegate void (CodeBlock cb) { cb.cmovl(RBX, X86Opnd(RBP)); },
+        "480F4CDD"
+    );
+    test(
+        delegate void (CodeBlock cb) { cb.cmovle(ESI, X86Opnd(32, RSP, 4)); },
+        "0F4E742404"
+    );
+    */
+
+    // cmp
+    /*
+    test(
+        delegate void (CodeBlock cb) { cb.cmp(X86Opnd(CL), X86Opnd(DL)); },
+        "38D1"
+    );
+    */
+    cb_set_pos(cb, 0); cmp(cb, ECX, EDI); check_bytes(cb, "39F9");
+    cb_set_pos(cb, 0); cmp(cb, RDX, mem_opnd(64, R12, 0)); check_bytes(cb, "493B1424");
+    cb_set_pos(cb, 0); cmp(cb, RAX, imm_opnd(2)); check_bytes(cb, "4883F802");
+
+    // cqo
+    cb_set_pos(cb, 0); cqo(cb); check_bytes(cb, "4899");
+
     // dec
     /*
     test(
@@ -178,6 +216,92 @@ void run_tests() https://github.com/ruby/ruby/blob/trunk/ujit_asm_tests.c#L216
     // nop
     cb_set_pos(cb, 0); nop(cb, 1); check_bytes(cb, "90");
 
+    // not
+    /*
+    test(
+        delegate void (CodeBlock cb) { cb.not(X86Opnd(AX)); },
+        "66F7D0"
+    );
+    */
+    cb_set_pos(cb, 0); not(cb, EAX); check_bytes(cb, "F7D0");
+    cb_set_pos(cb, 0); not(cb, mem_opnd(64, R12, 0)); check_bytes(cb, "49F71424");
+    cb_set_pos(cb, 0); not(cb, mem_opnd(32, RSP, 301)); check_bytes(cb, "F794242D010000");
+    cb_set_pos(cb, 0); not(cb, mem_opnd(32, RSP, 0)); check_bytes(cb, "F71424");
+    cb_set_pos(cb, 0); not(cb, mem_opnd(32, RSP, 3)); check_bytes(cb, "F7542403");
+    cb_set_pos(cb, 0); not(cb, mem_opnd(32, RBP, 0)); check_bytes(cb, "F75500");
+    cb_set_pos(cb, 0); not(cb, mem_opnd(32, RBP, 13)); check_bytes(cb, "F7550D");
+    cb_set_pos(cb, 0); not(cb, RAX); check_bytes(cb, "48F7D0");
+    cb_set_pos(cb, 0); not(cb, R11); check_bytes(cb, "49F7D3");
+    cb_set_pos(cb, 0); not(cb, mem_opnd(32, RAX, 0)); check_bytes(cb, "F710");
+    cb_set_pos(cb, 0); not(cb, mem_opnd(32, RSI, 0)); check_bytes(cb, "F716");
+    cb_set_pos(cb, 0); not(cb, mem_opnd(32, RDI, 0)); check_bytes(cb, "F717");
+    cb_set_pos(cb, 0); not(cb, mem_opnd(32, RDX, 55)); check_bytes(cb, "F75237");
+    cb_set_pos(cb, 0); not(cb, mem_opnd(32, RDX, 1337)); check_bytes(cb, "F79239050000");
+    cb_set_pos(cb, 0); not(cb, mem_opnd(32, RDX, -55)); check_bytes(cb, "F752C9");
+    cb_set_pos(cb, 0); not(cb, mem_opnd(32, RDX, -555)); check_bytes(cb, "F792D5FDFFFF");
+    /*
+    test(
+        delegate void (CodeBlock cb) { cb.not(X86Opnd(32, RAX, 0, 1, RBX)); },
+        "F71418"
+    );
+    test(
+        delegate void (CodeBlock cb) { cb.not(X86Opnd(32, RAX, 0, 1, R12)); },
+        "42F71420"
+    );
+    test(
+        delegate void (CodeBlock cb) { cb.not(X86Opnd(32, R15, 0, 1, R12)); },
+        "43F71427"
+    );
+    test(
+        delegate void (CodeBlock cb) { cb.not(X86Opnd(32, R15, 5, 1, R12)); },
+        "43F7542705"
+    );
+    test(
+        delegate void (CodeBlock cb) { cb.not(X86Opnd(32, R15, 5, 8, R12)); },
+        "43F754E705"
+    );
+    test(
+        delegate void (CodeBlock cb) { cb.not(X86Opnd(32, R15, 5, 8, R13)); },
+        "43F754EF05"
+    );
+    test(
+        delegate void (CodeBlock cb) { cb.not(X86Opnd(32, R12, 5, 4, R9)); },
+        "43F7548C05"
+    );
+    test(
+        delegate void (CodeBlock cb) { cb.not(X86Opnd(32, R12, 301, 4, R9)); },
+        "43F7948C2D010000"
+    );
+    test(
+        delegate void (CodeBlock cb) { cb.not(X86Opnd(32, RAX, 5, 4, RDX)); },
+        "F7549005"
+    );
+    test(
+        delegate void (CodeBlock cb) { cb.not(X86Opnd(64, RAX, 0, 2, RDX)); },
+        "48F71450"
+    );
+    test(
+        delegate void (CodeBlock cb) { cb.not(X86Opnd(32, RSP, 0, 1, RBX)); },
+        "F7141C"
+    );
+    test(
+        delegate void (CodeBlock cb) { cb.not(X86Opnd(32, RSP, 3, 1, RBX)); },
+        "F7541C03"
+    );
+    test(
+        delegate void (CodeBlock cb) { cb.not(X86Opnd(32, RBP, 13, 1, RDX)); },
+        "F754150D"
+    );
+    */
+
+    // or
+    /*
+    test(
+        delegate void (CodeBlock cb) { cb.or(X86Opnd(EDX), X86Opnd(ESI)); },
+        "09F2"
+    );
+    */
+
     // pop
     cb_set_pos(cb, 0); pop(cb, RAX); check_bytes(cb, "58");
     cb_set_pos(cb, 0); pop(cb, RBX); check_bytes(cb, "5B");
diff --git a/ujit_compile.c b/ujit_compile.c
index bc49d63fee..82ea7291f8 100644
--- a/ujit_compile.c
+++ b/ujit_compile.c
@@ -42,18 +42,37 @@ ujit_compile_insn(rb_iseq_t *iseq, size_t insn_idx) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L42
     }
 
     int insn = (int)iseq->body->iseq_encoded[insn_idx];
-
     //const char* name = insn_name(insn);
     //printf("%s\n", name);
 
+    // Get a pointer to the current write position in the code block
+    uint8_t* code_ptr = &cb->mem_block[cb->write_pos];
+    //printf("write pos: %ld\n", cb->write_pos);
+
     // TODO: encode individual instructions, eg
-    // nop, putnil, putobject, putself, pop, dup, getlocal, nilp
+    // nop, putnil, putobject, putself, pop, dup, getlocal, setlocal, nilp
 
-    if (insn == BIN(pop))
+    // TODO: we should move the codegen for individual instructions
+    // into separate functions
+    if (insn == BIN(nop))
     {
-        // Get a pointer to the current write position in the code block
-        uint8_t* code_ptr = &cb->mem_block[cb->write_pos];
+        // Write the pre call bytes
+        cb_write_prologue(cb);
+
+        add(cb, RSI, imm_opnd(8));                  // increment PC
+        mov(cb, mem_opnd(64, RDI, 0), RSI);         // write new PC to EC object, not ne (... truncated)

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

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