diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-02-21 18:13:49 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-02-21 18:13:49 +0100 |
| commit | f09b541ab73dc7eb753a812c3fdd4d0cc17f7b02 (patch) | |
| tree | 73e5115e5b7ab0ec320942882f9e6308653715d5 | |
| parent | e71df7eb670a1d943a41b7c94f3fc3794bc927eb (diff) | |
| download | box64-f09b541ab73dc7eb753a812c3fdd4d0cc17f7b02.tar.gz box64-f09b541ab73dc7eb753a812c3fdd4d0cc17f7b02.zip | |
[ARM64_DYNAREC] Added RCR 8bits with constant optimisation, and fixed RCL 8bit with const
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_00.c | 15 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_emit_shift.c | 57 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.h | 2 | ||||
| -rw-r--r-- | src/emu/x64run_private.c | 15 |
4 files changed, 72 insertions, 17 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index a56e2aec..b9f31523 100644 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -1883,15 +1883,13 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 3: INST_NAME("RCR Eb, Ib"); - MESSAGE(LOG_DUMP, "Need Optimization\n"); - READFLAGS(X_CF); u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f; if(u8) { - SETFLAGS(X_OF|X_CF, SF_SET); + READFLAGS(X_CF); + SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING); GETEB(x1, 1); u8 = F8&0x1f; - MOV32w(x2, u8); - CALL_(rcr8, ed, x3); + emit_rcr8c(dyn, ninst, x1, u8, x4, x5); EBBACK; } else { FAKEED; @@ -2317,6 +2315,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 2: INST_NAME("RCL Eb, 1"); + READFLAGS(X_CF); SETFLAGS(X_OF|X_CF, SF_SUBSET); GETEB(x1, 0); emit_rcl8c(dyn, ninst, ed, 1, x4, x5); @@ -2324,12 +2323,10 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 3: INST_NAME("RCR Eb, 1"); - MESSAGE(LOG_DUMP, "Need Optimization\n"); READFLAGS(X_CF); - SETFLAGS(X_OF|X_CF, SF_SET); - MOV32w(x2, 1); + SETFLAGS(X_OF|X_CF, SF_SUBSET); GETEB(x1, 0); - CALL_(rcr8, x1, x3); + emit_rcr8c(dyn, ninst, ed, 1, x4, x5); EBBACK; break; case 4: diff --git a/src/dynarec/arm64/dynarec_arm64_emit_shift.c b/src/dynarec/arm64/dynarec_arm64_emit_shift.c index 0456359b..b8686477 100644 --- a/src/dynarec/arm64/dynarec_arm64_emit_shift.c +++ b/src/dynarec/arm64/dynarec_arm64_emit_shift.c @@ -976,34 +976,79 @@ void emit_ror16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int } } -// emit RcL8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch +// emit RCL8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch void emit_rcl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4) { MAYUSE(s1); MAYUSE(s3); MAYUSE(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_rol8); + SET_DF(s4, d_rcl8); + } else IFX(X_ALL) { + SET_DFNONE(s4); + } + BFIw(x1, xFlags, 8, 1); // insert cf + IFX(X_OF|X_CF) { + LSRw_IMM(x2, x1, 8-(c%9)); + } + ORRw_REG_LSL(x1, x1, x1, 9); // insert x1 again + if(c%9) { + LSRw_IMM(x1, x1, 9-(c%9)); // do the rcl + } + IFX(X_PEND) { + STRB_U12(s1, xEmu, offsetof(x64emu_t, res)); + } + IFX(X_OF|X_CF) { + BFIw(xFlags, x2, F_CF, 1); + IFX(X_OF) { + if(c==1) { + EORw_REG_LSR(x2, x2, x1, 7); + BFIw(xFlags, x2, F_OF, 1); + } + } + } +} + +// emit RCR8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch +void emit_rcr8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4) +{ + MAYUSE(s1); MAYUSE(s3); MAYUSE(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_rcr8); } else IFX(X_ALL) { SET_DFNONE(s4); } IFX(X_OF|X_CF) { if(c%9) { - LSRw_IMM(x2, x1, 8-(c%9)); + if((c%9)==1) { + MOVx_REG(x2, x1); + } else { + LSRw_IMM(x2, x1, (c%9)-1); + } + } else { + MOVw_REG(x2, xFlags); } } BFIw(x1, xFlags, 8, 1); // insert cf ORRw_REG_LSL(x1, x1, x1, 9); // insert x1 again - LSRw_IMM(x1, x1, 9-(c%9)); // do the rcl - UXTBw(x1, x1); + if(c%9) { + LSRw_IMM(x1, x1, (c%9)); // do the rcr + } + IFX(X_PEND) { + STRB_U12(s1, xEmu, offsetof(x64emu_t, res)); + } IFX(X_OF|X_CF) { - BFIw(xFlags, x2, F_CF, 1); IFX(X_OF) { if(c==1) { EORw_REG_LSR(x2, x2, x1, 7); BFIw(xFlags, x2, F_OF, 1); } } + BFIw(xFlags, x2, F_CF, 1); } } diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h index 902219c6..0fe4d252 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -1081,6 +1081,7 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr); #define emit_rol16c STEPNAME(emit_rol16c) #define emit_ror16c STEPNAME(emit_ror16c) #define emit_rcl8c STEPNAME(emit_rcl8c) +#define emit_rcr8c STEPNAME(emit_rcr8c) #define emit_shrd32c STEPNAME(emit_shrd32c) #define emit_shrd32 STEPNAME(emit_shrd32) #define emit_shld32c STEPNAME(emit_shld32c) @@ -1232,6 +1233,7 @@ void emit_ror8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s void emit_rol16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4); void emit_ror16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4); void emit_rcl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4); +void emit_rcr8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4); void emit_shrd32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint32_t c, int s3, int s4); void emit_shld32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint32_t c, int s3, int s4); void emit_shrd32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s5, int s3, int s4); diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c index 927d2d1c..5c88413e 100644 --- a/src/emu/x64run_private.c +++ b/src/emu/x64run_private.c @@ -1046,12 +1046,23 @@ void UpdateFlags(x64emu_t *emu) } CONDITIONAL_SET_FLAG(emu->res.u64 & (1L << 63), F_CF); break; - case d_rcl8: + cnt = emu->op2.u8%9; + CONDITIONAL_SET_FLAG(emu->op1.u8>>(9-cnt) & 1, F_CF); + // should for cnt==1 + CONDITIONAL_SET_FLAG(((emu->res.u8>>7) ^ ACCESS_FLAG(F_CF)) & 1, F_OF); + break; + case d_rcr8: + cnt = emu->op2.u8%9; + // should for cnt==1, using "before" CF + CONDITIONAL_SET_FLAG(((emu->res.u8>>7) ^ ACCESS_FLAG(F_CF)) & 1, F_OF); + // new CF + CONDITIONAL_SET_FLAG(((cnt==1)?emu->op1.u8:(emu->op1.u8>>(cnt-1))) & 1, F_CF); + break; + case d_rcl16: case d_rcl32: case d_rcl64: - case d_rcr8: case d_rcr16: case d_rcr32: case d_rcr64: |