diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_00.c | 16 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_emit_shift.c | 51 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.h | 2 |
3 files changed, 55 insertions, 14 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index 06d10a4e..d00c3229 100644 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -2309,14 +2309,18 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 5: INST_NAME("SHR Eb, CL"); - ANDSw_mask(x2, xRCX, 0, 0b00100); - SETFLAGS(X_ALL, SF_PENDING); + SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined + UFLAG_IF { + ANDSw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f + } else { + ANDw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f + } GETEB(x1, 0); - UFLAG_OP12(ed, x2); - LSRw_REG(ed, ed, x2); + UFLAG_IF { + B_NEXT(cEQ); + } + emit_shr8(dyn, ninst, x1, x2, x5, x4); EBBACK; - UFLAG_RES(ed); - UFLAG_DF(x3, d_shr8); break; case 7: INST_NAME("SAR Eb, CL"); diff --git a/src/dynarec/arm64/dynarec_arm64_emit_shift.c b/src/dynarec/arm64/dynarec_arm64_emit_shift.c index 526364ee..75caa99c 100644 --- a/src/dynarec/arm64/dynarec_arm64_emit_shift.c +++ b/src/dynarec/arm64/dynarec_arm64_emit_shift.c @@ -141,14 +141,6 @@ void emit_shr32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3 } else IFX(X_ALL) { SET_DFNONE(s4); } - IFX(X_ALL) { - CMPSxw_U12(s2, 0); //if(!c) - IFX(X_PEND) { - Bcond(cNE, +12); - STRxw_U12(s1, xEmu, offsetof(x64emu_t, res)); - } - B_NEXT(cEQ); - } IFX(X_CF) { SUBxw_U12(s3, s2, 1); LSRxw_REG(s3, s1, s3); @@ -367,6 +359,49 @@ void emit_shl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s } } +// emit SHR8 instruction, from s1 , s2, store result in s1 using s3 and s4 as scratch, s2 can be same as s3 +void emit_shr8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) +{ + MAYUSE(s2); + int64_t j64; + MAYUSE(j64); + + IFX(X_PEND) { + STRB_U12(s1, xEmu, offsetof(x64emu_t, op1)); + STRB_U12(s2, xEmu, offsetof(x64emu_t, op2)); + SET_DF(s4, d_shr8); + } else IFX(X_ALL) { + SET_DFNONE(s4); + } + IFX(X_CF) { + SUBw_U12(s3, s2, 1); + LSRw_REG(s3, s1, s3); + BFIw(xFlags, s3, 0, 1); + } + IFX(X_OF) { + CMPSw_U12(s2, 1); // if s2==1 + Bcond(cNE, 4+2*4); + LSRw(s4, s1, 7); + BFIw(xFlags, s4, F_OF, 1); + } + LSRw_REG(s1, s1, s2); + 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); + BFIw(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 c141ea8b..ac7ef7fd 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -1025,6 +1025,7 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr); #define emit_sar32c STEPNAME(emit_sar32c) #define emit_shl8 STEPNAME(emit_shl8) #define emit_shl8c STEPNAME(emit_shl8c) +#define emit_shr8 STEPNAME(emit_shr8) #define emit_rol32c STEPNAME(emit_rol32c) #define emit_ror32c STEPNAME(emit_ror32c) #define emit_rol8c STEPNAME(emit_rol8c) @@ -1160,6 +1161,7 @@ void emit_shr32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i void emit_sar32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4); 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_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); |