diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-08-11 14:56:13 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-08-11 14:56:13 +0200 |
| commit | 730eb1f472d823201f65fab41c6880cd2462ec7d (patch) | |
| tree | d192e68fce4f7b6e4f542d045d909dd808c2d112 /src | |
| parent | 3760be946f98f1580d06f397f38b6f7f2c19147e (diff) | |
| download | box64-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.c | 20 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_64.c | 4 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_66.c | 12 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_67.c | 4 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_emit_shift.c | 106 |
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 |