about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-12-24 21:06:52 +0800
committerGitHub <noreply@github.com>2024-12-24 14:06:52 +0100
commit05060803b243e143c1c95e4ec61be60f0e479181 (patch)
tree1add8bd42f83978876e448cf166bf05224de5aae /src
parente84f2e4a8beac7c781615f3b470c81e6f58f953b (diff)
downloadbox64-05060803b243e143c1c95e4ec61be60f0e479181.tar.gz
box64-05060803b243e143c1c95e4ec61be60f0e479181.zip
[RV64_DYNAREC] Fixed nativeflags tmp register usage (#2199)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f.c52
-rw-r--r--src/dynarec/rv64/dynarec_rv64_660f.c3
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h169
3 files changed, 117 insertions, 107 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c
index 28b8fc96..22cc4029 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f.c
@@ -100,7 +100,7 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         }
                         SRLI(xRDX, x3, 32);
                         ZEXTW2(xRAX, x3); // wipe upper part
-                        MV(xRCX, xZR);        // IA32_TSC, 0 for now
+                        MV(xRCX, xZR);    // IA32_TSC, 0 for now
                         break;
                     default:
                         DEFAULT;
@@ -898,30 +898,30 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             }
             break;
 
-#define GO(GETFLAGS, NO, YES, NATNO, NATYES, F)                                                     \
-    READFLAGS_FUSION(F, x1, x2, x3, x4, x5);                                                        \
-    if (!dyn->insts[ninst].nat_flags_fusion) {                                                      \
-        GETFLAGS;                                                                                   \
-    }                                                                                               \
-    nextop = F8;                                                                                    \
-    GETGD;                                                                                          \
-    if (MODREG) {                                                                                   \
-        ed = TO_NAT((nextop & 7) + (rex.b << 3));                                                   \
-        if (dyn->insts[ninst].nat_flags_fusion) {                                                   \
-            NATIVEJUMP(NATNO, 8);                                                                   \
-        } else {                                                                                    \
-            B##NO(tmp1, 8);                                                                         \
-        }                                                                                           \
-        MV(gd, ed);                                                                                 \
-    } else {                                                                                        \
-        addr = geted(dyn, addr, ninst, nextop, &ed, tmp2, tmp3, &fixedaddress, rex, NULL, 1, 0);    \
-        if (dyn->insts[ninst].nat_flags_fusion) {                                                   \
-            NATIVEJUMP(NATNO, 8);                                                                   \
-        } else {                                                                                    \
-            B##NO(tmp1, 8);                                                                         \
-        }                                                                                           \
-        LDxw(gd, ed, fixedaddress);                                                                 \
-    }                                                                                               \
+#define GO(GETFLAGS, NO, YES, NATNO, NATYES, F)                                                  \
+    READFLAGS_FUSION(F, x1, x2, x3, x4, x5);                                                     \
+    if (!dyn->insts[ninst].nat_flags_fusion) {                                                   \
+        GETFLAGS;                                                                                \
+    }                                                                                            \
+    nextop = F8;                                                                                 \
+    GETGD;                                                                                       \
+    if (MODREG) {                                                                                \
+        ed = TO_NAT((nextop & 7) + (rex.b << 3));                                                \
+        if (dyn->insts[ninst].nat_flags_fusion) {                                                \
+            NATIVEJUMP(NATNO, 8);                                                                \
+        } else {                                                                                 \
+            B##NO(tmp1, 8);                                                                      \
+        }                                                                                        \
+        MV(gd, ed);                                                                              \
+    } else {                                                                                     \
+        addr = geted(dyn, addr, ninst, nextop, &ed, tmp2, tmp3, &fixedaddress, rex, NULL, 1, 0); \
+        if (dyn->insts[ninst].nat_flags_fusion) {                                                \
+            NATIVEJUMP(NATNO, 8);                                                                \
+        } else {                                                                                 \
+            B##NO(tmp1, 8);                                                                      \
+        }                                                                                        \
+        LDxw(gd, ed, fixedaddress);                                                              \
+    }                                                                                            \
     if (!rex.w) ZEROUP(gd);
 
             GOCOND(0x40, "CMOV", "Gd, Ed");
@@ -1712,6 +1712,8 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
 
 #define GO(GETFLAGS, NO, YES, NATNO, NATYES, F)                                              \
     READFLAGS(F);                                                                            \
+    tmp1 = x1;                                                                               \
+    tmp3 = x3;                                                                               \
     GETFLAGS;                                                                                \
     nextop = F8;                                                                             \
     S##YES(x3, x1);                                                                          \
diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c
index 2bad6621..ac6f5b24 100644
--- a/src/dynarec/rv64/dynarec_rv64_660f.c
+++ b/src/dynarec/rv64/dynarec_rv64_660f.c
@@ -34,6 +34,7 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
     uint8_t gd, ed;
     uint8_t wback, wb1, wb2, gback;
     uint8_t eb1, eb2;
+    uint8_t tmp1, tmp2, tmp3;
     int64_t j64;
     uint64_t tmp64u, tmp64u2;
     int v0, v1;
@@ -276,6 +277,8 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
 
 #define GO(GETFLAGS, NO, YES, NATNO, NATYES, F)                                              \
     READFLAGS(F);                                                                            \
+    tmp1 = x1;                                                                               \
+    tmp3 = x3;                                                                               \
     GETFLAGS;                                                                                \
     nextop = F8;                                                                             \
     GETGD;                                                                                   \
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index e2b8fdc5..2a5fc687 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -1009,9 +1009,14 @@
 #endif
 
 #ifndef READFLAGS_FUSION
-#define READFLAGS_FUSION(A, s1, s2, s3, s4, s5)                                                                     \
-    if(dyn->insts[ninst].nat_flags_fusion) get_free_scratch(dyn, ninst, &tmp1, &tmp2, &tmp3, s1, s2, s3, s4, s5);   \
-    else { tmp1=s1; tmp2=s2; tmp3=s3; }                                                                             \
+#define READFLAGS_FUSION(A, s1, s2, s3, s4, s5)                                \
+    if (dyn->insts[ninst].nat_flags_fusion)                                    \
+        get_free_scratch(dyn, ninst, &tmp1, &tmp2, &tmp3, s1, s2, s3, s4, s5); \
+    else {                                                                     \
+        tmp1 = s1;                                                             \
+        tmp2 = s2;                                                             \
+        tmp3 = s3;                                                             \
+    }                                                                          \
     READFLAGS(A)
 #endif
 
@@ -1668,85 +1673,85 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
 #define MAYUSE(A)
 #endif
 
-// GOCOND will use x1 and x3
-#define GOCOND(B, T1, T2)                                                                   \
-    case B + 0x0:                                                                           \
-        INST_NAME(T1 "O " T2);                                                              \
-        GO(ANDI(x1, xFlags, 1 << F_OF2), EQZ, NEZ, _, _, X_OF)                              \
-        break;                                                                              \
-    case B + 0x1:                                                                           \
-        INST_NAME(T1 "NO " T2);                                                             \
-        GO(ANDI(x1, xFlags, 1 << F_OF2), NEZ, EQZ, _, _, X_OF)                              \
-        break;                                                                              \
-    case B + 0x2:                                                                           \
-        INST_NAME(T1 "C " T2);                                                              \
-        GO(ANDI(x1, xFlags, 1 << F_CF), EQZ, NEZ, GEU, LTU, X_CF)                           \
-        break;                                                                              \
-    case B + 0x3:                                                                           \
-        INST_NAME(T1 "NC " T2);                                                             \
-        GO(ANDI(x1, xFlags, 1 << F_CF), NEZ, EQZ, LTU, GEU, X_CF)                           \
-        break;                                                                              \
-    case B + 0x4:                                                                           \
-        INST_NAME(T1 "Z " T2);                                                              \
-        GO(ANDI(x1, xFlags, 1 << F_ZF), EQZ, NEZ, NE, EQ, X_ZF)                             \
-        break;                                                                              \
-    case B + 0x5:                                                                           \
-        INST_NAME(T1 "NZ " T2);                                                             \
-        GO(ANDI(x1, xFlags, 1 << F_ZF), NEZ, EQZ, EQ, NE, X_ZF)                             \
-        break;                                                                              \
-    case B + 0x6:                                                                           \
-        INST_NAME(T1 "BE " T2);                                                             \
-        GO(ANDI(x1, xFlags, (1 << F_CF) | (1 << F_ZF)), EQZ, NEZ, GTU, LEU, X_CF | X_ZF)    \
-        break;                                                                              \
-    case B + 0x7:                                                                           \
-        INST_NAME(T1 "NBE " T2);                                                            \
-        GO(ANDI(x1, xFlags, (1 << F_CF) | (1 << F_ZF)), NEZ, EQZ, LEU, GTU, X_CF | X_ZF)    \
-        break;                                                                              \
-    case B + 0x8:                                                                           \
-        INST_NAME(T1 "S " T2);                                                              \
-        GO(ANDI(x1, xFlags, 1 << F_SF), EQZ, NEZ, _, _, X_SF)                               \
-        break;                                                                              \
-    case B + 0x9:                                                                           \
-        INST_NAME(T1 "NS " T2);                                                             \
-        GO(ANDI(x1, xFlags, 1 << F_SF), NEZ, EQZ, _, _, X_SF)                               \
-        break;                                                                              \
-    case B + 0xA:                                                                           \
-        INST_NAME(T1 "P " T2);                                                              \
-        GO(ANDI(x1, xFlags, 1 << F_PF), EQZ, NEZ, _, _, X_PF)                               \
-        break;                                                                              \
-    case B + 0xB:                                                                           \
-        INST_NAME(T1 "NP " T2);                                                             \
-        GO(ANDI(x1, xFlags, 1 << F_PF), NEZ, EQZ, _, _, X_PF)                               \
-        break;                                                                              \
-    case B + 0xC:                                                                           \
-        INST_NAME(T1 "L " T2);                                                              \
-        GO(SRLI(x1, xFlags, F_SF - F_OF2);                                                  \
-            XOR(x1, x1, xFlags);                                                            \
-            ANDI(x1, x1, 1 << F_OF2), EQZ, NEZ, GE, LT, X_SF | X_OF)                        \
-        break;                                                                              \
-    case B + 0xD:                                                                           \
-        INST_NAME(T1 "GE " T2);                                                             \
-        GO(SRLI(x1, xFlags, F_SF - F_OF2);                                                  \
-            XOR(x1, x1, xFlags);                                                            \
-            ANDI(x1, x1, 1 << F_OF2), NEZ, EQZ, LT, GE, X_SF | X_OF)                        \
-        break;                                                                              \
-    case B + 0xE:                                                                           \
-        INST_NAME(T1 "LE " T2);                                                             \
-        GO(SRLI(x1, xFlags, F_SF - F_OF2);                                                  \
-            XOR(x1, x1, xFlags);                                                            \
-            ANDI(x1, x1, 1 << F_OF2);                                                       \
-            ANDI(x3, xFlags, 1 << F_ZF);                                                    \
-            OR(x1, x1, x3);                                                                 \
-            ANDI(x1, x1, (1 << F_OF2) | (1 << F_ZF)), EQZ, NEZ, GT, LE, X_SF | X_OF | X_ZF) \
-        break;                                                                              \
-    case B + 0xF:                                                                           \
-        INST_NAME(T1 "G " T2);                                                              \
-        GO(SRLI(x1, xFlags, F_SF - F_OF2);                                                  \
-            XOR(x1, x1, xFlags);                                                            \
-            ANDI(x1, x1, 1 << F_OF2);                                                       \
-            ANDI(x3, xFlags, 1 << F_ZF);                                                    \
-            OR(x1, x1, x3);                                                                 \
-            ANDI(x1, x1, (1 << F_OF2) | (1 << F_ZF)), NEZ, EQZ, LE, GT, X_SF | X_OF | X_ZF) \
+// GOCOND will use tmp1 and tmp3
+#define GOCOND(B, T1, T2)                                                                       \
+    case B + 0x0:                                                                               \
+        INST_NAME(T1 "O " T2);                                                                  \
+        GO(ANDI(tmp1, xFlags, 1 << F_OF2), EQZ, NEZ, _, _, X_OF)                                \
+        break;                                                                                  \
+    case B + 0x1:                                                                               \
+        INST_NAME(T1 "NO " T2);                                                                 \
+        GO(ANDI(tmp1, xFlags, 1 << F_OF2), NEZ, EQZ, _, _, X_OF)                                \
+        break;                                                                                  \
+    case B + 0x2:                                                                               \
+        INST_NAME(T1 "C " T2);                                                                  \
+        GO(ANDI(tmp1, xFlags, 1 << F_CF), EQZ, NEZ, GEU, LTU, X_CF)                             \
+        break;                                                                                  \
+    case B + 0x3:                                                                               \
+        INST_NAME(T1 "NC " T2);                                                                 \
+        GO(ANDI(tmp1, xFlags, 1 << F_CF), NEZ, EQZ, LTU, GEU, X_CF)                             \
+        break;                                                                                  \
+    case B + 0x4:                                                                               \
+        INST_NAME(T1 "Z " T2);                                                                  \
+        GO(ANDI(tmp1, xFlags, 1 << F_ZF), EQZ, NEZ, NE, EQ, X_ZF)                               \
+        break;                                                                                  \
+    case B + 0x5:                                                                               \
+        INST_NAME(T1 "NZ " T2);                                                                 \
+        GO(ANDI(tmp1, xFlags, 1 << F_ZF), NEZ, EQZ, EQ, NE, X_ZF)                               \
+        break;                                                                                  \
+    case B + 0x6:                                                                               \
+        INST_NAME(T1 "BE " T2);                                                                 \
+        GO(ANDI(tmp1, xFlags, (1 << F_CF) | (1 << F_ZF)), EQZ, NEZ, GTU, LEU, X_CF | X_ZF)      \
+        break;                                                                                  \
+    case B + 0x7:                                                                               \
+        INST_NAME(T1 "NBE " T2);                                                                \
+        GO(ANDI(tmp1, xFlags, (1 << F_CF) | (1 << F_ZF)), NEZ, EQZ, LEU, GTU, X_CF | X_ZF)      \
+        break;                                                                                  \
+    case B + 0x8:                                                                               \
+        INST_NAME(T1 "S " T2);                                                                  \
+        GO(ANDI(tmp1, xFlags, 1 << F_SF), EQZ, NEZ, _, _, X_SF)                                 \
+        break;                                                                                  \
+    case B + 0x9:                                                                               \
+        INST_NAME(T1 "NS " T2);                                                                 \
+        GO(ANDI(tmp1, xFlags, 1 << F_SF), NEZ, EQZ, _, _, X_SF)                                 \
+        break;                                                                                  \
+    case B + 0xA:                                                                               \
+        INST_NAME(T1 "P " T2);                                                                  \
+        GO(ANDI(tmp1, xFlags, 1 << F_PF), EQZ, NEZ, _, _, X_PF)                                 \
+        break;                                                                                  \
+    case B + 0xB:                                                                               \
+        INST_NAME(T1 "NP " T2);                                                                 \
+        GO(ANDI(tmp1, xFlags, 1 << F_PF), NEZ, EQZ, _, _, X_PF)                                 \
+        break;                                                                                  \
+    case B + 0xC:                                                                               \
+        INST_NAME(T1 "L " T2);                                                                  \
+        GO(SRLI(tmp1, xFlags, F_SF - F_OF2);                                                    \
+            XOR(tmp1, tmp1, xFlags);                                                            \
+            ANDI(tmp1, tmp1, 1 << F_OF2), EQZ, NEZ, GE, LT, X_SF | X_OF)                        \
+        break;                                                                                  \
+    case B + 0xD:                                                                               \
+        INST_NAME(T1 "GE " T2);                                                                 \
+        GO(SRLI(tmp1, xFlags, F_SF - F_OF2);                                                    \
+            XOR(tmp1, tmp1, xFlags);                                                            \
+            ANDI(tmp1, tmp1, 1 << F_OF2), NEZ, EQZ, LT, GE, X_SF | X_OF)                        \
+        break;                                                                                  \
+    case B + 0xE:                                                                               \
+        INST_NAME(T1 "LE " T2);                                                                 \
+        GO(SRLI(tmp1, xFlags, F_SF - F_OF2);                                                    \
+            XOR(tmp1, tmp1, xFlags);                                                            \
+            ANDI(tmp1, tmp1, 1 << F_OF2);                                                       \
+            ANDI(tmp3, xFlags, 1 << F_ZF);                                                      \
+            OR(tmp1, tmp1, tmp3);                                                               \
+            ANDI(tmp1, tmp1, (1 << F_OF2) | (1 << F_ZF)), EQZ, NEZ, GT, LE, X_SF | X_OF | X_ZF) \
+        break;                                                                                  \
+    case B + 0xF:                                                                               \
+        INST_NAME(T1 "G " T2);                                                                  \
+        GO(SRLI(tmp1, xFlags, F_SF - F_OF2);                                                    \
+            XOR(tmp1, tmp1, xFlags);                                                            \
+            ANDI(tmp1, tmp1, 1 << F_OF2);                                                       \
+            ANDI(tmp3, xFlags, 1 << F_ZF);                                                      \
+            OR(tmp1, tmp1, tmp3);                                                               \
+            ANDI(tmp1, tmp1, (1 << F_OF2) | (1 << F_ZF)), NEZ, EQZ, LE, GT, X_SF | X_OF | X_ZF) \
         break
 
 // Dummy macros