about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-08-24 21:03:55 +0200
committerGitHub <noreply@github.com>2024-08-24 21:03:55 +0200
commitdb1f0825ce26c1c49f61c01072598c52bbe9d6bc (patch)
tree2cc2c271c17b3cdbb8a25bba4a41fbbd84bd24d5 /src
parent66da28a02f83a05942abd11cfb80fa8e63408b15 (diff)
parentc7b2a5f2df98f0914c6536cda02c7b6c158492d7 (diff)
downloadbox64-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.c6
-rw-r--r--src/dynarec/rv64/dynarec_rv64_functions.c19
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.c69
-rw-r--r--src/dynarec/rv64/dynarec_rv64_private.h10
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;