about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/arm64_emitter.h2
-rw-r--r--src/dynarec/arm64/arm64_printer.c13
-rw-r--r--src/dynarec/arm64/dynarec_arm64_dd.c9
-rw-r--r--src/dynarec/arm64/dynarec_arm64_df.c26
-rw-r--r--src/dynarec/arm64/dynarec_arm64_functions.c8
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h6
-rw-r--r--src/emu/x87emu_private.h4
7 files changed, 44 insertions, 24 deletions
diff --git a/src/dynarec/arm64/arm64_emitter.h b/src/dynarec/arm64/arm64_emitter.h
index f86a93ec..be7bf0c7 100644
--- a/src/dynarec/arm64/arm64_emitter.h
+++ b/src/dynarec/arm64/arm64_emitter.h
@@ -1150,7 +1150,9 @@ int convert_bitmask(uint64_t bitmask);
 #define VFMOVDQ_8(Vd, u8)                   EMIT(FMOV_vector_imm(1, 1, ((u8)>>5)&0b111, (u8)&0b11111, Vd))
 
 #define FMOV_scalar_imm(type, imm8, Rd)     (0b11110<<24 | (type)<<22 | 1<<21 | (imm8)<<13 | 0b100<<10 | (Rd))
+// FMOV to Sd, imm=7 :~6:6:6:6:6:6:5:4 :3:2:1:0....
 #define FMOVS_8(Sd, u8)                     EMIT(FMOV_scalar_imm(0b00, u8, Sd))
+// FMOV to Dd, imm=7 :~6:6:6:6:6:6:6:6:6:5:4 :3:2:1:0....
 #define FMOVD_8(Dd, u8)                     EMIT(FMOV_scalar_imm(0b01, u8, Dd))
 
 // VMOV
diff --git a/src/dynarec/arm64/arm64_printer.c b/src/dynarec/arm64/arm64_printer.c
index 2d28a831..0b043886 100644
--- a/src/dynarec/arm64/arm64_printer.c
+++ b/src/dynarec/arm64/arm64_printer.c
@@ -743,8 +743,12 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
                 snprintf(buff, sizeof(buff), "BFC %s, %d, %d", sf?Xt[Rd]:Wt[Rd], lsb, width);

             else

                 snprintf(buff, sizeof(buff), "BFI %s, %s, %d, %d", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], lsb, width);

-        } else

-            snprintf(buff, sizeof(buff), "BFXIL %s, %s, %d, %d", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], immr, imms-immr+1);

+        } else {

+            if(Rn==31 && immr==0)

+                snprintf(buff, sizeof(buff), "BFC %s, %d, %d", sf?Xt[Rd]:Wt[Rd], immr, imms-immr+1);

+            else

+                snprintf(buff, sizeof(buff), "BFXIL %s, %s, %d, %d", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], immr, imms-immr+1);

+        }

         return buff;

     }

     // ---- BRANCH / TEST

@@ -1643,6 +1647,11 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
         snprintf(buff, sizeof(buff), "%cQXTN%s V%d.%s, V%d.%s", a.U?'U':'S', a.Q?"2":"", Rd, Vd, Rn, Va);

         return buff;

     }

+    if(isMask(opcode, "01U11110ff100001010010nnnnnddddd", &a)) {

+        const char Z[] = {'B', 'H', 'S', 'D', '?'};

+        snprintf(buff, sizeof(buff), "SQXT%sN %c%d, %c%d", a.U?"U":"", Z[sf], Rn, Z[sf+1], Rm);

+        return buff;

+    }

 

     // (S/U)SSHL(2) / (U/S)XTL(2)

     if(isMask(opcode, "0QU011110hhhhiii101001nnnnnddddd", &a)) {

diff --git a/src/dynarec/arm64/dynarec_arm64_dd.c b/src/dynarec/arm64/dynarec_arm64_dd.c
index 33282abd..6e93c789 100644
--- a/src/dynarec/arm64/dynarec_arm64_dd.c
+++ b/src/dynarec/arm64/dynarec_arm64_dd.c
@@ -161,19 +161,20 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     s0 = fpu_get_scratch(dyn, ninst);
                     if(arm64_frintts) {
                         FRINT64ZD(s0, v1);
-                        FCVTZSxD(x2, s0);
-                        STx(x2, ed, fixedaddress);
+                        VFCVTZSd(s0, s0);
+                        VST64(s0, ed, fixedaddress);
                     } else {
                         MRS_fpsr(x5);
                         BFCw(x5, FPSR_IOC, 1);   // reset IOC bit
                         MSR_fpsr(x5);
                         FRINTRRD(s0, v1, 3);
-                        FCVTZSxD(x2, s0);
+                        VFCVTZSd(s0, s0);
+                        VST64(s0, ed, fixedaddress);
                         MRS_fpsr(x5);   // get back FPSR to check the IOC bit
                         TBZ_MARK3(x5, FPSR_IOC);
                         ORRx_mask(x2, xZR, 1, 1, 0);    //0x8000000000000000
-                        MARK3;
                         STx(x2, ed, fixedaddress);
+                        MARK3;
                     }
                 }
                 X87_POP_OR_FAIL(dyn, ninst, x3);
diff --git a/src/dynarec/arm64/dynarec_arm64_df.c b/src/dynarec/arm64/dynarec_arm64_df.c
index 62bdbac7..dd03a515 100644
--- a/src/dynarec/arm64/dynarec_arm64_df.c
+++ b/src/dynarec/arm64/dynarec_arm64_df.c
@@ -356,16 +356,22 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         B_MARK3(c__);
                         MARK2;
                     }
-                    MRS_fpsr(x5);
-                    BFCw(x5, FPSR_IOC, 1);   // reset IOC bit
-                    MSR_fpsr(x5);
-                    FRINTXD(s0, v1);
-                    VFCVTZSd(s0, s0);
-                    VST64(s0, wback, fixedaddress);
-                    MRS_fpsr(x5);   // get back FPSR to check the IOC bit
-                    TBZ_MARK3(x5, FPSR_IOC);
-                    ORRx_mask(x5, xZR, 1, 1, 0);    //0x8000000000000000
-                    STx(x5, wback, fixedaddress);
+                    if(arm64_frintts) {
+                        FRINT64XD(s0, v1);
+                        VFCVTZSd(s0, s0);
+                        VST64(s0, wback, fixedaddress);
+                    } else {
+                        MRS_fpsr(x5);
+                        BFCw(x5, FPSR_IOC, 1);   // reset IOC bit
+                        MSR_fpsr(x5);
+                        FRINTXD(s0, v1);
+                        VFCVTZSd(s0, s0);
+                        VST64(s0, wback, fixedaddress);
+                        MRS_fpsr(x5);   // get back FPSR to check the IOC bit
+                        TBZ_MARK3(x5, FPSR_IOC);
+                        ORRx_mask(x5, xZR, 1, 1, 0);    //0x8000000000000000
+                        STx(x5, wback, fixedaddress);
+                    }
                     MARK3;
                     #endif
                     x87_restoreround(dyn, ninst, u8);
diff --git a/src/dynarec/arm64/dynarec_arm64_functions.c b/src/dynarec/arm64/dynarec_arm64_functions.c
index 28673221..2a7a2a09 100644
--- a/src/dynarec/arm64/dynarec_arm64_functions.c
+++ b/src/dynarec/arm64/dynarec_arm64_functions.c
@@ -926,9 +926,9 @@ uint8_t mark_natflag(dynarec_arm_t* dyn, int ninst, uint8_t flag, int before)
 {
     if(dyn->insts[ninst].x64.set_flags && !before) {
         dyn->insts[ninst].set_nat_flags |= flag;
-        if(dyn->insts[ninst].x64.use_flags) {
-            dyn->insts[ninst].use_nat_flags |= flag;
-        }
+        //if(dyn->insts[ninst].x64.use_flags) {
+        //    dyn->insts[ninst].use_nat_flags |= flag;
+        //}
     } else {
         if(before)
             dyn->insts[ninst].use_nat_flags_before |= flag;
@@ -1098,7 +1098,7 @@ void updateNativeFlags(dynarec_native_t* dyn)
 {
     if(!box64_dynarec_nativeflags)
         return;
-    // backward check if native flags are used
+    // forward check if native flags are used
     for(int ninst=0; ninst<dyn->size; ++ninst)
         if(flag2native(dyn->insts[ninst].x64.gen_flags) && (dyn->insts[ninst].nat_flags_op==NAT_FLAG_OP_TOUCH)) {
             propagateNativeFlags(dyn, ninst);
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index 2da90d59..f47ecaf7 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -950,7 +950,8 @@
     MOV32w(s2, 0b01000101); /* unordered */                                 \
     CSELw(s1, s2, s1, cVS);                                                 \
     if(v1||v2) {                                                            \
-        Bcond(cVS, 10*4);                                                   \
+        Bcond(cVS, 11*4);                                                   \
+        Bcond(cEQ, 10*4);                                                   \
         if(is_f) {                                                          \
             ORRw_mask(s4, xZR, 12, 10); /*+inf*/                            \
             FMOVwS(s2, v1);                                                 \
@@ -996,7 +997,8 @@
         CSELw(s1, s2, s1, cEQ);                                             \
         /* greater than leave 0 */                                          \
         if(s4) {                                                            \
-            Bcond(cVS, 10*4);                                               \
+            Bcond(cVS, 11*4);                                               \
+            Bcond(cEQ, 10*4);                                               \
             if(is_f) {                                                      \
                 ORRw_mask(s4, xZR, 12, 10); /*+inf*/                        \
                 FMOVwS(s2, v1);                                             \
diff --git a/src/emu/x87emu_private.h b/src/emu/x87emu_private.h
index e3f0d233..17691c49 100644
--- a/src/emu/x87emu_private.h
+++ b/src/emu/x87emu_private.h
@@ -73,7 +73,7 @@ static inline void fpu_fcom(x64emu_t* emu, double b)
         emu->sw.f.F87_C0 = 1;
         emu->sw.f.F87_C2 = 1;
         emu->sw.f.F87_C3 = 1;
-    } else if ((b==-INFINITY) || (ST0.d==INFINITY)) {
+    } else if (((b==-INFINITY) || (ST0.d==INFINITY)) && ST0.d!=b) {
         emu->sw.f.F87_C0 = 0;
         emu->sw.f.F87_C2 = 0;
         emu->sw.f.F87_C3 = 0;
@@ -104,7 +104,7 @@ static inline void fpu_fcomi(x64emu_t* emu, double b)
         SET_FLAG(F_CF);
         SET_FLAG(F_PF);
         SET_FLAG(F_ZF);
-    } else if ((b==-INFINITY) || (ST0.d==INFINITY)) {
+    } else if (((b==-INFINITY) || (ST0.d==INFINITY)) && ST0.d!=b) {
         CLEAR_FLAG(F_CF);
         CLEAR_FLAG(F_PF);
         CLEAR_FLAG(F_ZF);