about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-04-07 10:46:47 +0200
committerptitSeb <sebastien.chev@gmail.com>2023-04-07 12:39:26 +0200
commit07a3a0e1c87f1568af524a0a553ac8c26d4c1e44 (patch)
tree4f599892896de1fe981baa712c91ea9f246a4c0d /src
parentc43f4ea08058436ccbb7a5e5cde473f32ef1105a (diff)
downloadbox64-07a3a0e1c87f1568af524a0a553ac8c26d4c1e44.tar.gz
box64-07a3a0e1c87f1568af524a0a553ac8c26d4c1e44.zip
[ARM64_DYNAREC] Handling of FASTROUND=0 for 66 0F E6 opcode
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64/dynarec_arm64_660f.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c
index b06a9af2..eb459690 100755
--- a/src/dynarec/arm64/dynarec_arm64_660f.c
+++ b/src/dynarec/arm64/dynarec_arm64_660f.c
@@ -2198,8 +2198,32 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             nextop = F8;

             GETEX(v1, 0, 0);

             GETGX_empty(v0);

-            VFCVTZSQD(v0, v1);  // convert double -> int64

-            SQXTN_32(v0, v0);   // convert int64 -> int32 with saturation in lower part, RaZ high part

+            if(box64_dynarec_fastround) {

+                VFCVTZSQD(v0, v1);  // convert double -> int64

+                SQXTN_32(v0, v0);   // convert int64 -> int32 with saturation in lower part, RaZ high part

+            } else {

+                MRS_fpsr(x5);

+                BFCw(x5, FPSR_IOC, 1);   // reset IOC bit

+                MSR_fpsr(x5);

+                ORRw_mask(x4, xZR, 1, 0);    //0x80000000

+                d0 = fpu_get_scratch(dyn);

+                for(int i=1; i>=0; --i) {

+                    BFCw(x5, FPSR_IOC, 1);   // reset IOC bit

+                    MSR_fpsr(x5);

+                    if(i) {

+                        VMOVeD(d0, 0, v1, i);

+                        FRINTZD(d0, d0);

+                    } else {

+                        FRINTZD(d0, v1);

+                    }

+                    FCVTZSwD(x1, d0);

+                    MRS_fpsr(x5);   // get back FPSR to check the IOC bit

+                    TBZ(x5, FPSR_IOC, 4+4);

+                    MOVw_REG(x1, x4);

+                    VMOVQSfrom(v0, i, x1);

+                }

+                VMOVQDfrom(v0, 1, xZR);

+            }

             break;

         case 0xE7:

             INST_NAME("MOVNTDQ Ex, Gx");