about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-04-21 16:07:05 +0200
committerptitSeb <sebastien.chev@gmail.com>2025-04-21 16:07:05 +0200
commitc39869b77043e14fe58b8841c8140558e7f959be (patch)
tree11289a8fc5318fd4f4d72050f8fdc7b10c9f976a /src
parent302b6493e2e84de7e01a0479c7006c76322c00c4 (diff)
downloadbox64-c39869b77043e14fe58b8841c8140558e7f959be.tar.gz
box64-c39869b77043e14fe58b8841c8140558e7f959be.zip
[ARM64_DYNAREC] Better handling of x87double=2
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_d8.c12
-rw-r--r--src/dynarec/arm64/dynarec_arm64_d9.c1
-rw-r--r--src/dynarec/arm64/dynarec_arm64_da.c6
-rw-r--r--src/dynarec/arm64/dynarec_arm64_dc.c12
-rw-r--r--src/dynarec/arm64/dynarec_arm64_de.c12
-rw-r--r--src/dynarec/arm64/dynarec_arm64_functions.c4
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h3
-rw-r--r--src/dynarec/arm64/dynarec_arm64_pass0.h1
-rw-r--r--src/dynarec/arm64/dynarec_arm64_pass1.h1
-rw-r--r--src/dynarec/arm64/dynarec_arm64_private.h1
10 files changed, 53 insertions, 0 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_d8.c b/src/dynarec/arm64/dynarec_arm64_d8.c
index 76f2b4f3..f7ccac5e 100644
--- a/src/dynarec/arm64/dynarec_arm64_d8.c
+++ b/src/dynarec/arm64/dynarec_arm64_d8.c
@@ -58,6 +58,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 FADDD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
             }
+            MARK_X87PC();
             if(!BOX64ENV(dynarec_fastround))
                 x87_restoreround(dyn, ninst, u8);
             break;
@@ -80,6 +81,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 FMULD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
             }
+            MARK_X87PC();
             if(!BOX64ENV(dynarec_fastround))
                 x87_restoreround(dyn, ninst, u8);
             break;
@@ -139,6 +141,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 FSUBD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
             }
+            MARK_X87PC();
             if(!BOX64ENV(dynarec_fastround))
                 x87_restoreround(dyn, ninst, u8);
             break;
@@ -161,6 +164,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 FSUBD(v1, v2, v1);
                 X87_CHECK_PRECISION(v1);
             }
+            MARK_X87PC();
             if(!BOX64ENV(dynarec_fastround))
                 x87_restoreround(dyn, ninst, u8);
             break;
@@ -183,6 +187,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 FDIVD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
             }
+            MARK_X87PC();
             if(!BOX64ENV(dynarec_fastround))
                 x87_restoreround(dyn, ninst, u8);
             break;
@@ -205,6 +210,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 FDIVD(v1, v2, v1);
                 X87_CHECK_PRECISION(v1);
             }
+            MARK_X87PC();
             if(!BOX64ENV(dynarec_fastround))
                 x87_restoreround(dyn, ninst, u8);
             break;
@@ -228,6 +234,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     FADDD(v1, v1, s0);
                     X87_CHECK_PRECISION(v1);
                 }
+                MARK_X87PC();
                 if(!BOX64ENV(dynarec_fastround))
                     x87_restoreround(dyn, ninst, u8);
                 break;
@@ -246,6 +253,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     FMULD(v1, v1, s0);
                     X87_CHECK_PRECISION(v1);
                 }
+                MARK_X87PC();
                 if(!BOX64ENV(dynarec_fastround))
                     x87_restoreround(dyn, ninst, u8);
                 break;
@@ -293,6 +301,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     FSUBD(v1, v1, s0);
                     X87_CHECK_PRECISION(v1);
                 }
+                MARK_X87PC();
                 if(!BOX64ENV(dynarec_fastround))
                     x87_restoreround(dyn, ninst, u8);
                 break;
@@ -311,6 +320,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     FSUBD(v1, s0, v1);
                     X87_CHECK_PRECISION(v1);
                 }
+                MARK_X87PC();
                 if(!BOX64ENV(dynarec_fastround))
                     x87_restoreround(dyn, ninst, u8);
                 break;
@@ -329,6 +339,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     FDIVD(v1, v1, s0);
                     X87_CHECK_PRECISION(v1);
                 }
+                MARK_X87PC();
                 if(!BOX64ENV(dynarec_fastround))
                     x87_restoreround(dyn, ninst, u8);
                 break;
@@ -347,6 +358,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     FDIVD(v1, s0, v1);
                     X87_CHECK_PRECISION(v1);
                 }
+                MARK_X87PC();
                 if(!BOX64ENV(dynarec_fastround))
                     x87_restoreround(dyn, ninst, u8);
                 break;
diff --git a/src/dynarec/arm64/dynarec_arm64_d9.c b/src/dynarec/arm64/dynarec_arm64_d9.c
index c6615291..cd5a5b78 100644
--- a/src/dynarec/arm64/dynarec_arm64_d9.c
+++ b/src/dynarec/arm64/dynarec_arm64_d9.c
@@ -432,6 +432,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 FSQRTD(v1, v1);
                 X87_CHECK_PRECISION(v1);
             }
+            MARK_X87PC();
             if(!BOX64ENV(dynarec_fastround))
                 x87_restoreround(dyn, ninst, u8);
             break;
diff --git a/src/dynarec/arm64/dynarec_arm64_da.c b/src/dynarec/arm64/dynarec_arm64_da.c
index 8189f43f..40387735 100644
--- a/src/dynarec/arm64/dynarec_arm64_da.c
+++ b/src/dynarec/arm64/dynarec_arm64_da.c
@@ -151,6 +151,7 @@ uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     u8 = x87_setround(dyn, ninst, x1, x5, x4);
                 FADDD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
+                MARK_X87PC();
                 if(!BOX64ENV(dynarec_fastround))
                     x87_restoreround(dyn, ninst, u8);
                 break;
@@ -166,6 +167,7 @@ uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     u8 = x87_setround(dyn, ninst, x1, x5, x4);
                 FMULD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
+                MARK_X87PC();
                 if(!BOX64ENV(dynarec_fastround))
                     x87_restoreround(dyn, ninst, u8);
                 break;
@@ -204,6 +206,7 @@ uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     u8 = x87_setround(dyn, ninst, x1, x5, x4);
                 FSUBD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
+                MARK_X87PC();
                 if(!BOX64ENV(dynarec_fastround))
                     x87_restoreround(dyn, ninst, u8);
                 break;
@@ -219,6 +222,7 @@ uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     u8 = x87_setround(dyn, ninst, x1, x5, x4);
                 FSUBD(v1, v2, v1);
                 X87_CHECK_PRECISION(v1);
+                MARK_X87PC();
                 if(!BOX64ENV(dynarec_fastround))
                     x87_restoreround(dyn, ninst, u8);
                 break;
@@ -234,6 +238,7 @@ uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     u8 = x87_setround(dyn, ninst, x1, x5, x4);
                 FDIVD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
+                MARK_X87PC();
                 if(!BOX64ENV(dynarec_fastround))
                     x87_restoreround(dyn, ninst, u8);
                 break;
@@ -249,6 +254,7 @@ uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     u8 = x87_setround(dyn, ninst, x1, x5, x4);
                 FDIVD(v1, v2, v1);
                 X87_CHECK_PRECISION(v1);
+                MARK_X87PC();
                 if(!BOX64ENV(dynarec_fastround))
                     x87_restoreround(dyn, ninst, u8);
                 break;
diff --git a/src/dynarec/arm64/dynarec_arm64_dc.c b/src/dynarec/arm64/dynarec_arm64_dc.c
index b4d1a48d..3ff95fe6 100644
--- a/src/dynarec/arm64/dynarec_arm64_dc.c
+++ b/src/dynarec/arm64/dynarec_arm64_dc.c
@@ -56,6 +56,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 FADDD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
             }
+            MARK_X87PC();
             if(!BOX64ENV(dynarec_fastround))
                 x87_restoreround(dyn, ninst, u8);
             break;
@@ -78,6 +79,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 FMULD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
             }
+            MARK_X87PC();
             if(!BOX64ENV(dynarec_fastround))
                 x87_restoreround(dyn, ninst, u8);
             break;
@@ -137,6 +139,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 FSUBD(v1, v2, v1);
                 X87_CHECK_PRECISION(v1);
             }
+            MARK_X87PC();
             if(!BOX64ENV(dynarec_fastround))
                 x87_restoreround(dyn, ninst, u8);
             break;
@@ -159,6 +162,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 FSUBD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
             }
+            MARK_X87PC();
             if(!BOX64ENV(dynarec_fastround))
                 x87_restoreround(dyn, ninst, u8);
             break;
@@ -181,6 +185,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 FDIVD(v1, v2, v1);
                 X87_CHECK_PRECISION(v1);
             }
+            MARK_X87PC();
             if(!BOX64ENV(dynarec_fastround))
                 x87_restoreround(dyn, ninst, u8);
             break;
@@ -203,6 +208,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 FDIVD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
             }
+            MARK_X87PC();
             if(!BOX64ENV(dynarec_fastround))
                 x87_restoreround(dyn, ninst, u8);
             break;
@@ -221,6 +227,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     u8 = x87_setround(dyn, ninst, x1, x2, x4);
                 FADDD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
+                MARK_X87PC();
                 if(!BOX64ENV(dynarec_fastround))
                     x87_restoreround(dyn, ninst, u8);
                 break;
@@ -234,6 +241,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     u8 = x87_setround(dyn, ninst, x1, x2, x4);
                 FMULD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
+                MARK_X87PC();
                 if(!BOX64ENV(dynarec_fastround))
                     x87_restoreround(dyn, ninst, u8);
                 break;
@@ -266,6 +274,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     u8 = x87_setround(dyn, ninst, x1, x2, x4);
                 FSUBD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
+                MARK_X87PC();
                 if(!BOX64ENV(dynarec_fastround))
                     x87_restoreround(dyn, ninst, u8);
                 break;
@@ -279,6 +288,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     u8 = x87_setround(dyn, ninst, x1, x2, x4);
                 FSUBD(v1, v2, v1);
                 X87_CHECK_PRECISION(v1);
+                MARK_X87PC();
                 if(!BOX64ENV(dynarec_fastround))
                     x87_restoreround(dyn, ninst, u8);
                 break;
@@ -292,6 +302,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     u8 = x87_setround(dyn, ninst, x1, x2, x4);
                 FDIVD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
+                MARK_X87PC();
                 if(!BOX64ENV(dynarec_fastround))
                     x87_restoreround(dyn, ninst, u8);
                 break;
@@ -305,6 +316,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     u8 = x87_setround(dyn, ninst, x1, x2, x4);
                 FDIVD(v1, v2, v1);
                 X87_CHECK_PRECISION(v1);
+                MARK_X87PC();
                 if(!BOX64ENV(dynarec_fastround))
                     x87_restoreround(dyn, ninst, u8);
                 break;
diff --git a/src/dynarec/arm64/dynarec_arm64_de.c b/src/dynarec/arm64/dynarec_arm64_de.c
index 0c4122bd..2d861f2b 100644
--- a/src/dynarec/arm64/dynarec_arm64_de.c
+++ b/src/dynarec/arm64/dynarec_arm64_de.c
@@ -56,6 +56,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 FADDD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
             }
+            MARK_X87PC();
             if(!BOX64ENV(dynarec_fastround))
                 x87_restoreround(dyn, ninst, u8);
             X87_POP_OR_FAIL(dyn, ninst, x3);
@@ -79,6 +80,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 FMULD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
             }
+            MARK_X87PC();
             if(!BOX64ENV(dynarec_fastround))
                 x87_restoreround(dyn, ninst, u8);
             X87_POP_OR_FAIL(dyn, ninst, x3);
@@ -134,6 +136,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 FSUBD(v1, v2, v1);
                 X87_CHECK_PRECISION(v1);
             }
+            MARK_X87PC();
             if(!BOX64ENV(dynarec_fastround))
                 x87_restoreround(dyn, ninst, u8);
             X87_POP_OR_FAIL(dyn, ninst, x3);
@@ -157,6 +160,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 FSUBD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
             }
+            MARK_X87PC();
             if(!BOX64ENV(dynarec_fastround))
                 x87_restoreround(dyn, ninst, u8);
             X87_POP_OR_FAIL(dyn, ninst, x3);
@@ -180,6 +184,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 FDIVD(v1, v2, v1);
                 X87_CHECK_PRECISION(v1);
             }
+            MARK_X87PC();
             if(!BOX64ENV(dynarec_fastround))
                 x87_restoreround(dyn, ninst, u8);
             X87_POP_OR_FAIL(dyn, ninst, x3);
@@ -203,6 +208,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 FDIVD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
             }
+            MARK_X87PC();
             if(!BOX64ENV(dynarec_fastround))
                 x87_restoreround(dyn, ninst, u8);
             X87_POP_OR_FAIL(dyn, ninst, x3);
@@ -223,6 +229,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 SCVTFDD(v2, v2);
                 FADDD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
+                MARK_X87PC();
                 break;
             case 1:
                 INST_NAME("FIMUL ST0, word[ED]");
@@ -235,6 +242,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 SCVTFDD(v2, v2);
                 FMULD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
+                MARK_X87PC();
                 break;
             case 2:
                 INST_NAME("FICOM ST0, word[ED]");
@@ -272,6 +280,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 SCVTFDD(v2, v2);
                 FSUBD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
+                MARK_X87PC();
                 break;
             case 5:
                 INST_NAME("FISUBR ST0, word[ED]");
@@ -284,6 +293,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 SCVTFDD(v2, v2);
                 FSUBD(v1, v2, v1);
                 X87_CHECK_PRECISION(v1);
+                MARK_X87PC();
                 break;
             case 6:
                 INST_NAME("FIDIV ST0, word[ED]");
@@ -296,6 +306,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 SCVTFDD(v2, v2);
                 FDIVD(v1, v1, v2);
                 X87_CHECK_PRECISION(v1);
+                MARK_X87PC();
                 break;
             case 7:
                 INST_NAME("FIDIVR ST0, word[ED]");
@@ -308,6 +319,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 SCVTFDD(v2, v2);
                 FDIVD(v1, v2, v1);
                 X87_CHECK_PRECISION(v1);
+                MARK_X87PC();
                 break;
         }
     return addr;
diff --git a/src/dynarec/arm64/dynarec_arm64_functions.c b/src/dynarec/arm64/dynarec_arm64_functions.c
index cdfcb645..0f1ed4a1 100644
--- a/src/dynarec/arm64/dynarec_arm64_functions.c
+++ b/src/dynarec/arm64/dynarec_arm64_functions.c
@@ -298,6 +298,7 @@ static void neoncache_promote_double_combined(dynarec_arm_t* dyn, int ninst, int
         //if(BOX64DRENV(dynarec_dump)) dynarec_log(LOG_NONE, "neoncache_promote_double_combined, ninst=%d combined%c %d i=%d (stack:%d/%d)\n", ninst, (a == dyn->insts[ninst].n.combined2)?'2':'1', a ,i, dyn->insts[ninst].n.stack_push, -dyn->insts[ninst].n.stack_pop);
         if(i>=0) {
             dyn->insts[ninst].n.neoncache[i].t = NEON_CACHE_ST_D;
+            if(dyn->insts[ninst].x87precision) dyn->need_x87check = 2;
             if(!dyn->insts[ninst].n.barrier)
                 neoncache_promote_double_internal(dyn, ninst-1, maxinst, a-dyn->insts[ninst].n.stack_push);
             // go forward is combined is not pop'd
@@ -315,6 +316,7 @@ static void neoncache_promote_double_internal(dynarec_arm_t* dyn, int ninst, int
         //if(BOX64DRENV(dynarec_dump)) dynarec_log(LOG_NONE, "neoncache_promote_double_internal, ninst=%d, a=%d st=%d:%d, i=%d\n", ninst, a, dyn->insts[ninst].n.stack, dyn->insts[ninst].n.stack_next, i);
         if(i<0) return;
         dyn->insts[ninst].n.neoncache[i].t = NEON_CACHE_ST_D;
+        if(dyn->insts[ninst].x87precision) dyn->need_x87check = 2;
         // check combined propagation too
         if(dyn->insts[ninst].n.combined1 || dyn->insts[ninst].n.combined2) {
             if(dyn->insts[ninst].n.swapped) {
@@ -350,6 +352,7 @@ static void neoncache_promote_double_forward(dynarec_arm_t* dyn, int ninst, int
         //if(BOX64DRENV(dynarec_dump)) dynarec_log(LOG_NONE, "neoncache_promote_double_forward, ninst=%d, a=%d st=%d:%d(%d/%d), i=%d\n", ninst, a, dyn->insts[ninst].n.stack, dyn->insts[ninst].n.stack_next, dyn->insts[ninst].n.stack_push, -dyn->insts[ninst].n.stack_pop, i);
         if(i<0) return;
         dyn->insts[ninst].n.neoncache[i].t = NEON_CACHE_ST_D;
+        if(dyn->insts[ninst].x87precision) dyn->need_x87check = 2;
         // check combined propagation too
         if((dyn->insts[ninst].n.combined1 || dyn->insts[ninst].n.combined2) && !dyn->insts[ninst].n.swapped) {
             //if(BOX64DRENV(dynarec_dump)) dynarec_log(LOG_NONE, "neoncache_promote_double_forward, ninst=%d combined %d/%d vs %d with st %d\n", ninst, dyn->insts[ninst].n.combined1 ,dyn->insts[ninst].n.combined2, a, dyn->insts[ninst].n.stack);
@@ -372,6 +375,7 @@ void neoncache_promote_double(dynarec_arm_t* dyn, int ninst, int a)
     if(i<0) return;
     dyn->n.neoncache[i].t = NEON_CACHE_ST_D;
     dyn->insts[ninst].n.neoncache[i].t = NEON_CACHE_ST_D;
+    if(dyn->insts[ninst].x87precision) dyn->need_x87check = 2;
     // check combined propagation too
     if(dyn->n.combined1 || dyn->n.combined2) {
         if(dyn->n.swapped) {
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index f135cc91..7cbb8ff1 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -1013,6 +1013,9 @@
         FCVT_D_S(A, A);                             \
     }
 #endif
+#ifndef MARK_X87PC
+#define MARK_X87PC()
+#endif
 #define STORE_REG(A)    STRx_U12(x##A, xEmu, offsetof(x64emu_t, regs[_##A]))
 #define STP_REGS(A, B)  STPx_S7_offset(x##A, x##B, xEmu, offsetof(x64emu_t, regs[_##A]))
 #define LDP_REGS(A, B)  LDPx_S7_offset(x##A, x##B, xEmu, offsetof(x64emu_t, regs[_##A]))
diff --git a/src/dynarec/arm64/dynarec_arm64_pass0.h b/src/dynarec/arm64/dynarec_arm64_pass0.h
index 5307e0e3..2bd18ac5 100644
--- a/src/dynarec/arm64/dynarec_arm64_pass0.h
+++ b/src/dynarec/arm64/dynarec_arm64_pass0.h
@@ -75,3 +75,4 @@
 
 #define NATIVE_RESTORE_X87PC()
 #define X87_CHECK_PRECISION(A)
+#define MARK_X87PC()   if(dyn->need_x87check) dyn->insts[ninst].x87precision = 1
\ No newline at end of file
diff --git a/src/dynarec/arm64/dynarec_arm64_pass1.h b/src/dynarec/arm64/dynarec_arm64_pass1.h
index aaf27385..0f904c61 100644
--- a/src/dynarec/arm64/dynarec_arm64_pass1.h
+++ b/src/dynarec/arm64/dynarec_arm64_pass1.h
@@ -29,3 +29,4 @@
         if (dyn->need_x87check)     \
             dyn->need_x87check = 2; \
     } while (0)
+#define MARK_X87PC()   if(dyn->need_x87check) dyn->insts[ninst].x87precision = 1
\ No newline at end of file
diff --git a/src/dynarec/arm64/dynarec_arm64_private.h b/src/dynarec/arm64/dynarec_arm64_private.h
index f397e949..ed94ada2 100644
--- a/src/dynarec/arm64/dynarec_arm64_private.h
+++ b/src/dynarec/arm64/dynarec_arm64_private.h
@@ -126,6 +126,7 @@ typedef struct instruction_arm64_s {
     unsigned            invert_carry:1; // this opcode force an inverted carry
     unsigned            df_notneeded:1;
     unsigned            unaligned:1;    // this opcode can be re-generated for unaligned special case
+    unsigned            x87precision:1; // this opcode can handle x87pc
     flagcache_t         f_exit;     // flags status at end of instruction
     neoncache_t         n;          // neoncache at end of instruction (but before poping)
     flagcache_t         f_entry;    // flags status before the instruction begin