diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-11-11 15:40:35 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-11-11 15:40:35 +0100 |
| commit | 6d6f29b6e17e2932448b024182bb147b0fb7939d (patch) | |
| tree | 1061f8825b467c61be834908802408a4f30f0a3d | |
| parent | 0260b3177e01bfa70ef7ceadbbad278b4bfb762a (diff) | |
| download | box64-6d6f29b6e17e2932448b024182bb147b0fb7939d.tar.gz box64-6d6f29b6e17e2932448b024182bb147b0fb7939d.zip | |
[ARM64_DYNAREC] Added shl8c emitter
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_00.c | 16 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_emit_shift.c | 52 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.h | 2 |
3 files changed, 57 insertions, 13 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index ded12737..6760a583 100644 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -1776,21 +1776,11 @@ 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; - if(u8) { - SETFLAGS(X_ALL, SF_PENDING); - UFLAG_IF{ - MOV32w(x4, u8); UFLAG_OP2(x4); - }; - UFLAG_OP1(ed); - LSLw(ed, ed, u8); - EBBACK; - UFLAG_RES(ed); - UFLAG_DF(x3, d_shl8); - } else { - NOP; - } + emit_shl8c(dyn, ninst, ed, u8, x3, x4); + EBBACK; break; case 5: INST_NAME("SHR Eb, Ib"); diff --git a/src/dynarec/arm64/dynarec_arm64_emit_shift.c b/src/dynarec/arm64/dynarec_arm64_emit_shift.c index 485489a4..266576f7 100644 --- a/src/dynarec/arm64/dynarec_arm64_emit_shift.c +++ b/src/dynarec/arm64/dynarec_arm64_emit_shift.c @@ -270,6 +270,58 @@ void emit_sar32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i } } +// 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) +{ + 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_shl8); + } 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); + } + LSLw(s1, s1, c); + + IFX(X_PEND) { + STRB_U12(s1, xEmu, offsetof(x64emu_t, res)); + } + IFX(X_ZF) { + TSTw_REG(s1, s1); + CSETw(s4, cEQ); + BFIw(xFlags, s4, F_ZF, 1); + } + IFX(X_SF) { + LSRw(s4, s1, 7); + BFIw(xFlags, s4, F_SF, 1); + } + IFX(X_OF) { + if(c==1) { + IFX(X_SF) {} else {LSRw(s4, s1, 7);} + EORw_REG(s4, s4, xFlags); // CF is set if OF is asked + BFIw(xFlags, s4, F_OF, 1); + } else { + BFCw(xFlags, F_OF, 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 1c0fc352..1bb519f3 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -1023,6 +1023,7 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr); #define emit_shr32 STEPNAME(emit_shr32) #define emit_shr32c STEPNAME(emit_shr32c) #define emit_sar32c STEPNAME(emit_sar32c) +#define emit_shl8c STEPNAME(emit_shl8c) #define emit_rol32c STEPNAME(emit_rol32c) #define emit_ror32c STEPNAME(emit_ror32c) #define emit_rol8c STEPNAME(emit_rol8c) @@ -1156,6 +1157,7 @@ void emit_shl32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i void emit_shr32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4); void emit_shr32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4); void emit_sar32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4); +void emit_shl8c(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); |