diff options
Diffstat (limited to 'src/emu/x64run_private.c')
| -rw-r--r-- | src/emu/x64run_private.c | 472 |
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)]; |