about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-11-13 12:01:57 +0100
committerptitSeb <sebastien.chev@gmail.com>2023-11-13 12:01:57 +0100
commit590429d10456b346f56114563caac39dfb43c485 (patch)
treee9aa621c75309f66ae98215aef88720ba2b732f4 /src
parenteb0b5bd3f88077a052d234a7b0fe4a305f3f2ba6 (diff)
downloadbox64-590429d10456b346f56114563caac39dfb43c485.tar.gz
box64-590429d10456b346f56114563caac39dfb43c485.zip
[ARM64_DYNAREC] Optimized 16bits ROL/ROR opcodes
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_66.c84
-rw-r--r--src/dynarec/arm64/dynarec_arm64_emit_shift.c12
2 files changed, 60 insertions, 36 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c
index 258edfd5..4d58a850 100644
--- a/src/dynarec/arm64/dynarec_arm64_66.c
+++ b/src/dynarec/arm64/dynarec_arm64_66.c
@@ -931,21 +931,27 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("ROL Ew, Ib");

                     if(geted_ib(dyn, addr, ninst, nextop)&15) {

                         SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);

+                        GETEW(x1, 1);

+                        u8 = F8;

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

+                        EWBACK;

+                    } else {

+                        FAKEED;

+                        F8;

                     }

-                    GETEW(x1, 1);

-                    u8 = F8;

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

-                    EWBACK;

                     break;

                 case 1:

                     INST_NAME("ROR Ew, Ib");

                     if(geted_ib(dyn, addr, ninst, nextop)&15) {

                         SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);

+                        GETEW(x1, 1);

+                        u8 = F8;

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

+                        EWBACK;

+                    } else {

+                        FAKEED;

+                        F8;

                     }

-                    GETEW(x1, 1);

-                    u8 = F8;

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

-                    EWBACK;

                     break;

                 case 2:

                     INST_NAME("RCL Ew, Ib");

@@ -1034,20 +1040,16 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             switch((nextop>>3)&7) {

                 case 0:

                     INST_NAME("ROL Ew, 1");

-                    MOV32w(x2, 1);

-                    MESSAGE(LOG_DUMP, "Need Optimization\n");

-                    SETFLAGS(X_OF|X_CF, SF_SET);

+                    SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);

                     GETEW(x1, 0);

-                    CALL_(rol16, x1, x3);

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

                     EWBACK;

                     break;

                 case 1:

                     INST_NAME("ROR Ew, 1");

-                    MOV32w(x2, 1);

-                    MESSAGE(LOG_DUMP, "Need Optimization\n");

-                    SETFLAGS(X_OF|X_CF, SF_SET);

+                    SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);

                     GETEW(x1, 0);

-                    CALL_(ror16, x1, x3);

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

                     EWBACK;

                     break;

                 case 2:

@@ -1100,21 +1102,55 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             switch((nextop>>3)&7) {

                 case 0:

                     INST_NAME("ROL Ew, CL");

-                    ANDw_mask(x2, xRCX, 0, 0b00100);

-                    MESSAGE(LOG_DUMP, "Need Optimization\n");

-                    SETFLAGS(X_OF|X_CF, SF_SET);

+                    SETFLAGS(X_OF|X_CF, SF_SUBSET);

+                    if(box64_dynarec_safeflags>1)

+                        MAYSETFLAGS();

+                    UFLAG_IF {

+                        TSTw_mask(xRCX, 0, 0b00100);  //mask=0x00000001f

+                        B_NEXT(cEQ);

+                    }

+                    ANDw_mask(x2, xRCX, 0, 0b00011);  //mask=0x00000000f

+                    MOV32w(x4, 16);

+                    SUBx_REG(x2, x4, x2);

                     GETEW(x1, 0);

-                    CALL_(rol16, x1, x3);

+                    ORRw_REG_LSL(ed, ed, ed, 16);

+                    LSRw_REG(ed, ed, x2);

                     EWBACK;

+                    UFLAG_IF {  // calculate flags directly

+                        CMPSw_U12(x2, 15);

+                        B_MARK(cNE);

+                            LSRxw(x3, ed, 15);

+                            ADDxw_REG(x3, x3, ed);

+                            BFIw(xFlags, x3, F_OF, 1);

+                        MARK;

+                        BFIw(xFlags, ed, F_CF, 1);

+                        UFLAG_DF(x2, d_none);

+                    }

                     break;

                 case 1:

                     INST_NAME("ROR Ew, CL");

-                    ANDw_mask(x2, xRCX, 0, 0b00100);

-                    MESSAGE(LOG_DUMP, "Need Optimization\n");

-                    SETFLAGS(X_OF|X_CF, SF_SET);

+                    SETFLAGS(X_OF|X_CF, SF_SUBSET);

+                    if(box64_dynarec_safeflags>1)

+                        MAYSETFLAGS();

+                    UFLAG_IF {

+                        TSTw_mask(xRCX, 0, 0b00100);  //mask=0x00000001f

+                        B_NEXT(cEQ);

+                    }

+                    ANDw_mask(x2, xRCX, 0, 0b00011);  //mask=0x00000000f

                     GETEW(x1, 0);

-                    CALL_(ror16, x1, x3);

+                    ORRw_REG_LSL(ed, ed, ed, 16);

+                    LSRw_REG(ed, ed, x2);

                     EWBACK;

+                    UFLAG_IF {  // calculate flags directly

+                        CMPSw_U12(x2, 1);

+                        B_MARK(cNE);

+                            LSRxw(x2, ed, 14); // x2 = d>>14

+                            EORw_REG_LSR(x2, x2, x2, 1); // x2 = ((d>>14) ^ ((d>>14)>>1))

+                            BFIw(xFlags, x2, F_OF, 1);

+                        MARK;

+                        BFXILw(xFlags, ed, 15, 1);

+                        UFLAG_DF(x2, d_none);

+                    }

                     break;

                 case 2:

                     INST_NAME("RCL Ew, CL");

diff --git a/src/dynarec/arm64/dynarec_arm64_emit_shift.c b/src/dynarec/arm64/dynarec_arm64_emit_shift.c
index edb16a74..25b7fa54 100644
--- a/src/dynarec/arm64/dynarec_arm64_emit_shift.c
+++ b/src/dynarec/arm64/dynarec_arm64_emit_shift.c
@@ -953,12 +953,6 @@ void emit_rol16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
     } else IFX(X_ALL) {
         SET_DFNONE(s4);
     }
-    if(!c) {
-        IFX(X_PEND) {
-            STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
-        }
-        return;
-    }
     int rc = 16-(c&15);
     ORRw_REG_LSL(s1, s1, s1, 16);
     LSRw(s1, s1, rc);
@@ -987,12 +981,6 @@ void emit_ror16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
     } else IFX(X_ALL) {
         SET_DFNONE(s4);
     }
-    if(!c) {
-        IFX(X_PEND) {
-            STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
-        }
-        return;
-    }
     ORRw_REG_LSL(s1, s1, s1, 16);
     LSRw(s1, s1, c&15);
     IFX(X_PEND) {