about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-04-17 22:43:59 +0800
committerGitHub <noreply@github.com>2024-04-17 16:43:59 +0200
commit8f5fa863bfc2ee7e51be39e86a856019eebb0589 (patch)
treeb8f97cabbc21f9845a80a3d82a7c04b584cd4485 /src
parentd4e32fdbc0a971ce5c6f2880b38df7789b9d64a5 (diff)
downloadbox64-8f5fa863bfc2ee7e51be39e86a856019eebb0589.tar.gz
box64-8f5fa863bfc2ee7e51be39e86a856019eebb0589.zip
[DYNAREC] Fixed CF flag computation (#1453)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/la64/dynarec_la64_emit_math.c10
-rw-r--r--src/dynarec/rv64/dynarec_rv64_emit_math.c24
2 files changed, 22 insertions, 12 deletions
diff --git a/src/dynarec/la64/dynarec_la64_emit_math.c b/src/dynarec/la64/dynarec_la64_emit_math.c
index 1884ea9e..23a2acf9 100644
--- a/src/dynarec/la64/dynarec_la64_emit_math.c
+++ b/src/dynarec/la64/dynarec_la64_emit_math.c
@@ -68,7 +68,9 @@ void emit_add32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
             BEQZ(s5, 8);
             ORI(xFlags, xFlags, 1 << F_CF);
         } else {
-            ADD_D(s5, s1, s2);
+            AND(s3, s1, xMASK);
+            AND(s4, s2, xMASK);
+            ADD_D(s5, s3, s4);
             SRLI_D(s5, s5, 0x20);
             BEQZ(s5, 8);
             ORI(xFlags, xFlags, 1 << F_CF);
@@ -184,7 +186,9 @@ void emit_add32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i
             BEQZ(s5, 8);
             ORI(xFlags, xFlags, 1 << F_CF);
         } else {
-            ADD_D(s5, s1, s2);
+            AND(s3, s1, xMASK);
+            AND(s4, s2, xMASK);
+            ADD_D(s5, s3, s4);
             SRLI_D(s5, s5, 0x20);
             BEQZ(s5, 8);
             ORI(xFlags, xFlags, 1 << F_CF);
@@ -903,4 +907,4 @@ void emit_neg32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
         BNEZ(s1, 8);
         ORI(xFlags, xFlags, 1 << F_ZF);
     }
-}
\ No newline at end of file
+}
diff --git a/src/dynarec/rv64/dynarec_rv64_emit_math.c b/src/dynarec/rv64/dynarec_rv64_emit_math.c
index 3664a8d9..f3f7dbea 100644
--- a/src/dynarec/rv64/dynarec_rv64_emit_math.c
+++ b/src/dynarec/rv64/dynarec_rv64_emit_math.c
@@ -45,7 +45,9 @@ void emit_add32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
             BEQZ(s5, 8);
             ORI(xFlags, xFlags, 1 << F_CF);
         } else {
-            ADD(s5, s1, s2);
+            AND(s3, s1, xMASK);
+            AND(s4, s2, xMASK);
+            ADD(s5, s3, s4);
             SRLI(s5, s5, 0x20);
             BEQZ(s5, 8);
             ORI(xFlags, xFlags, 1 << F_CF);
@@ -137,7 +139,9 @@ void emit_add32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i
             BEQZ(s5, 8);
             ORI(xFlags, xFlags, 1 << F_CF);
         } else {
-            ADD(s5, s1, s2);
+            AND(s3, s1, xMASK);
+            AND(s4, s2, xMASK);
+            ADD(s5, s3, s4);
             SRLI(s5, s5, 0x20);
             BEQZ(s5, 8);
             ORI(xFlags, xFlags, 1 << F_CF);
@@ -1145,7 +1149,7 @@ void emit_neg32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
         BEQZ(s1, 8);
         ORI(xFlags, xFlags, 1 << F_CF);
     }
-    
+
     IFX(X_AF | X_OF) {
         OR(s3, s1, s3); // s3 = res | op1
         IFX(X_AF) {
@@ -1162,7 +1166,7 @@ void emit_neg32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
             ANDI(s2, s2, 1);
             BEQZ(s2, 8);
             ORI(xFlags, xFlags, 1 << F_OF2);
-        }    
+        }
     }
     IFX(X_SF) {
         BGE(s1, xZR, 8);
@@ -1204,7 +1208,7 @@ void emit_neg16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3)
         BEQZ(s1, 8);
         ORI(xFlags, xFlags, 1 << F_CF);
     }
-    
+
     IFX(X_AF | X_OF) {
         OR(s3, s1, s3); // s3 = res | op1
         IFX(X_AF) {
@@ -1221,7 +1225,7 @@ void emit_neg16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3)
             ANDI(s2, s2, 1);
             BEQZ(s2, 8);
             ORI(xFlags, xFlags, 1 << F_OF2);
-        }    
+        }
     }
     IFX(X_SF) {
         SRLI(s3, s1, 15-F_SF);    // put sign bit in place
@@ -1261,7 +1265,7 @@ void emit_neg8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3)
         BEQZ(s1, 8);
         ORI(xFlags, xFlags, 1 << F_CF);
     }
-    
+
     IFX(X_AF | X_OF) {
         OR(s3, s1, s3); // s3 = res | op1
         IFX(X_AF) {
@@ -1278,7 +1282,7 @@ void emit_neg8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3)
             ANDI(s2, s2, 1);
             BEQZ(s2, 8);
             ORI(xFlags, xFlags, 1 << F_OF2);
-        }    
+        }
     }
     IFX(X_SF) {
         ANDI(s3, s1, 1 << F_SF);    // 1<<F_SF is sign bit, so just mask
@@ -1381,7 +1385,9 @@ void emit_adc32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
             ADD(s5, s5, s4); // hi
             SRAI(s6, s5, 0x20);
         } else {
-            ADD(s5, s1, s2);
+            AND(s3, s1, xMASK);
+            AND(s4, s2, xMASK);
+            ADD(s5, s3, s4);
             SRLI(s6, s5, 0x20);
         }
     }