diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-22 09:45:59 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-22 09:45:59 +0100 |
| commit | 3cfd4c8ec2b018245b46331133fbe61fbed03785 (patch) | |
| tree | d71383888f0efaacceb8ddaa8090ab6cb8a88d67 | |
| parent | 9eb6d496167e694e84b5708617632953700a8180 (diff) | |
| download | box64-3cfd4c8ec2b018245b46331133fbe61fbed03785.tar.gz box64-3cfd4c8ec2b018245b46331133fbe61fbed03785.zip | |
[DYNAREC] Added 87 XCHG opcode
| -rwxr-xr-x | src/dynarec/arm64_emitter.h | 18 | ||||
| -rwxr-xr-x | src/dynarec/arm64_printer.c | 9 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_00.c | 30 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_helper.h | 8 |
4 files changed, 62 insertions, 3 deletions
diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h index a2ad2561..e59a9cbf 100755 --- a/src/dynarec/arm64_emitter.h +++ b/src/dynarec/arm64_emitter.h @@ -283,7 +283,20 @@ #define POP1(reg) LDRx_S9_postindex(reg, xRSP, 8) #define PUSH1(reg) STRx_S9_preindex(reg, xRSP, -8) -// BR and branchs +// LOAD/STORE Exclusive +#define MEMX_gen(size, L, Rs, Rn, Rt) ((size)<<30 | 0b001000<<24 | (L)<<22 | (Rs)<<16 | 1<<15 | 0b11111<<10 | (Rn)<<5 | (Rt)) +#define LDAXRB(Rt, Rn) EMIT(MEMX_gen(0b00, 1, 31, Rn, Rt)) +#define STLXRB(Rs, Rt, Rn) EMIT(MEMX_gen(0b00, 0, Rs, Rn, Rt)) +#define LDAXRH(Rt, Rn) EMIT(MEMX_gen(0b01, 1, 31, Rn, Rt)) +#define STLXRH(Rs, Rt, Rn) EMIT(MEMX_gen(0b01, 0, Rs, Rn, Rt)) +#define LDAXRw(Rt, Rn) EMIT(MEMX_gen(0b10, 1, 31, Rn, Rt)) +#define STLXRw(Rs, Rt, Rn) EMIT(MEMX_gen(0b10, 0, Rs, Rn, Rt)) +#define LDAXRx(Rt, Rn) EMIT(MEMX_gen(0b11, 1, 31, Rn, Rt)) +#define STLXRx(Rs, Rt, Rn) EMIT(MEMX_gen(0b11, 0, Rs, Rn, Rt)) +#define LDAXRxw(Rt, Rn) EMIT(MEMX_gen(2+rex.w, 1, 31, Rn, Rt)) +#define STLXRxw(Rs, Rt, Rn) EMIT(MEMX_gen(2+rex.w, 0, Rs, Rn, Rt)) + +// BR and Branches #define BR_gen(Z, op, A, M, Rn, Rm) (0b1101011<<25 | (Z)<<24 | (op)<<21 | 0b11111<<16 | (A)<<11 | (M)<<10 | (Rn)<<5 | (Rm)) #define BR(Rn) EMIT(BR_gen(0, 0b00, 0, 0, Rn, 0)) #define BLR(Rn) EMIT(BR_gen(0, 0b01, 0, 0, Rn, 0)) @@ -326,9 +339,8 @@ #define ORRw_mask(Rd, Rn, immr, imms) EMIT(LOGIC_gen(0, 0b01, 0, immr, imms, Rn, Rd)) #define EORx_mask(Rd, Rn, N, immr, imms) EMIT(LOGIC_gen(1, 0b10, N, immr, imms, Rn, Rd)) #define EORw_mask(Rd, Rn, immr, imms) EMIT(LOGIC_gen(0, 0b10, 0, immr, imms, Rn, Rd)) -#define TSTx_mask(Rn, immr, imms) ANDSx_mask(xZR, Rn, immr, imms) +#define TSTx_mask(Rn, N, immr, imms) ANDSx_mask(xZR, Rn, N, immr, imms) #define TSTw_mask(Rn, immr, imms) ANDSw_mask(wZR, Rn, immr, imms) -#define TSTxw_mask(Rn, immr, imms) ANDSxw_mask(xZR, Rn, immr, imms) #define LOGIC_REG_gen(sf, opc, shift, N, Rm, imm6, Rn, Rd) ((sf)<<31 | (opc)<<29 | 0b01010<<24 | (shift)<<22 | (N)<<21 | (Rm)<<16 | (imm6)<<10 | (Rn)<<5 | (Rd)) #define ANDx_REG(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(1, 0b00, 0b00, 0, Rm, 0, Rn, Rd)) diff --git a/src/dynarec/arm64_printer.c b/src/dynarec/arm64_printer.c index b068b9d8..103e6aff 100755 --- a/src/dynarec/arm64_printer.c +++ b/src/dynarec/arm64_printer.c @@ -106,6 +106,7 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr) #define Rm a.m #define Rd a.d #define Ra a.a + #define Rs a.s #define sf a.f #define imm a.i #define option a.o @@ -275,6 +276,14 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr) return buff; } + if(isMask(opcode, "ff0010000L0sssss111111nnnnnttttt", &a)) { + if(a.L) + snprintf(buff, sizeof(buff), "LDAXR%s %s, [%s]", (sf==0)?"B":((sf==1)?"H":""), (sf==2)?Wt[Rt]:Xt[Rt], XtSp[Rn]); + else + snprintf(buff, sizeof(buff), "STLXR%s %s, %s, [%s]", (sf==0)?"B":((sf==1)?"H":""), (sf==2)?Wt[Rs]:Xt[Rs], (sf==2)?Wt[Rt]:Xt[Rt], XtSp[Rn]); + return buff; + } + // --- MOV (REGS: see Logic MOV==ORR, MVN==ORN) if(isMask(opcode, "f10100101wwiiiiiiiiiiiiiiiiddddd", &a)) { if(!hw) diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c index 3bf36e57..bb51582a 100755 --- a/src/dynarec/dynarec_arm64_00.c +++ b/src/dynarec/dynarec_arm64_00.c @@ -830,6 +830,36 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin emit_test32(dyn, ninst, rex, ed, gd, x3, x5); break; + case 0x87: + INST_NAME("(LOCK)XCHG Ed, Gd"); + nextop = F8; + if(MODREG) { + GETGD; + GETED(0); + MOVxw_REG(x1, gd); + MOVxw_REG(gd, ed); + MOVxw_REG(ed, x1); + } else { + GETGD; + addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, 0, 0); + if(rex.w) { + TSTx_mask(ed, 1, 0, 2); // mask=7 + } else { + TSTw_mask(ed, 0, 1); // mask=3 + } + B_MARK(cNE); + MARKLOCK; + LDAXRxw(x1, ed); + STLXRxw(x3, gd, ed); + CBZx_MARKLOCK(x3); + B_MARK2_nocond; + MARK; + LDRxw_U12(x1, ed, 0); + STRxw_U12(gd, ed, 0); + MARK2; + MOVxw_REG(gd, x1); + } + break; case 0x88: INST_NAME("MOV Eb, Gb"); nextop = F8; diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h index ed8fd357..91bc4f83 100755 --- a/src/dynarec/dynarec_arm64_helper.h +++ b/src/dynarec/dynarec_arm64_helper.h @@ -261,6 +261,10 @@ #define B_MARK2(cond) \ j32 = GETMARK2-(dyn->arm_size); \ Bcond(cond, j32) +// Branch to MARK2 unconditionnal (use j32) +#define B_MARK2_nocond \ + j32 = GETMARK2-(dyn->arm_size); \ + B(j32) // Branch to MARK3 if cond (use j32) #define B_MARK3(cond) \ j32 = GETMARK3-(dyn->arm_size); \ @@ -289,6 +293,10 @@ #define B_MARKLOCK(cond) \ j32 = GETMARKLOCK-(dyn->arm_size); \ Bcond(cond, j32) +// Branch to MARKLOCK if reg is not 0 (use j32) +#define CBZx_MARKLOCK(reg) \ + j32 = GETMARKLOCK-(dyn->arm_size); \ + CBNZx(reg, j32) #define IFX(A) if(dyn->insts && (dyn->insts[ninst].x64.need_flags&(A))) #define IFXX(A) if(dyn->insts && (dyn->insts[ninst].x64.need_flags==(A))) |