From 6b6c9c64d5b2faa547cfec8ea0b42edf71c69ee9 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Thu, 28 May 2026 17:04:50 +0800 Subject: [PATCH] [LA64_DYNAREC] Fixed some AVX issues --- src/dynarec/la64/dynarec_la64_avx_66_0f.c | 4 ++-- src/dynarec/la64/dynarec_la64_avx_66_0f38.c | 2 +- src/dynarec/la64/dynarec_la64_helper.c | 9 +++++++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/dynarec/la64/dynarec_la64_avx_66_0f.c b/src/dynarec/la64/dynarec_la64_avx_66_0f.c index 38fbdc8355..f8dd2569fd 100644 --- a/src/dynarec/la64/dynarec_la64_avx_66_0f.c +++ b/src/dynarec/la64/dynarec_la64_avx_66_0f.c @@ -1048,13 +1048,13 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, VADDxy(D, v0, v1, v2); break; case 0xD5: - INST_NAME("VPMULLW Gx, Ex"); + INST_NAME("VPMULLW Gx, Vx, Ex"); nextop = F8; GETGY_empty_VYEY_xy(v0, v1, v2, 0); VMULxy(H, v0, v1, v2); break; case 0xD6: - INST_NAME("VMOVD Ex, Gx"); + INST_NAME("VMOVQ Ex, Gx"); nextop = F8; GETGYx(q0, 0); if (MODREG) { diff --git a/src/dynarec/la64/dynarec_la64_avx_66_0f38.c b/src/dynarec/la64/dynarec_la64_avx_66_0f38.c index 0b701b0b33..d2410a0f6c 100644 --- a/src/dynarec/la64/dynarec_la64_avx_66_0f38.c +++ b/src/dynarec/la64/dynarec_la64_avx_66_0f38.c @@ -698,7 +698,7 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i VMAXxy(WU, v0, v1, v2); break; case 0x40: - INST_NAME("VPMULLD Gx, Ex"); + INST_NAME("VPMULLD Gx, Vx, Ex"); nextop = F8; GETGY_empty_VYEY_xy(v0, v1, v2, 0); VMULxy(W, v0, v1, v2); diff --git a/src/dynarec/la64/dynarec_la64_helper.c b/src/dynarec/la64/dynarec_la64_helper.c index 188c94d5bf..fe25135cfc 100644 --- a/src/dynarec/la64/dynarec_la64_helper.c +++ b/src/dynarec/la64/dynarec_la64_helper.c @@ -1508,8 +1508,10 @@ int avx_get_reg_empty(dynarec_la64_t* dyn, int ninst, int s1, int a, int width) dyn->lsx.avxcache[a].dirty = width == LSX_AVX_WIDTH_128; return dyn->lsx.avxcache[a].reg; } - fpu_free_reg(dyn, dyn->lsx.ssecache[a].reg); - dyn->lsx.ssecache[a].v = -1; + if (dyn->lsx.ssecache[a].v != -1) { + fpu_free_reg(dyn, dyn->lsx.ssecache[a].reg); + dyn->lsx.ssecache[a].v = -1; + } dyn->lsx.avxcache[a].v = 0; dyn->lsx.avxcache[a].reg = fpu_get_reg_ymm(dyn, LSX_CACHE_YMMW, a); dyn->lsx.avxcache[a].write = 1; @@ -1685,6 +1687,9 @@ void fpu_popcache(dynarec_la64_t* dyn, int ninst, int s1, int not07) if (!dyn->lsx.avxcache[i].dirty) { VLD(SCRATCH, xEmu, offsetof(x64emu_t, ymm[i])); XVPERMI_Q(dyn->lsx.avxcache[i].reg, SCRATCH, XVPERMI_IMM_4_0(0, 2)); + } else { + XVXOR_V(SCRATCH, SCRATCH, SCRATCH); + XVPERMI_Q(dyn->lsx.avxcache[i].reg, SCRATCH, XVPERMI_IMM_4_0(0, 2)); } } }