1728 lines
27 KiB
C
1728 lines
27 KiB
C
/***************************************************************************
|
|
* Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
|
|
***************************************************************************/
|
|
|
|
/*
|
|
* ix86 core v0.5.1
|
|
* Authors: linuzappz <linuzappz@pcsx.net>
|
|
* alexey silinov
|
|
*/
|
|
|
|
#ifdef __i386__
|
|
|
|
#include "ix86.h"
|
|
|
|
s8 *x86Ptr;
|
|
u8 *j8Ptr[32];
|
|
u32 *j32Ptr[32];
|
|
|
|
void x86Init() {
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
#endif
|