diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2024-09-24 23:03:11 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-24 17:03:11 +0200 |
| commit | 2d0b60898cc4b7d7feaa49f47d3d569d407e93c1 (patch) | |
| tree | 854688c32639949babb375aca9755f407c7c9030 /src | |
| parent | c25fc8cc24bfcd67772971bbe467d0e7c6250d54 (diff) | |
| download | box64-2d0b60898cc4b7d7feaa49f47d3d569d407e93c1.tar.gz box64-2d0b60898cc4b7d7feaa49f47d3d569d407e93c1.zip | |
[RV64_DYNAREC] Added more opcodes for vector (#1863)
* [RV64_DYNAREC] Added more opcodes for vector * [RV64_DYNAREC] Added more opcodes for vector * [RV64_DYNAREC] Added more opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_0f_vector.c | 15 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_660f_vector.c | 99 |
2 files changed, 113 insertions, 1 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f_vector.c b/src/dynarec/rv64/dynarec_rv64_0f_vector.c index 96f7e7ee..104db227 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f_vector.c +++ b/src/dynarec/rv64/dynarec_rv64_0f_vector.c @@ -193,6 +193,21 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, SMWRITE2(); } break; + case 0x57: + INST_NAME("XORPS Gx, Ex"); + nextop = F8; + SET_ELEMENT_WIDTH(x1, VECTOR_SEWANY, 1); + GETG; + if (MODREG && ((nextop & 7) + (rex.b << 3) == gd)) { + // special case for XORPS Gx, Gx + q0 = sse_get_reg_empty_vector(dyn, ninst, x1, gd); + VXOR_VV(q0, q0, q0, VECTOR_UNMASKED); + } else { + q0 = sse_get_reg_vector(dyn, ninst, x1, gd, 1, dyn->vector_eew); + GETEX_vector(q1, 0, 0, dyn->vector_eew); + VXOR_VV(q0, q0, q1, VECTOR_UNMASKED); + } + break; case 0xC6: INST_NAME("SHUFPS Gx, Ex, Ib"); nextop = F8; diff --git a/src/dynarec/rv64/dynarec_rv64_660f_vector.c b/src/dynarec/rv64/dynarec_rv64_660f_vector.c index 6f6207dc..81afe063 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f_vector.c +++ b/src/dynarec/rv64/dynarec_rv64_660f_vector.c @@ -47,6 +47,87 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i MAYUSE(eb2); MAYUSE(j64); switch (opcode) { + case 0x10: + INST_NAME("MOVUPD Gx, Ex"); + nextop = F8; + GETG; + if (MODREG) { + SET_ELEMENT_WIDTH(x1, VECTOR_SEWANY, 1); + v1 = sse_get_reg_vector(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0, dyn->vector_eew); + v0 = sse_get_reg_empty_vector(dyn, ninst, x1, gd); + VMV_V_V(v0, v1); + } else { + SET_ELEMENT_WIDTH(x1, VECTOR_SEW8, 1); // unaligned! + SMREAD(); + v0 = sse_get_reg_empty_vector(dyn, ninst, x1, gd); + addr = geted(dyn, addr, ninst, nextop, &ed, x2, x3, &fixedaddress, rex, NULL, 0, 0); + VLE8_V(v0, ed, VECTOR_UNMASKED, VECTOR_NFIELD1); + } + break; + case 0x11: + INST_NAME("MOVUPD Ex, Gx"); + nextop = F8; + GETG; + if (MODREG) { + SET_ELEMENT_WIDTH(x1, VECTOR_SEWANY, 1); + v0 = sse_get_reg_vector(dyn, ninst, x1, gd, 0, dyn->vector_eew); + v1 = sse_get_reg_empty_vector(dyn, ninst, x1, (nextop & 7) + (rex.b << 3)); + VMV_V_V(v1, v0); + } else { + SET_ELEMENT_WIDTH(x1, VECTOR_SEW8, 1); // unaligned! + v0 = sse_get_reg_vector(dyn, ninst, x1, gd, 0, dyn->vector_eew); + addr = geted(dyn, addr, ninst, nextop, &ed, x2, x3, &fixedaddress, rex, NULL, 0, 0); + VSE8_V(v0, ed, VECTOR_UNMASKED, VECTOR_NFIELD1); + SMWRITE2(); + } + break; + case 0x14: + INST_NAME("UNPCKLPD Gx, Ex"); + nextop = F8; + SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1); + // GX->q[0] = GX->q[0]; -> unchanged + // GX->q[1] = EX->q[0]; + GETGX_vector(v0, 1, VECTOR_SEW64); + if (MODREG) { + v1 = sse_get_reg_vector(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0, VECTOR_SEW64); + if (v0 == v1) { + // for vslideup.vi, cannot be overlapped + v1 = fpu_get_scratch(dyn); + VMV_V_V(v1, v0); + } + VSLIDEUP_VI(v0, 1, v1, VECTOR_UNMASKED); + } else { + q0 = fpu_get_scratch(dyn); + VXOR_VV(q0, q0, q0, VECTOR_UNMASKED); + VMV_V_I(VMASK, 0b10); + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 0, 0); + VLUXEI64_V(v0, ed, q0, VECTOR_MASKED, VECTOR_NFIELD1); + } + break; + case 0x15: + INST_NAME("PUNPCKHQDQ Gx, Ex"); + nextop = F8; + SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1); + // GX->q[0] = GX->q[1]; + // GX->q[1] = EX->q[1]; + GETGX_vector(v0, 1, VECTOR_SEW64); + if (MODREG) { + v1 = sse_get_reg_vector(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0, VECTOR_SEW64); + q0 == fpu_get_scratch(dyn); + VSLIDE1DOWN_VX(q0, xZR, v0, VECTOR_UNMASKED); + VMV_X_S(x4, q0); + if (v0 != v1) { VMV_V_V(v0, v1); } + VMV_S_X(v0, x4); + } else { + q0 = fpu_get_scratch(dyn); + VMV_V_I(VMASK, 0b10); + VSLIDE1DOWN_VX(v0, xZR, v0, VECTOR_UNMASKED); + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 0, 0); + VLE64_V(v0, ed, VECTOR_MASKED, VECTOR_NFIELD1); + } + break; case 0x1F: return 0; case 0x28: @@ -66,6 +147,22 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i VLE_V(v0, ed, dyn->vector_eew, VECTOR_UNMASKED, VECTOR_NFIELD1); } break; + case 0x29: + INST_NAME("MOVAPD Ex, Gx"); + nextop = F8; + GETG; + SET_ELEMENT_WIDTH(x1, VECTOR_SEWANY, 1); + v0 = sse_get_reg_vector(dyn, ninst, x1, gd, 0, dyn->vector_eew); + if (MODREG) { + ed = (nextop & 7) + (rex.b << 3); + v1 = sse_get_reg_empty_vector(dyn, ninst, x1, ed); + VMV_V_V(v1, v0); + } else { + addr = geted(dyn, addr, ninst, nextop, &ed, x2, x3, &fixedaddress, rex, NULL, 0, 0); + VSE_V(v0, ed, dyn->vector_eew, VECTOR_UNMASKED, VECTOR_NFIELD1); + SMWRITE2(); + } + break; case 0x2E: case 0x2F: return 0; @@ -1217,7 +1314,7 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i VSE_V(v1, ed, dyn->vector_eew, VECTOR_UNMASKED, VECTOR_NFIELD1); } break; - case 0xBE: return 0; + case 0xA3 ... 0xC1: return 0; case 0xC4: INST_NAME("PINSRW Gx, Ed, Ib"); nextop = F8; |