about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-08-11 14:56:13 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-08-11 14:56:13 +0200
commit730eb1f472d823201f65fab41c6880cd2462ec7d (patch)
treed192e68fce4f7b6e4f542d045d909dd808c2d112 /src
parent3760be946f98f1580d06f397f38b6f7f2c19147e (diff)
downloadbox64-730eb1f472d823201f65fab41c6880cd2462ec7d.tar.gz
box64-730eb1f472d823201f65fab41c6880cd2462ec7d.zip
[ARM64_DYNAREC] Some small improvments to ROR/ROL/RCR/RCL opcodes
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c20
-rw-r--r--src/dynarec/arm64/dynarec_arm64_64.c4
-rw-r--r--src/dynarec/arm64/dynarec_arm64_66.c12
-rw-r--r--src/dynarec/arm64/dynarec_arm64_67.c4
-rw-r--r--src/dynarec/arm64/dynarec_arm64_emit_shift.c106
5 files changed, 36 insertions, 110 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index 7d84cc76..0253a6a7 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -1933,7 +1933,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("ROL Eb, Ib");
                     u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
                     if(u8) {
-                        SETFLAGS(X_CF|X_OF, SF_SUBSET_PENDING);
+                        SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
                         GETEB(x1, 1);
                         u8 = F8&0x1f;
                         emit_rol8c(dyn, ninst, x1, u8, x4, x5);
@@ -1947,7 +1947,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("ROR Eb, Ib");
                     u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
                     if(u8) {
-                        SETFLAGS(X_CF|X_OF, SF_SUBSET_PENDING);
+                        SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
                         GETEB(x1, 1);
                         u8 = F8&0x1f;
                         emit_ror8c(dyn, ninst, x1, u8, x4, x5);
@@ -1962,7 +1962,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
                     if(u8) {
                         READFLAGS(X_CF);
-                        SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
+                        SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
                         GETEB(x1, 1);
                         u8 = F8&0x1f;
                         emit_rcl8c(dyn, ninst, x1, u8, x4, x5);
@@ -1977,7 +1977,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
                     if(u8) {
                         READFLAGS(X_CF);
-                        SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
+                        SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
                         GETEB(x1, 1);
                         u8 = F8&0x1f;
                         emit_rcr8c(dyn, ninst, x1, u8, x4, x5);
@@ -2039,7 +2039,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("ROL Ed, Ib");
                     u8 = geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20));
                     if(u8) {
-                        SETFLAGS(X_CF|X_OF, SF_SUBSET_PENDING);
+                        SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
                         GETED(1);
                         u8 = (F8)&(rex.w?0x3f:0x1f);
                         emit_rol32c(dyn, ninst, rex, ed, u8, x3, x4);
@@ -2058,7 +2058,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("ROR Ed, Ib");
                     u8 = geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20));
                     if(u8) {
-                        SETFLAGS(X_CF|X_OF, SF_SUBSET_PENDING);
+                        SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
                         GETED(1);
                         u8 = (F8)&(rex.w?0x3f:0x1f);
                         emit_ror32c(dyn, ninst, rex, ed, u8, x3, x4);
@@ -2470,14 +2470,14 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             switch((nextop>>3)&7) {
                 case 0:
                     INST_NAME("ROL Eb, 1");
-                    SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
+                    SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
                     GETEB(x1, 0);
                     emit_rol8c(dyn, ninst, ed, 1, x4, x5);
                     EBBACK;
                     break;
                 case 1:
                     INST_NAME("ROR Eb, 1");
-                    SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
+                    SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
                     GETEB(x1, 0);
                     emit_ror8c(dyn, ninst, ed, 1, x4, x5);
                     EBBACK;
@@ -2527,14 +2527,14 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             switch((nextop>>3)&7) {
                 case 0:
                     INST_NAME("ROL Ed, 1");
-                    SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
+                    SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
                     GETED(0);
                     emit_rol32c(dyn, ninst, rex, ed, 1, x3, x4);
                     WBACK;
                     break;
                 case 1:
                     INST_NAME("ROR Ed, 1");
-                    SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
+                    SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
                     GETED(0);
                     emit_ror32c(dyn, ninst, rex, ed, 1, x3, x4);
                     WBACK;
diff --git a/src/dynarec/arm64/dynarec_arm64_64.c b/src/dynarec/arm64/dynarec_arm64_64.c
index 18bb67a8..85b89e3a 100644
--- a/src/dynarec/arm64/dynarec_arm64_64.c
+++ b/src/dynarec/arm64/dynarec_arm64_64.c
@@ -797,14 +797,14 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             switch((nextop>>3)&7) {
                 case 0:
                     INST_NAME("ROL Ed, 1");
-                    SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
+                    SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
                     GETEDO(x6, 0);
                     emit_rol32c(dyn, ninst, rex, ed, 1, x3, x4);
                     WBACKO(x6);
                     break;
                 case 1:
                     INST_NAME("ROR Ed, 1");
-                    SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
+                    SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
                     GETEDO(x6, 0);
                     emit_ror32c(dyn, ninst, rex, ed, 1, x3, x4);
                     WBACKO(x6);
diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c
index d0e81c11..9c39182c 100644
--- a/src/dynarec/arm64/dynarec_arm64_66.c
+++ b/src/dynarec/arm64/dynarec_arm64_66.c
@@ -977,7 +977,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("ROL Ew, Ib");

                     u8 = geted_ib(dyn, addr, ninst, nextop) & 15;

                     if (u8) {

-                        SETFLAGS(X_CF | X_OF, SF_SUBSET_PENDING);

+                        SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose

                         GETEW(x1, 1);

                         u8 = (F8)&0x1f;

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

@@ -990,7 +990,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 1:

                     INST_NAME("ROR Ew, Ib");

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

-                        SETFLAGS(X_CF | X_OF, SF_SUBSET_PENDING);

+                        SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose

                         GETEW(x1, 1);

                         u8 = (F8)&0x1f;

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

@@ -1006,7 +1006,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         READFLAGS(X_CF);

                         SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose

                         GETEW(x1, 1);

-                        u8 = F8;

+                        u8 = (F8)&0x1f;

                         emit_rcl16c(dyn, ninst, ed, u8, x4, x5);

                         EWBACK;

                     } else {

@@ -1020,7 +1020,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         READFLAGS(X_CF);

                         SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose

                         GETEW(x1, 1);

-                        u8 = F8;

+                        u8 = (F8)&0x1f;

                         emit_rcr16c(dyn, ninst, ed, u8, x4, x5);

                         EWBACK;

                     } else {

@@ -1093,14 +1093,14 @@ 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");

-                    SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);

+                    SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose

                     GETEW(x1, 0);

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

                     EWBACK;

                     break;

                 case 1:

                     INST_NAME("ROR Ew, 1");

-                    SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);

+                    SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose

                     GETEW(x1, 0);

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

                     EWBACK;

diff --git a/src/dynarec/arm64/dynarec_arm64_67.c b/src/dynarec/arm64/dynarec_arm64_67.c
index a5ab323e..398de489 100644
--- a/src/dynarec/arm64/dynarec_arm64_67.c
+++ b/src/dynarec/arm64/dynarec_arm64_67.c
@@ -1050,7 +1050,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             switch((nextop>>3)&7) {

                 case 0:

                     INST_NAME("ROL Ed, Ib");

-                    SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);

+                    SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose

                     GETED32(1);

                     u8 = (F8)&(rex.w?0x3f:0x1f);

                     emit_rol32c(dyn, ninst, rex, ed, u8, x3, x4);

@@ -1058,7 +1058,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     break;

                 case 1:

                     INST_NAME("ROR Ed, Ib");

-                    SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);

+                    SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose

                     GETED32(1);

                     u8 = (F8)&(rex.w?0x3f:0x1f);

                     emit_ror32c(dyn, ninst, rex, ed, u8, x3, x4);

diff --git a/src/dynarec/arm64/dynarec_arm64_emit_shift.c b/src/dynarec/arm64/dynarec_arm64_emit_shift.c
index 5516a8ce..b7e710a7 100644
--- a/src/dynarec/arm64/dynarec_arm64_emit_shift.c
+++ b/src/dynarec/arm64/dynarec_arm64_emit_shift.c
@@ -804,23 +804,9 @@ void emit_rol32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
 
     if (!c) return;
 
-    IFX(X_PEND) {
-        MOV32w(s3, c);
-        STRxw_U12(s3, xEmu, offsetof(x64emu_t, op2));
-        SET_DF(s4, rex.w?d_rol64:d_rol32);
-    } else IFX(X_ALL) {
-        SET_DFNONE(s4);
-    }
-    if(!c) {
-        IFX(X_PEND) {
-            STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
-        }
-        return;
-    }
+    SET_DFNONE(s4);
+
     RORxw(s1, s1, (rex.w?64:32)-c);
-    IFX(X_PEND) {
-        STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
-    }
     IFX(X_CF) {
         BFIw(xFlags, s1, F_CF, 1);
     }
@@ -839,23 +825,9 @@ void emit_ror32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
 
     if (!c) return;
 
-    IFX(X_PEND) {
-        MOV32w(s3, c);
-        STRxw_U12(s3, xEmu, offsetof(x64emu_t, op2));
-        SET_DF(s4, rex.w?d_ror64:d_ror32);
-    } else IFX(X_ALL) {
-        SET_DFNONE(s4);
-    }
-    if(!c) {
-        IFX(X_PEND) {
-            STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
-        }
-        return;
-    }
+    SET_DFNONE(s4);
+
     RORxw(s1, s1, c);
-    IFX(X_PEND) {
-        STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
-    }
     IFX(X_CF) {
         BFXILxw(xFlags, s1, rex.w?63:31, 1);
     }
@@ -875,21 +847,13 @@ void emit_rol8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
 
     if (!c) return;
 
-    IFX(X_PEND) {
-        MOV32w(s3, c);
-        STRB_U12(s3, xEmu, offsetof(x64emu_t, op2));
-        SET_DF(s4, d_rol8);
-    } else IFX(X_ALL) {
-        SET_DFNONE(s4);
-    }
+    SET_DFNONE(s4);
+
     if(c&7) {
         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));
-    }
     IFX(X_CF) {
         BFIw(xFlags, s1, F_CF, 1);
     }
@@ -908,20 +872,12 @@ void emit_ror8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
 
     if (!c) return;
 
-    IFX(X_PEND) {
-        MOV32w(s3, c);
-        STRB_U12(s3, xEmu, offsetof(x64emu_t, op2));
-        SET_DF(s4, d_ror8);
-    } else IFX(X_ALL) {
-        SET_DFNONE(s4);
-    }
+    SET_DFNONE(s4);
+
     if(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));
-    }
     IFX(X_CF) {
         BFXILw(xFlags, s1, 7, 1);
     }
@@ -941,21 +897,13 @@ void emit_rol16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
 
     if (!c) return;
 
-    IFX(X_PEND) {
-        MOV32w(s3, c);
-        STRH_U12(s3, xEmu, offsetof(x64emu_t, op2));
-        SET_DF(s4, d_rol16);
-    } else IFX(X_ALL) {
-        SET_DFNONE(s4);
-    }
+    SET_DFNONE(s4);
+
     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));
-    }
     IFX(X_CF) {
         BFIw(xFlags, s1, F_CF, 1);
     }
@@ -974,20 +922,12 @@ void emit_ror16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
 
     if (!c) return;
 
-    IFX(X_PEND) {
-        MOV32w(s3, c);
-        STRH_U12(s3, xEmu, offsetof(x64emu_t, op2));
-        SET_DF(s4, d_ror16);
-    } else IFX(X_ALL) {
-        SET_DFNONE(s4);
-    }
+    SET_DFNONE(s4);
+
     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));
-    }
     IFX(X_CF) {
         BFXILw(xFlags, s1, 15, 1);
     }
@@ -1020,9 +960,6 @@ void emit_rcl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
     }
     ORRw_REG_LSL(s1, s1, s1, 9);    // insert s1 again
     LSRw_IMM(s1, s1, 9-c); // do the rcl
-    IFX(X_PEND) {
-        STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
-    }
     IFX(X_OF|X_CF) {
         IFX(X_CF) {
             BFIw(xFlags, s3, F_CF, 1);
@@ -1063,9 +1000,6 @@ void emit_rcr8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
             BFIw(xFlags, s3, F_OF, 1);
         }
     }
-    IFX(X_PEND) {
-        STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
-    }
 }
 
 // emit RCL16 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
@@ -1088,9 +1022,6 @@ void emit_rcl16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
     }
     ORRx_REG_LSL(s1, s1, s1, 17);    // insert s1 again
     LSRx_IMM(s1, s1, 17-c); // do the rcl
-    IFX(X_PEND) {
-        STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
-    }
     IFX(X_CF) {
         BFIw(xFlags, s3, F_CF, 1);
     }
@@ -1129,9 +1060,6 @@ void emit_rcr16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
             BFIw(xFlags, s3, F_OF, 1);
         }
     }
-    IFX(X_PEND) {
-        STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
-    }
 }
 
 // emit RCL32/RCL64 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
@@ -1139,6 +1067,8 @@ void emit_rcl32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
 {
     MAYUSE(s1); MAYUSE(s3); MAYUSE(s4);
 
+    if(!c) return;
+
     SET_DFNONE(s4);
 
     IFX(X_OF|X_CF) {
@@ -1152,9 +1082,6 @@ void emit_rcl32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
         BFIxw(s4, xFlags, c-1, 1);
         ORRxw_REG_LSR(s1, s4, s1, (rex.w?65:33)-c);
     }
-    IFX(X_PEND) {
-        STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
-    }
     IFX(X_CF) {
         BFIw(xFlags, s3, F_CF, 1);
     }
@@ -1170,6 +1097,8 @@ void emit_rcr32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
 {
     MAYUSE(s1); MAYUSE(s3); MAYUSE(s4);
 
+    if(!c) return;
+
     SET_DFNONE(s4);
 
     IFX(X_OF) {
@@ -1192,9 +1121,6 @@ void emit_rcr32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
     IFX(X_CF) {
         BFIw(wFlags, s3, 0, 1);
     }
-    IFX(X_PEND) {
-        STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
-    }
 }
 
 // emit SHRD32 instruction, from s1, fill s2 , constant c, store result in s1 using s3 and s4 as scratch