about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-03-02 17:31:47 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-03-02 17:31:47 +0100
commitb72d3a77e91b4a80576c97b3da5cae34ef072c2d (patch)
treeb4f548ace11fd7a48ff3e043c65fff54119ec154 /src
parent64fdf541561d9c8858e2498ef18587c00964ee17 (diff)
downloadbox64-b72d3a77e91b4a80576c97b3da5cae34ef072c2d.tar.gz
box64-b72d3a77e91b4a80576c97b3da5cae34ef072c2d.zip
[ARM64_DYNAREC] More fixes and optim on IMUL flags
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c57
-rw-r--r--src/dynarec/arm64/dynarec_arm64_0f.c5
2 files changed, 49 insertions, 13 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index 527c21ba..20c15e26 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -862,10 +862,10 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 // 32bits imul
                 UFLAG_IF {
                     SMULL(gd, ed, x4);
-                    UFLAG_RES(gd);
                     LSRx(x3, gd, 32);
                     MOVw_REG(gd, gd);
                     IFX(X_PEND) {
+                        UFLAG_RES(gd);
                         UFLAG_OP1(x3);
                         UFLAG_DF(x1, d_imul32);
                     } else {
@@ -876,10 +876,9 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         BICw(xFlags, xFlags, x1);
                     }
                     IFX(X_CF | X_OF) {
-                        ASRw(x3, x3, 31);
                         ASRw(x4, gd, 31);
                         CMPSw_REG(x3, x4);
-                        CSETw(x3, cNE);
+                        CSETw(x1, cNE);
                         IFX(X_CF) {
                             BFIw(xFlags, x1, F_CF, 1);
                         }
@@ -902,7 +901,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             break;
         case 0x6B:
             INST_NAME("IMUL Gd, Ed, Ib");
-            SETFLAGS(X_ALL, SF_PENDING);
+            SETFLAGS(X_ALL, SF_SET_PENDING);
             nextop = F8;
             GETGD;
             GETED(1);
@@ -913,9 +912,28 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 UFLAG_IF {
                     SMULH(x3, ed, x4);
                     MULx(gd, ed, x4);
-                    UFLAG_OP1(x3);
-                    UFLAG_RES(gd);
-                    UFLAG_DF(x3, d_imul64);
+                    IFX(X_PEND) {
+                        UFLAG_OP1(x3);
+                        UFLAG_RES(gd);
+                        UFLAG_DF(x1, d_imul64);
+                    } else {
+                        SET_DFNONE(x1);
+                    }
+                    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);
+                        CSETw(x1, cNE);
+                        IFX(X_CF) {
+                            BFIw(xFlags, x1, F_CF, 1);
+                        }
+                        IFX(X_OF) {
+                            BFIw(xFlags, x1, F_OF, 1);
+                        }
+                    }
                 } else {
                     MULxw(gd, ed, x4);
                 }
@@ -923,11 +941,30 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 // 32bits imul
                 UFLAG_IF {
                     SMULL(gd, ed, x4);
-                    UFLAG_RES(gd);
                     LSRx(x3, gd, 32);
-                    UFLAG_OP1(x3);
-                    UFLAG_DF(x3, d_imul32);
                     MOVw_REG(gd, gd);
+                    IFX(X_PEND) {
+                        UFLAG_RES(gd);
+                        UFLAG_OP1(x3);
+                        UFLAG_DF(x1, d_imul32);
+                    } else {
+                        SET_DFNONE(x1);
+                    }
+                    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);
+                        CSETw(x1, cNE);
+                        IFX(X_CF) {
+                            BFIw(xFlags, x1, F_CF, 1);
+                        }
+                        IFX(X_OF) {
+                            BFIw(xFlags, x1, F_OF, 1);
+                        }
+                    }
                 } else {
                     MULxw(gd, ed, x4);
                 }
diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c
index 0d857fba..9e4bd704 100644
--- a/src/dynarec/arm64/dynarec_arm64_0f.c
+++ b/src/dynarec/arm64/dynarec_arm64_0f.c
@@ -1847,16 +1847,16 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 // 32bits imul

                 UFLAG_IF {

                     SMULL(gd, gd, ed);

+                    LSRx(x3, gd, 32);

+                    MOVw_REG(gd, gd);

                     IFX(X_PEND) {

                         UFLAG_RES(gd);

-                        LSRx(x3, gd, 32);

                         UFLAG_OP1(x3);

                         UFLAG_DF(x4, d_imul32);

                     } else IFX(X_CF|X_OF) {

                         SET_DFNONE(x4);

                     }

                     IFX(X_CF|X_OF) {

-                        ASRx(x3, gd, 63);

                         ASRw(x4, gd, 31);

                         CMPSw_REG(x3, x4);

                         CSETw(x3, cNE);

@@ -1874,7 +1874,6 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         BFCw(xFlags, F_ZF, 1);

                         BFCw(xFlags, F_SF, 1);

                     }

-                    MOVw_REG(gd, gd);

                 } else {

                     MULxw(gd, gd, ed);

                 }