about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-06-25 18:12:48 +0200
committerptitSeb <sebastien.chev@gmail.com>2023-06-25 18:12:48 +0200
commit0272446f2b09b70a29242a59f9a583d5bc0e616f (patch)
tree976e3257378b08f0def0c19576f49628126553e9 /src
parent735d7ab1b4bead627d2a380913864be49c214705 (diff)
downloadbox64-0272446f2b09b70a29242a59f9a583d5bc0e616f.tar.gz
box64-0272446f2b09b70a29242a59f9a583d5bc0e616f.zip
[32BITS][ARM64_DYNAREC] Hanlding of STll struct in FILD/FISTP 64bits (for #870)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_df.c42
-rwxr-xr-xsrc/dynarec/arm64/dynarec_arm64_helper.h4
2 files changed, 46 insertions, 0 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_df.c b/src/dynarec/arm64/dynarec_arm64_df.c
index 3e99ceae..c1ae66a3 100644
--- a/src/dynarec/arm64/dynarec_arm64_df.c
+++ b/src/dynarec/arm64/dynarec_arm64_df.c
@@ -291,7 +291,26 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
                     VLD64(v1, wback, fixedaddress);
                     if(!ST_IS_I64(0)) {
+                        if(rex.is32bits) {
+                            // need to also feed the STll stuff...
+                            ADDx_U12(x4, xEmu, offsetof(x64emu_t, fpu_ll));
+                            LDRw_U12(x1, xEmu, offsetof(x64emu_t, top));
+                            int a = 0 - dyn->n.x87stack;
+                            if(a) {
+                                if(a<0) {
+                                    SUBw_U12(x1, x1, -a);
+                                } else {
+                                    ADDw_U12(x1, x1, a);
+                                }
+                                ANDw_mask(x1, x1, 0, 2); //mask=7
+                            }
+                            ADDx_REG_LSL(x1, x4, x1, 4);    // fpu_ll is 2 i64
+                            VSTR64_U12(v1, x1, 8);  // ll
+                        }
                         SCVTFDD(v1, v1);
+                        if(rex.is32bits) {
+                            VSTR64_U12(v1, x1, 0);  // ref
+                        }
                     }
                     break;
                 case 6:
@@ -319,6 +338,29 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         VFCVTZSd(s0, s0);
                         VSTR64_U12(s0, wback, fixedaddress);
                         #else
+                        if(rex.is32bits) {
+                            // need to check STll first...
+                            ADDx_U12(x5, xEmu, offsetof(x64emu_t, fpu_ll));
+                            LDRw_U12(x1, xEmu, offsetof(x64emu_t, top));
+                            VMOVQDto(x3, v1, 0);
+                            int a = 0 - dyn->n.x87stack;
+                            if(a) {
+                                if(a<0) {
+                                    SUBw_U12(x1, x1, -a);
+                                } else {
+                                    ADDw_U12(x1, x1, a);
+                                }
+                                ANDw_mask(x1, x1, 0, 2); //mask=7
+                            }
+                            ADDx_REG_LSL(x1, x5, x1, 4);    // fpu_ll is 2 i64
+                            LDRx_U12(x5, x1, 0);  // ref
+                            SUBx_REG(x5, x5, x3);
+                            CBNZx_MARK2(x5);
+                            LDRx_U12(x5, x1, 8);  // ll
+                            STx(x5, wback, fixedaddress);
+                            B_MARK3(c__);
+                            MARK2;
+                        }
                         MRS_fpsr(x5);
                         BFCw(x5, FPSR_IOC, 1);   // reset IOC bit
                         MSR_fpsr(x5);
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index 64866147..8002b718 100755
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -525,6 +525,10 @@
 #define B_MARK2_nocond              \
     j64 = GETMARK2-(dyn->native_size); \
     B(j64)
+// Branch to MARK2 if reg is 0 (use j64)
+#define CBZx_MARK2(reg)             \
+    j64 = GETMARK2-(dyn->native_size); \
+    CBZx(reg, j64)
 // Branch to MARK2 if reg is not 0 (use j64)
 #define CBNZx_MARK2(reg)            \
     j64 = GETMARK2-(dyn->native_size); \