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

ruby-changes:68947

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:19:25 +0900 (JST)
Subject: [ruby-changes:68947] 6b5d26dc78 (master): Implement basic encodings for xchg

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

From 6b5d26dc788bfcf1d39db0bfe25645173507299c Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Wed, 12 May 2021 10:18:46 -0400
Subject: Implement basic encodings for xchg

---
 yjit_asm.c       | 23 +++++++++++++++++++++++
 yjit_asm.h       |  2 +-
 yjit_asm_tests.c |  6 ++++++
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/yjit_asm.c b/yjit_asm.c
index 76fc3bf8db..da640e6d7d 100644
--- a/yjit_asm.c
+++ b/yjit_asm.c
@@ -1682,6 +1682,29 @@ void ud2(codeblock_t* cb) https://github.com/ruby/ruby/blob/trunk/yjit_asm.c#L1682
     cb_write_bytes(cb, 2, 0x0F, 0x0B);
 }
 
+/// xchg - Exchange Register/Memory with Register
+void xchg(codeblock_t* cb, x86opnd_t rm_opnd, x86opnd_t r_opnd)
+{
+    assert (rm_opnd.num_bits == 64);
+    assert (r_opnd.num_bits == 64);
+    assert (rm_opnd.type == OPND_REG);
+    assert (r_opnd.type == OPND_REG);
+
+    // If we're exchanging with RAX
+    if (rm_opnd.type == OPND_REG && rm_opnd.as.reg.reg_no == RAX.as.reg.reg_no)
+    {
+        // Write the REX byte
+        cb_write_rex(cb, rm_opnd.num_bits == 64, 0, 0, r_opnd.as.reg.reg_no);
+
+        // Write the opcode and register number
+        cb_write_byte(cb, 0x90 + (r_opnd.as.reg.reg_no & 7));
+    }
+    else
+    {
+        cb_write_rm(cb, rm_opnd.num_bits == 16, rm_opnd.num_bits == 64, r_opnd, rm_opnd, 0xFF, 1, 0x87);
+    }
+}
+
 /// xor - Exclusive bitwise OR
 void xor(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
 {
diff --git a/yjit_asm.h b/yjit_asm.h
index 617a32aafc..15c670fec7 100644
--- a/yjit_asm.h
+++ b/yjit_asm.h
@@ -377,8 +377,8 @@ void shr(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1); https://github.com/ruby/ruby/blob/trunk/yjit_asm.h#L377
 void sub(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
 void test(codeblock_t* cb, x86opnd_t rm_opnd, x86opnd_t test_opnd);
 void ud2(codeblock_t* cb);
+void xchg(codeblock_t* cb, x86opnd_t rm_opnd, x86opnd_t r_opnd);
 void xor(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
-
 void cb_write_lock_prefix(codeblock_t* cb);
 
 #endif
diff --git a/yjit_asm_tests.c b/yjit_asm_tests.c
index 7fc40d497b..3d948d38f4 100644
--- a/yjit_asm_tests.c
+++ b/yjit_asm_tests.c
@@ -341,6 +341,12 @@ void run_tests() https://github.com/ruby/ruby/blob/trunk/yjit_asm_tests.c#L341
     cb_set_pos(cb, 0); test(cb, RAX, RSI); check_bytes(cb, "4885F0");
     cb_set_pos(cb, 0); test(cb, mem_opnd(64, RSI, 64), imm_opnd(~0x08)); check_bytes(cb, "48F74640F7FFFFFF");
 
+    // xchg
+    cb_set_pos(cb, 0); xchg(cb, RAX, RCX); check_bytes(cb, "4891");
+    cb_set_pos(cb, 0); xchg(cb, RAX, R13); check_bytes(cb, "4995");
+    cb_set_pos(cb, 0); xchg(cb, RCX, RBX); check_bytes(cb, "4887D9");
+    cb_set_pos(cb, 0); xchg(cb, R9, R15); check_bytes(cb, "4D87F9");
+
     // xor
     cb_set_pos(cb, 0); xor(cb, EAX, EAX); check_bytes(cb, "31C0");
 
-- 
cgit v1.2.1


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

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