about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-11-11 17:47:26 +0100
committerptitSeb <sebastien.chev@gmail.com>2023-11-11 17:47:26 +0100
commitcf6f01390912f1cbc0af8769fff16347971889ae (patch)
tree8f718563ff292da9c68a10c8338bb67c22c6d6f1 /src
parent2ed8557ea63399b199fadc4739a2eced35295fad (diff)
downloadbox64-cf6f01390912f1cbc0af8769fff16347971889ae.tar.gz
box64-cf6f01390912f1cbc0af8769fff16347971889ae.zip
[ARM64_DYNAREC] Added emit_shr8c and some mare adjustement to 8bits shifts
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c58
-rw-r--r--src/dynarec/arm64/dynarec_arm64_emit_shift.c56
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h2
-rw-r--r--src/emu/x64run_private.c10
4 files changed, 77 insertions, 49 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index d00c3229..cd312108 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -1735,21 +1735,21 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("ROL Eb, Ib");
                     if(geted_ib(dyn, addr, ninst, nextop)&0x1f) {
                         SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
+                        GETEB(x1, 1);
+                        u8 = F8;
+                        emit_rol8c(dyn, ninst, x1, u8&7, x4, x5);
+                        EBBACK;
                     }
-                    GETEB(x1, 1);
-                    u8 = F8;
-                    emit_rol8c(dyn, ninst, x1, u8&7, x4, x5);
-                    EBBACK;
                     break;
                 case 1:
                     INST_NAME("ROR Eb, Ib");
                     if(geted_ib(dyn, addr, ninst, nextop)&0x1f) {
                         SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
+                        GETEB(x1, 1);
+                        u8 = F8;
+                        emit_ror8c(dyn, ninst, x1, u8&7, x4, x5);
+                        EBBACK;
                     }
-                    GETEB(x1, 1);
-                    u8 = F8;
-                    emit_ror8c(dyn, ninst, x1, u8&7, x4, x5);
-                    EBBACK;
                     break;
                 case 2:
                     INST_NAME("RCL Eb, Ib");
@@ -1776,30 +1776,22 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 4:
                 case 6:
                     INST_NAME("SHL Eb, Ib");
-                    SETFLAGS(X_ALL, SF_SET_PENDING);    // some flags are left undefined
-                    GETEB(x1, 1);
-                    u8 = (F8)&0x1f;
-                    emit_shl8c(dyn, ninst, ed, u8, x3, x4);
-                    EBBACK;
+                    if(geted_ib(dyn, addr, ninst, nextop)&0x1f) {
+                        SETFLAGS(X_ALL, SF_SET_PENDING);    // some flags are left undefined
+                        GETEB(x1, 1);
+                        u8 = (F8)&0x1f;
+                        emit_shl8c(dyn, ninst, ed, u8, x3, x4);
+                        EBBACK;
+                    }
                     break;
                 case 5:
                     INST_NAME("SHR Eb, Ib");
-                    GETEB(x1, 1);
-                    u8 = (F8)&0x1f;
-                    if(u8) {
-                        SETFLAGS(X_ALL, SF_PENDING);
-                        UFLAG_IF{
-                            MOV32w(x4, u8); UFLAG_OP2(x4);
-                        };
-                        UFLAG_OP1(ed);
-                        if(u8) {
-                            LSRw(ed, ed, u8);
-                            EBBACK;
-                        }
-                        UFLAG_RES(ed);
-                        UFLAG_DF(x3, d_shr8);
-                    } else {
-                        NOP;
+                    if(geted_ib(dyn, addr, ninst, nextop)&0x1f) {
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
+                        GETEB(x1, 1);
+                        u8 = (F8)&0x1f;
+                        emit_shr8c(dyn, ninst, ed, u8, x3, x4);
+                        EBBACK;
                     }
                     break;
                 case 7:
@@ -2133,14 +2125,10 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     break;
                 case 5:
                     INST_NAME("SHR Eb, 1");
-                    MOV32w(x2, 1);
-                    SETFLAGS(X_ALL, SF_PENDING);
+                    SETFLAGS(X_ALL, SF_SET_PENDING);    // some flags are left undefined
                     GETEB(x1, 0);
-                    UFLAG_OP12(ed, x2);
-                    LSRw_REG(ed, ed, x2);
+                    emit_shr8c(dyn, ninst, ed, 1, x3, x4);
                     EBBACK;
-                    UFLAG_RES(ed);
-                    UFLAG_DF(x3, d_shr8);
                     break;
                 case 7:
                     INST_NAME("SAR Eb, 1");
diff --git a/src/dynarec/arm64/dynarec_arm64_emit_shift.c b/src/dynarec/arm64/dynarec_arm64_emit_shift.c
index 75caa99c..4e1a5b09 100644
--- a/src/dynarec/arm64/dynarec_arm64_emit_shift.c
+++ b/src/dynarec/arm64/dynarec_arm64_emit_shift.c
@@ -310,6 +310,8 @@ void emit_shl8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
 // emit SHL8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
 void emit_shl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
 {
+    if(!c)
+        return;
     IFX(X_PEND) {
         MOV32w(s3, c);
         STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
@@ -318,15 +320,6 @@ void emit_shl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
     } else IFX(X_ALL) {
         SET_DFNONE(s4);
     }
-    if(c==0) {
-        IFX(X_OF) {
-            BFCw(xFlags, F_OF, 1);
-        }
-        IFX(X_PEND) {
-            STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
-        }
-        return;
-    }
     IFX(X_CF|X_OF) {
         LSRw(s3, s1, 8-c);
         BFIw(xFlags, s3, F_CF, 1);
@@ -402,6 +395,51 @@ void emit_shr8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
     }
 }
 
+// emit SHR8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
+void emit_shr8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
+{
+    if(!c)
+        return;
+    IFX(X_PEND) {
+        MOV32w(s3, c);
+        STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
+        STRB_U12(s3, xEmu, offsetof(x64emu_t, op2));
+        SET_DF(s4, d_shr8);
+    } else IFX(X_ALL) {
+        SET_DFNONE(s4);
+    }
+    IFX(X_CF) {
+        if(c==1) {
+            BFIw(xFlags, s1, 0, 1);
+        } else {
+            LSRw(s3, s1, c-1);
+            BFIw(xFlags, s3, 0, 1);
+        }
+    }
+    IFX(X_OF) {
+        if(c==1) {
+            LSRw(s4, s1, 7);
+            BFIw(xFlags, s4, F_OF, 1);
+        }
+    }
+    LSRw(s1, s1, c);
+    IFX(X_PEND) {
+        STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
+    }
+    IFX(X_ZF) {
+        TSTw_mask(s1, 0, 7);
+        CSETw(s4, cEQ);
+        BFIw(xFlags, s4, F_ZF, 1);
+    }
+    IFX(X_SF) {
+        LSRw(s4, s1, 7);
+        BFIx(xFlags, s4, F_SF, 1);
+    }
+    IFX(X_PF) {
+        emit_pf(dyn, ninst, s1, s3, s4);
+    }
+}
+
 // emit ROL32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
 void emit_rol32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4)
 {
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index ac7ef7fd..2a420571 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -1026,6 +1026,7 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr);
 #define emit_shl8       STEPNAME(emit_shl8)
 #define emit_shl8c      STEPNAME(emit_shl8c)
 #define emit_shr8       STEPNAME(emit_shr8)
+#define emit_shr8c      STEPNAME(emit_shr8c)
 #define emit_rol32c     STEPNAME(emit_rol32c)
 #define emit_ror32c     STEPNAME(emit_ror32c)
 #define emit_rol8c      STEPNAME(emit_rol8c)
@@ -1162,6 +1163,7 @@ void emit_sar32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
 void emit_shl8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4);
 void emit_shl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4);
 void emit_shr8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4);
+void emit_shr8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4);
 void emit_rol32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4);
 void emit_ror32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4);
 void emit_rol8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4);
diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c
index ebae674d..a85495a9 100644
--- a/src/emu/x64run_private.c
+++ b/src/emu/x64run_private.c
@@ -457,11 +457,11 @@ void UpdateFlags(x64emu_t *emu)
                     CONDITIONAL_SET_FLAG((emu->res.u8 & 0xff) == 0, F_ZF);
                     CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF);
                     CONDITIONAL_SET_FLAG(PARITY(emu->res.u8 & 0xff), F_PF);
-                }
-                if (cnt == 1) {
-                    CONDITIONAL_SET_FLAG((((emu->res.u8 & 0x80) == 0x80) ^(ACCESS_FLAG(F_CF) != 0)), F_OF);
-                } else {
-                    CLEAR_FLAG(F_OF);
+                    if (cnt == 1) {
+                        CONDITIONAL_SET_FLAG((((emu->res.u8 & 0x80) == 0x80) ^(ACCESS_FLAG(F_CF) != 0)), F_OF);
+                    } else {
+                        CLEAR_FLAG(F_OF);
+                    }
                 }
             } else {
                 CONDITIONAL_SET_FLAG((emu->op1.u8 << (emu->op2.u8-1)) & 0x80, F_CF);