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