about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2022-07-31 18:19:25 +0200
committerptitSeb <sebastien.chev@gmail.com>2022-08-06 16:10:17 +0200
commit642260bdb63eb48667f35d21b376b04f0d5e1976 (patch)
tree2ed6f09e5f9758587e985c5a62e3da252b8379a0 /src
parentbafa85e772fff6b0a279c96678a7f92d1ce842f0 (diff)
downloadbox64-642260bdb63eb48667f35d21b376b04f0d5e1976.tar.gz
box64-642260bdb63eb48667f35d21b376b04f0d5e1976.zip
Chenged Interpretor so RIP is updated on opcode success (better precision for Signal)
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64/dynarec_arm64_00.c2
-rw-r--r--src/emu/modrm.h58
-rwxr-xr-xsrc/emu/x64int3.c33
-rwxr-xr-xsrc/emu/x64run.c178
-rw-r--r--src/emu/x64run0f.c39
-rw-r--r--src/emu/x64run64.c35
-rw-r--r--src/emu/x64run66.c29
-rw-r--r--src/emu/x64run660f.c20
-rw-r--r--src/emu/x64run6664.c8
-rw-r--r--src/emu/x64run66d9.c8
-rw-r--r--src/emu/x64run66dd.c8
-rw-r--r--src/emu/x64run66f0.c10
-rw-r--r--src/emu/x64run67.c22
-rw-r--r--src/emu/x64run670f.c8
-rw-r--r--src/emu/x64run6766.c8
-rw-r--r--src/emu/x64run67660f.c6
-rwxr-xr-xsrc/emu/x64run_private.c146
-rwxr-xr-xsrc/emu/x64run_private.h126
-rw-r--r--src/emu/x64rund8.c6
-rw-r--r--src/emu/x64rund9.c8
-rw-r--r--src/emu/x64runda.c6
-rw-r--r--src/emu/x64rundb.c8
-rw-r--r--src/emu/x64rundc.c6
-rw-r--r--src/emu/x64rundd.c8
-rw-r--r--src/emu/x64runde.c8
-rw-r--r--src/emu/x64rundf.c8
-rw-r--r--src/emu/x64runf0.c16
-rw-r--r--src/emu/x64runf20f.c8
-rw-r--r--src/emu/x64runf30f.c6
-rwxr-xr-xsrc/emu/x64syscall.c8
30 files changed, 434 insertions, 406 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index 423fa821..6bee4991 100755
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -1652,6 +1652,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     } else {
                         GETIP(ip+1); // read the 0xCC
                         STORE_XEMU_CALL(xRIP);
+                        ADDx_U12(x1, xEmu, (uint32_t)offsetof(x64emu_t, ip)); // setup addr as &emu->ip
                         CALL_S(x64Int3, -1);
                         LOAD_XEMU_CALL(xRIP);
                         addr+=8+8;
@@ -2099,6 +2100,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     } else {
                         GETIP_(dyn->insts[ninst].natcall); // read the 0xCC already
                         STORE_XEMU_CALL(xRIP);
+                        ADDx_U12(x1, xEmu, (uint32_t)offsetof(x64emu_t, ip)); // setup addr as &emu->ip
                         CALL_S(x64Int3, -1);
                         LOAD_XEMU_CALL(xRIP);
                         TABLE64(x3, dyn->insts[ninst].natcall);
diff --git a/src/emu/modrm.h b/src/emu/modrm.h
index dcb1a9ab..01f83e1f 100644
--- a/src/emu/modrm.h
+++ b/src/emu/modrm.h
@@ -1,38 +1,40 @@
-#define F8      *(uint8_t*)(R_RIP++)

-#define F8S     *(int8_t*)(R_RIP++)

-#define F16     *(uint16_t*)(R_RIP+=2, R_RIP-2)

-#define F16S    *(int16_t*)(R_RIP+=2, R_RIP-2)

-#define F32     *(uint32_t*)(R_RIP+=4, R_RIP-4)

-#define F32S    *(int32_t*)(R_RIP+=4, R_RIP-4)

+#define F8      *(uint8_t*)(addr++)

+#define F8S     *(int8_t*)(addr++)

+#define F16     *(uint16_t*)(addr+=2, addr-2)

+#define F16S    *(int16_t*)(addr+=2, addr-2)

+#define F32     *(uint32_t*)(addr+=4, addr-4)

+#define F32S    *(int32_t*)(addr+=4, addr-4)

 #define F32S64  (uint64_t)(int64_t)F32S

-#define F64     *(uint64_t*)(R_RIP+=8, R_RIP-8)

-#define F64S    *(int64_t*)(R_RIP+=8, R_RIP-8)

-#define PK(a)   *(uint8_t*)(R_RIP+a)

+#define F64     *(uint64_t*)(addr+=8, addr-8)

+#define F64S    *(int64_t*)(addr+=8, addr-8)

+#define PK(a)   *(uint8_t*)(addr+a)

 #ifdef DYNAREC

 #define STEP if(step) return 0;

+#define STEP2 if(step) {R_RIP = addr; return 0;}

 #else

 #define STEP

+#define STEP2

 #endif

 

-#define GETED(D)            oped=GetEd(emu, rex, nextop, D)

-#define GETED32(D)          oped=GetEd32O(emu, rex, nextop, D, 0)

-#define GETED_OFFS(D, O)    oped=GetEdO(emu, rex, nextop, D, O)

-#define GETGD               opgd=GetGd(emu, rex, nextop)

-#define GETEB(D)            oped=GetEb(emu, rex, nextop, D)

-#define GETEB32(D)          oped=GetEb32O(emu, rex, nextop, D, 0)

-#define GETEB_OFFS(D, O)    oped=GetEbO(emu, rex, nextop, D, O)

-#define GETGB               opgd=GetGb(emu, rex, nextop)

-#define GETEW(D)            oped=GetEw(emu, rex, nextop, D)

-#define GETEW32(D)          oped=GetEw32O(emu, rex, nextop, D, 0)

-#define GETEW_OFFS(D, O)    oped=GetEdO(emu, rex, nextop, D, O)

-#define GETGW               opgd=GetGw(emu, rex, nextop)

-#define GETEX(D)            opex=GetEx(emu, rex, nextop, D)

-#define GETEX32(D)          opex=GetEx32O(emu, rex, nextop, D, 0)

-#define GETEX_OFFS(D, O)    opex=GetExO(emu, rex, nextop, D, O)

-#define GETGX               opgx=GetGx(emu, rex, nextop)

-#define GETEM(D)            opem=GetEm(emu, rex, nextop, D)

-#define GETEM32(D)          opem=GetEm32O(emu, rex, nextop, D, 0)

-#define GETGM               opgm=GetGm(emu, rex, nextop)

+#define GETED(D)            oped=GetEd(emu, &addr, rex, nextop, D)

+#define GETED32(D)          oped=GetEd32O(emu, &addr, rex, nextop, D, 0)

+#define GETED_OFFS(D, O)    oped=GetEdO(emu, &addr, rex, nextop, D, O)

+#define GETGD               opgd=GetGd(emu, &addr, rex, nextop)

+#define GETEB(D)            oped=GetEb(emu, &addr, rex, nextop, D)

+#define GETEB32(D)          oped=GetEb32O(emu, &addr, rex, nextop, D, 0)

+#define GETEB_OFFS(D, O)    oped=GetEbO(emu, &addr, rex, nextop, D, O)

+#define GETGB               opgd=GetGb(emu, &addr, rex, nextop)

+#define GETEW(D)            oped=GetEw(emu, &addr, rex, nextop, D)

+#define GETEW32(D)          oped=GetEw32O(emu, &addr, rex, nextop, D, 0)

+#define GETEW_OFFS(D, O)    oped=GetEdO(emu, &addr, rex, nextop, D, O)

+#define GETGW               opgd=GetGw(emu, &addr, rex, nextop)

+#define GETEX(D)            opex=GetEx(emu, &addr, rex, nextop, D)

+#define GETEX32(D)          opex=GetEx32O(emu, &addr, rex, nextop, D, 0)

+#define GETEX_OFFS(D, O)    opex=GetExO(emu, &addr, rex, nextop, D, O)

+#define GETGX               opgx=GetGx(emu, &addr, rex, nextop)

+#define GETEM(D)            opem=GetEm(emu, &addr, rex, nextop, D)

+#define GETEM32(D)          opem=GetEm32O(emu, &addr, rex, nextop, D, 0)

+#define GETGM               opgm=GetGm(emu, &addr, rex, nextop)

 #define ED  oped

 #define GD  opgd

 #define EB  oped

diff --git a/src/emu/x64int3.c b/src/emu/x64int3.c
index 2faba3f2..f79d897d 100755
--- a/src/emu/x64int3.c
+++ b/src/emu/x64int3.c
@@ -65,20 +65,31 @@ x64emu_t* x64emu_fork(x64emu_t* emu, int forktype)
     return emu;
 }
 
+static uint64_t F64(uintptr_t* addr) {
+    uint64_t ret = *(uint64_t*)*addr;
+    *addr+=8;
+    return ret;
+}
+static uint8_t Peek8(uintptr_t addr, uintptr_t offset)
+{
+    return *(uint8_t*)(addr+offset);
+}
 extern int errno;
-void x64Int3(x64emu_t* emu)
+void x64Int3(x64emu_t* emu, uintptr_t* addr)
 {
-    if(Peek(emu, 0)=='S' && Peek(emu, 1)=='C') // Signature for "Out of x86 door"
+    if(Peek8(*addr, 0)=='S' && Peek8(*addr, 1)=='C') // Signature for "Out of x86 door"
     {
-        R_RIP += 2;
-        uintptr_t addr = Fetch64(emu);
-        if(addr==0) {
+        *addr += 2;
+        uintptr_t a = F64(addr);
+        if(a==0) {
+            R_RIP = *addr;
             //printf_log(LOG_INFO, "%p:Exit x86 emu (emu=%p)\n", *(void**)(R_ESP), emu);
             emu->quit=1; // normal quit
         } else {
             RESET_FLAGS(emu);
-            wrapper_t w = (wrapper_t)addr;
-            addr = Fetch64(emu);
+            wrapper_t w = (wrapper_t)a;
+            a = F64(addr);
+            R_RIP = *addr;
             /* This party can be used to trace only 1 specific lib (but it is quite slow)
             elfheader_t *h = FindElfAddress(my_context, *(uintptr_t*)(R_ESP));
             int have_trace = 0;
@@ -100,8 +111,8 @@ void x64Int3(x64emu_t* emu)
                 uint64_t *pu64 = NULL;
                 uint32_t *pu32 = NULL;
                 const char *s = NULL;
-                s = GetNativeName((void*)addr);
-                if(addr==(uintptr_t)PltResolver) {
+                s = GetNativeName((void*)a);
+                if(a==(uintptr_t)PltResolver) {
                     snprintf(buff, 256, "%s", cycle_log?"PltResolver ":" ... ");
                 } else if (!strcmp(s, "__open") || !strcmp(s, "open") || !strcmp(s, "open ") || !strcmp(s, "open64")) {
                     tmp = (char*)(R_RDI);
@@ -234,7 +245,7 @@ void x64Int3(x64emu_t* emu)
                 }
                 if(!cycle_log) printf_log(LOG_NONE, "%s =>", buff);
                 pthread_mutex_unlock(&emu->context->mutex_trace);
-                w(emu, addr);   // some function never come back, so unlock the mutex first!
+                w(emu, a);   // some function never come back, so unlock the mutex first!
                 pthread_mutex_lock(&emu->context->mutex_trace);
                 if(post)
                     switch(post) { // Only ever 2 for now...
@@ -267,7 +278,7 @@ void x64Int3(x64emu_t* emu)
                     printf_log(LOG_NONE, " return 0x%lX%s%s\n", R_RAX, buff2, buff3);
                 pthread_mutex_unlock(&emu->context->mutex_trace);
             } else
-                w(emu, addr);
+                w(emu, a);
         }
         return;
     }
diff --git a/src/emu/x64run.c b/src/emu/x64run.c
index 032ef9dd..09a0d4f7 100755
--- a/src/emu/x64run.c
+++ b/src/emu/x64run.c
@@ -40,33 +40,33 @@ int Run(x64emu_t *emu, int step)
     uint32_t tmp32u, tmp32u2;
     int64_t tmp64s;
     uint64_t tmp64u, tmp64u2, tmp64u3;
+    uintptr_t addr = R_RIP;
     rex_t rex;
     int rep;    // 0 none, 1=F2 prefix, 2=F3 prefix
     int unimp = 0;
 
     if(emu->quit)
         return 0;
-    if(R_RIP==0) {
+    if(addr==0) {
         emu->quit = 1;
         printf_log(LOG_INFO, "Ask to run at NULL, quit silently\n");
         return 0;
     }
-
     //ref opcode: http://ref.x64asm.net/geek32.html#xA1
-    printf_log(LOG_DEBUG, "Run X86 (%p), RIP=%p, Stack=%p\n", emu, (void*)R_RIP, (void*)R_RSP);
+    printf_log(LOG_DEBUG, "Run X86 (%p), RIP=%p, Stack=%p\n", emu, (void*)addr, (void*)R_RSP);
 
 x64emurun:
 
     while(1) {
 #ifdef HAVE_TRACE
-        __builtin_prefetch((void*)R_RIP, 0, 0); 
+        __builtin_prefetch((void*)addr, 0, 0); 
         emu->prev2_ip = emu->old_ip;
         if(my_context->dec && (
             (trace_end == 0) 
-            || ((R_RIP >= trace_start) && (R_RIP < trace_end))) )
-                PrintTrace(emu, R_RIP, 0);
+            || ((addr >= trace_start) && (addr < trace_end))) )
+                PrintTrace(emu, addr, 0);
 #endif
-        emu->old_ip = R_RIP;
+        emu->old_ip = addr;
 
         opcode = F8;
         
@@ -135,26 +135,28 @@ x64emurun:
         case 0x0F:                      /* More instructions */
             switch(rep) {
                 case 1:
-                    if(RunF20F(emu, rex)) {
+                    if(!(addr = RunF20F(emu, rex, addr))) {
                         unimp = 1;
                         goto fini;
                     }
                     break;
                 case 2:
-                    if(RunF30F(emu, rex)) {
+                    if(!(addr = RunF30F(emu, rex, addr))) {
                         unimp = 1;
                         goto fini;
                     }
                     break;
                 default:
-                    if(Run0F(emu, rex)) {
+                    if(!(addr = Run0F(emu, rex, addr))) {
                         unimp = 1;
                         goto fini;
                     }
                     break;
             }
-            if(emu->quit)
+            if(emu->quit) {
+                R_RIP = addr;
                 goto fini;
+            }
             break;
         GO(0x10, adc)                   /* ADC 0x10 -> 0x15 */
         GO(0x18, sbb)                   /* SBB 0x18 -> 0x1D */
@@ -250,36 +252,44 @@ x64emurun:
                     GD->sdword[0] = ED->sdword[0];  // meh?
             break;
         case 0x64:                      /* FS: prefix */
-            if(Run64(emu, rex, _FS)) {
+            if(!(addr = Run64(emu, rex, _FS, addr))) {
                 unimp = 1;
                 goto fini;
             }
-            if(emu->quit)
+            if(emu->quit) {
+                R_RIP = addr;
                 goto fini;
+            }
             break;
         case 0x65:                      /* GS: prefix */
-            if(Run64(emu, rex, _GS)) {
+            if(!(addr = Run64(emu, rex, _GS, addr))) {
                 unimp = 1;
                 goto fini;
             }
-            if(emu->quit)
+            if(emu->quit) {
+                R_RIP = addr;
                 goto fini;
+            }
             break;
         case 0x66:                      /* 16bits prefix */
-            if(Run66(emu, rex, rep)) {
+            if(!(addr = Run66(emu, rex, rep, addr))) {
                 unimp = 1;
                 goto fini;
             }
-            if(emu->quit)
+            if(emu->quit) {
+                R_RIP = addr;
                 goto fini;
+            }
             break;
         case 0x67:                      /* reduce EASize prefix */
-            if(Run67(emu, rex, rep)) {
+            if(!(addr = Run67(emu, rex, rep, addr))) {
                 unimp = 1;
                 goto fini;
             }
-            if(emu->quit)
+            if(emu->quit) {
+                R_RIP = addr;
                 goto fini;
+            }
             break;
         case 0x68:                      /* Push Id */
             Push(emu, F32S64);
@@ -313,14 +323,13 @@ x64emurun:
         case 0x6E:                      /* OUTSB DX */
         case 0x6F:                      /* OUTSL DX */
             // this is a privilege opcode...
-            --R_RIP;
             emit_signal(emu, SIGSEGV, (void*)R_RIP, 0);
             STEP;
             break;
 
         GOCOND(0x70
             ,   tmp8s = F8S; CHECK_FLAGS(emu);
-            ,   R_RIP += tmp8s;
+            ,   addr += tmp8s;
             ,
             )                           /* Jxx Ib */
         
@@ -1027,13 +1036,13 @@ x64emurun:
             break;
         case 0xC2:                      /* RETN Iw */
             tmp16u = F16;
-            R_RIP = Pop(emu);
+            addr = Pop(emu);
             R_RSP += tmp16u;
-            STEP
+            STEP2
             break;
         case 0xC3:                      /* RET */
-            R_RIP = Pop(emu);
-            STEP
+            addr = Pop(emu);
+            STEP2
             break;
 
         case 0xC6:                      /* MOV Eb,Ib */
@@ -1073,19 +1082,19 @@ x64emurun:
             break;
 
         case 0xCC:                      /* INT 3 */
-            x64Int3(emu);
-            if(emu->quit) goto fini;
+            x64Int3(emu, &addr);
+            if(emu->quit) goto fini;    // R_RIP is up to date when returning from x64Int3
+            addr = R_RIP;
             break;
         case 0xCD:                      /* INT n */
             // this is a privilege opcode...
-            --R_RIP;
             emit_signal(emu, SIGSEGV, (void*)R_RIP, 0);
             STEP;
             break;
 
 
         case 0xCF:                      /* IRET */
-            R_RIP = Pop(emu);
+            addr = Pop(emu);
             emu->segs[_CS] = Pop(emu)&0xffff;
             emu->segs_serial[_CS] = 0;
             emu->eflags.x64 = ((Pop(emu) & 0x3F7FD7)/* & (0xffff-40)*/ ) | 0x2; // mask off res2 and res3 and on res1
@@ -1094,6 +1103,7 @@ x64emurun:
             emu->segs_serial[_SS] = 0;
             R_RSP= tmp64u;
             RESET_FLAGS(emu);
+            R_RIP = addr;
             goto fini;      // exit, to recompute CS if needed
             break;
         case 0xD0:                      /* GRP2 Eb,1 */
@@ -1158,145 +1168,160 @@ x64emurun:
             R_AL = *(uint8_t*)(R_RBX + R_AL);
             break;
         case 0xD8:                      /* x87 opcodes */
-            if(RunD8(emu, rex)) {
+            if(!(addr = RunD8(emu, rex, addr))) {
                 unimp = 1;
                 goto fini;
             }
-            if(emu->quit)
+            if(emu->quit) {
+                R_RIP = addr;
                 goto fini;
+            }
             break;
         case 0xD9:                      /* x87 opcodes */
-            if(RunD9(emu, rex)) {
+            if(!(addr = RunD9(emu, rex, addr))) {
                 unimp = 1;
                 goto fini;
             }
-            if(emu->quit)
+            if(emu->quit) {
+                R_RIP = addr;
                 goto fini;
+            }
             break;
         case 0xDA:                      /* x87 opcodes */
-            if(RunDA(emu, rex)) {
+            if(!(addr = RunDA(emu, rex, addr))) {
                 unimp = 1;
                 goto fini;
             }
-            if(emu->quit)
+            if(emu->quit) {
+                R_RIP = addr;
                 goto fini;
+            }
             break;
         case 0xDB:                      /* x87 opcodes */
-            if(RunDB(emu, rex)) {
+            if(!(addr = RunDB(emu, rex, addr))) {
                 unimp = 1;
                 goto fini;
             }
-            if(emu->quit)
+            if(emu->quit) {
+                R_RIP = addr;
                 goto fini;
+            }
             break;
         case 0xDC:                      /* x87 opcodes */
-            if(RunDC(emu, rex)) {
+            if(!(addr = RunDC(emu, rex, addr))) {
                 unimp = 1;
                 goto fini;
             }
-            if(emu->quit)
+            if(emu->quit) {
+                R_RIP = addr;
                 goto fini;
+            }
             break;
         case 0xDD:                      /* x87 opcodes */
-            if(RunDD(emu, rex)) {
+            if(!(RunDD(emu, rex, addr))) {
                 unimp = 1;
                 goto fini;
             }
-            if(emu->quit)
+            if(emu->quit) {
+                R_RIP = addr;
                 goto fini;
+            }
             break;
         case 0xDE:                      /* x87 opcodes */
-            if(RunDE(emu, rex)) {
+            if(!(addr = RunDE(emu, rex, addr))) {
                 unimp = 1;
                 goto fini;
             }
-            if(emu->quit)
+            if(emu->quit) {
+                R_RIP = addr;
                 goto fini;
+            }
             break;
         case 0xDF:                      /* x87 opcodes */
-            if(RunDF(emu, rex)) {
+            if(!(addr = RunDF(emu, rex, addr))) {
                 unimp = 1;
                 goto fini;
             }
-            if(emu->quit)
+            if(emu->quit) {
+                R_RIP = addr;
                 goto fini;
+            }
             break;
         case 0xE0:                      /* LOOPNZ */
             CHECK_FLAGS(emu);
             tmp8s = F8S;
             --R_RCX; // don't update flags
             if(R_RCX && !ACCESS_FLAG(F_ZF))
-                R_RIP += tmp8s;
-            STEP
+                addr += tmp8s;
+            STEP2
             break;
         case 0xE1:                      /* LOOPZ */
             CHECK_FLAGS(emu);
             tmp8s = F8S;
             --R_RCX; // don't update flags
             if(R_RCX && ACCESS_FLAG(F_ZF))
-                R_RIP += tmp8s;
-            STEP
+                addr += tmp8s;
+            STEP2
             break;
         case 0xE2:                      /* LOOP */
             tmp8s = F8S;
             --R_RCX; // don't update flags
             if(R_RCX)
-                R_RIP += tmp8s;
-            STEP
+                addr += tmp8s;
+            STEP2
             break;
         case 0xE3:                      /* JECXZ */
             tmp8s = F8S;
             if(!R_RCX)
-                R_RIP += tmp8s;
-            STEP
+                addr += tmp8s;
+            STEP2
             break;
         case 0xE4:                      /* IN AL, XX */
         case 0xE5:                      /* IN EAX, XX */
         case 0xE6:                      /* OUT XX, AL */
         case 0xE7:                      /* OUT XX, EAX */
             // this is a privilege opcode...
-            --R_RIP;
             emit_signal(emu, SIGSEGV, (void*)R_RIP, 0);
             STEP;
             break;
         case 0xE8:                      /* CALL Id */
             tmp32s = F32S; // call is relative
-            Push(emu, R_RIP);
-            R_RIP += tmp32s;
-            STEP
+            Push(emu, addr);
+            addr += tmp32s;
+            STEP2
             break;
         case 0xE9:                      /* JMP Id */
             tmp32s = F32S; // jmp is relative
-            R_RIP += tmp32s;
-            STEP
+            addr += tmp32s;
+            STEP2
             break;
 
         case 0xEB:                      /* JMP Ib */
             tmp32s = F8S; // jump is relative
-            R_RIP += tmp32s;
-            STEP
+            addr += tmp32s;
+            STEP2
             break;
         case 0xEC:                      /* IN AL, DX */
         case 0xED:                      /* IN EAX, DX */
         case 0xEE:                      /* OUT DX, AL */
         case 0xEF:                      /* OUT DX, EAX */
             // this is a privilege opcode...
-            --R_RIP;
             emit_signal(emu, SIGSEGV, (void*)R_RIP, 0);
             STEP;
             break;
         case 0xF0:                      /* LOCK prefix */
-            if(RunF0(emu, rex)) {
+            if(!(addr = RunF0(emu, rex, addr))) {
                 unimp = 1;
                 goto fini;
             }
-            if(emu->quit)
+            if(emu->quit) {
+                R_RIP = addr;
                 goto fini;
+            }
             break;
 
         case 0xF4:                      /* HLT */
             // this is a privilege opcode...
-            --R_RIP;
             emit_signal(emu, SIGSEGV, (void*)R_RIP, 0);
             STEP;
             break;
@@ -1414,13 +1439,11 @@ x64emurun:
             break;
         case 0xFA:                      /* CLI */
             // this is a privilege opcode...
-            --R_RIP;
             emit_signal(emu, SIGSEGV, (void*)R_RIP, 0);
             STEP;
             break;
         case 0xFB:                      /* STI */
             // this is a privilege opcode...
-            --R_RIP;
             emit_signal(emu, SIGSEGV, (void*)R_RIP, 0);
             STEP;
             break;
@@ -1471,32 +1494,30 @@ x64emurun:
                     break;
                 case 2:                 /* CALL NEAR Ed */
                     tmp64u = (uintptr_t)getAlternate((void*)ED->q[0]);
-                    Push(emu, R_RIP);
-                    R_RIP = tmp64u;
-                    STEP
+                    Push(emu, addr);
+                    addr = tmp64u;
+                    STEP2
                     break;
                 case 3:                 /* CALL FAR Ed */
                     if(MODREG) {
-                        R_RIP = emu->old_ip;
                         printf_log(LOG_NONE, "Illegal Opcode %p: %02X %02X %02X %02X\n", (void*)R_RIP, opcode, nextop, PK(2), PK(3));
                         emu->quit=1;
                         emu->error |= ERR_ILLEGAL;
                         goto fini;
                     } else {
                         Push(emu, R_CS);
-                        Push(emu, R_RIP);
-                        R_RIP = (uintptr_t)getAlternate((void*)ED->q[0]);   // check CS?
+                        Push(emu, addr);
+                        R_RIP = addr = (uintptr_t)getAlternate((void*)ED->q[0]);   // check CS?
                         R_CS = (ED+1)->word[0];
                         goto fini;  // exit loop to recompute new CS...
                     }
                     break;
                 case 4:                 /* JMP NEAR Ed */
-                    R_RIP = (uintptr_t)getAlternate((void*)ED->q[0]);
-                    STEP
+                    addr = (uintptr_t)getAlternate((void*)ED->q[0]);
+                    STEP2
                     break;
                 case 5:                 /* JMP FAR Ed */
                     if(MODREG) {
-                        R_RIP = emu->old_ip;
                         printf_log(LOG_NONE, "Illegal Opcode %p: 0x%02X 0x%02X %02X %02X\n", (void*)R_RIP, opcode, nextop, PK(2), PK(3));
                         emu->quit=1;
                         emu->error |= ERR_ILLEGAL;
@@ -1512,7 +1533,6 @@ x64emurun:
                     Push(emu, tmp64u);  // avoid potential issue with push [esp+...]
                     break;
                 default:
-                    R_RIP = emu->old_ip;
                     printf_log(LOG_NONE, "Illegal Opcode %p: %02X %02X %02X %02X %02X %02X\n",(void*)R_RIP, opcode, nextop, PK(2), PK(3), PK(4), PK(5));
                     emu->quit=1;
                     emu->error |= ERR_ILLEGAL;
@@ -1523,18 +1543,19 @@ x64emurun:
             unimp = 1;
             goto fini;
         }
+        R_RIP = addr;
     }
 
 
 fini:
     printf_log(LOG_DEBUG, "End of X86 run (%p), RIP=%p, Stack=%p, unimp=%d, emu->fork=%d, emu->uc_link=%p, emu->quit=%d\n", emu, (void*)R_RIP, (void*)R_RSP, unimp, emu->fork, emu->uc_link, emu->quit);
     if(unimp) {
-        R_RIP = emu->old_ip;
         emu->quit = 1;
         UnimpOpcode(emu);
     }
     // fork handling
     if(emu->fork) {
+        addr = R_RIP;
         if(step)
             return 0;
         int forktype = emu->fork;
@@ -1547,6 +1568,7 @@ fini:
     else if(emu->uc_link) {
         emu->quit = 0;
         my_setcontext(emu, emu->uc_link);
+        addr = R_RIP;
         goto x64emurun;
     }
     return 0;
diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c
index 4441b2a0..a07c2030 100644
--- a/src/emu/x64run0f.c
+++ b/src/emu/x64run0f.c
@@ -28,7 +28,7 @@
 

 #include "modrm.h"

 

-int Run0F(x64emu_t *emu, rex_t rex)

+uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr)

 {

     uint8_t opcode;

     uint8_t nextop;

@@ -46,23 +46,21 @@ int Run0F(x64emu_t *emu, rex_t rex)
     switch(opcode) {

 

         case 0x05:                      /* SYSCALL */

+            R_RIP = addr;

             x64Syscall(emu);

             break;

         case 0x06:                      /* CLTS */

             // this is a privilege opcode...

-            R_RIP-=2;

             emit_signal(emu, SIGSEGV, (void*)R_RIP, 0);

             break;

 

         case 0x08:                      /* INVD */

         case 0x09:                      /* WBINVD */

             // this is a privilege opcode...

-            R_RIP-=2;

             emit_signal(emu, SIGSEGV, (void*)R_RIP, 0);

             break;

 

         case 0x0B:                      /* UD2 */

-            R_RIP-=2;

             emit_signal(emu, SIGILL, (void*)R_RIP, 0);

             break;

 

@@ -74,7 +72,7 @@ int Run0F(x64emu_t *emu, rex_t rex)
                     __builtin_prefetch((void*)ED, 1, 0);

                     break;

                 default:    //???

-                    return 1;

+                    return 0;

             }

             break;

 

@@ -160,7 +158,6 @@ int Run0F(x64emu_t *emu, rex_t rex)
         case 0x22:                      /* MOV cxR, REG */

         case 0x23:                      /* MOV drX, REG */

             // this is a privilege opcode...

-            R_RIP-=2;

             emit_signal(emu, SIGSEGV, (void*)R_RIP, 0);

             break;

 

@@ -308,7 +305,7 @@ int Run0F(x64emu_t *emu, rex_t rex)
                     break;

 

                 default:

-                    return 1;

+                    return 0;

             }

             break;

 

@@ -334,7 +331,7 @@ int Run0F(x64emu_t *emu, rex_t rex)
                     break;

 

                 default:

-                    return 1;

+                    return 0;

             }

             break;

 

@@ -649,7 +646,7 @@ int Run0F(x64emu_t *emu, rex_t rex)
                         for (int i=0; i<4; ++i) EM->uw[i] <<= tmp8u;

                     break;

                 default:

-                    return 1;

+                    return 0;

             }

             break;

         case 0x72:  /* GRP */

@@ -675,7 +672,7 @@ int Run0F(x64emu_t *emu, rex_t rex)
                         for (int i=0; i<2; ++i) EM->ud[i] <<= tmp8u;

                     break;

                 default:

-                    return 1;

+                    return 0;

             }

             break;

         case 0x73:  /* GRP */

@@ -697,7 +694,7 @@ int Run0F(x64emu_t *emu, rex_t rex)
                         {EM->q <<= tmp8u;}

                     break;

                 default:

-                    return 1;

+                    return 0;

             }

             break;

         case 0x74:                       /* PCMPEQB Gm,Em */

@@ -751,7 +748,7 @@ int Run0F(x64emu_t *emu, rex_t rex)
             break;

         GOCOND(0x80

             , tmp32s = F32S; CHECK_FLAGS(emu);

-            , R_RIP += tmp32s;

+            , addr += tmp32s;

             ,

         )                               /* 0x80 -> 0x8F Jxx */

         GOCOND(0x90

@@ -856,13 +853,13 @@ int Run0F(x64emu_t *emu, rex_t rex)
         case 0xAE:                      /* Grp Ed (SSE) */

             nextop = F8;

             if((nextop&0xF8)==0xE8) {

-                return 0;                   /* LFENCE */

+                return addr;            /* LFENCE */

             }

             if((nextop&0xF8)==0xF0) {

-                return 0;                   /* MFENCE */

+                return addr;            /* MFENCE */

             }

             if((nextop&0xF8)==0xF8) {

-                return 0;                   /* SFENCE */

+                return addr;            /* SFENCE */

             }

             GETED(0);

             switch((nextop>>3)&7) {

@@ -890,7 +887,7 @@ int Run0F(x64emu_t *emu, rex_t rex)
                     #endif

                     break;

                 default:

-                    return 1;

+                    return 0;

             }

             break;

         case 0xAF:                      /* IMUL Gd,Ed */

@@ -1062,7 +1059,7 @@ int Run0F(x64emu_t *emu, rex_t rex)
                     break;

 

                 default:

-                    return 1;

+                    return 0;

             }

             break;

         case 0xBB:                      /* BTC Ed,Gd */

@@ -1288,7 +1285,7 @@ int Run0F(x64emu_t *emu, rex_t rex)
                     }

                     break;

                 default:

-                    return 1;

+                    return 0;

             }

             break;

         case 0xC8:

@@ -1477,7 +1474,7 @@ int Run0F(x64emu_t *emu, rex_t rex)
         case 0xE7:                   /* MOVNTQ Em,Gm */

             nextop = F8;

             if((nextop&0xC0)==0xC0)

-                return 1;

+                return 0;

             GETEM(0);

             GETGM;

             EM->q = GM->q;

@@ -1630,7 +1627,7 @@ int Run0F(x64emu_t *emu, rex_t rex)
             break;

 

         default:

-            return 1;

+            return 0;

     }

-    return 0;

+    return addr;

 }
\ No newline at end of file
diff --git a/src/emu/x64run64.c b/src/emu/x64run64.c
index ad637ce2..be88c157 100644
--- a/src/emu/x64run64.c
+++ b/src/emu/x64run64.c
@@ -22,7 +22,7 @@
 

 #include "modrm.h"

 

-int Run64(x64emu_t *emu, rex_t rex, int seg)

+uintptr_t Run64(x64emu_t *emu, rex_t rex, int seg, uintptr_t addr)

 {

     uint8_t opcode;

     uint8_t nextop;

@@ -135,7 +135,7 @@ int Run64(x64emu_t *emu, rex_t rex, int seg)
                             }

                             break;

                         default:

-                            return 1;

+                            return 0;

                     }

                     break;

                 case 0x11:

@@ -159,7 +159,7 @@ int Run64(x64emu_t *emu, rex_t rex, int seg)
                             EX->ud[0] = GX->ud[0];

                             break;

                         default:

-                            return 1;

+                            return 0;

                     }

                     break;

 

@@ -173,7 +173,7 @@ int Run64(x64emu_t *emu, rex_t rex, int seg)
                             EX->q[1] = GX->q[1];

                             break;

                         default:

-                            return 1;

+                            return 0;

                     }

                     break;

 

@@ -187,7 +187,7 @@ int Run64(x64emu_t *emu, rex_t rex, int seg)
                             break;

 

                         default:

-                            return 1;

+                            return 0;

                     }

                     break;

 

@@ -201,7 +201,7 @@ int Run64(x64emu_t *emu, rex_t rex, int seg)
                             break;

                             

                         default:

-                            return 1;

+                            return 0;

                     }

                     break;

 

@@ -223,7 +223,7 @@ int Run64(x64emu_t *emu, rex_t rex, int seg)
                     break;

 

                 default:

-                    return 1;

+                    return 0;

             }

             break;

 

@@ -268,7 +268,7 @@ int Run64(x64emu_t *emu, rex_t rex, int seg)
             break;

 

         case 0x66:

-            return Run6664(emu, rex);

+            return Run6664(emu, rex, addr);

 

         case 0x80:                      /* GRP Eb,Ib */

             nextop = F8;

@@ -525,36 +525,34 @@ int Run64(x64emu_t *emu, rex_t rex, int seg)
                     break;

                 case 2:                 /* CALL NEAR Ed */

                     tmp64u = (uintptr_t)getAlternate((void*)ED->q[0]);

-                    Push(emu, R_RIP);

-                    R_RIP = tmp64u;

+                    Push(emu, addr);

+                    addr = tmp64u;

                     break;

                 case 3:                 /* CALL FAR Ed */

                     if(nextop>0xC0) {

-                        R_RIP = emu->old_ip;

                         printf_log(LOG_NONE, "Illegal Opcode %p: %02X %02X %02X %02X\n", (void*)R_RIP, opcode, nextop, PK(2), PK(3));

                         emu->quit=1;

                         emu->error |= ERR_ILLEGAL;

                         return 0;

                     } else {

                         Push16(emu, R_CS);

-                        Push(emu, R_RIP);

-                        R_RIP = ED->dword[0];

+                        Push(emu, addr);

+                        R_RIP = addr = ED->dword[0];

                         R_CS = (ED+1)->word[0];

                         return 0;  // exit loop to recompute new CS...

                     }

                     break;

                 case 4:                 /* JMP NEAR Ed */

-                    R_RIP = (uintptr_t)getAlternate((void*)ED->q[0]);

+                    addr = (uintptr_t)getAlternate((void*)ED->q[0]);

                     break;

                 case 5:                 /* JMP FAR Ed */

                     if(nextop>0xc0) {

-                        R_RIP = emu->old_ip;

                         printf_log(LOG_NONE, "Illegal Opcode %p: 0x%02X 0x%02X %02X %02X\n", (void*)R_RIP, opcode, nextop, PK(2), PK(3));

                         emu->quit=1;

                         emu->error |= ERR_ILLEGAL;

                         return 0;

                     } else {

-                        R_RIP = ED->q[0];

+                        R_RIP = addr = ED->q[0];

                         R_CS = (ED+1)->word[0];

                         return 0;  // exit loop to recompute CS...

                     }

@@ -564,7 +562,6 @@ int Run64(x64emu_t *emu, rex_t rex, int seg)
                     Push(emu, tmp64u);  // avoid potential issue with push [esp+...]

                     break;

                 default:

-                    R_RIP = emu->old_ip;

                     printf_log(LOG_NONE, "Illegal Opcode %p: %02X %02X %02X %02X %02X %02X\n",(void*)R_RIP, opcode, nextop, PK(2), PK(3), PK(4), PK(5));

                     emu->quit=1;

                     emu->error |= ERR_ILLEGAL;

@@ -572,7 +569,7 @@ int Run64(x64emu_t *emu, rex_t rex, int seg)
             }

             break;

         default:

-            return 1;

+            return 0;

     }

-    return 0;

+    return addr;

 }

diff --git a/src/emu/x64run66.c b/src/emu/x64run66.c
index 85ce674b..f7e0d93e 100644
--- a/src/emu/x64run66.c
+++ b/src/emu/x64run66.c
@@ -25,7 +25,7 @@
 

 #include "modrm.h"

 

-int Run66(x64emu_t *emu, rex_t rex, int rep)

+uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr)

 {

     uint8_t opcode;

     uint8_t nextop;

@@ -105,7 +105,7 @@ int Run66(x64emu_t *emu, rex_t rex, int rep)
     GO(0x30, xor)                   /* XOR 0x31 ~> 0x35 */

 

     case 0x0F:                              /* more opcdes */

-        return Run660F(emu, rex);

+        return Run660F(emu, rex, addr);

 

     case 0x39:

         nextop = F8;

@@ -133,7 +133,7 @@ int Run66(x64emu_t *emu, rex_t rex, int rep)
         break;

 

     case 0x64:                              /* FS: */

-        return Run6664(emu, rex);

+        return Run6664(emu, rex, addr);

 

     case 0x69:                      /* IMUL Gw,Ew,Iw */

         nextop = F8;

@@ -178,8 +178,8 @@ int Run66(x64emu_t *emu, rex_t rex, int rep)
     case 0x7e:

     case 0x7f:

         // just ignore the 66 (and maybe other) prefix and use regular conditional jump

-        R_RIP--;

-        return 0;

+        addr--;

+        return addr;

 

     case 0x81:                              /* GRP3 Ew,Iw */

     case 0x83:                              /* GRP3 Ew,Ib */

@@ -607,19 +607,19 @@ int Run66(x64emu_t *emu, rex_t rex, int rep)
         break;

 

     case 0xD9:                              /* x87 opcdes */

-        return Run66D9(emu, rex);

+        return Run66D9(emu, rex, addr);

 

     case 0xDD:                              /* x87 opcdes */

-        return Run66DD(emu, rex);

+        return Run66DD(emu, rex, addr);

 

     case 0xE8:                              /* CALL Id */

         tmp32s = F32S; // call is relative

-        Push(emu, R_RIP);

-        R_RIP += tmp32s;

+        Push(emu, addr);

+        addr += tmp32s;

         break;

 

     case 0xF0:                              /* LOCK: */

-        return Run66F0(emu, rex);

+        return Run66F0(emu, rex, addr);

 

     case 0xF7:                      /* GRP3 Ew(,Iw) */

         nextop = F8;

@@ -699,14 +699,13 @@ int Run66(x64emu_t *emu, rex_t rex, int rep)
                 break;

             case 2:                 /* CALL NEAR Ed */

                 tmp64u = (uintptr_t)getAlternate((void*)ED->q[0]);

-                Push(emu, R_RIP);

-                R_RIP = tmp64u;

+                Push(emu, addr);

+                addr = tmp64u;

                 break;

            /*case 6:

                 Push16(emu, EW->word[0]);

                 break;*/

             default:

-                    R_RIP = emu->old_ip;

                     printf_log(LOG_NONE, "Illegal Opcode %p: 66 %02X %02X %02X %02X %02X %02X\n",(void*)R_RIP, opcode, nextop, PK(2), PK(3), PK(4), PK(5));

                     emu->quit=1;

                     emu->error |= ERR_ILLEGAL;

@@ -715,7 +714,7 @@ int Run66(x64emu_t *emu, rex_t rex, int rep)
         break;

 

     default:

-        return 1;

+        return 0;

     }

-    return 0;

+    return addr;

 }
\ No newline at end of file
diff --git a/src/emu/x64run660f.c b/src/emu/x64run660f.c
index 6f58cfa9..a82be1d8 100644
--- a/src/emu/x64run660f.c
+++ b/src/emu/x64run660f.c
@@ -43,7 +43,7 @@ static uint8_t ff_mult(uint8_t a, uint8_t b)
 	return retval;

 }

 

-int Run660F(x64emu_t *emu, rex_t rex)

+uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)

 {

     uint8_t opcode;

     uint8_t nextop;

@@ -645,7 +645,7 @@ int Run660F(x64emu_t *emu, rex_t rex)
                 break;

 

             default:

-                return 1;

+                return 0;

         }

         break;

 

@@ -819,7 +819,7 @@ int Run660F(x64emu_t *emu, rex_t rex)
                 break;

 

             default:

-                return 1;

+                return 0;

         }

         break;

         

@@ -1195,7 +1195,7 @@ int Run660F(x64emu_t *emu, rex_t rex)
                     for (int i=0; i<8; ++i) EX->uw[i] <<= tmp8u;

                 break;

             default:

-                return 1;

+                return 0;

         }

         break;

     case 0x72:  /* GRP */

@@ -1224,7 +1224,7 @@ int Run660F(x64emu_t *emu, rex_t rex)
                     for (int i=0; i<4; ++i) EX->ud[i] <<= tmp8u;

                 break;

             default:

-                return 1;

+                return 0;

         }

         break;

     case 0x73:  /* GRP */

@@ -1276,7 +1276,7 @@ int Run660F(x64emu_t *emu, rex_t rex)
                 }

                 break;

             default:

-                return 1;

+                return 0;

         }

         break;

     case 0x74:  /* PCMPEQB Gx,Ex */

@@ -1589,7 +1589,7 @@ int Run660F(x64emu_t *emu, rex_t rex)
                 }

                 break;

             default:

-                return 1;

+                return 0;

         }

         break;

     case 0xBB:                      /* BTC Ew,Gw */

@@ -1825,7 +1825,7 @@ int Run660F(x64emu_t *emu, rex_t rex)
                 if(EX->ub[i]&0x80)

                     GD->dword[0] |= (1<<i);

         } else

-            return 1;

+            return 0;

         break;

     case 0xD8:  /* PSUBUSB Gx,Ex */

         nextop = F8;

@@ -2144,7 +2144,7 @@ int Run660F(x64emu_t *emu, rex_t rex)
         break;

     

     default:

-        return 1;

+        return 0;

     }

-    return 0;

+    return addr;

 }
\ No newline at end of file
diff --git a/src/emu/x64run6664.c b/src/emu/x64run6664.c
index 3b564517..f46d5b28 100644
--- a/src/emu/x64run6664.c
+++ b/src/emu/x64run6664.c
@@ -22,7 +22,7 @@
 

 #include "modrm.h"

 

-int Run6664(x64emu_t *emu, rex_t rex)

+uintptr_t Run6664(x64emu_t *emu, rex_t rex, uintptr_t addr)

 {

     uint8_t opcode;

     uint8_t nextop;

@@ -73,7 +73,7 @@ int Run6664(x64emu_t *emu, rex_t rex)
                     break;

 

                 default:

-                    return 1;

+                    return 0;

             }

             break;

 

@@ -98,7 +98,7 @@ int Run6664(x64emu_t *emu, rex_t rex)
             break;

 

        default:

-            return 1;

+            return 0;

     }

-    return 0;

+    return addr;

 }
\ No newline at end of file
diff --git a/src/emu/x64run66d9.c b/src/emu/x64run66d9.c
index e355ca46..198c3a88 100644
--- a/src/emu/x64run66d9.c
+++ b/src/emu/x64run66d9.c
@@ -22,7 +22,7 @@
 

 #include "modrm.h"

 

-int Run66D9(x64emu_t *emu, rex_t rex)

+uintptr_t Run66D9(x64emu_t *emu, rex_t rex, uintptr_t addr)

 {

     uint8_t nextop;

     reg64_t *oped;

@@ -73,7 +73,7 @@ int Run66D9(x64emu_t *emu, rex_t rex)
         case 0xFD:

         case 0xFE:

         case 0xFF:

-            return 1;

+            return 0;

         default:

         switch((nextop>>3)&7) {

             case 4:     /* FLDENV m */

@@ -87,8 +87,8 @@ int Run66D9(x64emu_t *emu, rex_t rex)
                 fpu_savenv(emu, (char*)ED, 1);

                 break;

             default:

-                return 1;

+                return 0;

         }

     }

-    return 0;

+    return addr;

 }

diff --git a/src/emu/x64run66dd.c b/src/emu/x64run66dd.c
index 8b2b7326..d0fc703c 100644
--- a/src/emu/x64run66dd.c
+++ b/src/emu/x64run66dd.c
@@ -22,7 +22,7 @@
 

 #include "modrm.h"

 

-int Run66DD(x64emu_t *emu, rex_t rex)

+uintptr_t Run66DD(x64emu_t *emu, rex_t rex, uintptr_t addr)

 {

     uint8_t nextop;

     reg64_t *oped;

@@ -73,7 +73,7 @@ int Run66DD(x64emu_t *emu, rex_t rex)
         case 0xFD:

         case 0xFE:

         case 0xFF:

-            return 1;

+            return 0;

         default:

         switch((nextop>>3)&7) {

             case 4: /* FRSTOR m94byte */

@@ -105,8 +105,8 @@ int Run66DD(x64emu_t *emu, rex_t rex)
                 reset_fpu(emu);

                 break;

             default:

-                return 1;

+                return 0;

         }

     }

-    return 0;

+    return addr;

 }

diff --git a/src/emu/x64run66f0.c b/src/emu/x64run66f0.c
index cbf08825..623ad8d2 100644
--- a/src/emu/x64run66f0.c
+++ b/src/emu/x64run66f0.c
@@ -25,7 +25,7 @@
 
 #include "modrm.h"
 
-int Run66F0(x64emu_t *emu, rex_t rex)
+uintptr_t Run66F0(x64emu_t *emu, rex_t rex, uintptr_t addr)
 {
     uint8_t opcode;
     uint8_t nextop;
@@ -43,7 +43,7 @@ int Run66F0(x64emu_t *emu, rex_t rex)
         opcode = F8;
     }
 
-    if(rex.w) return RunF0(emu, rex);
+    if(rex.w) return RunF0(emu, rex, addr);
 
     switch(opcode) {
         
@@ -121,7 +121,7 @@ int Run66F0(x64emu_t *emu, rex_t rex)
                     break;
 
                 default:
-                    return 1;
+                    return 0;
             }
             break;
 
@@ -335,7 +335,7 @@ int Run66F0(x64emu_t *emu, rex_t rex)
             }
             break;
        default:
-            return 1;
+            return 0;
     }
-    return 0;
+    return addr;
 }
diff --git a/src/emu/x64run67.c b/src/emu/x64run67.c
index 1075dfa2..caa65c19 100644
--- a/src/emu/x64run67.c
+++ b/src/emu/x64run67.c
@@ -22,7 +22,7 @@
 

 #include "modrm.h"

 

-int Run67(x64emu_t *emu, rex_t rex, int rep)

+uintptr_t Run67(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr)

 {

     uint8_t opcode;

     uint8_t nextop;

@@ -98,7 +98,7 @@ int Run67(x64emu_t *emu, rex_t rex, int rep)
     GO(0x00, add)                   /* ADD 0x00 -> 0x05 */

     GO(0x08, or)                    /*  OR 0x08 -> 0x0D */

     case 0x0F:

-        return Run670F(emu, rex, rep);

+        return Run670F(emu, rex, rep, addr);

     GO(0x10, adc)                   /* ADC 0x10 -> 0x15 */

     GO(0x18, sbb)                   /* SBB 0x18 -> 0x1D */

     GO(0x20, and)                   /* AND 0x20 -> 0x25 */

@@ -146,7 +146,7 @@ int Run67(x64emu_t *emu, rex_t rex, int rep)
         break;

 

     case 0x66:

-        return Run6766(emu, rex, rep);

+        return Run6766(emu, rex, rep, addr);

 

     case 0x80:                      /* GRP Eb,Ib */

         nextop = F8;

@@ -315,31 +315,31 @@ int Run67(x64emu_t *emu, rex_t rex, int rep)
         tmp8s = F8S;

         --R_ECX; // don't update flags

         if(R_ECX && !ACCESS_FLAG(F_ZF))

-            R_RIP += tmp8s;

+            addr += tmp8s;

         break;

     case 0xE1:                      /* LOOPZ */

         CHECK_FLAGS(emu);

         tmp8s = F8S;

         --R_ECX; // don't update flags

         if(R_ECX && ACCESS_FLAG(F_ZF))

-            R_RIP += tmp8s;

+            addr += tmp8s;

         break;

     case 0xE2:                      /* LOOP */

         tmp8s = F8S;

         --R_ECX; // don't update flags

         if(R_ECX)

-            R_RIP += tmp8s;

+            addr += tmp8s;

         break;

     case 0xE3:              /* JECXZ Ib */

         tmp8s = F8S;

         if(!R_ECX)

-            R_RIP += tmp8s;

+            addr += tmp8s;

         break;

 

     case 0xE8:                      /* CALL Id */

         tmp32s = F32S; // call is relative

-        Push(emu, R_RIP);

-        R_RIP += tmp32s;

+        Push(emu, addr);

+        addr += tmp32s;

         break;

 

     case 0xF7:                      /* GRP3 Ed(,Id) */

@@ -414,7 +414,7 @@ int Run67(x64emu_t *emu, rex_t rex, int rep)
         break;

             

     default:

-        return 1;

+        return 0;

     }

-    return 0;

+    return addr;

 }
\ No newline at end of file
diff --git a/src/emu/x64run670f.c b/src/emu/x64run670f.c
index 1671da03..c576c501 100644
--- a/src/emu/x64run670f.c
+++ b/src/emu/x64run670f.c
@@ -25,7 +25,7 @@
 
 #include "modrm.h"
 
-int Run670F(x64emu_t *emu, rex_t rex, int rep)
+uintptr_t Run670F(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr)
 {
     (void)rep;
     uint8_t opcode;
@@ -47,7 +47,7 @@ int Run670F(x64emu_t *emu, rex_t rex, int rep)
             // same for now
         case 0x2F:                      /* COMISS Gx, Ex */
             if(rep) {
-                return 1;
+                return 0;
             }
             RESET_FLAGS(emu);
             nextop = F8;
@@ -80,7 +80,7 @@ int Run670F(x64emu_t *emu, rex_t rex, int rep)
             break;
 
     default:
-        return 1;
+        return 0;
     }
-    return 0;
+    return addr;
 }
diff --git a/src/emu/x64run6766.c b/src/emu/x64run6766.c
index 2d53e3ff..c12e9032 100644
--- a/src/emu/x64run6766.c
+++ b/src/emu/x64run6766.c
@@ -25,7 +25,7 @@
 
 #include "modrm.h"
 
-int Run6766(x64emu_t *emu, rex_t rex, int rep)
+uintptr_t Run6766(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr)
 {
     // Hmmmm....
     (void)rep;
@@ -59,10 +59,10 @@ int Run6766(x64emu_t *emu, rex_t rex, int rep)
     switch(opcode) {
 
     case 0x0F:                              /* more opcodes */
-        return Run67660F(emu, rex);
+        return Run67660F(emu, rex, addr);
 
     default:
-        return 1;
+        return 0;
     }
-    return 0;
+    return addr;
 }
diff --git a/src/emu/x64run67660f.c b/src/emu/x64run67660f.c
index 6be0b044..75506426 100644
--- a/src/emu/x64run67660f.c
+++ b/src/emu/x64run67660f.c
@@ -22,7 +22,7 @@
 
 #include "modrm.h"
 
-int Run67660F(x64emu_t *emu, rex_t rex)
+uintptr_t Run67660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
 {
     uint8_t opcode;
     uint8_t nextop;
@@ -58,7 +58,7 @@ int Run67660F(x64emu_t *emu, rex_t rex)
         break;
 
     default:
-        return 1;
+        return 0;
     }
-    return 0;
+    return addr;
 }
diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c
index f84599eb..cf232e77 100755
--- a/src/emu/x64run_private.c
+++ b/src/emu/x64run_private.c
@@ -1058,86 +1058,122 @@ void PrintTrace(x64emu_t* emu, uintptr_t ip, int dynarec)
 
 #endif
 
-reg64_t* GetECommon(x64emu_t* emu, rex_t rex, uint8_t m, uint8_t delta)
+static uint8_t F8(uintptr_t* addr) {
+    uint8_t ret = *(uint8_t*)*addr;
+    *addr+=1;
+    return ret;
+}
+static int8_t F8S(uintptr_t* addr) {
+    int8_t ret = *(int8_t*)*addr;
+    *addr+=1;
+    return ret;
+}
+static uint16_t F16(uintptr_t* addr) {
+    uint16_t ret = *(uint16_t*)*addr;
+    *addr+=2;
+    return ret;
+}
+static int16_t F16S(uintptr_t* addr) {
+    int16_t ret = *(int16_t*)*addr;
+    *addr+=2;
+    return ret;
+}
+static uint32_t F32(uintptr_t* addr) {
+    uint32_t ret = *(uint32_t*)*addr;
+    *addr+=4;
+    return ret;
+}
+static int32_t F32S(uintptr_t* addr) {
+    int32_t ret = *(int32_t*)*addr;
+    *addr+=4;
+    return ret;
+}
+static uint64_t F64(uintptr_t* addr) {
+    uint64_t ret = *(uint64_t*)*addr;
+    *addr+=8;
+    return ret;
+}
+
+reg64_t* GetECommon(x64emu_t* emu, uintptr_t* addr, rex_t rex, uint8_t m, uint8_t delta)
 {
     if (m<=7) {
         if(m==0x4) {
-            uint8_t sib = Fetch8(emu);
-            uintptr_t base = ((sib&0x7)==5)?((uint64_t)(int64_t)Fetch32s(emu)):(emu->regs[(sib&0x7)+(rex.b<<3)].q[0]); // base
+            uint8_t sib = F8(addr);
+            uintptr_t base = ((sib&0x7)==5)?((uint64_t)(int64_t)F32S(addr)):(emu->regs[(sib&0x7)+(rex.b<<3)].q[0]); // base
             base += (emu->sbiidx[((sib>>3)&7)+(rex.x<<3)]->sq[0] << (sib>>6));
             return (reg64_t*)base;
         } else if (m==0x5) { //disp32
-            int32_t base = Fetch32s(emu);
-            return (reg64_t*)(base+R_RIP+delta);
+            int32_t base = F32S(addr);
+            return (reg64_t*)(base+*addr+delta);
         }
         return (reg64_t*)(emu->regs[m+(rex.b<<3)].q[0]);
     } else {
         uintptr_t base;
         if((m&7)==4) {
-            uint8_t sib = Fetch8(emu);
+            uint8_t sib = F8(addr);
             base = emu->regs[(sib&0x7)+(rex.b<<3)].q[0]; // base
             base += (emu->sbiidx[((sib>>3)&7)+(rex.x<<3)]->sq[0] << (sib>>6));
         } else {
             base = emu->regs[(m&0x7)+(rex.b<<3)].q[0];
         }
-        base+=(m&0x80)?Fetch32s(emu):Fetch8s(emu);
+        base+=(m&0x80)?F32S(addr):F8S(addr);
         return (reg64_t*)base;
     }
 }
 
-reg64_t* GetECommonO(x64emu_t* emu, rex_t rex, uint8_t m, uint8_t delta, uintptr_t base)
+reg64_t* GetECommonO(x64emu_t* emu, uintptr_t* addr, rex_t rex, uint8_t m, uint8_t delta, uintptr_t base)
 {
     if (m<=7) {
         if(m==0x4) {
-            uint8_t sib = Fetch8(emu);
-            base += ((sib&0x7)==5)?((uint64_t)(int64_t)Fetch32s(emu)):(emu->regs[(sib&0x7)+(rex.b<<3)].q[0]); // base
+            uint8_t sib = F8(addr);
+            base += ((sib&0x7)==5)?((uint64_t)(int64_t)F32S(addr)):(emu->regs[(sib&0x7)+(rex.b<<3)].q[0]); // base
             base += (emu->sbiidx[((sib>>3)&7)+(rex.x<<3)]->sq[0] << (sib>>6));
             return (reg64_t*)base;
         } else if (m==0x5) { //disp32
-            base += Fetch32s(emu);
-            return (reg64_t*)(base+R_RIP+delta);
+            base += F32S(addr);
+            return (reg64_t*)(base+*addr+delta);
         }
         return (reg64_t*)(base + emu->regs[m+(rex.b<<3)].q[0]);
     } else {
         if((m&7)==4) {
-            uint8_t sib = Fetch8(emu);
+            uint8_t sib = F8(addr);
             base += emu->regs[(sib&0x7)+(rex.b<<3)].q[0]; // base
             base += (emu->sbiidx[((sib>>3)&7)+(rex.x<<3)]->sq[0] << (sib>>6));
         } else {
             base += emu->regs[(m&0x7)+(rex.b<<3)].q[0];
         }
-        base+=(m&0x80)?Fetch32s(emu):Fetch8s(emu);
+        base+=(m&0x80)?F32S(addr):F8S(addr);
         return (reg64_t*)base;
     }
 }
 
-reg64_t* GetECommon32O(x64emu_t* emu, rex_t rex, uint8_t m, uint8_t delta, uintptr_t base)
+reg64_t* GetECommon32O(x64emu_t* emu, uintptr_t* addr, rex_t rex, uint8_t m, uint8_t delta, uintptr_t base)
 {
     if (m<=7) {
         if(m==0x4) {
-            uint8_t sib = Fetch8(emu);
-            base += ((sib&0x7)==5)?((uint64_t)(int64_t)Fetch32s(emu)):(emu->regs[(sib&0x7)+(rex.b<<3)].dword[0]); // base
+            uint8_t sib = F8(addr);
+            base += ((sib&0x7)==5)?((uint64_t)(int64_t)F32S(addr)):(emu->regs[(sib&0x7)+(rex.b<<3)].dword[0]); // base
             base += (emu->sbiidx[((sib>>3)&7)+(rex.x<<3)]->sdword[0] << (sib>>6));
             return (reg64_t*)base;
         } else if (m==0x5) { //disp32
-            base += Fetch32s(emu);
-            return (reg64_t*)(base+R_RIP+delta);
+            base += F32S(addr);
+            return (reg64_t*)(base+(*addr)+delta);
         }
         return (reg64_t*)(uintptr_t)(base + emu->regs[m+(rex.b<<3)].dword[0]);
     } else {
         if((m&7)==4) {
-            uint8_t sib = Fetch8(emu);
+            uint8_t sib = F8(addr);
             base += emu->regs[(sib&0x7)+(rex.b<<3)].dword[0]; // base
             base += (emu->sbiidx[((sib>>3)&7)+(rex.x<<3)]->sdword[0] << (sib>>6));
         } else {
             base += emu->regs[(m&0x7)+(rex.b<<3)].dword[0];
         }
-        base+=(m&0x80)?Fetch32s(emu):Fetch8s(emu);
+        base+=(m&0x80)?F32S(addr):F8S(addr);
         return (reg64_t*)base;
     }
 }
 
-reg64_t* GetEb(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta)
+reg64_t* GetEb(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta)
 {
     // rex ignored here
     uint8_t m = v&0xC7;    // filter Eb
@@ -1148,10 +1184,10 @@ reg64_t* GetEb(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta)
             int lowhigh = (m&4)>>2;
             return (reg64_t *)(((char*)(&emu->regs[(m&0x03)]))+lowhigh);  //?
         }
-    } else return GetECommon(emu, rex, m, delta);
+    } else return GetECommon(emu, addr, rex, m, delta);
 }
 
-reg64_t* GetEbO(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset)
+reg64_t* GetEbO(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset)
 {
     // rex ignored here
     uint8_t m = v&0xC7;    // filter Eb
@@ -1162,34 +1198,34 @@ reg64_t* GetEbO(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t of
             int lowhigh = (m&4)>>2;
             return (reg64_t *)(((char*)(&emu->regs[(m&0x03)]))+lowhigh);  //?
         }
-    } else return GetECommonO(emu, rex, m, delta, offset);
+    } else return GetECommonO(emu, addr, rex, m, delta, offset);
 }
 
-reg64_t* GetEd(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta)
+reg64_t* GetEd(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta)
 {
     uint8_t m = v&0xC7;    // filter Ed
     if(m>=0xC0) {
          return &emu->regs[(m&0x07)+(rex.b<<3)];
-    } else return GetECommon(emu, rex, m, delta);
+    } else return GetECommon(emu, addr, rex, m, delta);
 }
 
-reg64_t* GetEdO(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset)
+reg64_t* GetEdO(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset)
 {
     uint8_t m = v&0xC7;    // filter Ed
     if(m>=0xC0) {
          return &emu->regs[(m&0x07)+(rex.b<<3)];
-    } else return GetECommonO(emu, rex, m, delta, offset);
+    } else return GetECommonO(emu, addr, rex, m, delta, offset);
 }
 
-reg64_t* GetEd32O(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset)
+reg64_t* GetEd32O(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset)
 {
     uint8_t m = v&0xC7;    // filter Ed
     if(m>=0xC0) {
          return &emu->regs[(m&0x07)+(rex.b<<3)];
-    } else return GetECommon32O(emu, rex, m, delta, offset);
+    } else return GetECommon32O(emu, addr, rex, m, delta, offset);
 }
 
-reg64_t* GetEb32O(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset)
+reg64_t* GetEb32O(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset)
 {
     uint8_t m = v&0xC7;    // filter Eb
     if(m>=0xC0) {
@@ -1199,12 +1235,12 @@ reg64_t* GetEb32O(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t
             int lowhigh = (m&4)>>2;
             return (reg64_t *)(((char*)(&emu->regs[(m&0x03)]))+lowhigh);  //?
         }
-    } else return GetECommon32O(emu, rex, m, delta, offset);
+    } else return GetECommon32O(emu, addr, rex, m, delta, offset);
 }
 
 #define GetEw GetEd
 
-reg64_t* GetEw16(x64emu_t *emu, rex_t rex, uint8_t v)
+reg64_t* GetEw16(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v)
 {
     (void)rex;
 
@@ -1224,16 +1260,16 @@ reg64_t* GetEw16(x64emu_t *emu, rex_t rex, uint8_t v)
             case 7: base =      R_BX; break;
         }
         switch((m>>6)&3) {
-            case 0: if(m==6) base = Fetch16(emu); break;
-            case 1: base += Fetch8s(emu); break;
-            case 2: base += Fetch16s(emu); break;
+            case 0: if(m==6) base = F16(addr); break;
+            case 1: base += F8S(addr); break;
+            case 2: base += F16S(addr); break;
             // case 3 is C0..C7, already dealt with
         }
         return (reg64_t*)base;
     }
 }
 
-reg64_t* GetEw16off(x64emu_t *emu, rex_t rex, uint8_t v, uintptr_t offset)
+reg64_t* GetEw16off(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uintptr_t offset)
 {
     (void)rex;
 
@@ -1253,62 +1289,62 @@ reg64_t* GetEw16off(x64emu_t *emu, rex_t rex, uint8_t v, uintptr_t offset)
             case 7: base =      R_BX; break;
         }
         switch((m>>6)&3) {
-            case 0: if(m==6) base = Fetch16(emu); break;
-            case 1: base += Fetch8s(emu); break;
-            case 2: base += Fetch16s(emu); break;
+            case 0: if(m==6) base = F16(addr); break;
+            case 1: base += F8S(addr); break;
+            case 2: base += F16S(addr); break;
             // case 3 is C0..C7, already dealt with
         }
         return (reg64_t*)(base+offset);
     }
 }
 
-mmx87_regs_t* GetEm(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta)
+mmx87_regs_t* GetEm(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta)
 {
     uint8_t m = v&0xC7;    // filter Ed
     if(m>=0xC0) {
          return &emu->mmx[m&0x07];
-    } else return (mmx87_regs_t*)GetECommon(emu, rex, m, delta);
+    } else return (mmx87_regs_t*)GetECommon(emu, addr, rex, m, delta);
 }
 
-sse_regs_t* GetEx(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta)
+sse_regs_t* GetEx(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta)
 {
     uint8_t m = v&0xC7;    // filter Ed
     if(m>=0xC0) {
          return &emu->xmm[(m&0x07)+(rex.b<<3)];
-    } else return (sse_regs_t*)GetECommon(emu, rex, m, delta);
+    } else return (sse_regs_t*)GetECommon(emu, addr, rex, m, delta);
 }
 
-sse_regs_t* GetExO(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset)
+sse_regs_t* GetExO(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset)
 {
     uint8_t m = v&0xC7;    // filter Ed
     if(m>=0xC0) {
          return &emu->xmm[(m&0x07)+(rex.b<<3)];
-    } else return (sse_regs_t*)GetECommonO(emu, rex, m, delta, offset);
+    } else return (sse_regs_t*)GetECommonO(emu, addr, rex, m, delta, offset);
 }
 
-sse_regs_t* GetEx32O(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset)
+sse_regs_t* GetEx32O(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset)
 {
     uint8_t m = v&0xC7;    // filter Ed
     if(m>=0xC0) {
          return &emu->xmm[(m&0x07)+(rex.b<<3)];
-    } else return (sse_regs_t*)GetECommon32O(emu, rex, m, delta, offset);
+    } else return (sse_regs_t*)GetECommon32O(emu, addr, rex, m, delta, offset);
 }
 
-mmx87_regs_t* GetEm32O(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset)
+mmx87_regs_t* GetEm32O(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset)
 {
     uint8_t m = v&0xC7;    // filter Ed
     if(m>=0xC0) {
          return &emu->mmx[(m&0x07)];
-    } else return (mmx87_regs_t*)GetECommon32O(emu, rex, m, delta, offset);
+    } else return (mmx87_regs_t*)GetECommon32O(emu, addr, rex, m, delta, offset);
 }
 
 
-reg64_t* GetGd(x64emu_t *emu, rex_t rex, uint8_t v)
+reg64_t* GetGd(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v)
 {
     return &emu->regs[((v&0x38)>>3)+(rex.r<<3)];
 }
 
-reg64_t* GetGb(x64emu_t *emu, rex_t rex, uint8_t v)
+reg64_t* GetGb(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v)
 {
     uint8_t m = (v&0x38)>>3;
     if(rex.rex)
@@ -1317,7 +1353,7 @@ reg64_t* GetGb(x64emu_t *emu, rex_t rex, uint8_t v)
         return (reg64_t*)&emu->regs[m&3].byte[m>>2];
 }
 
-mmx87_regs_t* GetGm(x64emu_t *emu, rex_t rex, uint8_t v)
+mmx87_regs_t* GetGm(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v)
 {
     (void)rex;
 
@@ -1325,7 +1361,7 @@ mmx87_regs_t* GetGm(x64emu_t *emu, rex_t rex, uint8_t v)
     return &emu->mmx[m&7];
 }
 
-sse_regs_t* GetGx(x64emu_t *emu, rex_t rex, uint8_t v)
+sse_regs_t* GetGx(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v)
 {
     uint8_t m = (v&0x38)>>3;
     return &emu->xmm[(m&7)+(rex.r<<3)];
diff --git a/src/emu/x64run_private.h b/src/emu/x64run_private.h
index 55f2da98..b3aea763 100755
--- a/src/emu/x64run_private.h
+++ b/src/emu/x64run_private.h
@@ -17,44 +17,6 @@ typedef union rex_s {
     };
 } rex_t;
 
-static inline uint8_t Fetch8(x64emu_t *emu) {return *(uint8_t*)(R_RIP++);}
-static inline int8_t Fetch8s(x64emu_t *emu) {return *(int8_t*)(R_RIP++);}
-static inline uint16_t Fetch16(x64emu_t *emu)
-{
-    uint16_t val = *(uint16_t*)R_RIP;
-    R_RIP+=2;
-    return val;
-}
-static inline int16_t Fetch16s(x64emu_t *emu)
-{
-    int16_t val = *(int16_t*)R_RIP;
-    R_RIP+=2;
-    return val;
-}
-static inline uint32_t Fetch32(x64emu_t *emu)
-{
-    uint32_t val = *(uint32_t*)R_RIP;
-    R_RIP+=4;
-    return val;
-}
-static inline int32_t Fetch32s(x64emu_t *emu)
-{
-    int32_t val = *(int32_t*)R_RIP;
-    R_RIP+=4;
-    return val;
-}
-static inline uint64_t Fetch64(x64emu_t *emu)
-{
-    uint64_t val = *(uint64_t*)R_RIP;
-    R_RIP+=8;
-    return val;
-}
-static inline int64_t Fetch64s(x64emu_t *emu)
-{
-    int64_t val = *(int64_t*)R_RIP;
-    R_RIP+=8;
-    return val;
-}
 static inline uint8_t Peek(x64emu_t *emu, int offset){return *(uint8_t*)(R_RIP + offset);}
 
 static inline uint64_t Pop(x64emu_t *emu)
@@ -73,61 +35,61 @@ static inline void Push(x64emu_t *emu, uint64_t v)
 
 // the op code definition can be found here: http://ref.x86asm.net/geek32.html
 
-reg64_t* GetECommon(x64emu_t* emu, rex_t rex, uint8_t m, uint8_t delta);
-reg64_t* GetECommonO(x64emu_t* emu, rex_t rex, uint8_t m, uint8_t delta, uintptr_t offset);
-reg64_t* GetECommon32O(x64emu_t* emu, rex_t rex, uint8_t m, uint8_t delta, uintptr_t offset);
-reg64_t* GetEb(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta);
-reg64_t* GetEbO(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
-reg64_t* GetEd(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta);
-reg64_t* GetEdO(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
-reg64_t* GetEd32O(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
-reg64_t* GetEb32O(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
+reg64_t* GetECommon(x64emu_t* emu, uintptr_t* addr, rex_t rex, uint8_t m, uint8_t delta);
+reg64_t* GetECommonO(x64emu_t* emu, uintptr_t* addr, rex_t rex, uint8_t m, uint8_t delta, uintptr_t offset);
+reg64_t* GetECommon32O(x64emu_t* emu, uintptr_t* addr, rex_t rex, uint8_t m, uint8_t delta, uintptr_t offset);
+reg64_t* GetEb(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta);
+reg64_t* GetEbO(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
+reg64_t* GetEd(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta);
+reg64_t* GetEdO(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
+reg64_t* GetEd32O(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
+reg64_t* GetEb32O(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
 #define GetEw GetEd
 #define GetEw32O GetEd32O
-reg64_t* GetEw16(x64emu_t *emu, rex_t rex, uint8_t v);
-reg64_t* GetEw16off(x64emu_t *emu, rex_t rex, uint8_t v, uintptr_t offset);
-mmx87_regs_t* GetEm(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta);
-sse_regs_t* GetEx(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta);
-sse_regs_t* GetExO(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
-sse_regs_t* GetEx32O(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
-reg64_t* GetGd(x64emu_t *emu, rex_t rex, uint8_t v);
+reg64_t* GetEw16(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v);
+reg64_t* GetEw16off(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uintptr_t offset);
+mmx87_regs_t* GetEm(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta);
+sse_regs_t* GetEx(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta);
+sse_regs_t* GetExO(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
+sse_regs_t* GetEx32O(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
+reg64_t* GetGd(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v);
 #define GetGw GetGd
-reg64_t* GetGb(x64emu_t *emu, rex_t rex, uint8_t v);
-mmx87_regs_t* GetGm(x64emu_t *emu, rex_t rex, uint8_t v);
-mmx87_regs_t* GetEm32O(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
-sse_regs_t* GetGx(x64emu_t *emu, rex_t rex, uint8_t v);
+reg64_t* GetGb(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v);
+mmx87_regs_t* GetGm(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v);
+mmx87_regs_t* GetEm32O(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
+sse_regs_t* GetGx(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
 
-int Run0F(x64emu_t *emu, rex_t rex);
-int Run64(x64emu_t *emu, rex_t rex, int seg);
-int Run66(x64emu_t *emu, rex_t rex, int rep);
-int Run660F(x64emu_t *emu, rex_t rex);
-int Run6664(x64emu_t *emu, rex_t rex);
-int Run66D9(x64emu_t *emu, rex_t rex);
-int Run66DD(x64emu_t *emu, rex_t rex);
-int Run66F0(x64emu_t *emu, rex_t rex);
-int Run67(x64emu_t *emu, rex_t rex, int rep);
-int Run670F(x64emu_t *emu, rex_t rex, int rep);
-int Run6766(x64emu_t *emu, rex_t rex, int rep);
-int Run67660F(x64emu_t *emu, rex_t rex);
-int RunD8(x64emu_t *emu, rex_t rex);
-int RunD9(x64emu_t *emu, rex_t rex);
-int RunDA(x64emu_t *emu, rex_t rex);
-int RunDB(x64emu_t *emu, rex_t rex);
-int RunDC(x64emu_t *emu, rex_t rex);
-int RunDD(x64emu_t *emu, rex_t rex);
-int RunDE(x64emu_t *emu, rex_t rex);
-int RunDF(x64emu_t *emu, rex_t rex);
-int RunF0(x64emu_t *emu, rex_t rex);
-int RunF20F(x64emu_t *emu, rex_t rex);
-int RunF30F(x64emu_t *emu, rex_t rex);
+uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr);
+uintptr_t Run64(x64emu_t *emu, rex_t rex, int seg, uintptr_t addr);
+uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr);
+uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr);
+uintptr_t Run6664(x64emu_t *emu, rex_t rex, uintptr_t addr);
+uintptr_t Run66D9(x64emu_t *emu, rex_t rex, uintptr_t addr);
+uintptr_t Run66DD(x64emu_t *emu, rex_t rex, uintptr_t addr);
+uintptr_t Run66F0(x64emu_t *emu, rex_t rex, uintptr_t addr);
+uintptr_t Run67(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr);
+uintptr_t Run670F(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr);
+uintptr_t Run6766(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr);
+uintptr_t Run67660F(x64emu_t *emu, rex_t rex, uintptr_t addr);
+uintptr_t RunD8(x64emu_t *emu, rex_t rex, uintptr_t addr);
+uintptr_t RunD9(x64emu_t *emu, rex_t rex, uintptr_t addr);
+uintptr_t RunDA(x64emu_t *emu, rex_t rex, uintptr_t addr);
+uintptr_t RunDB(x64emu_t *emu, rex_t rex, uintptr_t addr);
+uintptr_t RunDC(x64emu_t *emu, rex_t rex, uintptr_t addr);
+uintptr_t RunDD(x64emu_t *emu, rex_t rex, uintptr_t addr);
+uintptr_t RunDE(x64emu_t *emu, rex_t rex, uintptr_t addr);
+uintptr_t RunDF(x64emu_t *emu, rex_t rex, uintptr_t addr);
+uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr);
+uintptr_t RunF20F(x64emu_t *emu, rex_t rex, uintptr_t addr);
+uintptr_t RunF30F(x64emu_t *emu, rex_t rex, uintptr_t addr);
 
 void x64Syscall(x64emu_t *emu);
-void x64Int3(x64emu_t* emu);
+void x64Int3(x64emu_t* emu, uintptr_t* addr);
 x64emu_t* x64emu_fork(x64emu_t* e, int forktype);
 
 uintptr_t GetSegmentBaseEmu(x64emu_t* emu, int seg);
diff --git a/src/emu/x64rund8.c b/src/emu/x64rund8.c
index 60b9e151..54160094 100644
--- a/src/emu/x64rund8.c
+++ b/src/emu/x64rund8.c
@@ -22,7 +22,7 @@
 

 #include "modrm.h"

 

-int RunD8(x64emu_t *emu, rex_t rex)

+uintptr_t RunD8(x64emu_t *emu, rex_t rex, uintptr_t addr)

 {

     uint8_t nextop;

     float f;

@@ -188,8 +188,8 @@ int RunD8(x64emu_t *emu, rex_t rex)
                 }

                 break;

             default:

-                return 1;

+                return 0;

         }

     }

-   return 0;

+   return addr;

 }
\ No newline at end of file
diff --git a/src/emu/x64rund9.c b/src/emu/x64rund9.c
index ee255400..bb341f62 100644
--- a/src/emu/x64rund9.c
+++ b/src/emu/x64rund9.c
@@ -22,7 +22,7 @@
 

 #include "modrm.h"

 

-int RunD9(x64emu_t *emu, rex_t rex)

+uintptr_t RunD9(x64emu_t *emu, rex_t rex, uintptr_t addr)

 {

     uint8_t nextop;

     int32_t tmp32s;

@@ -223,7 +223,7 @@ int RunD9(x64emu_t *emu, rex_t rex)
         case 0xE6:

         case 0xE7:

         case 0xEF:

-            return 1;

+            return 0;

         default:

         switch((nextop>>3)&7) {

             case 0:     /* FLD ST0, Ed float */

@@ -279,8 +279,8 @@ int RunD9(x64emu_t *emu, rex_t rex)
                 EW->word[0] = emu->cw;

                 break;

             default:

-                return 1;

+                return 0;

         }

     }

-   return 0;

+   return addr;

 }
\ No newline at end of file
diff --git a/src/emu/x64runda.c b/src/emu/x64runda.c
index 70a60222..8a0f793c 100644
--- a/src/emu/x64runda.c
+++ b/src/emu/x64runda.c
@@ -22,7 +22,7 @@
 

 #include "modrm.h"

 

-int RunDA(x64emu_t *emu, rex_t rex)

+uintptr_t RunDA(x64emu_t *emu, rex_t rex, uintptr_t addr)

 {

     uint8_t nextop;

     reg64_t *oped;

@@ -94,7 +94,7 @@ int RunDA(x64emu_t *emu, rex_t rex)
     case 0xF8:

     case 0xF9:

     case 0xFD:

-        return 1;

+        return 0;

     default:

         switch((nextop>>3)&7) {

             case 0:     /* FIADD ST0, Ed int */

@@ -132,5 +132,5 @@ int RunDA(x64emu_t *emu, rex_t rex)
                 break;

         }

    }

-   return 0;

+   return addr;

 }
\ No newline at end of file
diff --git a/src/emu/x64rundb.c b/src/emu/x64rundb.c
index cb5c180c..27d847dd 100644
--- a/src/emu/x64rundb.c
+++ b/src/emu/x64rundb.c
@@ -22,7 +22,7 @@
 

 #include "modrm.h"

 

-int RunDB(x64emu_t *emu, rex_t rex)

+uintptr_t RunDB(x64emu_t *emu, rex_t rex, uintptr_t addr)

 {

     uint8_t nextop;

     int32_t tmp32s;

@@ -123,7 +123,7 @@ int RunDB(x64emu_t *emu, rex_t rex)
     case 0xE5:

     case 0xE6:

     case 0xE7:

-        return 1;

+        return 0;

     default:

         switch((nextop>>3)&7) {

             case 0: /* FILD ST0, Ed */

@@ -174,8 +174,8 @@ int RunDB(x64emu_t *emu, rex_t rex)
                 fpu_do_pop(emu);

                 break;

             default:

-                return 1;

+                return 0;

         }

     }

-  return 0;

+  return addr;

 }
\ No newline at end of file
diff --git a/src/emu/x64rundc.c b/src/emu/x64rundc.c
index 9f581895..dbe4d45f 100644
--- a/src/emu/x64rundc.c
+++ b/src/emu/x64rundc.c
@@ -22,7 +22,7 @@
 
 #include "modrm.h"
 
-int RunDC(x64emu_t *emu, rex_t rex)
+uintptr_t RunDC(x64emu_t *emu, rex_t rex, uintptr_t addr)
 {
     uint8_t nextop;
     reg64_t *oped;
@@ -139,8 +139,8 @@ int RunDC(x64emu_t *emu, rex_t rex)
                 ST0.d = *(double*)ED / ST0.d;
                 break;
            default:
-                return 1;
+                return 0;
         }
     }
-  return 0;
+  return addr;
 }
diff --git a/src/emu/x64rundd.c b/src/emu/x64rundd.c
index ce6081cc..6b05adf9 100644
--- a/src/emu/x64rundd.c
+++ b/src/emu/x64rundd.c
@@ -22,7 +22,7 @@
 

 #include "modrm.h"

 

-int RunDD(x64emu_t *emu, rex_t rex)

+uintptr_t RunDD(x64emu_t *emu, rex_t rex, uintptr_t addr)

 {

     uint8_t nextop;

     reg64_t *oped;

@@ -107,7 +107,7 @@ int RunDD(x64emu_t *emu, rex_t rex)
     case 0xFD:

     case 0xFE:

     case 0xFF:

-        return 1;

+        return 0;

 

     default:

         switch((nextop>>3)&7) {

@@ -182,8 +182,8 @@ int RunDD(x64emu_t *emu, rex_t rex)
                 *(uint16_t*)ED = emu->sw.x16;

                 break;

             default:

-                return 1;

+                return 0;

         }

     }

-   return 0;

+   return addr;

 }
\ No newline at end of file
diff --git a/src/emu/x64runde.c b/src/emu/x64runde.c
index 0d69f313..4911be32 100644
--- a/src/emu/x64runde.c
+++ b/src/emu/x64runde.c
@@ -22,7 +22,7 @@
 
 #include "modrm.h"
 
-int RunDE(x64emu_t *emu, rex_t rex)
+uintptr_t RunDE(x64emu_t *emu, rex_t rex, uintptr_t addr)
 {
     uint8_t nextop;
     reg64_t *oped;
@@ -124,7 +124,7 @@ int RunDE(x64emu_t *emu, rex_t rex)
     case 0xDD:
     case 0xDE:
     case 0xDF:
-        return 1;
+        return 0;
     
     default:
         switch((nextop>>3)&7) {
@@ -153,8 +153,8 @@ int RunDE(x64emu_t *emu, rex_t rex)
                 ST0.d = (double)EW->sword[0] / ST0.d;
                 break;
            default:
-                return 1;
+                return 0;
         }
     }
-  return 0;
+  return addr;
 }
\ No newline at end of file
diff --git a/src/emu/x64rundf.c b/src/emu/x64rundf.c
index a059cfd8..dfe992c8 100644
--- a/src/emu/x64rundf.c
+++ b/src/emu/x64rundf.c
@@ -22,7 +22,7 @@
 

 #include "modrm.h"

 

-int RunDF(x64emu_t *emu, rex_t rex)

+uintptr_t RunDF(x64emu_t *emu, rex_t rex, uintptr_t addr)

 {

     uint8_t nextop;

     int16_t tmp16s;

@@ -111,7 +111,7 @@ int RunDF(x64emu_t *emu, rex_t rex)
     case 0xFD:

     case 0xFE:

     case 0xFF:

-        return 1;

+        return 0;

 

     default:

         switch((nextop>>3)&7) {

@@ -173,8 +173,8 @@ int RunDF(x64emu_t *emu, rex_t rex)
             fpu_do_pop(emu);

             break;

         default:

-            return 1;

+            return 0;

         }

     }

-    return 0;

+    return addr;

 }

diff --git a/src/emu/x64runf0.c b/src/emu/x64runf0.c
index 422cd5b3..df33758b 100644
--- a/src/emu/x64runf0.c
+++ b/src/emu/x64runf0.c
@@ -26,7 +26,7 @@
 

 #include "modrm.h"

 

-int RunF0(x64emu_t *emu, rex_t rex)

+uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr)

 {

     uint8_t opcode;

     uint8_t nextop;

@@ -582,7 +582,7 @@ int RunF0(x64emu_t *emu, rex_t rex)
                                 break;

 

                             default:

-                                return 1;

+                                return 0;

                         }

                         break;

 

@@ -715,17 +715,17 @@ int RunF0(x64emu_t *emu, rex_t rex)
 #endif

                             break;

                         default:

-                            return 1;

+                            return 0;

                     }

                     break;

 

             default:

-                return 1;

+                return 0;

             }

             break;

 

         case 0x66:

-            return Run66F0(emu, rex);   // more opcode F0 66 and 66 F0 is the same

+            return Run66F0(emu, rex, addr);   // more opcode F0 66 and 66 F0 is the same

 

         case 0x80:                      /* GRP Eb,Ib */

             nextop = F8;

@@ -905,7 +905,7 @@ int RunF0(x64emu_t *emu, rex_t rex)
 #endif

                     break;

                 default:

-                    return 1;

+                    return 0;

             }

             break;

 

@@ -1002,7 +1002,7 @@ int RunF0(x64emu_t *emu, rex_t rex)
             }

             break;

         default:

-            return 1;

+            return 0;

     }

-    return 0;

+    return addr;

 }

diff --git a/src/emu/x64runf20f.c b/src/emu/x64runf20f.c
index e6268fcc..db2500cd 100644
--- a/src/emu/x64runf20f.c
+++ b/src/emu/x64runf20f.c
@@ -22,7 +22,7 @@
 

 #include "modrm.h"

 

-int RunF20F(x64emu_t *emu, rex_t rex)

+uintptr_t RunF20F(x64emu_t *emu, rex_t rex, uintptr_t addr)

 {

     uint8_t opcode;

     uint8_t nextop;

@@ -256,7 +256,7 @@ int RunF20F(x64emu_t *emu, rex_t rex)
 

     GOCOND(0x80

         , tmp32s = F32S; CHECK_FLAGS(emu);

-        , R_RIP += tmp32s;

+        , addr += tmp32s;

         ,

     )                               /* 0x80 -> 0x8F Jxx */

         

@@ -329,7 +329,7 @@ int RunF20F(x64emu_t *emu, rex_t rex)
         break;

 

    default:

-        return 1;

+        return 0;

     }

-    return 0;

+    return addr;

 }
\ No newline at end of file
diff --git a/src/emu/x64runf30f.c b/src/emu/x64runf30f.c
index 0d9dbba7..82f8e2f5 100644
--- a/src/emu/x64runf30f.c
+++ b/src/emu/x64runf30f.c
@@ -22,7 +22,7 @@
 

 #include "modrm.h"

 

-int RunF30F(x64emu_t *emu, rex_t rex)

+uintptr_t RunF30F(x64emu_t *emu, rex_t rex, uintptr_t addr)

 {

     uint8_t opcode;

     uint8_t nextop;

@@ -351,7 +351,7 @@ int RunF30F(x64emu_t *emu, rex_t rex)
         break;

 

     default:

-        return 1;

+        return 0;

     }

-    return 0;

+    return addr;

 }

diff --git a/src/emu/x64syscall.c b/src/emu/x64syscall.c
index c5d740de..4bc83479 100755
--- a/src/emu/x64syscall.c
+++ b/src/emu/x64syscall.c
@@ -425,10 +425,10 @@ void EXPORT x64Syscall(x64emu_t *emu)
                 PushExit(newemu);
                 void* mystack = NULL;
                 if(my_context->stack_clone_used) {
-                    mystack = malloc(1024*1024);  // stack for own process... memory leak, but no practical way to remove it
+                    mystack = box_malloc(1024*1024);  // stack for own process... memory leak, but no practical way to remove it
                 } else {
                     if(!my_context->stack_clone)
-                        my_context->stack_clone = malloc(1024*1024);
+                        my_context->stack_clone = box_malloc(1024*1024);
                     mystack = my_context->stack_clone;
                     my_context->stack_clone_used = 1;
                 }
@@ -645,10 +645,10 @@ uintptr_t EXPORT my_syscall(x64emu_t *emu)
                 PushExit(newemu);
                 void* mystack = NULL;
                 if(my_context->stack_clone_used) {
-                    mystack = malloc(1024*1024);  // stack for own process... memory leak, but no practical way to remove it
+                    mystack = box_malloc(1024*1024);  // stack for own process... memory leak, but no practical way to remove it
                 } else {
                     if(!my_context->stack_clone)
-                        my_context->stack_clone = malloc(1024*1024);
+                        my_context->stack_clone = box_malloc(1024*1024);
                     mystack = my_context->stack_clone;
                     my_context->stack_clone_used = 1;
                 }