about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-11-07 15:03:55 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-11-07 15:03:55 +0100
commit2473bb69025c7b88eca3bf3496037278126ac613 (patch)
treec680e7760faa14961e35fc932f37f5c9b87ab1b4 /src
parentda0e153a055dde5c7b6fa0eaa79095b0ffdca518 (diff)
downloadbox64-2473bb69025c7b88eca3bf3496037278126ac613.tar.gz
box64-2473bb69025c7b88eca3bf3496037278126ac613.zip
Added 64/65 69 opcode ([ARM64_DYNAREC] too)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_64.c73
-rw-r--r--src/emu/x64run64.c11
2 files changed, 84 insertions, 0 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_64.c b/src/dynarec/arm64/dynarec_arm64_64.c
index bf30e5ff..09576603 100644
--- a/src/dynarec/arm64/dynarec_arm64_64.c
+++ b/src/dynarec/arm64/dynarec_arm64_64.c
@@ -488,6 +488,79 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             }
             break;
 
+        case 0x69:
+            INST_NAME("IMUL Gd, Ed, Id");
+            SETFLAGS(X_ALL, SF_SET_PENDING);
+            nextop = F8;
+            grab_segdata(dyn, addr, ninst, x4, seg);
+            GETGD;
+            GETEDO(x4, 4);
+            i64 = F32S;
+            MOV64xw(x4, i64);
+            if(rex.w) {
+                // 64bits imul
+                UFLAG_IF {
+                    SMULH(x3, ed, x4);
+                    MULx(gd, ed, x4);
+                    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);
+                }
+            } else {
+                // 32bits imul
+                UFLAG_IF {
+                    SMULL(gd, ed, x4);
+                    LSRx(x3, gd, 32);
+                    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);
+                }
+            }
+            break;
+
         case 0x6C:
         case 0x6D:
             INST_NAME(opcode == 0x6C ? "INSB" : "INSD");
diff --git a/src/emu/x64run64.c b/src/emu/x64run64.c
index 2a5d59fd..c3960e83 100644
--- a/src/emu/x64run64.c
+++ b/src/emu/x64run64.c
@@ -466,6 +466,17 @@ uintptr_t Run64(x64emu_t *emu, rex_t rex, int seg, uintptr_t addr)
             else

                 return 0;

 

+        case 0x69:                      /* IMUL Gd,Ed,Id */

+            nextop = F8;

+            GETED_OFFS(4, tlsdata);

+            GETGD;

+            tmp64u = F32S64;

+            if(rex.w)

+                GD->q[0] = imul64(emu, ED->q[0], tmp64u);

+            else

+                GD->q[0] = imul32(emu, ED->dword[0], tmp64u);

+            break;

+

         case 0x6C:                      /* INSB DX */

         case 0x6D:                      /* INSD DX */

         case 0x6E:                      /* OUTSB DX */