diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-11-11 17:47:26 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-11-11 17:47:26 +0100 |
| commit | cf6f01390912f1cbc0af8769fff16347971889ae (patch) | |
| tree | 8f718563ff292da9c68a10c8338bb67c22c6d6f1 /src | |
| parent | 2ed8557ea63399b199fadc4739a2eced35295fad (diff) | |
| download | box64-cf6f01390912f1cbc0af8769fff16347971889ae.tar.gz box64-cf6f01390912f1cbc0af8769fff16347971889ae.zip | |
[ARM64_DYNAREC] Added emit_shr8c and some mare adjustement to 8bits shifts
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_00.c | 58 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_emit_shift.c | 56 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.h | 2 | ||||
| -rw-r--r-- | src/emu/x64run_private.c | 10 |
4 files changed, 77 insertions, 49 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index d00c3229..cd312108 100644 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -1735,21 +1735,21 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("ROL Eb, Ib"); if(geted_ib(dyn, addr, ninst, nextop)&0x1f) { SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING); + GETEB(x1, 1); + u8 = F8; + emit_rol8c(dyn, ninst, x1, u8&7, x4, x5); + EBBACK; } - GETEB(x1, 1); - u8 = F8; - emit_rol8c(dyn, ninst, x1, u8&7, x4, x5); - EBBACK; break; case 1: INST_NAME("ROR Eb, Ib"); if(geted_ib(dyn, addr, ninst, nextop)&0x1f) { SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING); + GETEB(x1, 1); + u8 = F8; + emit_ror8c(dyn, ninst, x1, u8&7, x4, x5); + EBBACK; } - GETEB(x1, 1); - u8 = F8; - emit_ror8c(dyn, ninst, x1, u8&7, x4, x5); - EBBACK; break; case 2: INST_NAME("RCL Eb, Ib"); @@ -1776,30 +1776,22 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 4: case 6: INST_NAME("SHL Eb, Ib"); - SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined - GETEB(x1, 1); - u8 = (F8)&0x1f; - emit_shl8c(dyn, ninst, ed, u8, x3, x4); - EBBACK; + if(geted_ib(dyn, addr, ninst, nextop)&0x1f) { + SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined + GETEB(x1, 1); + u8 = (F8)&0x1f; + emit_shl8c(dyn, ninst, ed, u8, x3, x4); + EBBACK; + } break; case 5: INST_NAME("SHR Eb, Ib"); - GETEB(x1, 1); - u8 = (F8)&0x1f; - if(u8) { - SETFLAGS(X_ALL, SF_PENDING); - UFLAG_IF{ - MOV32w(x4, u8); UFLAG_OP2(x4); - }; - UFLAG_OP1(ed); - if(u8) { - LSRw(ed, ed, u8); - EBBACK; - } - UFLAG_RES(ed); - UFLAG_DF(x3, d_shr8); - } else { - NOP; + if(geted_ib(dyn, addr, ninst, nextop)&0x1f) { + SETFLAGS(X_ALL, SF_SET_PENDING); + GETEB(x1, 1); + u8 = (F8)&0x1f; + emit_shr8c(dyn, ninst, ed, u8, x3, x4); + EBBACK; } break; case 7: @@ -2133,14 +2125,10 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 5: INST_NAME("SHR Eb, 1"); - MOV32w(x2, 1); - SETFLAGS(X_ALL, SF_PENDING); + SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined GETEB(x1, 0); - UFLAG_OP12(ed, x2); - LSRw_REG(ed, ed, x2); + emit_shr8c(dyn, ninst, ed, 1, x3, x4); EBBACK; - UFLAG_RES(ed); - UFLAG_DF(x3, d_shr8); break; case 7: INST_NAME("SAR Eb, 1"); diff --git a/src/dynarec/arm64/dynarec_arm64_emit_shift.c b/src/dynarec/arm64/dynarec_arm64_emit_shift.c index 75caa99c..4e1a5b09 100644 --- a/src/dynarec/arm64/dynarec_arm64_emit_shift.c +++ b/src/dynarec/arm64/dynarec_arm64_emit_shift.c @@ -310,6 +310,8 @@ void emit_shl8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) // emit SHL8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch void emit_shl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4) { + if(!c) + return; IFX(X_PEND) { MOV32w(s3, c); STRB_U12(s1, xEmu, offsetof(x64emu_t, op1)); @@ -318,15 +320,6 @@ void emit_shl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s } else IFX(X_ALL) { SET_DFNONE(s4); } - if(c==0) { - IFX(X_OF) { - BFCw(xFlags, F_OF, 1); - } - IFX(X_PEND) { - STRB_U12(s1, xEmu, offsetof(x64emu_t, res)); - } - return; - } IFX(X_CF|X_OF) { LSRw(s3, s1, 8-c); BFIw(xFlags, s3, F_CF, 1); @@ -402,6 +395,51 @@ void emit_shr8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) } } +// emit SHR8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch +void emit_shr8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4) +{ + if(!c) + return; + 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_shr8); + } else IFX(X_ALL) { + SET_DFNONE(s4); + } + IFX(X_CF) { + if(c==1) { + BFIw(xFlags, s1, 0, 1); + } else { + LSRw(s3, s1, c-1); + BFIw(xFlags, s3, 0, 1); + } + } + IFX(X_OF) { + if(c==1) { + LSRw(s4, s1, 7); + BFIw(xFlags, s4, F_OF, 1); + } + } + LSRw(s1, s1, c); + IFX(X_PEND) { + STRB_U12(s1, xEmu, offsetof(x64emu_t, res)); + } + IFX(X_ZF) { + TSTw_mask(s1, 0, 7); + CSETw(s4, cEQ); + BFIw(xFlags, s4, F_ZF, 1); + } + IFX(X_SF) { + LSRw(s4, s1, 7); + BFIx(xFlags, s4, F_SF, 1); + } + IFX(X_PF) { + emit_pf(dyn, ninst, s1, s3, s4); + } +} + // emit ROL32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch void emit_rol32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4) { diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h index ac7ef7fd..2a420571 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -1026,6 +1026,7 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr); #define emit_shl8 STEPNAME(emit_shl8) #define emit_shl8c STEPNAME(emit_shl8c) #define emit_shr8 STEPNAME(emit_shr8) +#define emit_shr8c STEPNAME(emit_shr8c) #define emit_rol32c STEPNAME(emit_rol32c) #define emit_ror32c STEPNAME(emit_ror32c) #define emit_rol8c STEPNAME(emit_rol8c) @@ -1162,6 +1163,7 @@ void emit_sar32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i void emit_shl8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4); void emit_shl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4); void emit_shr8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4); +void emit_shr8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4); void emit_rol32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4); void emit_ror32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4); void emit_rol8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4); diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c index ebae674d..a85495a9 100644 --- a/src/emu/x64run_private.c +++ b/src/emu/x64run_private.c @@ -457,11 +457,11 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG((emu->res.u8 & 0xff) == 0, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u8 & 0xff), F_PF); - } - if (cnt == 1) { - CONDITIONAL_SET_FLAG((((emu->res.u8 & 0x80) == 0x80) ^(ACCESS_FLAG(F_CF) != 0)), F_OF); - } else { - CLEAR_FLAG(F_OF); + if (cnt == 1) { + CONDITIONAL_SET_FLAG((((emu->res.u8 & 0x80) == 0x80) ^(ACCESS_FLAG(F_CF) != 0)), F_OF); + } else { + CLEAR_FLAG(F_OF); + } } } else { CONDITIONAL_SET_FLAG((emu->op1.u8 << (emu->op2.u8-1)) & 0x80, F_CF); |