about summary refs log tree commit diff stats
path: root/src/emu/x64run_private.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/x64run_private.c')
-rw-r--r--src/emu/x64run_private.c472
1 files changed, 99 insertions, 373 deletions
diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c
index 25646d98..556ef6b4 100644
--- a/src/emu/x64run_private.c
+++ b/src/emu/x64run_private.c
@@ -233,7 +233,7 @@ reg64_t* GetECommon_32(x64emu_t* emu, uintptr_t* addr, uint8_t m, uint32_t base)
         return (reg64_t*)(uintptr_t)base;
     }
 }
-reg64_t* GetEw16_32(x64emu_t *emu, uintptr_t* addr, uint8_t m, uint32_t base)
+reg64_t* GetECommon_16(x64emu_t *emu, uintptr_t* addr, uint8_t m, uint32_t base)
 {
     switch(m&7) {
         case 0: base+= R_BX+R_SI; break;
@@ -254,94 +254,101 @@ reg64_t* GetEw16_32(x64emu_t *emu, uintptr_t* addr, uint8_t m, uint32_t base)
     return (reg64_t*)(uintptr_t)base;
 }
 
-reg64_t* GetECommon(x64emu_t* emu, uintptr_t* addr, rex_t rex, uint8_t m, uint8_t delta)
+reg64_t* GetECommon_64(x64emu_t* emu, uintptr_t* addr, rex_t rex, uint8_t m, uint8_t delta, uintptr_t base)
 {
-    if(rex.is32bits)
-        return GetECommon_32(emu, addr, m, 0);
     if (m<=7) {
         if(m==0x4) {
             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 += ((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 = F32S(addr);
+            base += F32S(addr);
             return (reg64_t*)(base+*addr+delta);
         }
-        return (reg64_t*)(emu->regs[m+(rex.b<<3)].q[0]);
+        return (reg64_t*)(base + emu->regs[m+(rex.b<<3)].q[0]);
     } else {
-        uintptr_t base;
         if((m&7)==4) {
             uint8_t sib = F8(addr);
-            base = emu->regs[(sib&0x7)+(rex.b<<3)].q[0]; // base
+            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 += emu->regs[(m&0x7)+(rex.b<<3)].q[0];
         }
         base+=(m&0x80)?F32S(addr):F8S(addr);
         return (reg64_t*)base;
     }
 }
 
-reg64_t* GetECommonO(x64emu_t* emu, uintptr_t* addr, 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(rex.is32bits)
-        return GetECommon_32(emu, addr, m, base);
     if (m<=7) {
         if(m==0x4) {
             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));
+            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 += F32S(addr);
-            return (reg64_t*)(base+*addr+delta);
+            return (reg64_t*)(base+(*addr)+delta);
         }
-        return (reg64_t*)(base + emu->regs[m+(rex.b<<3)].q[0]);
+        return (reg64_t*)(uintptr_t)(base + emu->regs[m+(rex.b<<3)].dword[0]);
     } else {
         if((m&7)==4) {
             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));
+            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)].q[0];
+            base += emu->regs[(m&0x7)+(rex.b<<3)].dword[0];
         }
         base+=(m&0x80)?F32S(addr):F8S(addr);
         return (reg64_t*)base;
     }
 }
 
-reg64_t* GetECommon32O(x64emu_t* emu, uintptr_t* addr, rex_t rex, uint8_t m, uint8_t delta, uintptr_t base)
+reg64_t* GetECommon(x64emu_t* emu, uintptr_t* addr, rex_t rex, uint8_t m, uint8_t delta)
 {
+    if(rex.is32bits && rex.is67)
+        return GetECommon_16(emu, addr, m, rex.offset);
     if(rex.is32bits)
-        return GetEw16_32(emu, addr, m, base);
+        return GetECommon_32(emu, addr, m, rex.offset);
+    if(rex.is67)
+        return GetECommon32O(emu, addr, rex, m, delta, rex.offset);
     if (m<=7) {
         if(m==0x4) {
             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));
+            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));
+            base += rex.offset;
             return (reg64_t*)base;
         } else if (m==0x5) { //disp32
-            base += F32S(addr);
-            return (reg64_t*)(base+(*addr)+delta);
+            int32_t base = F32S(addr);
+            base += rex.offset;
+            return (reg64_t*)(base+*addr+delta);
         }
-        return (reg64_t*)(uintptr_t)(base + emu->regs[m+(rex.b<<3)].dword[0]);
+        return (reg64_t*)(emu->regs[m+(rex.b<<3)].q[0]);
     } else {
+        uintptr_t base;
         if((m&7)==4) {
             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));
+            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)].dword[0];
+            base = emu->regs[(m&0x7)+(rex.b<<3)].q[0];
         }
         base+=(m&0x80)?F32S(addr):F8S(addr);
+        base += rex.offset;
         return (reg64_t*)base;
     }
 }
 
 reg64_t* GetEb(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta)
 {
-    // rex ignored here
+    if(rex.is67 && rex.is32bits) {
+        printf_log(LOG_NONE, "Need 32bits 67 prefix GetEb\n");
+        emu->quit = 1;
+        return NULL;
+    }
     uint8_t m = v&0xC7;    // filter Eb
     if(m>=0xC0) {
         if(rex.rex) {
@@ -355,41 +362,11 @@ reg64_t* GetEb(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t del
 
 reg64_t* TestEb(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta)
 {
-    // rex ignored here
-    uint8_t m = v&0xC7;    // filter Eb
-    if(m>=0xC0) {
-        if(rex.rex) {
-            return &test->emu->regs[(m&0x07)+(rex.b<<3)];
-        } else {
-            int lowhigh = (m&4)>>2;
-            return (reg64_t *)(((char*)(&test->emu->regs[(m&0x03)]))+lowhigh);  //?
-        }
-    } else {
-        reg64_t* ret = GetECommon(test->emu, addr, rex, m, delta);
-        test->memsize = 1;
-        test->memaddr = (uintptr_t)ret;
-        test->mem[0] = ret->byte[0];
-        return (reg64_t*)test->mem;
+    if(rex.is67 && rex.is32bits) {
+        printf_log(LOG_NONE, "Need 32bits 67 prefix TestEb\n");
+        test->emu->quit = 1;
+        return NULL;
     }
-}
-
-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
-    if(m>=0xC0) {
-        if(rex.rex) {
-            return &emu->regs[(m&0x07)+(rex.b<<3)];
-        } else {
-            int lowhigh = (m&4)>>2;
-            return (reg64_t *)(((char*)(&emu->regs[(m&0x03)]))+lowhigh);  //?
-        }
-    } else return GetECommonO(emu, addr, rex, m, delta, offset);
-}
-
-reg64_t* TestEbO(x64test_t *test, 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
     if(m>=0xC0) {
         if(rex.rex) {
@@ -399,7 +376,7 @@ reg64_t* TestEbO(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t
             return (reg64_t *)(((char*)(&test->emu->regs[(m&0x03)]))+lowhigh);  //?
         }
     } else {
-        reg64_t* ret =  GetECommonO(test->emu, addr, rex, m, delta, offset);
+        reg64_t* ret = GetECommon(test->emu, addr, rex, m, delta);
         test->memsize = 1;
         test->memaddr = (uintptr_t)ret;
         test->mem[0] = ret->byte[0];
@@ -409,6 +386,11 @@ reg64_t* TestEbO(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t
 
 reg64_t* GetEd(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta)
 {
+    if(rex.is67 && rex.is32bits) {
+        printf_log(LOG_NONE, "Need 32bits 67 prefix GetEd\n");
+        emu->quit = 1;
+        return NULL;
+    }
     uint8_t m = v&0xC7;    // filter Ed
     if(m>=0xC0) {
          return &emu->regs[(m&0x07)+(rex.b<<3)];
@@ -417,6 +399,11 @@ reg64_t* GetEd(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t del
 
 reg64_t* TestEd(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta)
 {
+    if(rex.is67 && rex.is32bits) {
+        printf_log(LOG_NONE, "Need 32bits 67 prefix TestEd\n");
+        test->emu->quit = 1;
+        return NULL;
+    }
     uint8_t m = v&0xC7;    // filter Ed
     if(m>=0xC0) {
         return &test->emu->regs[(m&0x07)+(rex.b<<3)];
@@ -433,24 +420,16 @@ reg64_t* TestEd(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t
 }
 reg64_t* TestEd4(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta)
 {
-    uint8_t m = v&0xC7;    // filter Ed
-    if(m>=0xC0) {
-        return &test->emu->regs[(m&0x07)+(rex.b<<3)];
-    } else {
-        reg64_t* ret =  GetECommon(test->emu, addr, rex, m, delta);
-        test->memsize = 4;
-        test->memaddr = (uintptr_t)ret;
-        *(uint32_t*)test->mem = ret->dword[0];
-        return (reg64_t*)test->mem;
+    if(rex.is67 && rex.is32bits) {
+        printf_log(LOG_NONE, "Need 32bits 67 prefix TestEd4x\n");
+        test->emu->quit = 1;
+        return NULL;
     }
-}
-reg64_t* TestEd4O(x64test_t *test, 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 &test->emu->regs[(m&0x07)+(rex.b<<3)];
     } else {
-        reg64_t* ret =  GetECommonO(test->emu, addr, rex, m, delta, offset);
+        reg64_t* ret =  GetECommon(test->emu, addr, rex, m, delta);
         test->memsize = 4;
         test->memaddr = (uintptr_t)ret;
         *(uint32_t*)test->mem = ret->dword[0];
@@ -459,24 +438,16 @@ reg64_t* TestEd4O(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_
 }
 reg64_t* TestEd8(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta)
 {
-    uint8_t m = v&0xC7;    // filter Ed
-    if(m>=0xC0) {
-        return &test->emu->regs[(m&0x07)+(rex.b<<3)];
-    } else {
-        reg64_t* ret =  GetECommon(test->emu, addr, rex, m, delta);
-        test->memsize = 8;
-        test->memaddr = (uintptr_t)ret;
-        *(uint64_t*)test->mem = ret->q[0];
-        return (reg64_t*)test->mem;
+    if(rex.is67 && rex.is32bits) {
+        printf_log(LOG_NONE, "Need 32bits 67 prefix TestEd8\n");
+        test->emu->quit = 1;
+        return NULL;
     }
-}
-reg64_t* TestEd8O(x64test_t *test, 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 &test->emu->regs[(m&0x07)+(rex.b<<3)];
     } else {
-        reg64_t* ret =  GetECommonO(test->emu, addr, rex, m, delta, offset);
+        reg64_t* ret =  GetECommon(test->emu, addr, rex, m, delta);
         test->memsize = 8;
         test->memaddr = (uintptr_t)ret;
         *(uint64_t*)test->mem = ret->q[0];
@@ -485,6 +456,11 @@ reg64_t* TestEd8O(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_
 }
 reg64_t* TestEdt(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta)
 {
+    if(rex.is67 && rex.is32bits) {
+        printf_log(LOG_NONE, "Need 32bits 67 prefix TestEdt\n");
+        test->emu->quit = 1;
+        return NULL;
+    }
     uint8_t m = v&0xC7;    // filter Ed
     if(m>=0xC0) {
         return &test->emu->regs[(m&0x07)+(rex.b<<3)];
@@ -498,6 +474,11 @@ reg64_t* TestEdt(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t
 }
 reg64_t* TestEd8xw(x64test_t *test, int w, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta)
 {
+    if(rex.is67 && rex.is32bits) {
+        printf_log(LOG_NONE, "Need 32bits 67 prefix TestEd4xw\n");
+        test->emu->quit = 1;
+        return NULL;
+    }
     uint8_t m = v&0xC7;    // filter Ed
     if(m>=0xC0) {
         return &test->emu->regs[(m&0x07)+(rex.b<<3)];
@@ -513,6 +494,11 @@ reg64_t* TestEd8xw(x64test_t *test, int w, uintptr_t* addr, rex_t rex, uint8_t v
 }
 reg64_t* TestEw(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta)
 {
+    if(rex.is67 && rex.is32bits) {
+        printf_log(LOG_NONE, "Need 32bits 67 prefix TestEw\n");
+        test->emu->quit = 1;
+        return NULL;
+    }
     uint8_t m = v&0xC7;    // filter Ed
     if(m>=0xC0) {
         return &test->emu->regs[(m&0x07)+(rex.b<<3)];
@@ -528,14 +514,6 @@ reg64_t* TestEw(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t
     }
 }
 
-uintptr_t GetEA(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 (uintptr_t)&emu->regs[(m&0x07)+(rex.b<<3)];
-    } else return (uintptr_t)GetECommon(emu, addr, rex, m, delta);
-}
-
 uintptr_t GetEA32(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta)
 {
     uint8_t m = v&0xC7;    // filter Ed
@@ -549,89 +527,19 @@ uintptr_t GetEA32_16(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8
     uint8_t m = v&0xC7;    // filter Ed
     if(m>=0xC0) {
          return (uintptr_t)&emu->regs[(m&0x07)+(rex.b<<3)];
-    } else return (uintptr_t)GetEw16off(emu, addr, rex, m, delta);
+    } else return (uintptr_t)GetECommon_16(emu, addr, m, rex.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, addr, rex, m, delta, offset);
-}
-
-reg64_t* TestEdO(x64test_t *test, 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 &test->emu->regs[(m&0x07)+(rex.b<<3)];
-    } else {
-        reg64_t* ret =  GetECommonO(test->emu, addr, rex, m, delta, offset);
-        test->memsize = 4<<rex.w;
-        test->memaddr = (uintptr_t)ret;
-        if(rex.w)
-            *(uint64_t*)test->mem = ret->q[0];
-        else
-            *(uint32_t*)test->mem = ret->dword[0];
-        return (reg64_t*)test->mem;
-    }
-}
-
-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, addr, rex, m, delta, offset);
-}
-
-reg64_t* TestEd32O(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset)
+uintptr_t GetEA(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta)
 {
+    if(rex.is67 && rex.is32bits)
+        return GetEA32_16(emu, addr, rex, v, delta);
+    if(rex.is67)
+        return GetEA32(emu, addr, rex, v, delta);
     uint8_t m = v&0xC7;    // filter Ed
     if(m>=0xC0) {
-        return &test->emu->regs[(m&0x07)+(rex.b<<3)];
-    } else {
-        reg64_t* ret =  GetECommon32O(test->emu, addr, rex, m, delta, offset);
-        test->memsize = 4<<rex.w;
-        test->memaddr = (uintptr_t)ret;
-        if(rex.w)
-            *(uint64_t*)test->mem = ret->q[0];
-        else
-            *(uint32_t*)test->mem = ret->dword[0];
-        return (reg64_t*)test->mem;
-    }
-}
-
-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) {
-        if(rex.rex) {
-            return &emu->regs[(m&0x07)+(rex.b<<3)];
-        } else {
-            int lowhigh = (m&4)>>2;
-            return (reg64_t *)(((char*)(&emu->regs[(m&0x03)]))+lowhigh);  //?
-        }
-    } else return GetECommon32O(emu, addr, rex, m, delta, offset);
-}
-
-reg64_t* TestEb32O(x64test_t *test, 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) {
-        if(rex.rex) {
-            return &test->emu->regs[(m&0x07)+(rex.b<<3)];
-        } else {
-            int lowhigh = (m&4)>>2;
-            return (reg64_t *)(((char*)(&test->emu->regs[(m&0x03)]))+lowhigh);  //?
-        }
-    } else {
-        reg64_t* ret =  GetECommon32O(test->emu, addr, rex, m, delta, offset);
-        test->memsize = 1;
-        test->memaddr = (uintptr_t)ret;
-        test->mem[0] = ret->byte[0];
-        return (reg64_t*)test->mem;
-    }
+         return (uintptr_t)&emu->regs[(m&0x07)+(rex.b<<3)];
+    } else return (uintptr_t)GetECommon(emu, addr, rex, m, delta);
 }
 
 #define GetEw GetEd
@@ -662,7 +570,7 @@ reg64_t* GetEw16(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v)
             case 2: base += F16S(addr); break;
             // case 3 is C0..C7, already dealt with
         }
-        return (reg64_t*)base;
+        return (reg64_t*)(base+rex.offset);
     }
 }
 
@@ -693,138 +601,19 @@ reg64_t* TestEw16(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v)
             // case 3 is C0..C7, already dealt with
         }
         test->memsize = 2;
-        *(uint16_t*)test->mem = *(uint16_t*)base;
-        test->memaddr = (uintptr_t)base;
-        return (reg64_t*)test->mem;
-    }
-}
-
-reg64_t* GetEw16off(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uintptr_t offset)
-{
-    (void)rex;
-
-    uint32_t m = v&0xC7;    // filter Ed
-    if(m>=0xC0) {
-         return &emu->regs[(m&0x07)];
-    } else {
-        uint32_t base = 0;
-        switch(m&7) {
-            case 0: base = R_BX+R_SI; break;
-            case 1: base = R_BX+R_DI; break;
-            case 2: base = R_BP+R_SI; break;
-            case 3: base = R_BP+R_DI; break;
-            case 4: base =      R_SI; break;
-            case 5: base =      R_DI; break;
-            case 6: base =      R_BP; break;
-            case 7: base =      R_BX; break;
-        }
-        switch((m>>6)&3) {
-            case 0: if((m&7)==6) base = F16S(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);
-    }
-}
-
-reg64_t* GetEd16off(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uintptr_t offset)
-{
-    (void)rex;
-
-    uint32_t m = v&0xC7;    // filter Ed
-    if(m>=0xC0) {
-         return &emu->regs[(m&0x07)];
-    } else {
-        uint32_t base = 0;
-        switch(m&7) {
-            case 0: base = R_BX+R_SI; break;
-            case 1: base = R_BX+R_DI; break;
-            case 2: base = R_BP+R_SI; break;
-            case 3: base = R_BP+R_DI; break;
-            case 4: base =      R_SI; break;
-            case 5: base =      R_DI; break;
-            case 6: base =      R_BP; break;
-            case 7: base =      R_BX; break;
-        }
-        switch((m>>6)&3) {
-            case 0: if((m&7)==6) base = F16S(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);
-    }
-}
-
-reg64_t* TestEw16off(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uintptr_t offset)
-{
-    (void)rex;
-    x64emu_t* emu = test->emu;
-
-    uint32_t m = v&0xC7;    // filter Ed
-    if(m>=0xC0) {
-        return &emu->regs[(m&0x07)];
-    } else {
-        uint32_t base = 0;
-        switch(m&7) {
-            case 0: base = R_BX+R_SI; break;
-            case 1: base = R_BX+R_DI; break;
-            case 2: base = R_BP+R_SI; break;
-            case 3: base = R_BP+R_DI; break;
-            case 4: base =      R_SI; break;
-            case 5: base =      R_DI; break;
-            case 6: base =      R_BP; break;
-            case 7: base =      R_BX; break;
-        }
-        switch((m>>6)&3) {
-            case 0: if((m&7)==6) base = F16S(addr); break;
-            case 1: base += F8S(addr); break;
-            case 2: base += F16S(addr); break;
-            // case 3 is C0..C7, already dealt with
-        }
-        test->memsize = 2;
-        *(uint16_t*)test->mem = *(uint16_t*)(base+offset);
-        test->memaddr = (uintptr_t)(base+offset);
-        return (reg64_t*)test->mem;
-    }
-}
-
-reg64_t* TestEd16off(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uintptr_t offset)
-{
-    (void)rex;
-    x64emu_t* emu = test->emu;
-
-    uint32_t m = v&0xC7;    // filter Ed
-    if(m>=0xC0) {
-        return &emu->regs[(m&0x07)];
-    } else {
-        uint32_t base = 0;
-        switch(m&7) {
-            case 0: base = R_BX+R_SI; break;
-            case 1: base = R_BX+R_DI; break;
-            case 2: base = R_BP+R_SI; break;
-            case 3: base = R_BP+R_DI; break;
-            case 4: base =      R_SI; break;
-            case 5: base =      R_DI; break;
-            case 6: base =      R_BP; break;
-            case 7: base =      R_BX; break;
-        }
-        switch((m>>6)&3) {
-            case 0: if((m&7)==6) base = F16S(addr); break;
-            case 1: base += F8S(addr); break;
-            case 2: base += F16S(addr); break;
-            // case 3 is C0..C7, already dealt with
-        }
-        test->memsize = 4;
-        *(uint32_t*)test->mem = *(uint32_t*)(base+offset);
-        test->memaddr = (uintptr_t)(base+offset);
+        *(uint16_t*)test->mem = *(uint16_t*)(base+rex.offset);
+        test->memaddr = (uintptr_t)(base+rex.offset);
         return (reg64_t*)test->mem;
     }
 }
 
 mmx87_regs_t* GetEm(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta)
 {
+    if(rex.is67 && rex.is32bits) {
+        printf_log(LOG_INFO, "Needed is67 32bits GetEm\n");
+        emu->quit = 1;
+        return NULL;
+    }
     uint8_t m = v&0xC7;    // filter Ed
     if(m>=0xC0) {
          return &emu->mmx[m&0x07];
@@ -847,6 +636,11 @@ mmx87_regs_t* TestEm(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uin
 
 sse_regs_t* GetEx(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta)
 {
+    if(rex.is67 && rex.is32bits) {
+        printf_log(LOG_INFO, "Needed is67 32bits GetEx\n");
+        emu->quit = 1;
+        return NULL;
+    }
     uint8_t m = v&0xC7;    // filter Ed
     if(m>=0xC0) {
          return &emu->xmm[(m&0x07)+(rex.b<<3)];
@@ -882,74 +676,6 @@ sse_regs_t* TestEy(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v)
     }
 }
 
-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, addr, rex, m, delta, offset);
-}
-
-sse_regs_t* TestExO(x64test_t *test, 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 &test->emu->xmm[(m&0x07)+(rex.b<<3)];
-    } else {
-        sse_regs_t* ret = (sse_regs_t*)GetECommonO(test->emu, addr, rex, m, delta, offset);
-        test->memsize = 16;
-        ((uint64_t*)test->mem)[0] = ret->q[0];
-        ((uint64_t*)test->mem)[1] = ret->q[1];
-        test->memaddr = (uintptr_t)ret;
-        return (sse_regs_t*)test->mem;
-    }
-}
-
-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, addr, rex, m, delta, offset);
-}
-
-sse_regs_t* TestEx32O(x64test_t *test, 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 &test->emu->xmm[(m&0x07)+(rex.b<<3)];
-    } else {
-        sse_regs_t* ret = (sse_regs_t*)GetECommon32O(test->emu, addr, rex, m, delta, offset);
-        test->memsize = 16;
-        ((uint64_t*)test->mem)[0] = ret->q[0];
-        ((uint64_t*)test->mem)[1] = ret->q[1];
-        test->memaddr = (uintptr_t)ret;
-        return (sse_regs_t*)test->mem;
-    }
-}
-
-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, addr, rex, m, delta, offset);
-}
-
-mmx87_regs_t* TestEm32O(x64test_t *test, 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 &test->emu->mmx[(m&0x07)];
-    } else {
-        mmx87_regs_t* ret = (mmx87_regs_t*)GetECommon32O(test->emu, addr, rex, m, delta, offset);
-        test->memsize = 8;
-        *(uint64_t*)test->mem = ret->q;
-        test->memaddr = (uintptr_t)ret;
-        return (mmx87_regs_t*)test->mem;
-    }
-}
-
 reg64_t* GetGd(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v)
 {
     return &emu->regs[((v&0x38)>>3)+(rex.r<<3)];