about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-04-22 18:59:57 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-04-22 18:59:57 +0200
commit17b7ec6358b58fc887135be78d368642397fc839 (patch)
tree9aa4c121589bfd3066a678af4618272ae7717646 /src
parent73c3190c86f72c542fc0b60e7ee8d69e28eb2546 (diff)
downloadbox64-17b7ec6358b58fc887135be78d368642397fc839.tar.gz
box64-17b7ec6358b58fc887135be78d368642397fc839.zip
[ARM64_DYNAREC] Small optim on flags handling
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c62
-rw-r--r--src/dynarec/arm64/dynarec_arm64_0f.c10
-rw-r--r--src/dynarec/arm64/dynarec_arm64_64.c18
-rw-r--r--src/dynarec/arm64/dynarec_arm64_66.c14
-rw-r--r--src/dynarec/arm64/dynarec_arm64_660f.c9
-rw-r--r--src/dynarec/arm64/dynarec_arm64_67.c14
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.c4
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h2
-rw-r--r--src/dynarec/arm64/dynarec_arm64_pass0.h4
-rw-r--r--src/dynarec/dynarec_private.h2
10 files changed, 69 insertions, 70 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index 638c41de..1b5915b8 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -401,7 +401,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 INST_NAME("DAA");
                 MESSAGE(LOG_DUMP, "Need Optimization DAA\n");
                 READFLAGS(X_AF|X_CF);
-                SETFLAGS(X_ALL, SF_SET);
+                SETFLAGS(X_ALL, SF_SET_DF);
                 UXTBx(x1, xRAX);
                 CALL_(daa8, x1, 0);
                 BFIz(xRAX, x1, 0, 8);
@@ -466,7 +466,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 INST_NAME("DAS");
                 MESSAGE(LOG_DUMP, "Need Optimization DAS\n");
                 READFLAGS(X_AF|X_CF);
-                SETFLAGS(X_ALL, SF_SET);
+                SETFLAGS(X_ALL, SF_SET_DF);
                 UXTBx(x1, xRAX);
                 CALL_(das8, x1, 0);
                 BFIz(xRAX, x1, 0, 8);
@@ -531,7 +531,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 INST_NAME("AAA");
                 MESSAGE(LOG_DUMP, "Need Optimization AAA\n");
                 READFLAGS(X_AF);
-                SETFLAGS(X_ALL, SF_SET);
+                SETFLAGS(X_ALL, SF_SET_DF);
                 UXTHx(x1, xRAX);
                 CALL_(aaa16, x1, 0);
                 BFIz(xRAX, x1, 0, 16);
@@ -599,7 +599,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 INST_NAME("AAS");
                 MESSAGE(LOG_DUMP, "Need Optimization AAS\n");
                 READFLAGS(X_AF);
-                SETFLAGS(X_ALL, SF_SET);
+                SETFLAGS(X_ALL, SF_SET_DF);
                 UXTHw(x1, xRAX);
                 CALL_(aas16, x1, 0);
                 BFIx(xRAX, x1, 0, 16);
@@ -973,7 +973,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
         case 0x6C:
         case 0x6D:
             INST_NAME(opcode == 0x6C ? "INSB" : "INSD");
-            SETFLAGS(X_ALL, SF_SET);    // Hack to set flags in "don't care" state
+            SETFLAGS(X_ALL, SF_SET_NODF);    // Hack to set flags in "don't care" state
             GETIP(ip);
             STORE_XEMU_CALL(xRIP);
             CALL(native_priv, -1);
@@ -985,7 +985,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
         case 0x6E:
         case 0x6F:
             INST_NAME(opcode == 0x6C ? "OUTSB" : "OUTSD");
-            SETFLAGS(X_ALL, SF_SET);    // Hack to set flags in "don't care" state
+            SETFLAGS(X_ALL, SF_SET_NODF);    // Hack to set flags in "don't care" state
             GETIP(ip);
             STORE_XEMU_CALL(xRIP);
             CALL(native_priv, -1);
@@ -2076,7 +2076,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     MESSAGE(LOG_DUMP, "Need Optimization\n");
                     READFLAGS(X_CF);
                     u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
-                    SETFLAGS(X_OF|X_CF, SF_SET);
+                    SETFLAGS(X_OF|X_CF, SF_SET_DF);
                     GETEDW(x4, x1, 1);
                     u8 = F8;
                     MOV32w(x2, u8);
@@ -2088,7 +2088,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     MESSAGE(LOG_DUMP, "Need Optimization\n");
                     READFLAGS(X_CF);
                     u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
-                    SETFLAGS(X_OF|X_CF, SF_SET);
+                    SETFLAGS(X_OF|X_CF, SF_SET_DF);
                     GETEDW(x4, x1, 1);
                     u8 = F8;
                     MOV32w(x2, u8);
@@ -2157,7 +2157,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             break;
         case 0xC2:
             INST_NAME("RETN");
-            //SETFLAGS(X_ALL, SF_SET);    // Hack, set all flags (to an unknown state...)
+            //SETFLAGS(X_ALL, SF_SET_NODF);    // Hack, set all flags (to an unknown state...)
             if(box64_dynarec_safeflags) {
                 READFLAGS(X_PEND);  // lets play safe here too
             }
@@ -2169,7 +2169,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             break;
         case 0xC3:
             INST_NAME("RET");
-            // SETFLAGS(X_ALL, SF_SET);    // Hack, set all flags (to an unknown state...)
+            // SETFLAGS(X_ALL, SF_SET_NODF);    // Hack, set all flags (to an unknown state...)
             if(box64_dynarec_safeflags) {
                 READFLAGS(X_PEND);  // so instead, force the deferred flags, so it's not too slow, and flags are not lost
             }
@@ -2285,7 +2285,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             break;
 
         case 0xCC:
-            SETFLAGS(X_ALL, SF_SET);    // Hack, set all flags (to an unknown state...)
+            SETFLAGS(X_ALL, SF_SET_NODF);    // Hack, set all flags (to an unknown state...)
             NOTEST(x1);
             if(PK(0)=='S' && PK(1)=='C') {
                 addr+=2;
@@ -2383,7 +2383,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 jump_to_epilog(dyn, 0, xRIP, ninst);
             } else {
                 INST_NAME("INT n");
-                SETFLAGS(X_ALL, SF_SET);    // Hack to set flags in "don't care" state
+                SETFLAGS(X_ALL, SF_SET_NODF);    // Hack to set flags in "don't care" state
                 GETIP(ip);
                 STORE_XEMU_CALL(xRIP);
                 CALL(native_int, -1);
@@ -2396,7 +2396,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
 
         case 0xCF:
             INST_NAME("IRET");
-            SETFLAGS(X_ALL, SF_SET);    // Not a hack, EFLAGS are restored
+            SETFLAGS(X_ALL, SF_SET_NODF);    // Not a hack, EFLAGS are restored
             BARRIER(BARRIER_FLOAT);
             iret_to_epilog(dyn, ninst, rex.w);
             *need_epilog = 0;
@@ -2480,7 +2480,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("RCL Ed, 1");
                     MESSAGE(LOG_DUMP, "Need Optimization\n");
                     READFLAGS(X_CF);
-                    SETFLAGS(X_OF|X_CF, SF_SET);
+                    SETFLAGS(X_OF|X_CF, SF_SET_DF);
                     MOV32w(x2, 1);
                     GETEDW(x4, x1, 0);
                     CALL_(rex.w?((void*)rcl64):((void*)rcl32), ed, x4);
@@ -2490,7 +2490,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("RCR Ed, 1");
                     MESSAGE(LOG_DUMP, "Need Optimization\n");
                     READFLAGS(X_CF);
-                    SETFLAGS(X_OF|X_CF, SF_SET);
+                    SETFLAGS(X_OF|X_CF, SF_SET_DF);
                     MOV32w(x2, 1);
                     GETEDW(x4, x1, 0);
                     CALL_(rex.w?((void*)rcr64):((void*)rcr32), ed, x4);
@@ -2580,7 +2580,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     READFLAGS(X_CF);
                     if(box64_dynarec_safeflags>1)
                         MAYSETFLAGS();
-                    SETFLAGS(X_OF|X_CF, SF_SET);
+                    SETFLAGS(X_OF|X_CF, SF_SET_DF);
                     ANDSw_mask(x2, xRCX, 0, 0b00100);
                     GETEB(x1, 0);
                     CALL_(rcl8, x1, x3);
@@ -2592,7 +2592,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     READFLAGS(X_CF);
                     if(box64_dynarec_safeflags>1)
                         MAYSETFLAGS();
-                    SETFLAGS(X_OF|X_CF, SF_SET);
+                    SETFLAGS(X_OF|X_CF, SF_SET_DF);
                     ANDSw_mask(x2, xRCX, 0, 0b00100);
                     GETEB(x1, 0);
                     CALL_(rcr8, x1, x3);
@@ -2726,7 +2726,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("RCL Ed, CL");
                     MESSAGE(LOG_DUMP, "Need Optimization\n");
                     READFLAGS(X_CF);
-                    SETFLAGS(X_OF|X_CF, SF_SET);
+                    SETFLAGS(X_OF|X_CF, SF_SET_DF);
                     if(box64_dynarec_safeflags>1)
                         MAYSETFLAGS();
                     if(rex.w) {
@@ -2744,7 +2744,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("RCR Ed, CL");
                     MESSAGE(LOG_DUMP, "Need Optimization\n");
                     READFLAGS(X_CF);
-                    SETFLAGS(X_OF|X_CF, SF_SET);
+                    SETFLAGS(X_OF|X_CF, SF_SET_DF);
                     if(box64_dynarec_safeflags>1)
                         MAYSETFLAGS();
                     if(rex.w) {
@@ -2845,7 +2845,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
         case 0xD4:
             if(rex.is32bits) {
                 INST_NAME("AAM Ib");
-                SETFLAGS(X_ALL, SF_SET);
+                SETFLAGS(X_ALL, SF_SET_DF);
                 UBFXx(x1, xRAX, 0, 8);    // load AL
                 u8 = F8;
                 MOV32w(x2, u8);
@@ -2858,7 +2858,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
         case 0xD5:
             if(rex.is32bits) {
                 INST_NAME("AAD Ib");
-                SETFLAGS(X_ALL, SF_SET);
+                SETFLAGS(X_ALL, SF_SET_DF);
                 UBFXx(x1, xRAX, 0, 16);    // load AX
                 u8 = F8;
                 MOV32w(x2, u8);
@@ -2954,7 +2954,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
         case 0xE6:                      /* OUT Ib, AL */
         case 0xE7:                      /* OUT Ib, EAX */
             INST_NAME(opcode==0xE4?"IN AL, Ib":(opcode==0xE5?"IN EAX, Ib":(opcode==0xE6?"OUT Ib, AL":"OUT Ib, EAX")));
-            SETFLAGS(X_ALL, SF_SET);    // Hack to set flags in "don't care" state
+            SETFLAGS(X_ALL, SF_SET_NODF);    // Hack to set flags in "don't care" state
             u8 = F8;
             GETIP(ip);
             STORE_XEMU_CALL(xRIP);
@@ -2982,7 +2982,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             #endif
             switch(tmp) {
                 case 3:
-                    SETFLAGS(X_ALL, SF_SET);    // Hack to set flags to "dont'care" state
+                    SETFLAGS(X_ALL, SF_SET_NODF);    // Hack to set flags to "dont'care" state
                     if(dyn->last_ip && (addr-dyn->last_ip<0x1000)) {
                         ADDx_U12(x2, xRIP, addr-dyn->last_ip);
                     } else {
@@ -3038,7 +3038,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     if((box64_dynarec_safeflags>1) || (ninst && dyn->insts[ninst-1].x64.set_flags)) {
                         READFLAGS(X_PEND);  // that's suspicious
                     } else {
-                        SETFLAGS(X_ALL, SF_SET);    // Hack to set flags to "dont'care" state
+                        SETFLAGS(X_ALL, SF_SET_NODF);    // Hack to set flags to "dont'care" state
                     }
                     // regular call
                     if(box64_dynarec_callret && box64_dynarec_bigblock>1) {
@@ -3123,7 +3123,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
         case 0xEE:                      /* OUT DX, AL */
         case 0xEF:                      /* OUT DX, EAX */
             INST_NAME(opcode==0xEC?"IN AL, DX":(opcode==0xED?"IN EAX, DX":(opcode==0xEE?"OUT DX, AL":"OUT DX, EAX")));
-            SETFLAGS(X_ALL, SF_SET);    // Hack to set flags in "don't care" state
+            SETFLAGS(X_ALL, SF_SET_NODF);    // Hack to set flags in "don't care" state
             GETIP(ip);
             STORE_XEMU_CALL(xRIP);
             CALL(native_priv, -1);
@@ -3139,7 +3139,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
 
         case 0xF4:
             INST_NAME("HLT");
-            SETFLAGS(X_ALL, SF_SET);    // Hack to set flags in "don't care" state
+            SETFLAGS(X_ALL, SF_SET_NODF);    // Hack to set flags in "don't care" state
             GETIP(ip);
             STORE_XEMU_CALL(xRIP);
             CALL(native_priv, -1);
@@ -3202,6 +3202,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 6:
                     INST_NAME("DIV Eb");
                     SETFLAGS(X_ALL, SF_SET);
+                    SET_DFNONE(x1);
                     GETEB(x1, 0);
                     UXTHw(x2, xRAX);
                     if(box64_dynarec_div0) {
@@ -3223,6 +3224,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("IDIV Eb");
                     SKIPTEST(x1);
                     SETFLAGS(X_ALL, SF_SET);
+                    SET_DFNONE(x1);
                     GETSEB(x1, 0);
                     if(box64_dynarec_div0) {
                         CBNZw_MARK3(ed);
@@ -3389,8 +3391,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("IDIV Ed");
                     SKIPTEST(x1);
                     SETFLAGS(X_ALL, SF_SET);
+                    SET_DFNONE(x2)
                     if(!rex.w) {
-                        SET_DFNONE(x2)
                         GETSEDw(0);
                         if(box64_dynarec_div0) {
                             CBNZx_MARK3(wb);
@@ -3413,7 +3415,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                            &&  dyn->insts[ninst-1].x64.addr
                            && *(uint8_t*)(dyn->insts[ninst-1].x64.addr)==0x48
                            && *(uint8_t*)(dyn->insts[ninst-1].x64.addr+1)==0x99) {
-                            SET_DFNONE(x2)
                             GETED(0);
                             if(box64_dynarec_div0) {
                                 CBNZx_MARK3(ed);
@@ -3456,7 +3457,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             SDIVx(x2, xRAX, ed);
                             MSUBx(xRDX, x2, ed, xRAX);
                             MOVx_REG(xRAX, x2);
-                            SET_DFNONE(x2)
                         }
                     }
                     break;
@@ -3477,7 +3477,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
         case 0xFA:                      /* STI */
         case 0xFB:                      /* CLI */
             INST_NAME(opcode==0xFA?"CLI":"STI");
-            SETFLAGS(X_ALL, SF_SET);    // Hack to set flags in "don't care" state
+            SETFLAGS(X_ALL, SF_SET_NODF);    // Hack to set flags in "don't care" state
             GETIP(ip);
             STORE_XEMU_CALL(xRIP);
             CALL(native_priv, -1);
@@ -3541,7 +3541,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     {
                         READFLAGS(X_PEND);          // that's suspicious
                     } else {
-                        SETFLAGS(X_ALL, SF_SET);    //Hack to put flag in "don't care" state
+                        SETFLAGS(X_ALL, SF_SET_NODF);    //Hack to put flag in "don't care" state
                     }
                     GETEDz(0);
                     if(box64_dynarec_callret && box64_dynarec_bigblock>1) {
diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c
index 8e8ec00e..35caadcb 100644
--- a/src/dynarec/arm64/dynarec_arm64_0f.c
+++ b/src/dynarec/arm64/dynarec_arm64_0f.c
@@ -69,7 +69,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             switch(nextop) {

                 case 0xD0:

                     INST_NAME("FAKE xgetbv");

-                    SETFLAGS(X_ALL, SF_SET);    // Hack to set flags in "don't care" state

+                    SETFLAGS(X_ALL, SF_SET_NODF);    // Hack to set flags in "don't care" state

                     GETIP(ip);

                     STORE_XEMU_CALL(xRIP);

                     CALL(native_ud, -1);

@@ -166,7 +166,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
 

         case 0x09:

             INST_NAME("WBINVD");

-            SETFLAGS(X_ALL, SF_SET);    // Hack to set flags in "don't care" state

+            SETFLAGS(X_ALL, SF_SET_NODF);    // Hack to set flags in "don't care" state

             GETIP(ip);

             STORE_XEMU_CALL(xRIP);

             CALL(native_ud, -1);

@@ -178,7 +178,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
 

         case 0x0B:

             INST_NAME("UD2");

-            SETFLAGS(X_ALL, SF_SET);    // Hack to set flags in "don't care" state

+            SETFLAGS(X_ALL, SF_SET_NODF);    // Hack to set flags in "don't care" state

             GETIP(ip);

             STORE_XEMU_CALL(xRIP);

             CALL(native_ud, -1);

@@ -202,7 +202,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             break;

         case 0x0E:

             INST_NAME("femms");

-            SETFLAGS(X_ALL, SF_SET);    // Hack to set flags in "don't care" state

+            SETFLAGS(X_ALL, SF_SET_NODF);    // Hack to set flags in "don't care" state

             GETIP(ip);

             STORE_XEMU_CALL(xRIP);

             CALL(native_ud, -1);

@@ -486,7 +486,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             // no special check...

         case 0x2F:

             if(opcode==0x2F) {INST_NAME("COMISS Gx, Ex");} else {INST_NAME("UCOMISS Gx, Ex");}

-            SETFLAGS(X_ALL, SF_SET);

+            SETFLAGS(X_ALL, SF_SET_NODF);

             nextop = F8;

             GETGX(v0, 0);

             GETEXSS(s0, 0, 0);

diff --git a/src/dynarec/arm64/dynarec_arm64_64.c b/src/dynarec/arm64/dynarec_arm64_64.c
index 028fc343..a7bc2aef 100644
--- a/src/dynarec/arm64/dynarec_arm64_64.c
+++ b/src/dynarec/arm64/dynarec_arm64_64.c
@@ -784,7 +784,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("RCL Ed, 1");
                     MESSAGE(LOG_DUMP, "Need Optimization\n");
                     READFLAGS(X_CF);
-                    SETFLAGS(X_OF|X_CF, SF_SET);
+                    SETFLAGS(X_OF|X_CF, SF_SET_DF);
                     MOV32w(x2, 1);
                     GETEDO(x6, 0);
                     if(wback) {ADDx_REG(x6, x6, wback); wback=x6;}
@@ -796,7 +796,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("RCR Ed, 1");
                     MESSAGE(LOG_DUMP, "Need Optimization\n");
                     READFLAGS(X_CF);
-                    SETFLAGS(X_OF|X_CF, SF_SET);
+                    SETFLAGS(X_OF|X_CF, SF_SET_DF);
                     MOV32w(x2, 1);
                     GETEDO(x6, 0);
                     if(wback) {ADDx_REG(x6, x6, wback); wback=x6;}
@@ -887,7 +887,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("RCL Ed, CL");
                     MESSAGE(LOG_DUMP, "Need Optimization\n");
                     READFLAGS(X_CF);
-                    SETFLAGS(X_OF|X_CF, SF_SET);
+                    SETFLAGS(X_OF|X_CF, SF_SET_DF);
                     if(rex.w) {
                         ANDSx_mask(x2, xRCX, 1, 0, 0b00101);  //mask=0x000000000000003f
                     } else {
@@ -904,7 +904,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("RCR Ed, CL");
                     MESSAGE(LOG_DUMP, "Need Optimization\n");
                     READFLAGS(X_CF);
-                    SETFLAGS(X_OF|X_CF, SF_SET);
+                    SETFLAGS(X_OF|X_CF, SF_SET_DF);
                     if(rex.w) {
                         ANDSx_mask(x2, xRCX, 1, 0, 0b00101);  //mask=0x000000000000003f
                     } else {
@@ -1031,8 +1031,8 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 6:
                     INST_NAME("DIV Ed");
                     SETFLAGS(X_ALL, SF_SET);
+                    SET_DFNONE(x2);
                     if(!rex.w) {
-                        SET_DFNONE(x2);
                         GETEDO(x6, 0);
                         if(box64_dynarec_div0) {
                             CBNZx_MARK3(ed);
@@ -1059,7 +1059,6 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                            && dyn->insts[ninst-1].x64.addr
                            && *(uint8_t*)(dyn->insts[ninst-1].x64.addr)==0x31
                            && *(uint8_t*)(dyn->insts[ninst-1].x64.addr+1)==0xD2) {
-                            SET_DFNONE(x2);
                             GETEDO(x6, 0);
                             if(box64_dynarec_div0) {
                                 CBNZx_MARK3(ed);
@@ -1094,7 +1093,6 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             UDIVx(x2, xRAX, ed);
                             MSUBx(xRDX, x2, ed, xRAX);
                             MOVx_REG(xRAX, x2);
-                            SET_DFNONE(x2);
                         }
                     }
                     break;
@@ -1102,8 +1100,8 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("IDIV Ed");
                     NOTEST(x1);
                     SETFLAGS(X_ALL, SF_SET);
+                    SET_DFNONE(x2)
                     if(!rex.w) {
-                        SET_DFNONE(x2)
                         GETSEDOw(x6, 0);
                         MOVw_REG(x3, xRAX);
                         ORRx_REG_LSL(x3, x3, xRDX, 32);
@@ -1126,7 +1124,6 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                            &&  dyn->insts[ninst-1].x64.addr
                            && *(uint8_t*)(dyn->insts[ninst-1].x64.addr)==0x48
                            && *(uint8_t*)(dyn->insts[ninst-1].x64.addr+1)==0x99) {
-                            SET_DFNONE(x2)
                             GETEDO(x6, 0);
                             if(box64_dynarec_div0) {
                                 CBNZx_MARK3(ed);
@@ -1163,7 +1160,6 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             SDIVx(x2, xRAX, ed);
                             MSUBx(xRDX, x2, ed, xRAX);
                             MOVx_REG(xRAX, x2);
-                            SET_DFNONE(x2)
                         }
                     }
                     break;
@@ -1196,7 +1192,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     {
                         READFLAGS(X_PEND);          // that's suspicious
                     } else {
-                        SETFLAGS(X_ALL, SF_SET);    //Hack to put flag in "don't care" state
+                        SETFLAGS(X_ALL, SF_SET_NODF);    //Hack to put flag in "don't care" state
                     }
                     GETEDOz(x6, 0);
                     if(box64_dynarec_callret && box64_dynarec_bigblock>1) {
diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c
index 8945b365..e6761c63 100644
--- a/src/dynarec/arm64/dynarec_arm64_66.c
+++ b/src/dynarec/arm64/dynarec_arm64_66.c
@@ -978,7 +978,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     MESSAGE(LOG_DUMP, "Need Optimization\n");

                     READFLAGS(X_CF);

                     u8 = geted_ib(dyn, addr, ninst, nextop) & 0x1f;

-                    SETFLAGS(X_OF | X_CF, SF_SET);

+                    SETFLAGS(X_OF | X_CF, SF_SET_DF);

                     GETEW(x1, 1);

                     u8 = F8;

                     MOV32w(x2, u8);

@@ -990,7 +990,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     MESSAGE(LOG_DUMP, "Need Optimization\n");

                     READFLAGS(X_CF);

                     u8 = geted_ib(dyn, addr, ninst, nextop) & 0x1f;

-                    SETFLAGS(X_OF | X_CF, SF_SET);

+                    SETFLAGS(X_OF | X_CF, SF_SET_DF);

                     GETEW(x1, 1);

                     u8 = F8;

                     MOV32w(x2, u8);

@@ -1078,7 +1078,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("RCL Ew, 1");

                     MESSAGE(LOG_DUMP, "Need Optimization\n");

                     READFLAGS(X_CF);

-                    SETFLAGS(X_OF|X_CF, SF_SET);

+                    SETFLAGS(X_OF|X_CF, SF_SET_DF);

                     MOV32w(x2, 1);

                     GETEW(x1, 0);

                     CALL_(rcl16, x1, x3);

@@ -1088,7 +1088,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("RCR Ew, 1");

                     MESSAGE(LOG_DUMP, "Need Optimization\n");

                     READFLAGS(X_CF);

-                    SETFLAGS(X_OF|X_CF, SF_SET);

+                    SETFLAGS(X_OF|X_CF, SF_SET_DF);

                     MOV32w(x2, 1);

                     GETEW(x1, 0);

                     CALL_(rcr16, x1, x3);

@@ -1179,7 +1179,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     READFLAGS(X_CF);

                     if(box64_dynarec_safeflags>1)

                         MAYSETFLAGS();

-                    SETFLAGS(X_OF|X_CF, SF_SET);

+                    SETFLAGS(X_OF|X_CF, SF_SET_DF);

                     ANDw_mask(x2, xRCX, 0, 0b00100);

                     GETEW(x1, 0);

                     CALL_(rcl16, x1, x3);

@@ -1191,7 +1191,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     READFLAGS(X_CF);

                     if(box64_dynarec_safeflags>1)

                         MAYSETFLAGS();

-                    SETFLAGS(X_OF|X_CF, SF_SET);

+                    SETFLAGS(X_OF|X_CF, SF_SET_DF);

                     ANDw_mask(x2, xRCX, 0, 0b00100);

                     GETEW(x1, 0);

                     CALL_(rcr16, x1, x3);

@@ -1299,6 +1299,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 6:

                     INST_NAME("DIV Ew");

                     SETFLAGS(X_ALL, SF_SET);

+                    SET_DFNONE(x1);

                     GETEW(x1, 0);

                     UXTHw(x2, xRAX);

                     BFIw(x2, xRDX, 16, 16);

@@ -1321,6 +1322,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("IDIV Ew");

                     SKIPTEST(x1);

                     SETFLAGS(X_ALL, SF_SET);

+                    SET_DFNONE(x1);

                     GETSEW(x1, 0);

                     if(box64_dynarec_div0) {

                         CBNZw_MARK3(ed);

diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c
index bed76d36..2b9a413e 100644
--- a/src/dynarec/arm64/dynarec_arm64_660f.c
+++ b/src/dynarec/arm64/dynarec_arm64_660f.c
@@ -1229,7 +1229,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
 

                 case 0x60:

                     INST_NAME("PCMPESTRM Gx, Ex, Ib");

-                    SETFLAGS(X_OF|X_CF|X_AF|X_ZF|X_SF|X_PF, SF_SET);

+                    SETFLAGS(X_ALL, SF_SET_DF);

                     nextop = F8;

                     GETG;

                     sse_forget_reg(dyn, ninst, gd);

@@ -1284,11 +1284,11 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                     break;

                 case 0x61:

                     INST_NAME("PCMPESTRI Gx, Ex, Ib");

-                    SETFLAGS(X_ALL, SF_SET);

                     nextop = F8;

                     GETG;

                     u8 = geted_ib(dyn, addr, ninst, nextop);

                     if((u8&0b1100)==0b1000) {

+                        SETFLAGS(X_ALL, SF_SET);

                         // this case is (un)signed word, equal each

                         GETGX(v0, 0);

                         GETEX(v1, 0, 1);

@@ -1397,6 +1397,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                             }

                         }

                     } else {

+                        SETFLAGS(X_ALL, SF_SET_DF);

                         if(gd>7)    // no need to reflect cache as xmm0-xmm7 will be saved before the function call anyway

                             sse_reflect_reg(dyn, ninst, gd);

                         ADDx_U12(x3, xEmu, offsetof(x64emu_t, xmm[gd]));

@@ -1433,7 +1434,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                     break;

                 case 0x62:

                     INST_NAME("PCMPISTRM Gx, Ex, Ib");

-                    SETFLAGS(X_OF|X_CF|X_AF|X_ZF|X_SF|X_PF, SF_SET);

+                    SETFLAGS(X_ALL, SF_SET_DF);

                     nextop = F8;

                     GETG;

                     sse_forget_reg(dyn, ninst, gd);

@@ -1486,7 +1487,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                     break;

                 case 0x63:

                     INST_NAME("PCMPISTRI Gx, Ex, Ib");

-                    SETFLAGS(X_OF|X_CF|X_AF|X_ZF|X_SF|X_PF, SF_SET);

+                    SETFLAGS(X_ALL, SF_SET_DF);

                     nextop = F8;

                     GETG;

                     if(gd>7)

diff --git a/src/dynarec/arm64/dynarec_arm64_67.c b/src/dynarec/arm64/dynarec_arm64_67.c
index 82dd7a27..e1a3fc4c 100644
--- a/src/dynarec/arm64/dynarec_arm64_67.c
+++ b/src/dynarec/arm64/dynarec_arm64_67.c
@@ -936,7 +936,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("RCL Ed, Ib");

                     MESSAGE(LOG_DUMP, "Need Optimization\n");

                     READFLAGS(X_CF);

-                    SETFLAGS(X_OF|X_CF, SF_SET);

+                    SETFLAGS(X_OF|X_CF, SF_SET_DF);

                     GETED32W(x4, x1, 1);

                     u8 = F8;

                     MOV32w(x2, u8);

@@ -947,7 +947,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("RCR Ed, Ib");

                     MESSAGE(LOG_DUMP, "Need Optimization\n");

                     READFLAGS(X_CF);

-                    SETFLAGS(X_OF|X_CF, SF_SET);

+                    SETFLAGS(X_OF|X_CF, SF_SET_DF);

                     GETED32W(x4, x1, 1);

                     u8 = F8;

                     MOV32w(x2, u8);

@@ -1160,8 +1160,8 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 6:

                     INST_NAME("DIV Ed");

                     SETFLAGS(X_ALL, SF_SET);

+                    SET_DFNONE(x2);

                     if(!rex.w) {

-                        SET_DFNONE(x2);

                         GETED32(0);

                         MOVw_REG(x3, xRAX);

                         ORRx_REG_LSL(x3, x3, xRDX, 32);

@@ -1178,7 +1178,6 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                            && dyn->insts[ninst-1].x64.addr

                            && *(uint8_t*)(dyn->insts[ninst-1].x64.addr)==0x31

                            && *(uint8_t*)(dyn->insts[ninst-1].x64.addr+1)==0xD2) {

-                            SET_DFNONE(x2);

                             GETED32(0);

                             UDIVx(x2, xRAX, ed);

                             MSUBx(xRDX, x2, ed, xRAX);

@@ -1193,7 +1192,6 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             UDIVx(x2, xRAX, ed);

                             MSUBx(xRDX, x2, ed, xRAX);

                             MOVx_REG(xRAX, x2);

-                            SET_DFNONE(x2);

                         }

                     }

                     break;

@@ -1201,8 +1199,8 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("IDIV Ed");

                     NOTEST(x1);

                     SETFLAGS(X_ALL, SF_SET);

+                    SET_DFNONE(x2);

                     if(!rex.w) {

-                        SET_DFNONE(x2)

                         GETSED32w(0);

                         MOVw_REG(x3, xRAX);

                         ORRx_REG_LSL(x3, x3, xRDX, 32);

@@ -1215,7 +1213,6 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                            &&  dyn->insts[ninst-1].x64.addr

                            && *(uint8_t*)(dyn->insts[ninst-1].x64.addr)==0x48

                            && *(uint8_t*)(dyn->insts[ninst-1].x64.addr+1)==0x99) {

-                            SET_DFNONE(x2)

                             GETED32(0);

                             SDIVx(x2, xRAX, ed);

                             MSUBx(xRDX, x2, ed, xRAX);

@@ -1232,7 +1229,6 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             SDIVx(x2, xRAX, ed);

                             MSUBx(xRDX, x2, ed, xRAX);

                             MOVx_REG(xRAX, x2);

-                            SET_DFNONE(x2)

                         }

                     }

                     break;

@@ -1249,7 +1245,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     {

                         READFLAGS(X_PEND);          // that's suspicious

                     } else {

-                        SETFLAGS(X_ALL, SF_SET);    //Hack to put flag in "don't care" state

+                        SETFLAGS(X_ALL, SF_SET_NODF);    //Hack to put flag in "don't care" state

                     }

                     GETED32(0);

                     if(box64_dynarec_callret && box64_dynarec_bigblock>1) {

diff --git a/src/dynarec/arm64/dynarec_arm64_helper.c b/src/dynarec/arm64/dynarec_arm64_helper.c
index 69850eb6..b8eb06f2 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.c
+++ b/src/dynarec/arm64/dynarec_arm64_helper.c
@@ -776,7 +776,7 @@ void call_c(dynarec_arm_t* dyn, int ninst, void* fnc, int reg, int ret, int save
     if(saveflags) {
         LDRx_U12(xFlags, xEmu, offsetof(x64emu_t, eflags));
     }
-    SET_NODF();
+    //SET_NODF();
 }
 
 void call_n(dynarec_arm_t* dyn, int ninst, void* fnc, int w)
@@ -822,7 +822,7 @@ void call_n(dynarec_arm_t* dyn, int ninst, void* fnc, int w)
 
     fpu_popcache(dyn, ninst, x3, 1);
     LDRx_U12(xFlags, xEmu, offsetof(x64emu_t, eflags));
-    SET_NODF();
+    //SET_NODF();
 }
 
 void grab_segdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg, int segment)
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index 665b27ee..617aecab 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -881,6 +881,8 @@
     if(dyn->insts[ninst].x64.gen_flags) switch(B) {                                             \
         case SF_SUBSET:                                                                         \
         case SF_SET: dyn->f.pending = SF_SET; break;                                            \
+        case SF_SET_DF: dyn->f.pending = SF_SET; dyn->f.dfnone = 1; break;                      \
+        case SF_SET_NODF: dyn->f.pending = SF_SET; dyn->f.dfnone = 0; break;                    \
         case SF_PENDING: dyn->f.pending = SF_PENDING; break;                                    \
         case SF_SUBSET_PENDING:                                                                 \
         case SF_SET_PENDING:                                                                    \
diff --git a/src/dynarec/arm64/dynarec_arm64_pass0.h b/src/dynarec/arm64/dynarec_arm64_pass0.h
index d86981b3..e8a4b0a8 100644
--- a/src/dynarec/arm64/dynarec_arm64_pass0.h
+++ b/src/dynarec/arm64/dynarec_arm64_pass0.h
@@ -12,9 +12,9 @@
         dyn->f.pending=SF_SET
 #define SETFLAGS(A,B)   \
         dyn->insts[ninst].x64.set_flags = A;    \
-        dyn->insts[ninst].x64.state_flags = B;  \
+        dyn->insts[ninst].x64.state_flags = (B)&~SF_DF;  \
         dyn->f.pending=(B)&SF_SET_PENDING;      \
-        dyn->f.dfnone=((B)&SF_SET)?1:0;
+        dyn->f.dfnone=((B)&SF_SET)?(((B)==SF_SET_NODF)?0:1):0;
 #define EMIT(A)         dyn->native_size+=4
 #define JUMP(A, C)         add_jump(dyn, ninst); add_next(dyn, (uintptr_t)A); SMEND(); dyn->insts[ninst].x64.jmp = A; dyn->insts[ninst].x64.jmp_cond = C
 #define BARRIER(A)      if(A!=BARRIER_MAYBE) {fpu_purgecache(dyn, ninst, 0, x1, x2, x3); dyn->insts[ninst].x64.barrier = A;} else dyn->insts[ninst].barrier_maybe = 1
diff --git a/src/dynarec/dynarec_private.h b/src/dynarec/dynarec_private.h
index 0c1094d3..d5678c71 100644
--- a/src/dynarec/dynarec_private.h
+++ b/src/dynarec/dynarec_private.h
@@ -26,6 +26,8 @@
 #define SF_SUBSET_PENDING   (SF_SUBSET|SF_PENDING)
 #define SF_DF       8
 #define SF_SET_DF   (SF_SET|SF_DF)
+#define SF_NODF     16
+#define SF_SET_NODF (SF_SET|SF_NODF)
 
 typedef struct instruction_x64_s {
     uintptr_t   addr;       //address of the instruction