about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-02-21 18:13:49 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-02-21 18:13:49 +0100
commitf09b541ab73dc7eb753a812c3fdd4d0cc17f7b02 (patch)
tree73e5115e5b7ab0ec320942882f9e6308653715d5 /src
parente71df7eb670a1d943a41b7c94f3fc3794bc927eb (diff)
downloadbox64-f09b541ab73dc7eb753a812c3fdd4d0cc17f7b02.tar.gz
box64-f09b541ab73dc7eb753a812c3fdd4d0cc17f7b02.zip
[ARM64_DYNAREC] Added RCR 8bits with constant optimisation, and fixed RCL 8bit with const
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c15
-rw-r--r--src/dynarec/arm64/dynarec_arm64_emit_shift.c57
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h2
-rw-r--r--src/emu/x64run_private.c15
4 files changed, 72 insertions, 17 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index a56e2aec..b9f31523 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -1883,15 +1883,13 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     break;
                 case 3:
                     INST_NAME("RCR Eb, Ib");
-                    MESSAGE(LOG_DUMP, "Need Optimization\n");
-                    READFLAGS(X_CF);
                     u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
                     if(u8) {
-                        SETFLAGS(X_OF|X_CF, SF_SET);
+                        READFLAGS(X_CF);
+                        SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
                         GETEB(x1, 1);
                         u8 = F8&0x1f;
-                        MOV32w(x2, u8);
-                        CALL_(rcr8, ed, x3);
+                        emit_rcr8c(dyn, ninst, x1, u8, x4, x5);
                         EBBACK;
                     } else {
                         FAKEED;
@@ -2317,6 +2315,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     break;
                 case 2:
                     INST_NAME("RCL Eb, 1");
+                    READFLAGS(X_CF);
                     SETFLAGS(X_OF|X_CF, SF_SUBSET);
                     GETEB(x1, 0);
                     emit_rcl8c(dyn, ninst, ed, 1, x4, x5);
@@ -2324,12 +2323,10 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     break;
                 case 3:
                     INST_NAME("RCR Eb, 1");
-                    MESSAGE(LOG_DUMP, "Need Optimization\n");
                     READFLAGS(X_CF);
-                    SETFLAGS(X_OF|X_CF, SF_SET);
-                    MOV32w(x2, 1);
+                    SETFLAGS(X_OF|X_CF, SF_SUBSET);
                     GETEB(x1, 0);
-                    CALL_(rcr8, x1, x3);
+                    emit_rcr8c(dyn, ninst, ed, 1, x4, x5);
                     EBBACK;
                     break;
                 case 4:
diff --git a/src/dynarec/arm64/dynarec_arm64_emit_shift.c b/src/dynarec/arm64/dynarec_arm64_emit_shift.c
index 0456359b..b8686477 100644
--- a/src/dynarec/arm64/dynarec_arm64_emit_shift.c
+++ b/src/dynarec/arm64/dynarec_arm64_emit_shift.c
@@ -976,34 +976,79 @@ void emit_ror16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
     }
 }
 
-// emit RcL8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
+// emit RCL8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
 void emit_rcl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
 {
     MAYUSE(s1); MAYUSE(s3); MAYUSE(s4);
     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_rol8);
+        SET_DF(s4, d_rcl8);
+    } else IFX(X_ALL) {
+        SET_DFNONE(s4);
+    }
+    BFIw(x1, xFlags, 8, 1); // insert cf
+    IFX(X_OF|X_CF) {
+        LSRw_IMM(x2, x1, 8-(c%9));
+    }
+    ORRw_REG_LSL(x1, x1, x1, 9);    // insert x1 again
+    if(c%9) {
+        LSRw_IMM(x1, x1, 9-(c%9)); // do the rcl
+    }
+    IFX(X_PEND) {
+        STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
+    }
+    IFX(X_OF|X_CF) {
+        BFIw(xFlags, x2, F_CF, 1);
+        IFX(X_OF) {
+            if(c==1) {
+                EORw_REG_LSR(x2, x2, x1, 7);
+                BFIw(xFlags, x2, F_OF, 1);
+            }
+        }
+    }
+}
+
+// emit RCR8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
+void emit_rcr8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
+{
+    MAYUSE(s1); MAYUSE(s3); MAYUSE(s4);
+    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_rcr8);
     } else IFX(X_ALL) {
         SET_DFNONE(s4);
     }
     IFX(X_OF|X_CF) {
         if(c%9) {
-            LSRw_IMM(x2, x1, 8-(c%9));
+            if((c%9)==1) {
+                MOVx_REG(x2, x1);
+            } else {
+                LSRw_IMM(x2, x1, (c%9)-1);
+            }
+        } else {
+            MOVw_REG(x2, xFlags);
         }
     }
     BFIw(x1, xFlags, 8, 1); // insert cf
     ORRw_REG_LSL(x1, x1, x1, 9);    // insert x1 again
-    LSRw_IMM(x1, x1, 9-(c%9)); // do the rcl
-    UXTBw(x1, x1);
+    if(c%9) {
+        LSRw_IMM(x1, x1, (c%9)); // do the rcr
+    }
+    IFX(X_PEND) {
+        STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
+    }
     IFX(X_OF|X_CF) {
-        BFIw(xFlags, x2, F_CF, 1);
         IFX(X_OF) {
             if(c==1) {
                 EORw_REG_LSR(x2, x2, x1, 7);
                 BFIw(xFlags, x2, F_OF, 1);
             }
         }
+        BFIw(xFlags, x2, F_CF, 1);
     }
 }
 
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index 902219c6..0fe4d252 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -1081,6 +1081,7 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr);
 #define emit_rol16c     STEPNAME(emit_rol16c)
 #define emit_ror16c     STEPNAME(emit_ror16c)
 #define emit_rcl8c      STEPNAME(emit_rcl8c)
+#define emit_rcr8c      STEPNAME(emit_rcr8c)
 #define emit_shrd32c    STEPNAME(emit_shrd32c)
 #define emit_shrd32     STEPNAME(emit_shrd32)
 #define emit_shld32c    STEPNAME(emit_shld32c)
@@ -1232,6 +1233,7 @@ void emit_ror8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
 void emit_rol16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4);
 void emit_ror16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4);
 void emit_rcl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4);
+void emit_rcr8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4);
 void emit_shrd32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint32_t c, int s3, int s4);
 void emit_shld32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint32_t c, int s3, int s4);
 void emit_shrd32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s5, int s3, int s4);
diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c
index 927d2d1c..5c88413e 100644
--- a/src/emu/x64run_private.c
+++ b/src/emu/x64run_private.c
@@ -1046,12 +1046,23 @@ void UpdateFlags(x64emu_t *emu)
             }
             CONDITIONAL_SET_FLAG(emu->res.u64 & (1L << 63), F_CF);
             break;
-
         case d_rcl8:
+            cnt = emu->op2.u8%9;
+            CONDITIONAL_SET_FLAG(emu->op1.u8>>(9-cnt) & 1, F_CF);
+            // should for cnt==1
+            CONDITIONAL_SET_FLAG(((emu->res.u8>>7) ^ ACCESS_FLAG(F_CF)) & 1, F_OF);
+            break;
+        case d_rcr8:
+            cnt = emu->op2.u8%9;
+            // should for cnt==1, using "before" CF
+            CONDITIONAL_SET_FLAG(((emu->res.u8>>7) ^ ACCESS_FLAG(F_CF)) & 1, F_OF);
+            // new CF
+            CONDITIONAL_SET_FLAG(((cnt==1)?emu->op1.u8:(emu->op1.u8>>(cnt-1))) & 1, F_CF);
+            break;
+
         case d_rcl16:
         case d_rcl32:
         case d_rcl64:
-        case d_rcr8:
         case d_rcr16:
         case d_rcr32:
         case d_rcr64: