about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-02-03 12:18:44 +0100
committerptitSeb <sebastien.chev@gmail.com>2025-02-03 12:18:44 +0100
commit7c27085bd3784ac3863aa22085d193afc572d580 (patch)
tree941bcc2fae9fde9e893a91cede1b5325e7caa643 /src
parent53834f2b29e9dd5440ac1d5fe1a6ed2c34c955b9 (diff)
downloadbox64-7c27085bd3784ac3863aa22085d193afc572d580.tar.gz
box64-7c27085bd3784ac3863aa22085d193afc572d580.zip
[ARM64_DYNAREC] Optimized RCL Eb, CL opcode
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index 043bba52..1526e518 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -2806,15 +2806,44 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     break;
                 case 2:
                     INST_NAME("RCL Eb, CL");
-                    MESSAGE(LOG_DUMP, "Need Optimization (RCL Eb, CL)\n");
                     READFLAGS(X_CF);
+                    SETFLAGS(X_OF|X_CF, SF_SUBSET);
                     if(BOX64DRENV(dynarec_safeflags)>1)
                         MAYSETFLAGS();
-                    SETFLAGS(X_OF|X_CF, SF_SET_DF);
-                    ANDw_mask(x2, xRCX, 0, 0b00100);
+                    ANDw_mask(x2, xRCX, 0, 0b00100);  //mask=0x00000001f
+                    UFLAG_IF {
+                        UFLAG_DF(x2, d_none);
+                        CBZw_NEXT(x2);
+                    }
+                    // get CL % 9
+                    MOV32w(x3, 0x1c71c71c); // 0x100000000 / 9
+                    UMULL(x3, x3, x2);
+                    LSRx(x3, x3, 32);   // x3 = CL / 9
+                    MOV32w(x4, 9);
+                    MSUBw(x2, x3, x4, x2);  // CL mod 9
                     GETEB(x1, 0);
-                    CALL_(rcl8, x1, x3);
+                    BFIw(ed, xFlags, 8, 1); // insert CF
+                    ORRw_REG_LSL(ed, ed, ed, 9);    // insert rest of ed
+                    SUBw_REG(x2, x4, x2);
+                    CBZw_NEXT(x2);
+                    IFX(X_OF|X_CF) {
+                        SUBw_U12(x5, x2, 1);
+                        LSRw_REG(x5, ed, x5);   // keep the new CF in x5
+                    }
+                    LSRw_REG(ed, ed, x2);
                     EBBACK;
+                    UFLAG_IF {  // calculate flags directly
+                        IFX(X_OF) {
+                            SUBw_U12(x3, x2, 8);
+                            CBNZw_MARK(x3);
+                                EORw_REG_LSR(x2, x5, ed, 7);
+                                BFIw(xFlags, x2, F_OF, 1);
+                            MARK;
+                        }
+                        IFX(X_CF) {
+                            BFXILw(xFlags, x5, 0, 1);
+                        }
+                    }
                     break;
                 case 3:
                     INST_NAME("RCR Eb, CL");