diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-31 11:05:02 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-31 11:05:02 +0200 |
| commit | 424a08607cdb4bb03e1ba2c443adae55db72243c (patch) | |
| tree | 6c07389f8c77baa4506048c9e844e2d3376043af | |
| parent | 0d2a060e663b092b7c966a2a720b380f21e0a38f (diff) | |
| download | box64-424a08607cdb4bb03e1ba2c443adae55db72243c.tar.gz box64-424a08607cdb4bb03e1ba2c443adae55db72243c.zip | |
[DYNAREC] Added 66 0F F6 opcode
| -rwxr-xr-x | src/dynarec/arm64_emitter.h | 73 | ||||
| -rwxr-xr-x | src/dynarec/arm64_printer.c | 30 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_660f.c | 19 |
3 files changed, 121 insertions, 1 deletions
diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h index 220d8444..0446bde6 100755 --- a/src/dynarec/arm64_emitter.h +++ b/src/dynarec/arm64_emitter.h @@ -1226,4 +1226,77 @@ #define VUMULL2_16(Rd, Rn, Rm) EMIT(MULL_vector(1, 1, 0b01, Rm, Rn, Rd)) #define VUMULL2_32(Rd, Rn, Rm) EMIT(MULL_vector(1, 1, 0b10, Rm, Rn, Rd)) +// Absolute Difference +#define AD_vector(Q, U, size, Rm, ac, Rn, Rd) ((Q)<<30 | (U)<<29 | 0b01110<<24 | (size)<<22 | 1<<21 | (Rm)<<16 | 0b0111<<12 | (ac)<<11 | 1<<10 | (Rn)<<5 | (Rd)) +// Signed Absolute Difference and accumulate +#define SABAQ_8(Rd, Rn, Rm) EMIT(AD_vector(1, 0, 0b00, Rm, 1, Rn, Rd)) +#define SABAQ_16(Rd, Rn, Rm) EMIT(AD_vector(1, 0, 0b01, Rm, 1, Rn, Rd)) +#define SABAQ_32(Rd, Rn, Rm) EMIT(AD_vector(1, 0, 0b10, Rm, 1, Rn, Rd)) +#define SABA_8(Rd, Rn, Rm) EMIT(AD_vector(0, 0, 0b00, Rm, 1, Rn, Rd)) +#define SABA_16(Rd, Rn, Rm) EMIT(AD_vector(0, 0, 0b01, Rm, 1, Rn, Rd)) +#define SABA_32(Rd, Rn, Rm) EMIT(AD_vector(0, 0, 0b10, Rm, 1, Rn, Rd)) +// Signed Absolute Difference +#define SABDQ_8(Rd, Rn, Rm) EMIT(AD_vector(1, 0, 0b00, Rm, 0, Rn, Rd)) +#define SABDQ_16(Rd, Rn, Rm) EMIT(AD_vector(1, 0, 0b01, Rm, 0, Rn, Rd)) +#define SABDQ_32(Rd, Rn, Rm) EMIT(AD_vector(1, 0, 0b10, Rm, 0, Rn, Rd)) +#define SABD_8(Rd, Rn, Rm) EMIT(AD_vector(0, 0, 0b00, Rm, 0, Rn, Rd)) +#define SABD_16(Rd, Rn, Rm) EMIT(AD_vector(0, 0, 0b01, Rm, 0, Rn, Rd)) +#define SABD_32(Rd, Rn, Rm) EMIT(AD_vector(0, 0, 0b10, Rm, 0, Rn, Rd)) + +#define ADL_vector(Q, U, size, Rm, op, Rn, Rd) ((Q)<<30 | (U)<<29 | 0b01110<<24 | (size)<<22 | 1<<21 | (Rm)<<16 | 0b01<<14 | (op)<<13 | 1<<12 | (Rn)<<5 | (Rd)) +#define SABAL_8(Rd, Rn, Rm) EMIT(ADL_vector(0, 0, 0b00, Rm, 0, Rn, Rd)) +#define SABAL2_8(Rd, Rn, Rm) EMIT(ADL_vector(1, 0, 0b00, Rm, 0, Rn, Rd)) +#define SABAL_16(Rd, Rn, Rm) EMIT(ADL_vector(0, 0, 0b01, Rm, 0, Rn, Rd)) +#define SABAL2_16(Rd, Rn, Rm) EMIT(ADL_vector(1, 0, 0b01, Rm, 0, Rn, Rd)) +#define SABAL_32(Rd, Rn, Rm) EMIT(ADL_vector(0, 0, 0b10, Rm, 0, Rn, Rd)) +#define SABAL2_32(Rd, Rn, Rm) EMIT(ADL_vector(1, 0, 0b10, Rm, 0, Rn, Rd)) +#define UABAL_8(Rd, Rn, Rm) EMIT(ADL_vector(0, 1, 0b00, Rm, 0, Rn, Rd)) +#define UABAL2_8(Rd, Rn, Rm) EMIT(ADL_vector(1, 1, 0b00, Rm, 0, Rn, Rd)) +#define UABAL_16(Rd, Rn, Rm) EMIT(ADL_vector(0, 1, 0b01, Rm, 0, Rn, Rd)) +#define UABAL2_16(Rd, Rn, Rm) EMIT(ADL_vector(1, 1, 0b01, Rm, 0, Rn, Rd)) +#define UABAL_32(Rd, Rn, Rm) EMIT(ADL_vector(0, 1, 0b10, Rm, 0, Rn, Rd)) +#define UABAL2_32(Rd, Rn, Rm) EMIT(ADL_vector(1, 1, 0b10, Rm, 0, Rn, Rd)) +#define SABDL_8(Rd, Rn, Rm) EMIT(ADL_vector(0, 0, 0b00, Rm, 1, Rn, Rd)) +#define SABDL2_8(Rd, Rn, Rm) EMIT(ADL_vector(1, 0, 0b00, Rm, 1, Rn, Rd)) +#define SABDL_16(Rd, Rn, Rm) EMIT(ADL_vector(0, 0, 0b01, Rm, 1, Rn, Rd)) +#define SABDL2_16(Rd, Rn, Rm) EMIT(ADL_vector(1, 0, 0b01, Rm, 1, Rn, Rd)) +#define SABDL_32(Rd, Rn, Rm) EMIT(ADL_vector(0, 0, 0b10, Rm, 1, Rn, Rd)) +#define SABDL2_32(Rd, Rn, Rm) EMIT(ADL_vector(1, 0, 0b10, Rm, 1, Rn, Rd)) +#define UABDL_8(Rd, Rn, Rm) EMIT(ADL_vector(0, 1, 0b00, Rm, 1, Rn, Rd)) +#define UABDL2_8(Rd, Rn, Rm) EMIT(ADL_vector(1, 1, 0b00, Rm, 1, Rn, Rd)) +#define UABDL_16(Rd, Rn, Rm) EMIT(ADL_vector(0, 1, 0b01, Rm, 1, Rn, Rd)) +#define UABDL2_16(Rd, Rn, Rm) EMIT(ADL_vector(1, 1, 0b01, Rm, 1, Rn, Rd)) +#define UABDL_32(Rd, Rn, Rm) EMIT(ADL_vector(0, 1, 0b10, Rm, 1, Rn, Rd)) +#define UABDL2_32(Rd, Rn, Rm) EMIT(ADL_vector(1, 1, 0b10, Rm, 1, Rn, Rd)) + +// Add Pairwise +#define ADDLP_vector(Q, U, size, op, Rn, Rd) ((Q)<<30 | (U)<<29 | 0b01110<<24 | (size)<<22 | 1<<21 | (op)<<14 | 0b10<<12 | 0b10<<10 | (Rn)<<5 | (Rd)) +#define SADDLPQ_8(Rd, Rn) EMIT(ADDLP_vector(1, 0, 0b00, 0, Rn, Rd)) +#define SADDLPQ_16(Rd, Rn) EMIT(ADDLP_vector(1, 0, 0b01, 0, Rn, Rd)) +#define SADDLPQ_32(Rd, Rn) EMIT(ADDLP_vector(1, 0, 0b10, 0, Rn, Rd)) +#define SADDLP_8(Rd, Rn) EMIT(ADDLP_vector(0, 0, 0b00, 0, Rn, Rd)) +#define SADDLP_16(Rd, Rn) EMIT(ADDLP_vector(0, 0, 0b01, 0, Rn, Rd)) +#define SADDLP_32(Rd, Rn) EMIT(ADDLP_vector(0, 0, 0b10, 0, Rn, Rd)) +#define UADDLPQ_8(Rd, Rn) EMIT(ADDLP_vector(1, 1, 0b00, 0, Rn, Rd)) +#define UADDLPQ_16(Rd, Rn) EMIT(ADDLP_vector(1, 1, 0b01, 0, Rn, Rd)) +#define UADDLPQ_32(Rd, Rn) EMIT(ADDLP_vector(1, 1, 0b10, 0, Rn, Rd)) +#define UADDLP_8(Rd, Rn) EMIT(ADDLP_vector(0, 1, 0b00, 0, Rn, Rd)) +#define UADDLP_16(Rd, Rn) EMIT(ADDLP_vector(0, 1, 0b01, 0, Rn, Rd)) +#define UADDLP_32(Rd, Rn) EMIT(ADDLP_vector(0, 1, 0b10, 0, Rn, Rd)) + +// Add accros vector +#define ADDLV_vector(Q, U, size, Rn, Rd) ((Q)<<30 | (U)<<29 | 0b01110<<24 | (size)<<22 | 0b11000<<17 | 0b00011<<12 | 0b10<<10 | (Rn)<<5 | (Rd)) +#define SADDLVQ_8(Rd, Rn) EMIT(ADDLV_vector(1, 0, 0b00, Rn, Rd)) +#define SADDLVQ_16(Rd, Rn) EMIT(ADDLV_vector(1, 0, 0b01, Rn, Rd)) +#define SADDLVQ_32(Rd, Rn) EMIT(ADDLV_vector(1, 0, 0b10, Rn, Rd)) +#define SADDLV_8(Rd, Rn) EMIT(ADDLV_vector(0, 0, 0b00, Rn, Rd)) +#define SADDLV_16(Rd, Rn) EMIT(ADDLV_vector(0, 0, 0b01, Rn, Rd)) +#define SADDLV_32(Rd, Rn) EMIT(ADDLV_vector(0, 0, 0b10, Rn, Rd)) +#define UADDLVQ_8(Rd, Rn) EMIT(ADDLV_vector(1, 1, 0b00, Rn, Rd)) +#define UADDLVQ_16(Rd, Rn) EMIT(ADDLV_vector(1, 1, 0b01, Rn, Rd)) +#define UADDLVQ_32(Rd, Rn) EMIT(ADDLV_vector(1, 1, 0b10, Rn, Rd)) +#define UADDLV_8(Rd, Rn) EMIT(ADDLV_vector(0, 1, 0b00, Rn, Rd)) +#define UADDLV_16(Rd, Rn) EMIT(ADDLV_vector(0, 1, 0b01, Rn, Rd)) +#define UADDLV_32(Rd, Rn) EMIT(ADDLV_vector(0, 1, 0b10, Rn, Rd)) + #endif //__ARM64_EMITTER_H__ diff --git a/src/dynarec/arm64_printer.c b/src/dynarec/arm64_printer.c index d7c52e97..606271af 100755 --- a/src/dynarec/arm64_printer.c +++ b/src/dynarec/arm64_printer.c @@ -1137,6 +1137,36 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr) return buff; } + // Absolute Difference + // SABA / SABD / UABA / UABD + if(isMask(opcode, "0QU01110ff1mmmmm0111c1nnnnnddddd", &a)) { + const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "???"}; + const char* Vd = Y[(sf<<1) | a.Q]; + snprintf(buff, sizeof(buff), "%cAB%c V%d.%s, V%d.%s, V%d.%s", a.U?'U':'S', a.c?'A':'D', Rd, Vd, Rn, Vd, Rm, Vd); + return buff; + } + if(isMask(opcode, "0QU01110ff1mmmmm01c100nnnnnddddd", &a)) { + const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "???"}; + const char* Vd = Y[(sf<<1) | a.Q]; + const char* Z[] = {"8H", "4S", "2D", "?"}; + const char* Va = Y[(sf<<1)]; + snprintf(buff, sizeof(buff), "%cAB%cL%s V%d.%s, V%d.%s, V%d.%s", a.U?'U':'S', a.c?'A':'D', a.Q?"2":"", Rd, Va, Rn, Vd, Rm, Vd); + return buff; + } + // Add pair / accros vector + if(isMask(opcode, "0QU01110ff1000000c1010nnnnnddddd", &a)) { + const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "???"}; + const char* Vd = Y[(sf<<1) | a.Q]; + snprintf(buff, sizeof(buff), "%cAD%cLP V%d.%s, V%d.%s", a.U?'U':'S', a.c?'A':'D', Rd, Vd, Rn, Vd); + return buff; + } + if(isMask(opcode, "0QU01110ff110000001110nnnnnddddd", &a)) { + const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "???"}; + const char* Vd = Y[(sf<<1) | a.Q]; + const char* Z[] = {"H", "S", "D", "?"}; + snprintf(buff, sizeof(buff), "%cADDLV V%d.%s, V%d.%s", a.U?'U':'S', Rd, Z[sf], Rn, Vd); + return buff; + } snprintf(buff, sizeof(buff), "%08X ???", __builtin_bswap32(opcode)); diff --git a/src/dynarec/dynarec_arm64_660f.c b/src/dynarec/dynarec_arm64_660f.c index b285b9e5..f9432aaf 100755 --- a/src/dynarec/dynarec_arm64_660f.c +++ b/src/dynarec/dynarec_arm64_660f.c @@ -53,10 +53,11 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n uint64_t tmp64u; int v0, v1; int q0, q1; - int d0; + int d0, d1; int fixedaddress; MAYUSE(d0); + MAYUSE(d1); MAYUSE(q0); MAYUSE(q1); MAYUSE(eb1); @@ -991,6 +992,22 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n VUMULL_32(v0, q0, q1); break; + case 0xF6: + INST_NAME("PSADBW Gx, Ex"); + nextop = F8; + GETGX(q0); + GETEX(q1, 0); + d0 = fpu_get_scratch(dyn); + d1 = fpu_get_scratch(dyn); + VEOR(d1, d1, d1); // is it necessary? + UABDL_8(d0, q0, q1); + UADDLVQ_16(d1, d0); + VMOVeD(q0, 0, d1, 0); + UABDL2_8(d0, q0, q1); + UADDLVQ_16(d1, d0); + VMOVeD(q0, 1, d1, 0); + break; + case 0xF8: INST_NAME("PSUBB Gx,Ex"); nextop = F8; |