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 04:29:49 +0800
committerGitHub <noreply@github.com>2024-12-23 21:29:49 +0100
commit93cc31bc489c0a15ad7596e7a3386deb2a60eb50 (patch)
tree1adedaf0640dd1fee49e54b4d357c084b242c890 /src
parent13ee4acd59ddf1cf35666ee06c8ecff44b7bfb1a (diff)
downloadbox64-93cc31bc489c0a15ad7596e7a3386deb2a60eb50.tar.gz
box64-93cc31bc489c0a15ad7596e7a3386deb2a60eb50.zip
[LA64_DYNAREC] Fixed various issues in LBT path (#2197)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/la64/dynarec_la64_emit_logic.c1
-rw-r--r--src/dynarec/la64/dynarec_la64_emit_math.c73
-rw-r--r--src/dynarec/la64/dynarec_la64_emit_shift.c13
3 files changed, 39 insertions, 48 deletions
diff --git a/src/dynarec/la64/dynarec_la64_emit_logic.c b/src/dynarec/la64/dynarec_la64_emit_logic.c
index 17d232f0..a9ee3fa3 100644
--- a/src/dynarec/la64/dynarec_la64_emit_logic.c
+++ b/src/dynarec/la64/dynarec_la64_emit_logic.c
@@ -74,6 +74,7 @@ void emit_xor8c(dynarec_la64_t* dyn, int ninst, int s1, int32_t c, int s3, int s
             X64_XOR_B(s1, s3);
         }
         XORI(s1, s1, c & 0xff);
+        ANDI(s1, s1, 0xff);
         IFX (X_PEND)
             ST_B(s1, xEmu, offsetof(x64emu_t, res));
         return;
diff --git a/src/dynarec/la64/dynarec_la64_emit_math.c b/src/dynarec/la64/dynarec_la64_emit_math.c
index bcee5e81..df2e1d5d 100644
--- a/src/dynarec/la64/dynarec_la64_emit_math.c
+++ b/src/dynarec/la64/dynarec_la64_emit_math.c
@@ -142,20 +142,16 @@ void emit_add32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i
         if (!rex.w) { ZEROUP(s1); }
         return;
     }
-    IFX(X_PEND | X_AF | X_CF | X_OF)
-    {
+    IFX (X_PEND | X_AF | X_CF | X_OF) {
         MOV64xw(s2, c);
     } else if (la64_lbt) {
         MOV64xw(s2, c);
     }
-    IFX(X_PEND)
-    {
+    IFX (X_PEND) {
         SDxw(s1, xEmu, offsetof(x64emu_t, op1));
         SDxw(s2, xEmu, offsetof(x64emu_t, op2));
         SET_DF(s3, rex.w ? d_add64 : d_add32b);
-    }
-    else IFX(X_ALL)
-    {
+    } else IFX (X_ALL) {
         SET_DFNONE();
     }
 
@@ -169,14 +165,12 @@ void emit_add32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i
         ADDxw(s1, s1, s2);
         if (!rex.w) ZEROUP(s1);
 
-        IFX(X_PEND)
-            SDxw(s1, xEmu, offsetof(x64emu_t, res));
+        IFX (X_PEND) SDxw(s1, xEmu, offsetof(x64emu_t, res));
         return;
     }
 
     CLEAR_FLAGS(s3);
-    IFX(X_CF)
-    {
+    IFX (X_CF) {
         if (rex.w) {
             ZEROUP2(s5, s1);
             ZEROUP2(s4, s2);
@@ -198,8 +192,7 @@ void emit_add32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i
             ORI(xFlags, xFlags, 1 << F_CF);
         }
     }
-    IFX(X_AF | X_OF)
-    {
+    IFX (X_AF | X_OF) {
         OR(s3, s1, s2);  // s3 = op1 | op2
         AND(s4, s1, s2); // s4 = op1 & op2
     }
@@ -215,22 +208,18 @@ void emit_add32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i
         ADDxw(s1, s1, s2);
     }
 
-    IFX(X_PEND)
-    {
+    IFX (X_PEND) {
         SDxw(s1, xEmu, offsetof(x64emu_t, res));
     }
-    IFX(X_AF | X_OF)
-    {
+    IFX (X_AF | X_OF) {
         ANDN(s3, s3, s1); // s3 = ~res & (op1 | op2)
         OR(s3, s3, s4);   // cc = (~res & (op1 | op2)) | (op1 & op2)
-        IFX(X_AF)
-        {
+        IFX (X_AF) {
             ANDI(s4, s3, 0x08); // AF: cc & 0x08
             BEQZ(s4, 8);
             ORI(xFlags, xFlags, 1 << F_AF);
         }
-        IFX(X_OF)
-        {
+        IFX (X_OF) {
             SRLI_D(s3, s3, rex.w ? 62 : 30);
             SRLI_D(s4, s3, 1);
             XOR(s3, s3, s4);
@@ -239,20 +228,17 @@ void emit_add32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i
             ORI(xFlags, xFlags, 1 << F_OF);
         }
     }
-    IFX(X_SF)
-    {
+    IFX (X_SF) {
         BGE(s1, xZR, 8);
         ORI(xFlags, xFlags, 1 << F_SF);
     }
     if (!rex.w) {
         ZEROUP(s1);
     }
-    IFX(X_PF)
-    {
+    IFX (X_PF) {
         emit_pf(dyn, ninst, s1, s3, s4);
     }
-    IFX(X_ZF)
-    {
+    IFX (X_ZF) {
         BNEZ(s1, 8);
         ORI(xFlags, xFlags, 1 << F_ZF);
     }
@@ -274,6 +260,7 @@ void emit_add8(dynarec_la64_t* dyn, int ninst, int s1, int s2, int s3, int s4)
             X64_ADD_B(s1, s2);
         }
         ADD_D(s1, s1, s2);
+        ANDI(s1, s1, 0xff);
         IFX(X_PEND)
             ST_H(s1, xEmu, offsetof(x64emu_t, res));
         return;
@@ -344,7 +331,7 @@ void emit_add8c(dynarec_la64_t* dyn, int ninst, int s1, int c, int s2, int s3, i
             X64_ADD_B(s1, s4);
         }
         ADDI_D(s1, s1, c & 0xff);
-
+        ANDI(s1, s1, 0xff);
         IFX(X_PEND)
             ST_H(s1, xEmu, offsetof(x64emu_t, res));
         return;
@@ -494,7 +481,7 @@ void emit_sub8(dynarec_la64_t* dyn, int ninst, int s1, int s2, int s3, int s4, i
             X64_SUB_B(s1, s2);
         }
         SUB_D(s1, s1, s2);
-
+        ANDI(s1, s1, 0xff);
         IFX(X_PEND)
             ST_H(s1, xEmu, offsetof(x64emu_t, res));
         return;
@@ -558,7 +545,10 @@ void emit_sub16(dynarec_la64_t* dyn, int ninst, int s1, int s2, int s3, int s4,
         ST_H(s1, xEmu, offsetof(x64emu_t, res));
     }
 
-    if (la64_lbt) return;
+    if (la64_lbt) {
+        BSTRPICK_D(s1, s1, 15, 0);
+        return;
+    }
 
     CLEAR_FLAGS(s3);
     SLLI_D(s1, s1, 48);
@@ -730,7 +720,6 @@ void emit_sbb8(dynarec_la64_t* dyn, int ninst, int s1, int s2, int s3, int s4, i
         IFX (X_ALL) {
             X64_SBC_B(s1, s2);
         }
-
         ANDI(s1, s3, 0xff);
         IFX (X_PEND)
             ST_B(s1, xEmu, offsetof(x64emu_t, res));
@@ -786,7 +775,7 @@ void emit_sbb16(dynarec_la64_t* dyn, int ninst, int s1, int s2, int s3, int s4,
         SET_DFNONE();
     }
 
-    IFXA (X_ALL, la64_lbt) {
+    if (la64_lbt) {
         SBC_H(s3, s1, s2);
 
         IFX (X_ALL) {
@@ -852,8 +841,10 @@ void emit_sbb32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
             else
                 X64_SBC_W(s1, s2);
         }
-        MVxw(s1, s3);
-        if (!rex.w) ZEROUP(s1);
+        if (rex.w)
+            MV(s1, s3);
+        else
+            ZEROUP2(s1, s3);
         IFX (X_PEND)
             SDxw(s1, xEmu, offsetof(x64emu_t, res));
         return;
@@ -983,9 +974,7 @@ void emit_neg32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
     }
 
     if (la64_lbt) {
-        if (!rex.w) {
-            ZEROUP(s1);
-        }
+        if (!rex.w) ZEROUP(s1);
         return;
     }
 
@@ -1046,7 +1035,7 @@ void emit_adc8(dynarec_la64_t* dyn, int ninst, int s1, int s2, int s3, int s4, i
         IFX (X_ALL) {
             X64_ADC_B(s1, s2);
         }
-        MV(s1, s3);
+        ANDI(s1, s3, 0xff);
         IFX (X_PEND) {
             ST_W(s1, xEmu, offsetof(x64emu_t, res));
         }
@@ -1129,7 +1118,7 @@ void emit_adc16(dynarec_la64_t* dyn, int ninst, int s1, int s2, int s3, int s4,
         IFX (X_ALL) {
             X64_ADC_H(s1, s2);
         }
-        MV(s1, s3);
+        BSTRPICK_D(s1, s3, 15, 0);
         IFX (X_PEND) {
             ST_W(s1, xEmu, offsetof(x64emu_t, res));
         }
@@ -1211,8 +1200,10 @@ void emit_adc32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
             else
                 X64_ADC_W(s1, s2);
         }
-        MV(s1, s3);
-        if (!rex.w) ZEROUP(s1);
+        if (rex.w)
+            MV(s1, s3);
+        else
+            ZEROUP2(s1, s3);
         IFX (X_PEND) {
             SDxw(s1, xEmu, offsetof(x64emu_t, res));
         }
diff --git a/src/dynarec/la64/dynarec_la64_emit_shift.c b/src/dynarec/la64/dynarec_la64_emit_shift.c
index a032be16..c15c630c 100644
--- a/src/dynarec/la64/dynarec_la64_emit_shift.c
+++ b/src/dynarec/la64/dynarec_la64_emit_shift.c
@@ -277,7 +277,7 @@ void emit_shl32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
         }
 
         SLLIxw(s1, s1, c);
-
+        if (!rex.w) ZEROUP(s1);
         IFX(X_PEND) {
             SDxw(s1, xEmu, offsetof(x64emu_t, res));
         }
@@ -613,7 +613,7 @@ void emit_shr32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
         }
 
         SRLIxw(s1, s1, c);
-
+        if (!rex.w) ZEROUP(s1);
         IFX(X_PEND) {
             SDxw(s1, xEmu, offsetof(x64emu_t, res));
         }
@@ -821,7 +821,7 @@ void emit_sar32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
         }
 
         SRAIxw(s1, s1, c);
-
+        if (!rex.w) ZEROUP(s1);
         IFX(X_PEND) {
             SDxw(s1, xEmu, offsetof(x64emu_t, res));
         }
@@ -896,6 +896,7 @@ void emit_ror32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
     }
 
     ROTRIxw(s1, s1, c);
+    if (!rex.w) ZEROUP(s1);
 
     IFX (X_PEND) {
         SDxw(s1, xEmu, offsetof(x64emu_t, res));
@@ -928,7 +929,8 @@ void emit_ror32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
 void emit_rol32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4)
 {
     int64_t j64;
-
+    if (!rex.w) ZEROUP(s1);
+    BEQ_NEXT(s2, xZR);
     IFX (X_PEND) {
         SDxw(s2, xEmu, offsetof(x64emu_t, op2));
         SET_DF(s4, rex.w ? d_rol64 : d_rol32);
@@ -943,9 +945,6 @@ void emit_rol32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
             X64_ROTL_W(s1, s2);
     }
 
-    if (!rex.w) ZEROUP(s1);
-    BEQ_NEXT(s2, xZR);
-
     SLLxw(s3, s1, s2);
     NEG_D(s4, s2);
     ADDI_D(s4, s4, rex.w ? 64 : 32);