about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2025-02-09 02:14:36 +0800
committerGitHub <noreply@github.com>2025-02-08 19:14:36 +0100
commit797731e9e25c656def00350643c3cfdc6dd8e4e6 (patch)
tree050af1e8983c07cf3dc8a2c432c137d5d65e8c2f /src
parent3e2c6987106b9cd8775618a0f3a7f31e0936821b (diff)
downloadbox64-797731e9e25c656def00350643c3cfdc6dd8e4e6.tar.gz
box64-797731e9e25c656def00350643c3cfdc6dd8e4e6.zip
[RV64_DYNAREC] Minor fixes and improvements on various opcodes (#2331)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_66.c13
-rw-r--r--src/dynarec/rv64/dynarec_rv64_660f.c52
2 files changed, 36 insertions, 29 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c
index eadb624e..1830054c 100644
--- a/src/dynarec/rv64/dynarec_rv64_66.c
+++ b/src/dynarec/rv64/dynarec_rv64_66.c
@@ -1284,6 +1284,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     ANDI(x2, xRCX, 0x1f);
                     MESSAGE(LOG_DUMP, "Need Optimization\n");
                     SETFLAGS(X_OF | X_CF, SF_SET_DF, NAT_FLAGS_NOFUSION);
+                    if (BOX64DRENV(dynarec_safeflags) > 1) MAYSETFLAGS();
                     GETEW(x1, 1);
                     CALL_(rol16, x1, x3, x1, x2);
                     EWBACK;
@@ -1293,6 +1294,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     ANDI(x2, xRCX, 0x1f);
                     MESSAGE(LOG_DUMP, "Need Optimization\n");
                     SETFLAGS(X_OF | X_CF, SF_SET_DF, NAT_FLAGS_NOFUSION);
+                    if (BOX64DRENV(dynarec_safeflags) > 1) MAYSETFLAGS();
                     GETEW(x1, 1);
                     CALL_(ror16, x1, x3, x1, x2);
                     EWBACK;
@@ -1303,6 +1305,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     MESSAGE("LOG_DUMP", "Need optimization\n");
                     READFLAGS(X_CF);
                     SETFLAGS(X_OF | X_CF, SF_SET_DF, NAT_FLAGS_NOFUSION);
+                    if (BOX64DRENV(dynarec_safeflags) > 1) MAYSETFLAGS();
                     GETEW(x1, 1);
                     CALL_(rcl16, x1, x3, x1, x2);
                     EWBACK;
@@ -1313,6 +1316,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     MESSAGE("LOG_DUMP", "Need optimization\n");
                     READFLAGS(X_CF);
                     SETFLAGS(X_OF | X_CF, SF_SET_DF, NAT_FLAGS_NOFUSION);
+                    if (BOX64DRENV(dynarec_safeflags) > 1) MAYSETFLAGS();
                     GETEW(x1, 1);
                     CALL_(rcr16, x1, x3, x1, x2);
                     EWBACK;
@@ -1322,8 +1326,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     ANDI(x2, xRCX, 0x1f);
                     BEQ_NEXT(x2, xZR);
                     SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION); // some flags are left undefined
-                    if (BOX64DRENV(dynarec_safeflags) > 1)
-                        MAYSETFLAGS();
+                    if (BOX64DRENV(dynarec_safeflags) > 1) MAYSETFLAGS();
                     GETEW(x1, 0);
                     emit_shr16(dyn, ninst, x1, x2, x5, x4, x6);
                     EWBACK;
@@ -1334,8 +1337,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     ANDI(x2, xRCX, 0x1f);
                     BEQ_NEXT(x2, xZR);
                     SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION); // some flags are left undefined
-                    if (BOX64DRENV(dynarec_safeflags) > 1)
-                        MAYSETFLAGS();
+                    if (BOX64DRENV(dynarec_safeflags) > 1) MAYSETFLAGS();
                     GETEW(x1, 0);
                     emit_shl16(dyn, ninst, x1, x2, x5, x4, x6);
                     EWBACK;
@@ -1345,8 +1347,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     ANDI(x2, xRCX, 0x1f);
                     BEQ_NEXT(x2, xZR);
                     SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION); // some flags are left undefined
-                    if (BOX64DRENV(dynarec_safeflags) > 1)
-                        MAYSETFLAGS();
+                    if (BOX64DRENV(dynarec_safeflags) > 1) MAYSETFLAGS();
                     GETSEW(x1, 0);
                     emit_sar16(dyn, ninst, x1, x2, x5, x4, x6);
                     EWBACK;
diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c
index 62043219..98c00e29 100644
--- a/src/dynarec/rv64/dynarec_rv64_660f.c
+++ b/src/dynarec/rv64/dynarec_rv64_660f.c
@@ -1272,9 +1272,11 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                     GETED(1);
                     u8 = F8;
                     u8 &= rex.w ? 0x3f : 15;
-                    BEXTI(x3, ed, u8); // F_CF is 1
-                    ANDI(xFlags, xFlags, ~1);
-                    OR(xFlags, xFlags, x3);
+                    IFX (X_CF) {
+                        BEXTI(x3, ed, u8); // F_CF is 1
+                        ANDI(xFlags, xFlags, ~1);
+                        OR(xFlags, xFlags, x3);
+                    }
                     break;
                 case 5:
                     INST_NAME("BTS Ew, Ib");
@@ -1283,18 +1285,18 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                     GETEW(x1, 1);
                     u8 = F8;
                     u8 &= (rex.w ? 0x3f : 15);
-                    ORI(xFlags, xFlags, 1 << F_CF);
+                    IFX (X_CF) ORI(xFlags, xFlags, 1 << F_CF);
                     if (u8 <= 10) {
                         ANDI(x6, ed, 1 << u8);
                         BNE_MARK(x6, xZR);
-                        ANDI(xFlags, xFlags, ~(1 << F_CF));
+                        IFX (X_CF) ANDI(xFlags, xFlags, ~(1 << F_CF));
                         XORI(ed, ed, 1 << u8);
                     } else {
                         ORI(x6, xZR, 1);
                         SLLI(x6, x6, u8);
                         AND(x4, ed, x6);
                         BNE_MARK(x4, xZR);
-                        ANDI(xFlags, xFlags, ~(1 << F_CF));
+                        IFX (X_CF) ANDI(xFlags, xFlags, ~(1 << F_CF));
                         XOR(ed, ed, x6);
                     }
                     EWBACK;
@@ -1307,18 +1309,18 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                     GETEW(x1, 1);
                     u8 = F8;
                     u8 &= (rex.w ? 0x3f : 15);
-                    ANDI(xFlags, xFlags, ~(1 << F_CF));
+                    IFX (X_CF) ANDI(xFlags, xFlags, ~(1 << F_CF));
                     if (u8 <= 10) {
                         ANDI(x6, ed, 1 << u8);
                         BEQ_MARK(x6, xZR);
-                        ORI(xFlags, xFlags, 1 << F_CF);
+                        IFX (X_CF) ORI(xFlags, xFlags, 1 << F_CF);
                         XORI(ed, ed, 1 << u8);
                     } else {
                         ORI(x6, xZR, 1);
                         SLLI(x6, x6, u8);
                         AND(x6, ed, x6);
                         BEQ_MARK(x6, xZR);
-                        ORI(xFlags, xFlags, 1 << F_CF);
+                        IFX (X_CF) ORI(xFlags, xFlags, 1 << F_CF);
                         XOR(ed, ed, x6);
                     }
                     MARK;
@@ -1331,9 +1333,11 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                     GETEW(x1, 1);
                     u8 = F8;
                     u8 &= rex.w ? 0x3f : 15;
-                    BEXTI(x6, ed, u8); // F_CF is 1
-                    ANDI(xFlags, xFlags, ~1);
-                    OR(xFlags, xFlags, x6);
+                    IFX (X_CF) {
+                        BEXTI(x6, ed, u8); // F_CF is 1
+                        ANDI(xFlags, xFlags, ~1);
+                        OR(xFlags, xFlags, x6);
+                    }
                     if (u8 <= 10) {
                         XORI(ed, ed, (1LL << u8));
                     } else {
@@ -1364,20 +1368,22 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 ed = x1;
                 wback = x3;
             }
-            if (rv64_zbs) {
-                if (rex.w) {
-                    BEXT_(x4, ed, gd);
+            IFX (X_CF) {
+                if (rv64_zbs) {
+                    if (rex.w) {
+                        BEXT_(x4, ed, gd);
+                    } else {
+                        ANDI(x2, gd, 0xf);
+                        BEXT_(x4, ed, x2);
+                    }
                 } else {
-                    ANDI(x2, gd, 0xf);
-                    BEXT_(x4, ed, x2);
+                    ANDI(x2, gd, rex.w ? 0x3f : 0xf);
+                    SRL(x4, ed, x2);
+                    ANDI(x4, x4, 1);
                 }
-            } else {
-                ANDI(x2, gd, rex.w ? 0x3f : 0xf);
-                SRL(x4, ed, x2);
-                ANDI(x4, x4, 1);
+                ANDI(xFlags, xFlags, ~1);
+                OR(xFlags, xFlags, x4);
             }
-            ANDI(xFlags, xFlags, ~1);
-            OR(xFlags, xFlags, x4);
             ADDI(x4, xZR, 1);
             ANDI(x2, gd, rex.w ? 0x3f : 15);
             SLL(x4, x4, x2);