about summary refs log tree commit diff stats
path: root/src/emu/x64run67.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/x64run67.c')
-rw-r--r--src/emu/x64run67.c602
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;

-}