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

ruby-changes:68685

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:12:21 +0900 (JST)
Subject: [ruby-changes:68685] 868a6809e7 (master): Add sign-extended mode for test() instruction

https://git.ruby-lang.org/ruby.git/commit/?id=868a6809e7

From 868a6809e7d15b95f14bff822268e2962747fb06 Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Mon, 14 Dec 2020 13:26:33 -0500
Subject: Add sign-extended mode for test() instruction

---
 ujit_asm.c       | 34 +++++++++++++++++++++++-----------
 ujit_asm_tests.c |  1 +
 2 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/ujit_asm.c b/ujit_asm.c
index 4cb7bb7caa..4fb0cc764a 100644
--- a/ujit_asm.c
+++ b/ujit_asm.c
@@ -1516,22 +1516,34 @@ void test(codeblock_t* cb, x86opnd_t rm_opnd, x86opnd_t test_opnd) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L1516
     if (test_opnd.type == OPND_IMM)
     {
         x86opnd_t imm_opnd = test_opnd;
-        assert (imm_opnd.as.imm >= 0);
-        assert (unsig_imm_size(imm_opnd.as.unsig_imm) <= 32);
-        assert (unsig_imm_size(imm_opnd.as.unsig_imm) <= rm_opnd.num_bits);
 
-        // Use the smallest operand size possible
-        rm_opnd = resize_opnd(rm_opnd, unsig_imm_size(imm_opnd.as.unsig_imm));
-
-        if (rm_opnd.num_bits == 8)
+        if (imm_opnd.as.imm >= 0)
         {
-            cb_write_rm(cb, false, false, NO_OPND, rm_opnd, 0x00, 1, 0xF6);
-            cb_write_int(cb, imm_opnd.as.imm, rm_opnd.num_bits);
+            assert (unsig_imm_size(imm_opnd.as.unsig_imm) <= 32);
+            assert (unsig_imm_size(imm_opnd.as.unsig_imm) <= rm_opnd.num_bits);
+
+            // Use the smallest operand size possible
+            rm_opnd = resize_opnd(rm_opnd, unsig_imm_size(imm_opnd.as.unsig_imm));
+
+            if (rm_opnd.num_bits == 8)
+            {
+                cb_write_rm(cb, false, false, NO_OPND, rm_opnd, 0x00, 1, 0xF6);
+                cb_write_int(cb, imm_opnd.as.imm, rm_opnd.num_bits);
+            }
+            else
+            {
+                cb_write_rm(cb, rm_opnd.num_bits == 16, false, NO_OPND, rm_opnd, 0x00, 1, 0xF7);
+                cb_write_int(cb, imm_opnd.as.imm, rm_opnd.num_bits);
+            }
         }
         else
         {
-            cb_write_rm(cb, rm_opnd.num_bits == 16, false, NO_OPND, rm_opnd, 0x00, 1, 0xF7);
-            cb_write_int(cb, imm_opnd.as.imm, rm_opnd.num_bits);
+            // This mode only applies to 64-bit R/M operands with 32-bit signed immediates
+            assert (imm_opnd.as.imm < 0);
+            assert (sig_imm_size(imm_opnd.as.imm) <= 32);
+            assert (rm_opnd.num_bits == 64);
+            cb_write_rm(cb, false, true, NO_OPND, rm_opnd, 0x00, 1, 0xF7);
+            cb_write_int(cb, imm_opnd.as.imm, 32);
         }
     }
     else
diff --git a/ujit_asm_tests.c b/ujit_asm_tests.c
index 532fb5367c..8f2fbdfcbf 100644
--- a/ujit_asm_tests.c
+++ b/ujit_asm_tests.c
@@ -315,6 +315,7 @@ void run_tests() https://github.com/ruby/ruby/blob/trunk/ujit_asm_tests.c#L315
     cb_set_pos(cb, 0); test(cb, mem_opnd(8, RSI, 16), imm_opnd(1)); check_bytes(cb, "F6461001");
     cb_set_pos(cb, 0); test(cb, mem_opnd(8, RSI, -16), imm_opnd(1)); check_bytes(cb, "F646F001");
     cb_set_pos(cb, 0); test(cb, mem_opnd(32, RSI, 64), EAX); check_bytes(cb, "854640");
+    cb_set_pos(cb, 0); test(cb, mem_opnd(64, RSI, 64), imm_opnd(~0x08)); check_bytes(cb, "48F74640F7FFFFFF");
 
     // 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/

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