about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-02-12 11:04:46 +0100
committerptitSeb <sebastien.chev@gmail.com>2025-02-12 11:04:46 +0100
commitc7ff0f658bc326c29dfbf79e9aac22250939e329 (patch)
tree607b2f3c1d9869544502f07c5cbca10b623f2c91 /src
parentb8cc8594f6d9cbe4a47b8a98ba9878da803a7243 (diff)
downloadbox64-c7ff0f658bc326c29dfbf79e9aac22250939e329.tar.gz
box64-c7ff0f658bc326c29dfbf79e9aac22250939e329.zip
[ARM64_DYNAREC] More work on flag
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c191
-rw-r--r--src/dynarec/arm64/dynarec_arm64_0f.c13
-rw-r--r--src/dynarec/arm64/dynarec_arm64_64.c63
-rw-r--r--src/dynarec/arm64/dynarec_arm64_66.c70
-rw-r--r--src/dynarec/arm64/dynarec_arm64_660f.c35
-rw-r--r--src/dynarec/arm64/dynarec_arm64_67.c48
-rw-r--r--src/dynarec/arm64/dynarec_arm64_emit_shift.c607
-rw-r--r--src/emu/x64primop.c50
8 files changed, 472 insertions, 605 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index c9e8abb7..0b01123c 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -900,10 +900,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     SMULH(x3, ed, x4);
                     MULx(gd, ed, x4);
                     SET_DFNONE();
-                    IFX(X_ZF | X_PF | X_AF | X_SF) {
-                        MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));
-                        BICw(xFlags, xFlags, x1);
-                    }
                     IFX(X_CF | X_OF) {
                         CMPSx_REG_ASR(x3, gd, 63);
                         CSETw(x1, cNE);
@@ -924,10 +920,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     LSRx(x3, gd, 32);
                     MOVw_REG(gd, gd);
                     SET_DFNONE();
-                    IFX(X_ZF | X_PF | X_AF | X_SF) {
-                        MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));
-                        BICw(xFlags, xFlags, x1);
-                    }
                     IFX(X_CF | X_OF) {
                         CMPSw_REG_ASR(x3, gd, 31);
                         CSETw(x1, cNE);
@@ -942,6 +934,13 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     MULxw(gd, ed, x4);
                 }
             }
+            IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
+            IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);}
+            IFX(X_SF) {
+                LSRxw(x3, gd, rex.w?63:31);
+                BFIw(xFlags, x3, F_SF, 1);
+            }
+            IFX(X_PF) emit_pf(dyn, ninst, gd, x3);
             break;
         case 0x6A:
             INST_NAME("PUSH Ib");
@@ -964,10 +963,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     SMULH(x3, ed, x4);
                     MULx(gd, ed, x4);
                     SET_DFNONE();
-                    IFX(X_ZF | X_PF | X_AF | X_SF) {
-                        MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));
-                        BICw(xFlags, xFlags, x1);
-                    }
                     IFX(X_CF | X_OF) {
                         CMPSx_REG_ASR(x3, gd, 63);
                         CSETw(x1, cNE);
@@ -988,10 +983,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     LSRx(x3, gd, 32);
                     MOVw_REG(gd, gd);
                     SET_DFNONE();
-                    IFX(X_ZF | X_PF | X_AF | X_SF) {
-                        MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));
-                        BICw(xFlags, xFlags, x1);
-                    }
                     IFX(X_CF | X_OF) {
                         CMPSw_REG_ASR(x3, gd, 31);
                         CSETw(x1, cNE);
@@ -1006,6 +997,13 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     MULxw(gd, ed, x4);
                 }
             }
+            IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
+            IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);}
+            IFX(X_SF) {
+                LSRxw(x3, gd, rex.w?63:31);
+                BFIw(xFlags, x3, F_SF, 1);
+            }
+            IFX(X_PF) emit_pf(dyn, ninst, gd, x3);
             break;
         case 0x6C:
         case 0x6D:
@@ -2786,8 +2784,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     SETFLAGS(X_OF|X_CF, SF_SUBSET);
                     if(BOX64DRENV(dynarec_safeflags)>1)
                         MAYSETFLAGS();
+                    SET_DFNONE();
                     UFLAG_IF {
-                        UFLAG_DF(x2, d_none);
                         ANDw_mask(x2, xRCX, 0, 0b00100);  //mask=0x00000001f
                         CBZw_NEXT(x2);
                     }
@@ -2798,17 +2796,12 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     ORRw_REG_LSL(ed, ed, ed, 8);
                     LSRw_REG(ed, ed, x2);
                     EBBACK;
-                    UFLAG_IF {  // calculate flags directly
-                        IFX(X_OF) {
-                            SUBw_U12(x3, x2, 7);
-                            CBNZw_MARK(x3);
-                                EORxw_REG_LSR(x3, ed, ed, 7);
-                                BFIw(xFlags, x3, F_OF, 1);
-                            MARK;
-                        }
-                        IFX(X_CF) {
-                            BFIw(xFlags, ed, F_CF, 1);
-                        }
+                    IFX(X_OF) {
+                        EORxw_REG_LSR(x3, ed, ed, 7);
+                        BFIw(xFlags, x3, F_OF, 1);
+                    }
+                    IFX(X_CF) {
+                        BFIw(xFlags, ed, F_CF, 1);
                     }
                     break;
                 case 1:
@@ -2816,28 +2809,27 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     SETFLAGS(X_OF|X_CF, SF_SUBSET);
                     if(BOX64DRENV(dynarec_safeflags)>1)
                         MAYSETFLAGS();
+                    SET_DFNONE();
                     UFLAG_IF {
-                        UFLAG_DF(x2, d_none);
                         ANDw_mask(x2, xRCX, 0, 0b00100);  //mask=0x00000001f
                         CBZw_NEXT(x2);
                     }
                     ANDw_mask(x2, xRCX, 0, 0b00010);  //mask=0x000000007
                     GETEB(x1, 0);
+                    IFX2(X_OF, && !BOX64ENV(cputype)) {
+                        EORw_REG_LSR(x4, ed, ed, 7);
+                        BFIw(xFlags, x4, F_OF, 1);
+                    }
                     ORRw_REG_LSL(ed, ed, ed, 8);
                     LSRw_REG(ed, ed, x2);
                     EBBACK;
-                    UFLAG_IF {  // calculate flags directly
-                        IFX(X_OF) {
-                            SUBw_U12(x3, x2, 1);
-                            CBNZw_MARK(x3);
-                                LSRxw(x2, ed, 6); // x2 = d>>6
-                                EORw_REG_LSR(x2, x2, x2, 1); // x2 = ((d>>6) ^ ((d>>6)>>1))
-                                BFIw(xFlags, x2, F_OF, 1);
-                            MARK;
-                        }
-                        IFX(X_CF) {
-                            BFXILw(xFlags, ed, 7, 1);
-                        }
+                    IFX2(X_OF, && BOX64ENV(cputype)) {
+                        LSRxw(x2, ed, 6); // x2 = d>>6
+                        EORw_REG_LSR(x2, x2, x2, 1); // x2 = ((d>>6) ^ ((d>>6)>>1))
+                        BFIw(xFlags, x2, F_OF, 1);
+                    }
+                    IFX(X_CF) {
+                        BFXILw(xFlags, ed, 7, 1);
                     }
                     break;
                 case 2:
@@ -2846,7 +2838,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     SETFLAGS(X_OF|X_CF, SF_SUBSET);
                     if(BOX64DRENV(dynarec_safeflags)>1)
                         MAYSETFLAGS();
-                    UFLAG_DF(x2, d_none);
+                    SET_DFNONE();
                     ANDw_mask(x2, xRCX, 0, 0b00100);  //mask=0x00000001f
                     // get CL % 9
                     MOV32w(x3, 0x1c72); // 0x10000 / 9 + 1 (this is precise enough in the 0..31 range)
@@ -2866,11 +2858,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     LSRw_REG(ed, ed, x2);
                     EBBACK;
                     IFX(X_OF) {
-                        SUBw_U12(x3, x2, 8);
-                        CBNZw_MARK(x3);
-                            EORw_REG_LSR(x2, x5, ed, 7);
-                            BFIw(xFlags, x2, F_OF, 1);
-                        MARK;
+                        EORw_REG_LSR(x2, x5, ed, 7);
+                        BFIw(xFlags, x2, F_OF, 1);
                     }
                     IFX(X_CF) {
                         BFXILw(xFlags, x5, 0, 1);
@@ -2882,7 +2871,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     SETFLAGS(X_OF|X_CF, SF_SUBSET);
                     if(BOX64DRENV(dynarec_safeflags)>1)
                         MAYSETFLAGS();
-                    UFLAG_DF(x2, d_none);
+                    SET_DFNONE();
                     ANDw_mask(x2, xRCX, 0, 0b00100);  //mask=0x00000001f
                     // get CL % 9
                     MOV32w(x3, 0x1c72); // 0x10000 / 9 + 1
@@ -2894,16 +2883,12 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     GETEB(x1, 0);
                     BFIw(ed, xFlags, 8, 1); // insert CF
                     ORRw_REG_LSL(ed, ed, ed, 9);    // insert rest of ed
-                    IFX(X_OF|X_CF) {
-                        SUBw_U12(x4, x2, 1);
-                    }
                     IFX(X_OF) {
-                        CBNZw_MARK(x4);
-                            EORw_REG_LSR(x5, xFlags, ed, 7);
-                            BFIw(xFlags, x5, F_OF, 1);
-                        MARK;
+                        EORw_REG_LSR(x5, xFlags, ed, 7);
+                        BFIw(xFlags, x5, F_OF, 1);
                     }
                     IFX(X_CF) {
+                        SUBw_U12(x4, x2, 1);
                         LSRw_REG(x5, ed, x4);
                         BFIw(xFlags, x5, F_CF, 1);
                     }
@@ -2977,17 +2962,12 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     SUBx_REG(x3, x4, x3);
                     RORxw_REG(ed, ed, x3);
                     WBACK;
-                    UFLAG_IF {  // calculate flags directly
-                        IFX(X_OF) {
-                            SUBw_U12(x3, x3, rex.w?63:31);
-                            CBNZw_MARK(x3);
-                                EORxw_REG_LSR(x1, ed, ed, rex.w?63:31);
-                                BFIw(xFlags, x1, F_OF, 1);
-                            MARK;
-                        }
-                        IFX(X_CF) {
-                            BFIw(xFlags, ed, F_CF, 1);
-                        }
+                    IFX(X_OF) {
+                        EORxw_REG_LSR(x3, ed, ed, rex.w?63:31);
+                        BFIw(xFlags, x3, F_OF, 1);
+                    }
+                    IFX(X_CF) {
+                        BFIw(xFlags, ed, F_CF, 1);
                     }
                     break;
                 case 1:
@@ -3000,28 +2980,25 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     } else {
                         ANDw_mask(x3, xRCX, 0, 0b00100);  //mask=0x00000001f
                     }
-                    UFLAG_IF {
-                        UFLAG_DF(x2, d_none);
-                    }
+                    SET_DFNONE();
                     GETED(0);
                     UFLAG_IF {
                         if(!rex.w && !rex.is32bits && MODREG) {MOVw_REG(ed, ed);}
                         CBZw_NEXT(x3);
                     }
+                    IFX2(X_OF, && !BOX64ENV(cputype)) {
+                        EORxw_REG_LSR(x4, ed, ed, rex.w?63:31);
+                        BFIw(xFlags, x4, F_OF, 1);
+                    }
                     RORxw_REG(ed, ed, x3);
                     WBACK;
-                    UFLAG_IF {  // calculate flags directly
-                        IFX(X_OF) {
-                            SUBw_U12(x2, x3, 1);
-                            CBNZw_MARK(x2);
-                                LSRxw(x2, ed, rex.w?62:30); // x2 = d>>30
-                                EORw_REG_LSR(x2, x2, x2, 1); // x2 = ((d>>30) ^ ((d>>30)>>1))
-                                BFIw(xFlags, x2, F_OF, 1);
-                            MARK;
-                        }
-                        IFX(X_CF) {
-                            BFXILxw(xFlags, ed, rex.w?63:31, 1);
-                        }
+                    IFX2(X_OF, && BOX64ENV(cputype)) {
+                        LSRxw(x2, ed, rex.w?62:30); // x2 = d>>30
+                        EORw_REG_LSR(x2, x2, x2, 1); // x2 = ((d>>30) ^ ((d>>30)>>1))
+                        BFIw(xFlags, x2, F_OF, 1);
+                    }
+                    IFX(X_CF) {
+                        BFXILxw(xFlags, ed, rex.w?63:31, 1);
                     }
                     break;
                 case 2:
@@ -3037,8 +3014,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         ANDw_mask(x2, xRCX, 0, 0b00100);  //mask=0x00000001f
                     }
                     GETEDW(x4, x1, 0);
-                    if(!rex.w && !rex.is32bits && MODREG) {MOVw_REG(ed, ed);}
-                    CBZw_NEXT(x2);
                     CALL_(rex.w?((void*)rcl64):((void*)rcl32), ed, x4);
                     WBACK;
                     break;
@@ -3055,8 +3030,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         ANDw_mask(x2, xRCX, 0, 0b00100);  //mask=0x00000001f
                     }
                     GETEDW(x4, x1, 0);
-                    if(!rex.w && !rex.is32bits && MODREG) {MOVw_REG(ed, ed);}
-                    CBZw_NEXT(x2);
                     CALL_(rex.w?((void*)rcr64):((void*)rcr32), ed, x4);
                     WBACK;
                     break;
@@ -3543,13 +3516,14 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             BFIw(xFlags, x3, F_OF, 1);
                         }
                     }
-                    IFX(X_AF | X_PF | X_ZF | X_SF)
-                        if (BOX64ENV(dynarec_test)) {
-                            // to avoid noise during test
-                            MOV32w(x3, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));
-                            BICw(xFlags, xFlags, x3);
-                        }
-                    break;
+                    IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
+                    IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);}
+                    IFX(X_SF) {
+                        LSRxw(x3, xRAX, 15);
+                        BFIw(xFlags, x3, F_SF, 1);
+                    }
+                    IFX(X_PF) emit_pf(dyn, ninst, xRAX, x3);
+                            break;
                 case 6:
                     INST_NAME("DIV Eb");
                     SETFLAGS(X_ALL, SF_SET);
@@ -3677,25 +3651,24 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         MOVw_REG(xRAX, xRDX);
                         LSRx(xRDX, xRDX, 32);
                     }
-                    UFLAG_IF {
-                        SET_DFNONE();
-                        IFX(X_CF|X_OF) {
-                            CMPSxw_REG_ASR(xRDX, xRAX, rex.w?63:31);
-                            CSETw(x3, cNE);
-                            IFX(X_CF) {
-                                BFIw(xFlags, x3, F_CF, 1);
-                            }
-                            IFX(X_OF) {
-                                BFIw(xFlags, x3, F_OF, 1);
-                            }
+                    SET_DFNONE();
+                    IFX(X_CF|X_OF) {
+                        CMPSxw_REG_ASR(xRDX, xRAX, rex.w?63:31);
+                        CSETw(x3, cNE);
+                        IFX(X_CF) {
+                            BFIw(xFlags, x3, F_CF, 1);
                         }
-                        IFX(X_AF | X_PF | X_ZF | X_SF)
-                            if (BOX64ENV(dynarec_test)) {
-                                // to avoid noise during test
-                                MOV32w(x3, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));
-                                BICw(xFlags, xFlags, x3);
-                            }
+                        IFX(X_OF) {
+                            BFIw(xFlags, x3, F_OF, 1);
+                        }
+                    }
+                    IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
+                    IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);}
+                    IFX(X_SF) {
+                        LSRxw(x3, xRAX, rex.w?63:31);
+                        BFIw(xFlags, x3, F_SF, 1);
                     }
+                    IFX(X_PF) emit_pf(dyn, ninst, xRAX, x3);
                     break;
                 case 6:
                     INST_NAME("DIV Ed");
diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c
index 13e988a9..afa1f6d0 100644
--- a/src/dynarec/arm64/dynarec_arm64_0f.c
+++ b/src/dynarec/arm64/dynarec_arm64_0f.c
@@ -2041,12 +2041,13 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     MULxw(gd, gd, ed);

                 }

             }

-            IFX(X_AF | X_PF | X_ZF | X_SF)

-                if (BOX64ENV(dynarec_test)) {

-                    // to avoid noise during test

-                    MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));

-                    BICw(xFlags, xFlags, x1);

-                }

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

+            IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);}

+            IFX(X_SF) {

+                LSRxw(x3, gd, rex.w?63:31);

+                BFIw(xFlags, x3, F_SF, 1);

+            }

+            IFX(X_PF) emit_pf(dyn, ninst, gd, x3);

             break;

 

         case 0xB1:

diff --git a/src/dynarec/arm64/dynarec_arm64_64.c b/src/dynarec/arm64/dynarec_arm64_64.c
index 64421bcd..1bfc1fe3 100644
--- a/src/dynarec/arm64/dynarec_arm64_64.c
+++ b/src/dynarec/arm64/dynarec_arm64_64.c
@@ -319,12 +319,13 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                                     MULxw(gd, gd, ed);
                                 }
                             }
-                            IFX(X_AF | X_PF | X_ZF | X_SF)
-                                if (BOX64ENV(dynarec_test)) {
-                                    // to avoid noise during test
-                                    MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));
-                                    BICw(xFlags, xFlags, x1);
-                                }
+                            IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
+                            IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);}
+                            IFX(X_SF) {
+                                LSRxw(x3, gd, rex.w?63:31);
+                                BFIw(xFlags, x3, F_SF, 1);
+                            }
+                            IFX(X_PF) emit_pf(dyn, ninst, gd, x3);
                             break;
                         default:
                             DEFAULT;
@@ -549,10 +550,6 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     SMULH(x3, ed, x4);
                     MULx(gd, ed, x4);
                     SET_DFNONE();
-                    IFX(X_ZF | X_PF | X_AF | X_SF) {
-                        MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));
-                        BICw(xFlags, xFlags, x1);
-                    }
                     IFX(X_CF | X_OF) {
                         ASRx(x4, gd, 63);
                         CMPSx_REG(x3, x4);
@@ -574,10 +571,6 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     LSRx(x3, gd, 32);
                     MOVw_REG(gd, gd);
                     SET_DFNONE();
-                    IFX(X_ZF | X_PF | X_AF | X_SF) {
-                        MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));
-                        BICw(xFlags, xFlags, x1);
-                    }
                     IFX(X_CF | X_OF) {
                         ASRw(x4, gd, 31);
                         CMPSw_REG(x3, x4);
@@ -593,6 +586,13 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     MULxw(gd, ed, x4);
                 }
             }
+            IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
+            IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);}
+            IFX(X_SF) {
+                LSRxw(x3, gd, rex.w?63:31);
+                BFIw(xFlags, x3, F_SF, 1);
+            }
+            IFX(X_PF) emit_pf(dyn, ninst, gd, x3);
             break;
 
         case 0x6C:
@@ -1342,26 +1342,25 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         MOVw_REG(xRAX, xRDX);
                         LSRx(xRDX, xRDX, 32);
                     }
-                    UFLAG_IF {
-                        SET_DFNONE();
-                        IFX(X_CF|X_OF) {
-                            ASRxw(x4, xRAX, rex.w?63:31);
-                            CMPSxw_REG(xRDX, x4);
-                            CSETw(x3, cNE);
-                            IFX(X_CF) {
-                                BFIw(xFlags, x3, F_CF, 1);
-                            }
-                            IFX(X_OF) {
-                                BFIw(xFlags, x3, F_OF, 1);
-                            }
+                    SET_DFNONE();
+                    IFX(X_CF|X_OF) {
+                        ASRxw(x4, xRAX, rex.w?63:31);
+                        CMPSxw_REG(xRDX, x4);
+                        CSETw(x3, cNE);
+                        IFX(X_CF) {
+                            BFIw(xFlags, x3, F_CF, 1);
                         }
-                        IFX(X_AF | X_PF | X_ZF | X_SF)
-                            if (BOX64ENV(dynarec_test)) {
-                                // to avoid noise during test
-                                MOV32w(x3, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));
-                                BICw(xFlags, xFlags, x3);
-                            }
+                        IFX(X_OF) {
+                            BFIw(xFlags, x3, F_OF, 1);
+                        }
+                    }
+                    IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
+                    IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);}
+                    IFX(X_SF) {
+                        LSRxw(x3, xRAX, rex.w?63:31);
+                        BFIw(xFlags, x3, F_SF, 1);
                     }
+                    IFX(X_PF) emit_pf(dyn, ninst, xRAX, x3);
                     break;
                 case 6:
                     INST_NAME("DIV Ed");
diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c
index 73767538..0b110ce4 100644
--- a/src/dynarec/arm64/dynarec_arm64_66.c
+++ b/src/dynarec/arm64/dynarec_arm64_66.c
@@ -444,26 +444,25 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             MULw(x2, x2, x1);

             gd=x2;

             GWBACK;

-            UFLAG_IF {

-                SET_DFNONE();

-                IFX(X_CF|X_OF) {

-                    ASRw(x1, x2, 16);

-                    CMPSw_REG_ASR(x1, x2, 31);

-                    CSETw(x3, cNE);

-                    IFX(X_CF) {

-                        BFIw(xFlags, x3, F_CF, 1);

-                    }

-                    IFX(X_OF) {

-                        BFIw(xFlags, x3, F_OF, 1);

-                    }

+            SET_DFNONE();

+            IFX(X_CF|X_OF) {

+                ASRw(x1, x2, 16);

+                CMPSw_REG_ASR(x1, x2, 31);

+                CSETw(x3, cNE);

+                IFX(X_CF) {

+                    BFIw(xFlags, x3, F_CF, 1);

                 }

-                IFX(X_AF | X_PF | X_ZF | X_SF)

-                    if (BOX64ENV(dynarec_test)) {

-                        // to avoid noise during test

-                        MOV32w(x3, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));

-                        BICw(xFlags, xFlags, x3);

-                    }

+                IFX(X_OF) {

+                    BFIw(xFlags, x3, F_OF, 1);

+                }

+            }

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

+            IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);}

+            IFX(X_SF) {

+                LSRxw(x3, x2, 15);

+                BFIw(xFlags, x3, F_SF, 1);

             }

+            IFX(X_PF) emit_pf(dyn, ninst, x2, x3);

             break;

         case 0x6A:

             INST_NAME("PUSH Ib");

@@ -1422,26 +1421,25 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     MULw(x1, x2, x1);

                     BFIz(xRAX, x1, 0, 16);

                     BFXILx(xRDX, x1, 16, 16);

-                    UFLAG_IF {

-                        SET_DFNONE();

-                        IFX(X_CF|X_OF) {

-                            ASRw(x2, x1, 16);

-                            CMPSw_REG_ASR(x2, x1, 31);

-                            CSETw(x3, cNE);

-                            IFX(X_CF) {

-                                BFIw(xFlags, x3, F_CF, 1);

-                            }

-                            IFX(X_OF) {

-                                BFIw(xFlags, x3, F_OF, 1);

-                            }

+                    SET_DFNONE();

+                    IFX(X_CF|X_OF) {

+                        ASRw(x2, x1, 16);

+                        CMPSw_REG_ASR(x2, x1, 31);

+                        CSETw(x3, cNE);

+                        IFX(X_CF) {

+                            BFIw(xFlags, x3, F_CF, 1);

                         }

-                        IFX(X_AF | X_PF | X_ZF | X_SF)

-                            if (BOX64ENV(dynarec_test)) {

-                                // to avoid noise during test

-                                MOV32w(x3, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));

-                                BICw(xFlags, xFlags, x3);

-                            }

+                        IFX(X_OF) {

+                            BFIw(xFlags, x3, F_OF, 1);

+                        }

+                    }

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

+                    IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);}

+                    IFX(X_SF) {

+                        LSRxw(x3, xRAX, 15);

+                        BFIw(xFlags, x3, F_SF, 1);

                     }

+                    IFX(X_PF) emit_pf(dyn, ninst, xRAX, x3);

                     break;

                 case 6:

                     INST_NAME("DIV Ew");

diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c
index 412d2b62..2a30bc9c 100644
--- a/src/dynarec/arm64/dynarec_arm64_660f.c
+++ b/src/dynarec/arm64/dynarec_arm64_660f.c
@@ -2494,26 +2494,25 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             GETSGW(x2);

             MULw(x2, x2, x1);

             GWBACK;

-            UFLAG_IF {

-                SET_DFNONE();

-                IFX(X_CF|X_OF) {

-                    ASRw(x1, x2, 16);

-                    CMPSw_REG_ASR(x1, x2, 31);

-                    CSETw(x3, cNE);

-                    IFX(X_CF) {

-                        BFIw(xFlags, x3, F_CF, 1);

-                    }

-                    IFX(X_OF) {

-                        BFIw(xFlags, x3, F_OF, 1);

-                    }

+            SET_DFNONE();

+            IFX(X_CF|X_OF) {

+                ASRw(x1, x2, 16);

+                CMPSw_REG_ASR(x1, x2, 31);

+                CSETw(x3, cNE);

+                IFX(X_CF) {

+                    BFIw(xFlags, x3, F_CF, 1);

                 }

-                IFX(X_AF | X_PF | X_ZF | X_SF)

-                    if (BOX64ENV(dynarec_test)) {

-                        // to avoid noise during test

-                        MOV32w(x3, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));

-                        BICw(xFlags, xFlags, x3);

-                    }

+                IFX(X_OF) {

+                    BFIw(xFlags, x3, F_OF, 1);

+                }

+            }

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

+            IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);}

+            IFX(X_SF) {

+                LSRxw(x3, gd, 15);

+                BFIw(xFlags, x3, F_SF, 1);

             }

+            IFX(X_PF) emit_pf(dyn, ninst, gd, x3);

             break;

 

         case 0xB3:

diff --git a/src/dynarec/arm64/dynarec_arm64_67.c b/src/dynarec/arm64/dynarec_arm64_67.c
index 9c255932..4473c491 100644
--- a/src/dynarec/arm64/dynarec_arm64_67.c
+++ b/src/dynarec/arm64/dynarec_arm64_67.c
@@ -929,10 +929,6 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     SMULH(x3, ed, x4);

                     MULx(gd, ed, x4);

                     SET_DFNONE();

-                    IFX(X_ZF | X_PF | X_AF | X_SF) {

-                        MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));

-                        BICw(xFlags, xFlags, x1);

-                    }

                     IFX(X_CF | X_OF) {

                         CMPSx_REG_ASR(x3, gd, 63);

                         CSETw(x1, cNE);

@@ -953,10 +949,6 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     LSRx(x3, gd, 32);

                     MOVw_REG(gd, gd);

                     SET_DFNONE();

-                    IFX(X_ZF | X_PF | X_AF | X_SF) {

-                        MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));

-                        BICw(xFlags, xFlags, x1);

-                    }

                     IFX(X_CF | X_OF) {

                         CMPSw_REG_ASR(x3, gd, 31);

                         CSETw(x1, cNE);

@@ -971,6 +963,13 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     MULxw(gd, ed, x4);

                 }

             }

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

+            IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);}

+            IFX(X_SF) {

+                LSRxw(x3, gd, rex.w?63:31);

+                BFIw(xFlags, x3, F_SF, 1);

+            }

+            IFX(X_PF) emit_pf(dyn, ninst, gd, x3);

             break;

 

         case 0x70:

@@ -1509,25 +1508,24 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         MOVw_REG(xRAX, xRDX);

                         LSRx(xRDX, xRDX, 32);

                     }

-                    UFLAG_IF {

-                        SET_DFNONE();

-                        IFX(X_CF|X_OF) {

-                            CMPSxw_REG_ASR(xRDX, xRAX, rex.w?63:31);

-                            CSETw(x3, cNE);

-                            IFX(X_CF) {

-                                BFIw(xFlags, x3, F_CF, 1);

-                            }

-                            IFX(X_OF) {

-                                BFIw(xFlags, x3, F_OF, 1);

-                            }

+                    SET_DFNONE();

+                    IFX(X_CF|X_OF) {

+                        CMPSxw_REG_ASR(xRDX, xRAX, rex.w?63:31);

+                        CSETw(x3, cNE);

+                        IFX(X_CF) {

+                            BFIw(xFlags, x3, F_CF, 1);

                         }

-                        IFX(X_AF | X_PF | X_ZF | X_SF)

-                            if (BOX64ENV(dynarec_test)) {

-                                // to avoid noise during test

-                                MOV32w(x3, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));

-                                BICw(xFlags, xFlags, x3);

-                            }

+                        IFX(X_OF) {

+                            BFIw(xFlags, x3, F_OF, 1);

+                        }

+                    }

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

+                    IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);}

+                    IFX(X_SF) {

+                        LSRxw(x3, xRAX, rex.w?63:31);

+                        BFIw(xFlags, x3, F_SF, 1);

                     }

+                    IFX(X_PF) emit_pf(dyn, ninst, xRAX, x3);

                     break;

                 case 6:

                     INST_NAME("DIV Ed");

diff --git a/src/dynarec/arm64/dynarec_arm64_emit_shift.c b/src/dynarec/arm64/dynarec_arm64_emit_shift.c
index ebd138a1..6637ca51 100644
--- a/src/dynarec/arm64/dynarec_arm64_emit_shift.c
+++ b/src/dynarec/arm64/dynarec_arm64_emit_shift.c
@@ -35,32 +35,43 @@ void emit_shl32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
     } else {
         SET_DFNONE();
     }
-    IFX(X_CF | X_OF) {
-        MOV32w(s4, rex.w?64:32);
-        SUBxw_REG(s4, s4, s2);
-        LSRxw_REG(s4, s1, s4);
-        BFIw(xFlags, s4, F_CF, 1);
+    if(BOX64ENV(cputype)) {
+        IFX(X_CF | X_OF) {
+            MOV32w(s4, rex.w?64:32);
+            SUBxw_REG(s4, s4, s2);
+            LSRxw_REG(s4, s1, s4);
+            BFIw(xFlags, s4, F_CF, 1);
+        }
+    } else {
+        IFX(X_OF) {
+            LSRxw(s4, s1, rex.w?62:30);
+            EORw_REG_LSR(s4, s4, s4, 1);
+            BFIw(xFlags, s4, F_OF, 1);
+        }
+        IFX(X_CF) {
+            MOV32w(s4, rex.w?64:32);
+            SUBxw_REG(s4, s4, s2);
+            LSRxw_REG(s4, s1, s4);
+            BFIw(xFlags, s4, F_CF, 1);
+        }
     }
     LSLxw_REG(s1, s1, s2);
     IFX(X_PEND) {
         STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
     }
-    IFX(X_OF) {
-        LSRxw(s4, s1, (rex.w)?63:31);
-        EORxw_REG(s3, s4, xFlags);  // CF is set if OF is asked
-        if(BOX64ENV(dynarec_test)) {
-            CMPSxw_U12(s2, 1);   // if s2==1
-            CSELw(s3, s3, wZR, cEQ);
+    if(BOX64ENV(cputype))
+        IFX(X_OF) {
+            LSRxw(s4, s1, (rex.w)?63:31);
+            EORxw_REG(s3, s4, xFlags);  // CF is set if OF is asked
+            BFIw(xFlags, s3, F_OF, 1);
         }
-        BFIw(xFlags, s3, F_OF, 1);
-    }
     int need_tst = 0;
     IFX(X_ZF) need_tst = 1;
     IFXNATIVE(X_SF, NF_SF) need_tst = 1;
     if(need_tst) TSTxw_REG(s1, s1);
     IFX(X_SF) {
         IFNATIVE(NF_SF) {} else {
-            IFX(X_OF) {} else {LSRxw(s4, s1, (rex.w)?63:31);}
+            IFX2(X_OF, && BOX64ENV(cputype)) {} else {LSRxw(s4, s1, (rex.w)?63:31);}
             BFIw(xFlags, s4, F_SF, 1);
         }
     }
@@ -92,9 +103,21 @@ void emit_shl32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
     } else {
         SET_DFNONE();
     }
-    IFX(X_CF|X_OF) {
-        LSRxw(s3, s1, (rex.w?64:32)-c);
-        BFIxw(xFlags, s3, F_CF, 1);
+    if(BOX64ENV(cputype)) {
+        IFX(X_CF|X_OF) {
+            LSRxw(s3, s1, (rex.w?64:32)-c);
+            BFIxw(xFlags, s3, F_CF, 1);
+        }
+    } else {
+        IFX(X_OF) {
+            LSRxw(s3, s1, rex.w?62:30);
+            EORw_REG_LSR(s3, s3, s3, 1);
+            BFIw(xFlags, s3, F_OF, 1);
+        }
+        IFX(X_CF) {
+            LSRxw(s3, s1, (rex.w?64:32)-c);
+            BFIxw(xFlags, s3, F_CF, 1);
+        }
     }
     LSLxw(s1, s1, c);
 
@@ -117,19 +140,15 @@ void emit_shl32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
             BFIw(xFlags, s4, F_SF, 1);
         }
     }
-    IFX(X_OF) {
-        if(c==1 || BOX64DRENV(dynarec_safeflags)>1) {
+    if(BOX64ENV(cputype))
+        IFX(X_OF) {
             IFX(X_SF) {} else {LSRxw(s4, s1, (rex.w)?63:31);}
             EORxw_REG(s4, s4, xFlags);  // CF is set if OF is asked
             BFIw(xFlags, s4, F_OF, 1);
-        } else {
-            BFCw(xFlags, F_OF, 1);
         }
+    IFX(X_AF) {
+        BFCw(xFlags, F_AF, 1);
     }
-    if (BOX64ENV(dynarec_test))
-        IFX(X_AF) {
-            BFCw(xFlags, F_AF, 1);
-        }
     IFX(X_PF) {
         if(c>7) {
             // the 0xff area will be 0, so PF is known
@@ -161,10 +180,6 @@ void emit_shr32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
     }
     IFX(X_OF) {
         LSRxw(s4, s1, rex.w?63:31);
-        if(BOX64ENV(dynarec_test)) {
-            CMPSxw_U12(s2, 1);   // if s2==1
-            CSELw(s4, s4, xZR, cEQ);    // clear bit if c!=1
-        }
         BFIw(xFlags, s4, F_OF, 1);
     }
     LSRxw_REG(s1, s1, s2);
@@ -187,10 +202,9 @@ void emit_shr32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
             BFIx(xFlags, s4, F_SF, 1);
         }
     }
-    if (BOX64ENV(dynarec_test))
-        IFX(X_AF) {
-            BFCw(xFlags, F_AF, 1);
-        }
+    IFX(X_AF) {
+        BFCw(xFlags, F_AF, 1);
+    }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s4);
     }
@@ -217,7 +231,7 @@ void emit_shr32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
             BFIw(xFlags, s3, 0, 1);
         }
     }
-    IFX2(X_OF, && (c==1 || BOX64DRENV(dynarec_safeflags)>1)) {
+    IFX(X_OF) {
         LSRxw(s4, s1, rex.w?63:31);
         BFIw(xFlags, s4, F_OF, 1);
     }
@@ -241,13 +255,8 @@ void emit_shr32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
             BFCw(xFlags, F_SF, 1);
         }
     }
-    if (BOX64ENV(dynarec_test)) {
-        IFX(X_AF) {
-            BFCw(xFlags, F_AF, 1);
-        }
-        IFX(X_OF) if(c>1) {
-            BFCw(xFlags, F_OF, 1);
-        }
+    IFX(X_AF) {
+        BFCw(xFlags, F_AF, 1);
     }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s4);
@@ -296,10 +305,9 @@ void emit_sar32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
             BFIx(xFlags, s4, F_SF, 1);
         }
     }
-    if (BOX64ENV(dynarec_test))
-        IFX(X_AF) {
-            BFCw(xFlags, F_AF, 1);
-        }
+    IFX(X_AF) {
+        BFCw(xFlags, F_AF, 1);
+    }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s4);
     }
@@ -342,14 +350,12 @@ void emit_sar32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
             BFIx(xFlags, s4, F_SF, 1);
         }
     }
-    IFX(X_OF)
-        if (c == 1 || BOX64ENV(dynarec_test) || BOX64DRENV(dynarec_safeflags)>1) {
-            BFCw(xFlags, F_OF, 1);
-        }
-    if (BOX64ENV(dynarec_test))
-        IFX(X_AF) {
-            BFCw(xFlags, F_AF, 1);
-        }
+    IFX(X_OF) {
+        BFCw(xFlags, F_OF, 1);
+    }
+    IFX(X_AF) {
+        BFCw(xFlags, F_AF, 1);
+    }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s4);
     }
@@ -369,30 +375,40 @@ void emit_shl8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
     } else {
         SET_DFNONE();
     }
-    IFX(X_CF | X_OF) {
-        MOV32w(s4, 8);
-        SUBw_REG(s4, s4, s2);
-        LSRw_REG(s4, s1, s4);
-        BFIw(xFlags, s4, F_CF, 1);
+    if(BOX64ENV(cputype)) {
+        IFX(X_CF | X_OF) {
+            MOV32w(s4, 8);
+            SUBw_REG(s4, s4, s2);
+            LSRw_REG(s4, s1, s4);
+            BFIw(xFlags, s4, F_CF, 1);
+        }
+    } else {
+	    IFX(X_OF) {
+            LSRw(s4, s1, 6);
+            EORw_REG_LSR(s4, s4, s4, 1);
+            BFIw(xFlags, s4, F_OF, 1);
+        }
+        IFX(X_CF) {
+            MOV32w(s4, 8);
+            SUBw_REG(s4, s4, s2);
+            LSRw_REG(s4, s1, s4);
+            BFIw(xFlags, s4, F_CF, 1);
+        }
     }
     LSLw_REG(s1, s1, s2);
     IFX(X_PEND) {
         STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
     }
-    IFX(X_OF) {
-        LSRw(s3, s1, 7);
-        EORw_REG(s4, s3, xFlags);  // CF is set if OF is asked
-        if(BOX64ENV(dynarec_test)) {
-            CMPSw_U12(s2, 1);   // if s2==1
-            CSELw(s4, s4, wZR, cEQ);
+    if(BOX64ENV(cputype))
+        IFX(X_OF) {
+            LSRw(s3, s1, 7);
+            EORw_REG(s4, s3, xFlags);  // CF is set if OF is asked
+            BFIw(xFlags, s4, F_OF, 1);
         }
-        BFIw(xFlags, s4, F_OF, 1);
-    }
     COMP_ZFSF(s1, 8)
-    if (BOX64ENV(dynarec_test))
-        IFX(X_AF) {
-            BFCw(xFlags, F_AF, 1);
-        }
+    IFX(X_AF) {
+        BFCw(xFlags, F_AF, 1);
+    }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s4);
     }
@@ -412,8 +428,19 @@ void emit_shl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
         SET_DFNONE();
     }
     if(c<8) {
-        IFX(X_CF|X_OF) {
-            BFXILw(xFlags, s1, 8-c, 1);
+	    if(BOX64ENV(cputype)) {
+            IFX(X_CF|X_OF) {
+                BFXILw(xFlags, s1, 8-c, 1);
+            }
+        } else {
+            IFX(X_OF) {
+                LSRw(s4, s1, 6);
+                EORw_REG_LSR(s4, s4, s4, 1);
+                BFIw(xFlags, s4, F_OF, 1);
+            }
+            IFX(X_CF) {
+                BFXILw(xFlags, s1, 8-c, 1);
+            }
         }
         LSLw(s1, s1, c);
 
@@ -421,19 +448,15 @@ void emit_shl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
             STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
         }
         COMP_ZFSF(s1, 8)
-        IFX(X_OF) {
-            if(c==1 || BOX64DRENV(dynarec_safeflags)>1) {
+        if(BOX64ENV(cputype))
+            IFX(X_OF) {
                 IFX2(X_SF, && !arm64_flagm) {} else {LSRw(s3, s1, 7);}  //use COMP_ZFSF operation
                 EORw_REG(s4, s3, xFlags);  // CF is set if OF is asked
                 BFIw(xFlags, s4, F_OF, 1);
-            } else {
-                BFCw(xFlags, F_OF, 1);
             }
+        IFX (X_AF) {
+            BFCw(xFlags, F_AF, 1);
         }
-        if (BOX64ENV(dynarec_test))
-            IFX (X_AF) {
-                BFCw(xFlags, F_AF, 1);
-            }
         IFX(X_PF) {
             emit_pf(dyn, ninst, s1, s4);
         }
@@ -451,15 +474,14 @@ void emit_shl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
             IFNATIVE(NF_CF) {GEN_INVERTED_CARRY();} else {BFCw(xFlags, F_CF, 1);}
         }
         IFX(X_OF) {
-            BFCw(xFlags, F_OF, 1);
+            IFNATIVE(NF_VF) {} else BFCw(xFlags, F_OF, 1);
         }
         IFX(X_SF) {
             IFNATIVE(NF_SF) {} else BFCw(xFlags, F_SF, 1);
         }
-        if (BOX64ENV(dynarec_test))
-            IFX (X_AF) {
-                BFCw(xFlags, F_AF, 1);
-            }
+        IFX (X_AF) {
+            BFCw(xFlags, F_AF, 1);
+        }
         IFX(X_ZF) {
             IFNATIVE(NF_EQ) {} else {
                 ORRw_mask(xFlags, xFlags, 26, 0);   //1<<F_ZF
@@ -492,10 +514,6 @@ void emit_shr8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
     }
     IFX(X_OF) {
         LSRw(s4, s1, 7);
-        if(BOX64ENV(dynarec_test)) {
-            CMPSw_U12(s2, 1);   // if s2==1
-            CSELw(s4, s4, xZR, cEQ);
-        }
         BFIw(xFlags, s4, F_OF, 1);
     }
     LSRw_REG(s1, s1, s2);
@@ -503,10 +521,9 @@ void emit_shr8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
         STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
     }
     COMP_ZFSF(s1, 8)
-    if (BOX64ENV(dynarec_test))
-        IFX(X_AF) {
-            BFCw(xFlags, F_AF, 1);
-        }
+    IFX(X_AF) {
+        BFCw(xFlags, F_AF, 1);
+    }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s4);
     }
@@ -533,22 +550,17 @@ void emit_shr8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
         }
     }
     IFX(X_OF) {
-        if(c==1 || BOX64DRENV(dynarec_safeflags)>1) {
-            LSRw(s4, s1, 7);
-            BFIw(xFlags, s4, F_OF, 1);
-        } else if (BOX64ENV(dynarec_test)) {
-            BFCw(xFlags, F_OF, 1);
-        }
+        LSRw(s4, s1, 7);
+        BFIw(xFlags, s4, F_OF, 1);
     }
     LSRw(s1, s1, c);
     IFX(X_PEND) {
         STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
     }
     COMP_ZFSF(s1, 8)
-    if (BOX64ENV(dynarec_test))
-        IFX(X_AF) {
-            BFCw(xFlags, F_AF, 1);
-        }
+    IFX(X_AF) {
+        BFCw(xFlags, F_AF, 1);
+    }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s4);
     }
@@ -575,9 +587,7 @@ void emit_sar8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
     }
     COMP_ZFSF(s1, 8)
     IFX(X_OF) {
-        //SUBw_U12(s4, s2, 1);
-        //CBNZw(s4, 4+4);
-            BFCw(xFlags, F_OF, 1);
+        BFCw(xFlags, F_OF, 1);
     }
     if (BOX64ENV(dynarec_test))
         IFX(X_AF) {
@@ -609,10 +619,9 @@ void emit_sar8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
     }
     if(c<8) {
         COMP_ZFSF(s1, 8)
-        IFX(X_OF)
-            if ((c == 1) || BOX64ENV(dynarec_test) || BOX64DRENV(dynarec_safeflags)>1) {
-                BFCw(xFlags, F_OF, 1);
-            }
+        IFX(X_OF) {
+            BFCw(xFlags, F_OF, 1);
+        }
         IFX(X_PF) {
             emit_pf(dyn, ninst, s1, s4);
         }
@@ -625,7 +634,7 @@ void emit_sar8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
                 EORw_mask(s3, s3, 0, 0);    //1
                 BFIw(xFlags, s3, F_ZF, 1);
             }
-            IFX(X_OF){if(BOX64ENV(dynarec_test) || BOX64DRENV(dynarec_safeflags)>1) BFCw(xFlags, F_OF, 1);}
+            IFX(X_OF){BFCw(xFlags, F_OF, 1);}
             IFX(X_PF) {
                 ORRw_mask(xFlags, xFlags, 30, 0);   //1<<F_PF
             }
@@ -647,30 +656,40 @@ void emit_shl16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
     } else {
         SET_DFNONE();
     }
-    IFX(X_CF | X_OF) {
-        MOV32w(s4, 16);
-        SUBw_REG(s4, s4, s2);
-        LSRw_REG(s4, s1, s4);
-        BFIw(xFlags, s4, F_CF, 1);
+    if(BOX64ENV(cputype)) {
+        IFX(X_CF | X_OF) {
+            MOV32w(s4, 16);
+            SUBw_REG(s4, s4, s2);
+            LSRw_REG(s4, s1, s4);
+            BFIw(xFlags, s4, F_CF, 1);
+        }
+    } else {
+        IFX(F_OF) {
+            LSRw(s4, s1, 14);
+            EORw_REG_LSR(s4, s4, s4, 1);
+            BFIw(xFlags, s4, F_OF, 1);
+        }
+        IFX(X_CF) {
+            MOV32w(s4, 16);
+            SUBw_REG(s4, s4, s2);
+            LSRw_REG(s4, s1, s4);
+            BFIw(xFlags, s4, F_CF, 1);
+        }
     }
     LSLw_REG(s1, s1, s2);
     IFX(X_PEND) {
         STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
     }
-    IFX(X_OF) {
-        LSRw(s3, s1, 15);
-        EORw_REG(s4, s3, xFlags);  // CF is set if OF is asked
-        if(BOX64ENV(dynarec_test)) {
-            CMPSw_U12(s2, 1);   // if s2==1
-            CSELw(s4, s4, wZR, cEQ);
+    if(BOX64ENV(cputype))
+        IFX(X_OF) {
+            LSRw(s3, s1, 15);
+            EORw_REG(s4, s3, xFlags);  // CF is set if OF is asked
+            BFIw(xFlags, s4, F_OF, 1);
         }
-        BFIw(xFlags, s4, F_OF, 1);
-    }
     COMP_ZFSF(s1, 16)
-    if (BOX64ENV(dynarec_test))
-        IFX(X_AF) {
-            BFCw(xFlags, F_AF, 1);
-        }
+    IFX(X_AF) {
+        BFCw(xFlags, F_AF, 1);
+    }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s4);
     }
@@ -689,9 +708,21 @@ void emit_shl16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
         SET_DFNONE();
     }
     if(c<16) {
-        IFX(X_CF|X_OF) {
-            LSRw(s3, s1, 16-c);
-            BFIw(xFlags, s3, F_CF, 1);
+        if(BOX64ENV(cputype)) {
+            IFX(X_CF|X_OF) {
+                LSRw(s3, s1, 16-c);
+                BFIw(xFlags, s3, F_CF, 1);
+            }
+        } else {
+            IFX(F_OF) {
+                LSRw(s4, s1, 14);
+                EORw_REG_LSR(s4, s4, s4, 1);
+                BFIw(xFlags, s4, F_OF, 1);
+            }
+            IFX(X_CF) {
+                LSRw(s3, s1, 16-c);
+                BFIw(xFlags, s3, F_CF, 1);
+            }
         }
         LSLw(s1, s1, c);
 
@@ -699,19 +730,15 @@ void emit_shl16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
             STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
         }
         COMP_ZFSF(s1, 16)
-        IFX(X_OF) {
-            if(c==1 || BOX64DRENV(dynarec_safeflags)>1) {
+        if(BOX64ENV(cputype))
+            IFX(X_OF) {
                 IFX2(X_SF, && !arm64_flagm) {} else {LSRw(s3, s1, 15);} // use COMP_ZFSF operation
                 EORw_REG(s4, s3, xFlags);  // CF is set if OF is asked
                 BFIw(xFlags, s4, F_OF, 1);
-            } else if (BOX64ENV(dynarec_test)) {
-                BFCw(xFlags, F_OF, 1);
             }
+        IFX (X_AF) {
+            BFCw(xFlags, F_AF, 1);
         }
-        if (BOX64ENV(dynarec_test))
-            IFX (X_AF) {
-                BFCw(xFlags, F_AF, 1);
-            }
         IFX(X_PF) {
             if(c>7) {
                 // the 0xff area will be 0, so PF is known
@@ -738,10 +765,9 @@ void emit_shl16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
         IFX(X_SF) {
             IFNATIVE(NF_SF) {} else BFCw(xFlags, F_SF, 1);
         }
-        if (BOX64ENV(dynarec_test))
-            IFX (X_AF) {
-                BFCw(xFlags, F_AF, 1);
-            }
+        IFX (X_AF) {
+            BFCw(xFlags, F_AF, 1);
+        }
         IFX(X_ZF) {
             IFNATIVE(NF_EQ) {} else {
                 ORRw_mask(xFlags, xFlags, 26, 0);   //1<<F_ZF
@@ -770,10 +796,6 @@ void emit_shr16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
     }
     IFX(X_OF) {
         LSRw(s4, s1, 15);
-        if(BOX64DRENV(dynarec_test)) {
-            CMPSw_U12(s2, 1);   // if s2==1
-            CSELw(s4, s4, xZR, cEQ);
-        }
         BFIw(xFlags, s4, F_OF, 1);
     }
     LSRw_REG(s1, s1, s2);
@@ -812,22 +834,17 @@ void emit_shr16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
         }
     }
     IFX(X_OF) {
-        if(c==1 || BOX64DRENV(dynarec_safeflags)>1) {
-            LSRw(s4, s1, 15);
-            BFIw(xFlags, s4, F_OF, 1);
-        } else if (BOX64ENV(dynarec_test)) {
-            BFCw(xFlags, F_OF, 1);
-        }
+        LSRw(s4, s1, 15);
+        BFIw(xFlags, s4, F_OF, 1);
     }
     LSRw(s1, s1, c);
     IFX(X_PEND) {
         STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
     }
     COMP_ZFSF(s1, 16)
-    if (BOX64ENV(dynarec_test))
-        IFX(X_AF) {
-            BFCw(xFlags, F_AF, 1);
-        }
+    IFX(X_AF) {
+        BFCw(xFlags, F_AF, 1);
+    }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s4);
     }
@@ -853,15 +870,12 @@ void emit_sar16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
         STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
     }
     IFX(X_OF) {
-        //SUBw_U12(s4, s2, 1);
-        //CBNZw(s4, 4+4);
-            BFCw(xFlags, F_OF, 1);
+        BFCw(xFlags, F_OF, 1);
     }
     COMP_ZFSF(s1, 16)
-    if (BOX64ENV(dynarec_test))
-        IFX(X_AF) {
-            BFCw(xFlags, F_AF, 1);
-        }
+    IFX(X_AF) {
+        BFCw(xFlags, F_AF, 1);
+    }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s4);
     }
@@ -888,14 +902,12 @@ void emit_sar16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
         STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
     }
     COMP_ZFSF(s1, 16)
-    IFX(X_OF)
-        if ((c == 1) || BOX64ENV(dynarec_test) || BOX64DRENV(dynarec_safeflags)>1) {
-            BFCw(xFlags, F_OF, 1);
-        }
-    if (BOX64ENV(dynarec_test))
-        IFX(X_AF) {
-            BFCw(xFlags, F_AF, 1);
-        }
+    IFX(X_OF) {
+        BFCw(xFlags, F_OF, 1);
+    }
+    IFX(X_AF) {
+        BFCw(xFlags, F_AF, 1);
+    }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s4);
     }
@@ -914,12 +926,8 @@ void emit_rol32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
         BFIw(xFlags, s1, F_CF, 1);
     }
     IFX(X_OF) {
-        if(c==1) {
-            EORxw_REG_LSR(s3, s1, s1, rex.w?63:31);
-            BFIw(xFlags, s3, F_OF, 1);
-        } else if (BOX64ENV(dynarec_test)) {
-            BFCw(xFlags, F_OF, 1);
-        }
+        EORxw_REG_LSR(s3, s1, s1, rex.w?63:31);
+        BFIw(xFlags, s3, F_OF, 1);
     }
 }
 
@@ -932,19 +940,22 @@ void emit_ror32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
 
     SET_DFNONE();
 
+    if(!BOX64ENV(cputype))
+        IFX(X_OF) {
+            EORxw_REG_LSR(s3, s1, s1, rex.w?63:31);
+            BFIw(xFlags, s3, F_OF, 1);
+        }
+
     RORxw(s1, s1, c);
     IFX(X_CF) {
         BFXILxw(xFlags, s1, rex.w?63:31, 1);
     }
-    IFX(X_OF) {
-        if(c==1) {
+    if(BOX64ENV(cputype))
+        IFX(X_OF) {
             LSRxw(s3, s1, rex.w?62:30);
             EORxw_REG_LSR(s3, s3, s3, 1);
             BFIw(xFlags, s3, F_OF, 1);
-        } else if (BOX64ENV(dynarec_test)) {
-            BFCw(xFlags, F_OF, 1);
         }
-    }
 }
 
 // emit ROL8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
@@ -965,12 +976,8 @@ void emit_rol8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
         BFIw(xFlags, s1, F_CF, 1);
     }
     IFX(X_OF) {
-        if(c==1) {
-            EORw_REG_LSR(s3, s1, s1, 7);
-            BFIw(xFlags, s3, F_OF, 1);
-        } else if (BOX64ENV(dynarec_test)) {
-            BFCw(xFlags, F_OF, 1);
-        }
+        EORw_REG_LSR(s3, s1, s1, 7);
+        BFIw(xFlags, s3, F_OF, 1);
     }
 }
 
@@ -983,6 +990,12 @@ void emit_ror8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
 
     SET_DFNONE();
 
+    if(!BOX64ENV(cputype))
+        IFX(X_OF) {
+            EORw_REG_LSR(s3, s1, s1, 7);
+            BFIw(xFlags, s3, F_OF, 1);
+        }
+
     if(c&7) {
         ORRw_REG_LSL(s1, s1, s1, 8);
         LSRw(s1, s1, c&7);
@@ -990,15 +1003,12 @@ void emit_ror8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
     IFX(X_CF) {
         BFXILw(xFlags, s1, 7, 1);
     }
-    IFX(X_OF) {
-        if(c==1) {
+    if(BOX64ENV(cputype))
+        IFX(X_OF) {
             LSRw(s3, s1, 6);
             EORw_REG_LSR(s3, s3, s3, 1);
             BFIw(xFlags, s3, F_OF, 1);
-        } else if (BOX64ENV(dynarec_test)) {
-            BFCw(xFlags, F_OF, 1);
         }
-    }
 }
 
 // emit ROL16 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
@@ -1019,12 +1029,8 @@ void emit_rol16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
         BFIw(xFlags, s1, F_CF, 1);
     }
     IFX(X_OF) {
-        if(c==1) {
-            EORw_REG_LSR(s3, s1, s1, 15);
-            BFIw(xFlags, s3, F_OF, 1);
-        } else if (BOX64ENV(dynarec_test)) {
-            BFCw(xFlags, F_OF, 1);
-        }
+        EORw_REG_LSR(s3, s1, s1, 15);
+        BFIw(xFlags, s3, F_OF, 1);
     }
 }
 
@@ -1037,6 +1043,11 @@ void emit_ror16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
 
     SET_DFNONE();
 
+    if(!BOX64ENV(cputype))
+        IFX(X_OF) {
+            EORw_REG_LSR(s3, s1, s1, 15);
+            BFIw(xFlags, s3, F_OF, 1);
+        }
     if(c&15) {
         ORRw_REG_LSL(s1, s1, s1, 16);
         LSRw(s1, s1, c&15);
@@ -1044,15 +1055,12 @@ void emit_ror16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
     IFX(X_CF) {
         BFXILw(xFlags, s1, 15, 1);
     }
-    IFX(X_OF) {
-        if(c==1) {
+    if(BOX64ENV(cputype))
+        IFX(X_OF) {
             LSRw(s3, s1, 14);
             EORw_REG_LSR(s3, s3, s3, 1);
             BFIw(xFlags, s3, F_OF, 1);
-        } else if (BOX64ENV(dynarec_test)) {
-            BFCw(xFlags, F_OF, 1);
         }
-    }
 }
 
 // emit RCL8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
@@ -1074,18 +1082,12 @@ void emit_rcl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
     }
     ORRw_REG_LSL(s1, s1, s1, 9);    // insert s1 again
     LSRw_IMM(s1, s1, 9-c); // do the rcl
-    IFX(X_OF|X_CF) {
-        IFX(X_CF) {
-            BFIw(xFlags, s3, F_CF, 1);
-        }
-        IFX(X_OF) {
-            if(c==1) {
-                EORw_REG_LSR(s3, s3, s1, 7);
-                BFIw(xFlags, s3, F_OF, 1);
-            } else if (BOX64ENV(dynarec_test)) {
-                BFCw(xFlags, F_OF, 1);
-            }
-        }
+    IFX(X_CF) {
+        BFIw(xFlags, s3, F_CF, 1);
+    }
+    IFX(X_OF) {
+        EORw_REG_LSR(s3, s3, s1, 7);
+        BFIw(xFlags, s3, F_OF, 1);
     }
 }
 
@@ -1099,12 +1101,8 @@ void emit_rcr8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
 
     c%=9;
     IFX(X_OF) {
-        if(c==1) {
-            EORw_REG_LSR(s3, xFlags, s1, 7);
-            BFIw(xFlags, s3, F_OF, 1);
-        } else if (BOX64ENV(dynarec_test)) {
-            BFCw(xFlags, F_OF, 1);
-        }
+        EORw_REG_LSR(s3, xFlags, s1, 7);
+        BFIw(xFlags, s3, F_OF, 1);
     }
     BFIw(s1, xFlags, 8, 1); // insert cf
     IFX(X_CF) {
@@ -1139,12 +1137,8 @@ void emit_rcl16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
         BFIw(xFlags, s3, F_CF, 1);
     }
     IFX(X_OF) {
-        if(c==1) {
-            EORw_REG_LSR(s3, s3, s1, 15);
-            BFIw(xFlags, s3, F_OF, 1);
-        } else if (BOX64ENV(dynarec_test)) {
-            BFCw(xFlags, F_OF, 1);
-        }
+        EORw_REG_LSR(s3, s3, s1, 15);
+        BFIw(xFlags, s3, F_OF, 1);
     }
 }
 
@@ -1159,12 +1153,8 @@ void emit_rcr16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
     c%=17;
     BFIw(s1, xFlags, 16, 1); // insert cf
     IFX(X_OF) {
-        if(c==1) {
-            EORw_REG_LSR(s3, xFlags, s1, 15);
-            BFIw(xFlags, s3, F_OF, 1);
-        } else if (BOX64ENV(dynarec_test)) {
-            BFCw(xFlags, F_OF, 1);
-        }
+        EORw_REG_LSR(s3, xFlags, s1, 15);
+        BFIw(xFlags, s3, F_OF, 1);
     }
     IFX(X_CF) {
         BFXILx(xFlags, s1, c-1, 1);
@@ -1199,12 +1189,8 @@ void emit_rcl32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
         BFIw(xFlags, s3, F_CF, 1);
     }
     IFX(X_OF) {
-        if(c==1) {
-            EORxw_REG_LSR(s3, s3, s1, rex.w?63:31);
-            BFIw(xFlags, s3, F_OF, 1);
-        } else if (BOX64ENV(dynarec_test)) {
-            BFCw(xFlags, F_OF, 1);
-        }
+        EORxw_REG_LSR(s3, s3, s1, rex.w?63:31);
+        BFIw(xFlags, s3, F_OF, 1);
     }
 }
 // emit RCR32/RCR64 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
@@ -1217,12 +1203,8 @@ void emit_rcr32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
     SET_DFNONE();
 
     IFX(X_OF) {
-        if(c==1) {
-            EORxw_REG_LSR(s3, xFlags, s1, rex.w?63:31);
-            BFIw(xFlags, s3, F_OF, 1);
-        } else if (BOX64ENV(dynarec_test)) {
-            BFCw(xFlags, F_OF, 1);
-        }
+        EORxw_REG_LSR(s3, xFlags, s1, rex.w?63:31);
+        BFIw(xFlags, s3, F_OF, 1);
     }
     IFX(X_CF) {
         BFXILxw(s3, s1, c-1, 1);
@@ -1255,19 +1237,15 @@ void emit_shrd32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint
         BFXILxw(xFlags, s1, c-1, 1);    // set CF
     }
     IFX(X_OF) {
-        if(c==1) {
-            LSRxw(s4, s1, rex.w?63:31);
-        }
+        LSRxw(s4, s1, rex.w?63:31);
     }
     EXTRxw(s1, s2, s1, c);
     IFX(X_PEND) {
         STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
     }
     IFX(X_OF) {
-        if(c==1) {
-            EORx_REG_LSR(s3, s4, s1, rex.w?63:31);   // OF is set if sign changed
-            BFIw(xFlags, s3, F_OF, 1);
-        }
+        EORx_REG_LSR(s3, s4, s1, rex.w?63:31);   // OF is set if sign changed
+        BFIw(xFlags, s3, F_OF, 1);
     }
     int need_tst = 0;
     IFX(X_ZF) need_tst = 1;
@@ -1285,10 +1263,7 @@ void emit_shrd32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint
             BFIx(xFlags, s4, F_SF, 1);
         }
     }
-    if (BOX64ENV(dynarec_test)) {
-        IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
-        IFX2(X_OF, && (c>1)) {BFCw(xFlags, F_OF, 1);}
-    }
+    IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s4);
     }
@@ -1307,10 +1282,8 @@ void emit_shld32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint
     IFX(X_CF) {
         BFXILx(xFlags, s1, (rex.w?64:32)-c, 1);
     }
-    if(c==1) {
-        IFX(X_OF) {
-            LSRxw(s4, s1, rex.w?63:31);
-        }
+    IFX(X_OF) {
+        LSRxw(s4, s1, rex.w?63:31);
     }
     EXTRxw(s1, s1, s2, (rex.w?64:32)-c);
 
@@ -1318,7 +1291,7 @@ void emit_shld32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint
         STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
     }
     IFX(X_OF) {
-        if(c==1) {
+        if((c==1) || (BOX64DRENV(dynarec_safeflags)>1)) {
             EORx_REG_LSR(s3, s4, s1, rex.w?63:31);   // OF is set if sign changed
             BFIw(xFlags, s3, F_OF, 1);
         }
@@ -1339,10 +1312,7 @@ void emit_shld32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint
             BFIx(xFlags, s4, F_SF, 1);
         }
     }
-    if (BOX64ENV(dynarec_test)) {
-        IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
-        IFX2(X_OF, && (c>1)) {BFCw(xFlags, F_OF, 1);}
-    }
+    IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s4);
     }
@@ -1380,17 +1350,8 @@ void emit_shrd32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
         STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
     }
     IFX(X_OF) {
-        if (BOX64ENV(dynarec_test)) {
-            CMPSw_U12(s5, 1);
-            EORxw_REG_LSR(s3, s4, s1, rex.w?63:31);   // OF is set if sign changed
-            CSELw(s3, s3, xZR, cEQ);
-            BFIw(xFlags, s3, F_OF, 1);
-        } else {
-            // CMPSw_U12(s5, 1);
-            EORxw_REG_LSR(s3, s4, s1, rex.w?63:31);   // OF is set if sign changed
-        //    CSELw(s3, s3, xZR, cEQ);
-            BFIw(xFlags, s3, F_OF, 1);
-        }
+        EORxw_REG_LSR(s3, s4, s1, rex.w?63:31);   // OF is set if sign changed
+        BFIw(xFlags, s3, F_OF, 1);
     }
     int need_tst = 0;
     IFX(X_ZF) need_tst = 1;
@@ -1408,9 +1369,7 @@ void emit_shrd32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
             BFIx(xFlags, s4, F_SF, 1);
         }
     }
-    if (BOX64ENV(dynarec_test)) {
-        IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
-    }
+    IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s4);
     }
@@ -1446,17 +1405,8 @@ void emit_shld32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
         STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
     }
     IFX(X_OF) {
-        if (BOX64ENV(dynarec_test)) {
-            CMPSw_U12(s5, 1);
-            EORx_REG_LSR(s3, s4, s1, rex.w?63:31);   // OF is set if sign changed
-            CSELw(s3, s3, xZR, cEQ);
-            BFIw(xFlags, s3, F_OF, 1);
-        } else {
-            // CMPSw_U12(s5, 1);
-            EORx_REG_LSR(s3, s4, s1, rex.w?63:31);   // OF is set if sign changed
-        //    CSELw(s3, s3, xZR, cEQ);
-            BFIw(xFlags, s3, F_OF, 1);
-        }
+        EORx_REG_LSR(s3, s4, s1, rex.w?63:31);   // OF is set if sign changed
+        BFIw(xFlags, s3, F_OF, 1);
     }
     int need_tst = 0;
     IFX(X_ZF) need_tst = 1;
@@ -1474,9 +1424,7 @@ void emit_shld32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
             BFIx(xFlags, s4, F_SF, 1);
         }
     }
-    if (BOX64ENV(dynarec_test)) {
-        IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
-    }
+    IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s4);
     }
@@ -1505,9 +1453,7 @@ void emit_shrd16c(dynarec_arm_t* dyn, int ninst, int s1, int s2, uint32_t c, int
         BFXILw(xFlags, s1, c-1, 1);    // set CF
     }
     IFX(X_OF) {
-        if(c==1) {
-            LSRw(s4, s1, 15);
-        }
+        LSRw(s4, s1, 15);
     }
     RORw(s1, s1, c);
     IFX(X_PEND) {
@@ -1515,15 +1461,10 @@ void emit_shrd16c(dynarec_arm_t* dyn, int ninst, int s1, int s2, uint32_t c, int
     }
     COMP_ZFSF(s1, 16)
     IFX(X_OF) {
-        if(c==1) {
-            EORx_REG_LSR(s3, s4, s1, 15);   // OF is set if sign changed
-            BFIw(xFlags, s3, F_OF, 1);
-        }
-    }
-    if (BOX64ENV(dynarec_test)) {
-        IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
-        IFX2(X_OF, && (c>1)) {BFCw(xFlags, F_OF, 1);}
+        EORx_REG_LSR(s3, s4, s1, 15);   // OF is set if sign changed
+        BFIw(xFlags, s3, F_OF, 1);
     }
+    IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s4);
     }
@@ -1554,19 +1495,11 @@ void emit_shrd16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s5, int s3,
         STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
     }
     IFX(X_OF) {
-        if (BOX64ENV(dynarec_test)) {
-            CMPSw_U12(s5, 1);
-            EORw_REG_LSR(s3, s4, s1, 15);   // OF is set if sign changed
-            CSELw(s3, s3, xZR, cEQ);
-            BFIw(xFlags, s3, F_OF, 1);
-        } else {
-            // CMPSw_U12(s5, 1);
-            EORw_REG_LSR(s3, s4, s1, 15);   // OF is set if sign changed
-        //    CSELw(s3, s3, xZR, cEQ);
-            BFIw(xFlags, s3, F_OF, 1);
-        }
+        EORw_REG_LSR(s3, s4, s1, 15);   // OF is set if sign changed
+        BFIw(xFlags, s3, F_OF, 1);
     }
     COMP_ZFSF(s1, 16)
+    IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s4);
     }
@@ -1583,17 +1516,8 @@ void emit_shld16c(dynarec_arm_t* dyn, int ninst, int s1, int s2, uint32_t c, int
     } else {
         SET_DFNONE();
     }
-    if(c==0) {
-        IFX(X_OF) {
-            BFCw(xFlags, F_OF, 1);
-        }
-        IFX(X_PEND) {
-            STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
-        }
-        return;
-    }
     BFIw(s1, s2, 16, 16);   // create concat first
-    IFX(X_CF) {
+    IFX2(X_CF, && c) {
         if(c<16)
             LSRw(s3, s1, 16-c);
         else
@@ -1603,22 +1527,18 @@ void emit_shld16c(dynarec_arm_t* dyn, int ninst, int s1, int s2, uint32_t c, int
     IFX(X_OF) {
         LSRw(s4, s1, 15);
     }
-    RORw(s1, s1, 32-c);
+    if(c)
+        RORw(s1, s1, 32-c);
 
     IFX(X_PEND) {
         STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
     }
     COMP_ZFSF(s1, 16)
     IFX(X_OF) {
-        if(c==1) {
-            EORw_REG_LSR(s3, s4, s1, 15);   // OF is set if sign changed
-            BFIw(xFlags, s3, F_OF, 1);
-        }
-    }
-    if (BOX64ENV(dynarec_test)) {
-        IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
-        IFX2(X_OF, && (c>1)) {BFCw(xFlags, F_OF, 1);}
+        EORw_REG_LSR(s3, s4, s1, 15);   // OF is set if sign changed
+        BFIw(xFlags, s3, F_OF, 1);
     }
+    IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s4);
     }
@@ -1652,22 +1572,11 @@ void emit_shld16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s5, int s3,
         STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
     }
     IFX(X_OF) {
-        if (BOX64ENV(dynarec_test)) {
-            CMPSw_U12(s5, 1);
-            EORw_REG_LSR(s3, s4, s1, 15);   // OF is set if sign changed
-            CSELw(s3, s3, xZR, cEQ);
+        EORw_REG_LSR(s3, s4, s1, 15);   // OF is set if sign changed
             BFIw(xFlags, s3, F_OF, 1);
-        } else {
-            // CMPSw_U12(s5, 1);
-            EORw_REG_LSR(s3, s4, s1, 15);   // OF is set if sign changed
-        //    CSELw(s3, s3, xZR, cEQ);
-            BFIw(xFlags, s3, F_OF, 1);
-        }
     }
     COMP_ZFSF(s1, 16)
-    if (BOX64ENV(dynarec_test)) {
-        IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
-    }
+    IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s4);
     }
diff --git a/src/emu/x64primop.c b/src/emu/x64primop.c
index 85abdd07..e1961434 100644
--- a/src/emu/x64primop.c
+++ b/src/emu/x64primop.c
@@ -521,8 +521,7 @@ uint8_t rcl8(x64emu_t *emu, uint8_t d, uint8_t s)
 		CONDITIONAL_SET_FLAG(cf, F_CF);
         /* OVERFLOW is set *IFF* cnt==1, then it is the 
            xor of CF and the most significant bit.  Blecck. */
-		if(cnt == 1)
-        	CONDITIONAL_SET_FLAG((cf ^ (res >> 7)) & 0x1, F_OF);
+		CONDITIONAL_SET_FLAG((cf ^ (res >> 7)) & 0x1, F_OF);
 
     }
 	return (uint8_t)res;
@@ -544,8 +543,7 @@ uint16_t rcl16(x64emu_t *emu, uint16_t d, uint8_t s)
 			res |= 1 << (cnt - 1);
 		}
 		CONDITIONAL_SET_FLAG(cf, F_CF);
-		if(cnt == 1)
-        	CONDITIONAL_SET_FLAG((cf ^ (res >> 15)) & 0x1, F_OF);
+		CONDITIONAL_SET_FLAG((cf ^ (res >> 15)) & 0x1, F_OF);
 	}
 	return (uint16_t)res;
 }
@@ -566,10 +564,7 @@ uint32_t rcl32(x64emu_t *emu, uint32_t d, uint8_t s)
 			res |= 1 << (cnt - 1);
 		}
 		CONDITIONAL_SET_FLAG(cf, F_CF);
-		if(cnt == 1)
-        	CONDITIONAL_SET_FLAG((cf ^ (res >> 31)) & 0x1, F_OF);
-		else
-			CLEAR_FLAG(F_OF);	// UND, but clear for dynarec_test
+		CONDITIONAL_SET_FLAG((cf ^ (res >> 31)) & 0x1, F_OF);
 	}
 	return res;
 }
@@ -590,10 +585,7 @@ uint64_t rcl64(x64emu_t *emu, uint64_t d, uint8_t s)
 			res |= 1LL << (cnt - 1);
 		}
 		CONDITIONAL_SET_FLAG(cf, F_CF);
-		if(cnt == 1)
-        	CONDITIONAL_SET_FLAG((cf ^ (res >> 63)) & 0x1, F_OF);
-		else
-			CLEAR_FLAG(F_OF);	// UND, but clear for dynarec_test
+		CONDITIONAL_SET_FLAG((cf ^ (res >> 63)) & 0x1, F_OF);
 	}
 	return res;
 }
@@ -634,7 +626,13 @@ uint8_t rcr8(x64emu_t *emu, uint8_t d, uint8_t s)
 	if ((cnt = s % 9) != 0) {
         /* extract the new CARRY FLAG. */
         /* CF <-  b_(n-1)              */
-        if (cnt == 1) {
+		ocf = ACCESS_FLAG(F_CF) != 0;
+		/* OVERFLOW is set *IFF* cnt==1, then it is the 
+		xor of CF and the most significant bit.  Blecck. */
+		/* parenthesized... */
+		CONDITIONAL_SET_FLAG((ocf ^ (d >> 7)) & 0x1,
+							 F_OF);
+		if (cnt == 1) {
             cf = d & 0x1;
             /* note hackery here.  Access_flag(..) evaluates to either
                0 if flag not set
@@ -643,12 +641,6 @@ uint8_t rcr8(x64emu_t *emu, uint8_t d, uint8_t s)
 			   0..1 in any representation of the flags register
                (i.e. packed bit array or unpacked.)
              */
-			ocf = ACCESS_FLAG(F_CF) != 0;
-			/* OVERFLOW is set *IFF* cnt==1, then it is the 
-			xor of CF and the most significant bit.  Blecck. */
-			/* parenthesized... */
-			CONDITIONAL_SET_FLAG((ocf ^ (d >> 7)) & 0x1,
-								 F_OF);
         } else
             cf = (d >> (cnt - 1)) & 0x1;
 
@@ -691,11 +683,11 @@ uint16_t rcr16(x64emu_t *emu, uint16_t d, uint8_t s)
 	/* rotate right through carry */
 	res = d;
 	if ((cnt = s % 17) != 0) {
+		ocf = ACCESS_FLAG(F_CF) != 0;
+		CONDITIONAL_SET_FLAG((ocf ^ (d >> 15)) & 0x1,
+							 F_OF);
 		if (cnt == 1) {
 			cf = d & 0x1;
-			ocf = ACCESS_FLAG(F_CF) != 0;
-			CONDITIONAL_SET_FLAG((ocf ^ (d >> 15)) & 0x1,
-								 F_OF);
 		} else
 			cf = (d >> (cnt - 1)) & 0x1;
 		mask = (1 << (16 - cnt)) - 1;
@@ -719,14 +711,13 @@ uint32_t rcr32(x64emu_t *emu, uint32_t d, uint8_t s)
 	/* rotate right through carry */
 	res = d;
 	if ((cnt = s) != 0) {
+		ocf = ACCESS_FLAG(F_CF) != 0;
+		CONDITIONAL_SET_FLAG((ocf ^ (d >> 31)) & 0x1,
+							 F_OF);
 		if (cnt == 1) {
 			cf = d & 0x1;
-			ocf = ACCESS_FLAG(F_CF) != 0;
-			CONDITIONAL_SET_FLAG((ocf ^ (d >> 31)) & 0x1,
-								 F_OF);
 		} else {
 			cf = (d >> (cnt - 1)) & 0x1;
-			CLEAR_FLAG(F_OF);	// UND, but clear for dynarec_test
 		}
 		mask = (1 << (32 - cnt)) - 1;
 		res = (d >> cnt) & mask;
@@ -750,14 +741,13 @@ uint64_t rcr64(x64emu_t *emu, uint64_t d, uint8_t s)
 	/* rotate right through carry */
 	res = d;
 	if ((cnt = s) != 0) {
+		ocf = ACCESS_FLAG(F_CF) != 0;
+		CONDITIONAL_SET_FLAG((ocf ^ (d >> 63)) & 0x1,
+							 F_OF);
 		if (cnt == 1) {
 			cf = d & 0x1;
-			ocf = ACCESS_FLAG(F_CF) != 0;
-			CONDITIONAL_SET_FLAG((ocf ^ (d >> 63)) & 0x1,
-								 F_OF);
 		} else {
 			cf = (d >> (cnt - 1)) & 0x1;
-			CLEAR_FLAG(F_OF);	// UND, but clear for dynarec_test
 		}
 		mask = (1LL << (64 - cnt)) - 1;
 		res = (d >> cnt) & mask;