about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-04-26 02:17:36 +0800
committerGitHub <noreply@github.com>2024-04-25 20:17:36 +0200
commit1c040117ec8412fdbc1737b90af0a289f7051e40 (patch)
tree7a5bd2c245d3aaf96136e8aa6261db5cc2f13f95 /src
parent856d2653bce9d70c6b45016e12ab150ac45eb2b4 (diff)
downloadbox64-1c040117ec8412fdbc1737b90af0a289f7051e40.tar.gz
box64-1c040117ec8412fdbc1737b90af0a289f7051e40.zip
[DYNAREC] Fixed emit_shift functions and more (#1466)
* [LA64_DYNAREC] Fixed emit_shift functions

* [RV64_DYNAREC] Fixed emit_shift functions and more

* Fixed la64 build
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/la64/dynarec_la64_emit_shift.c24
-rw-r--r--src/dynarec/rv64/dynarec_rv64_emit_shift.c26
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f0.c2
3 files changed, 38 insertions, 14 deletions
diff --git a/src/dynarec/la64/dynarec_la64_emit_shift.c b/src/dynarec/la64/dynarec_la64_emit_shift.c
index f5a3b213..aa528b34 100644
--- a/src/dynarec/la64/dynarec_la64_emit_shift.c
+++ b/src/dynarec/la64/dynarec_la64_emit_shift.c
@@ -118,7 +118,6 @@ 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));
         }
@@ -136,7 +135,11 @@ void emit_shl32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
         }
     }
 
-    SLLIxw(s1, s1, c);
+    if (rex.w) {
+        SLLI_D(s1, s1, c);
+    } else {
+        SLLI_W(s1, s1, c);
+    }
 
     IFX(X_SF) {
         BGE(s1, xZR, 8);
@@ -293,7 +296,11 @@ void emit_shr32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
         }
     }
 
-    SRLIxw(s1, s1, c);
+    if (rex.w) {
+        SRLI_D(s1, s1, c);
+    } else {
+        SRLI_W(s1, s1, c);
+    }
 
     IFX(X_SF) {
         BGE(s1, xZR, 8);
@@ -346,7 +353,6 @@ 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));
@@ -366,9 +372,13 @@ void emit_sar32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
         OR(xFlags, xFlags, s3);
     }
 
-    SRAIxw(s1, s1, c);
+    if (rex.w) {
+        SRAI_D(s1, s1, c);
+    } else {
+        SRAI_W(s1, s1, c);
+    }
 
-    // SRAIW sign-extends, so test sign bit before clearing upper bits
+    // SRAI_W sign-extends, so test sign bit before clearing upper bits
     IFX(X_SF) {
         BGE(s1, xZR, 8);
         ORI(xFlags, xFlags, 1 << F_SF);
@@ -419,8 +429,6 @@ 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));
     }
diff --git a/src/dynarec/rv64/dynarec_rv64_emit_shift.c b/src/dynarec/rv64/dynarec_rv64_emit_shift.c
index a4bd4e19..3349ccd4 100644
--- a/src/dynarec/rv64/dynarec_rv64_emit_shift.c
+++ b/src/dynarec/rv64/dynarec_rv64_emit_shift.c
@@ -674,7 +674,11 @@ void emit_shl32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
         }
     }
 
-    SLLxw(s1, s1, s2);
+    if (rex.w) {
+        SLL(s1, s1, s2);
+    } else {
+        SLLW(s1, s1, s2);
+    }
 
     IFX(X_SF) {
         BGE(s1, xZR, 8);
@@ -730,7 +734,11 @@ void emit_shl32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
         }
     }
 
-    SLLIxw(s1, s1, c);
+    if (rex.w) {
+        SLLI(s1, s1, c);
+    } else {
+        SLLIW(s1, s1, c);
+    }
 
     IFX(X_SF) {
         BGE(s1, xZR, 8);
@@ -855,13 +863,17 @@ void emit_shr32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
         }
     }
 
-    SRLIxw(s1, s1, c);
+    if (rex.w) {
+        SRLI(s1, s1, c);
+    } else {
+        SRLIW(s1, s1, c);
+    }
 
     IFX(X_SF) {
         BGE(s1, xZR, 8);
         ORI(xFlags, xFlags, 1 << F_SF);
     }
-    if (!rex.w) {
+    if (!rex.w && c == 0) {
         ZEROUP(s1);
     }
     IFX(X_PEND) {
@@ -910,7 +922,11 @@ void emit_sar32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
         OR(xFlags, xFlags, s3);
     }
 
-    SRAIxw(s1, s1, c);
+    if (rex.w) {
+        SRAI(s1, s1, c);
+    } else {
+        SRAIW(s1, s1, c);
+    }
 
     // SRAIW sign-extends, so test sign bit before clearing upper bits
     IFX(X_SF) {
diff --git a/src/dynarec/rv64/dynarec_rv64_f0.c b/src/dynarec/rv64/dynarec_rv64_f0.c
index a9f842f6..5b61d340 100644
--- a/src/dynarec/rv64/dynarec_rv64_f0.c
+++ b/src/dynarec/rv64/dynarec_rv64_f0.c
@@ -782,7 +782,7 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         SCxw(x3, x4, wback, 1, 1);
                         BNEZ_MARKLOCK(x3);
                         IFX(X_ALL|X_PEND)
-                            emit_inc32(dyn, ninst, rex, x1, x3, x4, x5, x6);
+                            emit_dec32(dyn, ninst, rex, x1, x3, x4, x5, x6);
                     }
                     break;
                 default: