aboutsummaryrefslogtreecommitdiff
path: root/libpcsxcore/ix86/ix86.c
diff options
context:
space:
mode:
Diffstat (limited to 'libpcsxcore/ix86/ix86.c')
-rw-r--r--libpcsxcore/ix86/ix86.c1723
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);
+}