about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-05-20 22:01:46 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-05-20 22:01:46 +0200
commit181457b69f4eda0c39bc1286359704acbcd077c2 (patch)
treeb08098e6bb49439307413107047f89ee016610d4 /src
parent0b6f543bbd0d6be332d0305abb96406dbfc879b0 (diff)
downloadbox64-181457b69f4eda0c39bc1286359704acbcd077c2.tar.gz
box64-181457b69f4eda0c39bc1286359704acbcd077c2.zip
[RV64_DYNAREC] Fixed some issue with shld/shrd emitter
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_emit_shift.c42
-rw-r--r--src/dynarec/rv64/rv64_emitter.h12
2 files changed, 29 insertions, 25 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_emit_shift.c b/src/dynarec/rv64/dynarec_rv64_emit_shift.c
index b6cc3855..8bda1867 100644
--- a/src/dynarec/rv64/dynarec_rv64_emit_shift.c
+++ b/src/dynarec/rv64/dynarec_rv64_emit_shift.c
@@ -1198,13 +1198,14 @@ void emit_shrd32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, uin
     SLLIxw(s1, s2, (rex.w?64:32)-c);
     OR(s1, s1, s3);
 
-    IFX(X_SF) {
-        BGE(s1, xZR, 8);
-        ORI(xFlags, xFlags, 1 << F_SF);
-    }
     if (!rex.w) {
         ZEROUP(s1);
     }
+    IFX(X_SF) {
+        SRLIxw(s3, s1, rex.w?63:31);
+        BEQZ(s3, 8);
+        ORI(xFlags, xFlags, 1 << F_SF);
+    }
     IFX(X_PEND) {
         SDxw(s1, xEmu, offsetof(x64emu_t, res));
     }
@@ -1331,13 +1332,14 @@ void emit_shld32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, uin
     SRLIxw(s1, s2, (rex.w?64:32)-c);
     OR(s1, s1, s3);
 
-    IFX(X_SF) {
-        BGE(s1, xZR, 8);
-        ORI(xFlags, xFlags, 1 << F_SF);
-    }
     if (!rex.w) {
         ZEROUP(s1);
     }
+    IFX(X_SF) {
+        SRLIxw(s3, s1, rex.w?63:31);
+        BEQZ(s3, 8);
+        ORI(xFlags, xFlags, 1 << F_SF);
+    }
     IFX(X_PEND) {
         SDxw(s1, xEmu, offsetof(x64emu_t, res));
     }
@@ -1372,14 +1374,14 @@ void emit_shrd32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int
         SET_DFNONE();
     }
     IFX(X_CF) {
-        SUB(s3, s5, 1);
+        SUBI(s3, s5, 1);
         SRA(s3, s1, s3);
         ANDI(s3, s3, 1); // LSB == F_CF
         OR(xFlags, xFlags, s3);
     }
     IFX(X_OF) {
         // Store current sign for later use.
-        SRLxw(s6, s1, rex.w ? 63 : 31);
+        SRLIxw(s6, s1, rex.w ? 63 : 31);
     }
     ADDI(s4, xZR, (rex.w ? 64 : 32));
     SUB(s4, s4, s5);
@@ -1390,13 +1392,14 @@ void emit_shrd32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int
     IFX(X_PEND) {
         SDxw(s1, xEmu, offsetof(x64emu_t, res));
     }
-    IFX(X_SF) {
-        BGE(s1, xZR, 8);
-        ORI(xFlags, xFlags, 1 << F_SF);
-    }
     if (!rex.w) {
         ZEROUP(s1);
     }
+    IFX(X_SF) {
+        SRLIxw(s3, s1, rex.w?63:31);
+        BEQZ(s3, 8);
+        ORI(xFlags, xFlags, 1 << F_SF);
+    }
     IFX(X_ZF) {
         BNEZ(s1, 8);
         ORI(xFlags, xFlags, 1 << F_ZF);
@@ -1435,7 +1438,7 @@ void emit_shld32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int
     }
     IFX(X_OF) {
         // Store current sign for later use.
-        SRLxw(s6, s1, rex.w ? 63 : 31);
+        SRLIxw(s6, s1, rex.w ? 63 : 31);
     }
     SLLxw(s4, s1, s5);
     SRLxw(s3, s2, s3);
@@ -1444,13 +1447,14 @@ void emit_shld32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int
     IFX(X_PEND) {
         SDxw(s1, xEmu, offsetof(x64emu_t, res));
     }
-    IFX(X_SF) {
-        BGE(s1, xZR, 8);
-        ORI(xFlags, xFlags, 1 << F_SF);
-    }
     if (!rex.w) {
         ZEROUP(s1);
     }
+    IFX(X_SF) {
+        SRLIxw(s3, s1, rex.w?63:31);
+        BEQZ(s3, 8);
+        ORI(xFlags, xFlags, 1 << F_SF);
+    }
     IFX(X_ZF) {
         BNEZ(s1, 8);
         ORI(xFlags, xFlags, 1 << F_ZF);
diff --git a/src/dynarec/rv64/rv64_emitter.h b/src/dynarec/rv64/rv64_emitter.h
index 720b0f62..8bdca605 100644
--- a/src/dynarec/rv64/rv64_emitter.h
+++ b/src/dynarec/rv64/rv64_emitter.h
@@ -487,12 +487,12 @@ f28–31  ft8–11  FP temporaries                  Caller
 // Shift Right Logical Immediate, 32-bit, sign-extended
 #define SRLIW(rd, rs1, imm5) EMIT(I_type(imm5, rs1, 0b101, rd, 0b0011011))
 // Shift Right Logical Immediate
-#define SRLIxw(rd, rs1, imm)      \
-    if (rex.w) {                  \
-        SRLI(rd, rs1, imm);       \
-    } else {                      \
-        SRLIW(rd, rs1, imm);      \
-        if (imm == 0) ZEROUP(rd); \
+#define SRLIxw(rd, rs1, imm)        \
+    if (rex.w) {                    \
+        SRLI(rd, rs1, imm);         \
+    } else {                        \
+        SRLIW(rd, rs1, imm);        \
+        if ((imm) == 0) ZEROUP(rd); \
     }
 // Shift Right Arithmetic Immediate, 32-bit, sign-extended
 #define SRAIW(rd, rs1, imm5) EMIT(I_type((imm5) | (0b0100000 << 5), rs1, 0b101, rd, 0b0011011))