From 1e34db98a854c0adf0e38de120c7df896c11f5f0 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Wed, 30 Oct 2024 04:01:14 +0800 Subject: [RV64_DYNAREC] Added more opcodes for vector (#1978) --- src/dynarec/rv64/dynarec_rv64_0f_vector.c | 44 +++++++++++++++++++++++++++++ src/dynarec/rv64/dynarec_rv64_f30f_vector.c | 38 +++++++++++++++++++++++-- 2 files changed, 80 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/dynarec/rv64/dynarec_rv64_0f_vector.c b/src/dynarec/rv64/dynarec_rv64_0f_vector.c index 7435a468..d8036ed4 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f_vector.c +++ b/src/dynarec/rv64/dynarec_rv64_0f_vector.c @@ -378,6 +378,50 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, VADD_VX(q0, q1, xZR, VECTOR_MASKED); } break; + case 0xC2: + INST_NAME("CMPPS Gx, Ex, Ib"); + nextop = F8; + SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1); + GETGX_vector(v0, 1, VECTOR_SEW32); + GETEX_vector(v1, 0, 1, VECTOR_SEW32); + u8 = F8; + if ((u8 & 7) == 0) { // Equal + VMFEQ_VV(VMASK, v0, v1, VECTOR_UNMASKED); + } else if ((u8 & 7) == 4) { // Not Equal or unordered + VMFEQ_VV(VMASK, v0, v1, VECTOR_UNMASKED); + VXOR_VI(VMASK, VMASK, 0x1F, VECTOR_UNMASKED); + } else { + d0 = fpu_get_scratch(dyn); + VMFEQ_VV(VMASK, v0, v0, VECTOR_UNMASKED); + VMFEQ_VV(d0, v1, v1, VECTOR_UNMASKED); + VMAND_MM(VMASK, VMASK, d0); + switch (u8 & 7) { + case 1: // Less than + VMFLT_VV(d0, v0, v1, VECTOR_UNMASKED); + VMAND_MM(VMASK, VMASK, d0); + break; + case 2: // Less or equal + VMFLE_VV(d0, v0, v1, VECTOR_UNMASKED); + VMAND_MM(VMASK, VMASK, d0); + break; + case 3: // NaN + VXOR_VI(VMASK, VMASK, 0x1F, VECTOR_UNMASKED); + break; + case 5: // Greater or equal or unordered + VMFLE_VV(d0, v1, v0, VECTOR_UNMASKED); + VMORN_MM(VMASK, d0, VMASK); + break; + case 6: // Greater or unordered, test inverted, N!=V so unordered or less than (inverted) + VMFLT_VV(d0, v1, v0, VECTOR_UNMASKED); + VMORN_MM(VMASK, d0, VMASK); + break; + case 7: // Not NaN + break; + } + } + VXOR_VV(v0, v0, v0, VECTOR_UNMASKED); + VXOR_VI(v0, v0, 0x1F, VECTOR_MASKED); + break; case 0xC6: INST_NAME("SHUFPS Gx, Ex, Ib"); nextop = F8; diff --git a/src/dynarec/rv64/dynarec_rv64_f30f_vector.c b/src/dynarec/rv64/dynarec_rv64_f30f_vector.c index d5ac666a..c4f82e45 100644 --- a/src/dynarec/rv64/dynarec_rv64_f30f_vector.c +++ b/src/dynarec/rv64/dynarec_rv64_f30f_vector.c @@ -124,6 +124,24 @@ uintptr_t dynarec64_F30F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i break; case 0x38: return 0; + case 0x58: + INST_NAME("ADDSS Gx, Ex"); + nextop = F8; + SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1); + if (MODREG) { + GETGX_vector(v0, 1, VECTOR_SEW32); + v1 = sse_get_reg_vector(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0, VECTOR_SEW32); + } else { + SMREAD(); + v1 = fpu_get_scratch(dyn); + addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0); + LWU(x4, ed, fixedaddress); + VMV_S_X(v1, x4); + GETGX_vector(v0, 1, VECTOR_SEW32); + } + VECTOR_LOAD_VMASK(0b0001, x4, 1); + VFADD_VV(v0, v0, v1, VECTOR_MASKED); + break; case 0x59: INST_NAME("MULSS Gx, Ex"); nextop = F8; @@ -136,7 +154,6 @@ uintptr_t dynarec64_F30F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i v1 = fpu_get_scratch(dyn); addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0); LWU(x4, ed, fixedaddress); - VXOR_VV(v1, v1, v1, VECTOR_UNMASKED); VMV_S_X(v1, x4); GETGX_vector(v0, 1, VECTOR_SEW32); } @@ -177,7 +194,6 @@ uintptr_t dynarec64_F30F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i v1 = fpu_get_scratch(dyn); addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0); LWU(x4, ed, fixedaddress); - VXOR_VV(v1, v1, v1, VECTOR_UNMASKED); VMV_S_X(v1, x4); GETGX_vector(v0, 1, VECTOR_SEW32); } @@ -192,6 +208,24 @@ uintptr_t dynarec64_F30F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i VMV_S_X(v0, x4); } break; + case 0x5C: + INST_NAME("SUBSS Gx, Ex"); + nextop = F8; + SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1); + if (MODREG) { + GETGX_vector(v0, 1, VECTOR_SEW32); + v1 = sse_get_reg_vector(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0, VECTOR_SEW32); + } else { + SMREAD(); + v1 = fpu_get_scratch(dyn); + addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0); + LWU(x4, ed, fixedaddress); + VMV_S_X(v1, x4); + GETGX_vector(v0, 1, VECTOR_SEW32); + } + VECTOR_LOAD_VMASK(0b0001, x4, 1); + VFSUB_VV(v0, v0, v1, VECTOR_MASKED); + break; case 0x5D: INST_NAME("MINSS Gx, Ex"); nextop = F8; -- cgit 1.4.1