diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-11-13 12:01:57 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-11-13 12:01:57 +0100 |
| commit | 590429d10456b346f56114563caac39dfb43c485 (patch) | |
| tree | e9aa621c75309f66ae98215aef88720ba2b732f4 /src | |
| parent | eb0b5bd3f88077a052d234a7b0fe4a305f3f2ba6 (diff) | |
| download | box64-590429d10456b346f56114563caac39dfb43c485.tar.gz box64-590429d10456b346f56114563caac39dfb43c485.zip | |
[ARM64_DYNAREC] Optimized 16bits ROL/ROR opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_66.c | 84 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_emit_shift.c | 12 |
2 files changed, 60 insertions, 36 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c index 258edfd5..4d58a850 100644 --- a/src/dynarec/arm64/dynarec_arm64_66.c +++ b/src/dynarec/arm64/dynarec_arm64_66.c @@ -931,21 +931,27 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("ROL Ew, Ib"); if(geted_ib(dyn, addr, ninst, nextop)&15) { SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING); + GETEW(x1, 1); + u8 = F8; + emit_rol16c(dyn, ninst, x1, u8&15, x4, x5); + EWBACK; + } else { + FAKEED; + F8; } - GETEW(x1, 1); - u8 = F8; - emit_rol16c(dyn, ninst, x1, u8&15, x4, x5); - EWBACK; break; case 1: INST_NAME("ROR Ew, Ib"); if(geted_ib(dyn, addr, ninst, nextop)&15) { SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING); + GETEW(x1, 1); + u8 = F8; + emit_ror16c(dyn, ninst, x1, u8&15, x4, x5); + EWBACK; + } else { + FAKEED; + F8; } - GETEW(x1, 1); - u8 = F8; - emit_ror16c(dyn, ninst, x1, u8&15, x4, x5); - EWBACK; break; case 2: INST_NAME("RCL Ew, Ib"); @@ -1034,20 +1040,16 @@ 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"); - MOV32w(x2, 1); - MESSAGE(LOG_DUMP, "Need Optimization\n"); - SETFLAGS(X_OF|X_CF, SF_SET); + SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING); GETEW(x1, 0); - CALL_(rol16, x1, x3); + emit_rol16c(dyn, ninst, x1, 1, x5, x4); EWBACK; break; case 1: INST_NAME("ROR Ew, 1"); - MOV32w(x2, 1); - MESSAGE(LOG_DUMP, "Need Optimization\n"); - SETFLAGS(X_OF|X_CF, SF_SET); + SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING); GETEW(x1, 0); - CALL_(ror16, x1, x3); + emit_ror16c(dyn, ninst, x1, 1, x5, x4); EWBACK; break; case 2: @@ -1100,21 +1102,55 @@ 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, CL"); - ANDw_mask(x2, xRCX, 0, 0b00100); - MESSAGE(LOG_DUMP, "Need Optimization\n"); - SETFLAGS(X_OF|X_CF, SF_SET); + SETFLAGS(X_OF|X_CF, SF_SUBSET); + if(box64_dynarec_safeflags>1) + MAYSETFLAGS(); + UFLAG_IF { + TSTw_mask(xRCX, 0, 0b00100); //mask=0x00000001f + B_NEXT(cEQ); + } + ANDw_mask(x2, xRCX, 0, 0b00011); //mask=0x00000000f + MOV32w(x4, 16); + SUBx_REG(x2, x4, x2); GETEW(x1, 0); - CALL_(rol16, x1, x3); + ORRw_REG_LSL(ed, ed, ed, 16); + LSRw_REG(ed, ed, x2); EWBACK; + UFLAG_IF { // calculate flags directly + CMPSw_U12(x2, 15); + B_MARK(cNE); + LSRxw(x3, ed, 15); + ADDxw_REG(x3, x3, ed); + BFIw(xFlags, x3, F_OF, 1); + MARK; + BFIw(xFlags, ed, F_CF, 1); + UFLAG_DF(x2, d_none); + } break; case 1: INST_NAME("ROR Ew, CL"); - ANDw_mask(x2, xRCX, 0, 0b00100); - MESSAGE(LOG_DUMP, "Need Optimization\n"); - SETFLAGS(X_OF|X_CF, SF_SET); + SETFLAGS(X_OF|X_CF, SF_SUBSET); + if(box64_dynarec_safeflags>1) + MAYSETFLAGS(); + UFLAG_IF { + TSTw_mask(xRCX, 0, 0b00100); //mask=0x00000001f + B_NEXT(cEQ); + } + ANDw_mask(x2, xRCX, 0, 0b00011); //mask=0x00000000f GETEW(x1, 0); - CALL_(ror16, x1, x3); + ORRw_REG_LSL(ed, ed, ed, 16); + LSRw_REG(ed, ed, x2); EWBACK; + UFLAG_IF { // calculate flags directly + CMPSw_U12(x2, 1); + B_MARK(cNE); + LSRxw(x2, ed, 14); // x2 = d>>14 + EORw_REG_LSR(x2, x2, x2, 1); // x2 = ((d>>14) ^ ((d>>14)>>1)) + BFIw(xFlags, x2, F_OF, 1); + MARK; + BFXILw(xFlags, ed, 15, 1); + UFLAG_DF(x2, d_none); + } break; case 2: INST_NAME("RCL Ew, CL"); diff --git a/src/dynarec/arm64/dynarec_arm64_emit_shift.c b/src/dynarec/arm64/dynarec_arm64_emit_shift.c index edb16a74..25b7fa54 100644 --- a/src/dynarec/arm64/dynarec_arm64_emit_shift.c +++ b/src/dynarec/arm64/dynarec_arm64_emit_shift.c @@ -953,12 +953,6 @@ void emit_rol16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int } else IFX(X_ALL) { SET_DFNONE(s4); } - if(!c) { - IFX(X_PEND) { - STRH_U12(s1, xEmu, offsetof(x64emu_t, res)); - } - return; - } int rc = 16-(c&15); ORRw_REG_LSL(s1, s1, s1, 16); LSRw(s1, s1, rc); @@ -987,12 +981,6 @@ void emit_ror16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int } else IFX(X_ALL) { SET_DFNONE(s4); } - if(!c) { - IFX(X_PEND) { - STRH_U12(s1, xEmu, offsetof(x64emu_t, res)); - } - return; - } ORRw_REG_LSL(s1, s1, s1, 16); LSRw(s1, s1, c&15); IFX(X_PEND) { |