diff options
Diffstat (limited to 'src/emu/x64run67.c')
| -rw-r--r-- | src/emu/x64run67.c | 602 |
1 files changed, 0 insertions, 602 deletions
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; -} |