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

ruby-changes:68558

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:08:15 +0900 (JST)
Subject: [ruby-changes:68558] 1392a6f2a4 (master): Added jmp R/M instruction

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

From 1392a6f2a499f7400320b87d0bf53d3ef0e26d93 Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Wed, 9 Sep 2020 17:16:21 -0400
Subject: Added jmp R/M instruction

---
 ujit_asm.c       | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ujit_asm.h       |  1 +
 ujit_asm_tests.c | 24 ++++++++++----
 3 files changed, 118 insertions(+), 6 deletions(-)

diff --git a/ujit_asm.c b/ujit_asm.c
index 41167e9d42..d8d7756ac4 100644
--- a/ujit_asm.c
+++ b/ujit_asm.c
@@ -613,6 +613,105 @@ void call(codeblock_t* cb, x86opnd_t opnd) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L613
     cb_write_rm(cb, false, false, NO_OPND, opnd, 2, 1, 0xFF);
 }
 
+/**
+Encode a relative jump to a label (direct or conditional)
+Note: this always encodes a 32-bit offset
+*/
+/*
+void writeJcc(string mnem, opcode...)(CodeBlock cb, Label label)
+{
+    cb.writeASM(mnem, label);
+
+    // Write the opcode
+    cb.writeBytes(opcode);
+
+    // Add a reference to the label
+    cb.addLabelRef(label);
+
+    // Relative 32-bit offset to be patched
+    cb.writeInt(0, 32);
+}
+*/
+
+/*
+/// jcc - Conditional relative jump to a label
+alias ja = writeJcc!("ja", 0x0F, 0x87);
+alias jae = writeJcc!("jae", 0x0F, 0x83);
+alias jb = writeJcc!("jb", 0x0F, 0x82);
+alias jbe = writeJcc!("jbe", 0x0F, 0x86);
+alias jc = writeJcc!("jc", 0x0F, 0x82);
+alias je = writeJcc!("je", 0x0F, 0x84);
+alias jg = writeJcc!("jg", 0x0F, 0x8F);
+alias jge = writeJcc!("jge", 0x0F, 0x8D);
+alias jl = writeJcc!("jl", 0x0F, 0x8C);
+alias jle = writeJcc!("jle", 0x0F, 0x8E);
+alias jna = writeJcc!("jna", 0x0F, 0x86);
+alias jnae = writeJcc!("jnae", 0x0F, 0x82);
+alias jnb = writeJcc!("jnb", 0x0F, 0x83);
+alias jnbe = writeJcc!("jnbe", 0x0F, 0x87);
+alias jnc = writeJcc!("jnc", 0x0F, 0x83);
+alias jne = writeJcc!("jne", 0x0F, 0x85);
+alias jng = writeJcc!("jng", 0x0F, 0x8E);
+alias jnge = writeJcc!("jnge", 0x0F, 0x8C);
+alias jnl = writeJcc!("jnl", 0x0F, 0x8D);
+alias jnle = writeJcc!("jnle", 0x0F, 0x8F);
+alias jno = writeJcc!("jno", 0x0F, 0x81);
+alias jnp = writeJcc!("jnp", 0x0F, 0x8b);
+alias jns = writeJcc!("jns", 0x0F, 0x89);
+alias jnz = writeJcc!("jnz", 0x0F, 0x85);
+alias jo = writeJcc!("jo", 0x0F, 0x80);
+alias jp = writeJcc!("jp", 0x0F, 0x8A);
+alias jpe = writeJcc!("jpe", 0x0F, 0x8A);
+alias jpo = writeJcc!("jpo", 0x0F, 0x8B);
+alias js = writeJcc!("js", 0x0F, 0x88);
+alias jz = writeJcc!("jz", 0x0F, 0x84);
+
+/// Opcode for direct jump with relative 8-bit offset
+const ubyte JMP_REL8_OPCODE = 0xEB;
+
+/// Opcode for direct jump with relative 32-bit offset
+const ubyte JMP_REL32_OPCODE = 0xE9;
+
+/// Opcode for jump on equal with relative 32-bit offset
+const ubyte[] JE_REL32_OPCODE = [0x0F, 0x84];
+
+/// jmp - Direct relative jump to label
+alias jmp = writeJcc!("jmp", JMP_REL32_OPCODE);
+*/
+
+/// jmp - Indirect jump near to an R/M operand
+void jmp(codeblock_t* cb, x86opnd_t opnd)
+{
+    //cb.writeASM("jmp", opnd);
+    cb_write_rm(cb, false, false, NO_OPND, opnd, 4, 1, 0xFF);
+}
+
+/*
+/// jmp - Jump with relative 8-bit offset
+void jmp8(CodeBlock cb, int8_t offset)
+{
+    cb.writeASM("jmp", ((offset > 0)? "+":"-") ~ to!string(offset));
+    cb.writeByte(JMP_REL8_OPCODE);
+    cb.writeByte(offset);
+}
+
+/// jmp - Jump with relative 32-bit offset
+void jmp32(CodeBlock cb, int32_t offset)
+{
+    cb.writeASM("jmp", ((offset > 0)? "+":"-") ~ to!string(offset));
+    cb.writeByte(JMP_REL32_OPCODE);
+    cb.writeInt(offset, 32);
+}
+*/
+
+/// lea - Load Effective Address
+void lea(codeblock_t* cb, x86opnd_t dst, x86opnd_t src)
+{
+    //cb.writeASM("lea", dst, src);
+    assert (dst.num_bits == 64);
+    cb_write_rm(cb, false, true, dst, src, 0xFF, 1, 0x8D);
+}
+
 /// mov - Data move operation
 void mov(codeblock_t* cb, x86opnd_t dst, x86opnd_t src)
 {
diff --git a/ujit_asm.h b/ujit_asm.h
index 9facd68017..1f8ed35f8f 100644
--- a/ujit_asm.h
+++ b/ujit_asm.h
@@ -169,6 +169,7 @@ void cb_write_epilogue(codeblock_t* cb); https://github.com/ruby/ruby/blob/trunk/ujit_asm.h#L169
 // Encode individual instructions into a code block
 void add(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
 void call(codeblock_t* cb, x86opnd_t opnd);
+void jmp(codeblock_t* cb, x86opnd_t opnd);
 void mov(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 void nop(codeblock_t* cb, size_t length);
 void push(codeblock_t* cb, x86opnd_t reg);
diff --git a/ujit_asm_tests.c b/ujit_asm_tests.c
index ac148d1b7f..b705c7bfe7 100644
--- a/ujit_asm_tests.c
+++ b/ujit_asm_tests.c
@@ -105,6 +105,24 @@ void run_tests() https://github.com/ruby/ruby/blob/trunk/ujit_asm_tests.c#L105
     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");
 
+    /*
+    // jcc
+    test(
+        delegate void (CodeBlock cb) { auto l = cb.label(Label.LOOP); cb.jge(l); },
+        "0F8DFAFFFFFF"
+    );
+    test(
+        delegate void (CodeBlock cb) { cb.label(Label.LOOP); cb.jo(Label.LOOP); },
+        "0F80FAFFFFFF"
+    );
+    */
+
+    // jmp
+    cb_set_pos(cb, 0); jmp(cb, R12); check_bytes(cb, "41FFE4");
+
+    // lea
+    //cb_set_pos(cb, 0); mov(cb, EBX, mem_opnd(32, RSP, 4))); check_bytes(cb, "8D5C2404");
+
     // mov
     /*
     test(
@@ -117,7 +135,6 @@ void run_tests() https://github.com/ruby/ruby/blob/trunk/ujit_asm_tests.c#L135
     );
     */
     cb_set_pos(cb, 0); mov(cb, R15, imm_opnd(3)); check_bytes(cb, "49BF0300000000000000");
-
     /*
     test(
         delegate void (CodeBlock cb) { cb.mov(X86Opnd(EAX), X86Opnd(EBX)); },
@@ -150,11 +167,6 @@ void run_tests() https://github.com/ruby/ruby/blob/trunk/ujit_asm_tests.c#L167
     */
     cb_set_pos(cb, 0); mov(cb, mem_opnd(8, RSP, 0), imm_opnd(-3)); check_bytes(cb, "C60424FD");
 
-
-
-
-
-
     // nop
     cb_set_pos(cb, 0); nop(cb, 1); check_bytes(cb, "90");
 
-- 
cgit v1.2.1


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

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