diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-05-17 08:13:07 +0000 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-05-17 08:13:07 +0000 |
| commit | bc40c86f10727f447380d37c60c99533eef899bc (patch) | |
| tree | c1fc13552cca7f6d2822b24a09bc9ca961739d30 /src/dynarec | |
| parent | d61f3e79e23ed0c2139361091603fd4dc627bccb (diff) | |
| download | box64-bc40c86f10727f447380d37c60c99533eef899bc.tar.gz box64-bc40c86f10727f447380d37c60c99533eef899bc.zip | |
[RV64_DYNAREC] Fixed SSE reg Cache when a SSE change type (SS/SD/Vector)
Diffstat (limited to 'src/dynarec')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_functions.c | 11 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.c | 16 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_pass0.h | 1 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_pass1.h | 1 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_private.h | 10 |
5 files changed, 38 insertions, 1 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_functions.c b/src/dynarec/rv64/dynarec_rv64_functions.c index bdb6fc00..7abec870 100644 --- a/src/dynarec/rv64/dynarec_rv64_functions.c +++ b/src/dynarec/rv64/dynarec_rv64_functions.c @@ -346,12 +346,21 @@ void extcacheUnwind(extcache_t* cache) cache->combined1 = cache->combined2 = 0; } if(cache->news) { - // reove the newly created extcache + // remove the newly created extcache for(int i=0; i<24; ++i) if(cache->news&(1<<i)) cache->extcache[i].v = 0; cache->news = 0; } + // add/change bad regs + for(int i=0; i<16; ++i) { + if(cache->olds[i].changed) { + cache->extcache[i].t = cache->olds[i].single?EXT_CACHE_SS:EXT_CACHE_SD; + } else if(cache->olds[i].purged) { + cache->extcache[i].n = i; + cache->extcache[i].t = cache->olds[i].single?EXT_CACHE_SS:EXT_CACHE_SD; + } + } if(cache->stack_push) { // unpush for(int j=0; j<24; ++j) { diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c index 2743ec71..19caa8b2 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.c +++ b/src/dynarec/rv64/dynarec_rv64_helper.c @@ -1306,6 +1306,10 @@ int sse_get_reg(dynarec_rv64_t* dyn, int ninst, int s1, int a, int single) // forget / reload if change of size if(dyn->e.ssecache[a].single!=single) { sse_forget_reg(dyn, ninst, a); + // update olds after the forget... + dyn->e.olds[a].changed = 1; + dyn->e.olds[a].purged = 0; + dyn->e.olds[a].single = 1-single; return sse_get_reg(dyn, ninst, s1, a, single); } return dyn->e.ssecache[a].reg; @@ -1329,6 +1333,10 @@ int sse_get_reg_empty(dynarec_rv64_t* dyn, int ninst, int s1, int a, int single) // need to wipe the half high 32bits of old Double because we now have a single //SW(xZR, xEmu, offsetof(x64emu_t, xmm[a])+4); } + dyn->e.olds[a].changed = 1; + dyn->e.olds[a].purged = 0; + dyn->e.olds[a].reg = EXTIDX(dyn->e.ssecache[a].reg); + dyn->e.olds[a].single = 1-single; dyn->e.ssecache[a].single = single; dyn->e.extcache[EXTIDX(dyn->e.ssecache[a].reg)].t = single?EXT_CACHE_SS:EXT_CACHE_SD; return dyn->e.ssecache[a].reg; @@ -1347,6 +1355,10 @@ void sse_forget_reg(dynarec_rv64_t* dyn, int ninst, int a) else FSD(dyn->e.ssecache[a].reg, xEmu, offsetof(x64emu_t, xmm[a])); fpu_free_reg(dyn, dyn->e.ssecache[a].reg); + dyn->e.olds[a].changed = 0; + dyn->e.olds[a].purged = 1; + dyn->e.olds[a].reg = dyn->e.ssecache[a].reg; + dyn->e.olds[a].single = dyn->e.ssecache[a].single; dyn->e.ssecache[a].v = -1; return; } @@ -1388,6 +1400,10 @@ static void sse_purgecache(dynarec_rv64_t* dyn, int ninst, int next, int s1) FSD(dyn->e.ssecache[i].reg, xEmu, offsetof(x64emu_t, xmm[i])); if(!next) { fpu_free_reg(dyn, dyn->e.ssecache[i].reg); + dyn->e.olds[i].changed = 0; + dyn->e.olds[i].purged = 1; + dyn->e.olds[i].reg = dyn->e.ssecache[i].reg; + dyn->e.olds[i].single = dyn->e.ssecache[i].single; dyn->e.ssecache[i].v = -1; } } diff --git a/src/dynarec/rv64/dynarec_rv64_pass0.h b/src/dynarec/rv64/dynarec_rv64_pass0.h index debb052f..fc461f0a 100644 --- a/src/dynarec/rv64/dynarec_rv64_pass0.h +++ b/src/dynarec/rv64/dynarec_rv64_pass0.h @@ -29,6 +29,7 @@ dyn->insts[ninst].x64.addr = ip; \ dyn->e.combined1 = dyn->e.combined2 = 0;\ dyn->e.swapped = 0; dyn->e.barrier = 0; \ + for(int i=0; i<16; ++i) dyn->e.olds[i].v = 0;\ dyn->insts[ninst].f_entry = dyn->f; \ if(ninst) {dyn->insts[ninst-1].x64.size = dyn->insts[ninst].x64.addr - dyn->insts[ninst-1].x64.addr;} diff --git a/src/dynarec/rv64/dynarec_rv64_pass1.h b/src/dynarec/rv64/dynarec_rv64_pass1.h index c818c26c..34d0a468 100644 --- a/src/dynarec/rv64/dynarec_rv64_pass1.h +++ b/src/dynarec/rv64/dynarec_rv64_pass1.h @@ -5,6 +5,7 @@ #define NEW_INST \ dyn->insts[ninst].f_entry = dyn->f; \ dyn->e.combined1 = dyn->e.combined2 = 0;\ + for(int i=0; i<16; ++i) dyn->e.olds[i].v = 0;\ dyn->e.swapped = 0; dyn->e.barrier = 0 #define INST_EPILOG \ diff --git a/src/dynarec/rv64/dynarec_rv64_private.h b/src/dynarec/rv64/dynarec_rv64_private.h index 08182afd..b9cbb2af 100644 --- a/src/dynarec/rv64/dynarec_rv64_private.h +++ b/src/dynarec/rv64/dynarec_rv64_private.h @@ -31,6 +31,15 @@ typedef union sse_cache_s { uint8_t single:1; }; } sse_cache_t; +typedef union sse_old_s { + int8_t v; + struct { + uint8_t changed:1; + uint8_t purged:1; + uint8_t reg:4; + uint8_t single:1; + }; +} sse_old_t; typedef struct extcache_s { // ext cache ext_cache_t extcache[24]; @@ -43,6 +52,7 @@ typedef struct extcache_s { uint8_t swapped; // the combined reg were swapped uint8_t barrier; // is there a barrier at instruction epilog? uint32_t news; // bitmask, wich neoncache are new for this opcode + sse_old_t olds[16]; // SSE regs has changed or has been removed // fpu cache int8_t x87cache[8]; // cache status for the 8 x87 register behind the fpu stack int8_t x87reg[8]; // reg used for x87cache entry |