From d3635126b727751d6b937a570e3351696748f7f1 Mon Sep 17 00:00:00 2001 From: wannacu Date: Thu, 31 Aug 2023 13:18:36 +0800 Subject: [ARM64_DYNAREC] Added 0F 38 01/02/03/05/06/07 opcodes --- src/dynarec/arm64/dynarec_arm64_0f.c | 56 ++++++++++++++++++++++++++++++++-- src/dynarec/arm64/dynarec_arm64_660f.c | 11 ++++++- 2 files changed, 64 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c index d1103c4e..0ede6e3b 100644 --- a/src/dynarec/arm64/dynarec_arm64_0f.c +++ b/src/dynarec/arm64/dynarec_arm64_0f.c @@ -425,7 +425,30 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin VAND(d0, d0, q1); // mask the index VTBL1_8(q0, q0, d0); break; - + case 0x01: + INST_NAME("PHADDW Gm, Em"); + nextop = F8; + GETGM(q0); + GETEM(q1, 0); + VADDP_16(q0, q0, q1); + break; + case 0x2: + INST_NAME("PHADDD Gm, Em"); + nextop = F8; + GETGM(q0); + GETEM(q1, 0); + VADDP_32(q0, q0, q1); + break; + case 0x03: + INST_NAME("PHADDSW Gm, Em"); + nextop = F8; + GETGM(q0); + GETEM(q1, 0); + v0 = fpu_get_scratch(dyn); + VUZP1_16(v0, q0, q1); + VUZP2_16(q0, q0, q1); + SQADD_16(q0, q0, v0); + break; case 0x04: INST_NAME("PMADDUBSW Gm,Em"); nextop = F8; @@ -439,7 +462,36 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin SADDLPQ_16(v1, v0); SQXTN_16(q0, v1); break; - + case 0x05: + INST_NAME("PHSUBW Gm,Em"); + nextop = F8; + GETGM(q0); + GETEM(q1, 0); + v0 = fpu_get_scratch(dyn); + VUZP1_16(v0, q0, q1); + VUZP2_16(q0, q0, q1); + VSUB_16(q0, v0, q0); + break; + case 0x06: + INST_NAME("PHSUBD Gm,Em"); + nextop = F8; + GETGM(q0); + GETEM(q1, 0); + v0 = fpu_get_scratch(dyn); + VUZP1_32(v0, q0, q1); + VUZP2_32(q0, q0, q1); + VSUB_32(q0, v0, q0); + break; + case 0x07: + INST_NAME("PHSUBSW Gm,Em"); + nextop = F8; + GETGM(q0); + GETEM(q1, 0); + v0 = fpu_get_scratch(dyn); + VUZP1_16(v0, q0, q1); + VUZP2_16(q0, q0, q1); + SQSUB_16(q0, v0, q0); + break; case 0x0B: INST_NAME("PMULHRSW Gm,Em"); nextop = F8; diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c index 30cfc937..7508bd0d 100644 --- a/src/dynarec/arm64/dynarec_arm64_660f.c +++ b/src/dynarec/arm64/dynarec_arm64_660f.c @@ -326,7 +326,16 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n GETEX(q1, 0, 0); VADDPQ_32(q0, q0, q1); break; - + case 0x03: + INST_NAME("PHADDSW Gx, Ex"); + nextop = F8; + GETGX(q0, 1); + GETEX(q1, 0, 0); + v0 = fpu_get_scratch(dyn); + VUZP1Q_16(v0, q0, q1); + VUZP2Q_16(q0, q0, q1); + SQADDQ_16(q0, q0, v0); + break; case 0x04: INST_NAME("PMADDUBSW Gx,Ex"); nextop = F8; -- cgit 1.4.1 From 41d5fa16a7cc6dc89aa19d1f6e04021174372c00 Mon Sep 17 00:00:00 2001 From: wannacu Date: Thu, 31 Aug 2023 13:19:17 +0800 Subject: [ARM64_DYNAREC] Added 66 0F 38 37 opcode --- src/dynarec/arm64/dynarec_arm64_660f.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c index 7508bd0d..85699ba6 100644 --- a/src/dynarec/arm64/dynarec_arm64_660f.c +++ b/src/dynarec/arm64/dynarec_arm64_660f.c @@ -676,7 +676,13 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n GETGX_empty(q0); UXTL_32(q0, q1); // 32bits->64bits break; - + case 0x37: + INST_NAME("PCMPGTQ Gx, Ex"); // SSE4 opcode! + nextop = F8; + GETEX(q1, 0, 0); + GETGX(q0, 1); + VCMGTQ_64(q0, q0, q1); + break; case 0x38: INST_NAME("PMINSB Gx, Ex"); // SSE4 opcode! nextop = F8; -- cgit 1.4.1 From be4791f8265533f8085cb01d8087c19eb0dae33b Mon Sep 17 00:00:00 2001 From: wannacu Date: Thu, 31 Aug 2023 13:41:36 +0800 Subject: [ARM64_DYNAREC] Added 0F 38 08/09/0A opcode --- src/dynarec/arm64/arm64_emitter.h | 9 +++++++++ src/dynarec/arm64/arm64_printer.c | 16 +++++++++++++++ src/dynarec/arm64/dynarec_arm64_0f.c | 39 ++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) (limited to 'src') diff --git a/src/dynarec/arm64/arm64_emitter.h b/src/dynarec/arm64/arm64_emitter.h index e27011db..16cca694 100644 --- a/src/dynarec/arm64/arm64_emitter.h +++ b/src/dynarec/arm64/arm64_emitter.h @@ -1600,6 +1600,15 @@ #define CMEQQ_0_16(Rd, Rn) EMIT(CMEQ_0_vector(1, 0b01, Rn, Rd)) #define CMEQQ_0_32(Rd, Rn) EMIT(CMEQ_0_vector(1, 0b10, Rn, Rd)) #define CMEQQ_0_64(Rd, Rn) EMIT(CMEQ_0_vector(1, 0b11, Rn, Rd)) +// Greater Than 0 +#define CMCond_0_vector(Q, U, size, op, Rn, Rd) ((Q)<<30 | (U)<<29 | 0b01110<<24 | (size)<<22 | 0b10000<<17 | 0b0100<<13 | (op)<<12 | 0b10<<10 | (Rn)<<5 | (Rd)) +#define CMGT_0_8(Rd, Rn) EMIT(CMCond_0_vector(0, 0, 0b00, 0, Rn, Rd)) +#define CMGT_0_16(Rd, Rn) EMIT(CMCond_0_vector(0, 0, 0b01, 0, Rn, Rd)) +#define CMGT_0_32(Rd, Rn) EMIT(CMCond_0_vector(0, 0, 0b10, 0, Rn, Rd)) +#define CMGTQ_0_8(Rd, Rn) EMIT(CMCond_0_vector(1, 0, 0b00, 0, Rn, Rd)) +#define CMGTQ_0_16(Rd, Rn) EMIT(CMCond_0_vector(1, 0, 0b01, 0, Rn, Rd)) +#define CMGTQ_0_32(Rd, Rn) EMIT(CMCond_0_vector(1, 0, 0b10, 0, Rn, Rd)) +#define CMGTQ_0_64(Rd, Rn) EMIT(CMCond_0_vector(1, 0, 0b11, 0, Rn, Rd)) // Vector Float CMP // EQual diff --git a/src/dynarec/arm64/arm64_printer.c b/src/dynarec/arm64/arm64_printer.c index 705314df..973255f8 100644 --- a/src/dynarec/arm64/arm64_printer.c +++ b/src/dynarec/arm64/arm64_printer.c @@ -950,6 +950,22 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr) snprintf(buff, sizeof(buff), "VCMEQ V%d.%s, V%d.%s, V%d.%s", Rd, Vd, Rn, Vd, Rm, Vd); return buff; } + // CMP zero + if(isMask(opcode, "0QU01110ff100000100o10nnnnnddddd", &a)) { + const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "2D"}; + const char* Z[] = {"GT", "GE", "EQ", "LE"}; + const char* Vd = Y[((sf)<<1) | a.Q]; + const char* Cond = Z[(a.o << 1 | a.U)]; + snprintf(buff, sizeof(buff), "VCM%s V%d.%s, V%d.%s, #0", Cond, Rd, Vd, Rn, Vd); + return buff; + } + // CMPLT zero + if(isMask(opcode, "0Q001110ff100000101010nnnnnddddd", &a)) { + const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "2D"}; + const char* Vd = Y[((sf)<<1) | a.Q]; + snprintf(buff, sizeof(buff), "VCMLT V%d.%s, V%d.%s, #0", Rd, Vd, Rn, Vd); + return buff; + } // MIN/MAX if(isMask(opcode, "0QU01110ff1mmmmm0110o1nnnnnddddd", &a)) { const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "2D"}; diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c index 0ede6e3b..fe39a5e6 100644 --- a/src/dynarec/arm64/dynarec_arm64_0f.c +++ b/src/dynarec/arm64/dynarec_arm64_0f.c @@ -492,6 +492,45 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin VUZP2_16(q0, q0, q1); SQSUB_16(q0, v0, q0); break; + case 0x08: + INST_NAME("PSIGNB Gm,Em"); + nextop = F8; + GETGM(q0); + GETEM(q1, 0); + v0 = fpu_get_scratch(dyn); + v1 = fpu_get_scratch(dyn); + CMGT_0_8(v0, q1); + VAND(v0, v0, q0); + CMLT_0_8(v1, q1); + VMUL_8(q0, q0, v1); + VORR(q0, q0, v0); + break; + case 0x09: + INST_NAME("PSIGNW Gm,Em"); + nextop = F8; + GETGM(q0); + GETEM(q1, 0); + v0 = fpu_get_scratch(dyn); + v1 = fpu_get_scratch(dyn); + CMGT_0_16(v0, q1); + VAND(v0, v0, q0); + CMLT_0_16(v1, q1); + VMUL_16(q0, q0, v1); + VORR(q0, q0, v0); + break; + case 0x0A: + INST_NAME("PSIGND Gm,Em"); + nextop = F8; + GETGM(q0); + GETEM(q1, 0); + v0 = fpu_get_scratch(dyn); + v1 = fpu_get_scratch(dyn); + CMGT_0_32(v0, q1); + VAND(v0, v0, q0); + CMLT_0_32(v1, q1); + VMUL_32(q0, q0, v1); + VORR(q0, q0, v0); + break; case 0x0B: INST_NAME("PMULHRSW Gm,Em"); nextop = F8; -- cgit 1.4.1