diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-22 18:27:03 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-22 18:27:03 +0100 |
| commit | b14be7f6142676daddc66749b42758c858c6fed4 (patch) | |
| tree | bc2c2ac718c769370012493528ece3d0084af4b1 /src | |
| parent | 35f8500acdcb84568579db604f47d5cfdd532012 (diff) | |
| download | box64-b14be7f6142676daddc66749b42758c858c6fed4.tar.gz box64-b14be7f6142676daddc66749b42758c858c6fed4.zip | |
[DYNAREC] Added (F2/F3) A6 opcode
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/arm64_emitter.h | 4 | ||||
| -rwxr-xr-x | src/dynarec/arm64_printer.c | 15 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_00.c | 46 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_helper.h | 4 |
4 files changed, 67 insertions, 2 deletions
diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h index ecf35d50..e4fb4572 100755 --- a/src/dynarec/arm64_emitter.h +++ b/src/dynarec/arm64_emitter.h @@ -323,6 +323,10 @@ #define CBZw(Rt, imm19) EMIT(CB_gen(0, 0, ((imm19)>>2)&0x7FFFF, Rt)) #define CBZxw(Rt, imm19) EMIT(CB_gen(rex.w, 0, ((imm19)>>2)&0x7FFFF, Rt)) +#define TB_gen(b5, op, b40, imm14, Rt) ((b5)<<31 | 0b011011<<25 | (op)<<24 | (b40)<<19 | (imm14)<<5 | (Rt)) +#define TBZ(Rt, bit, imm16) EMIT(TB_gen(((bit)>>5)&1, 0, (bit)&0x1f, ((imm19)>>2)&0x3FFF, Rt)) +#define TBNZ(Rt, bit, imm16) EMIT(TB_gen(((bit)>>5)&1, 1, (bit)&0x1f, ((imm19)>>2)&0x3FFF, Rt)) + #define Bcond_gen(imm19, cond) (0b0101010<<25 | (imm19)<<5 | (cond)) #define Bcond(cond, imm19) EMIT(Bcond_gen(((imm19)>>2)&0x7FFFF, cond)) diff --git a/src/dynarec/arm64_printer.c b/src/dynarec/arm64_printer.c index c5c09e62..0f894ea7 100755 --- a/src/dynarec/arm64_printer.c +++ b/src/dynarec/arm64_printer.c @@ -665,8 +665,19 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr) snprintf(buff, sizeof(buff), "CBNZ %s, #%+di\t; %p", Xt[Rt], offset>>2, (void*)(addr + offset)); return buff; } - if(isMask(opcode, "f0011010100mmmmmcccc00nnnnnddddd", &a)) { - snprintf(buff, sizeof(buff), "CSEL %s, %s, %s, %s", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm], conds[cond]); + if(isMask(opcode, "f0110100iiiiiiiiiiiiiiiiiiittttt", &a)) { + int offset = signExtend(imm, 19)<<2; + snprintf(buff, sizeof(buff), "CBZ %s, #%+di\t; %p", Xt[Rt], offset>>2, (void*)(addr + offset)); + return buff; + } + if(isMask(opcode, "s0110110sssssiiiiiiiiiiiiiittttt", &a)) { + int offset = signExtend(imm, 14)<<2; + snprintf(buff, sizeof(buff), "TBZ %s, 0x%x, #%+di\t; %p", (imms<31)?Xt[Rt]:Wt[Rt], imms, offset>>2, (void*)(addr + offset)); + return buff; + } + if(isMask(opcode, "s0110111sssssiiiiiiiiiiiiiittttt", &a)) { + int offset = signExtend(imm, 14)<<2; + snprintf(buff, sizeof(buff), "TBNZ %s, 0x%x, #%+di\t; %p", (imms<31)?Xt[Rt]:Wt[Rt], imms, offset>>2, (void*)(addr + offset)); return buff; } diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c index 99a2cab6..a4351282 100755 --- a/src/dynarec/dynarec_arm64_00.c +++ b/src/dynarec/dynarec_arm64_00.c @@ -989,6 +989,52 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin ADDx_REG(xRDI, xRDI, x3); } break; + case 0xA6: + switch(rep) { + case 1: + INST_NAME("REPZ CMPSB"); + SETFLAGS(X_ALL, SF_SET); + GETDIR(x3, 1); + CBZx_NEXT(xRCX); + MARK; + LDRB_U12(x1, xRSI, 0); + LDRB_U12(x2, xRDI, 0); + ADDx_REG(xRSI, xRSI, x3); + ADDx_REG(xRDI, xRDI, x3); + SUBx_U12(xRCX, xRCX, 1); + CMPSw_REG(x1, x2); + Bcond(cEQ, 4+4); + CBNZx_MARK(xRCX); + emit_cmp8(dyn, ninst, x1, x2, x3, x4, x5); + break; + case 2: + INST_NAME("REPNZ CMPSB"); + SETFLAGS(X_ALL, SF_SET); + GETDIR(x3, 1); + CBZx_NEXT(xRCX); + MARK; + LDRB_U12(x1, xRSI, 0); + LDRB_U12(x2, xRDI, 0); + ADDx_REG(xRSI, xRSI, x3); + ADDx_REG(xRDI, xRDI, x3); + SUBx_U12(xRCX, xRCX, 1); + CMPSw_REG(x1, x2); + Bcond(cNE, 4+4); + CBNZx_MARK(xRCX); + emit_cmp8(dyn, ninst, x1, x2, x3, x4, x5); + break; + default: + INST_NAME("CMPSB"); + SETFLAGS(X_ALL, SF_SET); + GETDIR(x3, 1); + LDRB_U12(x1, xRSI, 0); + LDRB_U12(x2, xRDI, 0); + ADDx_REG(xRSI, xRSI, x3); + ADDx_REG(xRDI, xRDI, x3); + emit_cmp8(dyn, ninst, x1, x2, x3, x4, x5); + break; + } + break; case 0xA8: INST_NAME("TEST AL, Ib"); diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h index d4920dec..94cdd652 100755 --- a/src/dynarec/dynarec_arm64_helper.h +++ b/src/dynarec/dynarec_arm64_helper.h @@ -297,6 +297,10 @@ #define CBZw_NEXT(reg) \ j32 = (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->arm_size)):0; \ CBZw(reg, j32) +// Branch to next instruction if reg is 0 (use j32) +#define CBZx_NEXT(reg) \ + j32 = (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->arm_size)):0; \ + CBZx(reg, j32) // Branch to MARKSEG if cond (use j32) #define B_MARKSEG(cond) \ j32 = GETMARKSEG-(dyn->arm_size); \ |