about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-04-27 17:37:44 +0200
committerptitSeb <sebastien.chev@gmail.com>2025-04-27 17:37:44 +0200
commitb552de33f98a573a1548372e970bf5c7a3bf1849 (patch)
tree93051adcfce57f2c7cead228846e12bae73a2faf /src
parent35c8beb15faa3e99390fabc2afdba575b5d5bf43 (diff)
downloadbox64-b552de33f98a573a1548372e970bf5c7a3bf1849.tar.gz
box64-b552de33f98a573a1548372e970bf5c7a3bf1849.zip
[ARM64_DYNAREC] Some work on UD flags on (66) F3 0F BC/BD opcodes
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");