about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-12-11 17:54:17 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-12-11 17:54:17 +0100
commit4c238f0e1777f197f6550a7f99e1cf1d7894c2e7 (patch)
treef59718de04d4ea78fa4e7d04d44bf030a57be0f5 /src
parent7c000adb8704eee81395a6e2bb52010c8254b4ce (diff)
downloadbox64-4c238f0e1777f197f6550a7f99e1cf1d7894c2e7.tar.gz
box64-4c238f0e1777f197f6550a7f99e1cf1d7894c2e7.zip
[ARM64_DYNAREC] Better hadnling of flags on btx opcode familly ([COSIM] and improved undefined flags when running with cosim)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_0f.c68
-rw-r--r--src/dynarec/arm64/dynarec_arm64_660f.c69
-rw-r--r--src/dynarec/arm64/dynarec_arm64_f0.c135
3 files changed, 222 insertions, 50 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c
index dbfd4822..5b885ba4 100644
--- a/src/dynarec/arm64/dynarec_arm64_0f.c
+++ b/src/dynarec/arm64/dynarec_arm64_0f.c
@@ -1641,7 +1641,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             break;

         case 0xA3:

             INST_NAME("BT Ed, Gd");

-            SETFLAGS(X_CF, SF_SUBSET);

+            SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);

             SET_DFNONE(x1);

             nextop = F8;

             GETGD;

@@ -1665,6 +1665,12 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 LSRxw_REG(x4, ed, x2);

                 BFIw(xFlags, x4, F_CF, 1);

             }

+            if(box64_dynarec_test) {

+                IFX(X_OF) {BFCw(xFlags, F_OF, 1);}

+                IFX(X_SF) {BFCw(xFlags, F_SF, 1);}

+                IFX(X_AF) {BFCw(xFlags, F_AF, 1);}

+                IFX(X_PF) {BFCw(xFlags, F_PF, 1);}

+            }

             break;

         case 0xA4:

             nextop = F8;

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

         case 0xAB:

             INST_NAME("BTS Ed, Gd");

-            SETFLAGS(X_CF, SF_SUBSET);

+            SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);

             SET_DFNONE(x1);

             nextop = F8;

             GETGD;

@@ -1747,6 +1753,12 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 STxw(ed, wback, fixedaddress);

                 SMWRITE();

             }

+            if(box64_dynarec_test) {

+                IFX(X_OF) {BFCw(xFlags, F_OF, 1);}

+                IFX(X_SF) {BFCw(xFlags, F_SF, 1);}

+                IFX(X_AF) {BFCw(xFlags, F_AF, 1);}

+                IFX(X_PF) {BFCw(xFlags, F_PF, 1);}

+            }

             break;

         case 0xAC:

             nextop = F8;

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

         case 0xB3:

             INST_NAME("BTR Ed, Gd");

-            SETFLAGS(X_CF, SF_SUBSET);

+            SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);

             SET_DFNONE(x1);

             nextop = F8;

             GETGD;

@@ -1987,6 +1999,12 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 STxw(ed, wback, fixedaddress);

                 SMWRITE();

             }

+            if(box64_dynarec_test) {

+                IFX(X_OF) {BFCw(xFlags, F_OF, 1);}

+                IFX(X_SF) {BFCw(xFlags, F_SF, 1);}

+                IFX(X_AF) {BFCw(xFlags, F_AF, 1);}

+                IFX(X_PF) {BFCw(xFlags, F_PF, 1);}

+            }

             break;

 

         case 0xB6:

@@ -2028,7 +2046,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             switch((nextop>>3)&7) {

                 case 4:

                     INST_NAME("BT Ed, Ib");

-                    SETFLAGS(X_CF, SF_SUBSET);

+                    SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);

                     SET_DFNONE(x1);

                     gd = x2;

                     if(MODREG) {

@@ -2041,11 +2059,19 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     }

                     u8 = F8;

                     u8&=rex.w?0x3f:0x1f;

-                    BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)

+                    IFX(X_CF) {

+                        BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)

+                    }

+                    if(box64_dynarec_test) {

+                        IFX(X_OF) {BFCw(xFlags, F_OF, 1);}

+                        IFX(X_SF) {BFCw(xFlags, F_SF, 1);}

+                        IFX(X_AF) {BFCw(xFlags, F_AF, 1);}

+                        IFX(X_PF) {BFCw(xFlags, F_PF, 1);}

+                    }

                     break;

                 case 5:

                     INST_NAME("BTS Ed, Ib");

-                    SETFLAGS(X_CF, SF_SUBSET);

+                    SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);

                     SET_DFNONE(x1);

                     if(MODREG) {

                         ed = TO_NAT((nextop & 7) + (rex.b << 3));

@@ -2067,10 +2093,16 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         STxw(ed, wback, fixedaddress);

                         SMWRITE();

                     }

+                    if(box64_dynarec_test) {

+                        IFX(X_OF) {BFCw(xFlags, F_OF, 1);}

+                        IFX(X_SF) {BFCw(xFlags, F_SF, 1);}

+                        IFX(X_AF) {BFCw(xFlags, F_AF, 1);}

+                        IFX(X_PF) {BFCw(xFlags, F_PF, 1);}

+                    }

                     break;

                 case 6:

                     INST_NAME("BTR Ed, Ib");

-                    SETFLAGS(X_CF, SF_SUBSET);

+                    SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);

                     SET_DFNONE(x1);

                     if(MODREG) {

                         ed = TO_NAT((nextop & 7) + (rex.b << 3));

@@ -2091,10 +2123,16 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         STxw(ed, wback, fixedaddress);

                         SMWRITE();

                     }

+                    if(box64_dynarec_test) {

+                        IFX(X_OF) {BFCw(xFlags, F_OF, 1);}

+                        IFX(X_SF) {BFCw(xFlags, F_SF, 1);}

+                        IFX(X_AF) {BFCw(xFlags, F_AF, 1);}

+                        IFX(X_PF) {BFCw(xFlags, F_PF, 1);}

+                    }

                     break;

                 case 7:

                     INST_NAME("BTC Ed, Ib");

-                    SETFLAGS(X_CF, SF_SUBSET);

+                    SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);

                     SET_DFNONE(x1);

                     if(MODREG) {

                         ed = TO_NAT((nextop & 7) + (rex.b << 3));

@@ -2116,6 +2154,12 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         STxw(ed, wback, fixedaddress);

                         SMWRITE();

                     }

+                    if(box64_dynarec_test) {

+                        IFX(X_OF) {BFCw(xFlags, F_OF, 1);}

+                        IFX(X_SF) {BFCw(xFlags, F_SF, 1);}

+                        IFX(X_AF) {BFCw(xFlags, F_AF, 1);}

+                        IFX(X_PF) {BFCw(xFlags, F_PF, 1);}

+                    }

                     break;

                 default:

                     DEFAULT;

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

         case 0xBB:

             INST_NAME("BTC Ed, Gd");

-            SETFLAGS(X_CF, SF_SUBSET);

+            SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);

             SET_DFNONE(x1);

             nextop = F8;

             GETGD;

@@ -2156,6 +2200,12 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 STxw(ed, wback, fixedaddress);

                 SMWRITE();

             }

+            if(box64_dynarec_test) {

+                IFX(X_OF) {BFCw(xFlags, F_OF, 1);}

+                IFX(X_SF) {BFCw(xFlags, F_SF, 1);}

+                IFX(X_AF) {BFCw(xFlags, F_AF, 1);}

+                IFX(X_PF) {BFCw(xFlags, F_PF, 1);}

+            }

             break;

         case 0xBC:

             INST_NAME("BSF Gd, Ed");

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

         case 0xA3:

             INST_NAME("BT Ew, Gw");

-            SETFLAGS(X_CF, SF_SUBSET);

+            SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);

             SET_DFNONE(x1);

             nextop = F8;

             gd = TO_NAT(((nextop & 0x38) >> 3) + (rex.r << 3)); // GETGD

@@ -2334,6 +2334,12 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                 LSRw_REG(x1, ed, x2);

                 BFIw(xFlags, x1, F_CF, 1);

             }

+            if(box64_dynarec_test) {

+                IFX(X_OF) {BFCw(xFlags, F_OF, 1);}

+                IFX(X_SF) {BFCw(xFlags, F_SF, 1);}

+                IFX(X_AF) {BFCw(xFlags, F_AF, 1);}

+                IFX(X_PF) {BFCw(xFlags, F_PF, 1);}

+            }

             break;

         case 0xA4:

             INST_NAME("SHLD Ew, Gw, Ib");

@@ -2369,7 +2375,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
 

         case 0xAB:

             INST_NAME("BTS Ew, Gw");

-            SETFLAGS(X_CF, SF_SUBSET);

+            SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);

             SET_DFNONE(x1);

             nextop = F8;

             gd = TO_NAT(((nextop & 0x38) >> 3) + (rex.r << 3)); // GETGD

@@ -2394,6 +2400,13 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             ORRx_REG(ed, ed, x1);

             if(wback) {

                 STH(ed, wback, fixedaddress);

+                SMWRITE();

+            }

+            if(box64_dynarec_test) {

+                IFX(X_OF) {BFCw(xFlags, F_OF, 1);}

+                IFX(X_SF) {BFCw(xFlags, F_SF, 1);}

+                IFX(X_AF) {BFCw(xFlags, F_AF, 1);}

+                IFX(X_PF) {BFCw(xFlags, F_PF, 1);}

             }

             break;

         case 0xAC:

@@ -2443,7 +2456,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
 

         case 0xB3:

             INST_NAME("BTR Ew, Gw");

-            SETFLAGS(X_CF, SF_SUBSET);

+            SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);

             SET_DFNONE(x1);

             nextop = F8;

             gd = TO_NAT(((nextop & 0x38) >> 3) + (rex.r << 3)); // GETGD

@@ -2469,6 +2482,12 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                 STH(ed, wback, fixedaddress);

                 SMWRITE();

             }

+            if(box64_dynarec_test) {

+                IFX(X_OF) {BFCw(xFlags, F_OF, 1);}

+                IFX(X_SF) {BFCw(xFlags, F_SF, 1);}

+                IFX(X_AF) {BFCw(xFlags, F_AF, 1);}

+                IFX(X_PF) {BFCw(xFlags, F_PF, 1);}

+            }

             break;

 

         case 0xB6:

@@ -2513,17 +2532,25 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             switch((nextop>>3)&7) {

                 case 4:

                     INST_NAME("BT Ew, Ib");

-                    SETFLAGS(X_CF, SF_SUBSET);

+                    SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);

                     SET_DFNONE(x1);

                     gd = x2;

                     GETEW(x1, 1);

                     u8 = F8;

                     u8&=rex.w?0x3f:0x0f;

-                    BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)

+                    IFX(X_CF) {

+                        BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)

+                    }

+                    if(box64_dynarec_test) {

+                        IFX(X_OF) {BFCw(xFlags, F_OF, 1);}

+                        IFX(X_SF) {BFCw(xFlags, F_SF, 1);}

+                        IFX(X_AF) {BFCw(xFlags, F_AF, 1);}

+                        IFX(X_PF) {BFCw(xFlags, F_PF, 1);}

+                    }

                     break;

                 case 5:

                     INST_NAME("BTS Ew, Ib");

-                    SETFLAGS(X_CF, SF_SUBSET);

+                    SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);

                     SET_DFNONE(x1);

                     GETEW(x1, 1);

                     u8 = F8;

@@ -2534,10 +2561,16 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                     mask = convert_bitmask_xw(1<<u8);

                     ORRxw_mask(ed, ed, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F);

                     EWBACK;

+                    if(box64_dynarec_test) {

+                        IFX(X_OF) {BFCw(xFlags, F_OF, 1);}

+                        IFX(X_SF) {BFCw(xFlags, F_SF, 1);}

+                        IFX(X_AF) {BFCw(xFlags, F_AF, 1);}

+                        IFX(X_PF) {BFCw(xFlags, F_PF, 1);}

+                    }

                     break;

                 case 6:

                     INST_NAME("BTR Ew, Ib");

-                    SETFLAGS(X_CF, SF_SUBSET);

+                    SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);

                     SET_DFNONE(x1);

                     GETEW(x1, 1);

                     u8 = F8;

@@ -2547,10 +2580,16 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                     }

                     BFCxw(ed, u8, 1);

                     EWBACK;

+                    if(box64_dynarec_test) {

+                        IFX(X_OF) {BFCw(xFlags, F_OF, 1);}

+                        IFX(X_SF) {BFCw(xFlags, F_SF, 1);}

+                        IFX(X_AF) {BFCw(xFlags, F_AF, 1);}

+                        IFX(X_PF) {BFCw(xFlags, F_PF, 1);}

+                    }

                     break;

                 case 7:

                     INST_NAME("BTC Ew, Ib");

-                    SETFLAGS(X_CF, SF_SUBSET);

+                    SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);

                     SET_DFNONE(x1);

                     GETEW(x1, 1);

                     u8 = F8;

@@ -2561,6 +2600,12 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                     mask = convert_bitmask_xw(1<<u8);

                     EORxw_mask(ed, ed, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F);

                     EWBACK;

+                    if(box64_dynarec_test) {

+                        IFX(X_OF) {BFCw(xFlags, F_OF, 1);}

+                        IFX(X_SF) {BFCw(xFlags, F_SF, 1);}

+                        IFX(X_AF) {BFCw(xFlags, F_AF, 1);}

+                        IFX(X_PF) {BFCw(xFlags, F_PF, 1);}

+                    }

                     break;

                 default:

                     DEFAULT;

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

         case 0xBB:

             INST_NAME("BTC Ew, Gw");

-            SETFLAGS(X_CF, SF_SUBSET);

+            SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);

             SET_DFNONE(x1);

             nextop = F8;

             gd = TO_NAT(((nextop & 0x38) >> 3) + (rex.r << 3)); // GETGD

@@ -2596,6 +2641,12 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                 STH(ed, wback, fixedaddress);

                 SMWRITE();

             }

+            if(box64_dynarec_test) {

+                IFX(X_OF) {BFCw(xFlags, F_OF, 1);}

+                IFX(X_SF) {BFCw(xFlags, F_SF, 1);}

+                IFX(X_AF) {BFCw(xFlags, F_AF, 1);}

+                IFX(X_PF) {BFCw(xFlags, F_PF, 1);}

+            }

             break;

         case 0xBC:

             INST_NAME("BSF Gw,Ew");

diff --git a/src/dynarec/arm64/dynarec_arm64_f0.c b/src/dynarec/arm64/dynarec_arm64_f0.c
index 780377af..f4f0bfe1 100644
--- a/src/dynarec/arm64/dynarec_arm64_f0.c
+++ b/src/dynarec/arm64/dynarec_arm64_f0.c
@@ -33,7 +33,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
     int32_t i32;
     int64_t i64, j64;
     int64_t fixedaddress;
-    int unscaled;
+    int unscaled, mask;
     MAYUSE(eb1);
     MAYUSE(eb2);
     MAYUSE(gb1);
@@ -208,7 +208,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
 
                 case 0xAB:
                     INST_NAME("LOCK BTS Ed, Gd");
-                    SETFLAGS(X_CF, SF_SUBSET);
+                    SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
                     SET_DFNONE(x1);
                     nextop = F8;
                     GETGD;
@@ -226,7 +226,9 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         } else {
                             ANDSw_mask(x4, x4, 0, 0);  //mask=1
                         }
-                        BFIw(xFlags, x4, F_CF, 1);
+                        IFX(X_CF) {
+                            BFIw(xFlags, x4, F_CF, 1);
+                        }
                         MOV32w(x4, 1);
                         LSLxw_REG(x4, x4, x2);
                         ORRxw_REG(ed, ed, x4);
@@ -235,20 +237,29 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         ANDw_mask(x2, gd, 0, 0b00010);  //mask=0x000000007
                         addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                         ASRxw(x1, gd, 3); // r1 = (gd>>3)
-                        ADDx_REG_LSL(x3, wback, x1, 0); //(&ed)+=r1;
+                        if(!rex.w && !rex.is32bits) {SXTWx(x1, x1);}
+                        ADDz_REG_LSL(x3, wback, x1, 0); //(&ed)+=r1;
                         ed = x1;
                         wback = x3;
                         MOV32w(x5, 1);
                         MARKLOCK;
                         LDAXRB(ed, wback);
                         LSRw_REG(x4, ed, x2);
-                        BFIw(xFlags, x4, F_CF, 1);
+                        IFX(X_CF) {
+                            BFIw(xFlags, x4, F_CF, 1);
+                        }
                         LSLw_REG(x4, x5, x2);
                         ORRw_REG(ed, ed, x4);
                         STLXRB(x4, ed, wback);
                         CBNZw_MARKLOCK(x4);
                         SMDMB();
                     }
+                    if(box64_dynarec_test) {
+                        IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
+                        IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
+                        IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
+                        IFX(X_PF) {BFCw(xFlags, F_PF, 1);}
+                    }
                     break;
                 case 0xB0:
                     switch(rep) {
@@ -395,7 +406,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
 
                 case 0xB3:
                     INST_NAME("LOCK BTR Ed, Gd");
-                    SETFLAGS(X_CF, SF_SUBSET);
+                    SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
                     SET_DFNONE(x1);
                     nextop = F8;
                     GETGD;
@@ -408,12 +419,9 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             ANDw_mask(x2, gd, 0, 0b00100);  //mask=0x00000001f
                         }
                         LSRxw_REG(x4, ed, x2);
-                        if(rex.w) {
-                            ANDx_mask(x4, x4, 1, 0, 0);  //mask=1
-                        } else {
-                            ANDw_mask(x4, x4, 0, 0);  //mask=1
+                        IFX(X_CF) {
+                            BFIw(xFlags, x4, F_CF, 1);
                         }
-                        BFIw(xFlags, x4, F_CF, 1);
                         MOV32w(x4, 1);
                         LSLxw_REG(x4, x4, x2);
                         BICxw_REG(ed, ed, x4);
@@ -422,20 +430,29 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         ANDw_mask(x2, gd, 0, 0b00010);  //mask=0x000000007
                         addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                         ASRx(x1, gd, 3); // r1 = (gd>>3), there might be an issue for negative 32bits values here
-                        ADDx_REG_LSL(x3, wback, x1, 0); //(&ed)+=r1;
+                        if(!rex.w && !rex.is32bits) {SXTWx(x1, x1);}
+                        ADDz_REG_LSL(x3, wback, x1, 0); //(&ed)+=r1;
                         ed = x1;
                         wback = x3;
                         MOV32w(x5, 1);
                         MARKLOCK;
                         LDAXRB(ed, wback);
                         LSRw_REG(x4, ed, x2);
-                        BFIw(xFlags, x4, F_CF, 1);
+                        IFX(X_CF) {
+                            BFIw(xFlags, x4, F_CF, 1);
+                        }
                         LSLw_REG(x4, x5, x2);
                         BICw_REG(ed, ed, x4);
                         STLXRB(x4, ed, wback);
                         CBNZw_MARKLOCK(x4);
                         SMDMB();
                     }
+                    if(box64_dynarec_test) {
+                        IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
+                        IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
+                        IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
+                        IFX(X_PF) {BFCw(xFlags, F_PF, 1);}
+                    }
                     break;
 
             case 0xBA:
@@ -443,14 +460,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 switch((nextop>>3)&7) {
                     case 4:
                         INST_NAME("LOCK BT Ed, Ib");
-                        SETFLAGS(X_CF, SF_SUBSET);
+                        SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
                         SET_DFNONE(x1);
                         gd = x2;
                         if(MODREG) {
                             ed = TO_NAT((nextop & 7) + (rex.b << 3));
                             u8 = F8;
                             u8&=rex.w?0x3f:0x1f;
-                            BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)
+                            IFX(X_CF) {
+                                BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)
+                            }
                         } else {
                             // Will fetch only 1 byte, to avoid alignment issue
                             addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
@@ -463,22 +482,37 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             LDAXRB(x1, wback);
                             ed = x1;
                             wback = x3;
-                            BFXILxw(xFlags, x1, u8&7, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)
+                            IFX(X_CF) {
+                                BFXILxw(xFlags, x1, u8&7, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)
+                            }
+                        }
+                        if(box64_dynarec_test) {
+                            IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
+                            IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
+                            IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
+                            IFX(X_PF) {BFCw(xFlags, F_PF, 1);}
                         }
                         break;
                     case 5:
                         INST_NAME("LOCK BTS Ed, Ib");
-                        SETFLAGS(X_CF, SF_SUBSET);
+                        SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
                         SET_DFNONE(x1);
                         if(MODREG) {
                             ed = TO_NAT((nextop & 7) + (rex.b << 3));
                             wback = 0;
                             u8 = F8;
                             u8&=(rex.w?0x3f:0x1f);
-                            BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)
-                            TBNZ_NEXT(xFlags, 0); // bit already set, jump to next instruction
-                            MOV32w(x4, 1);
-                            ORRxw_REG_LSL(ed, ed, x4, u8);
+                            IFX(X_CF) {
+                                BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)
+                            }
+                            if(box64_dynarec_test) {
+                                IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
+                                IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
+                                IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
+                                IFX(X_PF) {BFCw(xFlags, F_PF, 1);}
+                            }
+                            mask = convert_bitmask_xw(1LL<<u8);
+                            ORRxw_mask(ed, ed, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F);
                         } else {
                             // Will fetch only 1 byte, to avoid alignment issue
                             addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
@@ -488,11 +522,19 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                                 wback = x3;
                             }
                             ed = x1;
-                            MOV32w(x5, 1);
                             MARKLOCK;
                             LDAXRB(ed, wback);
-                            BFXILw(xFlags, ed, u8&7, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
-                            BFIw(ed, x5, u8&7, 1);
+                            IFX(X_CF) {
+                                BFXILw(xFlags, ed, u8&7, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
+                            }
+                            if(box64_dynarec_test) {
+                                IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
+                                IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
+                                IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
+                                IFX(X_PF) {BFCw(xFlags, F_PF, 1);}
+                            }
+                            mask = convert_bitmask_xw(1LL<<(u8&7));
+                            ORRxw_mask(ed, ed, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F);
                             STLXRB(x4, ed, wback);
                             CBNZw_MARKLOCK(x4);
                             SMDMB();
@@ -500,15 +542,22 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         break;
                     case 6:
                         INST_NAME("LOCK BTR Ed, Ib");
-                        SETFLAGS(X_CF, SF_SUBSET);
+                        SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
                         SET_DFNONE(x1);
                         if(MODREG) {
                             ed = TO_NAT((nextop & 7) + (rex.b << 3));
                             wback = 0;
                             u8 = F8;
                             u8&=(rex.w?0x3f:0x1f);
-                            BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)
-                            TBZ_NEXT(xFlags, 0); // bit already clear, jump to next instruction
+                            IFX(X_CF) {
+                                BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)
+                            }
+                            if(box64_dynarec_test) {
+                                IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
+                                IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
+                                IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
+                                IFX(X_PF) {BFCw(xFlags, F_PF, 1);}
+                            }
                             BFCxw(ed, u8, 1);
                         } else {
                             addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
@@ -521,6 +570,12 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             MARKLOCK;
                             LDAXRB(ed, wback);
                             BFXILw(xFlags, ed, u8&7, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
+                            if(box64_dynarec_test) {
+                                IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
+                                IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
+                                IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
+                                IFX(X_PF) {BFCw(xFlags, F_PF, 1);}
+                            }
                             BFCw(ed, u8&7, 1);
                             STLXRB(x4, ed, wback);
                             CBNZw_MARKLOCK(x4);
@@ -529,14 +584,22 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         break;
                     case 7:
                         INST_NAME("LOCK BTC Ed, Ib");
-                        SETFLAGS(X_CF, SF_SUBSET);
+                        SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
                         SET_DFNONE(x1);
                         if(MODREG) {
                             ed = TO_NAT((nextop & 7) + (rex.b << 3));
                             wback = 0;
                             u8 = F8;
                             u8&=(rex.w?0x3f:0x1f);
-                            BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)
+                            IFX(X_CF) {
+                                BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)
+                            }
+                            if(box64_dynarec_test) {
+                                IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
+                                IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
+                                IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
+                                IFX(X_PF) {BFCw(xFlags, F_PF, 1);}
+                            }
                             MOV32w(x4, 1);
                             EORxw_REG_LSL(ed, ed, x4, u8);
                         } else {
@@ -547,11 +610,19 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                                 wback = x3;
                             }
                             ed = x1;
-                            MOV32w(x5, 1);
                             MARKLOCK;
                             LDAXRB(ed, wback);
-                            BFXILw(xFlags, ed, u8&7, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
-                            EORw_REG_LSL(ed, ed, x5, u8&7);
+                            IFX(X_CF) {
+                                BFXILw(xFlags, ed, u8&7, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
+                            }
+                            if(box64_dynarec_test) {
+                                IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
+                                IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
+                                IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
+                                IFX(X_PF) {BFCw(xFlags, F_PF, 1);}
+                            }
+                            mask = convert_bitmask_xw(1LL<<(u8&7));
+                            ORRxw_mask(ed, ed, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F);
                             STLXRB(x4, ed, wback);
                             CBNZw_MARKLOCK(x4);
                             SMDMB();