From e7b71cba5fe8ef92cc50266ed380203b7b2ed4ef Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Sat, 29 Mar 2025 10:04:19 +0100 Subject: [ARM64_DYNAREC] Fixed a potential issue with SSE regs when internal jumping to a native call --- src/dynarec/arm64/dynarec_arm64_functions.c | 21 ++++++++++++++++++++- src/dynarec/arm64/dynarec_arm64_private.h | 6 ++++-- 2 files changed, 24 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/dynarec/arm64/dynarec_arm64_functions.c b/src/dynarec/arm64/dynarec_arm64_functions.c index dbc084dd..6b8013af 100644 --- a/src/dynarec/arm64/dynarec_arm64_functions.c +++ b/src/dynarec/arm64/dynarec_arm64_functions.c @@ -65,6 +65,8 @@ void fpu_reset_scratch(dynarec_arm_t* dyn) dyn->n.ymm_regs = 0; dyn->n.ymm_write = 0; dyn->n.ymm_removed = 0; + dyn->n.xmm_write = 0; + dyn->n.xmm_removed = 0; } // Get a x87 double reg int fpu_get_reg_x87(dynarec_arm_t* dyn, int ninst, int t, int n) @@ -96,6 +98,11 @@ void fpu_free_reg(dynarec_arm_t* dyn, int reg) else dyn->n.ymm_regs |= ((uint64_t)(reg-EMM0))<<(dyn->n.neoncache[reg].n*4); } + if(dyn->n.neoncache[reg].t==NEON_CACHE_XMMR || dyn->n.neoncache[reg].t==NEON_CACHE_XMMW) { + dyn->n.xmm_removed |= 1<n.neoncache[reg].n; + if(dyn->n.neoncache[reg].t==NEON_CACHE_XMMW) + dyn->n.xmm_write |= 1<n.neoncache[reg].n; + } if(dyn->n.neoncache[reg].t!=NEON_CACHE_ST_F && dyn->n.neoncache[reg].t!=NEON_CACHE_ST_D && dyn->n.neoncache[reg].t!=NEON_CACHE_ST_I64) dyn->n.neoncache[reg].v = 0; if(dyn->n.fpu_scratch && reg==SCRATCH0+dyn->n.fpu_scratch-1) @@ -174,6 +181,8 @@ static void fpu_reset_reg_neoncache(neoncache_t* n) n->ymm_removed = 0; n->ymm_used = 0; n->ymm_write = 0; + n->xmm_removed = 0; + n->xmm_write = 0; } void fpu_reset_reg(dynarec_arm_t* dyn) @@ -578,7 +587,17 @@ void neoncacheUnwind(neoncache_t* cache) cache->fpuused[i] = 0; } } - // add back removed YMM + // add back removed XMM + if(cache->xmm_removed) { + for(int i=0; i<16; ++i) + if(cache->xmm_removed&(1<neoncache[reg].t = (cache->xmm_write&(1<neoncache[reg].n = i; + } + cache->xmm_write = cache->xmm_removed = 0; + } + // add back removed YMM if(cache->ymm_removed) { for(int i=0; i<16; ++i) if(cache->ymm_removed&(1<