about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-01-04 11:35:11 +0100
committerptitSeb <sebastien.chev@gmail.com>2025-01-04 12:30:28 +0100
commitd0870201399ea7d694a1610f122e148404139491 (patch)
tree6994feadb68efb82062dcb338daf536af2b77e7b /src
parent4065e61ec5fce97d1be4f1e0657037061742d25e (diff)
downloadbox64-d0870201399ea7d694a1610f122e148404139491.tar.gz
box64-d0870201399ea7d694a1610f122e148404139491.zip
[ARM64_DYNAREC] Small improvment on edge cases double to int x87 conversions
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_db.c18
-rw-r--r--src/dynarec/arm64/dynarec_arm64_df.c25
2 files changed, 28 insertions, 15 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_db.c b/src/dynarec/arm64/dynarec_arm64_db.c
index feba2072..d527a6d2 100644
--- a/src/dynarec/arm64/dynarec_arm64_db.c
+++ b/src/dynarec/arm64/dynarec_arm64_db.c
@@ -202,13 +202,17 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 } else {
                     MRS_fpsr(x5);
                     BFCw(x5, FPSR_IOC, 1);   // reset IOC bit
+                    BFCw(x5, FPSR_QC, 1);   // reset QC bit
                     MSR_fpsr(x5);
                     FRINTZD(s0, v1);
                     VFCVTZSd(s0, s0);
                     SQXTN_S_D(s0, s0);
                     VST32(s0, wback, fixedaddress);
                     MRS_fpsr(x5);   // get back FPSR to check the IOC bit
-                    TBZ_MARK3(x5, FPSR_IOC);
+                    TBNZ_MARK2(x5, FPSR_IOC);
+                    TBNZ_MARK2(x5, FPSR_QC);
+                    B_MARK3_nocond;
+                    MARK2;
                     MOV32w(x5, 0x80000000);
                     STW(x5, wback, fixedaddress);
                     MARK3;
@@ -228,13 +232,17 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 } else {
                     MRS_fpsr(x5);
                     BFCw(x5, FPSR_IOC, 1);   // reset IOC bit
+                    BFCw(x5, FPSR_QC, 1);   // reset QC bit
                     MSR_fpsr(x5);
                     FRINTXD(s0, v1);
                     VFCVTZSd(s0, s0);
                     SQXTN_S_D(s0, s0);
                     VST32(s0, wback, fixedaddress);
                     MRS_fpsr(x5);   // get back FPSR to check the IOC bit
-                    TBZ_MARK3(x5, FPSR_IOC);
+                    TBNZ_MARK2(x5, FPSR_IOC);
+                    TBNZ_MARK2(x5, FPSR_QC);
+                    B_MARK3_nocond;
+                    MARK2;
                     MOV32w(x5, 0x80000000);
                     STW(x5, wback, fixedaddress);
                     MARK3;
@@ -254,13 +262,17 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 } else {
                     MRS_fpsr(x5);
                     BFCw(x5, FPSR_IOC, 1);   // reset IOC bit
+                    BFCw(x5, FPSR_QC, 1);   // reset QC bit
                     MSR_fpsr(x5);
                     FRINTXD(s0, v1);
                     VFCVTZSd(s0, s0);
                     SQXTN_S_D(s0, s0);
                     VST32(s0, wback, fixedaddress);
                     MRS_fpsr(x5);   // get back FPSR to check the IOC bit
-                    TBZ_MARK3(x5, FPSR_IOC);
+                    TBNZ_MARK2(x5, FPSR_IOC);
+                    TBNZ_MARK2(x5, FPSR_QC);
+                    B_MARK3_nocond;
+                    MARK2;
                     MOV32w(x5, 0x80000000);
                     STW(x5, wback, fixedaddress);
                     MARK3;
diff --git a/src/dynarec/arm64/dynarec_arm64_df.c b/src/dynarec/arm64/dynarec_arm64_df.c
index bbcf3758..62bdbac7 100644
--- a/src/dynarec/arm64/dynarec_arm64_df.c
+++ b/src/dynarec/arm64/dynarec_arm64_df.c
@@ -175,12 +175,12 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     VFCVTZSd(s0, v1);
                     SQXTN_S_D(s0, s0);
                 }
-                VMOVSto(x3, s0, 0);
+                SQXTN_H_S(s0, s0);
+                VMOVHto(x3, s0, 0);
                 MRS_fpsr(x5);   // get back FPSR to check the IOC bit
                 TBNZ_MARK2(x5, FPSR_IOC);
-                SXTHw(x5, x3);  // check if 16bits value is fine
-                SUBw_REG(x5, x5, x3);
-                CBZw_MARK3(x5);
+                TBNZ_MARK2(x5, FPSR_QC);
+                B_MARK3_nocond;
                 MARK2;
                 MOV32w(x3, 0x8000);
                 MARK3;
@@ -215,12 +215,12 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     VFCVTZSd(s0, s0);
                     SQXTN_S_D(s0, s0);
                 }
-                VMOVSto(x3, s0, 0);
+                SQXTN_H_S(s0, s0);
+                VMOVHto(x3, s0, 0);
                 MRS_fpsr(x5);   // get back FPSR to check the IOC bit
                 TBNZ_MARK2(x5, FPSR_IOC);
-                SXTHw(x5, x3);  // check if 16bits value is fine
-                SUBw_REG(x5, x5, x3);
-                CBZw_MARK3(x5);
+                TBNZ_MARK2(x5, FPSR_QC);
+                B_MARK3_nocond;
                 MARK2;
                 MOV32w(x3, 0x8000);
                 MARK3;
@@ -245,6 +245,7 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 #else
                 MRS_fpsr(x5);
                 BFCw(x5, FPSR_IOC, 1);   // reset IOC bit
+                BFCw(x5, FPSR_QC, 1);   // reset QC bit
                 MSR_fpsr(x5);
                 if(ST_IS_F(0)) {
                     FRINTXS(s0, v1);
@@ -254,12 +255,12 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     VFCVTZSd(s0, s0);
                     SQXTN_S_D(s0, s0);
                 }
-                VMOVSto(x3, s0, 0);
+                SQXTN_H_S(s0, s0);
+                VMOVHto(x3, s0, 0);
                 MRS_fpsr(x5);   // get back FPSR to check the IOC bit
                 TBNZ_MARK2(x5, FPSR_IOC);
-                SXTHw(x5, x3);  // check if 16bits value is fine
-                SUBw_REG(x5, x5, x3);
-                CBZw_MARK3(x5);
+                TBNZ_MARK2(x5, FPSR_QC);
+                B_MARK3_nocond;
                 MARK2;
                 MOV32w(x3, 0x8000);
                 MARK3;