From f611ec93d082cf32fdaf436f11fb033ff26837c2 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Fri, 13 Nov 2026 20:08:53 +0800 Subject: [PATCH] [LA64_DYNAREC] Optimized xmm/ymm registers preloading --- src/dynarec/la64/dynarec_la64_functions.c | 10 +++++++--- src/dynarec/la64/dynarec_la64_helper.c | 10 ++++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/dynarec/la64/dynarec_la64_functions.c b/src/dynarec/la64/dynarec_la64_functions.c index 184eb1f772..08eb79f279 100644 --- a/src/dynarec/la64/dynarec_la64_functions.c +++ b/src/dynarec/la64/dynarec_la64_functions.c @@ -1127,16 +1127,20 @@ static int tryApplyPreloadCache(dynarec_la64_t* dyn, int first, int last, int re lsx_cache_t first_cache = dyn->insts[first_use].lsx.lsxcache[reg]; if (first_cache.n != reg) return 0; + int dirty = 0; if (ymm) { if (first_cache.t != LSX_CACHE_YMMR && first_cache.t != LSX_CACHE_YMMW) return 0; + dirty = first_cache.t == LSX_CACHE_YMMW; } else if (first_cache.t != LSX_CACHE_XMMR && first_cache.t != LSX_CACHE_XMMW) { return 0; + } else { + dirty = first_cache.t == LSX_CACHE_XMMW; } for (int i = first; i < first_use; ++i) { lsxcache_t* cache = &dyn->insts[i].lsx; - cache->lsxcache[reg].t = ymm ? LSX_CACHE_YMMR : LSX_CACHE_XMMR; + cache->lsxcache[reg].t = ymm ? (dirty ? LSX_CACHE_YMMW : LSX_CACHE_YMMR) : (dirty ? LSX_CACHE_XMMW : LSX_CACHE_XMMR); cache->lsxcache[reg].n = reg; cache->fpuused[reg] = 1; cache->news &= ~(1u << reg); @@ -1145,12 +1149,12 @@ static int tryApplyPreloadCache(dynarec_la64_t* dyn, int first, int last, int re cache->ssecache[reg].v = -1; cache->avxcache[reg].reg = reg; cache->avxcache[reg].upper_zero_pending = 0; - cache->avxcache[reg].write = 0; + cache->avxcache[reg].write = dirty; if (!cache->avxcache[reg].v) cache->avxcache[reg].write = 1; } else { cache->avxcache[reg].v = -1; cache->ssecache[reg].reg = reg; - cache->ssecache[reg].write = 0; + cache->ssecache[reg].write = dirty; if (!cache->ssecache[reg].v) cache->ssecache[reg].write = 1; } } diff --git a/src/dynarec/la64/dynarec_la64_helper.c b/src/dynarec/la64/dynarec_la64_helper.c index 5015469447..89592929a8 100644 --- a/src/dynarec/la64/dynarec_la64_helper.c +++ b/src/dynarec/la64/dynarec_la64_helper.c @@ -2571,18 +2571,20 @@ void doPreload(dynarec_la64_t* dyn, int ninst) MESSAGE(LOG_INFO, "Preload XMM/YMM -------- %x\n", preload); for (int i = 0; i < 16; ++i) { if (preload & (1u << i)) { + int t = dyn->insts[ninst].lsx.lsxcache[i].t == LSX_CACHE_XMMW ? LSX_CACHE_XMMW : LSX_CACHE_XMMR; dyn->lsx.avxcache[i].v = -1; - dyn->lsx.ssecache[i].reg = fpu_get_reg_xmm(dyn, LSX_CACHE_XMMR, i); - dyn->lsx.ssecache[i].write = 0; + dyn->lsx.ssecache[i].reg = fpu_get_reg_xmm(dyn, t, i); + dyn->lsx.ssecache[i].write = (t == LSX_CACHE_XMMW); if (!dyn->lsx.ssecache[i].v) dyn->lsx.ssecache[i].write = 1; VLD(dyn->lsx.ssecache[i].reg, xEmu, offsetof(x64emu_t, xmm[i])); } if (preload & (1u << (16 + i))) { + int t = dyn->insts[ninst].lsx.lsxcache[i].t == LSX_CACHE_YMMW ? LSX_CACHE_YMMW : LSX_CACHE_YMMR; dyn->lsx.ssecache[i].v = -1; dyn->lsx.avxcache[i].v = 0; - dyn->lsx.avxcache[i].reg = fpu_get_reg_ymm(dyn, LSX_CACHE_YMMR, i); + dyn->lsx.avxcache[i].reg = fpu_get_reg_ymm(dyn, t, i); dyn->lsx.avxcache[i].upper_zero_pending = 0; - dyn->lsx.avxcache[i].write = 0; + dyn->lsx.avxcache[i].write = (t == LSX_CACHE_YMMW); if (!dyn->lsx.avxcache[i].v) dyn->lsx.avxcache[i].write = 1; VLD(dyn->lsx.avxcache[i].reg, xEmu, offsetof(x64emu_t, xmm[i])); VLD(SCRATCH, xEmu, offsetof(x64emu_t, ymm[i]));