diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-22 16:44:11 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-22 16:44:11 +0100 |
| commit | 0878acf04c60772493599fa59a3eeada7fcf37c1 (patch) | |
| tree | ed9046dc99c05ef2b4d3298f4c788e51d28d5c3c | |
| parent | 735d9c107d5054019ef89367256a6df1a01edda7 (diff) | |
| download | box64-0878acf04c60772493599fa59a3eeada7fcf37c1.tar.gz box64-0878acf04c60772493599fa59a3eeada7fcf37c1.zip | |
[DYNAREC] Added (F2/F3) A5 opcode
| -rwxr-xr-x | src/dynarec/arm64_emitter.h | 8 | ||||
| -rwxr-xr-x | src/dynarec/arm64_printer.c | 7 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_00.c | 25 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_helper.h | 8 |
4 files changed, 44 insertions, 4 deletions
diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h index 4d39a2d3..ecf35d50 100755 --- a/src/dynarec/arm64_emitter.h +++ b/src/dynarec/arm64_emitter.h @@ -344,6 +344,14 @@ #define CSELw(Rd, Rn, Rm, cond) EMIT(CSEL_gen(0, Rm, cond, Rn, Rd)) #define CSELxw(Rd, Rn, Rm, cond) EMIT(CSEL_gen(rex.w, Rm, cond, Rn, Rd)) +#define CSNEG_gen(sf, Rm, cond, Rn, Rd) ((sf)<<31 | 1<<30 | 0b11010100<<21 | (Rm)<<16 | (cond)<<12 | 1<<10 | (Rn)<<5 | (Rd)) +#define CSNEGx(Rd, Rn, Rm, cond) EMIT(CSNEG_gen(1, Rm, cond, Rn, Rd)) +#define CSNEGw(Rd, Rn, Rm, cond) EMIT(CSNEG_gen(0, Rm, cond, Rn, Rd)) +#define CSNEGxw(Rd, Rn, Rm, cond) EMIT(CSNEG_gen(rex.w, Rm, cond, Rn, Rd)) +#define CNEGx(Rd, Rn, cond) CSNEGx(Rn, Rn, Rn, invCond(cond)) +#define CNEGw(Rd, Rn, cond) CSNEGw(Rn, Rn, Rn, invCond(cond)) +#define CNEGxw(Rd, Rn, cond) CSNEGxw(Rn, Rn, Rn, invCond(cond)) + // AND / ORR #define LOGIC_gen(sf, opc, N, immr, imms, Rn, Rd) ((sf)<<31 | (opc)<<29 | 0b100100<<23 | (N)<<22 | (immr)<<16 | (imms)<<10 | (Rn)<<5 | Rd) // logic to get the mask is ... convoluted... list of possible value there: https://gist.github.com/dinfuehr/51a01ac58c0b23e4de9aac313ed6a06a diff --git a/src/dynarec/arm64_printer.c b/src/dynarec/arm64_printer.c index 4a4e8247..c5c09e62 100755 --- a/src/dynarec/arm64_printer.c +++ b/src/dynarec/arm64_printer.c @@ -680,6 +680,13 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr) return buff; } + if(isMask(opcode, "f1011010100mmmmmcccc01nnnnnddddd", &a)) { + if((cond&0b1110)!=0b1110 && Rn==Rm) + snprintf(buff, sizeof(buff), "CNEG %s, %s, %s", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], conds[cond^1]); + else + snprintf(buff, sizeof(buff), "CSNEG %s, %s, %s, %s", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm], conds[cond]); + return buff; + } // MISC Bits if(isMask(opcode, "f10110101100000000010onnnnnddddd", &a)) { snprintf(buff, sizeof(buff), "CL%c %s, %s", option?'S':'Z', sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn]); diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c index 4c8e3e6d..714bb92d 100755 --- a/src/dynarec/dynarec_arm64_00.c +++ b/src/dynarec/dynarec_arm64_00.c @@ -970,6 +970,31 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin SET_DFNONE(x1); break; + case 0xA5: + if(rep) { + INST_NAME("REP MOVSD"); + TSTw_REG(xRCX, xRCX); + B_NEXT(cEQ); // end of loop + GETDIR(x3, rex.w?8:4); + MARK; + LDRxw_U12(x1, xRSI, 0); + STRxw_U12(x1, xRDI, 0); + ADDx_REG(xRSI, xRSI, x3); + ADDx_REG(xRDI, xRDI, x3); + SUBSx_U12(xRCX, xRCX, 1); + B_MARK(cNE); + // done + } else { + INST_NAME("MOVSD"); + GETDIR(x3, rex.w?8:4); + LDRxw_U12(x1, xRSI, 0); + STRxw_U12(x1, xRDI, 0); + ADDx_REG(xRSI, xRSI, x3); + ADDx_REG(xRDI, xRDI, x3); + SUBSx_U12(xRCX, xRCX, 1); + } + break; + case 0xA8: INST_NAME("TEST AL, Ib"); SETFLAGS(X_ALL, SF_SET); diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h index 6fe1bd24..7c1d4ca7 100755 --- a/src/dynarec/dynarec_arm64_helper.h +++ b/src/dynarec/dynarec_arm64_helper.h @@ -225,10 +225,10 @@ // Get Direction with size Z and based of F_DF flag, on register r ready for LDR/STR fetching // F_DF is 1<<10, so 1 ROR 11*2 (so F_OF) -#define GETDIR(r, A) \ - TSTS_IMM8_ROR(xFlags, 1, 0x0b); \ - MOVW(r, A); \ - RSB_COND_IMM8(cNE, r, r, 0) +#define GETDIR(r, A) \ + MOV32w(r, A); /* mask=1<<10 */ \ + TSTw_mask(xFlags, 0b010110, 0); \ + CNEGx(r, r, cNE) // CALL will use x7 for the call address. Return value can be put in ret (unless ret is -1) // R0 will not be pushed/popd if ret is -2 |