diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-08-24 21:03:55 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-24 21:03:55 +0200 |
| commit | db1f0825ce26c1c49f61c01072598c52bbe9d6bc (patch) | |
| tree | 2cc2c271c17b3cdbb8a25bba4a41fbbd84bd24d5 /src | |
| parent | 66da28a02f83a05942abd11cfb80fa8e63408b15 (diff) | |
| parent | c7b2a5f2df98f0914c6536cda02c7b6c158492d7 (diff) | |
| download | box64-db1f0825ce26c1c49f61c01072598c52bbe9d6bc.tar.gz box64-db1f0825ce26c1c49f61c01072598c52bbe9d6bc.zip | |
Merge pull request #1750 from ksco/fix
[RV64_DYNAREC] Fixed various issues in vector infra
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.c | 6 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_functions.c | 19 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.c | 69 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_private.h | 10 |
4 files changed, 63 insertions, 41 deletions
diff --git a/src/dynarec/la64/dynarec_la64_helper.c b/src/dynarec/la64/dynarec_la64_helper.c index b597cfa6..0458a93e 100644 --- a/src/dynarec/la64/dynarec_la64_helper.c +++ b/src/dynarec/la64/dynarec_la64_helper.c @@ -1146,7 +1146,6 @@ static void unloadCache(dynarec_la64_t* dyn, int ninst, int stack_cnt, int s1, i static void fpuCacheTransform(dynarec_la64_t* dyn, int ninst, int s1, int s2, int s3) { -#if STEP > 1 int i2 = dyn->insts[ninst].x64.jmp_insts; if (i2 < 0) return; @@ -1259,12 +1258,10 @@ static void fpuCacheTransform(dynarec_la64_t* dyn, int ninst, int s1, int s2, in } } MESSAGE(LOG_DUMP, "\t---- Cache Transform\n"); -#endif } static void flagsCacheTransform(dynarec_la64_t* dyn, int ninst, int s1) { -#if STEP > 1 int j64; int jmp = dyn->insts[ninst].x64.jmp_insts; if(jmp<0) @@ -1303,7 +1300,6 @@ static void flagsCacheTransform(dynarec_la64_t* dyn, int ninst, int s1) CALL_(UpdateFlags, -1, 0); MARKF2; } -#endif } void CacheTransform(dynarec_la64_t* dyn, int ninst, int cacheupd, int s1, int s2, int s3) { @@ -1339,4 +1335,4 @@ void la64_move64(dynarec_la64_t* dyn, int ninst, int reg, int64_t val) return; } LU52I_D(reg, reg, (val >> 52) & 0xfff); -} \ No newline at end of file +} diff --git a/src/dynarec/rv64/dynarec_rv64_functions.c b/src/dynarec/rv64/dynarec_rv64_functions.c index c5a3a071..37b81c09 100644 --- a/src/dynarec/rv64/dynarec_rv64_functions.c +++ b/src/dynarec/rv64/dynarec_rv64_functions.c @@ -415,17 +415,24 @@ void extcacheUnwind(extcache_t* cache) if(cache->news) { // remove the newly created extcache for(int i=0; i<24; ++i) - if(cache->news&(1<<i)) + if((cache->news&(1<<i)) && !cache->olds[i].changed) 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->olds[i].changed || cache->olds[i].purged) { + if (cache->olds[i].type == EXT_CACHE_OLD_XMMR) + cache->extcache[i].t = EXT_CACHE_XMMR; + else if (cache->olds[i].type == EXT_CACHE_OLD_XMMW) + cache->extcache[i].t = EXT_CACHE_XMMW; + else if (cache->olds[i].type == EXT_CACHE_OLD_SS) + cache->extcache[i].t = EXT_CACHE_SS; + else if (cache->olds[i].type == EXT_CACHE_OLD_SD) + cache->extcache[i].t = EXT_CACHE_SD; + + if (cache->olds[i].purged) + cache->extcache[i].n = i; } } diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c index 0deaa093..0ec15c43 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.c +++ b/src/dynarec/rv64/dynarec_rv64_helper.c @@ -1579,6 +1579,9 @@ int sse_get_reg(dynarec_rv64_t* dyn, int ninst, int s1, int a, int single) if (dyn->e.ssecache[a].vector == 1) { // it's in the fpu, forget it first... sse_forget_reg_vector(dyn, ninst, s1, a); + // update olds after the forget... + dyn->e.olds[a].changed = 1; + dyn->e.olds[a].purged = 0; return sse_get_reg(dyn, ninst, s1, a, single); } // forget / reload if change of size @@ -1587,7 +1590,7 @@ int sse_get_reg(dynarec_rv64_t* dyn, int ninst, int s1, int a, int single) // update olds after the forget... dyn->e.olds[a].changed = 1; dyn->e.olds[a].purged = 0; - dyn->e.olds[a].single = 1-single; + dyn->e.olds[a].type = 1 - single; return sse_get_reg(dyn, ninst, s1, a, single); } return dyn->e.ssecache[a].reg; @@ -1610,6 +1613,9 @@ int sse_get_reg_empty(dynarec_rv64_t* dyn, int ninst, int s1, int a, int single) if (dyn->e.ssecache[a].vector == 1) { // it's in the fpu, forget it first... sse_forget_reg_vector(dyn, ninst, s1, a); + // update olds after the forget... + dyn->e.olds[a].changed = 1; + dyn->e.olds[a].purged = 0; return sse_get_reg_empty(dyn, ninst, s1, a, single); } @@ -1622,7 +1628,7 @@ int sse_get_reg_empty(dynarec_rv64_t* dyn, int ninst, int s1, int a, int single) 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.olds[a].type = 1 - single; dyn->e.ssecache[a].single = single; dyn->e.ssecache[a].vector = 0; dyn->e.extcache[EXTIDX(dyn->e.ssecache[a].reg)].t = single?EXT_CACHE_SS:EXT_CACHE_SD; @@ -1649,8 +1655,8 @@ void sse_forget_reg(dynarec_rv64_t* dyn, int ninst, int s1, int 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.olds[a].reg = EXTIDX(dyn->e.ssecache[a].reg); + dyn->e.olds[a].type = dyn->e.ssecache[a].single; dyn->e.ssecache[a].v = -1; return; } @@ -1662,10 +1668,17 @@ int sse_get_reg_vector(dynarec_rv64_t* dyn, int ninst, int s1, int a, int forwri if (dyn->e.ssecache[a].vector == 0) { // it's in the fpu, forget it first... sse_forget_reg(dyn, ninst, s1, a); + // update olds after the forget... + dyn->e.olds[a].changed = 1; + dyn->e.olds[a].purged = 0; return sse_get_reg_vector(dyn, ninst, s1, a, forwrite, sew); } if (forwrite) { + 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].type = EXT_CACHE_OLD_XMMW; dyn->e.ssecache[a].write = 1; // update only if forwrite dyn->e.ssecache[a].single = 0; // just to be clean dyn->e.extcache[EXTIDX(dyn->e.ssecache[a].reg)].t = EXT_CACHE_XMMW; @@ -1689,8 +1702,15 @@ int sse_get_reg_empty_vector(dynarec_rv64_t* dyn, int ninst, int s1, int a) if (dyn->e.ssecache[a].vector == 0) { // it's in the fpu, forget it first... sse_forget_reg(dyn, ninst, s1, a); + // update olds after the forget... + dyn->e.olds[a].changed = 1; + dyn->e.olds[a].purged = 0; return sse_get_reg_empty_vector(dyn, ninst, s1, a); } + 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].type = EXT_CACHE_OLD_XMMW; dyn->e.ssecache[a].vector = 1; dyn->e.ssecache[a].write = 1; dyn->e.ssecache[a].single = 0; // just to be clean @@ -1717,6 +1737,10 @@ void sse_forget_reg_vector(dynarec_rv64_t* dyn, int ninst, int s1, int a) VSE8_V(dyn->e.ssecache[a].reg, s1, VECTOR_UNMASKED, VECTOR_NFIELD1); } 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].type = dyn->e.ssecache[a].write ? EXT_CACHE_OLD_XMMW : EXT_CACHE_OLD_XMMR; + dyn->e.olds[a].reg = EXTIDX(dyn->e.ssecache[a].reg); dyn->e.ssecache[a].v = -1; return; } @@ -1765,18 +1789,13 @@ static void sse_purgecache(dynarec_rv64_t* dyn, int ninst, int next, int s1) FSW(dyn->e.ssecache[i].reg, xEmu, offsetof(x64emu_t, xmm[i])); else FSD(dyn->e.ssecache[i].reg, xEmu, offsetof(x64emu_t, xmm[i])); - if(!next) { - if (dyn->e.ssecache[i].vector) { - fpu_free_reg(dyn, dyn->e.ssecache[i].reg); - dyn->e.ssecache[i].v = -1; - } else { - 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; - } + 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].type = dyn->e.ssecache[i].vector ? (dyn->e.ssecache[i].write ? EXT_CACHE_OLD_XMMW : EXT_CACHE_OLD_XMMR) : dyn->e.ssecache[i].single; + dyn->e.olds[i].reg = dyn->e.ssecache[i].reg; + dyn->e.ssecache[i].v = -1; } } if(old!=-1) { @@ -1966,10 +1985,12 @@ static void swapCache(dynarec_rv64_t* dyn, int ninst, int i, int j, extcache_t * if (i == j) return; if (cache->extcache[i].t == EXT_CACHE_XMMR || cache->extcache[i].t == EXT_CACHE_XMMW || cache->extcache[j].t == EXT_CACHE_XMMR || cache->extcache[j].t == EXT_CACHE_XMMW) { + int reg_i = EXTREG(i); + int reg_j = EXTREG(j); if (!cache->extcache[i].v) { // a mov is enough, no need to swap MESSAGE(LOG_DUMP, "\t - Moving %d <- %d\n", i, j); - VMV_V_V(i, j); + VMV_V_V(reg_i, reg_j); cache->extcache[i].v = cache->extcache[j].v; cache->extcache[j].v = 0; return; @@ -1977,9 +1998,9 @@ static void swapCache(dynarec_rv64_t* dyn, int ninst, int i, int j, extcache_t * // SWAP ext_cache_t tmp; MESSAGE(LOG_DUMP, "\t - Swapping %d <-> %d\n", i, j); - VXOR_VV(i, i, j, VECTOR_UNMASKED); - VXOR_VV(j, i, j, VECTOR_UNMASKED); - VXOR_VV(i, i, j, VECTOR_UNMASKED); + VXOR_VV(reg_i, reg_i, reg_j, VECTOR_UNMASKED); + VXOR_VV(reg_j, reg_i, reg_j, VECTOR_UNMASKED); + VXOR_VV(reg_i, reg_i, reg_j, VECTOR_UNMASKED); tmp.v = cache->extcache[i].v; cache->extcache[i].v = cache->extcache[j].v; cache->extcache[j].v = tmp.v; @@ -2034,7 +2055,7 @@ static void loadCache(dynarec_rv64_t* dyn, int ninst, int stack_cnt, int s1, int int j = i + 1; while (cache->extcache[j].v) ++j; MESSAGE(LOG_DUMP, "\t - Moving away %d\n", i); - VMV_V_V(j, i); + VMV_V_V(EXTREG(j), reg); cache->extcache[j].v = cache->extcache[i].v; } else if (cache->extcache[i].v) { int single = 0; @@ -2168,7 +2189,6 @@ static void unloadCache(dynarec_rv64_t* dyn, int ninst, int stack_cnt, int s1, i static void fpuCacheTransform(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3) { -#if STEP > 1 int i2 = dyn->insts[ninst].x64.jmp_insts; if(i2<0) return; @@ -2302,11 +2322,9 @@ static void fpuCacheTransform(dynarec_rv64_t* dyn, int ninst, int s1, int s2, in stack_cnt = cache_i2.stack; } MESSAGE(LOG_DUMP, "\t---- Cache Transform\n"); -#endif } static void flagsCacheTransform(dynarec_rv64_t* dyn, int ninst, int s1) { -#if STEP > 1 int j64; int jmp = dyn->insts[ninst].x64.jmp_insts; if(jmp<0) @@ -2347,19 +2365,16 @@ static void flagsCacheTransform(dynarec_rv64_t* dyn, int ninst, int s1) CALL_(UpdateFlags, -1, 0); MARKF2; } -#endif } static void sewTransform(dynarec_rv64_t* dyn, int ninst, int s1) { -#if STEP > 1 int j64; int jmp = dyn->insts[ninst].x64.jmp_insts; if (jmp < 0) return; if (dyn->insts[jmp].vector_sew == VECTOR_SEWNA) return; MESSAGE(LOG_DUMP, "\tSEW changed to %d ---- ninst=%d -> %d\n", dyn->insts[jmp].vector_sew, ninst, jmp); vector_vsetvl_emul1(dyn, ninst, s1, dyn->insts[jmp].vector_sew); -#endif } void CacheTransform(dynarec_rv64_t* dyn, int ninst, int cacheupd, int s1, int s2, int s3) { diff --git a/src/dynarec/rv64/dynarec_rv64_private.h b/src/dynarec/rv64/dynarec_rv64_private.h index b5bfff5b..fa02ab9d 100644 --- a/src/dynarec/rv64/dynarec_rv64_private.h +++ b/src/dynarec/rv64/dynarec_rv64_private.h @@ -21,6 +21,11 @@ typedef struct instsize_s instsize_t; #define EXT_CACHE_XMMW 8 #define EXT_CACHE_XMMR 9 +#define EXT_CACHE_OLD_SD 0 +#define EXT_CACHE_OLD_SS 1 +#define EXT_CACHE_OLD_XMMW 2 +#define EXT_CACHE_OLD_XMMR 3 + typedef union ext_cache_s { int8_t v; struct { @@ -32,11 +37,10 @@ typedef union ext_cache_s { typedef union sse_cache_s { int16_t v; struct { - uint16_t reg : 7; + uint16_t reg : 13; uint16_t vector : 1; uint16_t single : 1; uint16_t write : 1; - uint16_t unused : 7; }; } sse_cache_t; @@ -46,7 +50,7 @@ typedef union sse_old_s { uint8_t changed:1; uint8_t purged:1; uint8_t reg:4; - uint8_t single:1; + uint8_t type:2; }; } sse_old_t; |