mirror of
https://github.com/ptitSeb/box64.git
synced 2025-05-09 00:21:32 +08:00
[WOW64] Added non-functional PE build (#2532)
This commit is contained in:
parent
cf32412f98
commit
6b2373af93
@ -351,7 +351,9 @@ set(OS_LINUX_SRC
|
||||
"${BOX64_ROOT}/src/os/emit_signals_linux.c"
|
||||
"${BOX64_ROOT}/src/os/freq_linux.c"
|
||||
"${BOX64_ROOT}/src/os/os_linux.c"
|
||||
"${BOX64_ROOT}/src/os/perfmap.c"
|
||||
"${BOX64_ROOT}/src/os/symbolfuncs_linux.c"
|
||||
"${BOX64_ROOT}/src/os/my_cpuid_linux.c"
|
||||
)
|
||||
|
||||
set(ELFLOADER_SRC
|
||||
@ -367,6 +369,7 @@ set(ELFLOADER_SRC
|
||||
"${BOX64_ROOT}/src/elfs/elfhash.c"
|
||||
"${BOX64_ROOT}/src/elfs/elfload_dump.c"
|
||||
"${BOX64_ROOT}/src/elfs/elfdwarf_private.c"
|
||||
"${BOX64_ROOT}/src/emu/entrypoint.c"
|
||||
"${BOX64_ROOT}/src/emu/x64compstrings.c"
|
||||
"${BOX64_ROOT}/src/emu/x64emu.c"
|
||||
"${BOX64_ROOT}/src/emu/x64printer.c"
|
||||
@ -394,8 +397,6 @@ set(ELFLOADER_SRC
|
||||
"${BOX64_ROOT}/src/tools/callback.c"
|
||||
"${BOX64_ROOT}/src/tools/cleanup.c"
|
||||
"${BOX64_ROOT}/src/tools/gdbjit.c"
|
||||
"${BOX64_ROOT}/src/tools/perfmap.c"
|
||||
"${BOX64_ROOT}/src/tools/my_cpuid.c"
|
||||
"${BOX64_ROOT}/src/tools/fileutils.c"
|
||||
"${BOX64_ROOT}/src/tools/pathcoll.c"
|
||||
"${BOX64_ROOT}/src/tools/rbtree.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;
|
||||
}
|
142
src/emu/entrypoint.c
Normal file
142
src/emu/entrypoint.c
Normal file
@ -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
|
980
src/emu/x64emu.c
980
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];
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "x87emu_private.h"
|
||||
#include "box64context.h"
|
||||
#include "bridge.h"
|
||||
#include "signals.h"
|
||||
|
||||
void print_banner(x64emu_t* ref)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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_
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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_
|
||||
|
@ -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);
|
||||
|
||||
|
22
src/os/emit_signal_wine.c
Normal file
22
src/os/emit_signal_wine.c
Normal file
@ -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
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
#incldue "freq.h"
|
||||
#include "freq.h"
|
||||
|
||||
// TODO: box64_rdtsc?
|
||||
|
||||
|
29
src/os/my_cpuid_wine.c
Normal file
29
src/os/my_cpuid_wine.c
Normal file
@ -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;
|
||||
}
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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
|
@ -63,6 +63,7 @@ set(DYNAREC_PASS_SRC
|
||||
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_f0.c"
|
||||
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_f20f.c"
|
||||
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_f30f.c"
|
||||
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_helper.c"
|
||||
"${BOX64_ROOT}/src/dynarec/dynarec_native_pass.c"
|
||||
)
|
||||
|
||||
@ -120,9 +121,9 @@ set_target_properties(test_interpreter PROPERTIES COMPILE_DEFINITIONS "TEST_INTE
|
||||
|
||||
set(BOX64CPU_SRC
|
||||
"${BOX64_ROOT}/src/custommem.c"
|
||||
"${BOX64_ROOT}/src/dynarec/arm64/arm64_immenc.c"
|
||||
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_arch.c"
|
||||
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_functions.c"
|
||||
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_helper.c"
|
||||
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_jmpnext.c"
|
||||
"${BOX64_ROOT}/src/dynarec/dynablock.c"
|
||||
"${BOX64_ROOT}/src/dynarec/dynarec_native_functions.c"
|
||||
@ -132,11 +133,17 @@ set(BOX64CPU_SRC
|
||||
"${BOX64_ROOT}/src/emu/x64emu.c"
|
||||
"${BOX64_ROOT}/src/emu/x64primop.c"
|
||||
"${BOX64_ROOT}/src/emu/x64shaext.c"
|
||||
"${BOX64_ROOT}/src/emu/x64test.c"
|
||||
"${BOX64_ROOT}/src/emu/x64trace.c"
|
||||
"${BOX64_ROOT}/src/emu/x64run_private.c"
|
||||
"${BOX64_ROOT}/src/emu/x87emu_private.c"
|
||||
"${BOX64_ROOT}/src/os/backtrace.c"
|
||||
"${BOX64_ROOT}/src/os/os_wine.c"
|
||||
"${BOX64_ROOT}/src/os/freq_wine.c"
|
||||
"${BOX64_ROOT}/src/os/symbolfuncs_wine.c"
|
||||
"${BOX64_ROOT}/src/os/emit_signal_wine.c"
|
||||
"${BOX64_ROOT}/src/os/perfmap.c"
|
||||
"${BOX64_ROOT}/src/os/my_cpuid_wine.c"
|
||||
"${BOX64_ROOT}/src/tools/alternate.c"
|
||||
"${BOX64_ROOT}/src/tools/rbtree.c"
|
||||
)
|
||||
|
@ -10,6 +10,11 @@
|
||||
|
||||
uintptr_t box64_pagesize = 4096;
|
||||
|
||||
uint32_t default_gs = 0x2b;
|
||||
uint32_t default_fs = 0;
|
||||
|
||||
int box64_rdtsc = 0;
|
||||
uint8_t box64_rdtsc_shift = 0;
|
||||
int box64_is32bits = 0;
|
||||
int box64_wine = 0; // this is for the emulated x86 Wine.
|
||||
|
||||
@ -19,6 +24,23 @@ box64env_t* GetCurEnvByAddr(uintptr_t addr) {
|
||||
return &box64env;
|
||||
}
|
||||
|
||||
int is_addr_unaligned(uintptr_t addr)
|
||||
{
|
||||
// FIXME
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef void (*wrapper_t)(x64emu_t* emu, uintptr_t fnc);
|
||||
int isSimpleWrapper(wrapper_t fun)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int isRetX87Wrapper(wrapper_t fun)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int arm64_asimd = 0;
|
||||
int arm64_aes = 0;
|
||||
int arm64_pmull = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user