about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2025-04-29 02:32:54 +0800
committerGitHub <noreply@github.com>2025-04-28 20:32:54 +0200
commitf72d43b77e68e7eea4a3c31c596365e77f1c0cd7 (patch)
treed48f0144ba5a3a6df0eaf4506e64e2f7adeb6eb3 /src
parent25de8bd35cb594944afeee3762bc1a11fa3eeebf (diff)
downloadbox64-f72d43b77e68e7eea4a3c31c596365e77f1c0cd7.tar.gz
box64-f72d43b77e68e7eea4a3c31c596365e77f1c0cd7.zip
[RV64_DYNAREC] Minor optim to 8 bit TEST opcode (#2583)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_2.c14
-rw-r--r--src/dynarec/rv64/dynarec_rv64_emit_tests.c16
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h1
3 files changed, 18 insertions, 13 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00_2.c b/src/dynarec/rv64/dynarec_rv64_00_2.c
index f8103fa3..34c805d9 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_2.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_2.c
@@ -263,8 +263,13 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION);
             nextop = F8;
             GETEB(x1, 0);
-            GETGB(x2);
-            emit_test8(dyn, ninst, x1, x2, x6, x4, x5);
+            if (GB_EQ_EB())
+                u8 = x1;
+            else {
+                GETGB(x2);
+                u8 = x2;
+            }
+            emit_test8(dyn, ninst, x1, u8, x6, x4, x5);
             break;
         case 0x85:
             INST_NAME("TEST Ed, Gd");
@@ -845,10 +850,9 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
         case 0xA8:
             INST_NAME("TEST AL, Ib");
             SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION);
-            ANDI(x1, xRAX, 0xff);
             u8 = F8;
-            MOV32w(x2, u8);
-            emit_test8(dyn, ninst, x1, x2, x3, x4, x5);
+            ADDI(x2, xZR, u8);
+            emit_test8(dyn, ninst, x2, xRAX, x3, x4, x5);
             break;
         case 0xA9:
             INST_NAME("TEST EAX, Id");
diff --git a/src/dynarec/rv64/dynarec_rv64_emit_tests.c b/src/dynarec/rv64/dynarec_rv64_emit_tests.c
index 6c2f2ba8..acdb9275 100644
--- a/src/dynarec/rv64/dynarec_rv64_emit_tests.c
+++ b/src/dynarec/rv64/dynarec_rv64_emit_tests.c
@@ -315,29 +315,29 @@ void emit_test8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4,
         SET_DFNONE();
     }
 
-    AND(s3, s1, s2); // res = s1 & s2
+    if (s1 != s2) AND(s1, s1, s2); // res = s1 & s2
 
     IFX_PENDOR0 {
-        SD(s3, xEmu, offsetof(x64emu_t, res));
+        SD(s1, xEmu, offsetof(x64emu_t, res));
     }
 
-    if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s3, xZR);
+    if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR);
 
     IFX (X_SF) {
-        SRLI(s4, s3, 7);
+        SRLI(s4, s1, 7);
         SET_FLAGS_NEZ(s4, F_SF, s5);
     }
     IFX (X_ZF) {
-        SET_FLAGS_EQZ(s3, F_ZF, s5);
+        SET_FLAGS_EQZ(s1, F_ZF, s5);
     }
     IFX (X_PF) {
-        emit_pf(dyn, ninst, s3, s4, s5);
+        emit_pf(dyn, ninst, s1, s4, s5);
     }
 
     NAT_FLAGS_ENABLE_SIGN();
     if (dyn->insts[ninst].nat_flags_fusion && dyn->insts[ninst].nat_flags_needsign) {
-        SLLI(s3, s3, 56);
-        SRAI(s3, s3, 56);
+        SLLI(s1, s1, 56);
+        SRAI(s1, s1, 56);
     }
 }
 
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index 3c8f5dc1..48886fbd 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -394,6 +394,7 @@
         OR(wback, wback, ed);             \
     }
 
+#define GB_EQ_EB() (MODREG && ((nextop & 0x38) >> 3) == (nextop & 7) && (rex.r == rex.b))
 
 #define YMM0(a) ymm_mark_zero(dyn, ninst, a);