about summary refs log tree commit diff stats
path: root/src/dynarec
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-05-20 21:06:42 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-05-20 21:06:42 +0200
commit0b6f543bbd0d6be332d0305abb96406dbfc879b0 (patch)
treef8afb0e77879b27e1568a19c53caa566da08f16d /src/dynarec
parent01a386445c82ef2009ef0c527352dceb6d0281d1 (diff)
downloadbox64-0b6f543bbd0d6be332d0305abb96406dbfc879b0.tar.gz
box64-0b6f543bbd0d6be332d0305abb96406dbfc879b0.zip
[RV64_DYNAREC] Fixed some rotation emiters
Diffstat (limited to 'src/dynarec')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_3.c14
-rw-r--r--src/dynarec/rv64/dynarec_rv64_66.c10
-rw-r--r--src/dynarec/rv64/dynarec_rv64_emit_shift.c40
3 files changed, 38 insertions, 26 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00_3.c b/src/dynarec/rv64/dynarec_rv64_00_3.c
index d3593b6e..3cf4bcd9 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_3.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_3.c
@@ -490,10 +490,9 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                         MOV32w(x2, 1);
                     } else {
                         INST_NAME("ROL Eb, CL");
-                        ANDI(x2, xRCX, 7);
+                        ANDI(x2, xRCX, 0x1f);
                     }
                     MESSAGE(LOG_DUMP, "Need Optimization\n");
-                    READFLAGS(X_CF);
                     SETFLAGS(X_OF|X_CF, SF_SET_DF);
                     GETEB(x1, 0);
                     CALL_(rol8, ed, x3);
@@ -505,10 +504,9 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                         MOV32w(x2, 1);
                     } else {
                         INST_NAME("ROR Eb, CL");
-                        ANDI(x2, xRCX, 7);
+                        ANDI(x2, xRCX, 0x1f);
                     }
                     MESSAGE(LOG_DUMP, "Need Optimization\n");
-                    READFLAGS(X_CF);
                     SETFLAGS(X_OF|X_CF, SF_SET_DF);
                     GETEB(x1, 0);
                     CALL_(ror8, ed, x3);
@@ -520,7 +518,7 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                         MOV32w(x2, 1);
                     } else {
                         INST_NAME("RCL Eb, CL");
-                        ANDI(x2, xRCX, 7);
+                        ANDI(x2, xRCX, 0x1f);
                     }
                     MESSAGE(LOG_DUMP, "Need Optimization\n");
                     READFLAGS(X_CF);
@@ -535,7 +533,7 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                         MOV32w(x2, 1);
                     } else {
                         INST_NAME("RCR Eb, CL");
-                        ANDI(x2, xRCX, 7);
+                        ANDI(x2, xRCX, 0x1f);
                     }
                     MESSAGE(LOG_DUMP, "Need Optimization\n");
                     READFLAGS(X_CF);
@@ -625,6 +623,7 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                     GETEDW(x4, x1, 0);
                     CALL_(rex.w ? ((void*)rcl64) : ((void*)rcl32), ed, x4);
                     WBACK;
+                    if(!wback && !rex.w) ZEROUP(ed);
                     break;
                 case 3:
                     INST_NAME("RCR Ed, 1");
@@ -635,6 +634,7 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                     GETEDW(x4, x1, 0);
                     CALL_(rex.w?((void*)rcr64):((void*)rcr32), ed, x4);
                     WBACK;
+                    if(!wback && !rex.w) ZEROUP(ed);
                     break;
                 case 4:
                 case 6:
@@ -691,6 +691,7 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                     GETEDW(x4, x1, 0);
                     CALL_(rex.w ? ((void*)rcl64) : ((void*)rcl32), ed, x4);
                     WBACK;
+                    if(!wback && !rex.w) ZEROUP(ed);
                     break;
                 case 3:
                     INST_NAME("RCR Ed, CL");
@@ -701,6 +702,7 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                     GETEDW(x4, x1, 0);
                     CALL_(rex.w?((void*)rcr64):((void*)rcr32), ed, x4);
                     WBACK;
+                    if(!wback && !rex.w) ZEROUP(ed);
                     break;
                 case 4:
                 case 6:
diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c
index 0e13192b..d7183e1b 100644
--- a/src/dynarec/rv64/dynarec_rv64_66.c
+++ b/src/dynarec/rv64/dynarec_rv64_66.c
@@ -1012,7 +1012,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         MOV32w(x2, 1);
                     } else {
                         INST_NAME("ROL Ew, CL");
-                        ANDI(x2, xRCX, 15);
+                        ANDI(x2, xRCX, 0x1f);
                     }
                     MESSAGE(LOG_DUMP, "Need Optimization\n");
                     SETFLAGS(X_OF|X_CF, SF_SET_DF);
@@ -1026,7 +1026,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         MOV32w(x2, 1);
                     } else {
                         INST_NAME("ROR Ew, CL");
-                        ANDI(x2, xRCX, 15);
+                        ANDI(x2, xRCX, 0x1f);
                     }
                     MESSAGE(LOG_DUMP, "Need Optimization\n");
                     SETFLAGS(X_OF|X_CF, SF_SET_DF);
@@ -1040,7 +1040,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         MOV32w(x2, 1);
                     } else {
                         INST_NAME("RCL Ew, CL");
-                        ANDI(x2, xRCX, 15);
+                        ANDI(x2, xRCX, 0x1f);
                     }
                     MESSAGE("LOG_DUMP", "Need optimization\n");
                     READFLAGS(X_CF);
@@ -1048,13 +1048,14 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     GETEW(x1, 1);
                     CALL_(rcl16, x1, x3);
                     EWBACK;
+                    break;
                 case 3:
                     if(opcode==0xD1) {
                         INST_NAME("RCR Ew, 1");
                         MOV32w(x2, 1);
                     } else {
                         INST_NAME("RCR Ew, CL");
-                        ANDI(x2, xRCX, 15);
+                        ANDI(x2, xRCX, 0x1f);
                     }
                     MESSAGE("LOG_DUMP", "Need optimization\n");
                     READFLAGS(X_CF);
@@ -1062,6 +1063,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     GETEW(x1, 1);
                     CALL_(rcr16, x1, x3);
                     EWBACK;
+                    break;
                 case 5:
                     if(opcode==0xD1) {
                         INST_NAME("SHR Ew, 1");
diff --git a/src/dynarec/rv64/dynarec_rv64_emit_shift.c b/src/dynarec/rv64/dynarec_rv64_emit_shift.c
index fc7fa1d1..b6cc3855 100644
--- a/src/dynarec/rv64/dynarec_rv64_emit_shift.c
+++ b/src/dynarec/rv64/dynarec_rv64_emit_shift.c
@@ -952,10 +952,16 @@ void emit_sar32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
 void emit_rol32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4)
 {
     int64_t j64;
-    IFX(X_CF | X_OF) {
-        ANDI(xFlags, xFlags, ~(1UL<<F_CF | 1UL<<F_OF2));
-    }
 
+    if(rex.w) {
+        ANDI(s4, s2, 0x3f);
+    } else {
+        ANDI(s4, s2, 0x1f);
+    }
+    if (!rex.w) {
+        ZEROUP(s1);
+    }
+    BEQ_NEXT(s4, xZR);
     IFX(X_PEND) {
         SDxw(s2, xEmu, offsetof(x64emu_t, op2));
         SET_DF(s4, rex.w?d_rol64:d_rol32);
@@ -963,11 +969,6 @@ void emit_rol32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
         SET_DFNONE();
     }
 
-    if(rex.w) {
-        ANDI(s4, s2, 0x3f);
-    } else {
-        ANDI(s4, s2, 0x1f);
-    }
     if(rv64_zbb) {
         ROLxw(s1, s1, s4);
     } else {
@@ -981,6 +982,9 @@ void emit_rol32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
         SDxw(s1, xEmu, offsetof(x64emu_t, res));
     }
     IFX(X_CF | X_OF) {
+        ANDI(xFlags, xFlags, ~((1UL<<F_CF) | (1UL<<F_OF2)));
+    }
+    IFX(X_CF | X_OF) {
         ANDI(s4, s1, 1); // LSB == F_CF
         IFX(X_CF) OR(xFlags, xFlags, s4);
     }
@@ -999,10 +1003,16 @@ void emit_rol32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
 void emit_ror32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4)
 {
     int64_t j64;
-    IFX(X_CF | X_OF) {
-        ANDI(xFlags, xFlags, ~(1UL<<F_CF | 1UL<<F_OF2));
-    }
 
+    if(rex.w) {
+        ANDI(s4, s2, 0x3f);
+    } else {
+        ANDI(s4, s2, 0x1f);
+    }
+    if (!rex.w) {
+        ZEROUP(s1);
+    }
+    BEQ_NEXT(s4, xZR);
     IFX(X_PEND) {
         SDxw(s2, xEmu, offsetof(x64emu_t, op2));
         SET_DF(s4, rex.w?d_ror64:d_ror32);
@@ -1010,11 +1020,6 @@ void emit_ror32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
         SET_DFNONE();
     }
 
-    if(rex.w) {
-        ANDI(s4, s2, 0x3f);
-    } else {
-        ANDI(s4, s2, 0x1f);
-    }
     if(rv64_zbb) {
         RORxw(s1, s1, s4);
     } else {
@@ -1027,6 +1032,9 @@ void emit_ror32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
     IFX(X_PEND) {
         SDxw(s1, xEmu, offsetof(x64emu_t, res));
     }
+    IFX(X_CF | X_OF) {
+        ANDI(xFlags, xFlags, ~(1UL<<F_CF | 1UL<<F_OF2));
+    }
     IFX(X_CF) {
         SRLIxw(s3, s1, rex.w?63:31);
         OR(xFlags, xFlags, s3);