about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-10-23 16:12:41 +0200
committerptitSeb <sebastien.chev@gmail.com>2023-10-23 16:12:41 +0200
commit54f8d0510554da4a76d9a1b6b3fc03a950f4d849 (patch)
treea19ece5a1f1825537d8e047a335a7ab34871d112
parent892f102e4a2c8f0b5381dbe2b35966f655b07209 (diff)
downloadbox64-54f8d0510554da4a76d9a1b6b3fc03a950f4d849.tar.gz
box64-54f8d0510554da4a76d9a1b6b3fc03a950f4d849.zip
[ARM64_DYNAREC] Some fixes to x87 opcodes (helps 32bits games on WoW64)
-rw-r--r--src/dynarec/arm64/dynarec_arm64_d9.c14
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.c19
2 files changed, 25 insertions, 8 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_d9.c b/src/dynarec/arm64/dynarec_arm64_d9.c
index 2a95b10a..7b695e02 100644
--- a/src/dynarec/arm64/dynarec_arm64_d9.c
+++ b/src/dynarec/arm64/dynarec_arm64_d9.c
@@ -195,11 +195,17 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             MESSAGE(LOG_DUMP, "Need Optimization\n");
             x87_forget(dyn, ninst, x1, x2, 0);
             CALL(native_ftan, -1);
-            X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_F);
-            if(ST_IS_F(0)) {
-                FMOVS_8(v1, 0b01110000);
+            if(PK(0)==0xdd && PK(1)==0xd8) {
+                MESSAGE(LOG_DUMP, "Optimized next DD D8 fstp st0, st0, not emiting 1\n");
+                u8 = F8;
+                u8 = F8;
             } else {
-                FMOVD_8(v1, 0b01110000);
+                X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_F);
+                if(ST_IS_F(0)) {
+                    FMOVS_8(v1, 0b01110000);
+                } else {
+                    FMOVD_8(v1, 0b01110000);
+                }
             }
             break;
         case 0xF3:
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.c b/src/dynarec/arm64/dynarec_arm64_helper.c
index 0e7e468c..8b334740 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.c
+++ b/src/dynarec/arm64/dynarec_arm64_helper.c
@@ -1153,6 +1153,8 @@ int x87_get_current_cache(dynarec_arm_t* dyn, int ninst, int st, int t)
             #if STEP == 1
             if(t==NEON_CACHE_ST_D && (dyn->n.neoncache[dyn->n.x87reg[i]].t==NEON_CACHE_ST_F || dyn->n.neoncache[dyn->n.x87reg[i]].t==NEON_CACHE_ST_I64))
                 neoncache_promote_double(dyn, ninst, st);
+            else if(t==NEON_CACHE_ST_I64 && (dyn->n.neoncache[dyn->n.x87reg[i]].t==NEON_CACHE_ST_F))
+                neoncache_promote_double(dyn, ninst, st);
             else if(t==NEON_CACHE_ST_F && (dyn->n.neoncache[dyn->n.x87reg[i]].t==NEON_CACHE_ST_I64))
                 neoncache_promote_double(dyn, ninst, st);
             #endif
@@ -1258,8 +1260,9 @@ void x87_forget(dynarec_arm_t* dyn, int ninst, int s1, int s2, int st)
     if(ret==-1)    // nothing to do
         return;
     MESSAGE(LOG_DUMP, "\tForget x87 Cache for ST%d\n", st);
+    const int reg = dyn->n.x87reg[ret];
     #if STEP == 1
-    if(dyn->n.neoncache[dyn->n.x87reg[ret]].t==NEON_CACHE_ST_F || dyn->n.neoncache[dyn->n.x87reg[ret]].t==NEON_CACHE_ST_I64)
+    if(dyn->n.neoncache[reg].t==NEON_CACHE_ST_F || dyn->n.neoncache[reg].t==NEON_CACHE_ST_I64)
         neoncache_promote_double(dyn, ninst, st);
     #endif
     // prepare offset to fpu => s1
@@ -1271,11 +1274,19 @@ void x87_forget(dynarec_arm_t* dyn, int ninst, int s1, int s2, int st)
         ADDw_U12(s2, s2, st);
         ANDw_mask(s2, s2, 0, 2); //mask=7    // (emu->top + i)&7
     }
-    VSTR64_REG_LSL3(dyn->n.x87reg[ret], s1, s2);
+    if(dyn->n.neoncache[reg].t==NEON_CACHE_ST_F) {
+        FCVT_D_S(31, reg);
+        VSTR64_REG_LSL3(31, s1, s2);
+    } else if(dyn->n.neoncache[reg].t==NEON_CACHE_ST_I64) {
+        SCVTFDD(31, reg);
+        VSTR64_REG_LSL3(31, s1, s2);
+    } else {
+        VSTR64_REG_LSL3(reg, s1, s2);
+    }
     MESSAGE(LOG_DUMP, "\t--------x87 Cache for ST%d\n", st);
     // and forget that cache
-    fpu_free_reg(dyn, dyn->n.x87reg[ret]);
-    dyn->n.neoncache[dyn->n.x87reg[ret]].v = 0;
+    fpu_free_reg(dyn, reg);
+    dyn->n.neoncache[reg].v = 0;
     dyn->n.x87cache[ret] = -1;
     dyn->n.x87reg[ret] = -1;
 }