diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2025-04-14 19:34:43 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-14 13:34:43 +0200 |
| commit | 6b2373af93e033019dd1ddd5683f2d866e253d8c (patch) | |
| tree | d8716018ee1c02a8b4e09e88456d1e2c425d3e40 /src | |
| parent | cf32412f986a5a9c281dda5dc24bf22641a305ed (diff) | |
| download | box64-6b2373af93e033019dd1ddd5683f2d866e253d8c.tar.gz box64-6b2373af93e033019dd1ddd5683f2d866e253d8c.zip | |
[WOW64] Added non-functional PE build (#2532)
Diffstat (limited to 'src')
| -rw-r--r-- | src/elfs/elfloader.c | 27 | ||||
| -rw-r--r-- | src/emu/entrypoint.c | 142 | ||||
| -rw-r--r-- | src/emu/x64emu.c | 980 | ||||
| -rw-r--r-- | src/emu/x64run_private.c | 1180 | ||||
| -rw-r--r-- | src/emu/x64run_private.h | 11 | ||||
| -rw-r--r-- | src/emu/x64test.c | 1 | ||||
| -rw-r--r-- | src/emu/x64tls.c | 33 | ||||
| -rw-r--r-- | src/include/elfloader.h | 2 | ||||
| -rw-r--r-- | src/include/freq.h | 2 | ||||
| -rw-r--r-- | src/include/os.h | 6 | ||||
| -rw-r--r-- | src/include/x64emu.h | 5 | ||||
| -rw-r--r-- | src/include/x64tls.h | 3 | ||||
| -rw-r--r-- | src/os/emit_signal_wine.c | 22 | ||||
| -rw-r--r-- | src/os/freq_wine.c | 2 | ||||
| -rw-r--r-- | src/os/my_cpuid_linux.c (renamed from src/tools/my_cpuid.c) | 0 | ||||
| -rw-r--r-- | src/os/my_cpuid_wine.c | 29 | ||||
| -rw-r--r-- | src/os/os_linux.c | 70 | ||||
| -rw-r--r-- | src/os/os_wine.c | 42 | ||||
| -rw-r--r-- | src/os/perfmap.c (renamed from src/tools/perfmap.c) | 6 |
19 files changed, 1336 insertions, 1227 deletions
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c index c12f29b9..f0ab7320 100644 --- a/src/elfs/elfloader.c +++ b/src/elfs/elfloader.c @@ -1918,3 +1918,30 @@ EXPORT void PltResolver64(x64emu_t* emu) // jmp to function R_RIP = offs; } + +const char* getAddrFunctionName(uintptr_t addr) +{ + static char rets[8][1000]; + static int idx = 0; + char* ret = rets[idx]; + idx = (idx + 1) & 7; + uint64_t sz = 0; + uintptr_t start = 0; + elfheader_t* elf = FindElfAddress(my_context, addr); + const char* symbname = FindNearestSymbolName(elf, (void*)addr, &start, &sz); + if (!sz) sz = 0x100; // arbitrary value... + if (symbname && addr >= start && (addr < (start + sz) || !sz)) { + if (symbname[0] == '\0') + sprintf(ret, "%s + 0x%lx + 0x%lx", ElfName(elf), start - (uintptr_t)GetBaseAddress(elf), addr - start); + else if (addr == start) + sprintf(ret, "%s/%s", ElfName(elf), symbname); + else + sprintf(ret, "%s/%s + 0x%lx", ElfName(elf), symbname, addr - start); + } else { + if (elf) { + sprintf(ret, "%s + 0x%lx", ElfName(elf), addr - (uintptr_t)GetBaseAddress(elf)); + } else + sprintf(ret, "???"); + } + return ret; +} \ No newline at end of file diff --git a/src/emu/entrypoint.c b/src/emu/entrypoint.c new file mode 100644 index 00000000..927ac0d1 --- /dev/null +++ b/src/emu/entrypoint.c @@ -0,0 +1,142 @@ +#include "debug.h" +#include "x64run_private.h" +#include "box64cpu.h" +#include "box64cpu_util.h" +#include "elfloader.h" +#include "box32.h" + +#ifdef ANDROID +void EXPORT my___libc_init(x64emu_t* emu, void* raw_args , void (*onexit)(void) , int (*main)(int, char**, char**), void const * const structors ) +{ + //TODO: register fini + // let's cheat and set all args... + SetRDX(emu, (uintptr_t)my_context->envv); + SetRSI(emu, (uintptr_t)my_context->argv); + SetRDI(emu, (uintptr_t)my_context->argc); + + printf_log(LOG_DEBUG, "Transfert to main(%d, %p, %p)=>%p from __libc_init\n", my_context->argc, my_context->argv, my_context->envv, main); + // should call structors->preinit_array and structors->init_array! + // call main and finish + Push64(emu, GetRBP(emu)); // set frame pointer + SetRBP(emu, GetRSP(emu)); // save RSP + SetRSP(emu, GetRSP(emu)&~0xFLL); // Align RSP + PushExit(emu); + R_RIP=(uintptr_t)main; + + DynaRun(emu); + + SetRSP(emu, GetRBP(emu)); // restore RSP + SetRBP(emu, Pop64(emu)); // restore RBP + emu->quit = 1; // finished! +} +#else +EXPORT int32_t my___libc_start_main(x64emu_t* emu, int (*main) (int, char * *, char * *), int argc, char * * ubp_av, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void (* stack_end)) +{ + (void)argc; (void)ubp_av; (void)fini; (void)rtld_fini; (void)stack_end; + + if(init) { + uintptr_t old_rsp = GetRSP(emu); + uintptr_t old_rbp = GetRBP(emu); // should not be needed, but seems to be without dynarec + Push64(emu, GetRBP(emu)); // set frame pointer + SetRBP(emu, GetRSP(emu)); // save RSP + SetRSP(emu, GetRSP(emu)&~0xFLL); // Align RSP + PushExit(emu); + SetRDX(emu, (uint64_t)my_context->envv); + SetRSI(emu, (uint64_t)my_context->argv); + SetRDI(emu, (uint64_t)my_context->argc); + R_RIP=(uint64_t)*init; + printf_dump(LOG_DEBUG, "Calling init(%p) from __libc_start_main\n", *init); + DynaRun(emu); + if(emu->error) // any error, don't bother with more + return 0; + SetRSP(emu, GetRBP(emu)); // restore RSP + SetRBP(emu, Pop64(emu)); // restore RBP + SetRSP(emu, old_rsp); + SetRBP(emu, old_rbp); + emu->quit = 0; + } else { + if(my_context->elfs[0]) { + printf_dump(LOG_DEBUG, "Calling init from main elf\n"); + RunElfInit(my_context->elfs[0], emu); + } + } + if(my_context->elfs[0]) { + MarkElfInitDone(my_context->elfs[0]); + } + printf_log(LOG_DEBUG, "Transfert to main(%d, %p, %p)=>%p from __libc_start_main\n", my_context->argc, my_context->argv, my_context->envv, main); + // call main and finish + Push64(emu, GetRBP(emu)); // set frame pointer + SetRBP(emu, GetRSP(emu)); // save RSP + SetRSP(emu, GetRSP(emu)&~0xFLL); // Align RSP + PushExit(emu); + SetRDX(emu, (uint64_t)my_context->envv); + SetRSI(emu, (uint64_t)my_context->argv); + SetRDI(emu, (uint64_t)my_context->argc); + R_RIP=(uint64_t)main; + + DynaRun(emu); + + if(!emu->quit) { + SetRSP(emu, GetRBP(emu)); // restore RSP + SetRBP(emu, Pop64(emu)); // restore RBP + emu->quit = 1; // finished! + } + return (int)GetEAX(emu); +} +#ifdef BOX32 +#ifdef ANDROID +void EXPORT my32___libc_init(x64emu_t* emu, void* raw_args , void (*onexit)(void) , int (*main)(int, char**, char**), void const * const structors ) +{ + //TODO: register fini + // let's cheat and set all args... + Push_32(emu, (uint32_t)my_context->envv32); + Push_32(emu, (uint32_t)my_context->argv32); + Push_32(emu, (uint32_t)my_context->argc); + + printf_log(LOG_DEBUG, "Transfert to main(%d, %p, %p)=>%p from __libc_init\n", my_context->argc, my_context->argv, my_context->envv, main); + // should call structors->preinit_array and structors->init_array! + // call main and finish + PushExit_32(emu); + R_EIP=to_ptrv(main); + + DynaRun(emu); + + emu->quit = 1; // finished! +} +#else +int32_t EXPORT my32___libc_start_main(x64emu_t* emu, int *(main) (int, char * *, char * *), int argc, char * * ubp_av, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void (* stack_end)) +{ + // let's cheat and set all args... + Push_32(emu, my_context->envv32); + Push_32(emu, my_context->argv32); + Push_32(emu, my_context->argc); + if(init) { + PushExit_32(emu); + R_EIP=to_ptrv(*init); + printf_log(LOG_DEBUG, "Calling init(%p) from __libc_start_main\n", *init); + DynaRun(emu); + if(emu->error) // any error, don't bother with more + return 0; + emu->quit = 0; + } else { + if(my_context->elfs[0]) { + printf_dump(LOG_DEBUG, "Calling init from main elf\n"); + RunElfInit(my_context->elfs[0], emu); + } + } + if(my_context->elfs[0]) { + MarkElfInitDone(my_context->elfs[0]); + } + printf_log(LOG_DEBUG, "Transfert to main(%d, %p, %p)=>%p from __libc_start_main\n", my_context->argc, my_context->argv, my_context->envv, main); + // call main and finish + PushExit_32(emu); + R_EIP=to_ptrv(main); + + DynaRun(emu); + + emu->quit = 1; // finished! + return 0; +} +#endif +#endif +#endif diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c index c4a90a11..3d3492d0 100644 --- a/src/emu/x64emu.c +++ b/src/emu/x64emu.c @@ -608,3 +608,983 @@ void applyFlushTo0(x64emu_t* emu) #endif #endif } + +#define PARITY(x) (((emu->x64emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0) +#define XOR2(x) (((x) ^ ((x) >> 1)) & 0x1) +void UpdateFlags(x64emu_t* emu) +{ + uint64_t cc; + uint64_t lo, hi; + uint64_t bc; + uint64_t cnt; + + switch (emu->df) { + case d_none: + return; + case d_add8: + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x100, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + cc = (emu->op1.u8 & emu->op2.u8) | ((~emu->res.u8) & (emu->op1.u8 | emu->op2.u8)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + break; + case d_add8b: + CONDITIONAL_SET_FLAG(((uint16_t)emu->op1.u8 + emu->op2.u8) & 0x100, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + cc = (emu->op1.u8 & emu->op2.u8) | ((~emu->res.u8) & (emu->op1.u8 | emu->op2.u8)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + break; + case d_add16: + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x10000, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + cc = (emu->op1.u16 & emu->op2.u16) | ((~emu->res.u16) & (emu->op1.u16 | emu->op2.u16)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + break; + case d_add16b: + CONDITIONAL_SET_FLAG(((uint32_t)emu->op1.u16 + emu->op2.u16) & 0x10000, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + cc = (emu->op1.u16 & emu->op2.u16) | ((~emu->res.u16) & (emu->op1.u16 | emu->op2.u16)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + break; + case d_add32: + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x100000000LL, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + cc = (emu->op1.u32 & emu->op2.u32) | ((~emu->res.u32) & (emu->op1.u32 | emu->op2.u32)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + break; + case d_add32b: + lo = (emu->op2.u32 & 0xFFFF) + (emu->op1.u32 & 0xFFFF); + hi = (lo >> 16) + (emu->op2.u32 >> 16) + (emu->op1.u32 >> 16); + CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + cc = (emu->op1.u32 & emu->op2.u32) | ((~emu->res.u32) & (emu->op1.u32 | emu->op2.u32)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + break; + case d_add64: + lo = (emu->op2.u64 & 0xFFFFFFFF) + (emu->op1.u64 & 0xFFFFFFFF); + hi = (lo >> 32) + (emu->op2.u64 >> 32) + (emu->op1.u64 >> 32); + CONDITIONAL_SET_FLAG(hi & 0x100000000L, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + cc = (emu->op1.u64 & emu->op2.u64) | ((~emu->res.u64) & (emu->op1.u64 | emu->op2.u64)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 62), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + break; + case d_and8: + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + break; + case d_and16: + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + break; + case d_and32: + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + break; + case d_and64: + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(emu->res.u64 == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + break; + case d_dec8: + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + bc = (emu->res.u8 & (~emu->op1.u8 | 1)) | (~emu->op1.u8 & 1); + CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + break; + case d_dec16: + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + bc = (emu->res.u16 & (~emu->op1.u16 | 1)) | (~emu->op1.u16 & 1); + CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + break; + case d_dec32: + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + bc = (emu->res.u32 & (~emu->op1.u32 | 1)) | (~emu->op1.u32 & 1); + CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + break; + case d_dec64: + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + bc = (emu->res.u64 & (~emu->op1.u64 | 1LL)) | (~emu->op1.u64 & 1LL); + CONDITIONAL_SET_FLAG(XOR2(bc >> 62), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + break; + case d_inc8: + CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + cc = ((1 & emu->op1.u8) | (~emu->res.u8)) & (1 | emu->op1.u8); + CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + break; + case d_inc16: + CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + cc = (1 & emu->op1.u16) | ((~emu->res.u16) & (1 | emu->op1.u16)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + break; + case d_inc32: + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + cc = (1 & emu->op1.u32) | ((~emu->res.u32) & (1 | emu->op1.u32)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + break; + case d_inc64: + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + cc = (1LL & emu->op1.u64) | ((~emu->res.u64) & (1LL | emu->op1.u64)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 62), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + break; + case d_imul8: + lo = emu->res.u16 & 0xff; + hi = (emu->res.u16 >> 8) & 0xff; + if (((lo & 0x80) == 0 && hi == 0x00) || ((lo & 0x80) != 0 && hi == 0xFF)) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + if (!BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u8 >> 7) & 1, F_SF); + CLEAR_FLAG(F_ZF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + } + break; + case d_imul16: + lo = (uint16_t)emu->res.u32; + hi = (uint16_t)(emu->res.u32 >> 16); + if (((lo & 0x8000) == 0 && hi == 0x00) || ((lo & 0x8000) != 0 && hi == 0xFFFF)) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + if (!BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u16 >> 15) & 1, F_SF); + CLEAR_FLAG(F_ZF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + } + break; + case d_imul32: + if ((((emu->res.u32 & 0x80000000) == 0) && emu->op1.u32 == 0x00) || (((emu->res.u32 & 0x80000000) != 0) && emu->op1.u32 == 0xFFFFFFFF)) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + if (!BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u32 >> 31) & 1, F_SF); + CLEAR_FLAG(F_ZF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + } + break; + case d_imul64: + if (((emu->res.u64 & 0x8000000000000000LL) == 0 && emu->op1.u64 == 0x00) || ((emu->res.u64 & 0x8000000000000000LL) != 0 && emu->op1.u64 == 0xFFFFFFFFFFFFFFFFLL)) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + if (!BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u64 >> 63) & 1, F_SF); + CLEAR_FLAG(F_ZF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + } + break; + case d_mul8: + hi = (emu->res.u16 >> 8) & 0xff; + if (hi == 0) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + if (!BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u8 >> 7) & 1, F_SF); + CLEAR_FLAG(F_ZF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + } + break; + case d_mul16: + hi = (uint16_t)(emu->res.u32 >> 16); + if (hi == 0) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + if (!BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u16 >> 15) & 1, F_SF); + CLEAR_FLAG(F_ZF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + } + break; + case d_mul32: + if (emu->op1.u32 == 0) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + if (!BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u32 >> 31) & 1, F_SF); + CLEAR_FLAG(F_ZF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + } + break; + case d_mul64: + if (emu->op1.u64 == 0) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + if (!BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u64 >> 63) & 1, F_SF); + CLEAR_FLAG(F_ZF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + } + break; + case d_or8: + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + break; + case d_or16: + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + break; + case d_or32: + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + break; + case d_or64: + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + break; + case d_neg8: + CONDITIONAL_SET_FLAG(emu->op1.u8, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + bc = emu->res.u8 | emu->op1.u8; + CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + break; + case d_neg16: + CONDITIONAL_SET_FLAG(emu->op1.u16, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + bc = emu->res.u16 | emu->op1.u16; + CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + break; + case d_neg32: + CONDITIONAL_SET_FLAG(emu->op1.u32, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + bc = emu->res.u32 | emu->op1.u32; + CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + break; + case d_neg64: + CONDITIONAL_SET_FLAG(emu->op1.u64, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + bc = emu->res.u64 | emu->op1.u64; + CONDITIONAL_SET_FLAG(XOR2(bc >> 62), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + break; + case d_shl8: + cnt = emu->op2.u8 & 0x1f; + if (cnt > 0) { + cc = emu->op1.u8 & (1 << (8 - cnt)); + CONDITIONAL_SET_FLAG(cc, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + if (BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG(((emu->res.u8 >> 7) ^ ACCESS_FLAG(F_CF)) & 0x01, F_OF); + SET_FLAG(F_AF); + } else { + CONDITIONAL_SET_FLAG(XOR2(emu->op1.u8 >> 6), F_OF); + CLEAR_FLAG(F_AF); + } + } + break; + case d_shl16: + cnt = emu->op2.u16 & 0x1f; + if (cnt > 0) { + cc = emu->op1.u16 & (1 << (16 - cnt)); + CONDITIONAL_SET_FLAG(cc, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + if (BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG(((emu->res.u16 >> 15) ^ ACCESS_FLAG(F_CF)) & 0x01, F_OF); + SET_FLAG(F_AF); + } else { + CONDITIONAL_SET_FLAG(XOR2(emu->op1.u16 >> 14), F_OF); + CLEAR_FLAG(F_AF); + } + } + break; + case d_shl32: + cnt = emu->op2.u32 & 0x1f; + if (cnt > 0) { + cc = emu->op1.u32 & (1 << (32 - cnt)); + CONDITIONAL_SET_FLAG(cc, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + if (BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG(((emu->res.u32 >> 31) ^ ACCESS_FLAG(F_CF)) & 0x01, F_OF); + SET_FLAG(F_AF); + } else { + CONDITIONAL_SET_FLAG(XOR2(emu->op1.u32 >> 30), F_OF); + CLEAR_FLAG(F_AF); + } + } + break; + case d_shl64: + if (emu->op2.u64 > 0) { + cc = emu->op1.u64 & (1LL << (64 - emu->op2.u64)); + CONDITIONAL_SET_FLAG(cc, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + if (BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG(((emu->res.u64 >> 63) ^ ACCESS_FLAG(F_CF)) & 0x01, F_OF); + SET_FLAG(F_AF); + } else { + CONDITIONAL_SET_FLAG(XOR2(emu->op1.u64 >> 62), F_OF); + CLEAR_FLAG(F_AF); + } + } + break; + case d_sar8: + if (emu->op2.u8) { + cc = (emu->op1.i8 >> (emu->op2.u8 - 1)) & 1; + CONDITIONAL_SET_FLAG(cc, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CLEAR_FLAG(F_OF); + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else + CLEAR_FLAG(F_AF); + } + break; + case d_sar16: + if (emu->op2.u16) { + cc = (emu->op1.i16 >> (emu->op2.u16 - 1)) & 1; + CONDITIONAL_SET_FLAG(cc, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + CLEAR_FLAG(F_OF); + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else + CLEAR_FLAG(F_AF); + } + break; + case d_sar32: + if (emu->op2.u32) { + cc = emu->op1.u32 & (1 << (emu->op2.u32 - 1)); + CONDITIONAL_SET_FLAG(cc, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + CLEAR_FLAG(F_OF); + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else + CLEAR_FLAG(F_AF); + } + break; + case d_sar64: + if (emu->op2.u64) { + cc = emu->op1.u64 & (1LL << (emu->op2.u64 - 1)); + CONDITIONAL_SET_FLAG(cc, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + CLEAR_FLAG(F_OF); + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else + CLEAR_FLAG(F_AF); + } + break; + case d_shr8: + cnt = emu->op2.u8 & 0x1f; + if (cnt > 0) { + cc = emu->op1.u8 & (1 << (cnt - 1)); + CONDITIONAL_SET_FLAG(cc, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + if (BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u8 >> 6) & 0x1, F_OF); + SET_FLAG(F_AF); + } else { + CONDITIONAL_SET_FLAG((emu->op1.u8 >> 7) & 0x1, F_OF); + CLEAR_FLAG(F_AF); + } + } + break; + case d_shr16: + cnt = emu->op2.u16 & 0x1f; + if (cnt > 0) { + cc = emu->op1.u16 & (1 << (cnt - 1)); + CONDITIONAL_SET_FLAG(cc, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + if (BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u16 >> 14) & 0x1, F_OF); + SET_FLAG(F_AF); + } else { + CONDITIONAL_SET_FLAG((emu->op1.u16 >> 15) & 0x1, F_OF); + CLEAR_FLAG(F_AF); + } + } + if (cnt == 1) { + CONDITIONAL_SET_FLAG(emu->op1.u16 & 0x8000, F_OF); + } + break; + case d_shr32: + cnt = emu->op2.u32 & 0x1f; + if (cnt > 0) { + cc = emu->op1.u32 & (1 << (cnt - 1)); + CONDITIONAL_SET_FLAG(cc, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + if (BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u32 >> 30) & 0x1, F_OF); + SET_FLAG(F_AF); + } else { + CONDITIONAL_SET_FLAG((emu->op1.u32 >> 31) & 0x1, F_OF); + CLEAR_FLAG(F_AF); + } + } + break; + case d_shr64: + cnt = emu->op2.u64; + if (cnt > 0) { + cc = emu->op1.u64 & (1LL << (cnt - 1)); + CONDITIONAL_SET_FLAG(cc, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + if (BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u64 >> 62) & 0x1, F_OF); + SET_FLAG(F_AF); + } else { + CONDITIONAL_SET_FLAG((emu->op1.u64 >> 63) & 0x1, F_OF); + CLEAR_FLAG(F_AF); + } + } + break; + case d_shrd16: + cnt = emu->op2.u16; + if (cnt > 0) { + cc = emu->op1.u16 & (1 << (cnt - 1)); + if (cnt > 15 && BOX64ENV(cputype)) + cc = 0; + CONDITIONAL_SET_FLAG(cc, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + } + if BOX64ENV (cputype) { + CONDITIONAL_SET_FLAG(XOR2(emu->res.u16 >> 14), F_OF); + } else { + CONDITIONAL_SET_FLAG(((emu->res.u16 >> (16 - (cnt & 15))) ^ (emu->op1.u16 >> 15)) & 1, F_OF); + } + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else + CLEAR_FLAG(F_AF); + break; + case d_shrd32: + cnt = emu->op2.u32; + if (cnt > 0) { + cc = emu->op1.u32 & (1 << (cnt - 1)); + CONDITIONAL_SET_FLAG(cc, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + if BOX64ENV (cputype) { + CONDITIONAL_SET_FLAG(XOR2(emu->res.u32 >> 30), F_OF); + } else { + CONDITIONAL_SET_FLAG(((emu->res.u32 >> (32 - cnt)) ^ (emu->op1.u32 >> 31)) & 1, F_OF); + } + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else + CLEAR_FLAG(F_AF); + } + break; + case d_shrd64: + cnt = emu->op2.u64; + if (cnt > 0) { + cc = emu->op1.u64 & (1LL << (cnt - 1)); + CONDITIONAL_SET_FLAG(cc, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + if BOX64ENV (cputype) { + CONDITIONAL_SET_FLAG(XOR2(emu->res.u64 >> 62), F_OF); + } else { + CONDITIONAL_SET_FLAG(((emu->res.u64 >> (64 - cnt)) ^ (emu->op1.u64 >> 63)) & 1, F_OF); + } + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else + CLEAR_FLAG(F_AF); + } + break; + case d_shld16: + cnt = emu->op2.u16; + if (cnt > 0) { + cc = emu->op1.u16 & (1 << (16 - cnt)); + CONDITIONAL_SET_FLAG(cc, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + if BOX64ENV (cputype) { + if (cnt > 15) + CONDITIONAL_SET_FLAG(ACCESS_FLAG(F_CF), F_OF); + else + CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (emu->res.u16 >> 15)) & 1, F_OF); + } else { + CONDITIONAL_SET_FLAG(XOR2(emu->op1.u16 >> 14), F_OF); + } + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else + CLEAR_FLAG(F_AF); + } + break; + case d_shld32: + cnt = emu->op2.u32; + if (cnt > 0) { + cc = emu->op1.u32 & (1 << (32 - cnt)); + CONDITIONAL_SET_FLAG(cc, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + if BOX64ENV (cputype) { + CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (emu->res.u32 >> 31)) & 1, F_OF); + } else { + CONDITIONAL_SET_FLAG(XOR2(emu->op1.u32 >> 30), F_OF); + } + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else + CLEAR_FLAG(F_AF); + } + break; + case d_shld64: + cnt = emu->op2.u64; + if (cnt > 0) { + cc = emu->op1.u64 & (1LL << (64 - cnt)); + CONDITIONAL_SET_FLAG(cc, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + if BOX64ENV (cputype) { + CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (emu->res.u64 >> 63)) & 1, F_OF); + } else { + CONDITIONAL_SET_FLAG(XOR2(emu->op1.u64 >> 62), F_OF); + } + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else + CLEAR_FLAG(F_AF); + } + break; + case d_sub8: + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + bc = (emu->res.u8 & (~emu->op1.u8 | emu->op2.u8)) | (~emu->op1.u8 & emu->op2.u8); + CONDITIONAL_SET_FLAG(bc & 0x80, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + break; + case d_sub16: + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + bc = (emu->res.u16 & (~emu->op1.u16 | emu->op2.u16)) | (~emu->op1.u16 & emu->op2.u16); + CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + break; + case d_sub32: + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + bc = (emu->res.u32 & (~emu->op1.u32 | emu->op2.u32)) | (~emu->op1.u32 & emu->op2.u32); + CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + break; + case d_sub64: + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + bc = (emu->res.u64 & (~emu->op1.u64 | emu->op2.u64)) | (~emu->op1.u64 & emu->op2.u64); + CONDITIONAL_SET_FLAG(bc & 0x8000000000000000LL, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 62), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + break; + case d_xor8: + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + break; + case d_xor16: + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + break; + case d_xor32: + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + break; + case d_xor64: + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + break; + case d_cmp8: + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG((emu->res.u8 & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + bc = (emu->res.u8 & (~emu->op1.u8 | emu->op2.u8)) | (~emu->op1.u8 & emu->op2.u8); + CONDITIONAL_SET_FLAG(bc & 0x80, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + break; + case d_cmp16: + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG((emu->res.u16 & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + bc = (emu->res.u16 & (~emu->op1.u16 | emu->op2.u16)) | (~emu->op1.u16 & emu->op2.u16); + CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + break; + case d_cmp32: + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + bc = (emu->res.u32 & (~emu->op1.u32 | emu->op2.u32)) | (~emu->op1.u32 & emu->op2.u32); + CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + break; + case d_cmp64: + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + bc = (emu->res.u64 & (~emu->op1.u64 | emu->op2.u64)) | (~emu->op1.u64 & emu->op2.u64); + CONDITIONAL_SET_FLAG(bc & 0x8000000000000000LL, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 62), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + break; + case d_tst8: + CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + CLEAR_FLAG(F_CF); + break; + case d_tst16: + CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + CLEAR_FLAG(F_CF); + break; + case d_tst32: + CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + CLEAR_FLAG(F_CF); + break; + case d_tst64: + CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + CLEAR_FLAG(F_CF); + break; + case d_adc8: + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x100, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + cc = (emu->op1.u8 & emu->op2.u8) | ((~emu->res.u8) & (emu->op1.u8 | emu->op2.u8)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + break; + case d_adc16: + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x10000, F_CF); + CONDITIONAL_SET_FLAG((emu->res.u16 & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + cc = (emu->op1.u16 & emu->op2.u16) | ((~emu->res.u16) & (emu->op1.u16 | emu->op2.u16)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + break; + case d_adc32: + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x100000000L, F_CF); + CONDITIONAL_SET_FLAG((emu->res.u32 & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + cc = (emu->op1.u32 & emu->op2.u32) | ((~emu->res.u32) & (emu->op1.u32 | emu->op2.u32)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + break; + case d_adc32b: + if (emu->res.u32 == (emu->op1.u32 + emu->op2.u32)) { + lo = (emu->op1.u32 & 0xFFFF) + (emu->op2.u32 & 0xFFFF); + } else { + lo = 1 + (emu->op1.u32 & 0xFFFF) + (emu->op2.u32 & 0xFFFF); + } + hi = (lo >> 16) + (emu->op1.u32 >> 16) + (emu->op2.u32 >> 16); + CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + cc = (emu->op2.u32 & emu->op1.u32) | ((~emu->res.u32) & (emu->op2.u32 | emu->op1.u32)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + break; + case d_adc64: + if (emu->res.u64 == (emu->op1.u64 + emu->op2.u64)) { + lo = (emu->op1.u64 & 0xFFFFFFFF) + (emu->op2.u64 & 0xFFFFFFFF); + } else { + lo = 1 + (emu->op1.u64 & 0xFFFFFFFF) + (emu->op2.u64 & 0xFFFFFFFF); + } + hi = (lo >> 32) + (emu->op1.u64 >> 32) + (emu->op2.u64 >> 32); + CONDITIONAL_SET_FLAG(hi & 0x100000000L, F_CF); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + cc = (emu->op2.u64 & emu->op1.u64) | ((~emu->res.u64) & (emu->op2.u64 | emu->op1.u64)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 62), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + break; + case d_sbb8: + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + CONDITIONAL_SET_FLAG((emu->res.u8 & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + bc = (emu->res.u8 & (~emu->op1.u8 | emu->op2.u8)) | (~emu->op1.u8 & emu->op2.u8); + CONDITIONAL_SET_FLAG(bc & 0x80, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + break; + case d_sbb16: + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); + CONDITIONAL_SET_FLAG((emu->res.u16 & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + bc = (emu->res.u16 & (~emu->op1.u16 | emu->op2.u16)) | (~emu->op1.u16 & emu->op2.u16); + CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + break; + case d_sbb32: + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + bc = (emu->res.u32 & (~emu->op1.u32 | emu->op2.u32)) | (~emu->op1.u32 & emu->op2.u32); + CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + break; + case d_sbb64: + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); + CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); + bc = (emu->res.u64 & (~emu->op1.u64 | emu->op2.u64)) | (~emu->op1.u64 & emu->op2.u64); + CONDITIONAL_SET_FLAG(bc & 0x8000000000000000LL, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 62), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + break; + case d_rol8: + if (BOX64ENV(cputype)) + CONDITIONAL_SET_FLAG((emu->res.u8 + (emu->res.u8 >> 7)) & 1, F_OF); + else + CONDITIONAL_SET_FLAG(XOR2(emu->op1.u8 >> 6), F_OF); + CONDITIONAL_SET_FLAG(emu->res.u8 & 0x1, F_CF); + break; + case d_rol16: + if (BOX64ENV(cputype)) + CONDITIONAL_SET_FLAG((emu->res.u16 + (emu->res.u16 >> 15)) & 1, F_OF); + else + CONDITIONAL_SET_FLAG(XOR2(emu->op1.u16 >> 14), F_OF); + CONDITIONAL_SET_FLAG(emu->res.u16 & 0x1, F_CF); + break; + case d_rol32: + if (BOX64ENV(cputype)) + CONDITIONAL_SET_FLAG((emu->res.u32 + (emu->res.u32 >> 31)) & 1, F_OF); + else + CONDITIONAL_SET_FLAG(XOR2(emu->op1.u32 >> 30), F_OF); + CONDITIONAL_SET_FLAG(emu->res.u32 & 0x1, F_CF); + break; + case d_rol64: + if (BOX64ENV(cputype)) + CONDITIONAL_SET_FLAG((emu->res.u64 + (emu->res.u64 >> 63)) & 1, F_OF); + else + CONDITIONAL_SET_FLAG(XOR2(emu->op1.u64 >> 62), F_OF); + CONDITIONAL_SET_FLAG(emu->res.u64 & 0x1, F_CF); + break; + case d_ror8: + if (BOX64ENV(cputype)) + CONDITIONAL_SET_FLAG(XOR2(emu->res.u8 >> 6), F_OF); + else + CONDITIONAL_SET_FLAG(((emu->op1.u8 >> 7) ^ emu->op1.u8) & 1, F_OF); + CONDITIONAL_SET_FLAG(emu->res.u8 & (1 << 7), F_CF); + break; + case d_ror16: + if (BOX64ENV(cputype)) + CONDITIONAL_SET_FLAG(XOR2(emu->res.u16 >> 14), F_OF); + else + CONDITIONAL_SET_FLAG(((emu->op1.u16 >> 15) ^ emu->op1.u16) & 1, F_OF); + CONDITIONAL_SET_FLAG(emu->res.u16 & (1 << 15), F_CF); + break; + case d_ror32: + if (BOX64ENV(cputype)) + CONDITIONAL_SET_FLAG(XOR2(emu->res.u32 >> 30), F_OF); + else + CONDITIONAL_SET_FLAG(((emu->op1.u32 >> 31) ^ emu->op1.u32) & 1, F_OF); + CONDITIONAL_SET_FLAG(emu->res.u32 & (1 << 31), F_CF); + break; + case d_ror64: + if (BOX64ENV(cputype)) + CONDITIONAL_SET_FLAG(XOR2(emu->res.u64 >> 62), F_OF); + else + CONDITIONAL_SET_FLAG(((emu->op1.u64 >> 63) ^ emu->op1.u64) & 1, F_OF); + CONDITIONAL_SET_FLAG(emu->res.u64 & (1L << 63), F_CF); + break; + + case d_unknown: + printf_log(LOG_NONE, "%p trying to evaluate Unknown deferred Flags\n", (void*)R_RIP); + break; + } + RESET_FLAGS(emu); +} + +uintptr_t GetSegmentBaseEmu(x64emu_t* emu, int seg) +{ + if (emu->segs_serial[seg] != emu->context->sel_serial) { + emu->segs_offs[seg] = (uintptr_t)GetSegmentBase(emu->segs[seg]); + emu->segs_serial[seg] = emu->context->sel_serial; + } + return emu->segs_offs[seg]; +} diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c index e3760cc0..37a64f4c 100644 --- a/src/emu/x64run_private.c +++ b/src/emu/x64run_private.c @@ -14,11 +14,11 @@ #include "x64emu.h" #include "box64cpu.h" #include "box64cpu_util.h" -#include "x64run_private.h" #include "x64emu_private.h" +#include "x64run_private.h" #include "box64context.h" #include "librarian.h" -#include "elfloader.h" +#include "symbolfuncs.h" #ifdef HAVE_TRACE #include "x64trace.h" #endif @@ -30,1182 +30,6 @@ #define from_ptrv(A) ((void*)(uintptr_t)(A)) #endif -#define PARITY(x) (((emu->x64emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0) -#define XOR2(x) (((x) ^ ((x)>>1)) & 0x1) - -#ifdef ANDROID -void EXPORT my___libc_init(x64emu_t* emu, void* raw_args , void (*onexit)(void) , int (*main)(int, char**, char**), void const * const structors ) -{ - //TODO: register fini - // let's cheat and set all args... - SetRDX(emu, (uintptr_t)my_context->envv); - SetRSI(emu, (uintptr_t)my_context->argv); - SetRDI(emu, (uintptr_t)my_context->argc); - - printf_log(LOG_DEBUG, "Transfert to main(%d, %p, %p)=>%p from __libc_init\n", my_context->argc, my_context->argv, my_context->envv, main); - // should call structors->preinit_array and structors->init_array! - // call main and finish - Push64(emu, GetRBP(emu)); // set frame pointer - SetRBP(emu, GetRSP(emu)); // save RSP - SetRSP(emu, GetRSP(emu)&~0xFLL); // Align RSP - PushExit(emu); - R_RIP=(uintptr_t)main; - - DynaRun(emu); - - SetRSP(emu, GetRBP(emu)); // restore RSP - SetRBP(emu, Pop64(emu)); // restore RBP - emu->quit = 1; // finished! -} -#else -EXPORT int32_t my___libc_start_main(x64emu_t* emu, int (*main) (int, char * *, char * *), int argc, char * * ubp_av, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void (* stack_end)) -{ - (void)argc; (void)ubp_av; (void)fini; (void)rtld_fini; (void)stack_end; - - if(init) { - uintptr_t old_rsp = GetRSP(emu); - uintptr_t old_rbp = GetRBP(emu); // should not be needed, but seems to be without dynarec - Push64(emu, GetRBP(emu)); // set frame pointer - SetRBP(emu, GetRSP(emu)); // save RSP - SetRSP(emu, GetRSP(emu)&~0xFLL); // Align RSP - PushExit(emu); - SetRDX(emu, (uint64_t)my_context->envv); - SetRSI(emu, (uint64_t)my_context->argv); - SetRDI(emu, (uint64_t)my_context->argc); - R_RIP=(uint64_t)*init; - printf_dump(LOG_DEBUG, "Calling init(%p) from __libc_start_main\n", *init); - DynaRun(emu); - if(emu->error) // any error, don't bother with more - return 0; - SetRSP(emu, GetRBP(emu)); // restore RSP - SetRBP(emu, Pop64(emu)); // restore RBP - SetRSP(emu, old_rsp); - SetRBP(emu, old_rbp); - emu->quit = 0; - } else { - if(my_context->elfs[0]) { - printf_dump(LOG_DEBUG, "Calling init from main elf\n"); - RunElfInit(my_context->elfs[0], emu); - } - } - if(my_context->elfs[0]) { - MarkElfInitDone(my_context->elfs[0]); - } - printf_log(LOG_DEBUG, "Transfert to main(%d, %p, %p)=>%p from __libc_start_main\n", my_context->argc, my_context->argv, my_context->envv, main); - // call main and finish - Push64(emu, GetRBP(emu)); // set frame pointer - SetRBP(emu, GetRSP(emu)); // save RSP - SetRSP(emu, GetRSP(emu)&~0xFLL); // Align RSP - PushExit(emu); - SetRDX(emu, (uint64_t)my_context->envv); - SetRSI(emu, (uint64_t)my_context->argv); - SetRDI(emu, (uint64_t)my_context->argc); - R_RIP=(uint64_t)main; - - DynaRun(emu); - - if(!emu->quit) { - SetRSP(emu, GetRBP(emu)); // restore RSP - SetRBP(emu, Pop64(emu)); // restore RBP - emu->quit = 1; // finished! - } - return (int)GetEAX(emu); -} -#ifdef BOX32 -#ifdef ANDROID -void EXPORT my32___libc_init(x64emu_t* emu, void* raw_args , void (*onexit)(void) , int (*main)(int, char**, char**), void const * const structors ) -{ - //TODO: register fini - // let's cheat and set all args... - Push_32(emu, (uint32_t)my_context->envv32); - Push_32(emu, (uint32_t)my_context->argv32); - Push_32(emu, (uint32_t)my_context->argc); - - printf_log(LOG_DEBUG, "Transfert to main(%d, %p, %p)=>%p from __libc_init\n", my_context->argc, my_context->argv, my_context->envv, main); - // should call structors->preinit_array and structors->init_array! - // call main and finish - PushExit_32(emu); - R_EIP=to_ptrv(main); - - DynaRun(emu); - - emu->quit = 1; // finished! -} -#else -int32_t EXPORT my32___libc_start_main(x64emu_t* emu, int *(main) (int, char * *, char * *), int argc, char * * ubp_av, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void (* stack_end)) -{ - // let's cheat and set all args... - Push_32(emu, my_context->envv32); - Push_32(emu, my_context->argv32); - Push_32(emu, my_context->argc); - if(init) { - PushExit_32(emu); - R_EIP=to_ptrv(*init); - printf_log(LOG_DEBUG, "Calling init(%p) from __libc_start_main\n", *init); - DynaRun(emu); - if(emu->error) // any error, don't bother with more - return 0; - emu->quit = 0; - } else { - if(my_context->elfs[0]) { - printf_dump(LOG_DEBUG, "Calling init from main elf\n"); - RunElfInit(my_context->elfs[0], emu); - } - } - if(my_context->elfs[0]) { - MarkElfInitDone(my_context->elfs[0]); - } - printf_log(LOG_DEBUG, "Transfert to main(%d, %p, %p)=>%p from __libc_start_main\n", my_context->argc, my_context->argv, my_context->envv, main); - // call main and finish - PushExit_32(emu); - R_EIP=to_ptrv(main); - - DynaRun(emu); - - emu->quit = 1; // finished! - return 0; -} -#endif -#endif -#endif - -const char* GetNativeName(void* p) -{ - static char buff[500] = {0}; - { - const char* n = getBridgeName(p); - if(n) - return n; - } - Dl_info info; - if(dladdr(p, &info)==0) { - const char *ret = GetNameOffset(my_context->maplib, p); - if(ret) - return ret; - sprintf(buff, "%s(%p)", "???", p); - return buff; - } else { - if(info.dli_sname) { - strcpy(buff, info.dli_sname); - if(info.dli_fname) { - strcat(buff, "("); strcat(buff, info.dli_fname); strcat(buff, ")"); - } - } else { - sprintf(buff, "%s(%s+%p)", "???", info.dli_fname, (void*)(p-info.dli_fbase)); - return buff; - } - } - return buff; -} -void UpdateFlags(x64emu_t *emu) -{ - uint64_t cc; - uint64_t lo, hi; - uint64_t bc; - uint64_t cnt; - - switch(emu->df) { - case d_none: - return; - case d_add8: - CONDITIONAL_SET_FLAG(emu->res.u16 & 0x100, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - cc = (emu->op1.u8 & emu->op2.u8) | ((~emu->res.u8) & (emu->op1.u8 | emu->op2.u8)); - CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - break; - case d_add8b: - CONDITIONAL_SET_FLAG(((uint16_t)emu->op1.u8+emu->op2.u8) & 0x100, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - cc = (emu->op1.u8 & emu->op2.u8) | ((~emu->res.u8) & (emu->op1.u8 | emu->op2.u8)); - CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - break; - case d_add16: - CONDITIONAL_SET_FLAG(emu->res.u32 & 0x10000, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - cc = (emu->op1.u16 & emu->op2.u16) | ((~emu->res.u16) & (emu->op1.u16 | emu->op2.u16)); - CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - break; - case d_add16b: - CONDITIONAL_SET_FLAG(((uint32_t)emu->op1.u16+emu->op2.u16) & 0x10000, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - cc = (emu->op1.u16 & emu->op2.u16) | ((~emu->res.u16) & (emu->op1.u16 | emu->op2.u16)); - CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - break; - case d_add32: - CONDITIONAL_SET_FLAG(emu->res.u64 & 0x100000000LL, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - cc = (emu->op1.u32 & emu->op2.u32) | ((~emu->res.u32) & (emu->op1.u32 | emu->op2.u32)); - CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - break; - case d_add32b: - lo = (emu->op2.u32 & 0xFFFF) + (emu->op1.u32 & 0xFFFF); - hi = (lo >> 16) + (emu->op2.u32 >> 16) + (emu->op1.u32 >> 16); - CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - cc = (emu->op1.u32 & emu->op2.u32) | ((~emu->res.u32) & (emu->op1.u32 | emu->op2.u32)); - CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - break; - case d_add64: - lo = (emu->op2.u64 & 0xFFFFFFFF) + (emu->op1.u64 & 0xFFFFFFFF); - hi = (lo >> 32) + (emu->op2.u64 >> 32) + (emu->op1.u64 >> 32); - CONDITIONAL_SET_FLAG(hi & 0x100000000L, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - cc = (emu->op1.u64 & emu->op2.u64) | ((~emu->res.u64) & (emu->op1.u64 | emu->op2.u64)); - CONDITIONAL_SET_FLAG(XOR2(cc >> 62), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - break; - case d_and8: - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - break; - case d_and16: - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - break; - case d_and32: - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - break; - case d_and64: - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(emu->res.u64 == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - break; - case d_dec8: - CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - bc = (emu->res.u8 & (~emu->op1.u8 | 1)) | (~emu->op1.u8 & 1); - CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - break; - case d_dec16: - CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - bc = (emu->res.u16 & (~emu->op1.u16 | 1)) | (~emu->op1.u16 & 1); - CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - break; - case d_dec32: - CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - bc = (emu->res.u32 & (~emu->op1.u32 | 1)) | (~emu->op1.u32 & 1); - CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - break; - case d_dec64: - CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - bc = (emu->res.u64 & (~emu->op1.u64 | 1LL)) | (~emu->op1.u64 & 1LL); - CONDITIONAL_SET_FLAG(XOR2(bc >> 62), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - break; - case d_inc8: - CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - cc = ((1 & emu->op1.u8) | (~emu->res.u8)) & (1 | emu->op1.u8); - CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - break; - case d_inc16: - CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - cc = (1 & emu->op1.u16) | ((~emu->res.u16) & (1 | emu->op1.u16)); - CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - break; - case d_inc32: - CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - cc = (1 & emu->op1.u32) | ((~emu->res.u32) & (1 | emu->op1.u32)); - CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - break; - case d_inc64: - CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - cc = (1LL & emu->op1.u64) | ((~emu->res.u64) & (1LL | emu->op1.u64)); - CONDITIONAL_SET_FLAG(XOR2(cc >> 62), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - break; - case d_imul8: - lo = emu->res.u16 & 0xff; - hi = (emu->res.u16>>8)&0xff; - if (((lo & 0x80) == 0 && hi == 0x00) || - ((lo & 0x80) != 0 && hi == 0xFF)) { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_OF); - } else { - SET_FLAG(F_CF); - SET_FLAG(F_OF); - } - if (!BOX64ENV(cputype)) { - CONDITIONAL_SET_FLAG((emu->res.u8>>7)&1, F_SF); - CLEAR_FLAG(F_ZF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - } - break; - case d_imul16: - lo = (uint16_t)emu->res.u32; - hi = (uint16_t)(emu->res.u32 >> 16); - if (((lo & 0x8000) == 0 && hi == 0x00) || - ((lo & 0x8000) != 0 && hi == 0xFFFF)) { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_OF); - } else { - SET_FLAG(F_CF); - SET_FLAG(F_OF); - } - if (!BOX64ENV(cputype)) { - CONDITIONAL_SET_FLAG((emu->res.u16>>15)&1, F_SF); - CLEAR_FLAG(F_ZF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - } - break; - case d_imul32: - if ((((emu->res.u32 & 0x80000000) == 0) && emu->op1.u32 == 0x00) || - (((emu->res.u32 & 0x80000000) != 0) && emu->op1.u32 == 0xFFFFFFFF)) { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_OF); - } else { - SET_FLAG(F_CF); - SET_FLAG(F_OF); - } - if (!BOX64ENV(cputype)) { - CONDITIONAL_SET_FLAG((emu->res.u32>>31)&1, F_SF); - CLEAR_FLAG(F_ZF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - } - break; - case d_imul64: - if (((emu->res.u64 & 0x8000000000000000LL) == 0 && emu->op1.u64 == 0x00) || - ((emu->res.u64 & 0x8000000000000000LL) != 0 && emu->op1.u64 == 0xFFFFFFFFFFFFFFFFLL)) { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_OF); - } else { - SET_FLAG(F_CF); - SET_FLAG(F_OF); - } - if (!BOX64ENV(cputype)) { - CONDITIONAL_SET_FLAG((emu->res.u64>>63)&1, F_SF); - CLEAR_FLAG(F_ZF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - } - break; - case d_mul8: - hi = (emu->res.u16>>8)&0xff; - if (hi == 0) { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_OF); - } else { - SET_FLAG(F_CF); - SET_FLAG(F_OF); - } - if (!BOX64ENV(cputype)) { - CONDITIONAL_SET_FLAG((emu->res.u8>>7)&1, F_SF); - CLEAR_FLAG(F_ZF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - } - break; - case d_mul16: - hi = (uint16_t)(emu->res.u32 >> 16); - if (hi == 0) { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_OF); - } else { - SET_FLAG(F_CF); - SET_FLAG(F_OF); - } - if (!BOX64ENV(cputype)) { - CONDITIONAL_SET_FLAG((emu->res.u16>>15)&1, F_SF); - CLEAR_FLAG(F_ZF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - } - break; - case d_mul32: - if (emu->op1.u32 == 0) { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_OF); - } else { - SET_FLAG(F_CF); - SET_FLAG(F_OF); - } - if (!BOX64ENV(cputype)) { - CONDITIONAL_SET_FLAG((emu->res.u32>>31)&1, F_SF); - CLEAR_FLAG(F_ZF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - } - break; - case d_mul64: - if (emu->op1.u64 == 0) { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_OF); - } else { - SET_FLAG(F_CF); - SET_FLAG(F_OF); - } - if (!BOX64ENV(cputype)) { - CONDITIONAL_SET_FLAG((emu->res.u64>>63)&1, F_SF); - CLEAR_FLAG(F_ZF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - } - break; - case d_or8: - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - break; - case d_or16: - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - break; - case d_or32: - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - break; - case d_or64: - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - break; - case d_neg8: - CONDITIONAL_SET_FLAG(emu->op1.u8, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - bc = emu->res.u8 | emu->op1.u8; - CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - break; - case d_neg16: - CONDITIONAL_SET_FLAG(emu->op1.u16, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - bc = emu->res.u16 | emu->op1.u16; - CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - break; - case d_neg32: - CONDITIONAL_SET_FLAG(emu->op1.u32, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - bc = emu->res.u32 | emu->op1.u32; - CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - break; - case d_neg64: - CONDITIONAL_SET_FLAG(emu->op1.u64, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - bc = emu->res.u64 | emu->op1.u64; - CONDITIONAL_SET_FLAG(XOR2(bc >> 62), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - break; - case d_shl8: - cnt = emu->op2.u8 & 0x1f; - if (cnt > 0) { - cc = emu->op1.u8 & (1 << (8 - cnt)); - CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (BOX64ENV(cputype)) { - CONDITIONAL_SET_FLAG(((emu->res.u8>>7) ^ ACCESS_FLAG(F_CF))&0x01, F_OF); - SET_FLAG(F_AF); - } else { - CONDITIONAL_SET_FLAG(XOR2(emu->op1.u8>>6), F_OF); - CLEAR_FLAG(F_AF); - } - } - break; - case d_shl16: - cnt = emu->op2.u16 & 0x1f; - if (cnt > 0) { - cc = emu->op1.u16 & (1 << (16 - cnt)); - CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (BOX64ENV(cputype)) { - CONDITIONAL_SET_FLAG(((emu->res.u16>>15) ^ ACCESS_FLAG(F_CF))&0x01, F_OF); - SET_FLAG(F_AF); - } else { - CONDITIONAL_SET_FLAG(XOR2(emu->op1.u16>>14), F_OF); - CLEAR_FLAG(F_AF); - } - } - break; - case d_shl32: - cnt = emu->op2.u32 & 0x1f; - if (cnt > 0) { - cc = emu->op1.u32 & (1 << (32 - cnt)); - CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (BOX64ENV(cputype)) { - CONDITIONAL_SET_FLAG(((emu->res.u32>>31) ^ ACCESS_FLAG(F_CF))&0x01, F_OF); - SET_FLAG(F_AF); - } else { - CONDITIONAL_SET_FLAG(XOR2(emu->op1.u32>>30), F_OF); - CLEAR_FLAG(F_AF); - } - } - break; - case d_shl64: - if (emu->op2.u64 > 0) { - cc = emu->op1.u64 & (1LL << (64 - emu->op2.u64)); - CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (BOX64ENV(cputype)) { - CONDITIONAL_SET_FLAG(((emu->res.u64>>63) ^ ACCESS_FLAG(F_CF))&0x01, F_OF); - SET_FLAG(F_AF); - } else { - CONDITIONAL_SET_FLAG(XOR2(emu->op1.u64>>62), F_OF); - CLEAR_FLAG(F_AF); - } - } - break; - case d_sar8: - if(emu->op2.u8) { - cc = (emu->op1.i8 >> (emu->op2.u8 - 1)) & 1; - CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); - CLEAR_FLAG(F_OF); - if (BOX64ENV(cputype)) - SET_FLAG(F_AF); - else - CLEAR_FLAG(F_AF); - } - break; - case d_sar16: - if(emu->op2.u16) { - cc = (emu->op1.i16 >> (emu->op2.u16 - 1)) & 1; - CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - CLEAR_FLAG(F_OF); - if (BOX64ENV(cputype)) - SET_FLAG(F_AF); - else - CLEAR_FLAG(F_AF); - } - break; - case d_sar32: - if(emu->op2.u32) { - cc = emu->op1.u32 & (1 << (emu->op2.u32 - 1)); - CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - CLEAR_FLAG(F_OF); - if (BOX64ENV(cputype)) - SET_FLAG(F_AF); - else - CLEAR_FLAG(F_AF); - } - break; - case d_sar64: - if(emu->op2.u64) { - cc = emu->op1.u64 & (1LL << (emu->op2.u64 - 1)); - CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - CLEAR_FLAG(F_OF); - if (BOX64ENV(cputype)) - SET_FLAG(F_AF); - else - CLEAR_FLAG(F_AF); - } - break; - case d_shr8: - cnt = emu->op2.u8 & 0x1f; - if (cnt > 0) { - cc = emu->op1.u8 & (1 << (cnt - 1)); - CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (BOX64ENV(cputype)) { - CONDITIONAL_SET_FLAG((emu->res.u8>>6)&0x1, F_OF); - SET_FLAG(F_AF); - } else { - CONDITIONAL_SET_FLAG((emu->op1.u8>>7)&0x1, F_OF); - CLEAR_FLAG(F_AF); - } - } - break; - case d_shr16: - cnt = emu->op2.u16 & 0x1f; - if (cnt > 0) { - cc = emu->op1.u16 & (1 << (cnt - 1)); - CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (BOX64ENV(cputype)) { - CONDITIONAL_SET_FLAG((emu->res.u16>>14)&0x1, F_OF); - SET_FLAG(F_AF); - } else { - CONDITIONAL_SET_FLAG((emu->op1.u16>>15)&0x1, F_OF); - CLEAR_FLAG(F_AF); - } - } - if (cnt == 1) { - CONDITIONAL_SET_FLAG(emu->op1.u16 & 0x8000, F_OF); - } - break; - case d_shr32: - cnt = emu->op2.u32 & 0x1f; - if (cnt > 0) { - cc = emu->op1.u32 & (1 << (cnt - 1)); - CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (BOX64ENV(cputype)) { - CONDITIONAL_SET_FLAG((emu->res.u32>>30)&0x1, F_OF); - SET_FLAG(F_AF); - } else { - CONDITIONAL_SET_FLAG((emu->op1.u32>>31)&0x1, F_OF); - CLEAR_FLAG(F_AF); - } - } - break; - case d_shr64: - cnt = emu->op2.u64; - if (cnt > 0) { - cc = emu->op1.u64 & (1LL << (cnt - 1)); - CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (BOX64ENV(cputype)) { - CONDITIONAL_SET_FLAG((emu->res.u64>>62)&0x1, F_OF); - SET_FLAG(F_AF); - } else { - CONDITIONAL_SET_FLAG((emu->op1.u64>>63)&0x1, F_OF); - CLEAR_FLAG(F_AF); - } - } - break; - case d_shrd16: - cnt = emu->op2.u16; - if (cnt > 0) { - cc = emu->op1.u16 & (1 << (cnt - 1)); - if(cnt>15 && BOX64ENV(cputype)) - cc = 0; - CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - } - if BOX64ENV(cputype) { - CONDITIONAL_SET_FLAG(XOR2(emu->res.u16>>14), F_OF); - } else { - CONDITIONAL_SET_FLAG(((emu->res.u16>>(16-(cnt&15))) ^ (emu->op1.u16>>15))&1, F_OF); - } - if (BOX64ENV(cputype)) - SET_FLAG(F_AF); - else - CLEAR_FLAG(F_AF); - break; - case d_shrd32: - cnt = emu->op2.u32; - if (cnt > 0) { - cc = emu->op1.u32 & (1 << (cnt - 1)); - CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if BOX64ENV(cputype) { - CONDITIONAL_SET_FLAG(XOR2(emu->res.u32>>30), F_OF); - } else { - CONDITIONAL_SET_FLAG(((emu->res.u32>>(32-cnt)) ^ (emu->op1.u32>>31))&1, F_OF); - } - if (BOX64ENV(cputype)) - SET_FLAG(F_AF); - else - CLEAR_FLAG(F_AF); - } - break; - case d_shrd64: - cnt = emu->op2.u64; - if (cnt > 0) { - cc = emu->op1.u64 & (1LL << (cnt - 1)); - CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if BOX64ENV(cputype) { - CONDITIONAL_SET_FLAG(XOR2(emu->res.u64>>62), F_OF); - } else { - CONDITIONAL_SET_FLAG(((emu->res.u64>>(64-cnt)) ^ (emu->op1.u64>>63))&1, F_OF); - } - if (BOX64ENV(cputype)) - SET_FLAG(F_AF); - else - CLEAR_FLAG(F_AF); - } - break; - case d_shld16: - cnt = emu->op2.u16; - if (cnt > 0) { - cc = emu->op1.u16 & (1 << (16 - cnt)); - CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if BOX64ENV(cputype) { - if(cnt>15) - CONDITIONAL_SET_FLAG(ACCESS_FLAG(F_CF), F_OF); - else - CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (emu->res.u16>>15))&1, F_OF); - } else { - CONDITIONAL_SET_FLAG(XOR2(emu->op1.u16>>14), F_OF); - } - if (BOX64ENV(cputype)) - SET_FLAG(F_AF); - else - CLEAR_FLAG(F_AF); - } - break; - case d_shld32: - cnt = emu->op2.u32; - if (cnt > 0) { - cc = emu->op1.u32 & (1 << (32 - cnt)); - CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if BOX64ENV(cputype) { - CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (emu->res.u32>>31))&1, F_OF); - } else { - CONDITIONAL_SET_FLAG(XOR2(emu->op1.u32>>30), F_OF); - } - if (BOX64ENV(cputype)) - SET_FLAG(F_AF); - else - CLEAR_FLAG(F_AF); - } - break; - case d_shld64: - cnt = emu->op2.u64; - if (cnt > 0) { - cc = emu->op1.u64 & (1LL << (64 - cnt)); - CONDITIONAL_SET_FLAG(cc, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if BOX64ENV(cputype) { - CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (emu->res.u64>>63))&1, F_OF); - } else { - CONDITIONAL_SET_FLAG(XOR2(emu->op1.u64>>62), F_OF); - } - if (BOX64ENV(cputype)) - SET_FLAG(F_AF); - else - CLEAR_FLAG(F_AF); - } - break; - case d_sub8: - CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - bc = (emu->res.u8 & (~emu->op1.u8 | emu->op2.u8)) | (~emu->op1.u8 & emu->op2.u8); - CONDITIONAL_SET_FLAG(bc & 0x80, F_CF); - CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - break; - case d_sub16: - CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - bc = (emu->res.u16 & (~emu->op1.u16 | emu->op2.u16)) | (~emu->op1.u16 & emu->op2.u16); - CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF); - CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - break; - case d_sub32: - CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - bc = (emu->res.u32 & (~emu->op1.u32 | emu->op2.u32)) | (~emu->op1.u32 & emu->op2.u32); - CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF); - CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - break; - case d_sub64: - CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - bc = (emu->res.u64 & (~emu->op1.u64 | emu->op2.u64)) | (~emu->op1.u64 & emu->op2.u64); - CONDITIONAL_SET_FLAG(bc & 0x8000000000000000LL, F_CF); - CONDITIONAL_SET_FLAG(XOR2(bc >> 62), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - break; - case d_xor8: - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - break; - case d_xor16: - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - break; - case d_xor32: - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - break; - case d_xor64: - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - break; - case d_cmp8: - CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); - CONDITIONAL_SET_FLAG((emu->res.u8 & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - bc = (emu->res.u8 & (~emu->op1.u8 | emu->op2.u8)) | (~emu->op1.u8 & emu->op2.u8); - CONDITIONAL_SET_FLAG(bc & 0x80, F_CF); - CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - break; - case d_cmp16: - CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); - CONDITIONAL_SET_FLAG((emu->res.u16 & 0xffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - bc = (emu->res.u16 & (~emu->op1.u16 | emu->op2.u16)) | (~emu->op1.u16 & emu->op2.u16); - CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF); - CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - break; - case d_cmp32: - CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - bc = (emu->res.u32 & (~emu->op1.u32 | emu->op2.u32)) | (~emu->op1.u32 & emu->op2.u32); - CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF); - CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - break; - case d_cmp64: - CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - bc = (emu->res.u64 & (~emu->op1.u64 | emu->op2.u64)) | (~emu->op1.u64 & emu->op2.u64); - CONDITIONAL_SET_FLAG(bc & 0x8000000000000000LL, F_CF); - CONDITIONAL_SET_FLAG(XOR2(bc >> 62), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - break; - case d_tst8: - CLEAR_FLAG(F_OF); - CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - CLEAR_FLAG(F_CF); - break; - case d_tst16: - CLEAR_FLAG(F_OF); - CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - CLEAR_FLAG(F_CF); - break; - case d_tst32: - CLEAR_FLAG(F_OF); - CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - CLEAR_FLAG(F_CF); - break; - case d_tst64: - CLEAR_FLAG(F_OF); - CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - CLEAR_FLAG(F_CF); - break; - case d_adc8: - CONDITIONAL_SET_FLAG(emu->res.u16 & 0x100, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - cc = (emu->op1.u8 & emu->op2.u8) | ((~emu->res.u8) & (emu->op1.u8 | emu->op2.u8)); - CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - break; - case d_adc16: - CONDITIONAL_SET_FLAG(emu->res.u32 & 0x10000, F_CF); - CONDITIONAL_SET_FLAG((emu->res.u16 & 0xffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - cc = (emu->op1.u16 & emu->op2.u16) | ((~emu->res.u16) & (emu->op1.u16 | emu->op2.u16)); - CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - break; - case d_adc32: - CONDITIONAL_SET_FLAG(emu->res.u64 & 0x100000000L, F_CF); - CONDITIONAL_SET_FLAG((emu->res.u32 & 0xffffffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - cc = (emu->op1.u32 & emu->op2.u32) | ((~emu->res.u32) & (emu->op1.u32 | emu->op2.u32)); - CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - break; - case d_adc32b: - if(emu->res.u32 == (emu->op1.u32+emu->op2.u32)) { - lo = (emu->op1.u32 & 0xFFFF) + (emu->op2.u32 & 0xFFFF); - } else { - lo = 1 + (emu->op1.u32 & 0xFFFF) + (emu->op2.u32 & 0xFFFF); - } - hi = (lo >> 16) + (emu->op1.u32 >> 16) + (emu->op2.u32 >> 16); - CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - cc = (emu->op2.u32 & emu->op1.u32) | ((~emu->res.u32) & (emu->op2.u32 | emu->op1.u32)); - CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - break; - case d_adc64: - if(emu->res.u64 == (emu->op1.u64+emu->op2.u64)) { - lo = (emu->op1.u64 & 0xFFFFFFFF) + (emu->op2.u64 & 0xFFFFFFFF); - } else { - lo = 1 + (emu->op1.u64 & 0xFFFFFFFF) + (emu->op2.u64 & 0xFFFFFFFF); - } - hi = (lo >> 32) + (emu->op1.u64 >> 32) + (emu->op2.u64 >> 32); - CONDITIONAL_SET_FLAG(hi & 0x100000000L, F_CF); - CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); - CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - cc = (emu->op2.u64 & emu->op1.u64) | ((~emu->res.u64) & (emu->op2.u64 | emu->op1.u64)); - CONDITIONAL_SET_FLAG(XOR2(cc >> 62), F_OF); - CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); - break; - case d_sbb8: - CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); - CONDITIONAL_SET_FLAG((emu->res.u8 & 0xff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - bc = (emu->res.u8 & (~emu->op1.u8 | emu->op2.u8)) | (~emu->op1.u8 & emu->op2.u8); - CONDITIONAL_SET_FLAG(bc & 0x80, F_CF); - CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - break; - case d_sbb16: - CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); - CONDITIONAL_SET_FLAG((emu->res.u16 & 0xffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - bc = (emu->res.u16 & (~emu->op1.u16 | emu->op2.u16)) | (~emu->op1.u16 & emu->op2.u16); - CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF); - CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - break; - case d_sbb32: - CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - bc = (emu->res.u32 & (~emu->op1.u32 | emu->op2.u32)) | (~emu->op1.u32 & emu->op2.u32); - CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF); - CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - break; - case d_sbb64: - CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); - CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); - CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - bc = (emu->res.u64 & (~emu->op1.u64 | emu->op2.u64)) | (~emu->op1.u64 & emu->op2.u64); - CONDITIONAL_SET_FLAG(bc & 0x8000000000000000LL, F_CF); - CONDITIONAL_SET_FLAG(XOR2(bc >> 62), F_OF); - CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); - break; - case d_rol8: - if(BOX64ENV(cputype)) - CONDITIONAL_SET_FLAG((emu->res.u8 + (emu->res.u8 >> 7)) & 1, F_OF); - else - CONDITIONAL_SET_FLAG(XOR2(emu->op1.u8>>6), F_OF); - CONDITIONAL_SET_FLAG(emu->res.u8 & 0x1, F_CF); - break; - case d_rol16: - if(BOX64ENV(cputype)) - CONDITIONAL_SET_FLAG((emu->res.u16 + (emu->res.u16 >> 15)) & 1, F_OF); - else - CONDITIONAL_SET_FLAG(XOR2(emu->op1.u16>>14), F_OF); - CONDITIONAL_SET_FLAG(emu->res.u16 & 0x1, F_CF); - break; - case d_rol32: - if(BOX64ENV(cputype)) - CONDITIONAL_SET_FLAG((emu->res.u32 + (emu->res.u32 >> 31)) & 1, F_OF); - else - CONDITIONAL_SET_FLAG(XOR2(emu->op1.u32>>30), F_OF); - CONDITIONAL_SET_FLAG(emu->res.u32 & 0x1, F_CF); - break; - case d_rol64: - if(BOX64ENV(cputype)) - CONDITIONAL_SET_FLAG((emu->res.u64 + (emu->res.u64 >> 63)) & 1, F_OF); - else - CONDITIONAL_SET_FLAG(XOR2(emu->op1.u64>>62), F_OF); - CONDITIONAL_SET_FLAG(emu->res.u64 & 0x1, F_CF); - break; - case d_ror8: - if(BOX64ENV(cputype)) - CONDITIONAL_SET_FLAG(XOR2(emu->res.u8 >> 6), F_OF); - else - CONDITIONAL_SET_FLAG(((emu->op1.u8 >> 7)^emu->op1.u8)&1, F_OF); - CONDITIONAL_SET_FLAG(emu->res.u8 & (1 << 7), F_CF); - break; - case d_ror16: - if(BOX64ENV(cputype)) - CONDITIONAL_SET_FLAG(XOR2(emu->res.u16 >> 14), F_OF); - else - CONDITIONAL_SET_FLAG(((emu->op1.u16 >> 15)^emu->op1.u16)&1, F_OF); - CONDITIONAL_SET_FLAG(emu->res.u16 & (1 << 15), F_CF); - break; - case d_ror32: - if(BOX64ENV(cputype)) - CONDITIONAL_SET_FLAG(XOR2(emu->res.u32 >> 30), F_OF); - else - CONDITIONAL_SET_FLAG(((emu->op1.u32 >> 31)^emu->op1.u32)&1, F_OF); - CONDITIONAL_SET_FLAG(emu->res.u32 & (1 << 31), F_CF); - break; - case d_ror64: - if(BOX64ENV(cputype)) - CONDITIONAL_SET_FLAG(XOR2(emu->res.u64 >> 62), F_OF); - else - CONDITIONAL_SET_FLAG(((emu->op1.u64 >> 63)^emu->op1.u64)&1, F_OF); - CONDITIONAL_SET_FLAG(emu->res.u64 & (1L << 63), F_CF); - break; - - case d_unknown: - printf_log(LOG_NONE, "%p trying to evaluate Unknown deferred Flags\n", (void*)R_RIP); - break; - } - RESET_FLAGS(emu); -} - -uintptr_t GetSegmentBaseEmu(x64emu_t* emu, int seg) -{ - if(emu->segs_serial[seg] != emu->context->sel_serial) { - emu->segs_offs[seg] = (uintptr_t)GetSegmentBase(emu->segs[seg]); - emu->segs_serial[seg] = emu->context->sel_serial; - } - return emu->segs_offs[seg]; -} - - -const char* getAddrFunctionName(uintptr_t addr) -{ - static char rets[8][1000]; - static int idx = 0; - char* ret = rets[idx]; - idx = (idx+1)&7; - uint64_t sz = 0; - uintptr_t start = 0; - elfheader_t* elf = FindElfAddress(my_context, addr); - const char* symbname = FindNearestSymbolName(elf, (void*)addr, &start, &sz); - if(!sz) sz=0x100; // arbitrary value... - if(symbname && addr>=start && (addr<(start+sz) || !sz)) { - if(symbname[0]=='\0') - sprintf(ret, "%s + 0x%lx + 0x%lx", ElfName(elf), start - (uintptr_t)GetBaseAddress(elf), addr - start); - else if(addr==start) - sprintf(ret, "%s/%s", ElfName(elf), symbname); - else - sprintf(ret, "%s/%s + 0x%lx", ElfName(elf), symbname, addr - start); - } else { - if(elf) { - sprintf(ret, "%s + 0x%lx", ElfName(elf), addr - (uintptr_t)GetBaseAddress(elf)); - } else - sprintf(ret, "???"); - } - return ret; -} #ifdef HAVE_TRACE #define PK(a) (*(uint8_t*)(ip+a)) diff --git a/src/emu/x64run_private.h b/src/emu/x64run_private.h index d4ff67c5..e493f189 100644 --- a/src/emu/x64run_private.h +++ b/src/emu/x64run_private.h @@ -6,6 +6,7 @@ #include "x64emu_private.h" #include "box64context.h" #include "symbolfuncs.h" +#include "x64emu.h" typedef struct rex_s { union { @@ -92,8 +93,6 @@ mmx87_regs_t* TestEm32O(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, sse_regs_t* GetGx(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v); sse_regs_t* GetGy(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v); -void UpdateFlags(x64emu_t *emu); - #define CHECK_FLAGS(emu) if(emu->df) UpdateFlags(emu) #define RESET_FLAGS(emu) emu->df = d_none @@ -179,14 +178,6 @@ uintptr_t TestAVX_F20F3A(x64test_t *test, vex_t vex, uintptr_t addr, int *step); uintptr_t TestAVX_F30F38(x64test_t *test, vex_t vex, uintptr_t addr, int *step); uintptr_t TestAVX_F30F3A(x64test_t *test, vex_t vex, uintptr_t addr, int *step); -uintptr_t GetSegmentBaseEmu(x64emu_t* emu, int seg); -#define GetGSBaseEmu(emu) GetSegmentBaseEmu(emu, _GS) -#define GetFSBaseEmu(emu) GetSegmentBaseEmu(emu, _FS) -#define GetESBaseEmu(emu) GetSegmentBaseEmu(emu, _ES) -#define GetDSBaseEmu(emu) GetSegmentBaseEmu(emu, _DS) - -const char* GetNativeName(void* p); - #ifdef HAVE_TRACE void PrintTrace(x64emu_t* emu, uintptr_t ip, int dynarec); #endif diff --git a/src/emu/x64test.c b/src/emu/x64test.c index 4ac4eeff..0355f346 100644 --- a/src/emu/x64test.c +++ b/src/emu/x64test.c @@ -20,7 +20,6 @@ #include "x87emu_private.h" #include "box64context.h" #include "bridge.h" -#include "signals.h" void print_banner(x64emu_t* ref) { diff --git a/src/emu/x64tls.c b/src/emu/x64tls.c index 79a8ae5b..4c17dda8 100644 --- a/src/emu/x64tls.c +++ b/src/emu/x64tls.c @@ -140,7 +140,6 @@ uint32_t my_modify_ldt(x64emu_t* emu, int op, thread_area_t* td, int size) return 0; } -static void* GetSeg43Base(); static const char* arch_prctl_param(int code) { static char ret[10] = {0}; @@ -375,34 +374,4 @@ tlsdatasize_t* getTLSData(box64context_t *context) if(ptr->tlssize != context->tlssize) ptr = (tlsdatasize_t*)resizeTLSData(context, ptr); return ptr; -} - -static void* GetSeg43Base() -{ - tlsdatasize_t* ptr = getTLSData(my_context); - return ptr->data; -} - -void* GetSegmentBase(uint32_t desc) -{ - if(!desc) { - printf_log(LOG_NONE, "Warning, accessing segment NULL\n"); - return NULL; - } - int base = desc>>3; - if(!box64_is32bits && base==0x8 && !my_context->segtls[base].key_init) - return GetSeg43Base(); - if(box64_is32bits && (base==0x6)) - return GetSeg43Base(); - if(base>15) { - printf_log(LOG_NONE, "Warning, accessing segment unknown 0x%x or unset\n", desc); - return NULL; - } - if(my_context->segtls[base].key_init) { - void* ptr = pthread_getspecific(my_context->segtls[base].key); - return ptr; - } - - void* ptr = (void*)my_context->segtls[base].base; - return ptr; -} +} \ No newline at end of file diff --git a/src/include/elfloader.h b/src/include/elfloader.h index 4184788f..56a0571e 100644 --- a/src/include/elfloader.h +++ b/src/include/elfloader.h @@ -99,4 +99,6 @@ void AddMainElfToLinkmap(elfheader_t* lib); void PltResolver32(x64emu_t* emu); void PltResolver64(x64emu_t* emu); +const char* getAddrFunctionName(uintptr_t addr); + #endif //__ELF_LOADER_H_ diff --git a/src/include/freq.h b/src/include/freq.h index 2f3a2427..fe94bef9 100644 --- a/src/include/freq.h +++ b/src/include/freq.h @@ -1,6 +1,8 @@ #ifndef __FREQ_H_ #define __FREQ_H_ +#include <stdint.h> + typedef struct x64emu_s x64emu_t; uint64_t ReadTSC(x64emu_t* emu); diff --git a/src/include/os.h b/src/include/os.h index d4566305..1257cc48 100644 --- a/src/include/os.h +++ b/src/include/os.h @@ -41,6 +41,9 @@ int SchedYield(void); void EmuX64Syscall(void* emu); void EmuX86Syscall(void* emu); +void* GetSeg43Base(); +void* GetSegmentBase(uint32_t desc); + // These functions only applies to Linux -------------------------- int IsBridgeSignature(char s, char c); int IsNativeCall(uintptr_t addr, int is32bits, uintptr_t* calladdress, uint16_t* retn); @@ -50,6 +53,7 @@ void* EmuFork(void* emu, int forktype); void PersonalityAddrLimit32Bit(void); int IsAddrElfOrFileMapped(uintptr_t addr); +const char* GetNativeName(void* p); // ---------------------------------------------------------------- #ifndef _WIN32 @@ -86,7 +90,7 @@ int IsAddrElfOrFileMapped(uintptr_t addr); extern int isinff(float); extern int isnanf(float); #elif defined(_WIN32) -#define isnanf _isnanf +#define isnanf isnan #define isinff isinf #endif diff --git a/src/include/x64emu.h b/src/include/x64emu.h index d4311c77..ab60a57c 100644 --- a/src/include/x64emu.h +++ b/src/include/x64emu.h @@ -1,6 +1,8 @@ #ifndef __X86EMU_H_ #define __X86EMU_H_ +#include <stdint.h> + typedef struct x64emu_s x64emu_t; typedef struct box64context_s box64context_t; typedef struct elfheader_s elfheader_t; @@ -27,6 +29,7 @@ long double LD2localLD(void* ld); // long double (80bits pointer) -> long void LD2D(void* ld, void* d); // long double (80bits) -> double (64bits) void D2LD(void* d, void* ld); // double (64bits) -> long double (64bits) -const char* getAddrFunctionName(uintptr_t addr); +uintptr_t GetSegmentBaseEmu(x64emu_t* emu, int seg); +void UpdateFlags(x64emu_t* emu); #endif //__X86EMU_H_ diff --git a/src/include/x64tls.h b/src/include/x64tls.h index 66f0d9eb..e8eefd31 100644 --- a/src/include/x64tls.h +++ b/src/include/x64tls.h @@ -7,8 +7,7 @@ typedef struct thread_area_32_s thread_area_32_t; uint32_t my_set_thread_area_32(x64emu_t* emu, thread_area_32_t* td); uint32_t my_modify_ldt(x64emu_t* emu, int op, thread_area_t* td, int size); -tlsdatasize_t* getTLSData(box64context_t *context); -void* GetSegmentBase(uint32_t desc); +tlsdatasize_t* getTLSData(box64context_t* context); int my_arch_prctl(x64emu_t *emu, int code, void* addr); diff --git a/src/os/emit_signal_wine.c b/src/os/emit_signal_wine.c new file mode 100644 index 00000000..0539a818 --- /dev/null +++ b/src/os/emit_signal_wine.c @@ -0,0 +1,22 @@ +#include "x64emu.h" +#include "custommem.h" + +void EmitSignal(x64emu_t* emu, int sig, void* addr, int code) +{ + // FIXME +} + +void CheckExec(x64emu_t* emu, uintptr_t addr) +{ + // FIXME +} + +void EmitInterruption(x64emu_t* emu, int num, void* addr) +{ + // FIXME +} + +void EmitDiv0(x64emu_t* emu, void* addr, int code) +{ + // FIXME +} diff --git a/src/os/freq_wine.c b/src/os/freq_wine.c index 6b2a9dc4..9879b609 100644 --- a/src/os/freq_wine.c +++ b/src/os/freq_wine.c @@ -1,4 +1,4 @@ -#incldue "freq.h" +#include "freq.h" // TODO: box64_rdtsc? diff --git a/src/tools/my_cpuid.c b/src/os/my_cpuid_linux.c index df505ac0..df505ac0 100644 --- a/src/tools/my_cpuid.c +++ b/src/os/my_cpuid_linux.c diff --git a/src/os/my_cpuid_wine.c b/src/os/my_cpuid_wine.c new file mode 100644 index 00000000..c2d24b1c --- /dev/null +++ b/src/os/my_cpuid_wine.c @@ -0,0 +1,29 @@ +#include <windows.h> + +#include "my_cpuid.h" + +const char* getBoxCpuName() +{ + return NULL; +} + +void my_cpuid(x64emu_t* emu, uint32_t tmp32u) +{ + // FIXME +} + +uint32_t helper_getcpu(x64emu_t* emu) { + return 0; +} + +uint32_t get_random32(void) +{ + // FIXME + return 0; +} + +uint64_t get_random64(void) +{ + // FIXME + return 0; +} \ No newline at end of file diff --git a/src/os/os_linux.c b/src/os/os_linux.c index 6d9db214..556d4d9b 100644 --- a/src/os/os_linux.c +++ b/src/os/os_linux.c @@ -1,8 +1,11 @@ +#define _GNU_SOURCE #include <sys/syscall.h> #include <sched.h> #include <unistd.h> #include <stdint.h> #include <sys/personality.h> +#include <dlfcn.h> +#include <string.h> #include "os.h" #include "signals.h" @@ -10,6 +13,9 @@ #include "bridge.h" #include "elfloader.h" #include "env.h" +#include "debug.h" +#include "x64tls.h" +#include "librarian.h" int GetTID(void) { @@ -51,6 +57,70 @@ void EmuX86Syscall(void* emu) x86Syscall((x64emu_t*)emu); } +extern int box64_is32bits; + +void* GetSeg43Base() +{ + tlsdatasize_t* ptr = getTLSData(my_context); + return ptr->data; +} + +void* GetSegmentBase(uint32_t desc) +{ + if (!desc) { + printf_log(LOG_NONE, "Warning, accessing segment NULL\n"); + return NULL; + } + int base = desc >> 3; + if (!box64_is32bits && base == 0x8 && !my_context->segtls[base].key_init) + return GetSeg43Base(); + if (box64_is32bits && (base == 0x6)) + return GetSeg43Base(); + if (base > 15) { + printf_log(LOG_NONE, "Warning, accessing segment unknown 0x%x or unset\n", desc); + return NULL; + } + if (my_context->segtls[base].key_init) { + void* ptr = pthread_getspecific(my_context->segtls[base].key); + return ptr; + } + + void* ptr = (void*)my_context->segtls[base].base; + return ptr; +} + +const char* GetNativeName(void* p) +{ + static char buff[500] = { 0 }; + { + const char* n = getBridgeName(p); + if (n) + return n; + } + Dl_info info; + if (dladdr(p, &info) == 0) { + const char* ret = GetNameOffset(my_context->maplib, p); + if (ret) + return ret; + sprintf(buff, "%s(%p)", "???", p); + return buff; + } else { + if (info.dli_sname) { + strcpy(buff, info.dli_sname); + if (info.dli_fname) { + strcat(buff, "("); + strcat(buff, info.dli_fname); + strcat(buff, ")"); + } + } else { + sprintf(buff, "%s(%s+%p)", "???", info.dli_fname, (void*)(p - info.dli_fbase)); + return buff; + } + } + return buff; +} + + void PersonalityAddrLimit32Bit(void) { personality(ADDR_LIMIT_32BIT); diff --git a/src/os/os_wine.c b/src/os/os_wine.c index 7e3c58fb..06a8317b 100644 --- a/src/os/os_wine.c +++ b/src/os/os_wine.c @@ -17,13 +17,53 @@ int IsBridgeSignature(char s, char c) return FALSE; } -void PersonalityAddrLimit32Bit(void) { } +void* GetSeg43Base() +{ + return NULL; +} + +void* GetSegmentBase(uint32_t desc) +{ + // FIXME + return NULL; +} + +void EmuInt3(void* emu, void* addr) { } +void* EmuFork(void* emu, int forktype) { return NULL; } + + +void EmuX64Syscall(void* emu) +{ + // FIXME +} + +void EmuX86Syscall(void* emu) +{ + // FIXME +} + +const char* GetNativeName(void* p) +{ + return NULL; +} + + +void PersonalityAddrLimit32Bit(void) +{ +} int IsAddrElfOrFileMapped(uintptr_t addr) { return 0; } + +int IsNativeCall(uintptr_t addr, int is32bits, uintptr_t* calladdress, uint16_t* retn) +{ + return 0; +} + + ULONG_PTR default_zero_bits32 = 0x7fffffff; static uint32_t prot_unix_to_win32(uint32_t unx) diff --git a/src/tools/perfmap.c b/src/os/perfmap.c index c3a9d0e3..700863cf 100644 --- a/src/tools/perfmap.c +++ b/src/os/perfmap.c @@ -4,10 +4,13 @@ #include <errno.h> #include <string.h> #include <assert.h> +#include <unistd.h> #include "debug.h" #include "box64context.h" #include "perfmap.h" + +#ifndef _WIN32 #include "elfloader.h" void writePerfMap(uintptr_t func_addr, uintptr_t code_addr, size_t code_size, const char* inst_name) @@ -19,3 +22,6 @@ void writePerfMap(uintptr_t func_addr, uintptr_t code_addr, size_t code_size, co snprintf(pbuf, sizeof(pbuf), "0x%lx %ld %s:%s\n", code_addr, code_size, symbname, inst_name); write(BOX64ENV(dynarec_perf_map_fd), pbuf, strlen(pbuf)); } +#else +void writePerfMap(uintptr_t func_addr, uintptr_t code_addr, size_t code_size, const char* inst_name) { } +#endif \ No newline at end of file |