about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-11-13 14:38:14 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-11-13 14:38:14 +0100
commitf66aa575947ce827fc99f694ee74a3509d2c5c00 (patch)
tree432b6f61aee0d8d2fd7c6ec0bc492893a7189aec /src
parent506cb980b10b8850c9a2aaac1e4d97104617ba15 (diff)
downloadbox64-f66aa575947ce827fc99f694ee74a3509d2c5c00.tar.gz
box64-f66aa575947ce827fc99f694ee74a3509d2c5c00.zip
[ARM64_DYNAREC] Improved div/idiv opcode flags (non)handling
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c30
-rw-r--r--src/dynarec/arm64/dynarec_arm64_64.c14
-rw-r--r--src/dynarec/arm64/dynarec_arm64_66.c14
-rw-r--r--src/dynarec/arm64/dynarec_arm64_67.c14
4 files changed, 60 insertions, 12 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index 0e4b22c2..bc0140ce 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -3270,7 +3270,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 6:
                     INST_NAME("DIV Eb");
                     SETFLAGS(X_ALL, SF_SET);
-                    SET_DFNONE(x1);
                     GETEB(x1, 0);
                     UXTHw(x2, xRAX);
                     if(box64_dynarec_div0) {
@@ -3287,12 +3286,17 @@ 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(x2);
+                    IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
+                        if(box64_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);
+                        }
                     break;
                 case 7:
                     INST_NAME("IDIV Eb");
                     SKIPTEST(x1);
                     SETFLAGS(X_ALL, SF_SET);
-                    SET_DFNONE(x1);
                     GETSEB(x1, 0);
                     if(box64_dynarec_div0) {
                         CBNZw_MARK3(ed);
@@ -3309,6 +3313,12 @@ 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(x2);
+                    IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
+                        if(box64_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);
+                        }
                     break;
             }
             break;
@@ -3410,7 +3420,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("DIV Ed");
                     SETFLAGS(X_ALL, SF_SET);
                     if(!rex.w) {
-                        SET_DFNONE(x2);
                         GETED(0);
                         if(ninst && (nextop==0xF0)
                            && dyn->insts[ninst-1].x64.addr
@@ -3449,7 +3458,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                            && dyn->insts[ninst-1].x64.addr
                            && *(uint8_t*)(dyn->insts[ninst-1].x64.addr)==0x31
                            && *(uint8_t*)(dyn->insts[ninst-1].x64.addr+1)==0xD2) {
-                            SET_DFNONE(x2);
                             GETED(0);
                             if(box64_dynarec_div0) {
                                 CBNZx_MARK3(ed);
@@ -3484,15 +3492,19 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             UDIVx(x2, xRAX, ed);
                             MSUBx(xRDX, x2, ed, xRAX);
                             MOVx_REG(xRAX, x2);
-                            SET_DFNONE(x2);
                         }
                     }
+                    SET_DFNONE(x2);
+                    IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
+                        if(box64_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);
+                        }
                     break;
                 case 7:
                     INST_NAME("IDIV Ed");
                     SKIPTEST(x1);
                     SETFLAGS(X_ALL, SF_SET);
-                    SET_DFNONE(x2)
                     if(!rex.w) {
                         GETSEDw(0);
                         if(box64_dynarec_div0) {
@@ -3560,6 +3572,12 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             MOVx_REG(xRAX, x2);
                         }
                     }
+                    SET_DFNONE(x2);
+                    IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
+                        if(box64_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);
+                        }
                     break;
             }
             break;
diff --git a/src/dynarec/arm64/dynarec_arm64_64.c b/src/dynarec/arm64/dynarec_arm64_64.c
index 1fcca3e6..d674c622 100644
--- a/src/dynarec/arm64/dynarec_arm64_64.c
+++ b/src/dynarec/arm64/dynarec_arm64_64.c
@@ -1388,7 +1388,6 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 6:
                     INST_NAME("DIV Ed");
                     SETFLAGS(X_ALL, SF_SET);
-                    SET_DFNONE(x2);
                     if(!rex.w) {
                         GETEDO(x6, 0);
                         if(box64_dynarec_div0) {
@@ -1452,12 +1451,17 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             MOVx_REG(xRAX, x2);
                         }
                     }
+                    SET_DFNONE(x2);
+                    IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
+                        if(box64_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);
+                        }
                     break;
                 case 7:
                     INST_NAME("IDIV Ed");
                     NOTEST(x1);
                     SETFLAGS(X_ALL, SF_SET);
-                    SET_DFNONE(x2)
                     if(!rex.w) {
                         GETSEDOw(x6, 0);
                         MOVw_REG(x3, xRAX);
@@ -1519,6 +1523,12 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             MOVx_REG(xRAX, x2);
                         }
                     }
+                    SET_DFNONE(x2);
+                    IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
+                        if(box64_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);
+                        }
                     break;
             }
             break;
diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c
index 8a270619..ac14430a 100644
--- a/src/dynarec/arm64/dynarec_arm64_66.c
+++ b/src/dynarec/arm64/dynarec_arm64_66.c
@@ -1374,7 +1374,6 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 6:

                     INST_NAME("DIV Ew");

                     SETFLAGS(X_ALL, SF_SET);

-                    SET_DFNONE(x1);

                     GETEW(x1, 0);

                     UXTHw(x2, xRAX);

                     BFIw(x2, xRDX, 16, 16);

@@ -1392,12 +1391,17 @@ 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(x2);

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

+                        if(box64_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);

+                        }

                     break;

                 case 7:

                     INST_NAME("IDIV Ew");

                     SKIPTEST(x1);

                     SETFLAGS(X_ALL, SF_SET);

-                    SET_DFNONE(x1);

                     GETSEW(x1, 0);

                     if(box64_dynarec_div0) {

                         CBNZw_MARK3(ed);

@@ -1415,6 +1419,12 @@ 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(x2);

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

+                        if(box64_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);

+                        }

                     break;

             }

             break;

diff --git a/src/dynarec/arm64/dynarec_arm64_67.c b/src/dynarec/arm64/dynarec_arm64_67.c
index c3df1bf6..b6210534 100644
--- a/src/dynarec/arm64/dynarec_arm64_67.c
+++ b/src/dynarec/arm64/dynarec_arm64_67.c
@@ -1517,7 +1517,6 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 6:

                     INST_NAME("DIV Ed");

                     SETFLAGS(X_ALL, SF_SET);

-                    SET_DFNONE(x2);

                     if(!rex.w) {

                         GETED32(0);

                         MOVw_REG(x3, xRAX);

@@ -1551,12 +1550,17 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             MOVx_REG(xRAX, x2);

                         }

                     }

+                    SET_DFNONE(x2);

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

+                        if(box64_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);

+                        }

                     break;

                 case 7:

                     INST_NAME("IDIV Ed");

                     NOTEST(x1);

                     SETFLAGS(X_ALL, SF_SET);

-                    SET_DFNONE(x2);

                     if(!rex.w) {

                         GETSED32w(0);

                         MOVw_REG(x3, xRAX);

@@ -1588,6 +1592,12 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             MOVx_REG(xRAX, x2);

                         }

                     }

+                    SET_DFNONE(x2);

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

+                        if(box64_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);

+                        }

                     break;

             }

             break;