diff --git a/src/dynarec/rv64/dynarec_rv64_00_0.c b/src/dynarec/rv64/dynarec_rv64_00_0.c index 4399c7c1f..5172bf7af 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_0.c +++ b/src/dynarec/rv64/dynarec_rv64_00_0.c @@ -478,6 +478,9 @@ uintptr_t dynarec64_00_0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int i64 = F32S; emit_sub32c(dyn, ninst, rex, xRAX, i64, x2, x3, x4, x5); break; + case 0x2E: + INST_NAME("CS:"); + break; case 0x30: INST_NAME("XOR Eb, Gb"); SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION); diff --git a/src/dynarec/rv64/dynarec_rv64_660f_vector.c b/src/dynarec/rv64/dynarec_rv64_660f_vector.c index a339ccf23..f206d7d52 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f_vector.c +++ b/src/dynarec/rv64/dynarec_rv64_660f_vector.c @@ -400,6 +400,16 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i vector_vsetvli(dyn, ninst, x1, VECTOR_SEW16, VECTOR_LMUL1, 1); VNSRL_WI(q0, v0, 1, VECTOR_UNMASKED); break; + case 0x10: + INST_NAME("PBLENDVB Gx, Ex"); + nextop = F8; + SET_ELEMENT_WIDTH(x1, VECTOR_SEW8, 1); + GETGX_vector(q0, 1, VECTOR_SEW8); + GETEX_vector(q1, 0, 0, VECTOR_SEW8); + v0 = sse_get_reg_vector(dyn, ninst, x4, 0, 0, VECTOR_SEW8); + VMSLT_VX(VMASK, v0, xZR, VECTOR_UNMASKED); + VADD_VX(q0, q1, xZR, VECTOR_MASKED); + break; case 0x14: INST_NAME("PBLENDVPS Gx, Ex"); nextop = F8; @@ -589,6 +599,16 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i vector_vsetvli(dyn, ninst, x1, VECTOR_SEW64, VECTOR_LMUL1, 1); if (v0 != q0) VMV_V_V(q0, v0); break; + case 0x29: + INST_NAME("PCMPEQQ Gx, Ex"); // SSE4 opcode! + nextop = F8; + SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1); + GETEX_vector(q1, 0, 0, VECTOR_SEW64); + GETGX_vector(q0, 1, VECTOR_SEW64); + VMSEQ_VV(VMASK, q0, q1, VECTOR_UNMASKED); + VXOR_VV(q0, q0, q0, VECTOR_UNMASKED); + VMERGE_VIM(q0, q0, 0b11111); + break; case 0x2B: INST_NAME("PACKUSDW Gx, Ex"); nextop = F8; diff --git a/src/dynarec/rv64/dynarec_rv64_67.c b/src/dynarec/rv64/dynarec_rv64_67.c index a42cc19ee..eeedc8317 100644 --- a/src/dynarec/rv64/dynarec_rv64_67.c +++ b/src/dynarec/rv64/dynarec_rv64_67.c @@ -29,8 +29,8 @@ uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni uint8_t opcode = F8; uint8_t nextop; - uint8_t gd, ed, wback, wb, wb1, wb2, gb, gb1, gb2, eb1, eb2; - int64_t fixedaddress; + uint8_t gd, ed, wback, wb, wb1, wb2, gback, gb, gb1, gb2, eb1, eb2; + int64_t fixedaddress, gdoffset; int unscaled; int8_t i8; uint8_t u8; @@ -136,6 +136,23 @@ uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0x0F: opcode = F8; switch (opcode) { + case 0x11: + switch (rep) { + case 0: + INST_NAME("MOVUPS Ex, Gx"); + nextop = F8; + GETGX(); + GETEX32(x2, 0, 8); + LD(x3, gback, gdoffset + 0); + LD(x4, gback, gdoffset + 8); + SD(x3, wback, fixedaddress + 0); + SD(x4, wback, fixedaddress + 8); + if (!MODREG) SMWRITE2(); + break; + default: + DEFAULT; + } + break; case 0x2E: // no special check... case 0x2F: diff --git a/src/dynarec/rv64/dynarec_rv64_67_vector.c b/src/dynarec/rv64/dynarec_rv64_67_vector.c index 297893b0e..236133081 100644 --- a/src/dynarec/rv64/dynarec_rv64_67_vector.c +++ b/src/dynarec/rv64/dynarec_rv64_67_vector.c @@ -66,7 +66,28 @@ uintptr_t dynarec64_67_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, opcode = F8; switch (opcode) { case 0x11: - DEFAULT_VECTOR; + switch (rep) { + case 0: + INST_NAME("MOVUPS Ex,Gx"); + nextop = F8; + if (MODREG) { + SET_ELEMENT_WIDTH(x1, VECTOR_SEWANY, 1); + GETGX_vector(v0, 0, dyn->vector_eew); + ed = (nextop & 7) + (rex.b << 3); + v1 = sse_get_reg_empty_vector(dyn, ninst, x1, ed); + VMV_V_V(v1, v0); + } else { + SET_ELEMENT_WIDTH(x1, VECTOR_SEW8, 1); // unaligned! + GETGX_vector(v0, 0, dyn->vector_eew); + addr = geted32(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; + default: + DEFAULT; + } + break; case 0x2E: case 0x2F: DEFAULT_VECTOR; diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index 4c223b6bc..1183feb70 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -474,6 +474,17 @@ ed = 16; \ addr = geted(dyn, addr, ninst, nextop, &wback, a, x3, &fixedaddress, rex, NULL, I12, D); \ } +#define GETEX32(a, D, I12) \ + if (MODREG) { \ + ed = (nextop & 7) + (rex.b << 3); \ + sse_forget_reg(dyn, ninst, x3, ed); \ + fixedaddress = offsetof(x64emu_t, xmm[ed]); \ + wback = xEmu; \ + } else { \ + SMREAD(); \ + ed = 16; \ + addr = geted32(dyn, addr, ninst, nextop, &wback, a, x3, &fixedaddress, rex, NULL, I12, D); \ + } // Get GX as a quad (might use x1) #define GETGX_vector(a, w, sew) \ diff --git a/src/dynarec/rv64/dynarec_rv64_pass0.h b/src/dynarec/rv64/dynarec_rv64_pass0.h index ed5b7b0b5..3c675e33c 100644 --- a/src/dynarec/rv64/dynarec_rv64_pass0.h +++ b/src/dynarec/rv64/dynarec_rv64_pass0.h @@ -74,7 +74,7 @@ --dyn->size; \ *ok = -1; \ if (ninst) { dyn->insts[ninst - 1].x64.size = ip - dyn->insts[ninst - 1].x64.addr; } \ - if (BOX64ENV(dynarec_log) >= LOG_INFO || BOX64DRENV(dynarec_dump) || BOX64ENV(dynarec_missing) == 1) { \ + if (BOX64ENV(dynarec_log) >= LOG_INFO || BOX64DRENV(dynarec_dump) || BOX64ENV(dynarec_missing)) { \ dynarec_log(LOG_NONE, "%p: Dynarec stopped because of %s Opcode ", (void*)ip, rex.is32bits ? "x86" : "x64"); \ zydis_dec_t* dec = rex.is32bits ? my_context->dec32 : my_context->dec; \ if (dec) { \