diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-05 10:42:40 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-05 10:42:40 +0100 |
| commit | 3da0e6c633352d2105e8758e482b2e8689894df9 (patch) | |
| tree | 80f9479ded151c1f79102aa216ba0c99bba1be53 /src | |
| parent | 57730a4b14da3efe73ba312e5371c08797282877 (diff) | |
| download | box64-3da0e6c633352d2105e8758e482b2e8689894df9.tar.gz box64-3da0e6c633352d2105e8758e482b2e8689894df9.zip | |
Added REX 0F AF IMUL opcodes
Diffstat (limited to 'src')
| -rwxr-xr-x | src/emu/x64primop.h | 23 | ||||
| -rwxr-xr-x | src/emu/x64run.c | 2 | ||||
| -rw-r--r-- | src/emu/x64run0f.c | 15 | ||||
| -rwxr-xr-x | src/emu/x64run_private.h | 2 |
4 files changed, 37 insertions, 5 deletions
diff --git a/src/emu/x64primop.h b/src/emu/x64primop.h index 377ae9aa..2b018548 100755 --- a/src/emu/x64primop.h +++ b/src/emu/x64primop.h @@ -544,6 +544,29 @@ static inline void imul32_eax(x64emu_t *emu, uint32_t s) emu->op1 = R_EDX; } +static inline void imul64_direct(uint64_t *res_lo, uint64_t* res_hi,uint64_t d, uint64_t s) +{ + __int128 res = (__int128)(int64_t)d * (int64_t)s; + + *res_lo = (uint64_t)res; + *res_hi = (uint64_t)(res >> 64); +} + +static inline uint64_t imul64(x64emu_t *emu, uint64_t op1, uint64_t op2) +{ + emu->df = d_imul64; + imul64_direct(&emu->res,&emu->op1,op1,op2); + return emu->res; +} + +static inline void imul64_eax(x64emu_t *emu, uint64_t s) +{ + emu->df = d_imul64; + imul64_direct(&R_RAX,&R_RDX,R_RAX,s); + emu->res = R_RAX; + emu->op1 = R_RDX; +} + static inline void mul8(x64emu_t *emu, uint8_t s) { emu->df = d_mul8; diff --git a/src/emu/x64run.c b/src/emu/x64run.c index af256e93..4031ec69 100755 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -141,7 +141,7 @@ x64emurun: GO(0x00, add) /* ADD 0x00 -> 0x05 */ GO(0x08, or) /* OR 0x08 -> 0x0D */ case 0x0F: /* More instructions */ - if(Run0F(emu)) { + if(Run0F(emu, rex)) { unimp = 1; goto fini; } diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c index c084d1ec..a46e488e 100644 --- a/src/emu/x64run0f.c +++ b/src/emu/x64run0f.c @@ -43,12 +43,11 @@ #define EB oped #define GB oped->byte[0] -int Run0F(x64emu_t *emu) +int Run0F(x64emu_t *emu, rex_t rex) { uint8_t opcode; uint8_t nextop; reg64_t *oped, *opgd; - rex_t rex = {0}; opcode = F8; while(opcode>=0x40 && opcode<=0x4f) { @@ -61,12 +60,22 @@ int Run0F(x64emu_t *emu) case 0x05: /* SYSCALL */ x64Syscall(emu); break; - + case 0x1F: /* NOP (multi-byte) */ nextop = F8; GETED; break; + case 0xAF: /* IMUL Gd,Ed */ + nextop = F8; + GETED; + GETGD; + if(rex.w) + GD->q[0] = imul64(emu, GD->q[0], ED->q[0]); + else + GD->dword[0] = imul32(emu, GD->dword[0], ED->dword[0]); + break; + default: return 1; } diff --git a/src/emu/x64run_private.h b/src/emu/x64run_private.h index 69ae17ff..e797c71f 100755 --- a/src/emu/x64run_private.h +++ b/src/emu/x64run_private.h @@ -227,7 +227,7 @@ void UpdateFlags(x64emu_t *emu); #define RESET_FLAGS(emu) emu->df = d_none //void Run67(x64emu_t *emu); -int Run0F(x64emu_t *emu); +int Run0F(x64emu_t *emu, rex_t rex); //void Run660F(x64emu_t *emu); //void Run66D9(x64emu_t *emu); // x87 //void Run6766(x64emu_t *emu); |