mirror of
https://github.com/ptitSeb/box64.git
synced 2024-11-30 13:26:03 +08:00
First x86_64 opcode executed :)
This commit is contained in:
parent
8cccb02e6b
commit
9613868aa4
@ -107,6 +107,7 @@ set(ELFLOADER_SRC
|
||||
"${BOX64_ROOT}/src/emu/x64emu.c"
|
||||
"${BOX64_ROOT}/src/emu/x64int3.c"
|
||||
"${BOX64_ROOT}/src/emu/x87emu_private.c"
|
||||
"${BOX64_ROOT}/src/emu/x64primop.c"
|
||||
"${BOX64_ROOT}/src/emu/x64run.c"
|
||||
"${BOX64_ROOT}/src/emu/x64run_private.c"
|
||||
"${BOX64_ROOT}/src/emu/x64syscall.c"
|
||||
|
1464
src/emu/x64primop.c
Executable file
1464
src/emu/x64primop.c
Executable file
File diff suppressed because it is too large
Load Diff
576
src/emu/x64primop.h
Executable file
576
src/emu/x64primop.h
Executable file
@ -0,0 +1,576 @@
|
||||
#ifndef __X64PRIMOP_H_
|
||||
#define __X64PRIMOP_H_
|
||||
|
||||
typedef struct x64emu_s x64emu_t;
|
||||
|
||||
// Based on libx86emu
|
||||
|
||||
uint16_t aaa16 (x64emu_t *emu, uint16_t d);
|
||||
uint16_t aas16 (x64emu_t *emu, uint16_t d);
|
||||
uint16_t aad16 (x64emu_t *emu, uint16_t d, uint8_t base);
|
||||
uint16_t aam16 (x64emu_t *emu, uint8_t d, uint8_t base);
|
||||
uint8_t adc8 (x64emu_t *emu, uint8_t d, uint8_t s);
|
||||
uint16_t adc16 (x64emu_t *emu, uint16_t d, uint16_t s);
|
||||
uint32_t adc32 (x64emu_t *emu, uint32_t d, uint32_t s);
|
||||
uint64_t adc64 (x64emu_t *emu, uint64_t d, uint64_t s);
|
||||
|
||||
static inline uint8_t add8(x64emu_t *emu, uint8_t d, uint8_t s)
|
||||
{
|
||||
emu->res = d + s;
|
||||
emu->op1 = d;
|
||||
emu->op2 = s;
|
||||
emu->df = d_add8;
|
||||
return (uint8_t)emu->res;
|
||||
}
|
||||
|
||||
static inline uint16_t add16(x64emu_t *emu, uint16_t d, uint16_t s)
|
||||
{
|
||||
emu->res = d + s;
|
||||
emu->op1 = d;
|
||||
emu->op2 = s;
|
||||
emu->df = d_add16;
|
||||
return (uint16_t)emu->res;
|
||||
}
|
||||
|
||||
static inline uint32_t add32(x64emu_t *emu, uint32_t d, uint32_t s)
|
||||
{
|
||||
emu->res = d + s;
|
||||
emu->op1 = d;
|
||||
emu->op2 = s;
|
||||
emu->df = d_add32;
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint64_t add64(x64emu_t *emu, uint64_t d, uint64_t s)
|
||||
{
|
||||
emu->res = d + s;
|
||||
emu->op1 = d;
|
||||
emu->op2 = s;
|
||||
emu->df = d_add64;
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint8_t and8(x64emu_t *emu, uint8_t d, uint8_t s)
|
||||
{
|
||||
emu->res = d & s;
|
||||
emu->df = d_and8;
|
||||
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint16_t and16(x64emu_t *emu, uint16_t d, uint16_t s)
|
||||
{
|
||||
emu->res = d & s;
|
||||
emu->df = d_and16;
|
||||
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint32_t and32(x64emu_t *emu, uint32_t d, uint32_t s)
|
||||
{
|
||||
emu->res = d & s;
|
||||
emu->df = d_and32;
|
||||
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint64_t and64(x64emu_t *emu, uint64_t d, uint64_t s)
|
||||
{
|
||||
emu->res = d & s;
|
||||
emu->df = d_and64;
|
||||
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
uint8_t cmp8 (x64emu_t *emu, uint8_t d, uint8_t s);
|
||||
uint16_t cmp16 (x64emu_t *emu, uint16_t d, uint16_t s);
|
||||
uint32_t cmp32 (x64emu_t *emu, uint32_t d, uint32_t s);
|
||||
uint64_t cmp64 (x64emu_t *emu, uint64_t d, uint64_t s);
|
||||
uint8_t daa8 (x64emu_t *emu, uint8_t d);
|
||||
uint8_t das8 (x64emu_t *emu, uint8_t d);
|
||||
|
||||
static inline uint8_t dec8(x64emu_t *emu, uint8_t d)
|
||||
{
|
||||
emu->res = d - 1;
|
||||
emu->op1 = d;
|
||||
emu->df = d_dec8;
|
||||
return (uint8_t)emu->res;
|
||||
}
|
||||
|
||||
static inline uint16_t dec16(x64emu_t *emu, uint16_t d)
|
||||
{
|
||||
emu->res = d - 1;
|
||||
emu->op1 = d;
|
||||
emu->df = d_dec16;
|
||||
return (uint16_t)emu->res;
|
||||
|
||||
}
|
||||
|
||||
static inline uint32_t dec32(x64emu_t *emu, uint32_t d)
|
||||
{
|
||||
emu->res = d - 1;
|
||||
emu->op1 = d;
|
||||
emu->df = d_dec32;
|
||||
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint64_t dec64(x64emu_t *emu, uint64_t d)
|
||||
{
|
||||
emu->res = d - 1;
|
||||
emu->op1 = d;
|
||||
emu->df = d_dec64;
|
||||
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint8_t inc8(x64emu_t *emu, uint8_t d)
|
||||
{
|
||||
emu->res = d + 1;
|
||||
emu->op1 = d;
|
||||
emu->df = d_inc8;
|
||||
return (uint8_t)emu->res;
|
||||
}
|
||||
|
||||
static inline uint16_t inc16(x64emu_t *emu, uint16_t d)
|
||||
{
|
||||
emu->res = d + 1;
|
||||
emu->op1 = d;
|
||||
emu->df = d_inc16;
|
||||
return (uint16_t)emu->res;
|
||||
}
|
||||
|
||||
static inline uint32_t inc32(x64emu_t *emu, uint32_t d)
|
||||
{
|
||||
if(emu->df == d_shr32) {
|
||||
// workaround for some wine trickery
|
||||
uint32_t cnt = emu->op2;
|
||||
if (cnt > 0) {
|
||||
uint32_t cc = emu->op1 & (1 << (cnt - 1));
|
||||
CONDITIONAL_SET_FLAG(cc, F_CF);
|
||||
}
|
||||
}
|
||||
emu->res = d + 1;
|
||||
emu->op1 = d;
|
||||
emu->df = d_inc32;
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint64_t inc64(x64emu_t *emu, uint64_t d)
|
||||
{
|
||||
if(emu->df == d_shr64) {
|
||||
// workaround for some wine trickery
|
||||
uint64_t cnt = emu->op2;
|
||||
if (cnt > 0) {
|
||||
uint64_t cc = emu->op1 & (1L << (cnt - 1));
|
||||
CONDITIONAL_SET_FLAG(cc, F_CF);
|
||||
}
|
||||
}
|
||||
emu->res = d + 1;
|
||||
emu->op1 = d;
|
||||
emu->df = d_inc64;
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint8_t or8(x64emu_t *emu, uint8_t d, uint8_t s)
|
||||
{
|
||||
emu->res = d | s;
|
||||
emu->df = d_or8;
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint16_t or16(x64emu_t *emu, uint16_t d, uint16_t s)
|
||||
{
|
||||
emu->res = d | s;
|
||||
emu->df = d_or16;
|
||||
/* set the carry flag to be bit 8 */
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint32_t or32(x64emu_t *emu, uint32_t d, uint32_t s)
|
||||
{
|
||||
emu->res = d | s;
|
||||
emu->df = d_or32;
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint64_t or64(x64emu_t *emu, uint64_t d, uint64_t s)
|
||||
{
|
||||
emu->res = d | s;
|
||||
emu->df = d_or64;
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint8_t neg8(x64emu_t *emu, uint8_t s)
|
||||
{
|
||||
emu->res = (uint8_t)-s;
|
||||
emu->op1 = s;
|
||||
emu->df = d_neg8;
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint16_t neg16(x64emu_t *emu, uint16_t s)
|
||||
{
|
||||
emu->res = (uint16_t)-s;
|
||||
emu->op1 = s;
|
||||
emu->df = d_neg16;
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint32_t neg32(x64emu_t *emu, uint32_t s)
|
||||
{
|
||||
emu->res = (uint32_t)-s;
|
||||
emu->op1 = s;
|
||||
emu->df = d_neg32;
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint64_t neg64(x64emu_t *emu, uint64_t s)
|
||||
{
|
||||
emu->res = (uint64_t)-s;
|
||||
emu->op1 = s;
|
||||
emu->df = d_neg64;
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint8_t not8(x64emu_t *emu, uint8_t s)
|
||||
{
|
||||
return ~s;
|
||||
}
|
||||
|
||||
static inline uint16_t not16(x64emu_t *emu, uint16_t s)
|
||||
{
|
||||
return ~s;
|
||||
}
|
||||
|
||||
static inline uint32_t not32(x64emu_t *emu, uint32_t s)
|
||||
{
|
||||
return ~s;
|
||||
}
|
||||
|
||||
static inline uint64_t not64(x64emu_t *emu, uint64_t s)
|
||||
{
|
||||
return ~s;
|
||||
}
|
||||
|
||||
uint8_t rcl8 (x64emu_t *emu, uint8_t d, uint8_t s);
|
||||
uint16_t rcl16 (x64emu_t *emu, uint16_t d, uint8_t s);
|
||||
uint32_t rcl32 (x64emu_t *emu, uint32_t d, uint8_t s);
|
||||
uint64_t rcl64 (x64emu_t *emu, uint64_t d, uint8_t s);
|
||||
uint8_t rcr8 (x64emu_t *emu, uint8_t d, uint8_t s);
|
||||
uint16_t rcr16 (x64emu_t *emu, uint16_t d, uint8_t s);
|
||||
uint32_t rcr32 (x64emu_t *emu, uint32_t d, uint8_t s);
|
||||
uint64_t rcr64 (x64emu_t *emu, uint64_t d, uint8_t s);
|
||||
uint8_t rol8 (x64emu_t *emu, uint8_t d, uint8_t s);
|
||||
uint16_t rol16 (x64emu_t *emu, uint16_t d, uint8_t s);
|
||||
uint32_t rol32 (x64emu_t *emu, uint32_t d, uint8_t s);
|
||||
uint64_t rol64 (x64emu_t *emu, uint64_t d, uint8_t s);
|
||||
uint8_t ror8 (x64emu_t *emu, uint8_t d, uint8_t s);
|
||||
uint16_t ror16 (x64emu_t *emu, uint16_t d, uint8_t s);
|
||||
uint32_t ror32 (x64emu_t *emu, uint32_t d, uint8_t s);
|
||||
uint64_t ror64 (x64emu_t *emu, uint64_t d, uint8_t s);
|
||||
uint16_t shld16 (x64emu_t *emu, uint16_t d, uint16_t fill, uint8_t s);
|
||||
uint32_t shld32 (x64emu_t *emu, uint32_t d, uint32_t fill, uint8_t s);
|
||||
uint64_t shld64 (x64emu_t *emu, uint64_t d, uint64_t fill, uint8_t s);
|
||||
uint16_t shrd16 (x64emu_t *emu, uint16_t d, uint16_t fill, uint8_t s);
|
||||
uint32_t shrd32 (x64emu_t *emu, uint32_t d, uint32_t fill, uint8_t s);
|
||||
uint64_t shrd64 (x64emu_t *emu, uint64_t d, uint64_t fill, uint8_t s);
|
||||
uint8_t sbb8 (x64emu_t *emu, uint8_t d, uint8_t s);
|
||||
uint16_t sbb16 (x64emu_t *emu, uint16_t d, uint16_t s);
|
||||
uint32_t sbb32 (x64emu_t *emu, uint32_t d, uint32_t s);
|
||||
uint64_t sbb64 (x64emu_t *emu, uint64_t d, uint64_t s);
|
||||
|
||||
static inline uint8_t shl8(x64emu_t *emu, uint8_t d, uint8_t s)
|
||||
{
|
||||
emu->df = d_shl8;
|
||||
emu->op1 = d;
|
||||
|
||||
s &= 0x1f;
|
||||
emu->op2 = s;
|
||||
emu->res = d << s;
|
||||
|
||||
return (uint8_t)emu->res;
|
||||
}
|
||||
|
||||
static inline uint16_t shl16(x64emu_t *emu, uint16_t d, uint8_t s)
|
||||
{
|
||||
emu->df = d_shl16;
|
||||
emu->op1 = d;
|
||||
|
||||
s &= 0x1f;
|
||||
emu->op2 = s;
|
||||
emu->res = d << s;
|
||||
return (uint16_t)emu->res;
|
||||
}
|
||||
|
||||
static inline uint32_t shl32(x64emu_t *emu, uint32_t d, uint8_t s)
|
||||
{
|
||||
emu->df = d_shl32;
|
||||
emu->op1 = d;
|
||||
|
||||
s &= 0x1f;
|
||||
emu->op2 = s;
|
||||
emu->res = d << s;
|
||||
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint64_t shl64(x64emu_t *emu, uint64_t d, uint8_t s)
|
||||
{
|
||||
emu->df = d_shl64;
|
||||
emu->op1 = d;
|
||||
|
||||
s &= 0x3f;
|
||||
emu->op2 = s;
|
||||
emu->res = d << s;
|
||||
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint8_t shr8(x64emu_t *emu, uint8_t d, uint8_t s)
|
||||
{
|
||||
emu->df = d_shr8;
|
||||
emu->op1 = d;
|
||||
|
||||
s &= 0x1f;
|
||||
emu->op2 = s;
|
||||
emu->res = d >> s;
|
||||
|
||||
return (uint8_t)emu->res;
|
||||
}
|
||||
|
||||
static inline uint16_t shr16(x64emu_t *emu, uint16_t d, uint8_t s)
|
||||
{
|
||||
emu->df = d_shr16;
|
||||
emu->op1 = d;
|
||||
|
||||
s &= 0x1f;
|
||||
emu->op2 = s;
|
||||
emu->res = d >> s;
|
||||
|
||||
return (uint16_t)emu->res;
|
||||
}
|
||||
|
||||
static inline uint32_t shr32(x64emu_t *emu, uint32_t d, uint8_t s)
|
||||
{
|
||||
RESET_FLAGS(emu); // TODO: Defered this one?
|
||||
|
||||
emu->df = d_shr32;
|
||||
emu->op1 = d;
|
||||
|
||||
s &= 0x1f;
|
||||
emu->op2 = s;
|
||||
emu->res = d >> s;
|
||||
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint64_t shr64(x64emu_t *emu, uint64_t d, uint8_t s)
|
||||
{
|
||||
RESET_FLAGS(emu); // TODO: Defered this one?
|
||||
|
||||
emu->df = d_shr64;
|
||||
emu->op1 = d;
|
||||
|
||||
s &= 0x3f;
|
||||
emu->op2 = s;
|
||||
emu->res = d >> s;
|
||||
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint8_t sar8(x64emu_t *emu, uint8_t d, uint8_t s)
|
||||
{
|
||||
emu->df = d_sar8;
|
||||
emu->op1 = d;
|
||||
|
||||
s &= 0x1f;
|
||||
emu->op2 = s;
|
||||
emu->res = (uint8_t)(((int8_t)d)>>s);
|
||||
|
||||
return (uint8_t)emu->res;
|
||||
}
|
||||
|
||||
static inline uint16_t sar16(x64emu_t *emu, uint16_t d, uint8_t s)
|
||||
{
|
||||
emu->df = d_sar16;
|
||||
emu->op1 = d;
|
||||
|
||||
s &= 0x1f;
|
||||
emu->op2 = s;
|
||||
emu->res = (uint16_t)(((int16_t)d)>>s);
|
||||
|
||||
return (uint16_t)emu->res;
|
||||
}
|
||||
|
||||
static inline uint32_t sar32(x64emu_t *emu, uint32_t d, uint8_t s)
|
||||
{
|
||||
emu->df = d_sar32;
|
||||
emu->op1 = d;
|
||||
|
||||
s &= 0x1f;
|
||||
emu->op2 = s;
|
||||
emu->res = (uint32_t)(((int32_t)d)>>s);
|
||||
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint64_t sar64(x64emu_t *emu, uint64_t d, uint8_t s)
|
||||
{
|
||||
emu->df = d_sar64;
|
||||
emu->op1 = d;
|
||||
|
||||
s &= 0x3f;
|
||||
emu->op2 = s;
|
||||
emu->res = (uint64_t)(((int64_t)d)>>s);
|
||||
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint8_t sub8(x64emu_t *emu, uint8_t d, uint8_t s)
|
||||
{
|
||||
emu->res = d - s;
|
||||
emu->op1 = d;
|
||||
emu->op2 = s;
|
||||
emu->df = d_sub8;
|
||||
return (uint8_t)emu->res;
|
||||
}
|
||||
|
||||
static inline uint16_t sub16(x64emu_t *emu, uint16_t d, uint16_t s)
|
||||
{
|
||||
emu->res = d - s;
|
||||
emu->op1 = d;
|
||||
emu->op2 = s;
|
||||
emu->df = d_sub16;
|
||||
return (uint16_t)emu->res;
|
||||
}
|
||||
|
||||
static inline uint32_t sub32(x64emu_t *emu, uint32_t d, uint32_t s)
|
||||
{
|
||||
emu->res = d - s;
|
||||
emu->op1 = d;
|
||||
emu->op2 = s;
|
||||
emu->df = d_sub32;
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint64_t sub64(x64emu_t *emu, uint64_t d, uint64_t s)
|
||||
{
|
||||
emu->res = d - s;
|
||||
emu->op1 = d;
|
||||
emu->op2 = s;
|
||||
emu->df = d_sub64;
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
void test8 (x64emu_t *emu, uint8_t d, uint8_t s);
|
||||
void test16 (x64emu_t *emu, uint16_t d, uint16_t s);
|
||||
void test32 (x64emu_t *emu, uint32_t d, uint32_t s);
|
||||
void test64 (x64emu_t *emu, uint64_t d, uint64_t s);
|
||||
|
||||
static inline uint8_t xor8(x64emu_t *emu, uint8_t d, uint8_t s)
|
||||
{
|
||||
emu->res = d ^ s;
|
||||
emu->df = d_xor8;
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
|
||||
static inline uint16_t xor16(x64emu_t *emu, uint16_t d, uint16_t s)
|
||||
{
|
||||
emu->res = d ^ s;
|
||||
emu->df = d_xor16;
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint32_t xor32(x64emu_t *emu, uint32_t d, uint32_t s)
|
||||
{
|
||||
emu->res = d ^ s;
|
||||
emu->df = d_xor32;
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline uint64_t xor64(x64emu_t *emu, uint64_t d, uint64_t s)
|
||||
{
|
||||
emu->res = d ^ s;
|
||||
emu->df = d_xor64;
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline void imul8(x64emu_t *emu, uint8_t s)
|
||||
{
|
||||
emu->df = d_imul8;
|
||||
R_AX = emu->res = (int16_t)(int8_t)R_AL * (int8_t)s;
|
||||
}
|
||||
|
||||
static inline void imul16_eax(x64emu_t *emu, uint16_t s)
|
||||
{
|
||||
emu->df = d_imul16;
|
||||
emu->res = (int32_t)(int16_t)R_AX * (int16_t)s;
|
||||
R_AX = (uint16_t)emu->res;
|
||||
R_DX = (uint16_t)(emu->res >> 16);
|
||||
}
|
||||
|
||||
static inline uint16_t imul16(x64emu_t *emu, uint16_t op1, uint16_t op2)
|
||||
{
|
||||
emu->df = d_imul16;
|
||||
emu->res = (int32_t)(int16_t)op1 * (int16_t)op2;
|
||||
return (uint16_t)emu->res;
|
||||
}
|
||||
|
||||
static inline void imul32_direct(uint32_t *res_lo, uint32_t* res_hi,uint32_t d, uint32_t s)
|
||||
{
|
||||
int64_t res = (int64_t)(int32_t)d * (int32_t)s;
|
||||
|
||||
*res_lo = (uint32_t)res;
|
||||
*res_hi = (uint32_t)(res >> 32);
|
||||
}
|
||||
|
||||
static inline uint32_t imul32(x64emu_t *emu, uint32_t op1, uint32_t op2)
|
||||
{
|
||||
emu->df = d_imul32;
|
||||
uint32_t _res, _op1;
|
||||
imul32_direct(&_res,&_op1,op1,op2);
|
||||
emu->res = _res;
|
||||
emu->op1 = _op1;
|
||||
return emu->res;
|
||||
}
|
||||
|
||||
static inline void imul32_eax(x64emu_t *emu, uint32_t s)
|
||||
{
|
||||
emu->df = d_imul32;
|
||||
imul32_direct(&R_EAX,&R_EDX,R_EAX,s);
|
||||
emu->res = R_EAX;
|
||||
emu->op1 = R_EDX;
|
||||
}
|
||||
|
||||
static inline void mul8(x64emu_t *emu, uint8_t s)
|
||||
{
|
||||
emu->df = d_mul8;
|
||||
R_AX = emu->res = (uint16_t)(R_AL) * s;
|
||||
}
|
||||
|
||||
static inline void mul16(x64emu_t *emu, uint16_t s)
|
||||
{
|
||||
emu->df = d_mul16;
|
||||
emu->res = (uint32_t)R_AX * s;
|
||||
R_AX = (uint16_t)emu->res;
|
||||
R_DX = (uint16_t)(emu->res >> 16);
|
||||
}
|
||||
|
||||
static inline void mul32_eax(x64emu_t *emu, uint32_t s)
|
||||
{
|
||||
emu->df = d_mul32;
|
||||
uint64_t res = (uint64_t)R_EAX * s;
|
||||
emu->res = R_EAX = (uint32_t)res;
|
||||
emu->op1 = R_EDX = (uint32_t)(res >> 32);
|
||||
}
|
||||
|
||||
void idiv8 (x64emu_t *emu, uint8_t s);
|
||||
void idiv16 (x64emu_t *emu, uint16_t s);
|
||||
void idiv32 (x64emu_t *emu, uint32_t s);
|
||||
void div8 (x64emu_t *emu, uint8_t s);
|
||||
void div16 (x64emu_t *emu, uint16_t s);
|
||||
void div32 (x64emu_t *emu, uint32_t s);
|
||||
|
||||
#endif //__X64PRIMOP_H_
|
@ -14,7 +14,7 @@
|
||||
#include "x64run.h"
|
||||
#include "x64emu_private.h"
|
||||
#include "x64run_private.h"
|
||||
//#include "x64primop.h"
|
||||
#include "x64primop.h"
|
||||
#include "x64trace.h"
|
||||
#include "x87emu_private.h"
|
||||
#include "box64context.h"
|
||||
@ -68,9 +68,13 @@ int Run(x64emu_t *emu, int step)
|
||||
#endif
|
||||
|
||||
#define GETED oped=GetEd(emu, rex, nextop)
|
||||
#define GETGD opgd=GeG(emu, rex, nextop)
|
||||
#define GETGD opgd=GetGd(emu, rex, nextop)
|
||||
#define GETEB oped=GetEb(emu, rex, nextop)
|
||||
#define GETGB oped=GetGb(emu, rex, nextop)
|
||||
#define ED oped
|
||||
#define GD opgd
|
||||
#define EB oped
|
||||
#define GB oped->byte[0]
|
||||
|
||||
x64emurun:
|
||||
|
||||
@ -95,6 +99,56 @@ x64emurun:
|
||||
|
||||
switch(opcode) {
|
||||
|
||||
#define GO(B, OP) \
|
||||
case B+0: \
|
||||
nextop = F8; \
|
||||
GETEB; \
|
||||
GETGB; \
|
||||
EB->byte[0] = OP##8(emu, EB->byte[0], GB); \
|
||||
break; \
|
||||
case B+1: \
|
||||
nextop = F8; \
|
||||
GETED; \
|
||||
GETGD; \
|
||||
if(rex.w) \
|
||||
ED->q[0] = OP##64(emu, ED->q[0], GD->q[0]); \
|
||||
else \
|
||||
ED->dword[0] = OP##32(emu, ED->dword[0], GD->dword[0]); \
|
||||
break; \
|
||||
case B+2: \
|
||||
nextop = F8; \
|
||||
GETEB; \
|
||||
GETGB; \
|
||||
GB = OP##8(emu, GB, EB->byte[0]); \
|
||||
break; \
|
||||
case B+3: \
|
||||
nextop = F8; \
|
||||
GETED; \
|
||||
GETGD; \
|
||||
if(rex.w) \
|
||||
GD->q[0] = OP##64(emu, GD->q[0], ED->q[0]); \
|
||||
else \
|
||||
GD->dword[0] = OP##32(emu, GD->dword[0], ED->dword[0]); \
|
||||
break; \
|
||||
case B+4: \
|
||||
R_AL = OP##8(emu, R_AL, F8); \
|
||||
break; \
|
||||
case B+5: \
|
||||
if(rex.w) \
|
||||
R_RAX = OP##64(emu, R_RAX, F32); \
|
||||
else \
|
||||
R_EAX = OP##32(emu, R_EAX, F32); \
|
||||
break;
|
||||
|
||||
GO(0x00, add) /* ADD 0x00 -> 0x05 */
|
||||
GO(0x08, or) /* OR 0x08 -> 0x0D */
|
||||
GO(0x10, adc) /* ADC 0x10 -> 0x15 */
|
||||
GO(0x18, sbb) /* SBB 0x18 -> 0x1D */
|
||||
GO(0x20, and) /* AND 0x20 -> 0x25 */
|
||||
GO(0x28, sub) /* SUB 0x28 -> 0x2D */
|
||||
GO(0x30, xor) /* XOR 0x30 -> 0x35 */
|
||||
#undef GO
|
||||
|
||||
case 0x40:
|
||||
case 0x41:
|
||||
case 0x42:
|
||||
|
@ -105,8 +105,12 @@ static inline reg64_t* GetEb(x64emu_t *emu, rex_t rex, uint8_t v)
|
||||
// rex ignored here
|
||||
uint8_t m = v&0xC7; // filter Eb
|
||||
if(m>=0xC0) {
|
||||
int lowhigh = (m&4)>>2;
|
||||
return (reg64_t *)(((char*)(&emu->regs[(m&0x03)]))+lowhigh); //?
|
||||
if(rex.rex) {
|
||||
int lowhigh = (m&4)>>2;
|
||||
return (reg64_t *)(((char*)(&emu->regs[(m&0x03)]))+lowhigh); //?
|
||||
} else {
|
||||
return &emu->regs[(m&0x07)+(rex.x<<4)];
|
||||
}
|
||||
} else return GetECommon(emu, rex, m);
|
||||
}
|
||||
|
||||
@ -114,7 +118,7 @@ static inline reg64_t* GetEd(x64emu_t *emu, rex_t rex, uint8_t v)
|
||||
{
|
||||
uint8_t m = v&0xC7; // filter Ed
|
||||
if(m>=0xC0) {
|
||||
return &emu->regs[(m&0x07)+(rex.b<<4)];
|
||||
return &emu->regs[(m&0x07)+(rex.x<<4)];
|
||||
} else return GetECommon(emu, rex, m);
|
||||
}
|
||||
|
||||
@ -186,12 +190,12 @@ static inline sse_regs_t* GetEx(x64emu_t *emu, rex_t rex, uint8_t v)
|
||||
{
|
||||
uint8_t m = v&0xC7; // filter Ed
|
||||
if(m>=0xC0) {
|
||||
return &emu->xmm[(m&0x07)+(rex.b<<4)];
|
||||
return &emu->xmm[(m&0x07)+(rex.x<<4)];
|
||||
} else return (sse_regs_t*)GetECommon(emu, rex, m);
|
||||
}
|
||||
|
||||
|
||||
static inline reg64_t* GetG(x64emu_t *emu, rex_t rex, uint8_t v)
|
||||
static inline reg64_t* GetGd(x64emu_t *emu, rex_t rex, uint8_t v)
|
||||
{
|
||||
return &emu->regs[((v&0x38)>>3)+(rex.r<<4)];
|
||||
}
|
||||
@ -199,7 +203,10 @@ static inline reg64_t* GetG(x64emu_t *emu, rex_t rex, uint8_t v)
|
||||
static inline reg64_t* GetGb(x64emu_t *emu, rex_t rex, uint8_t v)
|
||||
{
|
||||
uint8_t m = (v&0x38)>>3;
|
||||
return (reg64_t*)&emu->regs[m&3].byte[m>>2];
|
||||
if(rex.rex) {
|
||||
return (reg64_t*)&emu->regs[m&3].byte[m>>2];
|
||||
} else
|
||||
return &emu->regs[(m&7)+(rex.r<<4)];
|
||||
}
|
||||
|
||||
static inline mmx_regs_t* GetGm(x64emu_t *emu, rex_t rex, uint8_t v)
|
||||
@ -214,9 +221,9 @@ static inline sse_regs_t* GetGx(x64emu_t *emu, rex_t rex, uint8_t v)
|
||||
return &emu->xmm[(m&7)+(rex.r<<4)];
|
||||
}
|
||||
|
||||
//void UpdateFlags(x64emu_t *emu);
|
||||
void UpdateFlags(x64emu_t *emu);
|
||||
|
||||
//#define CHECK_FLAGS(emu) if(emu->df) UpdateFlags(emu)
|
||||
#define CHECK_FLAGS(emu) if(emu->df) UpdateFlags(emu)
|
||||
#define RESET_FLAGS(emu) emu->df = d_none
|
||||
|
||||
//void Run67(x64emu_t *emu);
|
||||
@ -240,7 +247,7 @@ uintptr_t GetSegmentBaseEmu(x64emu_t* emu, int seg);
|
||||
#define GetESBaseEmu(emu) GetSegmentBaseEmu(emu, _ES)
|
||||
#define GetDSBaseEmu(emu) GetSegmentBaseEmu(emu, _DS)
|
||||
|
||||
//const char* GetNativeName(void* p);
|
||||
const char* GetNativeName(void* p);
|
||||
|
||||
#ifdef HAVE_TRACE
|
||||
void PrintTrace(x64emu_t* emu, uintptr_t ip, int dynarec);
|
||||
|
Loading…
Reference in New Issue
Block a user