Logo Search packages:      
Sourcecode: pcsx version File versions  Download package

ix86.c

/*
 * ix86 core v0.5.1
 *  Authors: linuzappz <linuzappz@pcsx.net>
 *           alexey silinov
 */

#include <stdio.h>
#include <string.h>

#include "ix86.h"

static s32 iCpuId(s32 cmd, u32 *regs) {
      int flag;

#if defined (_MSC_VER_)
      __asm {
            push ebx
            push edi

            pushfd;
            pop eax;
            mov edx, eax;
            xor eax, 1 << 21;
            push eax;
            popfd;
            pushfd;
            pop eax;
            xor eax, edx;
            mov flag, eax;
      }
      if (!flag) return -1;

      __asm {
            mov eax, cmd;
            cpuid;
            mov flag, edx;
            mov edi, [regs]
            mov [edi], eax;
            mov [edi+4], ebx;
            mov [edi+8], ecx;
            mov [edi+12], edx;

            pop edi
            pop ebx
      }

      return 0;
#elif defined(__LINUX__) || (__MINGW32__)
      __asm__(
            "pushf\n" \
            "pop %%eax\n" \
            "mov %%eax, %%edx\n" \
            "xor $0x200000, %%eax\n" \
            "push %%eax\n" \
            "popf\n" \
            "pushf\n" \
            "pop %%eax\n" \
            "xor %%edx, %%eax\n" \
            "mov %%eax, %0" \
            : "=r"(flag) :
      );
      if (!flag) return -1;

      __asm__(
            "mov %4, %%eax\n"
            "cpuid\n"
            "mov %%eax, %0\n"
            "mov %%ebx, %1\n"
            "mov %%ecx, %2\n"
            "mov %%edx, %3"
            : "=m" (regs[0]), "=m" (regs[1]),
              "=m" (regs[2]), "=m" (regs[3])
            : "m"(cmd)
            : "eax", "ebx", "ecx", "edx"
      );

      return 0;
#endif
}

void x86Init() {
      u32 regs[4];
      u32 cmds;

      memset(x86ID, 0, sizeof(x86ID));
      x86Family = 0;
      x86Model  = 0;
      x86PType  = 0;
      x86StepID = 0;
      x86Flags  = 0;
      x86EFlags = 0;
      
      if (iCpuId(0, regs) != -1) {
            cmds = regs[0];
            ((u32*)x86ID)[0] = regs[1];
            ((u32*)x86ID)[1] = regs[3];
            ((u32*)x86ID)[2] = regs[2];
            if (cmds >= 0x00000001) {
                  if (iCpuId(0x00000001, regs) != -1) {
                        x86StepID =  regs[0]        & 0xf;
                        x86Model  = (regs[0] >>  4) & 0xf;
                        x86Family = (regs[0] >>  8) & 0xf;
                        x86PType  = (regs[0] >> 12) & 0x3;
                        x86Flags = regs[3];
                  }
            }

            if (iCpuId(0x80000000, regs) != -1) {
                  cmds = regs[0];
                  if (cmds >= 0x80000001) {
                        if (iCpuId(0x80000001, regs) != -1) {
                              x86EFlags = regs[3];
                        }
                  }
            }
      }
}

void x86SetPtr(char *ptr) {
      x86Ptr = ptr;
}

void x86Shutdown() {
}

void x86SetJ8(u8 *j8) {
      u32 jump = (x86Ptr - (s8*)j8) - 1;

      if (jump > 0x7f) printf("j8 greater than 0x7f!!\n");
      *j8 = (u8)jump;
}

void x86SetJ32(u32 *j32) {
      *j32 = (x86Ptr - (s8*)j32) - 4;
}

void x86Align(int bytes) {
      // fordward align
      x86Ptr = (s8*)(((u32)x86Ptr + bytes) & ~(bytes - 1));
}

#define SIB 4
#define DISP32 5

/* macros helpers */

#define ModRM(mod, rm, reg) \
      write8((mod << 6) | (rm << 3) | (reg));

#define SibSB(ss, rm, index) \
      write8((ss << 6) | (rm << 3) | (index));

#define SET8R(cc, to) { \
      write8(0x0F); write8(cc); \
      write8((0xC0) | (to)); }

#define J8Rel(cc, to) { \
      write8(cc); write8(to); return x86Ptr - 1; }

#define J32Rel(cc, to) { \
      write8(0x0F); write8(cc); write32(to); return (u32*)(x86Ptr - 4); }

#define CMOV32RtoR(cc, to, from) { \
      write8(0x0F); write8(cc); \
      ModRM(3, to, from); }

#define CMOV32MtoR(cc, to, from) { \
      write8(0x0F); write8(cc); \
      ModRM(0, to, DISP32); \
      write32(from); }

/********************/
/* IX86 intructions */
/********************/

// mov instructions

/* mov r32 to r32 */
void MOV32RtoR(int to, int from) {
      write8(0x89);
      ModRM(3, from, to);
}

/* mov r32 to m32 */
void MOV32RtoM(u32 to, int from) {
      write8(0x89);
      ModRM(0, from, DISP32);
      write32(to);
}

/* mov m32 to r32 */
void MOV32MtoR(int to, u32 from) {
      write8(0x8B);
      ModRM(0, to, DISP32);
      write32(from); 
}

/* mov [r32] to r32 */
void MOV32RmtoR(int to, int from) {
      write8(0x8B);
      ModRM(0, to, from);
}

/* mov [r32][r32*scale] to r32 */
void MOV32RmStoR(int to, int from, int from2, int scale) {
      write8(0x8B);
      ModRM(0, to, 0x4);
      SibSB(scale, from2, from);
}

/* mov r32 to [r32] */
void MOV32RtoRm(int to, int from) {
      write8(0x89);
      ModRM(0, from, to);
}

/* mov r32 to [r32][r32*scale] */
void MOV32RtoRmS(int to, int to2, int scale, int from) {
      write8(0x89);
      ModRM(0, from, 0x4);
      SibSB(scale, to2, to);
}

/* mov imm32 to r32 */
void MOV32ItoR(int to, u32 from) {
      write8(0xB8 | to); 
      write32(from);
}

/* mov imm32 to m32 */
void MOV32ItoM(u32 to, u32 from) {
      write8(0xC7);
      ModRM(0, 0, DISP32);
      write32(to);
      write32(from); 
}

/* mov r16 to m16 */
void MOV16RtoM(u32 to, int from) {
      write8(0x66);
      write8(0x89);
      ModRM(0, from, DISP32);
      write32(to);
}

/* mov m16 to r16 */
void MOV16MtoR(int to, u32 from) {
      write8(0x66);
      write8(0x8B);
      ModRM(0, to, DISP32);
      write32(from); 
}

/* mov imm16 to m16 */
void MOV16ItoM(u32 to, u16 from) {
      write8(0x66);
      write8(0xC7);
      ModRM(0, 0, DISP32);
      write32(to);
      write16(from); 
}

/* mov r8 to m8 */
void MOV8RtoM(u32 to, int from) {
      write8(0x88);
      ModRM(0, from, DISP32);
      write32(to);
}

/* mov m8 to r8 */
void MOV8MtoR(int to, u32 from) {
      write8(0x8A);
      ModRM(0, to, DISP32);
      write32(from); 
}

/* mov imm8 to m8 */
void MOV8ItoM(u32 to, u8 from) {
      write8(0xC6);
      ModRM(0, 0, DISP32);
      write32(to);
      write8(from); 
}

/* movsx r8 to r32 */
void MOVSX32R8toR(int to, int from) {
      write16(0xBE0F); 
      ModRM(3, to, from); 
}

/* movsx m8 to r32 */
void MOVSX32M8toR(int to, u32 from) {
      write16(0xBE0F); 
      ModRM(0, to, DISP32);
      write32(from);
}

/* movsx r16 to r32 */
void MOVSX32R16toR(int to, int from) {
      write16(0xBF0F); 
      ModRM(3, to, from); 
}

/* movsx m16 to r32 */
void MOVSX32M16toR(int to, u32 from) {
      write16(0xBF0F); 
      ModRM(0, to, DISP32);
      write32(from);
}

/* movzx r8 to r32 */
void MOVZX32R8toR(int to, int from) {
      write16(0xB60F); 
      ModRM(3, to, from); 
}

/* movzx m8 to r32 */
void MOVZX32M8toR(int to, u32 from) {
      write16(0xB60F); 
      ModRM(0, to, DISP32);
      write32(from);
}

/* movzx r16 to r32 */
void MOVZX32R16toR(int to, int from) {
      write16(0xB70F); 
      ModRM(3, to, from); 
}

/* movzx m16 to r32 */
void MOVZX32M16toR(int to, u32 from) {
      write16(0xB70F); 
      ModRM(0, to, DISP32);
      write32(from);
}

/* cmovne r32 to r32 */
void CMOVNE32RtoR(int to, int from) {
      CMOV32RtoR(0x45, to, from);
}

/* cmovne m32 to r32*/
void CMOVNE32MtoR(int to, u32 from) {
      CMOV32MtoR(0x45, to, from);
}

/* cmove r32 to r32*/
void CMOVE32RtoR(int to, int from) {
      CMOV32RtoR(0x44, to, from);
}

/* cmove m32 to r32*/
void CMOVE32MtoR(int to, u32 from) {
      CMOV32MtoR(0x44, to, from);
}

/* cmovg r32 to r32*/
void CMOVG32RtoR(int to, int from) {
      CMOV32RtoR(0x4F, to, from);
}

/* cmovg m32 to r32*/
void CMOVG32MtoR(int to, u32 from) {
      CMOV32MtoR(0x4F, to, from);
}

/* cmovge r32 to r32*/
void CMOVGE32RtoR(int to, int from) {
      CMOV32RtoR(0x4D, to, from);
}

/* cmovge m32 to r32*/
void CMOVGE32MtoR(int to, u32 from) {
      CMOV32MtoR(0x4D, to, from);
}

/* cmovl r32 to r32*/
void CMOVL32RtoR(int to, int from) {
      CMOV32RtoR(0x4C, to, from);
}

/* cmovl m32 to r32*/
void CMOVL32MtoR(int to, u32 from) {
      CMOV32MtoR(0x4C, to, from);
}

/* cmovle r32 to r32*/
void CMOVLE32RtoR(int to, int from) {
      CMOV32RtoR(0x4E, to, from);
}

/* cmovle m32 to r32*/
void CMOVLE32MtoR(int to, u32 from) {
      CMOV32MtoR(0x4E, to, from);
}

// arithmic instructions

/* add imm32 to r32 */
void ADD32ItoR(int to, u32 from) {
      if (to == EAX) {
            write8(0x05); 
      } else {
            write8(0x81); 
            ModRM(3, 0, to);
      }
      write32(from);
}

/* add imm32 to m32 */
void ADD32ItoM(u32 to, u32 from) {
      write8(0x81); 
      ModRM(0, 0, DISP32);
      write32(to);
      write32(from);
}

/* add r32 to r32 */
void ADD32RtoR(int to, int from) {
      write8(0x01); 
      ModRM(3, from, to);
}

/* add r32 to m32 */
void ADD32RtoM(u32 to, int from) {
      write8(0x01); 
      ModRM(0, from, DISP32);
      write32(to);
}

/* add m32 to r32 */
void ADD32MtoR(int to, u32 from) {
      write8(0x03); 
      ModRM(0, to, DISP32);
      write32(from);
}

/* adc imm32 to r32 */
void ADC32ItoR(int to, u32 from) {
      if (to == EAX) {
            write8(0x15);
      } else {
            write8(0x81);
            ModRM(3, 2, to);
      }
      write32(from); 
}

/* adc r32 to r32 */
void ADC32RtoR(int to, int from) {
      write8(0x11); 
      ModRM(3, from, to);
}

/* adc m32 to r32 */
void ADC32MtoR(int to, u32 from) {
      write8(0x13); 
      ModRM(0, to, DISP32);
      write32(from); 
}

/* inc r32 */
void INC32R(int to) {
      write8(0x40 + to);
}

/* inc m32 */
void INC32M(u32 to) {
      write8(0xFF);
      ModRM(0, 0, DISP32);
      write32(to);
}

/* sub imm32 to r32 */
void SUB32ItoR(int to, u32 from) {
      if (to == EAX) {
            write8(0x2D); 
      } else {
            write8(0x81); 
            ModRM(3, 5, to);
      }
      write32(from); 
}

/* sub r32 to r32 */
void SUB32RtoR(int to, int from) {
      write8(0x29); 
      ModRM(3, from, to);
}

/* sub m32 to r32 */
void SUB32MtoR(int to, u32 from) {
      write8(0x2B); 
      ModRM(0, to, DISP32);
      write32(from); 
}

/* sbb imm32 to r32 */
void SBB32ItoR(int to, u32 from) {
      if (to == EAX) {
            write8(0x1D);
      } else {
            write8(0x81);
            ModRM(3, 3, to);
      }
      write32(from); 
}

/* sbb r32 to r32 */
void SBB32RtoR(int to, int from) {
      write8(0x19); 
      ModRM(3, from, to);
}

/* sbb m32 to r32 */
void SBB32MtoR(int to, u32 from) {
      write8(0x1B); 
      ModRM(0, to, DISP32);
      write32(from); 
}

/* dec r32 */
void DEC32R(int to) {
      write8(0x48 + to);
}

/* dec m32 */
void DEC32M(u32 to) {
      write8(0xFF);
      ModRM(0, 1, DISP32);
      write32(to);
}

/* mul eax by r32 to edx:eax */
void MUL32R(int from) {
      write8(0xF7); 
      ModRM(3, 4, from);
}

/* imul eax by r32 to edx:eax */
void IMUL32R(int from) {
      write8(0xF7); 
      ModRM(3, 5, from);
}

/* mul eax by m32 to edx:eax */
void MUL32M(u32 from) {
      write8(0xF7); 
      ModRM(0, 4, DISP32);
      write32(from); 
}

/* imul eax by m32 to edx:eax */
void IMUL32M(u32 from) {
      write8(0xF7); 
      ModRM(0, 5, DISP32);
      write32(from); 
}

/* imul r32 by r32 to r32 */
void IMUL32RtoR(int to, int from) {
      write16(0xAF0F); 
      ModRM(3, to, from);
}

/* div eax by r32 to edx:eax */
void DIV32R(int from) {
      write8(0xF7); 
      ModRM(3, 6, from);
}

/* idiv eax by r32 to edx:eax */
void IDIV32R(int from) {
      write8(0xF7); 
      ModRM(3, 7, from);
}

/* div eax by m32 to edx:eax */
void DIV32M(u32 from) {
      write8(0xF7); 
      ModRM(0, 6, DISP32);
      write32(from); 
}

/* idiv eax by m32 to edx:eax */
void IDIV32M(u32 from) {
      write8(0xF7); 
      ModRM(0, 7, DISP32);
      write32(from); 
}

// shifting instructions

void RCR32ItoR(int to,int from)
{
      if (from==1)
      {
            write8(0xd1);
            write8(0xd8 | to);
      }
      else
      {
            write8(0xc1);
            write8(0xd8 | to);
            write8(from);
      }
}

/* shl imm8 to r32 */
void SHL32ItoR(int to, u8 from) {
      if (from==1)
      {
            write8(0xd1);
            write8(0xe0 | to);
            return;
      }
      write8(0xC1); 
      ModRM(3, 4, to);
      write8(from); 
}

/* shl cl to r32 */
void SHL32CLtoR(int to) {
      write8(0xD3); 
      ModRM(3, 4, to);
}

/* shr imm8 to r32 */
void SHR32ItoR(int to, u8 from) {
      if (from==1)
      {
            write8(0xd1);
            write8(0xe8 | to);
            return;
      }
      write8(0xC1); 
      ModRM(3, 5, to);
      write8(from); 
}

/* shr cl to r32 */
void SHR32CLtoR(int to) {
      write8(0xD3); 
      ModRM(3, 5, to);
}

/* sar imm8 to r32 */
void SAR32ItoR(int to, u8 from) {
      write8(0xC1); 
      ModRM(3, 7, to);
      write8(from); 
}

/* sar cl to r32 */
void SAR32CLtoR(int to) {
      write8(0xD3); 
      ModRM(3, 7, to);
}


// logical instructions

/* or imm32 to r32 */
void OR32ItoR(int to, u32 from) {
      if (to == EAX) {
            write8(0x0D); 
      } else {
            write8(0x81); 
            ModRM(3, 1, to);
      }
      write32(from); 
}

/* or imm32 to m32 */
void OR32ItoM(u32 to, u32 from) {
      write8(0x81); 
      ModRM(0, 1, DISP32);
      write32(to);
      write32(from); 
}

/* or r32 to r32 */
void OR32RtoR(int to, int from) {
      write8(0x09); 
      ModRM(3, from, to);
}

/* or r32 to m32 */
void OR32RtoM(u32 to, int from) {
      write8(0x09); 
      ModRM(0, from, DISP32);
      write32(to);
}

/* or m32 to r32 */
void OR32MtoR(int to, u32 from) {
      write8(0x0B); 
      ModRM(0, to, DISP32);
      write32(from); 
}

/* xor imm32 to r32 */
void XOR32ItoR(int to, u32 from) {
      if (to == EAX) {
            write8(0x35); 
      } else {
            write8(0x81); 
            ModRM(3, 6, to);
      }
      write32(from); 
}

/* xor imm32 to m32 */
void XOR32ItoM(u32 to, u32 from) {
      write8(0x81); 
      ModRM(0, 6, DISP32);
      write32(to); 
      write32(from); 
}

/* xor r32 to r32 */
void XOR32RtoR(int to, int from) {
      write8(0x31); 
      ModRM(3, from, to);
}

/* xor r32 to m32 */
void XOR32RtoM(u32 to, int from) {
      write8(0x31); 
      ModRM(0, from, DISP32);
      write32(to);
}

/* xor m32 to r32 */
void XOR32MtoR(int to, u32 from) {
      write8(0x33); 
      ModRM(0, to, DISP32);
      write32(from); 
}

/* and imm32 to r32 */
void AND32ItoR(int to, u32 from) {
      if (to == EAX) {
            write8(0x25); 
      } else {
            write8(0x81); 
            ModRM(3, 0x4, to);
      }
      write32(from); 
}

/* and imm32 to m32 */
void AND32ItoM(u32 to, u32 from) {
      write8(0x81); 
      ModRM(0, 0x4, DISP32);
      write32(to);
      write32(from); 
}

/* and r32 to r32 */
void AND32RtoR(int to, int from) {
      write8(0x21); 
      ModRM(3, from, to);
}

/* and r32 to m32 */
void AND32RtoM(u32 to, int from) {
      write8(0x21); 
      ModRM(0, from, DISP32);
      write32(to); 
}

/* and m32 to r32 */
void AND32MtoR(int to, u32 from) {
      write8(0x23); 
      ModRM(0, to, DISP32);
      write32(from); 
}

/* not r32 */
void NOT32R(int from) {
      write8(0xF7); 
      ModRM(3, 2, from);
}

/* neg r32 */
void NEG32R(int from) {
      write8(0xF7); 
      ModRM(3, 3, from);
}

// jump instructions

/* jmp rel8 */
u8*  JMP8(u8 to) {
      write8(0xEB); 
      write8(to);
      return x86Ptr - 1;
}

/* jmp rel32 */
u32* JMP32(u32 to) {
      write8(0xE9); 
      write32(to); 
      return (u32*)(x86Ptr - 4);
}

/* jmp r32 */
void JMP32R(int to) {
      write8(0xFF); 
      ModRM(3, 4, to);
}

/* je rel8 */
u8*  JE8(u8 to) {
      J8Rel(0x74, to);
}

/* jz rel8 */
u8*  JZ8(u8 to) {
      J8Rel(0x74, to); 
}

/* jg rel8 */
u8*  JG8(u8 to) { 
      J8Rel(0x7F, to);
}

/* jge rel8 */
u8*  JGE8(u8 to) { 
      J8Rel(0x7D, to); 
}

/* jl rel8 */
u8*  JL8(u8 to) { 
      J8Rel(0x7C, to); 
}

/* jle rel8 */
u8*  JLE8(u8 to) { 
      J8Rel(0x7E, to); 
}

/* jne rel8 */
u8*  JNE8(u8 to) { 
      J8Rel(0x75, to); 
}

/* jnz rel8 */
u8*  JNZ8(u8 to) { 
      J8Rel(0x75, to); 
}

/* jng rel8 */
u8*  JNG8(u8 to) { 
      J8Rel(0x7E, to); 
}

/* jnge rel8 */
u8*  JNGE8(u8 to) { 
      J8Rel(0x7C, to); 
}

/* jnl rel8 */
u8*  JNL8(u8 to) { 
      J8Rel(0x7D, to); 
}

/* jnle rel8 */
u8*  JNLE8(u8 to) { 
      J8Rel(0x7F, to); 
}

/* jo rel8 */
u8*  JO8(u8 to) { 
      J8Rel(0x70, to); 
}

/* jno rel8 */
u8*  JNO8(u8 to) { 
      J8Rel(0x71, to); 
}

/* je rel32 */
u32* JE32(u32 to) {
      J32Rel(0x84, to);
}

/* jz rel32 */
u32* JZ32(u32 to) {
      J32Rel(0x84, to); 
}

/* jg rel32 */
u32* JG32(u32 to) { 
      J32Rel(0x8F, to);
}

/* jge rel32 */
u32* JGE32(u32 to) { 
      J32Rel(0x8D, to); 
}

/* jl rel32 */
u32* JL32(u32 to) { 
      J32Rel(0x8C, to); 
}

/* jle rel32 */
u32* JLE32(u32 to) { 
      J32Rel(0x8E, to); 
}

/* jne rel32 */
u32* JNE32(u32 to) { 
      J32Rel(0x85, to); 
}

/* jnz rel32 */
u32* JNZ32(u32 to) { 
      J32Rel(0x85, to); 
}

/* jng rel32 */
u32* JNG32(u32 to) { 
      J32Rel(0x8E, to); 
}

/* jnge rel32 */
u32* JNGE32(u32 to) { 
      J32Rel(0x8C, to); 
}

/* jnl rel32 */
u32* JNL32(u32 to) { 
      J32Rel(0x8D, to); 
}

/* jnle rel32 */
u32*  JNLE32(u32 to) { 
      J32Rel(0x8F, to); 
}

/* jo rel32 */
u32*  JO32(u32 to) { 
      J32Rel(0x80, to); 
}

/* jno rel32 */
u32*  JNO32(u32 to) { 
      J32Rel(0x81, to); 
}

/* call func */
void CALLFunc(u32 func) {
      CALL32(func - ((u32)x86Ptr + 5));
}

/* call rel32 */
void CALL32(u32 to) {
      write8(0xE8); 
      write32(to); 
}

/* call r32 */
void CALL32R(int to) {
      write8(0xFF);
      ModRM(3, 2, to);
}

/* call m32 */
void CALL32M(u32 to) {
      write8(0xFF);
      ModRM(0, 2, DISP32);
      write32(to);
}

// misc instructions

/* cmp imm32 to r32 */
void CMP32ItoR(int to, u32 from) {
      if (to == EAX) {
            write8(0x3D);
      } else {
            write8(0x81);
            ModRM(3, 7, to);
      }
      write32(from); 
}

/* cmp imm32 to m32 */
void CMP32ItoM(u32 to, u32 from) {
      write8(0x81); 
      ModRM(0, 7, DISP32);
      write32(to); 
      write32(from); 
}

/* cmp r32 to r32 */
void CMP32RtoR(int to, int from) {
      write8(0x39);
      ModRM(3, from, to);
}

/* cmp m32 to r32 */
void CMP32MtoR(int to, u32 from) {
      write8(0x3B);
      ModRM(0, to, DISP32);
      write32(from); 
}

/* test imm32 to r32 */
void TEST32ItoR(int to, u32 from) {
      if (to == EAX) {
            write8(0xA9);
      } else {
            write8(0xF7);
            ModRM(3, 0, to);
      }
      write32(from); 
}

/* test r32 to r32 */
void TEST32RtoR(int to, int from) {
      write8(0x85);
      ModRM(3, from, to);
}

void BT32ItoR(int to,int from)
{
      write16(0xba0f);
      write8(0xe0 | to);
      write8(from);
}

/* sets r8 */
void SETS8R(int to) { 
        SET8R(0x98, to); 
}
/* setl r8 */
void SETL8R(int to) { 
      SET8R(0x9C, to); 
}

/* setb r8 */
void SETB8R(int to) { 
      SET8R(0x92, to); 
}

/* setnz r8 */
void SETNZ8R(int to) { 
      SET8R(0x95,to); 
}

/* cbw */
void CBW() {
      write16(0x9866); 
}

/* cwd */
void CWD() {
      write8(0x98);
}

/* cdq */
void CDQ() {
      write8(0x99); 
}

/* push r32 */
void PUSH32R(int from) {
      write8(0x50 | from); 
}

/* push m32 */
void PUSH32M(u32 from) {
      write8(0xFF);
      ModRM(0, 6, DISP32);
      write32(from); 
}

/* push imm32 */
void PUSH32I(u32 from) {
      write8(0x68); write32(from); 
}

/* pop r32 */
void POP32R(int from) {
      write8(0x58 | from); 
}

/* pushad */
void PUSHA32() {
      write8(0x60); 
}

/* popad */
void POPA32() {
      write8(0x61); 
}

/* ret */
void RET() {
      write8(0xC3); 
}

/********************/
/* FPU instructions */
/********************/

//Added:basara 14.01.2003
/* compare m32 to fpu reg stack */
void FCOMP32(u32 from) {
      write8(0xD8);
      ModRM(0, 0x3, DISP32);
      write32(from); 
}

void FNSTSWtoAX() {
      write16(0xE0DF);
}

/* fild m32 to fpu reg stack */
void FILD32(u32 from) {
      write8(0xDB);
      ModRM(0, 0x0, DISP32);
      write32(from); 
}

/* fistp m32 from fpu reg stack */
void FISTP32(u32 from) {
      write8(0xDB);
      ModRM(0, 0x3, DISP32);
      write32(from); 
}

/* fld m32 to fpu reg stack */
void FLD32(u32 from) {
      write8(0xD9);
      ModRM(0, 0x0, DISP32);
      write32(from); 
}

/* fstp m32 from fpu reg stack */
void FSTP32(u32 to) {
      write8(0xD9);
      ModRM(0, 0x3, DISP32);
      write32(to); 
}

//

/* fldcw fpu control word from m16 */
void FLDCW(u32 from) {
      write8(0xD9);
      ModRM(0, 0x5, DISP32);
      write32(from); 
}

/* fnstcw fpu control word to m16 */
void FNSTCW(u32 to) {
      write8(0xD9);
      ModRM(0, 0x7, DISP32);
      write32(to); 
}

//

/* fadd m32 to fpu reg stack */
void FADD32(u32 from) {
      write8(0xD8);
      ModRM(0, 0x0, DISP32);
      write32(from); 
}

/* fsub m32 to fpu reg stack */
void FSUB32(u32 from) {
      write8(0xD8);
      ModRM(0, 0x4, DISP32);
      write32(from); 
}

/* fmul m32 to fpu reg stack */
void FMUL32(u32 from) {
      write8(0xD8);
      ModRM(0, 0x1, DISP32);
      write32(from); 
}

/* fdiv m32 to fpu reg stack */
void FDIV32(u32 from) {
      write8(0xD8);
      ModRM(0, 0x6, DISP32);
      write32(from); 
}

/* fabs fpu reg stack */
void FABS() {
      write16(0xE1D9);
}

/* fsqrt fpu reg stack */
void FSQRT() {
      write16(0xFAD9);
}

/* fchs fpu reg stack */
void FCHS() {
      write16(0xE0D9);
}

/********************/
/* MMX instructions */
/********************/

// r64 = mm

/* movq m64 to r64 */
void MOVQMtoR(int to, u32 from) {
      write16(0x6F0F);
      ModRM(0, to, DISP32);
      write32(from); 
}

/* movq r64 to m64 */
void MOVQRtoM(u32 to, int from) {
      write16(0x7F0F);
      ModRM(0, from, DISP32);
      write32(to); 
}

/* pand r64 to r64 */
void PANDRtoR(int to, int from) {
      write16(0xDB0F);
      ModRM(3, to, from); 
}

/* pand r64 to r64 */
void PANDNRtoR(int to, int from) {
      write16(0xDF0F);
      ModRM(3, to, from); 
}

/* por r64 to r64 */
void PORRtoR(int to, int from) {
      write16(0xEB0F);
      ModRM(3, to, from); 
}

/* pxor r64 to r64 */
void PXORRtoR(int to, int from) {
      write16(0xEF0F);
      ModRM(3, to, from); 
}

/* psllq r64 to r64 */
void PSLLQRtoR(int to, int from) {
      write16(0xF30F);
      ModRM(3, to, from); 
}

/* psllq m64 to r64 */
void PSLLQMtoR(int to, u32 from) {
      write16(0xF30F); 
      ModRM(0, to, DISP32); 
      write32(from);
}

/* psllq imm8 to r64 */
void PSLLQItoR(int to, u8 from) {
      write16(0x730F); 
      ModRM(3, 6, to); 
      write8(from); 
}

/* psrlq r64 to r64 */
void PSRLQRtoR(int to, int from) {
      write16(0xD30F); 
      ModRM(3, to, from); 
}

/* psrlq m64 to r64 */
void PSRLQMtoR(int to, u32 from) {
      write16(0xD30F); 
      ModRM(0, to, DISP32); 
      write32(from); 
}

/* psrlq imm8 to r64 */
void PSRLQItoR(int to, u8 from) {
      write16(0x730F);
      ModRM(3, 2, to); 
      write8(from); 
}

/* paddusb r64 to r64 */
void PADDUSBRtoR(int to, int from) {
      write16(0xDC0F); 
      ModRM(3, to, from); 
}

/* paddusb m64 to r64 */
void PADDUSBMtoR(int to, u32 from) {
      write16(0xDC0F); 
      ModRM(0, to, DISP32); 
      write32(from); 
}

/* paddusw r64 to r64 */
void PADDUSWRtoR(int to, int from) {
      write16(0xDD0F); 
      ModRM(3, to, from); 
}

/* paddusw m64 to r64 */
void PADDUSWMtoR(int to, u32 from) {
      write16(0xDD0F); 
      ModRM(0, to, DISP32); 
      write32(from); 
}

/* paddb r64 to r64 */
void PADDBRtoR(int to, int from) {
      write16(0xFC0F); 
      ModRM(3, to, from); 
}

/* paddb m64 to r64 */
void PADDBMtoR(int to, u32 from) {
      write16(0xFC0F); 
      ModRM(0, to, DISP32); 
      write32(from); 
}

/* paddw r64 to r64 */
void PADDWRtoR(int to, int from) {
      write16(0xFD0F); 
      ModRM(3, to, from); 
}

/* paddw m64 to r64 */
void PADDWMtoR(int to, u32 from) {
      write16(0xFD0F); 
      ModRM(0, to, DISP32); 
      write32(from); 
}

/* paddd r64 to r64 */
void PADDDRtoR(int to, int from) {
      write16(0xFE0F); 
      ModRM(3, to, from); 
}

/* paddd m64 to r64 */
void PADDDMtoR(int to, u32 from) {
      write16(0xFE0F); 
      ModRM(0, to, DISP32); 
      write32(from); 
}

/* emms */
void EMMS() {
      //use femms if we have 3dnow
      write16(0x0e0f);
      return;
}

/* femms */
void FEMMS() {
      write16(0x770F);
      return;
}

//Basara:changed
void PADDSBRtoR(int to, int from) {
      write16(0xEC0F); 
      ModRM(3, to, from); 
}

void PADDSWRtoR(int to, int from) {
      write16(0xED0F);
      ModRM(3, to, from); 
}

void PADDSDRtoR(int to, int from) {
      write16(0xEE0F); 
      ModRM(3, to, from); 
}

void PSUBSBRtoR(int to, int from) {
      write16(0xE80F); 
      ModRM(3, to, from); 
}

void PSUBSWRtoR(int to, int from) {
      write16(0xE90F);
      ModRM(3, to, from); 
}

void PSUBSDRtoR(int to, int from) {
      write16(0xEA0F); 
      ModRM(3, to, from); 
}

void PSUBBRtoR(int to, int from) {
      write16(0xF80F); 
      ModRM(3, to, from); 
}

void PSUBWRtoR(int to, int from) {
      write16(0xF90F); 
      ModRM(3, to, from); 
}

void PSUBDRtoR(int to, int from) {
      write16(0xFA0F); 
      ModRM(3, to, from); 
}

//changed:basara
//P.s.It's sux.Don't use it offten.
void MOVQ64ItoR(int reg,u64 i)
{
      MOVQMtoR(reg,(u32)(x86Ptr)+2+7);
      JMP8(8);
      write64(i);
}

void PSUBUSBRtoR(int to, int from) {
      write16(0xD80F); 
      ModRM(3, to, from); 
}

void PSUBUSWRtoR(int to, int from) {
      write16(0xD90F); 
      ModRM(3, to, from); 
}

void PMAXSWRtoR(int to,int from)
{
      write16(0xEE0F); 
      ModRM(3, to, from); 
}

void PMINSWRtoR(int to,int from)
{
      write16(0xEA0F); 
      ModRM(3, to, from); 
}

void PCMPEQBRtoR(int to,int from)
{
      write16(0x740F); 
      ModRM(3, to, from); 
}

void PCMPEQWRtoR(int to,int from)
{
      write16(0x750F); 
      ModRM(3, to, from); 
}

void PCMPEQDRtoR(int to,int from)
{
      write16(0x760F); 
      ModRM(3, to, from); 
}

void PCMPGTBRtoR(int to,int from)
{
      write16(0x640F); 
      ModRM(3, to, from); 
}

void PCMPGTWRtoR(int to,int from)
{
      write16(0x650F); 
      ModRM(3, to, from); 
}

void PCMPGTDRtoR(int to,int from)
{
      write16(0x660F); 
      ModRM(3, to, from); 
}

//Basara:Added 10.01.2003
void PSRLWItoR(int to,int from)
{
      write16(0x710f);
      ModRM(2, 2 , to); 
      write8(from);
}
void PSRLDItoR(int to,int from)
{
      write16(0x720f);
      ModRM(2, 2 , to); 
      write8(from);
}

void PSLLWItoR(int to,int from)
{
      write16(0x710f);
      ModRM(3, 6 , to); 
      write8(from);
}

void PSLLDItoR(int to,int from)
{
      write16(0x720f);
      ModRM(3, 6 , to); 
      write8(from);
}

void PSRAWItoR(int to,int from)
{
      write16(0x710f);
      ModRM(3, 4 , to); 
      write8(from);
}

void PSRADItoR(int to,int from)
{
      write16(0x720f);
      ModRM(3, 4 , to); 
      write8(from);
}

/* por m64 to r64 */
void PORMtoR(int to, u32 from) {
      write16(0xEB0F);
      ModRM(0, to, DISP32); 
      write32(from);
}

/* pxor m64 to r64 */
void PXORMtoR(int to, u32 from) {
      write16(0xEF0F);
      ModRM(0, to, DISP32); 
      write32(from);
}

/* pand m64 to r64 */
void PANDMtoR(int to, u32 from) {
      write16(0xDB0F);
      ModRM(0, to, DISP32); 
      write32(from);
}

/* pandn m64 to r64 */
void PANDNMtoR(int to, u32 from) {
      write16(0xDF0F);
      ModRM(0, to, DISP32); 
      write32(from);
}

/* movd m32 to r64 */
void MOVDMtoR(int to, u32 from) {
      write16(0x6E0F);
      ModRM(0, to, DISP32);
      write32(from); 
}

/* movq r64 to m32 */
void MOVDRtoM(u32 to, int from) {
      write16(0x7E0F);
      ModRM(0, from, DISP32);
      write32(to); 
}

/* movd r32 to r64 */
void MOVD32RtoR(int to, int from) {
      write16(0x6E0F);
      ModRM(3, to,from);
}

/* movq r64 to r32 */
void MOVD64RtoR(int to, int from) {
      write16(0x7E0F);
      ModRM(3, from,to);
}

void MOVQRtoR(int to,int from)
{
      write16(0x6F0F);
      ModRM(3, to,from);
}

void PUNPCKHDQRtoR(int to,int from)
{
      write16(0x6A0F);
      ModRM(3, to,from);
}

void PUNPCKLDQRtoR(int to,int from)
{
      write16(0x620F);
      ModRM(3, to,from);
}

//////////////////////////////////////////////////////////////////////////
//    SSE   intructions 
//////////////////////////////////////////////////////////////////////////

void MOVAPSMtoR(int to,int from)
{
      write16(0x280f);
      ModRM(0, to, DISP32);
      write32(from);
}

void MOVAPSRtoM(int to,int from)
{
      write16(0x2b0f);
      ModRM(0, from, DISP32);
      write32(to);
}

void MOVAPSRtoR(int to,int from)
{
      write16(0x290f);
      ModRM(3, to,from);
}

void ORPSMtoR(int to,int from)
{
      write16(0x560f);
      ModRM(0, to, DISP32);
      write32(from);
}

void ORPSRtoR(int to,int from)
{
      write16(0x560f);
      ModRM(3, to,from);
}

void XORPSMtoR(int to,int from)
{
      write16(0x570f);
      ModRM(0, to, DISP32);
      write32(from);
}

void XORPSRtoR(int to,int from)
{
      write16(0x570f);
      ModRM(3, to,from);
}

void ANDPSMtoR(int to,int from)
{
      write16(0x540f);
      ModRM(0, to, DISP32);
      write32(from);
}

void ANDPSRtoR(int to,int from)
{
      write16(0x540f);
      ModRM(3, to,from);
}

/*
      3DNOW intructions 
*/

void PFCMPEQMtoR(int to,int from)
{
      write16(0x0f0f);
      ModRM(0, to, DISP32); 
      write32(from); 
      write8(0xb0);
}

void PFCMPGTMtoR(int to,int from)
{
      write16(0x0f0f);
      ModRM(0, to, DISP32); 
      write32(from); 
      write8(0xa0);
}

void PFCMPGEMtoR(int to,int from)
{
      write16(0x0f0f);
      ModRM(0, to, DISP32); 
      write32(from); 
      write8(0x90);
}


void PFADDMtoR(int to,int from)
{
      write16(0x0f0f);
      ModRM(0, to, DISP32); 
      write32(from); 
      write8(0x9e);
}

void PFADDRtoR(int to,int from)
{
      write16(0x0f0f);
      ModRM(3, to, from);
      write8(0x9e);
}


void PFSUBMtoR(int to,int from)
{
      write16(0x0f0f);
      ModRM(0, to, DISP32); 
      write32(from); 
      write8(0x9a);
}

void PFSUBRtoR(int to,int from)
{
      write16(0x0f0f);
      ModRM(3, to, from); 
      write8(0x9a);
}


void PFMULMtoR(int to,int from)
{
      write16(0x0f0f);
      ModRM(0, to, DISP32); 
      write32(from); 
      write8(0xb4);
}

void PFMULRtoR(int to,int from)
{
      write16(0x0f0f);
      ModRM(3, to,from); 
      write8(0xb4);
}

void PFRCPMtoR(int to,int from)
{
      write16(0x0f0f);
      ModRM(0, to, DISP32); 
      write32(from); 
      write8(0x96);
}

void PFRCPRtoR(int to,int from)
{
      write16(0x0f0f);
      ModRM(3, to,from); 
      write8(0x96);
}

void PFRCPIT1RtoR(int to,int from)
{
      write16(0x0f0f);
      ModRM(3, to,from); 
      write8(0xa6);
}

void PFRCPIT2RtoR(int to,int from)
{
      write16(0x0f0f);
      ModRM(3, to,from); 
      write8(0xb6);
}

void PFRSQRTRtoR(int to,int from)
{
      write16(0x0f0f);
      ModRM(3, to,from); 
      write8(0x97);
}

void PFRSQIT1RtoR(int to,int from)
{
      write16(0x0f0f);
      ModRM(3, to,from); 
      write8(0xa7);
}

void PF2IDMtoR(int to,int from)
{
      write16(0x0f0f);
      ModRM(0, to, DISP32); 
      write32(from); 
      write8(0x1d);
}

void PF2IDRtoR(int to,int from)
{
      write16(0x0f0f);
      ModRM(3, to, from); 
      write8(0x1d);
}

void PI2FDMtoR(int to,int from)
{
      write16(0x0f0f);
      ModRM(0, to, DISP32); 
      write32(from); 
      write8(0x0d);
}

void PI2FDRtoR(int to,int from)
{
      write16(0x0f0f);
      ModRM(3, to, from); 
      write8(0x0d);
}


/*
      3DNOW Extension intructions 
*/

void PFMAXMtoR(int to,int from)
{
      write16(0x0f0f);
      ModRM(0, to, DISP32); 
      write32(from); 
      write8(0xa4);
}

void PFMAXRtoR(int to,int from)
{
      write16(0x0f0f);
      ModRM(3, to, from); 
      write8(0xa4);
}

void PFMINMtoR(int to,int from)
{
      write16(0x0f0f);
      ModRM(0, to, DISP32); 
      write32(from); 
      write8(0x94);
}

void PFMINRtoR(int to,int from)
{
      write16(0x0f0f);
      ModRM(3, to, from);
      write8(0x94);
}




Generated by  Doxygen 1.6.0   Back to index