1 /***************************************************************************
2 * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. *
18 ***************************************************************************/
22 * Authors: linuzappz <linuzappz@pcsx.net>
35 void x86SetPtr(char *ptr) {
42 void x86SetJ8(u8 *j8) {
43 u32 jump = (x86Ptr - (s8*)j8) - 1;
45 if (jump > 0x7f) printf("j8 greater than 0x7f!!\n");
49 void x86SetJ32(u32 *j32) {
50 *j32 = (x86Ptr - (s8*)j32) - 4;
53 void x86Align(int bytes) {
55 x86Ptr = (s8*)(((u32)x86Ptr + bytes) & ~(bytes - 1));
63 #define ModRM(mod, rm, reg) \
64 write8((mod << 6) | (rm << 3) | (reg));
66 #define SibSB(ss, rm, index) \
67 write8((ss << 6) | (rm << 3) | (index));
69 #define SET8R(cc, to) { \
70 write8(0x0F); write8(cc); \
71 write8((0xC0) | (to)); }
73 #define J8Rel(cc, to) { \
74 write8(cc); write8(to); return x86Ptr - 1; }
76 #define J32Rel(cc, to) { \
77 write8(0x0F); write8(cc); write32(to); return (u32*)(x86Ptr - 4); }
79 #define CMOV32RtoR(cc, to, from) { \
80 write8(0x0F); write8(cc); \
83 #define CMOV32MtoR(cc, to, from) { \
84 write8(0x0F); write8(cc); \
85 ModRM(0, to, DISP32); \
88 /********************/
89 /* IX86 intructions */
90 /********************/
95 void MOV32RtoR(int to, int from) {
101 void MOV32RtoM(u32 to, int from) {
103 ModRM(0, from, DISP32);
108 void MOV32MtoR(int to, u32 from) {
110 ModRM(0, to, DISP32);
114 /* mov [r32] to r32 */
115 void MOV32RmtoR(int to, int from) {
120 /* mov [r32][r32*scale] to r32 */
121 void MOV32RmStoR(int to, int from, int from2, int scale) {
124 SibSB(scale, from2, from);
127 /* mov r32 to [r32] */
128 void MOV32RtoRm(int to, int from) {
133 /* mov r32 to [r32][r32*scale] */
134 void MOV32RtoRmS(int to, int to2, int scale, int from) {
137 SibSB(scale, to2, to);
140 /* mov imm32 to r32 */
141 void MOV32ItoR(int to, u32 from) {
146 /* mov imm32 to m32 */
147 void MOV32ItoM(u32 to, u32 from) {
155 void MOV16RtoM(u32 to, int from) {
158 ModRM(0, from, DISP32);
163 void MOV16MtoR(int to, u32 from) {
166 ModRM(0, to, DISP32);
170 /* mov imm16 to m16 */
171 void MOV16ItoM(u32 to, u16 from) {
180 void MOV8RtoM(u32 to, int from) {
182 ModRM(0, from, DISP32);
187 void MOV8MtoR(int to, u32 from) {
189 ModRM(0, to, DISP32);
194 void MOV8ItoM(u32 to, u8 from) {
201 /* movsx r8 to r32 */
202 void MOVSX32R8toR(int to, int from) {
207 /* movsx m8 to r32 */
208 void MOVSX32M8toR(int to, u32 from) {
210 ModRM(0, to, DISP32);
214 /* movsx r16 to r32 */
215 void MOVSX32R16toR(int to, int from) {
220 /* movsx m16 to r32 */
221 void MOVSX32M16toR(int to, u32 from) {
223 ModRM(0, to, DISP32);
227 /* movzx r8 to r32 */
228 void MOVZX32R8toR(int to, int from) {
233 /* movzx m8 to r32 */
234 void MOVZX32M8toR(int to, u32 from) {
236 ModRM(0, to, DISP32);
240 /* movzx r16 to r32 */
241 void MOVZX32R16toR(int to, int from) {
246 /* movzx m16 to r32 */
247 void MOVZX32M16toR(int to, u32 from) {
249 ModRM(0, to, DISP32);
253 /* cmovne r32 to r32 */
254 void CMOVNE32RtoR(int to, int from) {
255 CMOV32RtoR(0x45, to, from);
258 /* cmovne m32 to r32*/
259 void CMOVNE32MtoR(int to, u32 from) {
260 CMOV32MtoR(0x45, to, from);
263 /* cmove r32 to r32*/
264 void CMOVE32RtoR(int to, int from) {
265 CMOV32RtoR(0x44, to, from);
268 /* cmove m32 to r32*/
269 void CMOVE32MtoR(int to, u32 from) {
270 CMOV32MtoR(0x44, to, from);
273 /* cmovg r32 to r32*/
274 void CMOVG32RtoR(int to, int from) {
275 CMOV32RtoR(0x4F, to, from);
278 /* cmovg m32 to r32*/
279 void CMOVG32MtoR(int to, u32 from) {
280 CMOV32MtoR(0x4F, to, from);
283 /* cmovge r32 to r32*/
284 void CMOVGE32RtoR(int to, int from) {
285 CMOV32RtoR(0x4D, to, from);
288 /* cmovge m32 to r32*/
289 void CMOVGE32MtoR(int to, u32 from) {
290 CMOV32MtoR(0x4D, to, from);
293 /* cmovl r32 to r32*/
294 void CMOVL32RtoR(int to, int from) {
295 CMOV32RtoR(0x4C, to, from);
298 /* cmovl m32 to r32*/
299 void CMOVL32MtoR(int to, u32 from) {
300 CMOV32MtoR(0x4C, to, from);
303 /* cmovle r32 to r32*/
304 void CMOVLE32RtoR(int to, int from) {
305 CMOV32RtoR(0x4E, to, from);
308 /* cmovle m32 to r32*/
309 void CMOVLE32MtoR(int to, u32 from) {
310 CMOV32MtoR(0x4E, to, from);
313 // arithmic instructions
315 /* add imm32 to r32 */
316 void ADD32ItoR(int to, u32 from) {
326 /* add imm32 to m32 */
327 void ADD32ItoM(u32 to, u32 from) {
335 void ADD32RtoR(int to, int from) {
341 void ADD32RtoM(u32 to, int from) {
343 ModRM(0, from, DISP32);
348 void ADD32MtoR(int to, u32 from) {
350 ModRM(0, to, DISP32);
354 /* adc imm32 to r32 */
355 void ADC32ItoR(int to, u32 from) {
366 void ADC32RtoR(int to, int from) {
372 void ADC32MtoR(int to, u32 from) {
374 ModRM(0, to, DISP32);
379 void INC32R(int to) {
384 void INC32M(u32 to) {
390 /* sub imm32 to r32 */
391 void SUB32ItoR(int to, u32 from) {
402 void SUB32RtoR(int to, int from) {
408 void SUB32MtoR(int to, u32 from) {
410 ModRM(0, to, DISP32);
414 /* sbb imm32 to r32 */
415 void SBB32ItoR(int to, u32 from) {
426 void SBB32RtoR(int to, int from) {
432 void SBB32MtoR(int to, u32 from) {
434 ModRM(0, to, DISP32);
439 void DEC32R(int to) {
444 void DEC32M(u32 to) {
450 /* mul eax by r32 to edx:eax */
451 void MUL32R(int from) {
456 /* imul eax by r32 to edx:eax */
457 void IMUL32R(int from) {
462 /* mul eax by m32 to edx:eax */
463 void MUL32M(u32 from) {
469 /* imul eax by m32 to edx:eax */
470 void IMUL32M(u32 from) {
476 /* imul r32 by r32 to r32 */
477 void IMUL32RtoR(int to, int from) {
482 /* div eax by r32 to edx:eax */
483 void DIV32R(int from) {
488 /* idiv eax by r32 to edx:eax */
489 void IDIV32R(int from) {
494 /* div eax by m32 to edx:eax */
495 void DIV32M(u32 from) {
501 /* idiv eax by m32 to edx:eax */
502 void IDIV32M(u32 from) {
508 // shifting instructions
510 void RCR32ItoR(int to,int from)
525 /* shl imm8 to r32 */
526 void SHL32ItoR(int to, u8 from) {
539 void SHL32CLtoR(int to) {
544 /* shr imm8 to r32 */
545 void SHR32ItoR(int to, u8 from) {
558 void SHR32CLtoR(int to) {
563 /* sar imm8 to r32 */
564 void SAR32ItoR(int to, u8 from) {
571 void SAR32CLtoR(int to) {
577 // logical instructions
579 /* or imm32 to r32 */
580 void OR32ItoR(int to, u32 from) {
590 /* or imm32 to m32 */
591 void OR32ItoM(u32 to, u32 from) {
599 void OR32RtoR(int to, int from) {
605 void OR32RtoM(u32 to, int from) {
607 ModRM(0, from, DISP32);
612 void OR32MtoR(int to, u32 from) {
614 ModRM(0, to, DISP32);
618 /* xor imm32 to r32 */
619 void XOR32ItoR(int to, u32 from) {
629 /* xor imm32 to m32 */
630 void XOR32ItoM(u32 to, u32 from) {
638 void XOR32RtoR(int to, int from) {
644 void XOR32RtoM(u32 to, int from) {
646 ModRM(0, from, DISP32);
651 void XOR32MtoR(int to, u32 from) {
653 ModRM(0, to, DISP32);
657 /* and imm32 to r32 */
658 void AND32ItoR(int to, u32 from) {
668 /* and imm32 to m32 */
669 void AND32ItoM(u32 to, u32 from) {
671 ModRM(0, 0x4, DISP32);
677 void AND32RtoR(int to, int from) {
683 void AND32RtoM(u32 to, int from) {
685 ModRM(0, from, DISP32);
690 void AND32MtoR(int to, u32 from) {
692 ModRM(0, to, DISP32);
697 void NOT32R(int from) {
703 void NEG32R(int from) {
721 return (u32*)(x86Ptr - 4);
725 void JMP32R(int to) {
846 u32* JNGE32(u32 to) {
856 u32* JNLE32(u32 to) {
871 void CALLFunc(u32 func) {
872 CALL32(func - ((u32)x86Ptr + 5));
876 void CALL32(u32 to) {
882 void CALL32R(int to) {
888 void CALL32M(u32 to) {
896 /* cmp imm32 to r32 */
897 void CMP32ItoR(int to, u32 from) {
907 /* cmp imm32 to m32 */
908 void CMP32ItoM(u32 to, u32 from) {
916 void CMP32RtoR(int to, int from) {
922 void CMP32MtoR(int to, u32 from) {
924 ModRM(0, to, DISP32);
928 /* test imm32 to r32 */
929 void TEST32ItoR(int to, u32 from) {
939 /* test r32 to r32 */
940 void TEST32RtoR(int to, int from) {
945 void BT32ItoR(int to,int from)
953 void SETS8R(int to) {
957 void SETL8R(int to) {
962 void SETB8R(int to) {
967 void SETNZ8R(int to) {
987 void PUSH32R(int from) {
992 void PUSH32M(u32 from) {
999 void PUSH32I(u32 from) {
1000 write8(0x68); write32(from);
1004 void POP32R(int from) {
1005 write8(0x58 | from);
1023 /********************/
1024 /* FPU instructions */
1025 /********************/
1027 //Added:basara 14.01.2003
1028 /* compare m32 to fpu reg stack */
1029 void FCOMP32(u32 from) {
1031 ModRM(0, 0x3, DISP32);
1039 /* fild m32 to fpu reg stack */
1040 void FILD32(u32 from) {
1042 ModRM(0, 0x0, DISP32);
1046 /* fistp m32 from fpu reg stack */
1047 void FISTP32(u32 from) {
1049 ModRM(0, 0x3, DISP32);
1053 /* fld m32 to fpu reg stack */
1054 void FLD32(u32 from) {
1056 ModRM(0, 0x0, DISP32);
1060 /* fstp m32 from fpu reg stack */
1061 void FSTP32(u32 to) {
1063 ModRM(0, 0x3, DISP32);
1069 /* fldcw fpu control word from m16 */
1070 void FLDCW(u32 from) {
1072 ModRM(0, 0x5, DISP32);
1076 /* fnstcw fpu control word to m16 */
1077 void FNSTCW(u32 to) {
1079 ModRM(0, 0x7, DISP32);
1085 /* fadd m32 to fpu reg stack */
1086 void FADD32(u32 from) {
1088 ModRM(0, 0x0, DISP32);
1092 /* fsub m32 to fpu reg stack */
1093 void FSUB32(u32 from) {
1095 ModRM(0, 0x4, DISP32);
1099 /* fmul m32 to fpu reg stack */
1100 void FMUL32(u32 from) {
1102 ModRM(0, 0x1, DISP32);
1106 /* fdiv m32 to fpu reg stack */
1107 void FDIV32(u32 from) {
1109 ModRM(0, 0x6, DISP32);
1113 /* fabs fpu reg stack */
1118 /* fsqrt fpu reg stack */
1123 /* fchs fpu reg stack */
1128 /********************/
1129 /* MMX instructions */
1130 /********************/
1134 /* movq m64 to r64 */
1135 void MOVQMtoR(int to, u32 from) {
1137 ModRM(0, to, DISP32);
1141 /* movq r64 to m64 */
1142 void MOVQRtoM(u32 to, int from) {
1144 ModRM(0, from, DISP32);
1148 /* pand r64 to r64 */
1149 void PANDRtoR(int to, int from) {
1154 /* pand r64 to r64 */
1155 void PANDNRtoR(int to, int from) {
1160 /* por r64 to r64 */
1161 void PORRtoR(int to, int from) {
1166 /* pxor r64 to r64 */
1167 void PXORRtoR(int to, int from) {
1172 /* psllq r64 to r64 */
1173 void PSLLQRtoR(int to, int from) {
1178 /* psllq m64 to r64 */
1179 void PSLLQMtoR(int to, u32 from) {
1181 ModRM(0, to, DISP32);
1185 /* psllq imm8 to r64 */
1186 void PSLLQItoR(int to, u8 from) {
1192 /* psrlq r64 to r64 */
1193 void PSRLQRtoR(int to, int from) {
1198 /* psrlq m64 to r64 */
1199 void PSRLQMtoR(int to, u32 from) {
1201 ModRM(0, to, DISP32);
1205 /* psrlq imm8 to r64 */
1206 void PSRLQItoR(int to, u8 from) {
1212 /* paddusb r64 to r64 */
1213 void PADDUSBRtoR(int to, int from) {
1218 /* paddusb m64 to r64 */
1219 void PADDUSBMtoR(int to, u32 from) {
1221 ModRM(0, to, DISP32);
1225 /* paddusw r64 to r64 */
1226 void PADDUSWRtoR(int to, int from) {
1231 /* paddusw m64 to r64 */
1232 void PADDUSWMtoR(int to, u32 from) {
1234 ModRM(0, to, DISP32);
1238 /* paddb r64 to r64 */
1239 void PADDBRtoR(int to, int from) {
1244 /* paddb m64 to r64 */
1245 void PADDBMtoR(int to, u32 from) {
1247 ModRM(0, to, DISP32);
1251 /* paddw r64 to r64 */
1252 void PADDWRtoR(int to, int from) {
1257 /* paddw m64 to r64 */
1258 void PADDWMtoR(int to, u32 from) {
1260 ModRM(0, to, DISP32);
1264 /* paddd r64 to r64 */
1265 void PADDDRtoR(int to, int from) {
1270 /* paddd m64 to r64 */
1271 void PADDDMtoR(int to, u32 from) {
1273 ModRM(0, to, DISP32);
1279 //use femms if we have 3dnow
1291 void PADDSBRtoR(int to, int from) {
1296 void PADDSWRtoR(int to, int from) {
1301 void PADDSDRtoR(int to, int from) {
1306 void PSUBSBRtoR(int to, int from) {
1311 void PSUBSWRtoR(int to, int from) {
1316 void PSUBSDRtoR(int to, int from) {
1321 void PSUBBRtoR(int to, int from) {
1326 void PSUBWRtoR(int to, int from) {
1331 void PSUBDRtoR(int to, int from) {
1337 //P.s.It's sux.Don't use it offten.
1338 void MOVQ64ItoR(int reg,u64 i)
1340 MOVQMtoR(reg,(u32)(x86Ptr)+2+7);
1345 void PSUBUSBRtoR(int to, int from) {
1350 void PSUBUSWRtoR(int to, int from) {
1355 void PMAXSWRtoR(int to,int from)
1361 void PMINSWRtoR(int to,int from)
1367 void PCMPEQBRtoR(int to,int from)
1373 void PCMPEQWRtoR(int to,int from)
1379 void PCMPEQDRtoR(int to,int from)
1385 void PCMPGTBRtoR(int to,int from)
1391 void PCMPGTWRtoR(int to,int from)
1397 void PCMPGTDRtoR(int to,int from)
1403 //Basara:Added 10.01.2003
1404 void PSRLWItoR(int to,int from)
1410 void PSRLDItoR(int to,int from)
1417 void PSLLWItoR(int to,int from)
1424 void PSLLDItoR(int to,int from)
1431 void PSRAWItoR(int to,int from)
1438 void PSRADItoR(int to,int from)
1445 /* por m64 to r64 */
1446 void PORMtoR(int to, u32 from) {
1448 ModRM(0, to, DISP32);
1452 /* pxor m64 to r64 */
1453 void PXORMtoR(int to, u32 from) {
1455 ModRM(0, to, DISP32);
1459 /* pand m64 to r64 */
1460 void PANDMtoR(int to, u32 from) {
1462 ModRM(0, to, DISP32);
1466 /* pandn m64 to r64 */
1467 void PANDNMtoR(int to, u32 from) {
1469 ModRM(0, to, DISP32);
1473 /* movd m32 to r64 */
1474 void MOVDMtoR(int to, u32 from) {
1476 ModRM(0, to, DISP32);
1480 /* movq r64 to m32 */
1481 void MOVDRtoM(u32 to, int from) {
1483 ModRM(0, from, DISP32);
1487 /* movd r32 to r64 */
1488 void MOVD32RtoR(int to, int from) {
1493 /* movq r64 to r32 */
1494 void MOVD64RtoR(int to, int from) {
1499 void MOVQRtoR(int to, int from) {
1504 void PUNPCKHDQRtoR(int to, int from) {
1509 void PUNPCKLDQRtoR(int to, int from) {
1514 //////////////////////////////////////////////////////////////////////////
1516 //////////////////////////////////////////////////////////////////////////
1518 void MOVAPSMtoR(int to, int from) {
1520 ModRM(0, to, DISP32);
1524 void MOVAPSRtoM(int to, int from) {
1526 ModRM(0, from, DISP32);
1530 void MOVAPSRtoR(int to, int from) {
1535 void ORPSMtoR(int to, int from) {
1537 ModRM(0, to, DISP32);
1541 void ORPSRtoR(int to, int from) {
1546 void XORPSMtoR(int to, int from) {
1548 ModRM(0, to, DISP32);
1552 void XORPSRtoR(int to, int from) {
1557 void ANDPSMtoR(int to, int from) {
1559 ModRM(0, to, DISP32);
1563 void ANDPSRtoR(int to, int from) {
1572 void PFCMPEQMtoR(int to, int from) {
1574 ModRM(0, to, DISP32);
1579 void PFCMPGTMtoR(int to, int from) {
1581 ModRM(0, to, DISP32);
1586 void PFCMPGEMtoR(int to, int from) {
1588 ModRM(0, to, DISP32);
1593 void PFADDMtoR(int to, int from) {
1595 ModRM(0, to, DISP32);
1600 void PFADDRtoR(int to, int from) {
1606 void PFSUBMtoR(int to, int from) {
1608 ModRM(0, to, DISP32);
1613 void PFSUBRtoR(int to, int from) {
1619 void PFMULMtoR(int to, int from) {
1621 ModRM(0, to, DISP32);
1626 void PFMULRtoR(int to, int from) {
1632 void PFRCPMtoR(int to, int from) {
1634 ModRM(0, to, DISP32);
1639 void PFRCPRtoR(int to, int from) {
1645 void PFRCPIT1RtoR(int to, int from) {
1651 void PFRCPIT2RtoR(int to, int from) {
1657 void PFRSQRTRtoR(int to, int from) {
1663 void PFRSQIT1RtoR(int to, int from) {
1669 void PF2IDMtoR(int to, int from) {
1671 ModRM(0, to, DISP32);
1676 void PF2IDRtoR(int to, int from) {
1682 void PI2FDMtoR(int to, int from) {
1684 ModRM(0, to, DISP32);
1689 void PI2FDRtoR(int to, int from) {
1696 3DNOW Extension intructions
1699 void PFMAXMtoR(int to, int from) {
1701 ModRM(0, to, DISP32);
1706 void PFMAXRtoR(int to, int from) {
1712 void PFMINMtoR(int to, int from) {
1714 ModRM(0, to, DISP32);
1719 void PFMINRtoR(int to, int from) {