diff options
Diffstat (limited to 'libpcsxcore/ix86/ix86.c')
-rw-r--r-- | libpcsxcore/ix86/ix86.c | 1723 |
1 files changed, 1723 insertions, 0 deletions
diff --git a/libpcsxcore/ix86/ix86.c b/libpcsxcore/ix86/ix86.c new file mode 100644 index 0000000..d701e89 --- /dev/null +++ b/libpcsxcore/ix86/ix86.c @@ -0,0 +1,1723 @@ +/*************************************************************************** + * 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 02111-1307 USA. * + ***************************************************************************/ + +/* + * ix86 core v0.5.1 + * Authors: linuzappz <linuzappz@pcsx.net> + * alexey silinov + */ + +#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); +} |