about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-20 22:22:16 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-03-20 22:22:16 +0100
commit12de3807997e8f3b8c484a082e941a383adf8432 (patch)
treec00a51790e8c6111c93e93a29d75a693358888ec /src
parent89a3c359a632995db02b7481c029a1e98e997003 (diff)
downloadbox64-12de3807997e8f3b8c484a082e941a383adf8432.tar.gz
box64-12de3807997e8f3b8c484a082e941a383adf8432.zip
[DYNAREC] Added (66) 0F AF IMUL opcode
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/dynarec_arm64_0f.c32
-rwxr-xr-xsrc/dynarec/dynarec_arm64_660f.c12
-rwxr-xr-xsrc/dynarec/dynarec_arm64_helper.h2
-rwxr-xr-xsrc/emu/x64run_private.c2
4 files changed, 47 insertions, 1 deletions
diff --git a/src/dynarec/dynarec_arm64_0f.c b/src/dynarec/dynarec_arm64_0f.c
index 4694db51..28e8f7cc 100755
--- a/src/dynarec/dynarec_arm64_0f.c
+++ b/src/dynarec/dynarec_arm64_0f.c
@@ -238,6 +238,38 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             WBACK;

             break;

 

+        case 0xAF:

+            INST_NAME("IMUL Gd, Ed");

+            SETFLAGS(X_ALL, SF_PENDING);

+            nextop = F8;

+            GETGD;

+            GETED(0);

+            if(rex.w) {

+                // 64bits imul

+                UFLAG_IF {

+                    SMULH(x3, gd, ed);

+                    MULx(gd, gd, ed);

+                    UFLAG_OP1(x3);

+                    UFLAG_RES(gd);

+                    UFLAG_DF(x3, d_imul64);

+                } else {

+                    MULxw(gd, gd, ed);

+                }

+            } else {

+                // 32bits imul

+                UFLAG_IF {

+                    SMULL(gd, gd, ed);

+                    UFLAG_RES(gd);

+                    LSRx(x3, gd, 32);

+                    UFLAG_OP1(x3);

+                    UFLAG_DF(x3, d_imul32);

+                    MOVw_REG(gd, gd);

+                } else {

+                    MULxw(gd, gd, ed);

+                }

+            }

+            break;

+

         case 0xB3:

             INST_NAME("BTR Ed, Gd");

             SETFLAGS(X_CF, SF_SET);

diff --git a/src/dynarec/dynarec_arm64_660f.c b/src/dynarec/dynarec_arm64_660f.c
index b768af74..8f077871 100755
--- a/src/dynarec/dynarec_arm64_660f.c
+++ b/src/dynarec/dynarec_arm64_660f.c
@@ -134,6 +134,18 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             EWBACKW(x1);

             break;

 

+        case 0xAF:

+            INST_NAME("IMUL Gw,Ew");

+            SETFLAGS(X_ALL, SF_PENDING);

+            nextop = F8;

+            UFLAG_DF(x1, d_imul16);

+            GETSEW(x1, 0);

+            GETSGW(x2);

+            MULw(x2, x2, x1);

+            UFLAG_RES(x2);

+            GWBACK;

+            break;

+

         case 0xB3:

             INST_NAME("BTR Ew, Gw");

             SETFLAGS(X_CF, SF_SET);

diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h
index 5384e67a..1206858c 100755
--- a/src/dynarec/dynarec_arm64_helper.h
+++ b/src/dynarec/dynarec_arm64_helper.h
@@ -99,6 +99,8 @@
                 }
 // GETGW extract x64 register in gd, that is i
 #define GETGW(i) gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3); UXTHw(i, gd); gd = i;
+// GETGW extract x64 register in gd, that is i, Signed extented
+#define GETSGW(i) gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3); SXTHw(i, gd); gd = i;
 //GETEWW will use i for ed, and can use w for wback.
 #define GETEWW(w, i, D) if(MODREG) {        \
                     wback = xRAX+(nextop&7)+(rex.b<<3);\
diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c
index 429f766d..2c54b3dc 100755
--- a/src/emu/x64run_private.c
+++ b/src/emu/x64run_private.c
@@ -276,7 +276,7 @@ void UpdateFlags(x64emu_t *emu)
                 SET_FLAG(F_CF);
                 SET_FLAG(F_OF);
             }
-            CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF);
+            CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF);
             break;
         case d_imul64:
             if (((emu->res.u64 & 0x8000000000000000LL) == 0 && emu->op1.u64 == 0x00) ||