diff options
| author | phorcys <phorcys@126.com> | 2025-04-18 23:09:34 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-18 17:09:34 +0200 |
| commit | 518c860e5d275663785d88a62e8d11d36a0ee584 (patch) | |
| tree | 596564dbec89929445e78ba6380ecb7049e57319 /src | |
| parent | 053c389cfba933fe92b65cd6486e993d3fb1ab74 (diff) | |
| download | box64-518c860e5d275663785d88a62e8d11d36a0ee584.tar.gz box64-518c860e5d275663785d88a62e8d11d36a0ee584.zip | |
[LA64_DYNAREC]Add/opt more SSE/MMX ops (#2543)
* Add SSE2 op MASKMOVDQU.
* Opt PSADBW.
* Add SSE3 HSUBPD op.
* Add mmx PALIGNR op.
* Fix PSRLDQ.
* Fix PSRAW Gx,Ex PSRAW Gm,Em.
mmx/sse get COUNT from Em/Ex as an 64bit unsigned...
testsuite with shift 0x4,0x4,0x4,0x4, result COUNT as 0x04040404.Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_0f.c | 20 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_660f.c | 64 |
2 files changed, 60 insertions, 24 deletions
diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c index 0f2290cb..dd6639a2 100644 --- a/src/dynarec/la64/dynarec_la64_0f.c +++ b/src/dynarec/la64/dynarec_la64_0f.c @@ -526,6 +526,24 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0x3A: // more SSE3 opcodes opcode = F8; switch (opcode) { + case 0x0F: + INST_NAME("PALIGNR Gm, Em, Ib"); + nextop = F8; + GETGM(q0); + GETEM(q1, 1); + u8 = F8; + if (u8 > 15) { + VXOR_V(q0, q0, q0); + } else if (!u8) { + VEXTRINS_D(q0, q1, VEXTRINS_IMM_4_0(0, 0)); + } else { + d0 = fpu_get_scratch(dyn); + VOR_V(d0, q0, q0); + VSHUF4I_D(d0, q1, 0b00010010); + VBSRL_V(d0, d0, u8); + VEXTRINS_D(q0, d0, 0); + } + break; case 0xCC: INST_NAME("SHA1RNDS4 Gx, Ex, Ib"); nextop = F8; @@ -1917,7 +1935,7 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni GETGM(v0); GETEM(v1, 0); q0 = fpu_get_scratch(dyn); - VMINI_HU(q0, v1, 15); + VMINI_DU(q0, v1, 15); VREPLVEI_H(q0, q0, 0); VSRA_H(v0, v0, q0); break; diff --git a/src/dynarec/la64/dynarec_la64_660f.c b/src/dynarec/la64/dynarec_la64_660f.c index c0619ff8..c7ae2a56 100644 --- a/src/dynarec/la64/dynarec_la64_660f.c +++ b/src/dynarec/la64/dynarec_la64_660f.c @@ -1787,7 +1787,7 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int u8 = F8; if (u8) { if (u8 > 15) { - XVOR_V(q0, q0, q0); + VXOR_V(q0, q0, q0); } else { VBSRL_V(q0, q0, u8); } @@ -1869,6 +1869,30 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int VOR_V(q1, v0, v1); } break; + case 0x7D: + INST_NAME("HSUBPD Gx, Ex"); + nextop = F8; + GETGX(q1, 1); + GETEX(q0, 0, 0); + d0 = fpu_get_scratch(dyn); + VPICKEV_D(d0, q0, q1); + VPICKOD_D(q1, q0, q1); + if (!BOX64ENV(dynarec_fastnan)) { + v0 = fpu_get_scratch(dyn); + v1 = fpu_get_scratch(dyn); + VFCMP_D(v0, d0, q1, cUN); + } + VFSUB_D(q1, d0, q1); + if (!BOX64ENV(dynarec_fastnan)) { + VFCMP_D(v1, q1, q1, cUN); + VANDN_V(v0, v0, v1); + VLDI(v1, 0b011111111000); // broadcast 0xFFFFFFFFFFFFFFF8 + VSLLI_D(v1, v1, 48); + VAND_V(v1, v0, v1); + VANDN_V(v0, v0, q1); + VOR_V(q1, v0, v1); + } + break; case 0x7E: INST_NAME("MOVD Ed,Gx"); nextop = F8; @@ -2245,7 +2269,7 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int GETGX(q0, 1); GETEX(q1, 0, 0); v0 = fpu_get_scratch(dyn); - VMINI_HU(v0, q1, 15); + VMINI_DU(v0, q1, 15); VREPLVEI_H(v0, v0, 0); VSRA_H(q0, q0, v0); break; @@ -2446,27 +2470,21 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int d0 = fpu_get_scratch(dyn); d1 = fpu_get_scratch(dyn); VABSD_BU(q0, q0, q1); - - // 8bit -> 16bit merge - VPICKEV_B(d0, q0, q0); - VPICKOD_B(d1, q0, q0); - VEXTH_HU_BU(d0, d0); - VEXTH_HU_BU(d1, d1); - VADD_H(q0, d0, d1); - - // 16bit to 32bit merge - VPICKEV_H(d0, q0, q0); - VPICKOD_H(d1, q0, q0); - VEXTH_WU_HU(d0, d0); - VEXTH_WU_HU(d1, d1); - VADD_W(q0, d0, d1); - - // 32bit to 64bit merge - VPICKEV_W(d0, q0, q0); - VPICKOD_W(d1, q0, q0); - VEXTH_DU_WU(d0, d0); - VEXTH_DU_WU(d1, d1); - VADD_D(q0, d0, d1); + VHADDW_HU_BU(q0, q0, q0); + VHADDW_WU_HU(q0, q0, q0); + VHADDW_DU_WU(q0, q0, q0); + break; + case 0xF7: + INST_NAME("MASKMOVDQU Gx, Ex"); + nextop = F8; + GETGX(v0, 1); + GETEX(v1, 0, 0); + q0 = fpu_get_scratch(dyn); + q1 = fpu_get_scratch(dyn); + VSLTI_B(q1, v1, 0); // q1 = byte selection mask + VLD(q0, xRDI, 0); + VBITSEL_V(q0, q0, v0, q1); // sel v0 if mask is 1 + VST(q0, xRDI, 0); break; case 0xF8: INST_NAME("PSUBB Gx,Ex"); |