about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-02-17 17:46:03 +0100
committerptitSeb <sebastien.chev@gmail.com>2025-02-17 17:46:03 +0100
commit049cbd3783cf079a27fa5c871d69272e945f60bd (patch)
tree904b80736e1c13326aa1ae9a44668f24ba7648a1 /src
parent8b5b5aa3a7690746688496d9cbbeae729290f2b2 (diff)
downloadbox64-049cbd3783cf079a27fa5c871d69272e945f60bd.tar.gz
box64-049cbd3783cf079a27fa5c871d69272e945f60bd.zip
[ARM64_DYNAREC] More work on UD flags
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c130
-rw-r--r--src/dynarec/arm64/dynarec_arm64_0f.c2
-rw-r--r--src/dynarec/arm64/dynarec_arm64_64.c74
-rw-r--r--src/dynarec/arm64/dynarec_arm64_66.c74
-rw-r--r--src/dynarec/arm64/dynarec_arm64_67.c74
-rw-r--r--src/emu/x64primop.c28
6 files changed, 224 insertions, 158 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index 8bef8bc8..30fd5f6b 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -3521,7 +3521,11 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     break;
                 case 4:
                     INST_NAME("MUL AL, Eb");
-                    SETFLAGS(X_ALL, SF_SET);
+                    if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {
+                        SETFLAGS(X_OF|X_CF, SF_SET);
+                    } else {
+                        SETFLAGS(X_ALL, SF_SET);
+                    }
                     GETEB(x1, 0);
                     UXTBw(x2, xRAX);
                     MULw(x1, x2, x1);
@@ -3537,16 +3541,17 @@ 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);
-                        }
+                    IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
+                    IFX2(X_ZF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
+                    IFX2(X_SF, && !BOX64ENV(cputype)) {
+                        LSRxw(x3, xRAX, 7);
+                        BFIw(xFlags, x3, F_SF, 1);
+                    }
+                    IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, xRAX, x3);
                     break;
                 case 5:
                     INST_NAME("IMUL AL, Eb");
-                    if(BOX64ENV(dynarec_safeflags)>1 && BOX64ENV(cputype)) {
+                    if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {
                         SETFLAGS(X_OF|X_CF, SF_SET);
                     } else {
                         SETFLAGS(X_ALL, SF_SET);
@@ -3570,7 +3575,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
                     IFX2(X_ZF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
                     IFX2(X_SF, && !BOX64ENV(cputype)) {
-                        LSRxw(x3, xRAX, 15);
+                        LSRxw(x3, xRAX, 7);
                         BFIw(xFlags, x3, F_SF, 1);
                     }
                     IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, xRAX, x3);
@@ -3595,16 +3600,24 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     BFIx(xRAX, x3, 0, 8);
                     BFIx(xRAX, x4, 8, 8);
                     SET_DFNONE();
-                    IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
-                        if (BOX64ENV(dynarec_test)) {
-                            MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF));
-                            BICw(xFlags, xFlags, x1);
-                        }
+                    IFX(X_OF)                         {BFCw(xFlags, F_OF, 1);}
+                    IFX(X_CF)                         {BFCw(xFlags, F_CF, 1);}
+                    IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
+                    IFX2(X_AF, && BOX64ENV(cputype))  {ORRw_mask(xFlags, xFlags, 28, 0);}   //mask=0x10
+                    IFX2(X_ZF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 26, 0);}   //mask=0x40
+                    IFX2(X_ZF, && BOX64ENV(cputype))  {BFCw(xFlags, F_ZF, 1);}
+                    IFX(X_SF)                         {BFCw(xFlags, F_SF, 1);}
+                    IFX2(X_PF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 30, 0);}   //mask=0x04
+                    IFX2(X_PF, && BOX64ENV(cputype))  {BFCw(xFlags, F_PF, 1);}
                     break;
                 case 7:
                     INST_NAME("IDIV Eb");
                     SKIPTEST(x1);
-                    SETFLAGS(X_ALL, SF_SET);
+                    if(!BOX64ENV(dynarec_safeflags)) {
+                        SETFLAGS(X_ALL, SF_SET);
+                    } else if(BOX64ENV(cputype)) {
+                        SETFLAGS(X_SF|X_PF|X_ZF|X_AF, SF_SET);
+                    }
                     GETSEB(x1, 0);
                     if(BOX64ENV(dynarec_div0)) {
                         CBNZw_MARK3(ed);
@@ -3621,12 +3634,13 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     MSUBw(x4, x3, ed, x2);  // x4 = x2 mod ed (i.e. x2 - x3*ed)
                     BFIx(xRAX, x3, 0, 8);
                     BFIx(xRAX, x4, 8, 8);
-                    SET_DFNONE();
-                    IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
-                        if (BOX64ENV(dynarec_test)) {
-                            MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF));
-                            BICw(xFlags, xFlags, x1);
-                        }
+                    if(!BOX64ENV(dynarec_safeflags)) {
+                        SET_DFNONE();
+                    }
+                    IFX2(X_AF, && BOX64ENV(cputype))  {ORRw_mask(xFlags, xFlags, 28, 0);}   //mask=0x10
+                    IFX2(X_ZF, && BOX64ENV(cputype))  {BFCw(xFlags, F_ZF, 1);}
+                    IFX2(X_SF, && BOX64ENV(cputype))  {BFCw(xFlags, F_SF, 1);}
+                    IFX2(X_PF, && BOX64ENV(cputype))  {BFCw(xFlags, F_PF, 1);}
                     break;
             }
             break;
@@ -3656,7 +3670,11 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     break;
                 case 4:
                     INST_NAME("MUL EAX, Ed");
-                    SETFLAGS(X_ALL, SF_SET);
+                    if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {
+                        SETFLAGS(X_OF|X_CF, SF_SET);
+                    } else {
+                        SETFLAGS(X_ALL, SF_SET);
+                    }
                     GETED(0);
                     if(rex.w) {
                         if(ed==xRDX) gd=x3; else gd=xRDX;
@@ -3668,29 +3686,28 @@ 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_U12(xRDX, 0);
-                            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_U12(xRDX, 0);
+                        CSETw(x3, cNE);
+                        IFX(X_CF) {
+                            BFIw(xFlags, x3, F_CF, 1);
+                        }
+                        IFX(X_OF) {
+                            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);
-                            }
                     }
+                    IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
+                    IFX2(X_ZF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
+                    IFX2(X_SF, && !BOX64ENV(cputype)) {
+                        LSRxw(x3, xRAX, rex.w?63:31);
+                        BFIw(xFlags, x3, F_SF, 1);
+                    }
+                    IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, xRAX, x3);
                     break;
                 case 5:
                     INST_NAME("IMUL EAX, Ed");
-                    if(BOX64ENV(dynarec_safeflags)>1 && BOX64ENV(cputype)) {
+                    if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {
                         SETFLAGS(X_OF|X_CF, SF_SET);
                     } else {
                         SETFLAGS(X_ALL, SF_SET);
@@ -3804,16 +3821,24 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         }
                     }
                     SET_DFNONE();
-                    IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
-                        if (BOX64ENV(dynarec_test)) {
-                            MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF));
-                            BICw(xFlags, xFlags, x1);
-                        }
+                    IFX(X_OF)                         {BFCw(xFlags, F_OF, 1);}
+                    IFX(X_CF)                         {BFCw(xFlags, F_CF, 1);}
+                    IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
+                    IFX2(X_AF, && BOX64ENV(cputype))  {ORRw_mask(xFlags, xFlags, 28, 0);}   //mask=0x10
+                    IFX2(X_ZF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 26, 0);}   //mask=0x40
+                    IFX2(X_ZF, && BOX64ENV(cputype))  {BFCw(xFlags, F_ZF, 1);}
+                    IFX(X_SF)                         {BFCw(xFlags, F_SF, 1);}
+                    IFX2(X_PF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 30, 0);}   //mask=0x04
+                    IFX2(X_PF, && BOX64ENV(cputype))  {BFCw(xFlags, F_PF, 1);}
                     break;
                 case 7:
                     INST_NAME("IDIV Ed");
                     SKIPTEST(x1);
-                    SETFLAGS(X_ALL, SF_SET);
+                    if(!BOX64ENV(dynarec_safeflags)) {
+                        SETFLAGS(X_ALL, SF_SET);
+                    } else if(BOX64ENV(cputype)) {
+                        SETFLAGS(X_SF|X_PF|X_ZF|X_AF, SF_SET);
+                    }
                     if(!rex.w) {
                         GETSEDw(0);
                         if(BOX64ENV(dynarec_div0)) {
@@ -3881,12 +3906,13 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             MOVx_REG(xRAX, x2);
                         }
                     }
-                    SET_DFNONE();
-                    IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
-                        if (BOX64ENV(dynarec_test)) {
-                            MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF));
-                            BICw(xFlags, xFlags, x1);
-                        }
+                    if(!BOX64ENV(dynarec_safeflags)) {
+                        SET_DFNONE();
+                    }
+                    IFX2(X_AF, && BOX64ENV(cputype))  {ORRw_mask(xFlags, xFlags, 28, 0);}   //mask=0x10
+                    IFX2(X_ZF, && BOX64ENV(cputype))  {BFCw(xFlags, F_ZF, 1);}
+                    IFX2(X_SF, && BOX64ENV(cputype))  {BFCw(xFlags, F_SF, 1);}
+                    IFX2(X_PF, && BOX64ENV(cputype))  {BFCw(xFlags, F_PF, 1);}
                     break;
             }
             break;
diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c
index 5a0c1882..cda0cfc8 100644
--- a/src/dynarec/arm64/dynarec_arm64_0f.c
+++ b/src/dynarec/arm64/dynarec_arm64_0f.c
@@ -1996,7 +1996,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             break;

         case 0xAF:

             INST_NAME("IMUL Gd, Ed");

-            if(BOX64ENV(dynarec_safeflags)>1 && BOX64ENV(cputype)) {

+            if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {

                 SETFLAGS(X_OF|X_CF, SF_SET);

             } else {

                 SETFLAGS(X_ALL, SF_SET);

diff --git a/src/dynarec/arm64/dynarec_arm64_64.c b/src/dynarec/arm64/dynarec_arm64_64.c
index ee1d22f1..6c50e374 100644
--- a/src/dynarec/arm64/dynarec_arm64_64.c
+++ b/src/dynarec/arm64/dynarec_arm64_64.c
@@ -1334,7 +1334,11 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     break;
                 case 4:
                     INST_NAME("MUL EAX, Ed");
-                    SETFLAGS(X_ALL, SF_SET);
+                    if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {
+                        SETFLAGS(X_OF|X_CF, SF_SET);
+                    } else {
+                        SETFLAGS(X_ALL, SF_SET);
+                    }
                     GETEDO(x6, 0);
                     if(rex.w) {
                         if(ed==xRDX) gd=x3; else gd=xRDX;
@@ -1346,29 +1350,28 @@ 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) {
-                            CMPSxw_U12(xRDX, 0);
-                            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_U12(xRDX, 0);
+                        CSETw(x3, cNE);
+                        IFX(X_CF) {
+                            BFIw(xFlags, x3, F_CF, 1);
+                        }
+                        IFX(X_OF) {
+                            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);
-                            }
                     }
+                    IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
+                    IFX2(X_ZF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
+                    IFX2(X_SF, && !BOX64ENV(cputype)) {
+                        LSRxw(x3, xRAX, rex.w?63:31);
+                        BFIw(xFlags, x3, F_SF, 1);
+                    }
+                    IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, xRAX, x3);
                     break;
                 case 5:
                     INST_NAME("IMUL EAX, Ed");
-                    if(BOX64ENV(dynarec_safeflags)>1 && BOX64ENV(cputype)) {
+                    if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {
                         SETFLAGS(X_OF|X_CF, SF_SET);
                     } else {
                         SETFLAGS(X_ALL, SF_SET);
@@ -1471,16 +1474,24 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         }
                     }
                     SET_DFNONE();
-                    IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
-                        if (BOX64ENV(dynarec_test)) {
-                            MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF));
-                            BICw(xFlags, xFlags, x1);
-                        }
+                    IFX(X_OF)                         {BFCw(xFlags, F_OF, 1);}
+                    IFX(X_CF)                         {BFCw(xFlags, F_CF, 1);}
+                    IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
+                    IFX2(X_AF, && BOX64ENV(cputype))  {ORRw_mask(xFlags, xFlags, 28, 0);}   //mask=0x10
+                    IFX2(X_ZF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 26, 0);}   //mask=0x40
+                    IFX2(X_ZF, && BOX64ENV(cputype))  {BFCw(xFlags, F_ZF, 1);}
+                    IFX(X_SF)                         {BFCw(xFlags, F_SF, 1);}
+                    IFX2(X_PF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 30, 0);}   //mask=0x04
+                    IFX2(X_PF, && BOX64ENV(cputype))  {BFCw(xFlags, F_PF, 1);}
                     break;
                 case 7:
                     INST_NAME("IDIV Ed");
                     NOTEST(x1);
-                    SETFLAGS(X_ALL, SF_SET);
+                    if(!BOX64ENV(dynarec_safeflags)) {
+                        SETFLAGS(X_ALL, SF_SET);
+                    } else if(BOX64ENV(cputype)) {
+                        SETFLAGS(X_SF|X_PF|X_ZF|X_AF, SF_SET);
+                    }
                     if(!rex.w) {
                         GETSEDOw(x6, 0);
                         MOVw_REG(x3, xRAX);
@@ -1542,12 +1553,13 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             MOVx_REG(xRAX, x2);
                         }
                     }
-                    SET_DFNONE();
-                    IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
-                        if (BOX64ENV(dynarec_test)) {
-                            MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF));
-                            BICw(xFlags, xFlags, x1);
-                        }
+                    if(!BOX64ENV(dynarec_safeflags)) {
+                        SET_DFNONE();
+                    }
+                    IFX2(X_AF, && BOX64ENV(cputype))  {ORRw_mask(xFlags, xFlags, 28, 0);}   //mask=0x10
+                    IFX2(X_ZF, && BOX64ENV(cputype))  {BFCw(xFlags, F_ZF, 1);}
+                    IFX2(X_SF, && BOX64ENV(cputype))  {BFCw(xFlags, F_SF, 1);}
+                    IFX2(X_PF, && BOX64ENV(cputype))  {BFCw(xFlags, F_PF, 1);}
                     break;
             }
             break;
diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c
index b0dc2160..8fa366ef 100644
--- a/src/dynarec/arm64/dynarec_arm64_66.c
+++ b/src/dynarec/arm64/dynarec_arm64_66.c
@@ -1436,35 +1436,38 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     break;

                 case 4:

                     INST_NAME("MUL AX, Ew");

-                    SETFLAGS(X_ALL, SF_SET);

+                    if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {

+                        SETFLAGS(X_OF|X_CF, SF_SET);

+                    } else {

+                        SETFLAGS(X_ALL, SF_SET);

+                    }

                     GETEW(x1, 0);

                     UXTHw(x2, xRAX);

                     MULw(x1, x2, x1);

                     BFIz(xRAX, x1, 0, 16);

                     BFXILx(xRDX, x1, 16, 16);

-                    UFLAG_IF {

-                        SET_DFNONE();

-                        IFX(X_CF|X_OF) {

-                            CMPSw_REG_LSR(xZR, x1, 16);

-                            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) {

+                        CMPSw_REG_LSR(xZR, x1, 16);

+                        CSETw(x3, cNE);

+                        IFX(X_CF) {

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

+                        }

+                        IFX(X_OF) {

+                            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);

-                            }

                     }

+                    IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}

+                    IFX2(X_ZF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}

+                    IFX2(X_SF, && !BOX64ENV(cputype)) {

+                        LSRxw(x3, xRAX, 15);

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

+                    }

+                    IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, xRAX, x3);

                     break;

                 case 5:

                     INST_NAME("IMUL AX, Ew");

-                    if(BOX64ENV(dynarec_safeflags)>1 && BOX64ENV(cputype)) {

+                    if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {

                         SETFLAGS(X_OF|X_CF, SF_SET);

                     } else {

                         SETFLAGS(X_ALL, SF_SET);

@@ -1515,16 +1518,24 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     BFIz(xRAX, x3, 0, 16);

                     BFIz(xRDX, x4, 0, 16);

                     SET_DFNONE();

-                    IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)

-                        if (BOX64ENV(dynarec_test)) {

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

-                            BICw(xFlags, xFlags, x1);

-                        }

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

+                    IFX(X_CF)                         {BFCw(xFlags, F_CF, 1);}

+                    IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}

+                    IFX2(X_AF, && BOX64ENV(cputype))  {ORRw_mask(xFlags, xFlags, 28, 0);}   //mask=0x10

+                    IFX2(X_ZF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 26, 0);}   //mask=0x40

+                    IFX2(X_ZF, && BOX64ENV(cputype))  {BFCw(xFlags, F_ZF, 1);}

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

+                    IFX2(X_PF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 30, 0);}   //mask=0x04

+                    IFX2(X_PF, && BOX64ENV(cputype))  {BFCw(xFlags, F_PF, 1);}

                     break;

                 case 7:

                     INST_NAME("IDIV Ew");

                     SKIPTEST(x1);

-                    SETFLAGS(X_ALL, SF_SET);

+                    if(!BOX64ENV(dynarec_safeflags)) {

+                        SETFLAGS(X_ALL, SF_SET);

+                    } else if(BOX64ENV(cputype)) {

+                        SETFLAGS(X_SF|X_PF|X_ZF|X_AF, SF_SET);

+                    }

                     GETSEW(x1, 0);

                     if(BOX64ENV(dynarec_div0)) {

                         CBNZw_MARK3(ed);

@@ -1542,12 +1553,13 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     MSUBw(x4, x3, ed, x2);  // x4 = x2 mod ed (i.e. x2 - x3*ed)

                     BFIz(xRAX, x3, 0, 16);

                     BFIz(xRDX, x4, 0, 16);

-                    SET_DFNONE();

-                    IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)

-                        if (BOX64ENV(dynarec_test)) {

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

-                            BICw(xFlags, xFlags, x1);

-                        }

+                    if(!BOX64ENV(dynarec_safeflags)) {

+                        SET_DFNONE();

+                    }

+                    IFX2(X_AF, && BOX64ENV(cputype))  {ORRw_mask(xFlags, xFlags, 28, 0);}   //mask=0x10

+                    IFX2(X_ZF, && BOX64ENV(cputype))  {BFCw(xFlags, F_ZF, 1);}

+                    IFX2(X_SF, && BOX64ENV(cputype))  {BFCw(xFlags, F_SF, 1);}

+                    IFX2(X_PF, && BOX64ENV(cputype))  {BFCw(xFlags, F_PF, 1);}

                     break;

             }

             break;

diff --git a/src/dynarec/arm64/dynarec_arm64_67.c b/src/dynarec/arm64/dynarec_arm64_67.c
index 810a3a33..36180f02 100644
--- a/src/dynarec/arm64/dynarec_arm64_67.c
+++ b/src/dynarec/arm64/dynarec_arm64_67.c
@@ -1466,7 +1466,11 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     break;

                 case 4:

                     INST_NAME("MUL EAX, Ed");

-                    SETFLAGS(X_ALL, SF_SET);

+                    if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {

+                        SETFLAGS(X_OF|X_CF, SF_SET);

+                    } else {

+                        SETFLAGS(X_ALL, SF_SET);

+                    }

                     GETED32(0);

                     if(rex.w) {

                         if(ed==xRDX) gd=x3; else gd=xRDX;

@@ -1478,29 +1482,28 @@ 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_U12(xRDX, 0);

-                            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_U12(xRDX, 0);

+                        CSETw(x3, cNE);

+                        IFX(X_CF) {

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

+                        }

+                        IFX(X_OF) {

+                            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);

-                            }

                     }

+                    IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}

+                    IFX2(X_ZF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}

+                    IFX2(X_SF, && !BOX64ENV(cputype)) {

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

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

+                    }

+                    IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, xRAX, x3);

                     break;

                 case 5:

                     INST_NAME("IMUL EAX, Ed");

-                    if(BOX64ENV(dynarec_safeflags)>1 && BOX64ENV(cputype)) {

+                    if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {

                         SETFLAGS(X_OF|X_CF, SF_SET);

                     } else {

                         SETFLAGS(X_ALL, SF_SET);

@@ -1572,16 +1575,24 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         }

                     }

                     SET_DFNONE();

-                    IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)

-                        if (BOX64ENV(dynarec_test)) {

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

-                            BICw(xFlags, xFlags, x1);

-                        }

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

+                    IFX(X_CF)                         {BFCw(xFlags, F_CF, 1);}

+                    IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}

+                    IFX2(X_AF, && BOX64ENV(cputype))  {ORRw_mask(xFlags, xFlags, 28, 0);}   //mask=0x10

+                    IFX2(X_ZF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 26, 0);}   //mask=0x40

+                    IFX2(X_ZF, && BOX64ENV(cputype))  {BFCw(xFlags, F_ZF, 1);}

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

+                    IFX2(X_PF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 30, 0);}   //mask=0x04

+                    IFX2(X_PF, && BOX64ENV(cputype))  {BFCw(xFlags, F_PF, 1);}

                     break;

                 case 7:

                     INST_NAME("IDIV Ed");

                     NOTEST(x1);

-                    SETFLAGS(X_ALL, SF_SET);

+                    if(!BOX64ENV(dynarec_safeflags)) {

+                        SETFLAGS(X_ALL, SF_SET);

+                    } else if(BOX64ENV(cputype)) {

+                        SETFLAGS(X_SF|X_PF|X_ZF|X_AF, SF_SET);

+                    }

                     if(!rex.w) {

                         GETSED32w(0);

                         MOVw_REG(x3, xRAX);

@@ -1613,12 +1624,13 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             MOVx_REG(xRAX, x2);

                         }

                     }

-                    SET_DFNONE();

-                    IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)

-                        if (BOX64ENV(dynarec_test)) {

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

-                            BICw(xFlags, xFlags, x1);

-                        }

+                    if(!BOX64ENV(dynarec_safeflags)) {

+                        SET_DFNONE();

+                    }

+                    IFX2(X_AF, && BOX64ENV(cputype))  {ORRw_mask(xFlags, xFlags, 28, 0);}   //mask=0x10

+                    IFX2(X_ZF, && BOX64ENV(cputype))  {BFCw(xFlags, F_ZF, 1);}

+                    IFX2(X_SF, && BOX64ENV(cputype))  {BFCw(xFlags, F_SF, 1);}

+                    IFX2(X_PF, && BOX64ENV(cputype))  {BFCw(xFlags, F_PF, 1);}

                     break;

             }

             break;

diff --git a/src/emu/x64primop.c b/src/emu/x64primop.c
index 9c1f2865..8a17da5a 100644
--- a/src/emu/x64primop.c
+++ b/src/emu/x64primop.c
@@ -521,9 +521,12 @@ 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. */
-		CONDITIONAL_SET_FLAG((cf ^ (res >> 7)) & 0x1, F_OF);
-
-    }
+		if(BOX64ENV(cputype))
+		   CONDITIONAL_SET_FLAG((cf ^ (res >> 7)) & 0x1, F_OF);
+	   else
+		   CONDITIONAL_SET_FLAG((XOR2(d >> 6)), F_OF);
+    } else if(s && BOX64ENV(cputype))
+		CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (res >> 7)) & 0x1, F_OF);
 	return (uint8_t)res;
 }
 
@@ -547,7 +550,8 @@ uint16_t rcl16(x64emu_t *emu, uint16_t d, uint8_t s)
 			CONDITIONAL_SET_FLAG((cf ^ (res >> 15)) & 0x1, F_OF);
 		else
 			CONDITIONAL_SET_FLAG((XOR2(d >> 14)), F_OF);
-	}
+	} else if(s && BOX64ENV(cputype))
+		CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (res >> 15)) & 0x1, F_OF);
 	return (uint16_t)res;
 }
 
@@ -679,9 +683,9 @@ uint8_t rcr8(x64emu_t *emu, uint8_t d, uint8_t s)
         /* set the new carry flag, based on the variable "cf" */
 		CONDITIONAL_SET_FLAG(cf, F_CF);
 
-		if(BOX64ENV(cputype))
-			CONDITIONAL_SET_FLAG((XOR2(res >> 6)), F_OF);
 	}
+	if(s && BOX64ENV(cputype))
+		CONDITIONAL_SET_FLAG((XOR2(res >> 6)), F_OF);
 	return (uint8_t)res;
 }
 
@@ -709,9 +713,9 @@ uint16_t rcr16(x64emu_t *emu, uint16_t d, uint8_t s)
 			res |= 1 << (16 - cnt);
 		}
 		CONDITIONAL_SET_FLAG(cf, F_CF);
-		if(BOX64ENV(cputype))
-			CONDITIONAL_SET_FLAG((XOR2(res >> 14)), F_OF);
 	}
+	if(s && BOX64ENV(cputype))
+		CONDITIONAL_SET_FLAG((XOR2(res >> 14)), F_OF);
 	return (uint16_t)res;
 }
 
@@ -741,9 +745,9 @@ uint32_t rcr32(x64emu_t *emu, uint32_t d, uint8_t s)
 			res |= 1 << (32 - cnt);
 		}
 		CONDITIONAL_SET_FLAG(cf, F_CF);
-		if(BOX64ENV(cputype))
-			CONDITIONAL_SET_FLAG((XOR2(res >> 30)), F_OF);
 	}
+	if(s && BOX64ENV(cputype))
+		CONDITIONAL_SET_FLAG((XOR2(res >> 30)), F_OF);
 	return res;
 }
 
@@ -773,9 +777,9 @@ uint64_t rcr64(x64emu_t *emu, uint64_t d, uint8_t s)
 			res |= 1LL << (64 - cnt);
 		}
 		CONDITIONAL_SET_FLAG(cf, F_CF);
-		if(BOX64ENV(cputype))
-			CONDITIONAL_SET_FLAG((XOR2(res >> 62)), F_OF);
 	}
+	if(s && BOX64ENV(cputype))
+		CONDITIONAL_SET_FLAG((XOR2(res >> 62)), F_OF);
 	return res;
 }
 /****************************************************************************