diff --git a/src/dynarec/rv64/dynarec_rv64_660f_vector.c b/src/dynarec/rv64/dynarec_rv64_660f_vector.c index ede57dc2..ab5053c3 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f_vector.c +++ b/src/dynarec/rv64/dynarec_rv64_660f_vector.c @@ -808,6 +808,7 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i default: DEFAULT_VECTOR; } break; + case 0x40 ... 0x4F: return 0; case 0x50: INST_NAME("PMOVMSKD Gd, Ex"); nextop = F8; @@ -929,6 +930,26 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i VFSGNJN_VV(q0, q0, q0, VECTOR_MASKED); } break; + case 0x5A: + INST_NAME("CVTPD2PS Gx, Ex"); + nextop = F8; + SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1); + GETEX_vector(v1, 0, 0, VECTOR_SEW64); + GETGX_empty_vector(v0); + if (v1 & 1) { + d1 = fpu_get_scratch_lmul(dyn, VECTOR_LMUL2); + VMV_V_V(d1, v1); + } else { + d1 = v1; + } + vector_vsetvli(dyn, ninst, x1, VECTOR_SEW32, VECTOR_LMUL1, 0.5); + d0 = fpu_get_scratch_lmul(dyn, VECTOR_LMUL2); + VFNCVT_F_F_W(d0, d1, VECTOR_UNMASKED); + vector_vsetvli(dyn, ninst, x1, VECTOR_SEW64, VECTOR_LMUL1, 1); + if (!rv64_xtheadvector) VXOR_VV(v0, v0, v0, VECTOR_UNMASKED); + VMV_X_S(x4, d0); + VMV_S_X(v0, x4); + break; case 0x5B: if (!box64_dynarec_fastround) return 0; INST_NAME("CVTPS2DQ Gx, Ex"); diff --git a/src/dynarec/rv64/dynarec_rv64_f20f_vector.c b/src/dynarec/rv64/dynarec_rv64_f20f_vector.c index 2c3352e4..52247de8 100644 --- a/src/dynarec/rv64/dynarec_rv64_f20f_vector.c +++ b/src/dynarec/rv64/dynarec_rv64_f20f_vector.c @@ -95,6 +95,23 @@ uintptr_t dynarec64_F20F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i SMWRITE2(); } break; + case 0x12: + INST_NAME("MOVDDUP Gx, Ex"); + nextop = F8; + SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1); + if (MODREG) { + v1 = sse_get_reg_vector(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0, VECTOR_SEW64); + GETGX_empty_vector(v0); + VMV_X_S(x4, v1); + } else { + SMREAD(); + GETGX_empty_vector(v0); + v1 = fpu_get_scratch(dyn); + addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0); + LD(x4, ed, fixedaddress); + } + VMV_V_X(v0, x4); + break; case 0x2A: INST_NAME("CVTSI2SD Gx, Ed"); nextop = F8; @@ -526,6 +543,25 @@ uintptr_t dynarec64_F20F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i } VRGATHER_VV(v0, v1, d0, VECTOR_UNMASKED); break; + case 0x7C: + INST_NAME("HADDPS Gx, Ex"); + nextop = F8; + SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1); + GETGX_vector(q0, 1, VECTOR_SEW32); + GETEX_vector(q1, 0, 0, VECTOR_SEW32); + v0 = fpu_get_scratch_lmul(dyn, VECTOR_LMUL2); + d1 = fpu_get_scratch_lmul(dyn, VECTOR_LMUL2); + d0 = fpu_get_scratch_lmul(dyn, VECTOR_LMUL2); + VMV_V_V(v0, q0); + if (q1 & 1) VMV_V_V(d1, q1); + vector_vsetvli(dyn, ninst, x1, VECTOR_SEW32, VECTOR_LMUL2, 2); + VSLIDEUP_VI(v0, (q1 & 1) ? d1 : q1, 4, VECTOR_UNMASKED); + vector_vsetvli(dyn, ninst, x1, VECTOR_SEW32, VECTOR_LMUL1, 1); + ADDI(x4, xZR, 32); + VNSRL_WX(d0, v0, xZR, VECTOR_UNMASKED); + VNSRL_WX(d1, v0, x4, VECTOR_UNMASKED); + VFADD_VV(q0, d1, d0, VECTOR_UNMASKED); + break; case 0xC2: INST_NAME("CMPSD 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 56a91575..ac580845 100644 --- a/src/dynarec/rv64/dynarec_rv64_f30f_vector.c +++ b/src/dynarec/rv64/dynarec_rv64_f30f_vector.c @@ -582,6 +582,27 @@ uintptr_t dynarec64_F30F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i VMV_S_X(d0, x2); } break; + case 0xE6: + INST_NAME("CVTDQ2PD Gx, Ex"); + nextop = F8; + SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1); + if (MODREG) { + v1 = sse_get_reg_vector(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0, VECTOR_SEW64); + GETGX_empty_vector(v0); + } else { + SMREAD(); + v1 = fpu_get_scratch(dyn); + addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0); + LD(x4, ed, fixedaddress); + VMV_S_X(v1, x4); + GETGX_empty_vector(v0); + } + vector_vsetvli(dyn, ninst, x1, VECTOR_SEW32, VECTOR_LMUL1, 0.5); + d0 = fpu_get_scratch_lmul(dyn, VECTOR_LMUL2); + VFWCVT_F_X_V(d0, v1, VECTOR_UNMASKED); + vector_vsetvli(dyn, ninst, x1, VECTOR_SEW64, VECTOR_LMUL1, 1); + VMV_V_V(v0, d0); + break; default: DEFAULT_VECTOR; }