diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-11-07 15:03:55 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-11-07 15:03:55 +0100 |
| commit | 2473bb69025c7b88eca3bf3496037278126ac613 (patch) | |
| tree | c680e7760faa14961e35fc932f37f5c9b87ab1b4 /src | |
| parent | da0e153a055dde5c7b6fa0eaa79095b0ffdca518 (diff) | |
| download | box64-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.c | 73 | ||||
| -rw-r--r-- | src/emu/x64run64.c | 11 |
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 */ |