about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-02-20 16:32:41 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-02-20 16:32:41 +0100
commitb40a17fc51802774e374ec2f678478ef30d6f10d (patch)
treec9ff6c586453cd2e406f2e380abb0bd9ba402b51 /src
parent02fadef9e700f7d0fc8fc91534e8e650f98af7b5 (diff)
downloadbox64-b40a17fc51802774e374ec2f678478ef30d6f10d.tar.gz
box64-b40a17fc51802774e374ec2f678478ef30d6f10d.zip
[ARM64_DYNAREC] Fixed some case of ROL/ROR 8/16bits not computing CF flag correctly
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c4
-rw-r--r--src/dynarec/arm64/dynarec_arm64_66.c4
-rw-r--r--src/dynarec/arm64/dynarec_arm64_emit_shift.c36
3 files changed, 20 insertions, 24 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index 6fe6fe4f..f6ab74a8 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -1845,7 +1845,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         SETFLAGS(X_CF|((u8==1)?X_OF:0), SF_SUBSET_PENDING);
                         GETEB(x1, 1);
                         u8 = F8;
-                        emit_rol8c(dyn, ninst, x1, u8&7, x4, x5);
+                        emit_rol8c(dyn, ninst, x1, u8, x4, x5);
                         EBBACK;
                     } else {
                         FAKEED;
@@ -1859,7 +1859,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         SETFLAGS(X_CF|((u8==1)?X_OF:0), SF_SUBSET_PENDING);
                         GETEB(x1, 1);
                         u8 = F8;
-                        emit_ror8c(dyn, ninst, x1, u8&7, x4, x5);
+                        emit_ror8c(dyn, ninst, x1, u8, x4, x5);
                         EBBACK;
                     } else {
                         FAKEED;
diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c
index cdbc9796..b59e832d 100644
--- a/src/dynarec/arm64/dynarec_arm64_66.c
+++ b/src/dynarec/arm64/dynarec_arm64_66.c
@@ -948,7 +948,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         SETFLAGS(X_CF|((u8==1)?X_OF:0), SF_SUBSET_PENDING);

                         GETEW(x1, 1);

                         u8 = F8;

-                        emit_rol16c(dyn, ninst, x1, u8&15, x4, x5);

+                        emit_rol16c(dyn, ninst, x1, u8, x4, x5);

                         EWBACK;

                     } else {

                         FAKEED;

@@ -962,7 +962,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         SETFLAGS(X_CF|((u8==1)?X_OF:0), SF_SUBSET_PENDING);

                         GETEW(x1, 1);

                         u8 = F8;

-                        emit_ror16c(dyn, ninst, x1, u8&15, x4, x5);

+                        emit_ror16c(dyn, ninst, x1, u8, x4, x5);

                         EWBACK;

                     } else {

                         FAKEED;

diff --git a/src/dynarec/arm64/dynarec_arm64_emit_shift.c b/src/dynarec/arm64/dynarec_arm64_emit_shift.c
index 3199a013..61e866c7 100644
--- a/src/dynarec/arm64/dynarec_arm64_emit_shift.c
+++ b/src/dynarec/arm64/dynarec_arm64_emit_shift.c
@@ -867,15 +867,11 @@ void emit_rol8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
     } else IFX(X_ALL) {
         SET_DFNONE(s4);
     }
-    if(!c) {
-        IFX(X_PEND) {
-            STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
-        }
-        return;
+    if(c&7) {
+        int rc = 8-(c&7);
+        ORRw_REG_LSL(s1, s1, s1, 8);
+        LSRw(s1, s1, rc);
     }
-    int rc = 8-(c&7);
-    ORRw_REG_LSL(s1, s1, s1, 8);
-    LSRw(s1, s1, rc);
     IFX(X_PEND) {
         STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
     }
@@ -901,14 +897,10 @@ void emit_ror8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
     } else IFX(X_ALL) {
         SET_DFNONE(s4);
     }
-    if(!c) {
-        IFX(X_PEND) {
-            STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
-        }
-        return;
+    if(c&7) {
+        ORRw_REG_LSL(s1, s1, s1, 8);
+        LSRw(s1, s1, c&7);
     }
-    ORRw_REG_LSL(s1, s1, s1, 8);
-    LSRw(s1, s1, c&7);
     IFX(X_PEND) {
         STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
     }
@@ -935,9 +927,11 @@ void emit_rol16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
     } else IFX(X_ALL) {
         SET_DFNONE(s4);
     }
-    int rc = 16-(c&15);
-    ORRw_REG_LSL(s1, s1, s1, 16);
-    LSRw(s1, s1, rc);
+    if(c&15) {
+        int rc = 16-(c&15);
+        ORRw_REG_LSL(s1, s1, s1, 16);
+        LSRw(s1, s1, rc);
+    }
     IFX(X_PEND) {
         STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
     }
@@ -963,8 +957,10 @@ void emit_ror16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
     } else IFX(X_ALL) {
         SET_DFNONE(s4);
     }
-    ORRw_REG_LSL(s1, s1, s1, 16);
-    LSRw(s1, s1, c&15);
+    if(c&15) {
+        ORRw_REG_LSL(s1, s1, s1, 16);
+        LSRw(s1, s1, c&15);
+    }
     IFX(X_PEND) {
         STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
     }