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/emu | |
| parent | cf32412f986a5a9c281dda5dc24bf22641a305ed (diff) | |
| download | box64-6b2373af93e033019dd1ddd5683f2d866e253d8c.tar.gz box64-6b2373af93e033019dd1ddd5683f2d866e253d8c.zip | |
[WOW64] Added non-functional PE build (#2532)
Diffstat (limited to 'src/emu')
| -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 |
6 files changed, 1126 insertions, 1221 deletions
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 |