about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_0f.c38
-rw-r--r--src/dynarec/arm64/dynarec_arm64_660f.c42
2 files changed, 64 insertions, 16 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c
index 7850393d..5df3ba2d 100644
--- a/src/dynarec/arm64/dynarec_arm64_0f.c
+++ b/src/dynarec/arm64/dynarec_arm64_0f.c
@@ -2321,11 +2321,17 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             break;

         case 0xBC:

             INST_NAME("BSF Gd, Ed");

-            SETFLAGS(X_ZF, SF_SET);

+            if(!BOX64ENV(dynarec_safeflags) || BOX64ENV(cputype)) {

+                SETFLAGS(X_ZF, SF_SUBSET);

+            } else {

+                SETFLAGS(X_ALL, SF_SET);

+            }

             SET_DFNONE();

             nextop = F8;

             GETED(0);

             GETGD;

+            if(ed!=gd)

+                MOVxw_REG(gd, ed);  // to handle ed=0, setting UD gd to 0

             IFX(X_ZF) {

                 TSTxw_REG(ed, ed);

                 B_MARK(cEQ);

@@ -2337,18 +2343,31 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             MARK;

             IFX(X_ZF) {

                 IFNATIVE(NF_EQ) {} else {

-                    CSETw(x1, cEQ);    //other flags are undefined

-                    BFIw(xFlags, x1, F_ZF, 1);

+                    CSETw(x2, cEQ);    //other flags are undefined

+                    BFIw(xFlags, x2, F_ZF, 1);

                 }

             }

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

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

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

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

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

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

+            }

             break;

         case 0xBD:

             INST_NAME("BSR Gd, Ed");

-            SETFLAGS(X_ZF, SF_SET);

+            if(!BOX64ENV(dynarec_safeflags) || BOX64ENV(cputype)) {

+                SETFLAGS(X_ZF, SF_SUBSET);

+            } else {

+                SETFLAGS(X_ALL, SF_SET);

+            }

             SET_DFNONE();

             nextop = F8;

             GETED(0);

             GETGD;

+            if(ed!=gd)

+                MOVxw_REG(gd, ed);  // to handle ed=0, setting UD gd to 0

             IFX(X_ZF) {

                 TSTxw_REG(ed, ed);

                 B_MARK(cEQ);

@@ -2361,10 +2380,17 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             MARK;

             IFX(X_ZF) {

                 IFNATIVE(NF_EQ) {} else {

-                    CSETw(x1, cEQ);    //other flags are undefined

-                    BFIw(xFlags, x1, F_ZF, 1);

+                    CSETw(x2, cEQ);    //other flags are undefined

+                    BFIw(xFlags, x2, F_ZF, 1);

                 }

             }

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

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

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

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

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

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

+            }

             break;

         case 0xBE:

             INST_NAME("MOVSX Gd, Eb");

diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c
index cc9a6d63..40d9f7f3 100644
--- a/src/dynarec/arm64/dynarec_arm64_660f.c
+++ b/src/dynarec/arm64/dynarec_arm64_660f.c
@@ -2742,7 +2742,11 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             break;

         case 0xBC:

             INST_NAME("BSF Gw,Ew");

-            SETFLAGS(X_ZF, SF_SUBSET);

+            if(!BOX64ENV(dynarec_safeflags) || BOX64ENV(cputype)) {

+                SETFLAGS(X_ZF, SF_SUBSET);

+            } else {

+                SETFLAGS(X_ALL, SF_SET);

+            }

             SET_DFNONE();

             nextop = F8;

             GETGD;

@@ -2754,19 +2758,30 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                 CBZw_MARK(x1);

             }

             RBITw(x1, x1);   // reverse

-            CLZw(x2, x1);    // x2 gets leading 0 == BSF

-            BFIx(gd, x2, 0, 16);

+            CLZw(x1, x1);    // x2 gets leading 0 == BSF

             MARK;

+            BFIx(gd, x1, 0, 16);

             IFX(X_ZF) {

                 IFNATIVE(NF_EQ) {} else {

-                    CSETw(x1, cEQ);    //ZF not set

-                    BFIw(xFlags, x1, F_ZF, 1);

+                    CSETw(x2, cEQ);    //ZF not set

+                    BFIw(xFlags, x2, F_ZF, 1);

                 }

             }

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

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

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

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

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

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

+            }

             break;

         case 0xBD:

             INST_NAME("BSR Gw,Ew");

-            SETFLAGS(X_ZF, SF_SUBSET);

+            if(!BOX64ENV(dynarec_safeflags) || BOX64ENV(cputype)) {

+                SETFLAGS(X_ZF, SF_SUBSET);

+            } else {

+                SETFLAGS(X_ALL, SF_SET);

+            }

             SET_DFNONE();

             nextop = F8;

             GETGD;

@@ -2780,15 +2795,22 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             LSLw(x1, x1, 16);   // put bits on top

             CLZw(x2, x1);       // x2 gets leading 0

             SUBw_U12(x2, x2, 15);

-            NEGw_REG(x2, x2);   // complement

-            BFIx(gd, x2, 0, 16);

+            NEGw_REG(x1, x2);   // complement

             MARK;

+            BFIx(gd, x1, 0, 16);

             IFX(X_ZF) {

                 IFNATIVE(NF_EQ) {} else {

-                    CSETw(x1, cEQ);    //ZF not set

-                    BFIw(xFlags, x1, F_ZF, 1);

+                    CSETw(x2, cEQ);    //ZF not set

+                    BFIw(xFlags, x2, F_ZF, 1);

                 }

             }

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

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

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

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

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

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

+            }

             break;

         case 0xBE:

             INST_NAME("MOVSX Gw, Eb");