diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2025-08-22 18:10:13 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2025-08-22 18:10:13 +0200 |
| commit | cb2c29c5f992cb4e5ec481f8d99b973b90411403 (patch) | |
| tree | f7ce3b923e9b48b2605ce6107d1ba6e1039daf87 /src | |
| parent | 3b0977eee16a0fe3a13c393bd786c4fdfda449c9 (diff) | |
| download | box64-cb2c29c5f992cb4e5ec481f8d99b973b90411403.tar.gz box64-cb2c29c5f992cb4e5ec481f8d99b973b90411403.zip | |
[INTERP] Refactored how 64/65/66/67 and F2/F3 prefixes are handled, removing some (mostly) duplicated code
Diffstat (limited to 'src')
| -rw-r--r-- | src/emu/modrm.h | 33 | ||||
| -rw-r--r-- | src/emu/x64run.c | 271 | ||||
| -rw-r--r-- | src/emu/x64run64.c | 1094 | ||||
| -rw-r--r-- | src/emu/x64run64avx.c | 141 | ||||
| -rw-r--r-- | src/emu/x64run66.c | 66 | ||||
| -rw-r--r-- | src/emu/x64run67.c | 602 | ||||
| -rw-r--r-- | src/emu/x64run670f.c | 211 | ||||
| -rw-r--r-- | src/emu/x64run6764.c | 91 | ||||
| -rw-r--r-- | src/emu/x64run6764_32.c | 116 | ||||
| -rw-r--r-- | src/emu/x64run6766.c | 121 | ||||
| -rw-r--r-- | src/emu/x64run67660f.c | 110 | ||||
| -rw-r--r-- | src/emu/x64run67_32.c | 114 | ||||
| -rw-r--r-- | src/emu/x64run67avx.c | 120 | ||||
| -rw-r--r-- | src/emu/x64run_private.c | 472 | ||||
| -rw-r--r-- | src/emu/x64run_private.h | 41 | ||||
| -rw-r--r-- | src/emu/x64rund8.c | 52 | ||||
| -rw-r--r-- | src/emu/x64rund9.c | 46 |
17 files changed, 272 insertions, 3429 deletions
diff --git a/src/emu/modrm.h b/src/emu/modrm.h index d8c68889..d8687df4 100644 --- a/src/emu/modrm.h +++ b/src/emu/modrm.h @@ -25,35 +25,21 @@ #ifdef TEST_INTERPRETER #define GETED(D) oped=TestEd(test, &addr, rex, nextop, D) #define GETE4(D) oped=TestEd4(test, &addr, rex, nextop, D) -#define GETE4_OFFS(D, O) oped=TestEd4O(test, &addr, rex, nextop, D, O) #define GETE8(D) oped=TestEd8(test, &addr, rex, nextop, D) -#define GETE8_OFFS(D, O) oped=TestEd8O(test, &addr, rex, nextop, D, O) #define GETET(D) oped=TestEdt(test, &addr, rex, nextop, D) #define GETE8xw(D) oped=TestEd8xw(test, rex.w, &addr, rex, nextop, D) -#define GETED32(D) oped=TestEd32O(test, &addr, rex, nextop, D, 0) -#define GETED_OFFS(D, O) oped=TestEdO(test, &addr, rex, nextop, D, O) -#define GETED_OFFS_32(D, O) oped=TestEd32O(test, &addr, rex, nextop, D, O) -#define GETED_OFFS_16(O) oped=TestEd16off(test, &addr, rex, nextop, O) #define GETGD opgd=GetGd(test->emu, &addr, rex, nextop) #define GETEB(D) oped=TestEb(test, &addr, rex, nextop, D) -#define GETEB32(D) oped=TestEb32O(test, &addr, rex, nextop, D, 0) -#define GETEB_OFFS(D, O) oped=TestEbO(test, &addr, rex, nextop, D, O) #define GETGB opgd=GetGb(test->emu, &addr, rex, nextop) #define GETEW(D) oped=TestEw(test, &addr, rex, nextop, D) -#define GETEW32(D) oped=TestEw32O(test, &addr, rex, nextop, D, 0) -#define GETEW_OFFS(D, O) oped=TestEdO(test, &addr, rex, nextop, D, O) -#define GETEW_OFFS_16(O) oped=TestEw16off(test, &addr, rex, nextop, O) #define GETGW opgd=GetGw(test->emu, &addr, rex, nextop) #define GETEX(D) opex=TestEx(test, &addr, rex, nextop, D, 16) #define GETEX4(D) opex=TestEx(test, &addr, rex, nextop, D, 4) #define GETEX8(D) opex=TestEx(test, &addr, rex, nextop, D, 8) -#define GETEX32(D) opex=TestEx32O(test, &addr, rex, nextop, D, 0) -#define GETEX_OFFS(D, O) opex=TestExO(test, &addr, rex, nextop, D, O) #define GETGX opgx=GetGx(test->emu, &addr, rex, nextop) #define GETGY opgy=GetGy(test->emu, &addr, rex, nextop) #define GETEY opey=TestEy(test, &addr, rex, nextop) #define GETEM(D) opem=TestEm(test, &addr, rex, nextop, D) -#define GETEM32(D) opem=TestEm32O(test, &addr, rex, nextop, D, 0) #define GETGM opgm=GetGm(test->emu, &addr, rex, nextop) #define GETVX opvx=&test->emu->xmm[vex.v] #define GETVY opvy=&test->emu->ymm[vex.v] @@ -61,35 +47,21 @@ #else #define GETED(D) oped=GetEd(emu, &addr, rex, nextop, D) #define GETE4(D) GETED(D) -#define GETE4_OFFS(D, O) GETED_OFFS(D, O) #define GETE8(D) GETED(D) -#define GETE8_OFFS(D, O) GETED_OFFS(D, O) #define GETET(D) GETED(D) #define GETE8xw(D) GETED(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 GETED_OFFS_32(D, O) oped=GetEd32O(emu, &addr, rex, nextop, D, O) -#define GETED_OFFS_16(O) oped=GetEd16off(emu, &addr, rex, nextop, 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 GETEW_OFFS_16(O) oped=GetEw16off(emu, &addr, rex, nextop, O) #define GETGW opgd=GetGw(emu, &addr, rex, nextop) #define GETEX(D) opex=GetEx(emu, &addr, rex, nextop, D) #define GETEX4(D) GETEX(D) #define GETEX8(D) GETEX(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 GETGY opgy=GetGy(emu, &addr, rex, nextop) #define GETEY opey=(opex>=&emu->xmm[0] && opex<=&emu->xmm[15])?((sse_regs_t*)((uintptr_t)opex+offsetof(x64emu_t, ymm)-offsetof(x64emu_t, xmm))):((sse_regs_t*)((uintptr_t)opex+16)) #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 GETVX opvx=&emu->xmm[vex.v] #define GETVY opvy=&emu->ymm[vex.v] @@ -111,13 +83,8 @@ #define EM opem #define GM opgm #define FAKEED(D) GetEd(emu, &addr, rex, nextop, D) -#define FAKEED32(D) GetEd32O(emu, &addr, rex, nextop, D, 0) #define GETEA(D) GetEA(emu, &addr, rex, nextop, D) -#define GETEA32(D) GetEA32(emu, &addr, rex, nextop, D) -#define GETEA32_16(D) GetEA32_16(emu, &addr, rex, nextop, D) #define _GETED(D) oped=GetEd(emu, &addr, rex, nextop, D) -#define _GETED_OFFS(D, O) oped=GetEdO(emu, &addr, rex, nextop, D, O) -#define _GETED32(D) oped=GetEd32O(emu, &addr, rex, nextop, D, 0) #define _GETEB(D) oped=GetEb(emu, &addr, rex, nextop, D) #define _GETEX(D) opex=GetEx(emu, &addr, rex, nextop, D) diff --git a/src/emu/x64run.c b/src/emu/x64run.c index a393e84c..9c536731 100644 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -51,7 +51,6 @@ int Run(x64emu_t *emu, int step) #endif uintptr_t addr = R_RIP; rex_t rex = {0}; - int rep; // 0 none, 1=F2 prefix, 2=F3 prefix int unimp = 0; int is32bits = (emu->segs[_CS]==0x23); int tf_next = 0; @@ -85,24 +84,53 @@ x64emurun: opcode = F8; - rep = 0; - while((opcode==0xF2) || (opcode==0xF3) || (opcode==0x3E) || (opcode==0x26)) { + rex.rex = 0; + rex.seg = 0; + rex.offset = 0; + rex.is32bits = is32bits; + rex.is66 = 0; + rex.is67 = 0; + rex.rep = 0; + while((opcode==0xF2) || (opcode==0xF3) + || (opcode==0x3E) || (opcode==0x26) || (opcode==0x2e) || (opcode==0x36) + || (opcode==0x64) || (opcode==0x65) || (opcode==0x66) || (opcode==0x67) + || (!is32bits && (opcode>=0x40 && opcode<=0x4f))) { switch (opcode) { - case 0xF2: rep = 1; break; - case 0xF3: rep = 2; break; - case 0x3E: - case 0x26: /* ignored*/ break; + case 0xF2: rex.rep = 1; rex.rex = 0; break; + case 0xF3: rex.rep = 2; rex.rex = 0; break; + case 0x26: /* ES: */ + case 0x2E: /* CS: */ + case 0x36: /* SS; */ + case 0x3E: /* DS; */ + rex.seg = 0; rex.rex = 0; break; + case 0x64: rex.seg = _FS; rex.rex = 0; break; + case 0x65: rex.seg = _GS; rex.rex = 0; break; + case 0x66: rex.is66 = 1; rex.rex = 0; break; + case 0x67: rex.is67 = 1; rex.rex = 0; break; + case 0x40 ... 0x4F: rex.rex = opcode; break; } opcode = F8; } - rex.rex = 0; - rex.is32bits = is32bits; - if(!is32bits) - while(opcode>=0x40 && opcode<=0x4f) { - rex.rex = opcode; - opcode = F8; - } + if(rex.seg) + rex.offset = GetSegmentBaseEmu(emu, rex.seg); + + if(rex.is66) { + /* 16bits prefix */ + #ifdef TEST_INTERPRETER + if(!(addr = Test66(test, rex, addr-1))) + unimp = 1; + #else + if(!(addr = Run66(emu, rex, addr-1))) { + unimp = 1; + goto fini; + } + if(emu->quit) { + R_RIP = addr; + goto fini; + } + #endif + } else switch(opcode) { #define GO(B, OP) \ @@ -175,7 +203,7 @@ x64emurun: Push32(emu, emu->segs[_CS]); // even if a segment is a 16bits, a 32bits push/pop is done break; case 0x0F: /* More instructions */ - switch(rep) { + switch(rex.rep) { case 1: #ifdef TEST_INTERPRETER if(!(addr = TestF20F(test, rex, addr, &step))) @@ -458,98 +486,7 @@ x64emurun: GD->sdword[0] = ED->sdword[0]; // meh? } break; - case 0x64: /* FS: prefix */ - #ifdef TEST_INTERPRETER - if(!(addr = Test64(test, rex, _FS, addr))) - unimp = 1; - #else - if(!(addr = Run64(emu, rex, _FS, addr))) { - unimp = 1; - goto fini; - } - if(emu->quit) { - R_RIP = addr; - goto fini; - } - if(is32bits!=(emu->segs[_CS]==0x23)) { - is32bits = (emu->segs[_CS]==0x23); - if(is32bits) { - // Zero upper part of the 32bits regs - R_RAX = R_EAX; - R_RBX = R_EBX; - R_RCX = R_ECX; - R_RDX = R_EDX; - R_RSP = R_ESP; - R_RBP = R_EBP; - R_RSI = R_ESI; - R_RDI = R_EDI; - } - if(is32bits) - running32bits = 1; - } - #endif - break; - case 0x65: /* GS: prefix */ - #ifdef TEST_INTERPRETER - if(!(addr = Test64(test, rex, _GS, addr))) - unimp = 1; - #else - if(!(addr = Run64(emu, rex, _GS, addr))) { - unimp = 1; - goto fini; - } - if(emu->quit) { - R_RIP = addr; - goto fini; - } - if(is32bits!=(emu->segs[_CS]==0x23)) { - is32bits = (emu->segs[_CS]==0x23); - if(is32bits) { - // Zero upper part of the 32bits regs - R_RAX = R_EAX; - R_RBX = R_EBX; - R_RCX = R_ECX; - R_RDX = R_EDX; - R_RSP = R_ESP; - R_RBP = R_EBP; - R_RSI = R_ESI; - R_RDI = R_EDI; - } - if(is32bits) - running32bits = 1; - } - #endif - break; - case 0x66: /* 16bits prefix */ - #ifdef TEST_INTERPRETER - if(!(addr = Test66(test, rex, rep, addr))) - unimp = 1; - #else - if(!(addr = Run66(emu, rex, rep, addr))) { - unimp = 1; - goto fini; - } - if(emu->quit) { - R_RIP = addr; - goto fini; - } - #endif - break; - case 0x67: /* reduce EASize prefix */ - #ifdef TEST_INTERPRETER - if(!(addr = Test67(test, rex, rep, addr))) - unimp = 1; - #else - if(!(addr = Run67(emu, rex, rep, addr))) { - unimp = 1; - goto fini; - } - if(emu->quit) { - R_RIP = addr; - goto fini; - } - #endif - break; + case 0x68: /* Push Id */ if(rex.is32bits) Push32(emu, F32); @@ -919,39 +856,39 @@ x64emurun: break; case 0xA0: /* MOV AL,Ob */ if(rex.is32bits) - R_AL = *(uint8_t*)(uintptr_t)F32; + R_AL = *(uint8_t*)(uintptr_t)(ptr_t)(F32+rex.offset); else - R_AL = *(uint8_t*)F64; + R_AL = *(uint8_t*)(F64+rex.offset); break; case 0xA1: /* MOV EAX,Od */ if(rex.is32bits) - R_EAX = *(int32_t*)(uintptr_t)F32; + R_EAX = *(int32_t*)(uintptr_t)(ptr_t)(F32+rex.offset); else { if(rex.w) - R_RAX = *(uint64_t*)F64; + R_RAX = *(uint64_t*)(F64+rex.offset); else - R_RAX = *(uint32_t*)F64; + R_RAX = *(uint32_t*)(F64+rex.offset); } break; case 0xA2: /* MOV Ob,AL */ if(rex.is32bits) - *(uint8_t*)(uintptr_t)F32 = R_AL; + *(uint8_t*)(uintptr_t)(ptr_t)(F32+rex.offset) = R_AL; else - *(uint8_t*)F64 = R_AL; + *(uint8_t*)(F64+rex.offset) = R_AL; break; case 0xA3: /* MOV Od,EAX */ if(rex.is32bits) - *(uint32_t*)(uintptr_t)F32 = R_EAX; + *(uint32_t*)(uintptr_t)(ptr_t)(F32+rex.offset) = R_EAX; else { if(rex.w) - *(uint64_t*)F64 = R_RAX; + *(uint64_t*)(F64+rex.offset) = R_RAX; else - *(uint32_t*)F64 = R_EAX; + *(uint32_t*)(F64+rex.offset) = R_EAX; } break; case 0xA4: /* MOVSB */ tmp8s = ACCESS_FLAG(F_DF)?-1:+1; - tmp64u = (rep)?R_RCX:1L; + tmp64u = (rex.rep)?R_RCX:1L; while(tmp64u) { #ifndef TEST_INTERPRETER *(uint8_t*)R_RDI = *(uint8_t*)R_RSI; @@ -960,12 +897,12 @@ x64emurun: R_RSI += tmp8s; --tmp64u; } - if(rep) + if(rex.rep) R_RCX = tmp64u; break; case 0xA5: /* (REP) MOVSD */ tmp8s = ACCESS_FLAG(F_DF)?-1:+1; - tmp64u = (rep)?R_RCX:1L; + tmp64u = (rex.rep)?R_RCX:1L; if(rex.w) { tmp8s *= 8; while(tmp64u) { @@ -987,12 +924,12 @@ x64emurun: R_RSI += tmp8s; } } - if(rep) + if(rex.rep) R_RCX = tmp64u; break; case 0xA6: /* (REPZ/REPNE) CMPSB */ tmp8s = ACCESS_FLAG(F_DF)?-1:+1; - switch(rep) { + switch(rex.rep) { case 1: if(R_RCX) { while(R_RCX) { @@ -1034,7 +971,7 @@ x64emurun: tmp8s = ACCESS_FLAG(F_DF)?-8:+8; else tmp8s = ACCESS_FLAG(F_DF)?-4:+4; - switch(rep) { + switch(rex.rep) { case 1: if(R_RCX) { if(rex.w) { @@ -1117,7 +1054,7 @@ x64emurun: case 0xAA: /* (REP) STOSB */ tmp8s = ACCESS_FLAG(F_DF)?-1:+1; - tmp64u = (rep)?R_RCX:1L; + tmp64u = (rex.rep)?R_RCX:1L; while(tmp64u) { #ifndef TEST_INTERPRETER *(uint8_t*)R_RDI = R_AL; @@ -1125,7 +1062,7 @@ x64emurun: R_RDI += tmp8s; --tmp64u; } - if(rep) + if(rex.rep) R_RCX = tmp64u; break; case 0xAB: /* (REP) STOSD */ @@ -1133,7 +1070,7 @@ x64emurun: tmp8s = ACCESS_FLAG(F_DF)?-8:+8; else tmp8s = ACCESS_FLAG(F_DF)?-4:+4; - tmp64u = (rep)?R_RCX:1L; + tmp64u = (rex.rep)?R_RCX:1L; if((rex.w)) while(tmp64u) { #ifndef TEST_INTERPRETER @@ -1148,18 +1085,18 @@ x64emurun: R_RDI += tmp8s; --tmp64u; } - if(rep) + if(rex.rep) R_RCX = tmp64u; break; case 0xAC: /* LODSB */ tmp8s = ACCESS_FLAG(F_DF)?-1:+1; - tmp64u = (rep)?R_RCX:1L; + tmp64u = (rex.rep)?R_RCX:1L; while(tmp64u) { R_AL = *(uint8_t*)R_RSI; R_RSI += tmp8s; --tmp64u; } - if(rep) + if(rex.rep) R_RCX = tmp64u; break; case 0xAD: /* (REP) LODSD */ @@ -1167,7 +1104,7 @@ x64emurun: tmp8s = ACCESS_FLAG(F_DF)?-8:+8; else tmp8s = ACCESS_FLAG(F_DF)?-4:+4; - tmp64u = (rep)?R_RCX:1L; + tmp64u = (rex.rep)?R_RCX:1L; if((rex.w)) while(tmp64u) { R_RAX = *(uint64_t*)R_RSI; @@ -1180,12 +1117,12 @@ x64emurun: R_RSI += tmp8s; --tmp64u; } - if(rep) + if(rex.rep) R_RCX = tmp64u; break; case 0xAE: /* (REPZ/REPNE) SCASB */ tmp8s = ACCESS_FLAG(F_DF)?-1:+1; - switch(rep) { + switch(rex.rep) { case 1: if(R_RCX) { while(R_RCX) { @@ -1220,7 +1157,7 @@ x64emurun: tmp8s = ACCESS_FLAG(F_DF)?-8:+8; else tmp8s = ACCESS_FLAG(F_DF)?-4:+4; - switch(rep) { + switch(rex.rep) { case 1: if(R_RCX) { if(rex.w) { @@ -1723,10 +1660,10 @@ x64emurun: break; case 0xD8: /* x87 opcodes */ #ifdef TEST_INTERPRETER - if(!(addr = TestD8(test, rex, addr, 0))) + if(!(addr = TestD8(test, rex, addr))) unimp = 1; #else - if(!(addr = RunD8(emu, rex, addr, 0))) { + if(!(addr = RunD8(emu, rex, addr))) { unimp = 1; goto fini; } @@ -1738,10 +1675,10 @@ x64emurun: break; case 0xD9: /* x87 opcodes */ #ifdef TEST_INTERPRETER - if(!(addr = TestD9(test, rex, addr, 0))) + if(!(addr = TestD9(test, rex, addr))) unimp = 1; #else - if(!(addr = RunD9(emu, rex, addr, 0))) { + if(!(addr = RunD9(emu, rex, addr))) { unimp = 1; goto fini; } @@ -1844,30 +1781,68 @@ x64emurun: case 0xE0: /* LOOPNZ */ CHECK_FLAGS(emu); tmp8s = F8S; - --R_RCX; // don't update flags - if(R_RCX && !ACCESS_FLAG(F_ZF)) - addr += tmp8s; + if(rex.is32bits && rex.is67) { + --R_CX; // don't update flags + if(R_CX && !ACCESS_FLAG(F_ZF)) + addr += tmp8s; + } else if(rex.is32bits || rex.is67) { + --R_ECX; // don't update flags + if(R_ECX && !ACCESS_FLAG(F_ZF)) + addr += tmp8s; + } else { + --R_RCX; // don't update flags + if(R_RCX && !ACCESS_FLAG(F_ZF)) + 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)) - addr += tmp8s; + if(rex.is32bits && rex.is67) { + --R_CX; // don't update flags + if(R_CX && ACCESS_FLAG(F_ZF)) + addr += tmp8s; + } else if(rex.is32bits || rex.is67) { + --R_ECX; // don't update flags + if(R_ECX && ACCESS_FLAG(F_ZF)) + addr += tmp8s; + } else { + --R_RCX; // don't update flags + if(R_RCX && ACCESS_FLAG(F_ZF)) + addr += tmp8s; + } STEP2 break; case 0xE2: /* LOOP */ tmp8s = F8S; - --R_RCX; // don't update flags - if(R_RCX) - addr += tmp8s; + if(rex.is32bits && rex.is67) { + --R_CX; // don't update flags + if(R_CX) + addr += tmp8s; + } else if(rex.is32bits || rex.is67) { + --R_ECX; // don't update flags + if(R_ECX) + addr += tmp8s; + } else { + --R_RCX; // don't update flags + if(R_RCX) + addr += tmp8s; + } STEP2 break; case 0xE3: /* JRCXZ */ tmp8s = F8S; - if(!R_RCX) - addr += tmp8s; + if(rex.is32bits && rex.is67) { + if(!R_CX) + addr += tmp8s; + } else if(rex.is32bits || rex.is67) { + if(!R_ECX) + addr += tmp8s; + } else { + if(!R_RCX) + addr += tmp8s; + } STEP2 break; case 0xE4: /* IN AL, XX */ diff --git a/src/emu/x64run64.c b/src/emu/x64run64.c deleted file mode 100644 index 40cf5eb9..00000000 --- a/src/emu/x64run64.c +++ /dev/null @@ -1,1094 +0,0 @@ -#define _GNU_SOURCE -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include <string.h> -#include <signal.h> -#include <sys/types.h> -#include <unistd.h> - -#include "debug.h" -#include "box64stack.h" -#include "box64cpu_util.h" -#include "x64emu.h" -#include "x64emu_private.h" -#include "x64run_private.h" -#include "x64primop.h" -#include "x64trace.h" -#include "x87emu_private.h" -#include "box64context.h" -#include "alternate.h" -#include "emit_signals.h" - -#include "modrm.h" - -#ifdef TEST_INTERPRETER -uintptr_t Test64(x64test_t *test, rex_t rex, int seg, uintptr_t addr) -#else -uintptr_t Run64(x64emu_t *emu, rex_t rex, int seg, uintptr_t addr) -#endif -{ - uint8_t opcode; - uint8_t nextop; - uint8_t tmp8u; (void)tmp8u; - int16_t tmp16s; (void)tmp16s; - uint16_t tmp16u; (void)tmp16u; - int32_t tmp32s; - uint32_t tmp32u; - uint64_t tmp64u; - reg64_t *oped, *opgd; - sse_regs_t *opex, *opgx; - int rep; - #ifdef TEST_INTERPRETER - x64emu_t* emu = test->emu; - #endif - int is_nan; - uintptr_t tlsdata = GetSegmentBaseEmu(emu, seg); - - opcode = F8; - // REX prefix before the F0 are ignored - rex.rex = 0; - if(!rex.is32bits) - while(opcode>=0x40 && opcode<=0x4f) { - rex.rex = opcode; - opcode = F8; - } - rep = 0; - while((opcode==0xF2) || (opcode==0xF3)) { - rep = opcode-0xF1; - opcode = F8; - } - if(!rex.is32bits) - while(opcode>=0x40 && opcode<=0x4f) { - rex.rex = opcode; - opcode = F8; - } - - switch(opcode) { - #define GO(B, OP) \ - case B+0: \ - nextop = F8; \ - GETEB_OFFS(0, tlsdata); \ - GETGB; \ - EB->byte[0] = OP##8(emu, EB->byte[0], GB); \ - break; \ - case B+1: \ - nextop = F8; \ - GETED_OFFS(0, tlsdata); \ - GETGD; \ - if(rex.w) \ - ED->q[0] = OP##64(emu, ED->q[0], GD->q[0]); \ - else { \ - if(MODREG) \ - ED->q[0] = OP##32(emu, ED->dword[0], GD->dword[0]); \ - else \ - ED->dword[0] = OP##32(emu, ED->dword[0], GD->dword[0]); \ - } \ - break; \ - case B+2: \ - nextop = F8; \ - GETEB_OFFS(0, tlsdata); \ - GETGB; \ - GB = OP##8(emu, GB, EB->byte[0]); \ - break; \ - case B+3: \ - nextop = F8; \ - GETED_OFFS(0, tlsdata); \ - GETGD; \ - if(rex.w) \ - GD->q[0] = OP##64(emu, GD->q[0], ED->q[0]); \ - else \ - GD->q[0] = OP##32(emu, GD->dword[0], ED->dword[0]); \ - break; \ - case B+4: \ - R_AL = OP##8(emu, R_AL, F8); \ - break; \ - case B+5: \ - if(rex.w) \ - R_RAX = OP##64(emu, R_RAX, F32S64); \ - else \ - R_RAX = OP##32(emu, R_EAX, F32); \ - break; - - GO(0x00, add) /* ADD 0x00 -> 0x05 */ - GO(0x08, or) /* OR 0x08 -> 0x0D */ - GO(0x10, adc) /* ADC 0x10 -> 0x15 */ - GO(0x18, sbb) /* SBB 0x18 -> 0x1D */ - GO(0x20, and) /* AND 0x20 -> 0x25 */ - GO(0x28, sub) /* SUB 0x28 -> 0x2D */ - GO(0x30, xor) /* XOR 0x30 -> 0x35 */ - #undef GO - case 0x0F: - opcode = F8; - switch(opcode) { - - case 0x10: - switch(rep) { - case 0: /* MOVUPS Gx, FS:Ex */ - nextop = F8; - GETEX_OFFS(0, tlsdata); - GETGX; - GX->u128 = EX->u128; - break; - case 1: /* MOVSD Gx, FS:Ex */ - nextop = F8; - GETEX_OFFS(0, tlsdata); - GETGX; - GX->q[0] = EX->q[0]; - if(!MODREG) { - // EX is not a register - GX->q[1] = 0; - } - break; - case 2: /* MOVSS Gx, FS:Ex */ - nextop = F8; - GETEX_OFFS(0, tlsdata); - GETGX; - GX->ud[0] = EX->ud[0]; - if(!MODREG) { - // EX is not a register (reg to reg only move 31:0) - GX->ud[1] = GX->ud[2] = GX->ud[3] = 0; - } - break; - default: - return 0; - } - break; - case 0x11: - switch(rep) { - case 0: /* MOVUPS FS:Ex, Gx */ - nextop = F8; - GETEX_OFFS(0, tlsdata); - GETGX; - EX->u128 = GX->u128; - break; - case 1: /* MOVSD Ex, Gx */ - nextop = F8; - GETEX_OFFS(0, tlsdata); - GETGX; - EX->q[0] = GX->q[0]; - break; - case 2: /* MOVSS FS:Ex, Gx */ - nextop = F8; - GETEX_OFFS(0, tlsdata); - GETGX; - EX->ud[0] = GX->ud[0]; - break; - default: - return 0; - } - break; - - case 0x18: - case 0x19: - case 0x1F: /* NOP (multi-byte) */ - nextop = F8; - FAKEED(0); - break; - case 0x28: - switch(rep) { - case 0: /* MOVAPS Gx, FS:Ex */ - nextop = F8; - GETEX_OFFS(0, tlsdata); - GETGX; - GX->u128 = EX->u128; - break; - default: - return 0; - } - break; - case 0x29: /* MOVAPS FS:Ex,Gx */ - switch(rep) { - case 0: - nextop = F8; - GETEX_OFFS(0, tlsdata); - GETGX; - EX->q[0] = GX->q[0]; - EX->q[1] = GX->q[1]; - break; - default: - return 0; - } - break; - - case 0x58: - switch(rep) { - case 2: /* ADDSS Gx, FS:Ex */ - nextop = F8; - GETEX_OFFS(0, tlsdata); - GETGX; - is_nan = isnanf(GX->f[0]) || isnanf(EX->f[0]); - NAN_PROPAGATION(GX->f[0], EX->f[0], break); - GX->f[0] += EX->f[0]; - if(!is_nan && isnanf(GX->f[0])) GX->f[0] = -NAN; - break; - - default: - return 0; - } - break; - case 0x59: - switch(rep) { - case 2: /* MULSS Gx, FS:Ex */ - nextop = F8; - GETEX_OFFS(0, tlsdata); - GETGX; - NAN_PROPAGATION(GX->f[0], EX->f[0], break); - GX->f[0] *= EX->f[0]; - break; - - default: - return 0; - } - break; - case 0x5A: - switch(rep) { - case 2: /* CVTSS2SD Gx, FS:Ex */ - nextop = F8; - GETEX_OFFS(0, tlsdata); - GETGX; - GX->d[0] = EX->f[0]; - break; - - default: - return 0; - } - break; - - case 0x6F: - switch(rep) { - case 2: /* MOVDQU Gx, FS:Ex */ - nextop = F8; - GETEX_OFFS(0, tlsdata); - GETGX; - memcpy(GX, EX, 16); // unaligned... - break; - - default: - return 0; - } - break; - - case 0x7F: - switch(rep) { - case 2: /* MOVDQU FS:Ex, Gx */ - nextop = F8; - GETEX_OFFS(0, tlsdata); - GETGX; - memcpy(EX, GX, 16); // unaligned... - break; - default: - return 0; - } - break; - - case 0xAF: - switch(rep) { - case 0: /* IMUL Gd, FS:Ed */ - nextop = F8; - GETED_OFFS(0, tlsdata); - GETGD; - if(rex.w) - GD->q[0] = imul64(emu, GD->q[0], ED->q[0]); - else - GD->q[0] = imul32(emu, GD->dword[0], ED->dword[0]); - break; - default: - return 0; - } - break; - - case 0xB6: - switch(rep) { - case 0: /* MOVZX Gd, FS:Eb */ - nextop = F8; - GETEB_OFFS(0, tlsdata); - GETGD; - GD->q[0] = EB->byte[0]; - break; - default: - return 0; - } - break; - case 0xB7: - switch(rep) { - case 0: /* MOVZX Gd, FS:Ew */ - nextop = F8; - GETEW_OFFS(0, tlsdata); - GETGD; - GD->q[0] = EW->word[0]; - break; - default: - return 0; - } - break; - - case 0xBA: - nextop = F8; - switch((nextop>>3)&7) { - case 4: /* BT Ed,Ib */ - CHECK_FLAGS(emu); - GETED_OFFS(1, tlsdata); - tmp8u = F8; - if(rex.w) { - tmp8u&=63; - if(ED->q[0] & (1LL<<tmp8u)) - SET_FLAG(F_CF); - else - CLEAR_FLAG(F_CF); - } else { - tmp8u&=31; - if(ED->dword[0] & (1<<tmp8u)) - SET_FLAG(F_CF); - else - CLEAR_FLAG(F_CF); - } - if (BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_PF); - } - break; - case 5: /* BTS Ed, Ib */ - CHECK_FLAGS(emu); - GETED_OFFS(1, tlsdata); - tmp8u = F8; - if(rex.w) { - tmp8u&=63; - if(ED->q[0] & (1LL<<tmp8u)) { - SET_FLAG(F_CF); - } else { - ED->q[0] ^= (1LL<<tmp8u); - CLEAR_FLAG(F_CF); - } - } else { - tmp8u&=31; - if(ED->dword[0] & (1<<tmp8u)) { - SET_FLAG(F_CF); - } else { - ED->dword[0] ^= (1<<tmp8u); - CLEAR_FLAG(F_CF); - } - if(MODREG) - ED->dword[1] = 0; - } - if (BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_PF); - } - break; - case 6: /* BTR Ed, Ib */ - CHECK_FLAGS(emu); - GETED_OFFS(1, tlsdata); - tmp8u = F8; - if(rex.w) { - tmp8u&=63; - if(ED->q[0] & (1LL<<tmp8u)) { - SET_FLAG(F_CF); - ED->q[0] ^= (1LL<<tmp8u); - } else - CLEAR_FLAG(F_CF); - } else { - tmp8u&=31; - if(ED->dword[0] & (1<<tmp8u)) { - SET_FLAG(F_CF); - ED->dword[0] ^= (1<<tmp8u); - } else - CLEAR_FLAG(F_CF); - if(MODREG) - ED->dword[1] = 0; - } - if (BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_PF); - } - break; - case 7: /* BTC Ed, Ib */ - CHECK_FLAGS(emu); - GETED_OFFS(1, tlsdata); - tmp8u = F8; - if(rex.w) { - tmp8u&=63; - if(ED->q[0] & (1LL<<tmp8u)) - SET_FLAG(F_CF); - else - CLEAR_FLAG(F_CF); - ED->q[0] ^= (1LL<<tmp8u); - } else { - tmp8u&=31; - if(ED->dword[0] & (1<<tmp8u)) - SET_FLAG(F_CF); - else - CLEAR_FLAG(F_CF); - ED->dword[0] ^= (1<<tmp8u); - if(MODREG) - ED->dword[1] = 0; - } - if (BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_PF); - } - break; - - default: - return 0; - } - break; - - case 0xBF: - switch(rep) { - case 0: /* MOVSX Gd,FS:Ew */ - nextop = F8; - GETEW_OFFS(0, tlsdata); - GETGD; - if(rex.w) - GD->sq[0] = EW->sword[0]; - else { - GD->sdword[0] = EW->sword[0]; - GD->dword[1] = 0; - } - break; - default: - return 0; - } - break; - - default: - return 0; - } - break; - - case 0x38: - nextop = F8; - GETEB_OFFS(0, tlsdata); - GETGB; - cmp8(emu, EB->byte[0], GB); - break; - case 0x39: - nextop = F8; - GETED_OFFS(0, tlsdata); - GETGD; - if(rex.w) - cmp64(emu, ED->q[0], GD->q[0]); - else - cmp32(emu, ED->dword[0], GD->dword[0]); - break; - - case 0x3B: - nextop = F8; - GETED_OFFS(0, tlsdata); - GETGD; - if(rex.w) - cmp64(emu, GD->q[0], ED->q[0]); - else - cmp32(emu, GD->dword[0], ED->dword[0]); - break; - - - case 0x63: /* MOVSXD Gd, FS:Ed */ - nextop = F8; - GETED_OFFS(0, tlsdata); - GETGD; - if(rex.is32bits) { - // ARPL here - // faking to always happy... - SET_FLAG(F_ZF); - } else { - if(rex.w) - GD->sq[0] = ED->sdword[0]; - else - if(MODREG) - GD->q[0] = ED->dword[0]; // not really a sign extension - else - GD->sdword[0] = ED->sdword[0]; // meh? - } - break; - case 0x64: /* FS: prefix */ - #ifdef TEST_INTERPRETER - return Test64(test, rex, _FS, addr); - #else - return Run64(emu, rex, _FS, addr); - #endif - break; - case 0x65: /* GS: prefix */ - #ifdef TEST_INTERPRETER - return Test64(test, rex, _GS, addr); - #else - return Run64(emu, rex, _GS, addr); - #endif - break; - case 0x66: - return Run6664(emu, rex, seg, addr); - case 0x67: - if(rex.is32bits) - return Run6764_32(emu, rex, seg, seg, addr); - else - return Run6764(emu, rex, seg, seg, addr); - - case 0x69: /* IMUL Gd,Ed,Id */ - nextop = F8; - GETED_OFFS(4, tlsdata); - GETGD; - tmp64u = F32S64; - if(rex.w) - GD->q[0] = imul64(emu, ED->q[0], tmp64u); - else - GD->q[0] = imul32(emu, ED->dword[0], tmp64u); - break; - - case 0x6C: /* INSB DX */ - case 0x6D: /* INSD DX */ - case 0x6E: /* OUTSB DX */ - case 0x6F: /* OUTSD DX */ - return addr-1; // skip 64/65 prefix and resume normal execution - - case 0x80: /* GRP Eb,Ib */ - nextop = F8; - GETEB_OFFS(1, tlsdata); - tmp8u = F8; - switch((nextop>>3)&7) { - case 0: EB->byte[0] = add8(emu, EB->byte[0], tmp8u); break; - case 1: EB->byte[0] = or8(emu, EB->byte[0], tmp8u); break; - case 2: EB->byte[0] = adc8(emu, EB->byte[0], tmp8u); break; - case 3: EB->byte[0] = sbb8(emu, EB->byte[0], tmp8u); break; - case 4: EB->byte[0] = and8(emu, EB->byte[0], tmp8u); break; - case 5: EB->byte[0] = sub8(emu, EB->byte[0], tmp8u); break; - case 6: EB->byte[0] = xor8(emu, EB->byte[0], tmp8u); break; - case 7: cmp8(emu, EB->byte[0], tmp8u); break; - } - break; - case 0x81: /* GRP Ed,Id */ - case 0x83: /* GRP Ed,Ib */ - nextop = F8; - GETED_OFFS((opcode==0x81)?4:1, tlsdata); - if(opcode==0x81) { - tmp32s = F32S; - } else { - tmp32s = F8S; - } - if(rex.w) { - tmp64u = (uint64_t)(int64_t)tmp32s; - switch((nextop>>3)&7) { - case 0: ED->q[0] = add64(emu, ED->q[0], tmp64u); break; - case 1: ED->q[0] = or64(emu, ED->q[0], tmp64u); break; - case 2: ED->q[0] = adc64(emu, ED->q[0], tmp64u); break; - case 3: ED->q[0] = sbb64(emu, ED->q[0], tmp64u); break; - case 4: ED->q[0] = and64(emu, ED->q[0], tmp64u); break; - case 5: ED->q[0] = sub64(emu, ED->q[0], tmp64u); break; - case 6: ED->q[0] = xor64(emu, ED->q[0], tmp64u); break; - case 7: cmp64(emu, ED->q[0], tmp64u); break; - } - } else { - tmp32u = (uint32_t)tmp32s; - if(MODREG) - switch((nextop>>3)&7) { - case 0: ED->q[0] = add32(emu, ED->dword[0], tmp32u); break; - case 1: ED->q[0] = or32(emu, ED->dword[0], tmp32u); break; - case 2: ED->q[0] = adc32(emu, ED->dword[0], tmp32u); break; - case 3: ED->q[0] = sbb32(emu, ED->dword[0], tmp32u); break; - case 4: ED->q[0] = and32(emu, ED->dword[0], tmp32u); break; - case 5: ED->q[0] = sub32(emu, ED->dword[0], tmp32u); break; - case 6: ED->q[0] = xor32(emu, ED->dword[0], tmp32u); break; - case 7: cmp32(emu, ED->dword[0], tmp32u); break; - } - else - switch((nextop>>3)&7) { - case 0: ED->dword[0] = add32(emu, ED->dword[0], tmp32u); break; - case 1: ED->dword[0] = or32(emu, ED->dword[0], tmp32u); break; - case 2: ED->dword[0] = adc32(emu, ED->dword[0], tmp32u); break; - case 3: ED->dword[0] = sbb32(emu, ED->dword[0], tmp32u); break; - case 4: ED->dword[0] = and32(emu, ED->dword[0], tmp32u); break; - case 5: ED->dword[0] = sub32(emu, ED->dword[0], tmp32u); break; - case 6: ED->dword[0] = xor32(emu, ED->dword[0], tmp32u); break; - case 7: cmp32(emu, ED->dword[0], tmp32u); break; - } - } - break; - - case 0x85: /* TEST Ed,Gd */ - nextop = F8; - GETED_OFFS(0, tlsdata); - GETGD; - if(rex.w) - test64(emu, ED->q[0], GD->q[0]); - else - test32(emu, ED->dword[0], GD->dword[0]); - break; - case 0x86: /* XCHG Eb,Gb */ - nextop = F8; -#if defined(DYNAREC) && !defined(TEST_INTERPRETER) - GETEB_OFFS(0, tlsdata); - GETGB; - if(MODREG) { // reg / reg: no lock - tmp8u = GB; - GB = EB->byte[0]; - EB->byte[0] = tmp8u; - } else { - GB = native_lock_xchg_b(EB, GB); - } - // dynarec use need it's own mecanism -#else - GETEB_OFFS(0, tlsdata); - GETGB; - if(!MODREG) - pthread_mutex_lock(&my_context->mutex_lock); // XCHG always LOCK (but when accessing memory only) - tmp8u = GB; - GB = EB->byte[0]; - EB->byte[0] = tmp8u; - if(!MODREG) - pthread_mutex_unlock(&my_context->mutex_lock); -#endif - break; - - case 0x88: /* MOV FS:Eb,Gb */ - nextop = F8; - GETEB_OFFS(0, tlsdata); - GETGB; - EB->byte[0] = GB; - break; - case 0x89: /* MOV FS:Ed,Gd */ - nextop = F8; - GETED_OFFS(0, tlsdata); - GETGD; - if(rex.w) { - ED->q[0] = GD->q[0]; - } else { - if(MODREG) - ED->q[0] = GD->dword[0]; - else - ED->dword[0] = GD->dword[0]; - } - break; - case 0x8A: /* MOV Gb, FS:Eb */ - nextop = F8; - GETEB_OFFS(0, tlsdata); - GETGB; - GB = EB->byte[0]; - break; - case 0x8B: /* MOV Gd, FS:Ed */ - nextop = F8; - GETED_OFFS(0, tlsdata); - GETGD; - if(rex.w) - GD->q[0] = ED->q[0]; - else - GD->q[0] = ED->dword[0]; - break; - - case 0x8D: /* LEA Gd,M */ - nextop = F8; - GETGD; - tmp64u = GETEA(0); - if(rex.w) - GD->q[0] = tmp64u; - else - GD->q[0] = tmp64u&0xffffffff; - break; - case 0x8E: /* MOV Seg, Seg:Ew */ - nextop = F8; - GETED_OFFS(0, tlsdata); - emu->segs[((nextop&0x38)>>3)] = ED->word[0]; - emu->segs_serial[((nextop&0x38)>>3)] = 0; - break; - case 0x8F: /* POP FS:Ed */ - nextop = F8; - if(MODREG) { - emu->regs[(nextop&7)+(rex.b<<3)].q[0] = Pop64(emu); - } else { - if(rex.is32bits) { - tmp32u = Pop32(emu); // this order allows handling POP [ESP] and variant - GETED_OFFS(0, tlsdata); - R_ESP -= 4; // to prevent issue with SEGFAULT - ED->dword[0] = tmp32u; - R_ESP += 4; - } else { - tmp64u = Pop64(emu); // this order allows handling POP [ESP] and variant - GETED_OFFS(0, tlsdata); - R_RSP -= sizeof(void*); // to prevent issue with SEGFAULT - ED->q[0] = tmp64u; - R_RSP += sizeof(void*); - } - } - break; - case 0x90: /* NOP */ - break; - - case 0x9D: /* POPF */ - return addr-1; // skip 64/65 prefix and resume normal execution - - case 0xA1: /* MOV EAX,FS:Od */ - if(rex.is32bits) { - tmp32s = F32S; - R_EAX = *(uint32_t*)(tlsdata+tmp32s); - } else { - tmp64u = F64; - if(rex.w) - R_RAX = *(uint64_t*)(tlsdata+tmp64u); - else - R_RAX = *(uint32_t*)(tlsdata+tmp64u); - } - break; - case 0xA2: /* MOV Ob,AL */ - if(rex.is32bits) { - tmp32s = F32S; - *(uint8_t*)(uintptr_t)(tlsdata+tmp32s) = R_AL; - } else { - tmp64u = F64; - *(uint8_t*)(tlsdata+tmp64u) = R_AL; - } - break; - case 0xA3: /* MOV FS:Od,EAX */ - if(rex.is32bits) { - tmp32s = F32S; - *(uint32_t*)(uintptr_t)(tlsdata+tmp32s) = R_EAX; - } else { - tmp64u = F64; - if(rex.w) - *(uint64_t*)(tlsdata+tmp64u) = R_RAX; - else - *(uint32_t*)(tlsdata+tmp64u) = R_EAX; - } - break; - case 0xC4: /* LES Gd,Ed */ - nextop = F8; - if(rex.is32bits && !(MODREG)) { - GETED(0); - GETGD; - emu->segs[_ES] = *(uint16_t*)(((char*)ED) + 4); - emu->segs_serial[_ES] = 0; - GD->dword[0] = *(uint32_t*)ED; - } else { - vex_t vex = {0}; - vex.rex = rex; - tmp8u = nextop; - vex.m = tmp8u&0b00011111; - vex.rex.b = (tmp8u&0b00100000)?0:1; - vex.rex.x = (tmp8u&0b01000000)?0:1; - vex.rex.r = (tmp8u&0b10000000)?0:1; - tmp8u = F8; - vex.p = tmp8u&0b00000011; - vex.l = (tmp8u>>2)&1; - vex.v = ((~tmp8u)>>3)&0b1111; - vex.rex.w = (tmp8u>>7)&1; - #ifdef TEST_INTERPRETER - addr = Test64AVX(test, vex, addr, tlsdata); - #else - addr = Run64AVX(emu, vex, addr, tlsdata); - #endif - } - break; - case 0xC5: /* LDS Gd,Ed */ - nextop = F8; - if(rex.is32bits && !(MODREG)) { - GETED(0); - GETGD; - emu->segs[_DS] = *(uint16_t*)(((char*)ED) + 4); - emu->segs_serial[_DS] = 0; - GD->dword[0] = *(uint32_t*)ED; - } else { - vex_t vex = {0}; - vex.rex = rex; - tmp8u = nextop; - vex.p = tmp8u&0b00000011; - vex.l = (tmp8u>>2)&1; - vex.v = ((~tmp8u)>>3)&0b1111; - vex.rex.r = (tmp8u&0b10000000)?0:1; - vex.rex.b = 0; - vex.rex.x = 0; - vex.rex.w = 0; - vex.m = VEX_M_0F; - #ifdef TEST_INTERPRETER - addr = Test64AVX(test, vex, addr, tlsdata); - #else - addr = Run64AVX(emu, vex, addr, tlsdata); - #endif - } - break; - case 0xC6: /* MOV FS:Eb, Ib */ - nextop = F8; - GETEB_OFFS(1, tlsdata); - EB->byte[0] = F8; - break; - case 0xC7: /* MOV FS:Ed, Id */ - nextop = F8; - GETED_OFFS(4, tlsdata); - if(rex.w) - ED->q[0] = F32S64; - else - if(MODREG) - ED->q[0] = F32; - else - ED->dword[0] = F32; - break; - - case 0xD1: /* GRP2 Ed,1 */ - case 0xD3: /* GRP2 Ed,CL */ - nextop = F8; - GETED_OFFS(0, tlsdata); - tmp8u = (opcode==0xD1)?1:R_CL; - if(rex.w) { - switch((nextop>>3)&7) { - case 0: ED->q[0] = rol64(emu, ED->q[0], tmp8u); break; - case 1: ED->q[0] = ror64(emu, ED->q[0], tmp8u); break; - case 2: ED->q[0] = rcl64(emu, ED->q[0], tmp8u); break; - case 3: ED->q[0] = rcr64(emu, ED->q[0], tmp8u); break; - case 4: - case 6: ED->q[0] = shl64(emu, ED->q[0], tmp8u); break; - case 5: ED->q[0] = shr64(emu, ED->q[0], tmp8u); break; - case 7: ED->q[0] = sar64(emu, ED->q[0], tmp8u); break; - } - } else { - if(MODREG) - switch((nextop>>3)&7) { - case 0: ED->q[0] = rol32(emu, ED->dword[0], tmp8u); break; - case 1: ED->q[0] = ror32(emu, ED->dword[0], tmp8u); break; - case 2: ED->q[0] = rcl32(emu, ED->dword[0], tmp8u); break; - case 3: ED->q[0] = rcr32(emu, ED->dword[0], tmp8u); break; - case 4: - case 6: ED->q[0] = shl32(emu, ED->dword[0], tmp8u); break; - case 5: ED->q[0] = shr32(emu, ED->dword[0], tmp8u); break; - case 7: ED->q[0] = sar32(emu, ED->dword[0], tmp8u); break; - } - else - switch((nextop>>3)&7) { - case 0: ED->dword[0] = rol32(emu, ED->dword[0], tmp8u); break; - case 1: ED->dword[0] = ror32(emu, ED->dword[0], tmp8u); break; - case 2: ED->dword[0] = rcl32(emu, ED->dword[0], tmp8u); break; - case 3: ED->dword[0] = rcr32(emu, ED->dword[0], tmp8u); break; - case 4: - case 6: ED->dword[0] = shl32(emu, ED->dword[0], tmp8u); break; - case 5: ED->dword[0] = shr32(emu, ED->dword[0], tmp8u); break; - case 7: ED->dword[0] = sar32(emu, ED->dword[0], tmp8u); break; - } - } - break; - - case 0xD8: /* x87 opcodes */ - #ifdef TEST_INTERPRETER - return TestD8(test, rex, addr, tlsdata); - #else - return RunD8(emu, rex, addr, tlsdata); - #endif - break; - case 0xD9: /* x87 opcodes */ - #ifdef TEST_INTERPRETER - return TestD9(test, rex, addr, tlsdata); - #else - return RunD9(emu, rex, addr, tlsdata); - #endif - break; - - case 0xEB: /* JMP Ib */ - return addr-1; // skip 64/65 prefix and resume normal execution - - case 0xF6: /* GRP3 Eb(,Ib) */ - nextop = F8; - tmp8u = (nextop>>3)&7; - GETEB_OFFS((tmp8u<2)?1:0, tlsdata); - switch(tmp8u) { - case 0: - case 1: /* TEST Eb,Ib */ - tmp8u = F8; - test8(emu, EB->byte[0], tmp8u); - break; - case 2: /* NOT Eb */ - EB->byte[0] = not8(emu, EB->byte[0]); - break; - case 3: /* NEG Eb */ - EB->byte[0] = neg8(emu, EB->byte[0]); - break; - case 4: /* MUL AL,Eb */ - mul8(emu, EB->byte[0]); - break; - case 5: /* IMUL AL,Eb */ - imul8(emu, EB->byte[0]); - break; - case 6: /* DIV Eb */ - if(!EB->byte[0]) - EmitDiv0(emu, (void*)R_RIP, 1); - div8(emu, EB->byte[0]); - break; - case 7: /* IDIV Eb */ - if(!EB->byte[0]) - EmitDiv0(emu, (void*)R_RIP, 1); - idiv8(emu, EB->byte[0]); - break; - } - break; - case 0xF7: /* GRP3 Ed(,Id) */ - nextop = F8; - tmp8u = (nextop>>3)&7; - GETED_OFFS((tmp8u<2)?4:0, tlsdata); - if(rex.w) { - switch(tmp8u) { - case 0: - case 1: /* TEST Ed,Id */ - tmp64u = F32S64; - test64(emu, ED->q[0], tmp64u); - break; - case 2: /* NOT Ed */ - ED->q[0] = not64(emu, ED->q[0]); - break; - case 3: /* NEG Ed */ - ED->q[0] = neg64(emu, ED->q[0]); - break; - case 4: /* MUL RAX,Ed */ - mul64_rax(emu, ED->q[0]); - break; - case 5: /* IMUL RAX,Ed */ - imul64_rax(emu, ED->q[0]); - break; - case 6: /* DIV Ed */ - div64(emu, ED->q[0]); - break; - case 7: /* IDIV Ed */ - idiv64(emu, ED->q[0]); - break; - } - } else { - switch(tmp8u) { - case 0: - case 1: /* TEST Ed,Id */ - tmp32u = F32; - test32(emu, ED->dword[0], tmp32u); - break; - case 2: /* NOT Ed */ - if(MODREG) - ED->q[0] = not32(emu, ED->dword[0]); - else - ED->dword[0] = not32(emu, ED->dword[0]); - break; - case 3: /* NEG Ed */ - if(MODREG) - ED->q[0] = neg32(emu, ED->dword[0]); - else - ED->dword[0] = neg32(emu, ED->dword[0]); - break; - case 4: /* MUL EAX,Ed */ - mul32_eax(emu, ED->dword[0]); - emu->regs[_AX].dword[1] = 0; - break; - case 5: /* IMUL EAX,Ed */ - imul32_eax(emu, ED->dword[0]); - emu->regs[_AX].dword[1] = 0; - break; - case 6: /* DIV Ed */ - div32(emu, ED->dword[0]); - //emu->regs[_AX].dword[1] = 0; // already put high regs to 0 - //emu->regs[_DX].dword[1] = 0; - break; - case 7: /* IDIV Ed */ - idiv32(emu, ED->dword[0]); - //emu->regs[_AX].dword[1] = 0; - //emu->regs[_DX].dword[1] = 0; - break; - } - } - break; - - case 0xFF: /* GRP 5 Ed */ - nextop = F8; - GETED_OFFS(0, tlsdata); - switch((nextop>>3)&7) { - case 0: /* INC Ed */ - if(rex.w) - ED->q[0] = inc64(emu, ED->q[0]); - else { - if(MODREG) - ED->q[0] = inc32(emu, ED->dword[0]); - else - ED->dword[0] = inc32(emu, ED->dword[0]); - } - break; - case 1: /* DEC Ed */ - if(rex.w) - ED->q[0] = dec64(emu, ED->q[0]); - else { - if(MODREG) - ED->q[0] = dec32(emu, ED->dword[0]); - else - ED->dword[0] = dec32(emu, ED->dword[0]); - } - break; - case 2: /* CALL NEAR Ed */ - if(rex.is32bits) { - tmp64u = (uintptr_t)getAlternate((void*)(uintptr_t)ED->dword[0]); - Push32(emu, addr); - } else { - tmp64u = (uintptr_t)getAlternate((void*)ED->q[0]); - Push64(emu, addr); - } - addr = tmp64u; - break; - case 3: /* CALL FAR Ed */ - if(MODREG) { - 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 { - if(rex.is32bits || !rex.w) { - Push32(emu, R_CS); - Push32(emu, addr); - R_RIP = addr = ED->dword[0]; - R_CS = ED->word[2]; - } else { - Push64(emu, R_CS); - Push64(emu, addr); - R_RIP = addr = ED->q[0]; - R_CS = (ED+1)->word[0]; - } - return 0; // exit loop to recompute new CS... - } - break; - case 4: /* JMP NEAR Ed */ - if(rex.is32bits) - addr = (uintptr_t)getAlternate((void*)(uintptr_t)ED->dword[0]); - else - addr = (uintptr_t)getAlternate((void*)ED->q[0]); - break; - case 5: /* JMP FAR Ed */ - if(MODREG) { - 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 { - if(rex.is32bits || !rex.w) { - R_RIP = addr = ED->dword[0]; - R_CS = ED->word[2]; - } else { - R_RIP = addr = ED->q[0]; - R_CS = (ED+1)->word[0]; - } - } - break; - case 6: /* Push Ed */ - if(rex.is32bits) { - tmp32u = ED->dword[0]; - Push32(emu, tmp32u); // avoid potential issue with push [esp+...] - } else { - tmp64u = ED->q[0]; // rex.w ignored - Push64(emu, tmp64u); // avoid potential issue with push [esp+...] - } - break; - default: - 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; - return 0; - } - break; - default: - return 0; - } - return addr; -} diff --git a/src/emu/x64run64avx.c b/src/emu/x64run64avx.c deleted file mode 100644 index 57b753d5..00000000 --- a/src/emu/x64run64avx.c +++ /dev/null @@ -1,141 +0,0 @@ -#define _GNU_SOURCE -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include <fenv.h> -#include <string.h> -#include <signal.h> -#include <sys/types.h> -#include <unistd.h> - -#include "debug.h" -#include "box64stack.h" -#include "x64emu.h" -#include "x64emu_private.h" -#include "x64run_private.h" -#include "x64primop.h" -#include "x64trace.h" -#include "x87emu_private.h" -#include "box64context.h" -#include "my_cpuid.h" -#include "bridge.h" -#include "x64shaext.h" -#ifdef DYNAREC -#include "custommem.h" -#include "../dynarec/native_lock.h" -#endif - -#include "modrm.h" - -static const char* avx_prefix_string(uint16_t p) -{ - switch(p) { - case VEX_P_NONE: return "0"; - case VEX_P_66: return "66"; - case VEX_P_F2: return "F2"; - case VEX_P_F3: return "F3"; - default: return "??"; - } -} -static const char* avx_map_string(uint16_t m) -{ - switch(m) { - case VEX_M_NONE: return "0"; - case VEX_M_0F: return "0F"; - case VEX_M_0F38: return "0F38"; - case VEX_M_0F3A: return "0F3A"; - default: return "??"; - } -} - -#ifdef TEST_INTERPRETER -uintptr_t Test64AVX(x64test_t *test, vex_t vex, uintptr_t addr, uintptr_t tlsdata) -#else -uintptr_t Run64AVX(x64emu_t *emu, vex_t vex, uintptr_t addr, uintptr_t tlsdata) -#endif -{ - uint8_t opcode; - uint8_t nextop; - uint8_t tmp8u; - int8_t tmp8s; - int32_t tmp32s, tmp32s2; - uint32_t tmp32u, tmp32u2; - uint64_t tmp64u, tmp64u2; - int64_t tmp64s; - reg64_t *oped, *opgd; - sse_regs_t *opex, *opgx, *opvx, eax1; - sse_regs_t *opey, *opgy, *opvy, eay1; - -#ifdef TEST_INTERPRETER - x64emu_t *emu = test->emu; -#endif - - opcode = PK(0); - if( (vex.m==VEX_M_0F) && (vex.p==VEX_P_NONE)) { - opcode = F8; - rex_t rex = vex.rex; - switch(opcode) { - - case 0x10: /* VMOVUPS Gx, Ex */ - nextop = F8; - GETEX_OFFS(0, tlsdata); - GETGX; - GETGY; - GX->q[0] = EX->q[0]; - GX->q[1] = EX->q[1]; - if(vex.l) { - GETEY; - GY->q[0] = EY->q[0]; - GY->q[1] = EY->q[1]; - } else { - GY->u128 = 0; - } - break; - case 0x11: /* VMOVUPS Ex, Gx */ - nextop = F8; - GETEX_OFFS(0, tlsdata); - GETGX; - EX->q[0] = GX->q[0]; - EX->q[1] = GX->q[1]; - if(vex.l) { - GETEY; - GETGY; - EY->q[0] = GY->q[0]; - EY->q[1] = GY->q[1]; - } else if(MODREG) { - GETEY; - EY->u128 = 0; - } - break; - default: - addr = 0; - } - } - /*else if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_NONE)) - addr = RunAVX_0F38(emu, vex, addr, step); - else if( (vex.m==VEX_M_0F) && (vex.p==VEX_P_66)) - addr = RunAVX_660F(emu, vex, addr, step); - else if( (vex.m==VEX_M_0F) && (vex.p==VEX_P_F2)) - addr = RunAVX_F20F(emu, vex, addr, step); - else if( (vex.m==VEX_M_0F) && (vex.p==VEX_P_F3)) - addr = RunAVX_F30F(emu, vex, addr, step); - else if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_66)) - addr = RunAVX_660F38(emu, vex, addr, step); - else if( (vex.m==VEX_M_0F3A) && (vex.p==VEX_P_66)) - addr = RunAVX_660F3A(emu, vex, addr, step); - else if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_F2)) - addr = RunAVX_F20F38(emu, vex, addr, step); - else if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_F3)) - addr = RunAVX_F30F38(emu, vex, addr, step); - else if( (vex.m==VEX_M_0F3A) && (vex.p==VEX_P_F2)) - addr = RunAVX_F20F3A(emu, vex, addr, step); - else if( (vex.m==VEX_M_0F3A) && (vex.p==VEX_P_F3)) - addr = RunAVX_F30F3A(emu, vex, addr, step);*/ - else addr = 0; - - if(!addr) - printf_log(LOG_INFO, "Unimplemented 64/65 AVX opcode size %d prefix %s map %s opcode %02X ", 128<<vex.l, avx_prefix_string(vex.p), avx_map_string(vex.m), opcode); - - return addr; -} diff --git a/src/emu/x64run66.c b/src/emu/x64run66.c index b196758f..15d0bebc 100644 --- a/src/emu/x64run66.c +++ b/src/emu/x64run66.c @@ -26,9 +26,9 @@ #include "modrm.h" #ifdef TEST_INTERPRETER -uintptr_t Test66(x64test_t *test, rex_t rex, int rep, uintptr_t addr) +uintptr_t Test66(x64test_t *test, rex_t rex, uintptr_t addr) #else -uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr) +uintptr_t Run66(x64emu_t *emu, rex_t rex, uintptr_t addr) #endif { uint8_t opcode; @@ -47,21 +47,6 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr) opcode = F8; - while((opcode==0x2E) || (opcode==0x36) || (opcode==0x26) || (opcode==0x66)) // ignoring CS:, SS:, ES: or multiple 0x66 - opcode = F8; - - while((opcode==0xF2) || (opcode==0xF3)) { - rep = opcode-0xF1; - opcode = F8; - } - - rex.rex = 0; - if(!rex.is32bits) - while(opcode>=0x40 && opcode<=0x4f) { - rex.rex = opcode; - opcode = F8; - } - switch(opcode) { #define GO(B, OP) \ case B+0: \ @@ -127,7 +112,7 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr) break; case 0x0F: /* more opcdes */ - switch(rep) { + switch(rex.rep) { case 0: #ifdef TEST_INTERPRETER return Test660F(test, rex, addr); @@ -262,19 +247,6 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr) } break; - case 0x64: /* FS: */ - #ifdef TEST_INTERPRETER - return Test6664(test, rex, _FS, addr); - #else - return Run6664(emu, rex, _FS, addr); - #endif - case 0x65: /* GS: */ - #ifdef TEST_INTERPRETER - return Test6664(test, rex, _GS, addr); - #else - return Run6664(emu, rex, _GS, addr); - #endif - case 0x68: /* PUSH u16 */ tmp16u = F16; Push16(emu, tmp16u); @@ -461,28 +433,28 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr) case 0xA1: /* MOV EAX,Od */ if(rex.is32bits) { - R_AX = *(uint16_t*)(uintptr_t)F32; + R_AX = *(uint16_t*)(uintptr_t)(ptr_t)(F32+rex.offset); } else { if(rex.w) - R_RAX = *(uint64_t*)F64; + R_RAX = *(uint64_t*)(F64+rex.offset); else - R_AX = *(uint16_t*)F64; + R_AX = *(uint16_t*)(F64+rex.offset); } break; case 0xA3: /* MOV Od,EAX */ if(rex.is32bits) { - *(uint16_t*)(uintptr_t)F32 = R_AX; + *(uint16_t*)(uintptr_t)(ptr_t)(F32+rex.offset) = R_AX; } else { if(rex.w) - *(uint64_t*)F64 = R_RAX; + *(uint64_t*)(F64+rex.offset) = R_RAX; else - *(uint16_t*)F64 = R_AX; + *(uint16_t*)(F64+rex.offset) = R_AX; } break; case 0xA4: /* (REP) MOVSB */ tmp8s = ACCESS_FLAG(F_DF)?-1:+1; - tmp64u = (rep)?R_RCX:1L; + tmp64u = (rex.rep)?R_RCX:1L; while(tmp64u) { #ifndef TEST_INTERPRETER *(uint8_t*)R_RDI = *(uint8_t*)R_RSI; @@ -491,12 +463,12 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr) R_RSI += tmp8s; --tmp64u; } - if(rep) + if(rex.rep) R_RCX = tmp64u; break; case 0xA5: /* (REP) MOVSW */ tmp8s = ACCESS_FLAG(F_DF)?-1:+1; - tmp64u = (rep)?R_RCX:1L; + tmp64u = (rex.rep)?R_RCX:1L; if(rex.w) { tmp8s *= 8; while(tmp64u) { @@ -514,7 +486,7 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr) R_RSI += tmp8s; } } - if(rep) + if(rex.rep) R_RCX = tmp64u; break; @@ -523,7 +495,7 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr) tmp8s = ACCESS_FLAG(F_DF)?-8:+8; else tmp8s = ACCESS_FLAG(F_DF)?-2:+2; - switch(rep) { + switch(rex.rep) { case 1: if(R_RCX) { if(rex.w) { @@ -607,7 +579,7 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr) tmp8s = ACCESS_FLAG(F_DF)?-8:+8; else tmp8s = ACCESS_FLAG(F_DF)?-2:+2; - tmp64u = (rep)?R_RCX:1L; + tmp64u = (rex.rep)?R_RCX:1L; if((rex.w)) while(tmp64u) { #ifndef TEST_INTERPRETER @@ -624,7 +596,7 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr) R_RDI += tmp8s; --tmp64u; } - if(rep) + if(rex.rep) R_RCX = tmp64u; break; case 0xAD: /* (REP) LODSW */ @@ -632,7 +604,7 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr) tmp8s = ACCESS_FLAG(F_DF)?-8:+8; else tmp8s = ACCESS_FLAG(F_DF)?-2:+2; - tmp64u = (rep)?R_RCX:1L; + tmp64u = (rex.rep)?R_RCX:1L; if((rex.w)) while(tmp64u) { R_RAX = *(uint64_t*)R_RSI; @@ -645,7 +617,7 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr) R_RSI += tmp8s; --tmp64u; } - if(rep) + if(rex.rep) R_RCX = tmp64u; break; @@ -654,7 +626,7 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr) tmp8s = ACCESS_FLAG(F_DF)?-8:+8; else tmp8s = ACCESS_FLAG(F_DF)?-2:+2; - switch(rep) { + switch(rex.rep) { case 1: if(R_RCX) { if(rex.w) { diff --git a/src/emu/x64run67.c b/src/emu/x64run67.c deleted file mode 100644 index f6300aba..00000000 --- a/src/emu/x64run67.c +++ /dev/null @@ -1,602 +0,0 @@ -#define _GNU_SOURCE -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include <string.h> -#include <signal.h> -#include <sys/types.h> -#include <unistd.h> - -#include "debug.h" -#include "box64stack.h" -#include "box64cpu_util.h" -#include "x64emu.h" -#include "x64emu_private.h" -#include "x64run_private.h" -#include "x64primop.h" -#include "x64trace.h" -#include "x87emu_private.h" -#include "box64context.h" -#include "alternate.h" - -#include "modrm.h" - -#ifdef TEST_INTERPRETER -uintptr_t Test67(x64test_t *test, rex_t rex, int rep, uintptr_t addr) -#else -uintptr_t Run67(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr) -#endif -{ - uint8_t opcode; - uint8_t nextop; - int8_t tmp8s; - uint8_t tmp8u; - uint32_t tmp32u; - int32_t tmp32s; - uint64_t tmp64u; - reg64_t *oped, *opgd; - #ifdef TEST_INTERPRETER - x64emu_t* emu = test->emu; - #endif - if(rex.is32bits) - #ifdef TEST_INTERPRETER - return Test67_32(test, rex, rep, addr); - #else - return Run67_32(emu, rex, rep, addr); - #endif - - opcode = F8; - - while(opcode==0x67) - opcode = F8; - - // REX prefix before the 67 are ignored - rex.rex = 0; - while(opcode>=0x40 && opcode<=0x4f) { - rex.rex = opcode; - opcode = F8; - } - while((opcode==0xF2) || (opcode==0xF3)) { - rep = opcode-0xF1; - opcode = F8; - } - - switch(opcode) { - #define GO(B, OP) \ - case B+0: \ - nextop = F8; \ - GETEB32(0); \ - GETGB; \ - EB->byte[0] = OP##8(emu, EB->byte[0], GB); \ - break; \ - case B+1: \ - nextop = F8; \ - GETED32(0); \ - GETGD; \ - if(rex.w) \ - ED->q[0] = OP##64(emu, ED->q[0], GD->q[0]); \ - else { \ - if(MODREG) \ - ED->q[0] = OP##32(emu, ED->dword[0], GD->dword[0]); \ - else \ - ED->dword[0] = OP##32(emu, ED->dword[0], GD->dword[0]); \ - } \ - break; \ - case B+2: \ - nextop = F8; \ - GETEB32(0); \ - GETGB; \ - GB = OP##8(emu, GB, EB->byte[0]); \ - break; \ - case B+3: \ - nextop = F8; \ - GETED32(0); \ - GETGD; \ - if(rex.w) \ - GD->q[0] = OP##64(emu, GD->q[0], ED->q[0]); \ - else \ - GD->q[0] = OP##32(emu, GD->dword[0], ED->dword[0]); \ - break; \ - case B+4: \ - R_AL = OP##8(emu, R_AL, F8); \ - break; \ - case B+5: \ - if(rex.w) \ - R_RAX = OP##64(emu, R_RAX, F32S64); \ - else \ - R_RAX = OP##32(emu, R_EAX, F32); \ - break; - - GO(0x00, add) /* ADD 0x00 -> 0x05 */ - GO(0x08, or) /* OR 0x08 -> 0x0D */ - case 0x0F: - #ifdef TEST_INTERPRETER - return Test670F(test, rex, rep, addr); - #else - return Run670F(emu, rex, rep, addr); - #endif - GO(0x10, adc) /* ADC 0x10 -> 0x15 */ - GO(0x18, sbb) /* SBB 0x18 -> 0x1D */ - GO(0x20, and) /* AND 0x20 -> 0x25 */ - GO(0x28, sub) /* SUB 0x28 -> 0x2D */ - GO(0x30, xor) /* XOR 0x30 -> 0x35 */ - #undef GO - case 0x38: - nextop = F8; - GETEB32(0); - GETGB; - cmp8(emu, EB->byte[0], GB); - break; - case 0x39: - nextop = F8; - GETED32(0); - GETGD; - if(rex.w) - cmp64(emu, ED->q[0], GD->q[0]); - else - cmp32(emu, ED->dword[0], GD->dword[0]); - break; - case 0x3A: - nextop = F8; - GETEB32(0); - GETGB; - cmp8(emu, GB, EB->byte[0]); - break; - case 0x3B: - nextop = F8; - GETED32(0); - GETGD; - if(rex.w) - cmp64(emu, GD->q[0], ED->q[0]); - else - cmp32(emu, GD->dword[0], ED->dword[0]); - break; - case 0x3C: - R_AL = cmp8(emu, R_AL, F8); - break; - case 0x3D: - if(rex.w) - cmp64(emu, R_RAX, F32S64); - else - cmp32(emu, R_EAX, F32); - break; - - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x55: - case 0x56: - case 0x57: /* PUSH Reg */ - tmp8u = (opcode&7)+(rex.b<<3); - if(rex.is32bits) - Push32(emu, emu->regs[tmp8u].dword[0]); - else - Push64(emu, emu->regs[tmp8u].q[0]); - break; - case 0x58: - case 0x59: - case 0x5A: - case 0x5B: - case 0x5C: /* POP ESP */ - case 0x5D: - case 0x5E: - case 0x5F: /* POP Reg */ - tmp8u = (opcode&7)+(rex.b<<3); - emu->regs[tmp8u].q[0] = rex.is32bits?Pop32(emu):Pop64(emu); - break; - - case 0x63: /* MOVSXD Gd,Ed */ - nextop = F8; - GETED32(0); - GETGD; - if(rex.w) - GD->sq[0] = ED->sdword[0]; - else - if(MODREG) - GD->q[0] = ED->dword[0]; // not really a sign extension - else - GD->sdword[0] = ED->sdword[0]; // meh? - break; - case 0x64: /* FS: prefix */ - #ifdef TEST_INTERPRETER - return Test6764(test, rex, rep, _FS, addr); - #else - return Run6764(emu, rex, rep, _FS, addr); - #endif - break; - case 0x65: /* GS: prefix */ - #ifdef TEST_INTERPRETER - return Test6764(test, rex, rep, _GS, addr); - #else - return Run6764(emu, rex, rep, _GS, addr); - #endif - break; - case 0x66: - #ifdef TEST_INTERPRETER - return Test6766(test, rex, rep, addr); - #else - return Run6766(emu, rex, rep, addr); - #endif - - case 0x70 ... 0x7F: - return addr-1; // skip 67 prefix and resume normal execution - case 0x80: /* GRP Eb,Ib */ - nextop = F8; - GETEB32(1); - tmp8u = F8; - switch((nextop>>3)&7) { - case 0: EB->byte[0] = add8(emu, EB->byte[0], tmp8u); break; - case 1: EB->byte[0] = or8(emu, EB->byte[0], tmp8u); break; - case 2: EB->byte[0] = adc8(emu, EB->byte[0], tmp8u); break; - case 3: EB->byte[0] = sbb8(emu, EB->byte[0], tmp8u); break; - case 4: EB->byte[0] = and8(emu, EB->byte[0], tmp8u); break; - case 5: EB->byte[0] = sub8(emu, EB->byte[0], tmp8u); break; - case 6: EB->byte[0] = xor8(emu, EB->byte[0], tmp8u); break; - case 7: cmp8(emu, EB->byte[0], tmp8u); break; - } - break; - case 0x81: /* GRP Ed,Id */ - case 0x83: /* GRP Ed,Ib */ - nextop = F8; - GETED32((opcode==0x81)?4:1); - if(opcode==0x81) { - tmp32s = F32S; - } else { - tmp32s = F8S; - } - if(rex.w) { - tmp64u = (uint64_t)(int64_t)tmp32s; - switch((nextop>>3)&7) { - case 0: ED->q[0] = add64(emu, ED->q[0], tmp64u); break; - case 1: ED->q[0] = or64(emu, ED->q[0], tmp64u); break; - case 2: ED->q[0] = adc64(emu, ED->q[0], tmp64u); break; - case 3: ED->q[0] = sbb64(emu, ED->q[0], tmp64u); break; - case 4: ED->q[0] = and64(emu, ED->q[0], tmp64u); break; - case 5: ED->q[0] = sub64(emu, ED->q[0], tmp64u); break; - case 6: ED->q[0] = xor64(emu, ED->q[0], tmp64u); break; - case 7: cmp64(emu, ED->q[0], tmp64u); break; - } - } else { - tmp32u = (uint32_t)tmp32s; - if(MODREG) - switch((nextop>>3)&7) { - case 0: ED->q[0] = add32(emu, ED->dword[0], tmp32u); break; - case 1: ED->q[0] = or32(emu, ED->dword[0], tmp32u); break; - case 2: ED->q[0] = adc32(emu, ED->dword[0], tmp32u); break; - case 3: ED->q[0] = sbb32(emu, ED->dword[0], tmp32u); break; - case 4: ED->q[0] = and32(emu, ED->dword[0], tmp32u); break; - case 5: ED->q[0] = sub32(emu, ED->dword[0], tmp32u); break; - case 6: ED->q[0] = xor32(emu, ED->dword[0], tmp32u); break; - case 7: cmp32(emu, ED->dword[0], tmp32u); break; - } - else - switch((nextop>>3)&7) { - case 0: ED->dword[0] = add32(emu, ED->dword[0], tmp32u); break; - case 1: ED->dword[0] = or32(emu, ED->dword[0], tmp32u); break; - case 2: ED->dword[0] = adc32(emu, ED->dword[0], tmp32u); break; - case 3: ED->dword[0] = sbb32(emu, ED->dword[0], tmp32u); break; - case 4: ED->dword[0] = and32(emu, ED->dword[0], tmp32u); break; - case 5: ED->dword[0] = sub32(emu, ED->dword[0], tmp32u); break; - case 6: ED->dword[0] = xor32(emu, ED->dword[0], tmp32u); break; - case 7: cmp32(emu, ED->dword[0], tmp32u); break; - } - } - break; - - case 0x88: /* MOV Eb,Gb */ - nextop = F8; - GETEB32(0); - GETGB; - EB->byte[0] = GB; - break; - case 0x89: /* MOV Ed,Gd */ - nextop = F8; - GETED32(0); - GETGD; - if(rex.w) { - ED->q[0] = GD->q[0]; - } else { - //if ED is a reg, than the opcode works like movzx - if(MODREG) - ED->q[0] = GD->dword[0]; - else - ED->dword[0] = GD->dword[0]; - } - break; - case 0x8A: /* MOV Gb,Eb */ - nextop = F8; - GETEB32(0); - GETGB; - GB = EB->byte[0]; - break; - case 0x8B: /* MOV Gd,Ed */ - nextop = F8; - GETED32(0); - GETGD; - if(rex.w) - GD->q[0] = ED->q[0]; - else - GD->q[0] = ED->dword[0]; - break; - - case 0x8D: /* LEA Gd,M */ - nextop = F8; - _GETED32(0); - GETGD; - if(rex.w) - GD->q[0] = (uint64_t)ED; - else - GD->q[0] = ((uintptr_t)ED)&0xffffffff; - break; - - - case 0x9C: /* PUSHF */ - CHECK_FLAGS(emu); - Push64(emu, emu->eflags.x64); - break; - - case 0xA1: /* MOV EAX,Od */ - if(rex.w) - R_RAX = *(uint64_t*)(uintptr_t)F32; - else - R_RAX = *(uint32_t*)(uintptr_t)F32; - break; - - case 0xC1: /* GRP2 Ed,Ib */ - nextop = F8; - GETED32(1); - tmp8u = F8/* & 0x1f*/; // masking done in each functions - if(rex.w) { - switch((nextop>>3)&7) { - case 0: ED->q[0] = rol64(emu, ED->q[0], tmp8u); break; - case 1: ED->q[0] = ror64(emu, ED->q[0], tmp8u); break; - case 2: ED->q[0] = rcl64(emu, ED->q[0], tmp8u); break; - case 3: ED->q[0] = rcr64(emu, ED->q[0], tmp8u); break; - case 4: - case 6: ED->q[0] = shl64(emu, ED->q[0], tmp8u); break; - case 5: ED->q[0] = shr64(emu, ED->q[0], tmp8u); break; - case 7: ED->q[0] = sar64(emu, ED->q[0], tmp8u); break; - } - } else { - if(MODREG) - switch((nextop>>3)&7) { - case 0: ED->q[0] = rol32(emu, ED->dword[0], tmp8u); break; - case 1: ED->q[0] = ror32(emu, ED->dword[0], tmp8u); break; - case 2: ED->q[0] = rcl32(emu, ED->dword[0], tmp8u); break; - case 3: ED->q[0] = rcr32(emu, ED->dword[0], tmp8u); break; - case 4: - case 6: ED->q[0] = shl32(emu, ED->dword[0], tmp8u); break; - case 5: ED->q[0] = shr32(emu, ED->dword[0], tmp8u); break; - case 7: ED->q[0] = sar32(emu, ED->dword[0], tmp8u); break; - } - else - switch((nextop>>3)&7) { - case 0: ED->dword[0] = rol32(emu, ED->dword[0], tmp8u); break; - case 1: ED->dword[0] = ror32(emu, ED->dword[0], tmp8u); break; - case 2: ED->dword[0] = rcl32(emu, ED->dword[0], tmp8u); break; - case 3: ED->dword[0] = rcr32(emu, ED->dword[0], tmp8u); break; - case 4: - case 6: ED->dword[0] = shl32(emu, ED->dword[0], tmp8u); break; - case 5: ED->dword[0] = shr32(emu, ED->dword[0], tmp8u); break; - case 7: ED->dword[0] = sar32(emu, ED->dword[0], tmp8u); break; - } - } - break; - - case 0xC4: /* LES Gd,Ed */ - nextop = F8; - if(rex.is32bits && !(MODREG)) { - return 0; - } else { - if(rex.is32bits) { - return 0; - } - vex_t vex = {0}; - vex.rex = rex; - tmp8u = nextop; - vex.m = tmp8u&0b00011111; - vex.rex.b = (tmp8u&0b00100000)?0:1; - vex.rex.x = (tmp8u&0b01000000)?0:1; - vex.rex.r = (tmp8u&0b10000000)?0:1; - tmp8u = F8; - vex.p = tmp8u&0b00000011; - vex.l = (tmp8u>>2)&1; - vex.v = ((~tmp8u)>>3)&0b1111; - vex.rex.w = (tmp8u>>7)&1; - #ifdef TEST_INTERPRETER - addr = Test67AVX(test, vex, addr); - #else - addr = Run67AVX(emu, vex, addr); - #endif - } - break; - case 0xC5: /* LDS Gd,Ed */ - nextop = F8; - if(rex.is32bits && !(MODREG)) { - return 0; - } else { - if(rex.is32bits) { - return 0; - } - vex_t vex = {0}; - vex.rex = rex; - tmp8u = nextop; - vex.p = tmp8u&0b00000011; - vex.l = (tmp8u>>2)&1; - vex.v = ((~tmp8u)>>3)&0b1111; - vex.rex.r = (tmp8u&0b10000000)?0:1; - vex.rex.b = 0; - vex.rex.x = 0; - vex.rex.w = 0; - vex.m = VEX_M_0F; - #ifdef TEST_INTERPRETER - addr = Test67AVX(test, vex, addr); - #else - addr = Run67AVX(emu, vex, addr); - #endif - } - break; - case 0xC6: /* MOV Eb,Ib */ - nextop = F8; - GETEB32(1); - EB->byte[0] = F8; - break; - case 0xC7: /* MOV Ed,Id */ - nextop = F8; - GETED32(4); - if(rex.w) - ED->q[0] = F32S64; - else - if(MODREG) - ED->q[0] = F32; - else - ED->dword[0] = F32; - break; - - case 0xE0: /* LOOPNZ */ - CHECK_FLAGS(emu); - tmp8s = F8S; - --R_ECX; // don't update flags - if(R_ECX && !ACCESS_FLAG(F_ZF)) - addr += tmp8s; - break; - case 0xE1: /* LOOPZ */ - CHECK_FLAGS(emu); - tmp8s = F8S; - --R_ECX; // don't update flags - if(R_ECX && ACCESS_FLAG(F_ZF)) - addr += tmp8s; - break; - case 0xE2: /* LOOP */ - tmp8s = F8S; - --R_ECX; // don't update flags - if(R_ECX) - addr += tmp8s; - break; - case 0xE3: /* JECXZ Ib */ - tmp8s = F8S; - if(!R_ECX) - addr += tmp8s; - break; - - case 0xE8: /* CALL Id */ - tmp32s = F32S; // call is relative - Push64(emu, addr); - addr += tmp32s; - break; - - case 0xF7: /* GRP3 Ed(,Id) */ - nextop = F8; - tmp8u = (nextop>>3)&7; - GETED32((tmp8u<2)?4:0); - if(rex.w) { - switch(tmp8u) { - case 0: - case 1: /* TEST Ed,Id */ - tmp64u = F32S64; - test64(emu, ED->q[0], tmp64u); - break; - case 2: /* NOT Ed */ - ED->q[0] = not64(emu, ED->q[0]); - break; - case 3: /* NEG Ed */ - ED->q[0] = neg64(emu, ED->q[0]); - break; - case 4: /* MUL RAX,Ed */ - mul64_rax(emu, ED->q[0]); - break; - case 5: /* IMUL RAX,Ed */ - imul64_rax(emu, ED->q[0]); - break; - case 6: /* DIV Ed */ - div64(emu, ED->q[0]); - break; - case 7: /* IDIV Ed */ - idiv64(emu, ED->q[0]); - break; - } - } else { - switch(tmp8u) { - case 0: - case 1: /* TEST Ed,Id */ - tmp32u = F32; - test32(emu, ED->dword[0], tmp32u); - break; - case 2: /* NOT Ed */ - if(MODREG) - ED->q[0] = not32(emu, ED->dword[0]); - else - ED->dword[0] = not32(emu, ED->dword[0]); - break; - case 3: /* NEG Ed */ - if(MODREG) - ED->q[0] = neg32(emu, ED->dword[0]); - else - ED->dword[0] = neg32(emu, ED->dword[0]); - break; - case 4: /* MUL EAX,Ed */ - mul32_eax(emu, ED->dword[0]); - emu->regs[_AX].dword[1] = 0; - emu->regs[_DX].dword[1] = 0; - break; - case 5: /* IMUL EAX,Ed */ - imul32_eax(emu, ED->dword[0]); - emu->regs[_AX].dword[1] = 0; - emu->regs[_DX].dword[1] = 0; - break; - case 6: /* DIV Ed */ - div32(emu, ED->dword[0]); - //emu->regs[_AX].dword[1] = 0; - //emu->regs[_DX].dword[1] = 0; - break; - case 7: /* IDIV Ed */ - idiv32(emu, ED->dword[0]); - //emu->regs[_AX].dword[1] = 0; - //emu->regs[_DX].dword[1] = 0; - break; - } - } - break; - - case 0xFF: - nextop = F8; - switch((nextop>>3)&7) { - case 0: /* INC Ed */ - GETED32(0); - if(rex.w) - ED->q[0] = inc64(emu, ED->q[0]); - else { - if(MODREG) - ED->q[0] = inc32(emu, ED->dword[0]); - else - ED->dword[0] = inc32(emu, ED->dword[0]); - } - break; - case 1: /* DEC Ed */ - GETED32(0); - if(rex.w) - ED->q[0] = dec64(emu, ED->q[0]); - else { - if(MODREG) - ED->q[0] = dec32(emu, ED->dword[0]); - else - ED->dword[0] = dec32(emu, ED->dword[0]); - } - break; - case 2: /* CALL NEAR Ed */ - GETED32(0); - tmp64u = (uintptr_t)getAlternate((void*)ED->q[0]); - Push64(emu, addr); - addr = tmp64u; - break; - default: - return 0; - } - break; - default: - return 0; - } - return addr; -} diff --git a/src/emu/x64run670f.c b/src/emu/x64run670f.c deleted file mode 100644 index 54fe8808..00000000 --- a/src/emu/x64run670f.c +++ /dev/null @@ -1,211 +0,0 @@ -#define _GNU_SOURCE -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include <string.h> -#include <sys/types.h> -#include <unistd.h> - -#include "x64_signals.h" -#include "os.h" -#include "debug.h" -#include "box64stack.h" -#include "x64emu.h" -#include "x64emu_private.h" -#include "x64run_private.h" -#include "x64primop.h" -#include "x64trace.h" -#include "x87emu_private.h" -#include "box64context.h" -#include "bridge.h" -#include "emit_signals.h" -#ifdef DYNAREC -#include "../dynarec/native_lock.h" -#endif - -#include "modrm.h" -#include "x64compstrings.h" - -#ifdef TEST_INTERPRETER -uintptr_t Test670F(x64test_t *test, rex_t rex, int rep, uintptr_t addr) -#else -uintptr_t Run670F(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr) -#endif -{ - (void)rep; - uint8_t opcode; - uint8_t nextop; - uint8_t tmp8u; (void)tmp8u; - int8_t tmp8s; (void)tmp8s; - int32_t tmp32s, tmp32s2; (void)tmp32s; (void)tmp32s2; - uint32_t tmp32u, tmp32u2; (void)tmp32u; (void)tmp32u2; - uint64_t tmp64u, tmp64u2; (void)tmp64u; (void)tmp64u2; - reg64_t *oped, *opgd; (void)oped; (void)opgd; - sse_regs_t *opex, *opgx, eax1; (void)eax1; - mmx87_regs_t *opem, *opgm, eam1; (void)opem; (void)opgm; (void)eam1; - - #ifdef TEST_INTERPRETER - x64emu_t* emu = test->emu; - #endif - opcode = F8; - - switch(opcode) { - - case 0x11: - switch(rep) { - case 0: /* MOVUPS Ex,Gx */ - nextop = F8; - GETEX32(0); - GETGX; - EX->u128 = GX->u128; - break; - default: - return 0; - } - break; - - case 0x29: /* MOVAPS Ex,Gx */ - nextop = F8; - GETEX32(0); - GETGX; - EX->q[0] = GX->q[0]; - EX->q[1] = GX->q[1]; - break; - - case 0x2E: - // same for now - case 0x2F: - switch(rep) { - case 0: /* (U)COMISS Gx, Ex */ - RESET_FLAGS(emu); - nextop = F8; - GETEX32(0); - GETGX; - if(isnan(GX->f[0]) || isnan(EX->f[0])) { - SET_FLAG(F_ZF); SET_FLAG(F_PF); SET_FLAG(F_CF); - } else if(isgreater(GX->f[0], EX->f[0])) { - CLEAR_FLAG(F_ZF); CLEAR_FLAG(F_PF); CLEAR_FLAG(F_CF); - } else if(isless(GX->f[0], EX->f[0])) { - CLEAR_FLAG(F_ZF); CLEAR_FLAG(F_PF); SET_FLAG(F_CF); - } else { - SET_FLAG(F_ZF); CLEAR_FLAG(F_PF); CLEAR_FLAG(F_CF); - } - CLEAR_FLAG(F_OF); CLEAR_FLAG(F_AF); CLEAR_FLAG(F_SF); - break; - default: - return 0; - } - break; - - case 0x38: /* MAP 0F38 */ - opcode = F8; - switch(opcode) { - - case 0xF6: - switch(rep) { - case 2: - /* ADOX Gd, Rd */ - nextop = F8; - GETED32(0); - GETGD; - CHECK_FLAGS(emu); - if(rex.w) { - if (ACCESS_FLAG(F_OF)) { - tmp64u = 1 + (GD->q[0] & 0xFFFFFFFF) + (ED->q[0] & 0xFFFFFFFF); - tmp64u2 = 1 + GD->q[0] + ED->q[0]; - } - else { - tmp64u = (GD->q[0] & 0xFFFFFFFF) + (ED->q[0] & 0xFFFFFFFF); - tmp64u2 = GD->q[0] + ED->q[0]; - } - tmp64u = (tmp64u >> 32) + (GD->q[0] >> 32) + (ED->q[0] >> 32); - CONDITIONAL_SET_FLAG(tmp64u & 0x100000000L, F_OF); - GD->q[0] = tmp64u2; - } else { - if (ACCESS_FLAG(F_OF)) - GD->q[0] = 1LL + GD->dword[0] + ED->dword[0]; - else - GD->q[0] = (uint64_t)GD->dword[0] + ED->dword[0]; - CONDITIONAL_SET_FLAG(GD->q[0] & 0x100000000LL, F_OF); - } - break; - default: - return 0; - } - default: - return 0; - } - break; - - case 0x6F: - switch(rep) { - case 0: /* MOVQ Gm, Em */ - nextop = F8; - GETEM32(0); - GETGM; - GM->q = EM->q; - break; - case 2: /* MOVDQU Gx, Ex */ - nextop = F8; - GETEX32(0); - GETGX; - memcpy(GX, EX, 16); // unaligned... - break; - default: - return 0; - } - break; - - case 0x7F: - switch(rep) { - case 0: /* MOVQ Em, Gm */ - nextop = F8; - GETEM32(0); - GETGM; - EM->q = GM->q; - break; - case 2: /* MOVDQU Ex, Gx */ - nextop = F8; - GETEX32(0); - GETGX; - memcpy(EX, GX, 16); - break; - default: - return 0; - } - break; - - case 0xB6: /* MOVZX Gd,Eb */ - nextop = F8; - GETEB32(0); - GETGD; - GD->q[0] = EB->byte[0]; - break; - - case 0xB9: - switch(rep) { - case 0: /* UD1 Ed */ - nextop = F8; - FAKEED32(0); - #ifndef TEST_INTERPRETER - EmitSignal(emu, X64_SIGILL, (void*)R_RIP, 0); - #endif - break; - default: - return 0; - } - break; - - case 0xB7: /* MOVZX Gd,Ew */ - nextop = F8; - GETEW32(0); - GETGD; - GD->q[0] = EW->word[0]; - break; - - default: - return 0; - } - return addr; -} diff --git a/src/emu/x64run6764.c b/src/emu/x64run6764.c deleted file mode 100644 index af83db93..00000000 --- a/src/emu/x64run6764.c +++ /dev/null @@ -1,91 +0,0 @@ -#define _GNU_SOURCE -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include <string.h> -#include <signal.h> -#include <sys/types.h> -#include <unistd.h> - -#include "debug.h" -#include "box64stack.h" -#include "box64cpu_util.h" -#include "x64emu.h" -#include "x64emu_private.h" -#include "x64run_private.h" -#include "x64primop.h" -#include "x64trace.h" -#include "x87emu_private.h" -#include "box64context.h" -#include "bridge.h" - -#include "modrm.h" - -#ifdef TEST_INTERPRETER -uintptr_t Test6764(x64test_t *test, rex_t rex, int rep, int seg, uintptr_t addr) -#else -uintptr_t Run6764(x64emu_t *emu, rex_t rex, int rep, int seg, uintptr_t addr) -#endif -{ - (void)rep; - uint8_t opcode; - uint8_t nextop; - int8_t tmp8s; - uint8_t tmp8u; - uint32_t tmp32u; - int32_t tmp32s; - uint64_t tmp64u; - reg64_t *oped, *opgd; - #ifdef TEST_INTERPRETER - x64emu_t* emu = test->emu; - #endif - uintptr_t tlsdata = GetSegmentBaseEmu(emu, seg); - opcode = F8; - - while(opcode==0x67) - opcode = F8; - - rex.rex = 0; - while((opcode==0xF2) || (opcode==0xF3)) { - rep = opcode-0xF1; - opcode = F8; - } - - while (opcode >= 0x40 && opcode <= 0x4f) { - rex.rex = opcode; - opcode = F8; - } - - switch(opcode) { - - case 0x89: /* MOV FS:Ed, Gd */ - nextop = F8; - GETED_OFFS_32(0, tlsdata); - GETGD; - if(rex.w) { - ED->q[0] = GD->q[0]; - } else { - //if ED is a reg, than the opcode works like movzx - if(MODREG) - ED->q[0] = GD->dword[0]; - else - ED->dword[0] = GD->dword[0]; - } - break; - - case 0x8B: /* MOV Gd, FS:Ed */ - nextop = F8; - GETED_OFFS_32(0, tlsdata); - GETGD; - if(rex.w) - GD->q[0] = ED->q[0]; - else - GD->q[0] = ED->dword[0]; - break; - - default: - return 0; - } - return addr; -} diff --git a/src/emu/x64run6764_32.c b/src/emu/x64run6764_32.c deleted file mode 100644 index bb53498e..00000000 --- a/src/emu/x64run6764_32.c +++ /dev/null @@ -1,116 +0,0 @@ -#define _GNU_SOURCE -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include <string.h> -#include <signal.h> -#include <sys/types.h> -#include <unistd.h> - -#include "debug.h" -#include "box64stack.h" -#include "box64cpu_util.h" -#include "x64emu.h" -#include "x64emu_private.h" -#include "x64run_private.h" -#include "x64primop.h" -#include "x64trace.h" -#include "x87emu_private.h" -#include "box64context.h" -#include "bridge.h" - -#include "modrm.h" - -#ifdef TEST_INTERPRETER -uintptr_t Test6764_32(x64test_t *test, rex_t rex, int rep, int seg, uintptr_t addr) -#else -uintptr_t Run6764_32(x64emu_t *emu, rex_t rex, int rep, int seg, uintptr_t addr) -#endif -{ - (void)rep; - uint8_t opcode; - uint8_t nextop; - int8_t tmp8s; - uint8_t tmp8u; - uint32_t tmp32u; - int32_t tmp32s; - uint64_t tmp64u; - reg64_t *oped, *opgd; - #ifdef TEST_INTERPRETER - x64emu_t* emu = test->emu; - #endif - uintptr_t tlsdata = GetSegmentBaseEmu(emu, seg); - opcode = F8; - - while(opcode==0x67) - opcode = F8; - - rex.rex = 0; - while((opcode==0xF2) || (opcode==0xF3)) { - rep = opcode-0xF1; - opcode = F8; - } - - switch(opcode) { - - case 0x89: /* MOV FS:Ed, Gd */ - nextop = F8; - GETED_OFFS_16(tlsdata); - GETGD; - ED->dword[0] = GD->dword[0]; - break; - - case 0x8B: /* MOV Gd, FS:Ed */ - nextop = F8; - GETED_OFFS_16(tlsdata); - GETGD; - GD->dword[0] = ED->dword[0]; - break; - - case 0x8F: /* POP FS:Ed */ - nextop = F8; - GETED_OFFS_16(tlsdata); - ED->dword[0] = Pop32(emu); - break; - - case 0xA1: /* MOV EAX, FS:Od */ - tmp32u = F16; - #ifdef TEST_INTERPRETER - test->memaddr = tlsdata + tmp32u; - test->memsize = 4; - R_EAX = *(uint32_t*)(test->mem); - #else - R_EAX = *(uint32_t*)(tlsdata + tmp32u); - #endif - break; - - case 0xA3: /* MOV FS:Od,EAX */ - tmp32u = F16; - #ifdef TEST_INTERPRETER - test->memaddr = tlsdata + tmp32u; - test->memsize = 4; - *(uint32_t*)(test->mem) = R_EAX; - #else - *(uint32_t*)(tlsdata + tmp32u) = R_EAX; - #endif - break; - - case 0xFF: - nextop = F8; - GETEW_OFFS_16(tlsdata); - switch((nextop>>3)&7) { - case 6: // Push Ed - tmp32u = ED->dword[0]; - Push32(emu, tmp32u); - break; - default: - return 0; - } - break; - - default: - return 0; - } - return addr; -} diff --git a/src/emu/x64run6766.c b/src/emu/x64run6766.c deleted file mode 100644 index d7fd39be..00000000 --- a/src/emu/x64run6766.c +++ /dev/null @@ -1,121 +0,0 @@ -#define _GNU_SOURCE -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include <string.h> -#include <signal.h> -#include <sys/types.h> -#include <unistd.h> - -#include "debug.h" -#include "box64stack.h" -#include "x64emu.h" -#include "x64emu_private.h" -#include "x64run_private.h" -#include "x64primop.h" -#include "x64trace.h" -#include "x87emu_private.h" -#include "box64context.h" -#include "bridge.h" -#ifdef DYNAREC -#include "../dynarec/native_lock.h" -#endif - -#include "modrm.h" - -#ifdef TEST_INTERPRETER -uintptr_t Test6766(x64test_t *test, rex_t rex, int rep, uintptr_t addr) -#else -uintptr_t Run6766(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr) -#endif -{ - // Hmmmm.... - (void)rep; - uint8_t opcode; - uint8_t nextop; (void)nextop; - int8_t tmp8s; (void)tmp8s; - uint8_t tmp8u, tmp8u2; (void)tmp8u; (void)tmp8u2; - int16_t tmp16s; (void)tmp16s; - uint16_t tmp16u, tmp16u2; (void)tmp16u; (void)tmp16u2; - int32_t tmp32s; (void)tmp32s; - int64_t tmp64s; (void)tmp64s; - uint64_t tmp64u, tmp64u2, tmp64u3; (void)tmp64u; (void)tmp64u2; (void)tmp64u3; - reg64_t *oped, *opgd; (void)oped; (void)opgd; - #ifdef TEST_INTERPRETER - x64emu_t* emu = test->emu; - #endif - opcode = F8; - - while((opcode==0x2E) || (opcode==0x66)) // ignoring CS: or multiple 0x66 - opcode = F8; - - while((opcode==0xF2) || (opcode==0xF3)) { - rep = opcode-0xF1; - opcode = F8; - } - // REX prefix before the 66 are ignored - rex.rex = 0; - if(!rex.is32bits) - while(opcode>=0x40 && opcode<=0x4f) { - rex.rex = opcode; - opcode = F8; - } - - switch(opcode) { - - case 0x0F: /* more opcodes */ - #ifdef TEST_INTERPRETER - return Test67660F(test, rex, addr); - #else - return Run67660F(emu, rex, addr); - #endif - - case 0x81: /* GRP3 Ew,Iw */ - case 0x83: /* GRP3 Ew,Ib */ - nextop = F8; - GETEW32((opcode==0x81)?2:1); - GETGW; - if(opcode==0x81) - tmp16u = F16; - else { - tmp16s = F8S; - tmp16u = (uint16_t)tmp16s; - } - switch((nextop>>3)&7) { - case 0: EW->word[0] = add16(emu, EW->word[0], tmp16u); break; - case 1: EW->word[0] = or16(emu, EW->word[0], tmp16u); break; - case 2: EW->word[0] = adc16(emu, EW->word[0], tmp16u); break; - case 3: EW->word[0] = sbb16(emu, EW->word[0], tmp16u); break; - case 4: EW->word[0] = and16(emu, EW->word[0], tmp16u); break; - case 5: EW->word[0] = sub16(emu, EW->word[0], tmp16u); break; - case 6: EW->word[0] = xor16(emu, EW->word[0], tmp16u); break; - case 7: cmp16(emu, EW->word[0], tmp16u); break; - } - break; - - case 0x89: /* MOV Ew,Gw */ - nextop = F8; - GETEW32(0); - GETGW; - if(rex.w) - EW->q[0] = GW->q[0]; - else - EW->word[0] = GW->word[0]; - break; - - case 0x8D: /* LEA Gw,M */ - nextop = F8; - GETGW; - tmp64u = GETEA32(0); - if(rex.w) - GW->q[0] = tmp64u; - else - GW->word[0] = (uint16_t)tmp64u; - break; - - default: - return 0; - } - return addr; -} diff --git a/src/emu/x64run67660f.c b/src/emu/x64run67660f.c deleted file mode 100644 index 4e1a3f90..00000000 --- a/src/emu/x64run67660f.c +++ /dev/null @@ -1,110 +0,0 @@ -#define _GNU_SOURCE -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include <string.h> -#include <signal.h> -#include <sys/types.h> -#include <unistd.h> - -#include "debug.h" -#include "box64stack.h" -#include "x64emu.h" -#include "x64emu_private.h" -#include "x64run_private.h" -#include "x64primop.h" -#include "x64trace.h" -#include "x87emu_private.h" -#include "box64context.h" -#include "bridge.h" - -#include "modrm.h" - -#ifdef TEST_INTERPRETER -uintptr_t Test67660F(x64test_t *test, rex_t rex, uintptr_t addr) -#else -uintptr_t Run67660F(x64emu_t *emu, rex_t rex, uintptr_t addr) -#endif -{ - uint8_t opcode; - uint8_t nextop; - int8_t tmp8s; (void)tmp8s; - uint8_t tmp8u; (void)tmp8u; - int16_t tmp16s; (void)tmp16s; - uint16_t tmp16u; (void)tmp16u; - int32_t tmp32s; (void)tmp32s; - uint32_t tmp32u; (void)tmp32u; - int64_t tmp64s; (void)tmp64s; - uint64_t tmp64u; (void)tmp64u; - reg64_t *oped, *opgd; (void)oped; (void)opgd; - sse_regs_t *opex, *opgx; - #ifdef TEST_INTERPRETER - x64emu_t* emu = test->emu; - #endif - opcode = F8; - - switch(opcode) { - - case 0x6F: /* MOVDQA Gx,Ex */ - nextop = F8; - GETEX32(0); - GETGX; - GX->q[0] = EX->q[0]; - GX->q[1] = EX->q[1]; - break; - - case 0x76: /* PCMPEQD Gx,Ex */ - nextop = F8; - GETEX32(0); - GETGX; - for (int i=0; i<4; ++i) - GX->ud[i] = (GX->ud[i]==EX->ud[i])?0xffffffff:0; - break; - - case 0x7E: /* MOVD Ed, Gx */ - nextop = F8; - GETED32(0); - GETGX; - if(rex.w) - ED->q[0] = GX->q[0]; - else { - if(MODREG) - ED->q[0] = GX->ud[0]; - else - ED->dword[0] = GX->ud[0]; - } - break; - - case 0xD6: /* MOVQ Ex,Gx */ - nextop = F8; - GETEX32(0); - GETGX; - EX->q[0] = GX->q[0]; - if(MODREG) - EX->q[1] = 0; - break; - - case 0xEF: /* PXOR Gx,Ex */ - nextop = F8; - GETEX32(0); - GETGX; - GX->q[0] ^= EX->q[0]; - GX->q[1] ^= EX->q[1]; - break; - - case 0xFE: /* PADDD Gx,Ex */ - nextop = F8; - GETEX32(0); - GETGX; - GX->sd[0] += EX->sd[0]; - GX->sd[1] += EX->sd[1]; - GX->sd[2] += EX->sd[2]; - GX->sd[3] += EX->sd[3]; - break; - - default: - return 0; - } - return addr; -} diff --git a/src/emu/x64run67_32.c b/src/emu/x64run67_32.c deleted file mode 100644 index 73459143..00000000 --- a/src/emu/x64run67_32.c +++ /dev/null @@ -1,114 +0,0 @@ -#define _GNU_SOURCE -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include <string.h> -#include <signal.h> -#include <sys/types.h> -#include <unistd.h> - -#include "debug.h" -#include "box64stack.h" -#include "x64emu.h" -#include "x64emu_private.h" -#include "x64run_private.h" -#include "x64primop.h" -#include "x64trace.h" -#include "x87emu_private.h" -#include "box64context.h" -#include "bridge.h" - -#include "modrm.h" - -#ifdef TEST_INTERPRETER -uintptr_t Test67_32(x64test_t *test, rex_t rex, int rep, uintptr_t addr) -#else -uintptr_t Run67_32(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr) -#endif -{ - uint8_t opcode; - uint8_t nextop; - int8_t tmp8s; - uint8_t tmp8u; - uint32_t tmp32u; - int32_t tmp32s; - uint64_t tmp64u; - reg64_t *oped, *opgd; - #ifdef TEST_INTERPRETER - x64emu_t* emu = test->emu; - #endif - opcode = F8; - - while(opcode==0x67) - opcode = F8; - - rex.rex = 0; - while((opcode==0xF2) || (opcode==0xF3)) { - rep = opcode-0xF1; - opcode = F8; - } - - switch(opcode) { - - case 0x64: /* FS: prefix */ - #ifdef TEST_INTERPRETER - return Test6764_32(test, rex, rep, _FS, addr); - #else - return Run6764_32(emu, rex, rep, _FS, addr); - #endif - break; - case 0x65: /* GS: prefix */ - #ifdef TEST_INTERPRETER - return Test6764_32(test, rex, rep, _GS, addr); - #else - return Run6764_32(emu, rex, rep, _GS, addr); - #endif - break; - case 0x66: - opcode = F8; - switch(opcode) { - - case 0x8D: /* LEA Gw,M */ - nextop = F8; - GETGW; - tmp32u = GETEA32_16(0); - GW->word[0] = (uint16_t)tmp32u; - break; - - default: - return 0; - } - break; - - case 0xE0: /* LOOPNZ */ - CHECK_FLAGS(emu); - tmp8s = F8S; - --R_CX; // don't update flags - if(R_CX && !ACCESS_FLAG(F_ZF)) - addr += tmp8s; - break; - case 0xE1: /* LOOPZ */ - CHECK_FLAGS(emu); - tmp8s = F8S; - --R_CX; // don't update flags - if(R_CX && ACCESS_FLAG(F_ZF)) - addr += tmp8s; - break; - case 0xE2: /* LOOP */ - tmp8s = F8S; - --R_CX; // don't update flags - if(R_CX) - addr += tmp8s; - break; - case 0xE3: /* JECXZ Ib */ - tmp8s = F8S; - if(!R_CX) - addr += tmp8s; - break; - - default: - return 0; - } - return addr; -} diff --git a/src/emu/x64run67avx.c b/src/emu/x64run67avx.c deleted file mode 100644 index 854ff614..00000000 --- a/src/emu/x64run67avx.c +++ /dev/null @@ -1,120 +0,0 @@ -#define _GNU_SOURCE -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include <fenv.h> -#include <string.h> -#include <signal.h> -#include <sys/types.h> -#include <unistd.h> - -#include "debug.h" -#include "box64stack.h" -#include "x64emu.h" -#include "x64emu_private.h" -#include "x64run_private.h" -#include "x64primop.h" -#include "x64trace.h" -#include "x87emu_private.h" -#include "box64context.h" -#include "my_cpuid.h" -#include "bridge.h" -#include "x64shaext.h" -#ifdef DYNAREC -#include "custommem.h" -#include "../dynarec/native_lock.h" -#endif - -#include "modrm.h" - -static const char* avx_prefix_string(uint16_t p) -{ - switch(p) { - case VEX_P_NONE: return "0"; - case VEX_P_66: return "66"; - case VEX_P_F2: return "F2"; - case VEX_P_F3: return "F3"; - default: return "??"; - } -} -static const char* avx_map_string(uint16_t m) -{ - switch(m) { - case VEX_M_NONE: return "0"; - case VEX_M_0F: return "0F"; - case VEX_M_0F38: return "0F38"; - case VEX_M_0F3A: return "0F3A"; - default: return "??"; - } -} - -#ifdef TEST_INTERPRETER -uintptr_t Test67AVX(x64test_t *test, vex_t vex, uintptr_t addr) -#else -uintptr_t Run67AVX(x64emu_t *emu, vex_t vex, uintptr_t addr) -#endif -{ - uint8_t opcode; - uint8_t nextop; - uint8_t tmp8u; - int8_t tmp8s; - int32_t tmp32s, tmp32s2; - uint32_t tmp32u, tmp32u2; - uint64_t tmp64u, tmp64u2; - int64_t tmp64s; - reg64_t *oped, *opgd, *opvd; - sse_regs_t *opex, *opgx, *opvx, eax1; - sse_regs_t *opey, *opgy, *opvy, eay1; - -#ifdef TEST_INTERPRETER - x64emu_t *emu = test->emu; -#endif - opcode = F8; - - rex_t rex = vex.rex; - - if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_F2)) { - switch(opcode) { - - case 0xF6: /* MULX Gd, Vd, Ed (,RDX) */ - nextop = F8; - GETED32(0); - GETGD; - GETVD; - if(rex.w) { - unsigned __int128 res = (unsigned __int128)R_RDX * ED->q[0]; - VD->q[0] = res&0xFFFFFFFFFFFFFFFFLL; - GD->q[0] = res>>64; - } else { - tmp64u = (uint64_t)R_EDX * ED->dword[0]; - VD->q[0] = tmp64u&0xFFFFFFFF; - GD->q[0] = tmp64u>>32; - } - break; - - default: addr = 0; - } - } else if ((vex.m==VEX_M_0F) && (vex.p==VEX_P_66)) { - switch(opcode) { - case 0xD6: /* VMOVQ Ex, Gx */ - nextop = F8; - GETEX32(0); - GETGX; - EX->q[0] = GX->q[0]; - if(MODREG) { - EX->q[1] = 0; - GETEY; - EY->u128 = 0; - } - break; - - default: addr = 0; - } - } else addr = 0; - - if(!addr) - printf_log(LOG_INFO, "Unimplemented 67 AVX opcode size %d prefix %s map %s opcode %02X ", 128<<vex.l, avx_prefix_string(vex.p), avx_map_string(vex.m), opcode); - - return addr; -} 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)]; diff --git a/src/emu/x64run_private.h b/src/emu/x64run_private.h index 26c74c3c..b4c6670d 100644 --- a/src/emu/x64run_private.h +++ b/src/emu/x64run_private.h @@ -19,7 +19,12 @@ typedef struct rex_s { unsigned int s:4; }; }; - int is32bits; + uint8_t is32bits:1; + uint8_t is66:1; + uint8_t is67:1; + uint8_t seg:3; //seg is 0-5, but 0 is CS, so will always be no-offset + uint8_t rep:2; // 0 none, 1=F2 prefix, 2=F3 prefix + uint64_t offset; } rex_t; #define VEX_P_NONE 0 @@ -97,26 +102,15 @@ sse_regs_t* GetGy(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v); #define RESET_FLAGS(emu) emu->df = d_none uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step); -uintptr_t Run64(x64emu_t *emu, rex_t rex, int seg, uintptr_t addr); -uintptr_t Run64AVX(x64emu_t *emu, vex_t vex, uintptr_t addr, uintptr_t tlsdata); -uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr); +uintptr_t Run66(x64emu_t *emu, rex_t rex, uintptr_t addr); uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr); uintptr_t Run66F20F(x64emu_t *emu, rex_t rex, uintptr_t addr); uintptr_t Run66F30F(x64emu_t *emu, rex_t rex, uintptr_t addr); -uintptr_t Run6664(x64emu_t *emu, rex_t rex, int seg, 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 Run6764(x64emu_t *emu, rex_t rex, int rep, int seg, uintptr_t addr); -uintptr_t Run67AVX(x64emu_t *emu, vex_t vex, uintptr_t addr); -uintptr_t Run67_32(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr); -uintptr_t Run6764_32(x64emu_t *emu, rex_t rex, int rep, int seg, 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 offs); -uintptr_t RunD9(x64emu_t *emu, rex_t rex, uintptr_t addr, uintptr_t offs); +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); @@ -140,26 +134,15 @@ uintptr_t RunAVX_F30F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step); uintptr_t RunAVX_F30F3A(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step); uintptr_t Test0F(x64test_t *test, rex_t rex, uintptr_t addr, int *step); -uintptr_t Test64(x64test_t *test, rex_t rex, int seg, uintptr_t addr); -uintptr_t Test64AVX(x64test_t *test, vex_t vex, uintptr_t addr, uintptr_t tlsdata); -uintptr_t Test66(x64test_t *test, rex_t rex, int rep, uintptr_t addr); +uintptr_t Test66(x64test_t *test, rex_t rex, uintptr_t addr); uintptr_t Test660F(x64test_t *test, rex_t rex, uintptr_t addr); uintptr_t Test66F20F(x64test_t *test, rex_t rex, uintptr_t addr); uintptr_t Test66F30F(x64test_t *test, rex_t rex, uintptr_t addr); -uintptr_t Test6664(x64test_t *test, rex_t rex, int seg, uintptr_t addr); uintptr_t Test66D9(x64test_t *test, rex_t rex, uintptr_t addr); uintptr_t Test66DD(x64test_t *test, rex_t rex, uintptr_t addr); uintptr_t Test66F0(x64test_t *test, rex_t rex, uintptr_t addr); -uintptr_t Test67(x64test_t *test, rex_t rex, int rep, uintptr_t addr); -uintptr_t Test6764(x64test_t *test, rex_t rex, int rep, int seg, uintptr_t addr); -uintptr_t Test67AVX(x64test_t *test, vex_t vex, uintptr_t addr); -uintptr_t Test67_32(x64test_t *test, rex_t rex, int rep, uintptr_t addr); -uintptr_t Test6764_32(x64test_t *test, rex_t rex, int rep, int seg, uintptr_t addr); -uintptr_t Test670F(x64test_t *test, rex_t rex, int rep, uintptr_t addr); -uintptr_t Test6766(x64test_t *test, rex_t rex, int rep, uintptr_t addr); -uintptr_t Test67660F(x64test_t *test, rex_t rex, uintptr_t addr); -uintptr_t TestD8(x64test_t *test, rex_t rex, uintptr_t addr, uintptr_t offs); -uintptr_t TestD9(x64test_t *test, rex_t rex, uintptr_t addr, uintptr_t offs); +uintptr_t TestD8(x64test_t *test, rex_t rex, uintptr_t addr); +uintptr_t TestD9(x64test_t *test, rex_t rex, uintptr_t addr); uintptr_t TestDA(x64test_t *test, rex_t rex, uintptr_t addr); uintptr_t TestDB(x64test_t *test, rex_t rex, uintptr_t addr); uintptr_t TestDC(x64test_t *test, rex_t rex, uintptr_t addr); diff --git a/src/emu/x64rund8.c b/src/emu/x64rund8.c index fc1101f4..ffd988e6 100644 --- a/src/emu/x64rund8.c +++ b/src/emu/x64rund8.c @@ -24,9 +24,9 @@ #include "modrm.h" #ifdef TEST_INTERPRETER -uintptr_t TestD8(x64test_t *test, rex_t rex, uintptr_t addr, uintptr_t offs) +uintptr_t TestD8(x64test_t *test, rex_t rex, uintptr_t addr) #else -uintptr_t RunD8(x64emu_t *emu, rex_t rex, uintptr_t addr, uintptr_t offs) +uintptr_t RunD8(x64emu_t *emu, rex_t rex, uintptr_t addr) #endif { uint8_t nextop; @@ -134,73 +134,41 @@ uintptr_t RunD8(x64emu_t *emu, rex_t rex, uintptr_t addr, uintptr_t offs) } else switch((nextop>>3)&7) { case 0: /* FADD ST0, float */ - if(offs) { - GETE4_OFFS(0, offs); - } else { - GETE4(0); - } + GETE4(0); ST0.d += *(float*)ED; if(!emu->cw.f.C87_PC) ST0.d = (float)ST0.d; break; case 1: /* FMUL ST0, float */ - if(offs) { - GETE4_OFFS(0, offs); - } else { - GETE4(0); - } + GETE4(0); ST0.d *= *(float*)ED; if(!emu->cw.f.C87_PC) ST0.d = (float)ST0.d; break; case 2: /* FCOM ST0, float */ - if(offs) { - GETE4_OFFS(0, offs); - } else { - GETE4(0); - } + GETE4(0); fpu_fcom(emu, *(float*)ED); break; case 3: /* FCOMP */ - if(offs) { - GETE4_OFFS(0, offs); - } else { - GETE4(0); - } + GETE4(0); fpu_fcom(emu, *(float*)ED); fpu_do_pop(emu); break; case 4: /* FSUB ST0, float */ - if(offs) { - GETE4_OFFS(0, offs); - } else { - GETE4(0); - } + GETE4(0); ST0.d -= *(float*)ED; if(!emu->cw.f.C87_PC) ST0.d = (float)ST0.d; break; case 5: /* FSUBR ST0, float */ - if(offs) { - GETE4_OFFS(0, offs); - } else { - GETE4(0); - } + GETE4(0); ST0.d = *(float*)ED - ST0.d; if(!emu->cw.f.C87_PC) ST0.d = (float)ST0.d; break; case 6: /* FDIV ST0, float */ - if(offs) { - GETE4_OFFS(0, offs); - } else { - GETE4(0); - } + GETE4(0); ST0.d /= *(float*)ED; if(!emu->cw.f.C87_PC) ST0.d = (float)ST0.d; break; case 7: /* FDIVR ST0, float */ - if(offs) { - GETE4_OFFS(0, offs); - } else { - GETE4(0); - } + GETE4(0); ST0.d = *(float*)ED / ST0.d; if(!emu->cw.f.C87_PC) ST0.d = (float)ST0.d; break; diff --git a/src/emu/x64rund9.c b/src/emu/x64rund9.c index 0e9bb1b4..6f0faa8b 100644 --- a/src/emu/x64rund9.c +++ b/src/emu/x64rund9.c @@ -24,9 +24,9 @@ #include "modrm.h" #ifdef TEST_INTERPRETER -uintptr_t TestD9(x64test_t *test, rex_t rex, uintptr_t addr, uintptr_t offs) +uintptr_t TestD9(x64test_t *test, rex_t rex, uintptr_t addr) #else -uintptr_t RunD9(x64emu_t *emu, rex_t rex, uintptr_t addr, uintptr_t offs) +uintptr_t RunD9(x64emu_t *emu, rex_t rex, uintptr_t addr) #endif { uint8_t nextop; @@ -250,30 +250,18 @@ uintptr_t RunD9(x64emu_t *emu, rex_t rex, uintptr_t addr, uintptr_t offs) } else switch((nextop>>3)&7) { case 0: /* FLD ST0, Ed float */ - if(offs) { - GETE4_OFFS(0, offs); - } else { - GETE4(0); - } + GETE4(0); fpu_do_push(emu); ST0.d = *(float*)ED; break; case 2: /* FST Ed, ST0 */ - if(offs) { - GETE4_OFFS(0, offs); - } else { - GETE4(0); - } + GETE4(0); oldround = fpu_setround(emu); *(float*)ED = ST0.d; fesetround(oldround); break; case 3: /* FSTP Ed, ST0 */ - if(offs) { - GETE4_OFFS(0, offs); - } else { - GETE4(0); - } + GETE4(0); oldround = fpu_setround(emu); *(float*)ED = ST0.d; fesetround(oldround); @@ -281,40 +269,24 @@ uintptr_t RunD9(x64emu_t *emu, rex_t rex, uintptr_t addr, uintptr_t offs) break; case 4: /* FLDENV m */ // warning, incomplete - if(offs) { - _GETED_OFFS(0, offs); - } else { - _GETED(0); - } + _GETED(0); fpu_loadenv(emu, (char*)ED, 0); break; case 5: /* FLDCW Ew */ - if(offs) { - GETEW_OFFS(0, offs); - } else { - GETEW(0); - } + GETEW(0); emu->cw.x16 = EW->word[0]; // do something with cw? break; case 6: /* FNSTENV m */ // warning, incomplete - if(offs) { - GETE8_OFFS(0, offs); - } else { - GETE8(0); - } + GETE8(0); fpu_savenv(emu, (char*)ED, 0); // intruction pointer: 48bits // data (operand) pointer: 48bits // last opcode: 11bits save: 16bits restaured (1st and 2nd opcode only) break; case 7: /* FNSTCW Ew */ - if(offs) { - GETEW_OFFS(0, offs); - } else { - GETEW(0); - } + GETEW(0); EW->word[0] = emu->cw.x16; break; default: |