Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/dynarec/la64/dynarec_la64_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ static void fpu_reset_reg_lsxcache(lsxcache_t* lsx)
void fpu_reset_reg(dynarec_la64_t* dyn)
{
fpu_reset_reg_lsxcache(&dyn->lsx);
for (int i = 0; i < 24; ++i) dyn->lsx.olds[i].v = 0;
}


Expand Down Expand Up @@ -435,6 +436,10 @@ void lsxcacheUnwind(lsxcache_t* cache)
cache->lsxcache[i].v = 0;
cache->news = 0;
}
// restore the entries this opcode changed or removed
for (int i = 0; i < 24; ++i)
if (cache->olds[i].v)
cache->lsxcache[i] = cache->olds[i];
if (cache->stack_push) {
// unpush
for (int j = 0; j < 24; ++j) {
Expand Down Expand Up @@ -1135,6 +1140,7 @@ static int tryApplyPreloadCache(dynarec_la64_t* dyn, int first, int last, int re
cache->lsxcache[reg].n = reg;
cache->fpuused[reg] = 1;
cache->news &= ~(1u << reg);
cache->olds[reg].v = 0;
if (ymm) {
cache->ssecache[reg].v = -1;
cache->avxcache[reg].reg = reg;
Expand Down
21 changes: 21 additions & 0 deletions src/dynarec/la64/dynarec_la64_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -1459,6 +1459,17 @@ static void mmx_reflectcache(dynarec_la64_t* dyn, int ninst, int s1)
}

// SSE / SSE2 helpers

static void sse_save_entry_cache(dynarec_la64_t* dyn, int a)
{
if (a < 0 || a >= 16) return;
int slot = dyn->lsx.avxcache[a].v != -1 ? dyn->lsx.avxcache[a].reg : (dyn->lsx.ssecache[a].v != -1 ? dyn->lsx.ssecache[a].reg : -1);
if (slot < 0 || slot >= 24) return;
if (dyn->lsx.olds[slot].v) return;
if (dyn->lsx.news & (1u << slot)) return;
dyn->lsx.olds[slot] = dyn->lsx.lsxcache[slot];
}

void sse_merge_all(dynarec_la64_t* dyn, int ninst)
{
for (int i = 0; i < 16; ++i)
Expand All @@ -1469,6 +1480,7 @@ void sse_merge_all(dynarec_la64_t* dyn, int ninst)
int sse_get_reg(dynarec_la64_t* dyn, int ninst, int s1, int a, int forwrite)
{
dyn->lsx.xmm_used |= 1 << a;
sse_save_entry_cache(dyn, a);
if (dyn->lsx.ssecache[a].v != -1) {
xmm_scalar_merge(dyn, ninst, a);
if (forwrite) {
Expand All @@ -1490,6 +1502,7 @@ int sse_get_reg_scalar(dynarec_la64_t* dyn, int ninst, int s1, int a, int forwri
{
MAYUSE(forwrite);
dyn->lsx.xmm_used |= 1 << a;
sse_save_entry_cache(dyn, a);
if (dyn->lsx.scalarcache[a] != -1) {
int reg = dyn->lsx.scalarcache[a];
if (dyn->lsx.lsxcache[reg].t == (kind == XMM_SCALAR_SS ? LSX_CACHE_XMM_S : LSX_CACHE_XMM_D)) return reg;
Expand All @@ -1515,6 +1528,7 @@ int sse_get_reg_scalar(dynarec_la64_t* dyn, int ninst, int s1, int a, int forwri
int sse_get_reg_empty(dynarec_la64_t* dyn, int ninst, int s1, int a)
{
dyn->lsx.xmm_used |= 1 << a;
sse_save_entry_cache(dyn, a);
if (dyn->lsx.ssecache[a].v != -1) {
xmm_scalar_discard(dyn, a);
dyn->lsx.ssecache[a].write = 1;
Expand All @@ -1534,6 +1548,7 @@ int sse_get_reg_empty(dynarec_la64_t* dyn, int ninst, int s1, int a)
void sse_forget_reg(dynarec_la64_t* dyn, int ninst, int a)
{
dyn->lsx.xmm_used |= 1 << a;
sse_save_entry_cache(dyn, a);
if (dyn->lsx.ssecache[a].v == -1)
return;
xmm_scalar_merge(dyn, ninst, a);
Expand Down Expand Up @@ -1631,6 +1646,7 @@ static void sse_reflectcache(dynarec_la64_t* dyn, int ninst, int s1)
int avx_get_reg(dynarec_la64_t* dyn, int ninst, int s1, int a, int forwrite, int width)
{
dyn->lsx.ymm_used |= 1 << a;
sse_save_entry_cache(dyn, a);
if (width == LSX_AVX_WIDTH_256) {
ymm_live_read(dyn, ninst, a);
if (forwrite) ymm_live_write(dyn, ninst, a);
Expand Down Expand Up @@ -1671,6 +1687,7 @@ int avx_get_reg(dynarec_la64_t* dyn, int ninst, int s1, int a, int forwrite, int
int avx_get_reg_empty(dynarec_la64_t* dyn, int ninst, int s1, int a, int width)
{
dyn->lsx.ymm_used |= 1 << a;
sse_save_entry_cache(dyn, a);
if (width == LSX_AVX_WIDTH_128)
ymm_live_zero(dyn, ninst, a);
else
Expand All @@ -1696,6 +1713,7 @@ int avx_get_reg_empty(dynarec_la64_t* dyn, int ninst, int s1, int a, int width)
void avx_reflect_reg_upper128(dynarec_la64_t* dyn, int ninst, int a, int forwrite)
{
dyn->lsx.ymm_used |= 1 << a;
sse_save_entry_cache(dyn, a);
if (dyn->lsx.avxcache[a].v == -1 || forwrite == 0)
return;
if (dyn->lsx.lsxcache[dyn->lsx.avxcache[a].reg].t == LSX_CACHE_YMMW) {
Expand All @@ -1713,6 +1731,7 @@ void avx_reflect_reg_upper128(dynarec_la64_t* dyn, int ninst, int a, int forwrit
void avx_forget_reg(dynarec_la64_t* dyn, int ninst, int a)
{
dyn->lsx.ymm_used |= 1 << a;
sse_save_entry_cache(dyn, a);
if (dyn->lsx.avxcache[a].v == -1)
return;
if (dyn->lsx.lsxcache[dyn->lsx.avxcache[a].reg].t == LSX_CACHE_YMMW) {
Expand All @@ -1732,6 +1751,7 @@ void avx_forget_reg(dynarec_la64_t* dyn, int ninst, int a)
void avx_reflect_reg(dynarec_la64_t* dyn, int ninst, int a)
{
dyn->lsx.ymm_used |= 1 << a;
sse_save_entry_cache(dyn, a);
if (dyn->lsx.avxcache[a].v == -1)
return;
if (dyn->lsx.lsxcache[dyn->lsx.avxcache[a].reg].t == LSX_CACHE_YMMW) {
Expand Down Expand Up @@ -1988,6 +2008,7 @@ void fpu_propagate_stack(dynarec_la64_t* dyn, int ninst)
}
dyn->lsx.stack = dyn->lsx.stack_next;
dyn->lsx.news = 0;
for (int i = 0; i < 24; ++i) dyn->lsx.olds[i].v = 0;
dyn->lsx.stack_push = 0;
dyn->lsx.swapped = 0;
}
Expand Down
1 change: 1 addition & 0 deletions src/dynarec/la64/dynarec_la64_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ typedef struct lsxcache_s {
uint8_t pushed; // positive pushed value (to check for overflow)
uint8_t poped; // positive poped value (to check for underflow)
uint32_t news; // bitmask, wich neoncache are new for this opcode
lsx_cache_t olds[24]; // entry descriptor of slots changed or removed by this opcode
// 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
Expand Down
Loading