diff options
| author | phorcys <phorcys@126.com> | 2025-04-14 15:14:34 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-14 09:14:34 +0200 |
| commit | 1bd471bf135dce48949975eeee89b3324ee75b51 (patch) | |
| tree | ec59867f8a1c151e04558e457a97e85bcdcad633 /src | |
| parent | 21911620c8e983152878795f9939e52a38603f75 (diff) | |
| download | box64-1bd471bf135dce48949975eeee89b3324ee75b51.tar.gz box64-1bd471bf135dce48949975eeee89b3324ee75b51.zip | |
[LA64_DYNAREC] Add mmx related mov op (#2526)
* [LA64_DYNAREC] Add SSE2's MOVQ2DQ/MOVDQ2Q mmx op * [LA64_DYNAREC] Add mmx mov ops.
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_0f.c | 58 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_660f.c | 14 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_f20f.c | 7 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_f30f.c | 38 |
4 files changed, 102 insertions, 15 deletions
diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c index 18714f81..33843341 100644 --- a/src/dynarec/la64/dynarec_la64_0f.c +++ b/src/dynarec/la64/dynarec_la64_0f.c @@ -692,6 +692,29 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni VFMAX_S(v0, v0, v1); } break; + case 0x6E: + INST_NAME("MOVD Gm, Ed"); + nextop = F8; + GETG; + v0 = mmx_get_reg_empty(dyn, ninst, x1, x2, x3, gd); + if (MODREG) { + ed = TO_NAT(nextop & 7); + if (rex.w) { + MOVGR2FR_D(v0, ed); + } else { + MOVGR2FR_W(v0, ed); + MOVGR2FRH_W(v0, xZR); + } + } else { + addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, NULL, 1, 0); + if (rex.w) { + FLD_D(v0, wback, fixedaddress); + } else { + FLD_S(v0, wback, fixedaddress); + MOVGR2FRH_W(v0, xZR); + } + } + break; case 0x6F: INST_NAME("MOVQ Gm, Em"); nextop = F8; @@ -1489,6 +1512,16 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni GETEM(q1, 0); VMUL_H(q0, q0, q1); break; + case 0xD7: + nextop = F8; + INST_NAME("PMOVMSKB Gd, Em"); + GETGD; + v0 = fpu_get_scratch(dyn); + GETEM(v1, 0); + VMSKLTZ_B(v0, v1); + MOVFR2GR_D(x1, v0); + BSTRPICK_D(gd, x1, 7, 0); + break; case 0xD8: INST_NAME("PSUBUSB Gm, Em"); nextop = F8; @@ -1538,6 +1571,19 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni GETEM(v1, 0); VMUH_H(v0, v0, v1); break; + case 0xE7: + INST_NAME("MOVNTQ Em, Gm"); + nextop = F8; + GETGM(v0); + if (MODREG) { + v1 = mmx_get_reg_empty(dyn, ninst, x1, x2, x3, nextop & 7); + FMOV_D(v1, v0); + } else { + addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 1, 0); + FST_D(v0, ed, fixedaddress); + SMWRITE2(); + } + break; case 0xE8: INST_NAME("PSUBSB Gm,Em"); nextop = F8; @@ -1626,6 +1672,18 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni VMADDWOD_W_H(q0, v0, v1); VBSLL_V(v0, q0, 0); break; + case 0xF7: + INST_NAME("MASKMOVQ Gm, Em"); + nextop = F8; + GETGM(v0); + GETEM(v1, 0); + q0 = fpu_get_scratch(dyn); + q1 = fpu_get_scratch(dyn); + VSLTI_B(q1, v1, 0); // q1 = byte selection mask + FLD_D(q0, xRDI, 0); + VBITSEL_V(q0, q0, v0, q1); // sel v0 if mask is 1 + FST_D(q0, xRDI, 0); + break; case 0xF8: INST_NAME("PSUBB Gm, Em"); nextop = F8; diff --git a/src/dynarec/la64/dynarec_la64_660f.c b/src/dynarec/la64/dynarec_la64_660f.c index 8fe3981a..fc375fd7 100644 --- a/src/dynarec/la64/dynarec_la64_660f.c +++ b/src/dynarec/la64/dynarec_la64_660f.c @@ -208,6 +208,20 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int SMWRITE2(); } break; + case 0x2B: + INST_NAME("MOVNTPD Ex,Gx"); + nextop = F8; + GETG; + v0 = sse_get_reg(dyn, ninst, x1, gd, 0); + if (MODREG) { + ed = (nextop & 7) + (rex.b << 3); + v1 = sse_get_reg_empty(dyn, ninst, x1, ed); + VOR_V(v1, v0, v0); + } else { + addr = geted(dyn, addr, ninst, nextop, &ed, x2, x3, &fixedaddress, rex, NULL, 1, 0); + VST(v0, ed, fixedaddress); + } + break; case 0x2E: // no special check... case 0x2F: diff --git a/src/dynarec/la64/dynarec_la64_f20f.c b/src/dynarec/la64/dynarec_la64_f20f.c index 33461a66..63cf78ea 100644 --- a/src/dynarec/la64/dynarec_la64_f20f.c +++ b/src/dynarec/la64/dynarec_la64_f20f.c @@ -385,6 +385,13 @@ uintptr_t dynarec64_F20F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int VEXTRINS_W(q0, v0, 0); VEXTRINS_W(q0, v0, 0b00100010); break; + case 0xD6: + INST_NAME("MOVDQ2Q Gm, Ex"); + nextop = F8; + GETGM(v0); + GETEXSD(v1, 0, 0); + FMOV_D(v0, v1); + break; case 0xE6: // TODO: !fastround INST_NAME("CVTPD2DQ Gx, Ex"); nextop = F8; diff --git a/src/dynarec/la64/dynarec_la64_f30f.c b/src/dynarec/la64/dynarec_la64_f30f.c index 523f667d..22078287 100644 --- a/src/dynarec/la64/dynarec_la64_f30f.c +++ b/src/dynarec/la64/dynarec_la64_f30f.c @@ -51,7 +51,7 @@ uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int INST_NAME("MOVSS Gx, Ex"); nextop = F8; GETG; - if(MODREG) { + if (MODREG) { v0 = sse_get_reg(dyn, ninst, x1, gd, 1); v1 = sse_get_reg(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0); } else { @@ -104,7 +104,7 @@ uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int GETED(0); d1 = fpu_get_scratch(dyn); MOVGR2FR_D(d1, ed); - if(rex.w) { + if (rex.w) { FFINT_S_L(d1, d1); } else { FFINT_S_W(d1, d1); @@ -183,18 +183,18 @@ uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int VEXTRINS_W(v0, d1, 0); break; case 0x52: - INST_NAME("RSQRTSS Gx, Ex"); - nextop = F8; - GETGX(v0, 1); - GETEXSS(v1, 0, 0); - q0 = fpu_get_scratch(dyn); - q1 = fpu_get_scratch(dyn); - LU12I_W(x3, 0x3f800); // 1.0f - MOVGR2FR_W(q0, x3); - FSQRT_S(q1, v1); - FDIV_S(q0, q0, q1); - VEXTRINS_W(v0, q0, 0); - break; + INST_NAME("RSQRTSS Gx, Ex"); + nextop = F8; + GETGX(v0, 1); + GETEXSS(v1, 0, 0); + q0 = fpu_get_scratch(dyn); + q1 = fpu_get_scratch(dyn); + LU12I_W(x3, 0x3f800); // 1.0f + MOVGR2FR_W(q0, x3); + FSQRT_S(q1, v1); + FDIV_S(q0, q0, q1); + VEXTRINS_W(v0, q0, 0); + break; case 0x53: INST_NAME("RCPSS Gx, Ex"); nextop = F8; @@ -358,7 +358,7 @@ uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int INST_NAME("MOVDQU Ex,Gx"); nextop = F8; GETGX(v0, 0); - if(MODREG) { + if (MODREG) { v1 = sse_get_reg_empty(dyn, ninst, x1, (nextop & 7) + (rex.b << 3)); VOR_V(v1, v0, v0); } else { @@ -480,6 +480,14 @@ uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int MOVGR2FR_W(q1, x2); VEXTRINS_W(v0, q1, 0); break; + case 0xD6: + INST_NAME("MOVQ2DQ Gx, Em"); + nextop = F8; + GETGX_empty(v0); + GETEM(v1, 0); + VXOR_V(v0, v0, v0); + VEXTRINS_D(v0, v1, VEXTRINS_IMM_4_0(0, 0)); + break; case 0xE6: INST_NAME("CVTDQ2PD Gx, Ex"); nextop = F8; |