3 * Authors: linuzappz <linuzappz@pcsx.net>
9 // stop compiling if NORECBUILD build (only for Visual Studio)
10 #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD))
20 // visual studio calling convention
21 x86IntRegType g_x86savedregs[] = { RBX, RBP, RSI, RDI, R12, R13, R14, R15 };
22 x86IntRegType g_x86tempregs[] = { R8, R9, R10, R11, RDX, RCX };
24 // arranged in savedreg -> tempreg order
25 x86IntRegType g_x86allregs[14] = { RBX, RBP, RSI, RDI, R12, R13, R14, R15, R8, R9, R10, R11, RDX, RCX };
28 // standard calling convention
30 // registers saved by called functions (no need to flush them across calls)
31 x86IntRegType g_x86savedregs[] = { RBX, RBP, R12, R13, R14, R15 };
32 // temp registers that need to be saved across calls
33 x86IntRegType g_x86tempregs[] = { RCX, RDX, R8, R9, R10, R11, RSI, RDI };
35 // arranged in savedreg -> tempreg order
36 x86IntRegType g_x86allregs[14] = { RBX, RBP, R12, R13, R14, R15, RCX, RDX, R8, R9, R10, R11, RSI, RDI };
40 x86IntRegType g_x868bitregs[11] = { RBX, R12, R13, R14, R15, RCX, RDX, R8, R9, R10, R11 };
41 x86IntRegType g_x86non8bitregs[3] = { RBP, RSI, RDI };
49 void WriteRmOffset(x86IntRegType to, int offset)
56 else if( offset < 128 && offset >= -128 ) {
71 else if( offset < 128 && offset >= -128 ) {
82 void WriteRmOffsetFrom(x86IntRegType to, x86IntRegType from, int offset)
84 if ((from&7) == ESP) {
89 else if( offset < 128 && offset >= -128 ) {
102 ModRM( 0, to, from );
104 else if( offset < 128 && offset >= -128 ) {
105 ModRM( 1, to, from );
109 ModRM( 2, to, from );
115 // This function is just for rec debugging purposes
116 void CheckX86Ptr( void )
120 void writeVAROP(unsigned opl, u64 op)
129 #define writeVARROP(REX, opl, op) ({ \
130 if (opl > 1 && ((op & 0xFF) == 0x66 || (op & 0xFF) == 0xF3 || (op & 0xFF) == 0xF2)) { \
136 writeVAROP(opl, op); \
139 void MEMADDR_OP(bool w, unsigned opl, u64 op, bool isreg, int reg, uptr p, sptr off)
142 sptr pr = MEMADDR_(p, 5 + opl + (w || reg >= 8) + off);
145 writeVARROP(RexR(w, reg), opl, op);
146 ModRM(0, reg, DISP32);
151 writeVARROP(RexR(w, reg), opl, op);
153 SibSB(0, SIB, DISP32);
158 assert(!isreg || reg != X86_TEMP);
159 MOV64ItoR(X86_TEMP, p);
160 writeVARROP(RexRB(w, reg, X86_TEMP), opl, op);
161 ModRM(0, reg, X86_TEMP);
164 writeVARROP(RexR(w, reg), opl, op);
165 ModRM(0, reg, DISP32);
170 void SET8R( int cc, int to )
175 write8( 0xC0 | ( to ) );
178 u8* J8Rel( int cc, int to )
185 u16* J16Rel( int cc, u32 to )
190 return (u16*)( x86Ptr - 2 );
193 u32* J32Rel( int cc, u32 to )
198 return (u32*)( x86Ptr - 4 );
201 void CMOV32RtoR( int cc, int to, int from )
206 ModRM( 3, to, from );
209 void CMOV32MtoR( int cc, x86IntRegType to, uptr from )
211 MEMADDR_OP(0, VAROP2(0x0F, cc), true, to, from, 0);
214 ////////////////////////////////////////////////////
215 void x86SetPtr( char* ptr )
220 ////////////////////////////////////////////////////
221 void x86Shutdown( void )
225 ////////////////////////////////////////////////////
226 void x86SetJ8( u8* j8 )
228 u32 jump = ( x86Ptr - (s8*)j8 ) - 1;
232 SysPrintf( "j8 greater than 0x7f!!\n" );
237 void x86SetJ8A( u8* j8 )
239 u32 jump = ( x86Ptr - (s8*)j8 ) - 1;
243 SysPrintf( "j8 greater than 0x7f!!\n" );
246 if( ((uptr)x86Ptr&0xf) > 4 ) {
248 uptr newjump = jump + 16-((uptr)x86Ptr&0xf);
250 if( newjump <= 0x7f ) {
252 while((uptr)x86Ptr&0xf) *x86Ptr++ = 0x90;
258 void x86SetJ16( u16 *j16 )
261 u32 jump = ( x86Ptr - (s8*)j16 ) - 2;
263 if ( jump > 0x7fff ) {
265 SysPrintf( "j16 greater than 0x7fff!!\n" );
270 void x86SetJ16A( u16 *j16 )
272 if( ((uptr)x86Ptr&0xf) > 4 ) {
273 while((uptr)x86Ptr&0xf) *x86Ptr++ = 0x90;
278 ////////////////////////////////////////////////////
279 void x86SetJ32( u32* j32 )
281 *j32 = ( x86Ptr - (s8*)j32 ) - 4;
284 void x86SetJ32A( u32* j32 )
286 while((uptr)x86Ptr&0xf) *x86Ptr++ = 0x90;
290 ////////////////////////////////////////////////////
291 void x86Align( int bytes )
294 x86Ptr = (s8*)( ( (uptr)x86Ptr + bytes - 1) & ~( bytes - 1 ) );
297 /********************/
298 /* IX86 intructions */
299 /********************/
311 ////////////////////////////////////
312 // mov instructions /
313 ////////////////////////////////////
316 void MOV64RtoR( x86IntRegType to, x86IntRegType from )
320 ModRM( 3, from, to );
324 void MOV64RtoM( uptr to, x86IntRegType from )
334 MEMADDR_OP(1, VAROP1(0x89), true, from, to, 0);
339 void MOV64MtoR( x86IntRegType to, uptr from )
349 MEMADDR_OP(1, VAROP1(0x8B), true, to, from, 0);
353 /* mov imm32 to m64 */
354 void MOV64I32toM(uptr to, u32 from )
356 MEMADDR_OP(1, VAROP1(0xC7), false, 0, to, 4);
361 void MOV64ItoR( x86IntRegType to, u64 from)
364 write8( 0xB8 | (to & 0x7) );
368 /* mov imm32 to r64 */
369 void MOV64I32toR( x86IntRegType to, s32 from )
377 // mov imm64 to [r64+off]
378 void MOV64ItoRmOffset( x86IntRegType to, u32 from, int offset)
382 WriteRmOffset(to, offset);
386 // mov [r64+offset] to r64
387 void MOV64RmOffsettoR( x86IntRegType to, x86IntRegType from, int offset )
391 WriteRmOffsetFrom(to, from, offset);
394 /* mov [r64][r64*scale] to r64 */
395 void MOV64RmStoR( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale) {
396 RexRXB(1, to, from2, from);
399 SibSB(scale, from2, from );
402 /* mov r64 to [r64+offset] */
403 void MOV64RtoRmOffset( x86IntRegType to, x86IntRegType from, int offset )
407 WriteRmOffsetFrom(from, to, offset);
410 /* mov r64 to [r64][r64*scale] */
411 void MOV64RtoRmS( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale) {
412 RexRXB(1, to, from2, from);
415 SibSB(scale, from2, from );
420 void MOV32RtoR( x86IntRegType to, x86IntRegType from )
424 ModRM( 3, from, to );
428 void MOV32RtoM( uptr to, x86IntRegType from )
437 MEMADDR_OP(0, VAROP1(0x89), true, from, to, 0);
442 void MOV32MtoR( x86IntRegType to, uptr from )
451 MEMADDR_OP(0, VAROP1(0x8B), true, to, from, 0);
455 /* mov [r32] to r32 */
456 void MOV32RmtoR( x86IntRegType to, x86IntRegType from ) {
459 WriteRmOffsetFrom(to, from, 0);
462 void MOV32RmtoROffset( x86IntRegType to, x86IntRegType from, int offset ) {
465 WriteRmOffsetFrom(to, from, offset);
468 /* mov [r32+r32*scale] to r32 */
469 void MOV32RmStoR( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale) {
470 RexRXB(0,to,from2,from);
473 SibSB(scale, from2, from );
476 // mov r32 to [r32<<scale+from2]
477 void MOV32RmSOffsettoR( x86IntRegType to, x86IntRegType from1, int from2, int scale )
479 RexRXB(0,to,from1,0);
482 ModRM( scale, from1, 5);
486 /* mov r32 to [r32] */
487 void MOV32RtoRm( x86IntRegType to, x86IntRegType from ) {
491 ModRM( 0, from, 0x4 );
492 SibSB( 0, 0x4, 0x4 );
495 ModRM( 0, from, to );
499 /* mov r32 to [r32][r32*scale] */
500 void MOV32RtoRmS( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale) {
501 RexRXB(0, to, from2, from);
504 SibSB(scale, from2, from );
507 /* mov imm32 to r32 */
508 void MOV32ItoR( x86IntRegType to, u32 from )
511 write8( 0xB8 | (to & 0x7) );
515 /* mov imm32 to m32 */
516 void MOV32ItoM(uptr to, u32 from )
518 MEMADDR_OP(0, VAROP1(0xC7), false, 0, to, 4);
522 // mov imm32 to [r32+off]
523 void MOV32ItoRmOffset( x86IntRegType to, u32 from, int offset)
527 WriteRmOffset(to, offset);
531 // mov r32 to [r32+off]
532 void MOV32RtoRmOffset( x86IntRegType to, x86IntRegType from, int offset)
536 WriteRmOffsetFrom(from, to, offset);
540 void MOV16RtoM(uptr to, x86IntRegType from )
550 MEMADDR_OP(0, VAROP2(0x66, 0x89), true, from, to, 0);
555 void MOV16MtoR( x86IntRegType to, uptr from )
565 MEMADDR_OP(0, VAROP2(0x66, 0x8B), true, to, from, 0);
569 void MOV16RmtoR( x86IntRegType to, x86IntRegType from)
574 WriteRmOffsetFrom(to, from, 0);
577 void MOV16RmtoROffset( x86IntRegType to, x86IntRegType from, int offset )
582 WriteRmOffsetFrom(to, from, offset);
585 void MOV16RmSOffsettoR( x86IntRegType to, x86IntRegType from1, u32 from2, int scale )
588 RexRXB(0,to,from1,0);
591 ModRM( scale, from1, 5);
595 void MOV16RtoRm(x86IntRegType to, x86IntRegType from)
600 ModRM( 0, from, to );
603 /* mov imm16 to m16 */
604 void MOV16ItoM( uptr to, u16 from )
606 MEMADDR_OP(0, VAROP2(0x66, 0xC7), false, 0, to, 2);
610 /* mov r16 to [r32][r32*scale] */
611 void MOV16RtoRmS( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale) {
613 RexRXB(0,to,from2,from);
616 SibSB(scale, from2, from );
619 void MOV16ItoR( x86IntRegType to, u16 from )
622 write16( 0xB866 | ((to & 0x7)<<8) );
626 // mov imm16 to [r16+off]
627 void MOV16ItoRmOffset( x86IntRegType to, u16 from, u32 offset)
632 WriteRmOffset(to, offset);
636 // mov r16 to [r16+off]
637 void MOV16RtoRmOffset( x86IntRegType to, x86IntRegType from, int offset)
642 WriteRmOffsetFrom(from, to, offset);
646 void MOV8RtoM( uptr to, x86IntRegType from )
655 MEMADDR_OP(0, VAROP1(0x88), true, from, to, 0);
660 void MOV8MtoR( x86IntRegType to, uptr from )
669 MEMADDR_OP(0, VAROP1(0x8A), true, to, from, 0);
673 /* mov [r32] to r8 */
674 void MOV8RmtoR(x86IntRegType to, x86IntRegType from)
678 WriteRmOffsetFrom(to, from, 0);
681 void MOV8RmtoROffset(x86IntRegType to, x86IntRegType from, int offset)
685 WriteRmOffsetFrom(to, from, offset);
688 void MOV8RtoRm(x86IntRegType to, x86IntRegType from)
692 WriteRmOffsetFrom(from, to, 0);
696 void MOV8ItoM( uptr to, u8 from )
698 MEMADDR_OP(0, VAROP1(0xC6), false, 0, to, 1);
703 void MOV8ItoR( x86IntRegType to, u8 from )
706 write8( 0xB0 | (to & 0x7) );
710 // mov imm8 to [r8+off]
711 void MOV8ItoRmOffset( x86IntRegType to, u8 from, int offset)
716 WriteRmOffset(to,offset);
720 // mov r8 to [r8+off]
721 void MOV8RtoRmOffset( x86IntRegType to, x86IntRegType from, int offset)
726 WriteRmOffsetFrom(from,to,offset);
729 /* movsx r8 to r32 */
730 void MOVSX32R8toR( x86IntRegType to, x86IntRegType from )
734 ModRM( 3, to, from );
737 void MOVSX32Rm8toR( x86IntRegType to, x86IntRegType from )
741 ModRM( 0, to, from );
744 void MOVSX32Rm8toROffset( x86IntRegType to, x86IntRegType from, int offset )
748 WriteRmOffsetFrom(to,from,offset);
751 /* movsx m8 to r32 */
752 void MOVSX32M8toR( x86IntRegType to, uptr from )
754 MEMADDR_OP(0, VAROP2(0x0F, 0xBE), true, to, from, 0);
757 /* movsx r16 to r32 */
758 void MOVSX32R16toR( x86IntRegType to, x86IntRegType from )
762 ModRM( 3, to, from );
765 void MOVSX32Rm16toR( x86IntRegType to, x86IntRegType from )
769 ModRM( 0, to, from );
772 void MOVSX32Rm16toROffset( x86IntRegType to, x86IntRegType from, int offset )
776 WriteRmOffsetFrom(to,from,offset);
779 /* movsx m16 to r32 */
780 void MOVSX32M16toR( x86IntRegType to, uptr from )
782 MEMADDR_OP(0, VAROP2(0x0F, 0xBF), true, to, from, 0);
785 /* movzx r8 to r32 */
786 void MOVZX32R8toR( x86IntRegType to, x86IntRegType from )
790 ModRM( 3, to, from );
793 void MOVZX32Rm8toR( x86IntRegType to, x86IntRegType from )
797 ModRM( 0, to, from );
800 void MOVZX32Rm8toROffset( x86IntRegType to, x86IntRegType from, int offset )
804 WriteRmOffsetFrom(to,from,offset);
807 /* movzx m8 to r32 */
808 void MOVZX32M8toR( x86IntRegType to, uptr from )
810 MEMADDR_OP(0, VAROP2(0x0F, 0xB6), true, to, from, 0);
813 /* movzx r16 to r32 */
814 void MOVZX32R16toR( x86IntRegType to, x86IntRegType from )
818 ModRM( 3, to, from );
821 void MOVZX32Rm16toR( x86IntRegType to, x86IntRegType from )
825 ModRM( 0, to, from );
828 void MOVZX32Rm16toROffset( x86IntRegType to, x86IntRegType from, int offset )
832 WriteRmOffsetFrom(to,from,offset);
835 /* movzx m16 to r32 */
836 void MOVZX32M16toR( x86IntRegType to, uptr from )
838 MEMADDR_OP(0, VAROP2(0x0F, 0xB7), true, to, from, 0);
843 /* movzx r8 to r64 */
844 void MOVZX64R8toR( x86IntRegType to, x86IntRegType from )
848 ModRM( 3, to, from );
851 void MOVZX64Rm8toR( x86IntRegType to, x86IntRegType from )
855 ModRM( 0, to, from );
858 void MOVZX64Rm8toROffset( x86IntRegType to, x86IntRegType from, int offset )
862 WriteRmOffsetFrom(to,from,offset);
865 /* movzx m8 to r64 */
866 void MOVZX64M8toR( x86IntRegType to, uptr from )
868 MEMADDR_OP(1, VAROP2(0x0F, 0xB6), true, to, from, 0);
871 /* movzx r16 to r64 */
872 void MOVZX64R16toR( x86IntRegType to, x86IntRegType from )
876 ModRM( 3, to, from );
879 void MOVZX64Rm16toR( x86IntRegType to, x86IntRegType from )
883 ModRM( 0, to, from );
886 void MOVZX64Rm16toROffset( x86IntRegType to, x86IntRegType from, int offset )
890 WriteRmOffsetFrom(to,from,offset);
893 /* movzx m16 to r64 */
894 void MOVZX64M16toR( x86IntRegType to, uptr from )
896 MEMADDR_OP(1, VAROP2(0x0F, 0xB7), true, to, from, 0);
900 /* cmovbe r32 to r32 */
901 void CMOVBE32RtoR( x86IntRegType to, x86IntRegType from )
903 CMOV32RtoR( 0x46, to, from );
906 /* cmovbe m32 to r32*/
907 void CMOVBE32MtoR( x86IntRegType to, uptr from )
909 CMOV32MtoR( 0x46, to, from );
912 /* cmovb r32 to r32 */
913 void CMOVB32RtoR( x86IntRegType to, x86IntRegType from )
915 CMOV32RtoR( 0x42, to, from );
918 /* cmovb m32 to r32*/
919 void CMOVB32MtoR( x86IntRegType to, uptr from )
921 CMOV32MtoR( 0x42, to, from );
924 /* cmovae r32 to r32 */
925 void CMOVAE32RtoR( x86IntRegType to, x86IntRegType from )
927 CMOV32RtoR( 0x43, to, from );
930 /* cmovae m32 to r32*/
931 void CMOVAE32MtoR( x86IntRegType to, uptr from )
933 CMOV32MtoR( 0x43, to, from );
936 /* cmova r32 to r32 */
937 void CMOVA32RtoR( x86IntRegType to, x86IntRegType from )
939 CMOV32RtoR( 0x47, to, from );
942 /* cmova m32 to r32*/
943 void CMOVA32MtoR( x86IntRegType to, uptr from )
945 CMOV32MtoR( 0x47, to, from );
948 /* cmovo r32 to r32 */
949 void CMOVO32RtoR( x86IntRegType to, x86IntRegType from )
951 CMOV32RtoR( 0x40, to, from );
954 /* cmovo m32 to r32 */
955 void CMOVO32MtoR( x86IntRegType to, uptr from )
957 CMOV32MtoR( 0x40, to, from );
960 /* cmovp r32 to r32 */
961 void CMOVP32RtoR( x86IntRegType to, x86IntRegType from )
963 CMOV32RtoR( 0x4A, to, from );
966 /* cmovp m32 to r32 */
967 void CMOVP32MtoR( x86IntRegType to, uptr from )
969 CMOV32MtoR( 0x4A, to, from );
972 /* cmovs r32 to r32 */
973 void CMOVS32RtoR( x86IntRegType to, x86IntRegType from )
975 CMOV32RtoR( 0x48, to, from );
978 /* cmovs m32 to r32 */
979 void CMOVS32MtoR( x86IntRegType to, uptr from )
981 CMOV32MtoR( 0x48, to, from );
984 /* cmovno r32 to r32 */
985 void CMOVNO32RtoR( x86IntRegType to, x86IntRegType from )
987 CMOV32RtoR( 0x41, to, from );
990 /* cmovno m32 to r32 */
991 void CMOVNO32MtoR( x86IntRegType to, uptr from )
993 CMOV32MtoR( 0x41, to, from );
996 /* cmovnp r32 to r32 */
997 void CMOVNP32RtoR( x86IntRegType to, x86IntRegType from )
999 CMOV32RtoR( 0x4B, to, from );
1002 /* cmovnp m32 to r32 */
1003 void CMOVNP32MtoR( x86IntRegType to, uptr from )
1005 CMOV32MtoR( 0x4B, to, from );
1008 /* cmovns r32 to r32 */
1009 void CMOVNS32RtoR( x86IntRegType to, x86IntRegType from )
1011 CMOV32RtoR( 0x49, to, from );
1014 /* cmovns m32 to r32 */
1015 void CMOVNS32MtoR( x86IntRegType to, uptr from )
1017 CMOV32MtoR( 0x49, to, from );
1020 /* cmovne r32 to r32 */
1021 void CMOVNE32RtoR( x86IntRegType to, x86IntRegType from )
1023 CMOV32RtoR( 0x45, to, from );
1026 /* cmovne m32 to r32*/
1027 void CMOVNE32MtoR( x86IntRegType to, uptr from )
1029 CMOV32MtoR( 0x45, to, from );
1032 /* cmove r32 to r32*/
1033 void CMOVE32RtoR( x86IntRegType to, x86IntRegType from )
1035 CMOV32RtoR( 0x44, to, from );
1038 /* cmove m32 to r32*/
1039 void CMOVE32MtoR( x86IntRegType to, uptr from )
1041 CMOV32MtoR( 0x44, to, from );
1044 /* cmovg r32 to r32*/
1045 void CMOVG32RtoR( x86IntRegType to, x86IntRegType from )
1047 CMOV32RtoR( 0x4F, to, from );
1050 /* cmovg m32 to r32*/
1051 void CMOVG32MtoR( x86IntRegType to, uptr from )
1053 CMOV32MtoR( 0x4F, to, from );
1056 /* cmovge r32 to r32*/
1057 void CMOVGE32RtoR( x86IntRegType to, x86IntRegType from )
1059 CMOV32RtoR( 0x4D, to, from );
1062 /* cmovge m32 to r32*/
1063 void CMOVGE32MtoR( x86IntRegType to, uptr from )
1065 CMOV32MtoR( 0x4D, to, from );
1068 /* cmovl r32 to r32*/
1069 void CMOVL32RtoR( x86IntRegType to, x86IntRegType from )
1071 CMOV32RtoR( 0x4C, to, from );
1074 /* cmovl m32 to r32*/
1075 void CMOVL32MtoR( x86IntRegType to, uptr from )
1077 CMOV32MtoR( 0x4C, to, from );
1080 /* cmovle r32 to r32*/
1081 void CMOVLE32RtoR( x86IntRegType to, x86IntRegType from )
1083 CMOV32RtoR( 0x4E, to, from );
1086 /* cmovle m32 to r32*/
1087 void CMOVLE32MtoR( x86IntRegType to, uptr from )
1089 CMOV32MtoR( 0x4E, to, from );
1092 ////////////////////////////////////
1093 // arithmetic instructions /
1094 ////////////////////////////////////
1096 /* add imm32 to r64 */
1097 void ADD64ItoR( x86IntRegType to, u32 from )
1118 /* add m64 to r64 */
1119 void ADD64MtoR( x86IntRegType to, uptr from )
1121 MEMADDR_OP(1, VAROP1(0x03), true, to, from, 0);
1124 /* add r64 to r64 */
1125 void ADD64RtoR( x86IntRegType to, x86IntRegType from )
1129 ModRM( 3, from, to );
1132 /* add imm32 to r32 */
1133 void ADD32ItoR( x86IntRegType to, u32 from )
1146 /* add imm32 to m32 */
1147 void ADD32ItoM( uptr to, u32 from )
1149 MEMADDR_OP(0, VAROP1(0x81), false, 0, to, 4);
1153 // add imm32 to [r32+off]
1154 void ADD32ItoRmOffset( x86IntRegType to, u32 from, int offset)
1158 WriteRmOffset(to,offset);
1162 /* add r32 to r32 */
1163 void ADD32RtoR( x86IntRegType to, x86IntRegType from )
1167 ModRM( 3, from, to );
1170 /* add r32 to m32 */
1171 void ADD32RtoM(uptr to, x86IntRegType from )
1173 MEMADDR_OP(0, VAROP1(0x01), true, from, to, 0);
1176 /* add m32 to r32 */
1177 void ADD32MtoR( x86IntRegType to, uptr from )
1179 MEMADDR_OP(0, VAROP1(0x03), true, to, from, 0);
1183 void ADD16RtoR( x86IntRegType to , x86IntRegType from )
1188 ModRM( 3, to, from );
1191 /* add imm16 to r16 */
1192 void ADD16ItoR( x86IntRegType to, u16 from )
1208 /* add imm16 to m16 */
1209 void ADD16ItoM( uptr to, u16 from )
1211 MEMADDR_OP(0, VAROP2(0x66, 0x81), false, 0, to, 2);
1215 /* add r16 to m16 */
1216 void ADD16RtoM(uptr to, x86IntRegType from )
1218 MEMADDR_OP(0, VAROP2(0x66, 0x01), true, from, to, 0);
1221 /* add m16 to r16 */
1222 void ADD16MtoR( x86IntRegType to, uptr from )
1224 MEMADDR_OP(0, VAROP2(0x66, 0x03), true, to, from, 0);
1228 void ADD8MtoR( x86IntRegType to, uptr from )
1230 MEMADDR_OP(0, VAROP1(0x02), true, to, from, 0);
1233 /* adc imm32 to r32 */
1234 void ADC32ItoR( x86IntRegType to, u32 from )
1247 /* adc imm32 to m32 */
1248 void ADC32ItoM( uptr to, u32 from )
1250 MEMADDR_OP(0, VAROP1(0x81), false, 2, to, 4);
1254 /* adc r32 to r32 */
1255 void ADC32RtoR( x86IntRegType to, x86IntRegType from )
1259 ModRM( 3, from, to );
1262 /* adc m32 to r32 */
1263 void ADC32MtoR( x86IntRegType to, uptr from )
1265 MEMADDR_OP(0, VAROP1(0x13), true, to, from, 0);
1269 void ADC32RtoM( uptr to, x86IntRegType from )
1271 MEMADDR_OP(0, VAROP1(0x11), true, from, to, 0);
1276 void INC32R( x86IntRegType to )
1283 void INC32R( x86IntRegType to )
1286 write8( 0x40 + to );
1290 void INC32M( uptr to )
1292 MEMADDR_OP(0, VAROP1(0xFF), false, 0, to, 0);
1296 void INC16R( x86IntRegType to )
1300 write8( 0x40 + to );
1304 void INC16M( uptr to )
1306 MEMADDR_OP(0, VAROP2(0x66, 0xFF), false, 0, to, 0);
1310 /* sub imm32 to r64 */
1311 void SUB64ItoR( x86IntRegType to, u32 from )
1333 /* sub r64 to r64 */
1334 void SUB64RtoR( x86IntRegType to, x86IntRegType from )
1338 ModRM( 3, from, to );
1341 /* sub m64 to r64 */
1342 void SUB64MtoR( x86IntRegType to, uptr from )
1344 MEMADDR_OP(1, VAROP1(0x2B), true, to, from, 0);
1347 /* sub imm32 to r32 */
1348 void SUB32ItoR( x86IntRegType to, u32 from )
1361 /* sub imm32 to m32 */
1362 void SUB32ItoM( uptr to, u32 from )
1364 MEMADDR_OP(0, VAROP1(0x81), false, 5, to, 4);
1368 /* sub r32 to r32 */
1369 void SUB32RtoR( x86IntRegType to, x86IntRegType from )
1373 ModRM( 3, from, to );
1376 /* sub m32 to r32 */
1377 void SUB32MtoR( x86IntRegType to, uptr from )
1379 MEMADDR_OP(0, VAROP1(0x2B), true, to, from, 0);
1383 void SUB32RtoM( uptr to, x86IntRegType from )
1385 MEMADDR_OP(0, VAROP1(0x29), true, from, to, 0);
1389 void SUB16RtoR( x86IntRegType to, u16 from )
1394 ModRM( 3, to, from );
1397 /* sub imm16 to r16 */
1398 void SUB16ItoR( x86IntRegType to, u16 from ) {
1410 /* sub imm16 to m16 */
1411 void SUB16ItoM( uptr to, u16 from ) {
1412 MEMADDR_OP(0, VAROP2(0x66, 0x81), false, 5, to, 2);
1416 /* sub m16 to r16 */
1417 void SUB16MtoR( x86IntRegType to, uptr from ) {
1418 MEMADDR_OP(0, VAROP2(0x66, 0x2B), true, to, from, 0);
1421 /* sbb r64 to r64 */
1422 void SBB64RtoR( x86IntRegType to, x86IntRegType from ) {
1425 ModRM( 3, from, to );
1428 /* sbb imm32 to r32 */
1429 void SBB32ItoR( x86IntRegType to, u32 from ) {
1440 /* sbb imm32 to m32 */
1441 void SBB32ItoM( uptr to, u32 from ) {
1442 MEMADDR_OP(0, VAROP1(0x81), false, 3, to, 4);
1446 /* sbb r32 to r32 */
1447 void SBB32RtoR( x86IntRegType to, x86IntRegType from )
1451 ModRM( 3, from, to );
1454 /* sbb m32 to r32 */
1455 void SBB32MtoR( x86IntRegType to, uptr from )
1457 MEMADDR_OP(0, VAROP1(0x1B), true, to, from, 0);
1460 /* sbb r32 to m32 */
1461 void SBB32RtoM( uptr to, x86IntRegType from )
1463 MEMADDR_OP(0, VAROP1(0x19), true, from, to, 0);
1467 void DEC32R( x86IntRegType to )
1474 void DEC32R( x86IntRegType to )
1477 write8( 0x48 + to );
1482 void DEC32M( uptr to )
1484 MEMADDR_OP(0, VAROP1(0xFF), false, 1, to, 0);
1488 void DEC16R( x86IntRegType to )
1492 write8( 0x48 + to );
1496 void DEC16M( uptr to )
1498 MEMADDR_OP(0, VAROP2(0x66, 0xFF), false, 1, to, 0);
1501 /* mul eax by r32 to edx:eax */
1502 void MUL32R( x86IntRegType from )
1506 ModRM( 3, 4, from );
1509 /* imul eax by r32 to edx:eax */
1510 void IMUL32R( x86IntRegType from )
1514 ModRM( 3, 5, from );
1517 /* mul eax by m32 to edx:eax */
1518 void MUL32M( uptr from )
1520 MEMADDR_OP(0, VAROP1(0xF7), false, 4, from, 0);
1523 /* imul eax by m32 to edx:eax */
1524 void IMUL32M( uptr from )
1526 MEMADDR_OP(0, VAROP1(0xF7), false, 5, from, 0);
1529 /* imul r32 by r32 to r32 */
1530 void IMUL32RtoR( x86IntRegType to, x86IntRegType from )
1534 ModRM( 3, to, from );
1537 /* div eax by r32 to edx:eax */
1538 void DIV32R( x86IntRegType from )
1542 ModRM( 3, 6, from );
1545 /* idiv eax by r32 to edx:eax */
1546 void IDIV32R( x86IntRegType from )
1550 ModRM( 3, 7, from );
1553 /* div eax by m32 to edx:eax */
1554 void DIV32M( uptr from )
1556 MEMADDR_OP(0, VAROP1(0xF7), false, 6, from, 0);
1559 /* idiv eax by m32 to edx:eax */
1560 void IDIV32M( uptr from )
1562 MEMADDR_OP(0, VAROP1(0xF7), false, 7, from, 0);
1565 ////////////////////////////////////
1566 // shifting instructions /
1567 ////////////////////////////////////
1569 /* shl imm8 to r64 */
1570 void SHL64ItoR( x86IntRegType to, u8 from )
1585 void SHL64CLtoR( x86IntRegType to )
1592 /* shr imm8 to r64 */
1593 void SHR64ItoR( x86IntRegType to, u8 from )
1607 void SHR64CLtoR( x86IntRegType to )
1614 /* shl imm8 to r32 */
1615 void SHL32ItoR( x86IntRegType to, u8 from )
1621 write8( 0xE0 | (to & 0x7) );
1629 /* shl imm8 to m32 */
1630 void SHL32ItoM( uptr to, u8 from )
1634 MEMADDR_OP(0, VAROP1(0xD1), false, 4, to, 0);
1638 MEMADDR_OP(0, VAROP1(0xC1), false, 4, to, 1);
1644 void SHL32CLtoR( x86IntRegType to )
1652 void SHL16ItoR( x86IntRegType to, u8 from )
1659 write8( 0xE0 | (to & 0x7) );
1668 void SHL8ItoR( x86IntRegType to, u8 from )
1674 write8( 0xE0 | (to & 0x7) );
1682 /* shr imm8 to r32 */
1683 void SHR32ItoR( x86IntRegType to, u8 from ) {
1688 write8( 0xE8 | (to & 0x7) );
1698 /* shr imm8 to m32 */
1699 void SHR32ItoM( uptr to, u8 from )
1703 MEMADDR_OP(0, VAROP1(0xD1), false, 5, to, 0);
1707 MEMADDR_OP(0, VAROP1(0xC1), false, 5, to, 1);
1713 void SHR32CLtoR( x86IntRegType to )
1721 void SHR8ItoR( x86IntRegType to, u8 from )
1727 write8( 0xE8 | (to & 0x7) );
1737 /* sar imm8 to r64 */
1738 void SAR64ItoR( x86IntRegType to, u8 from )
1753 void SAR64CLtoR( x86IntRegType to )
1760 /* sar imm8 to r32 */
1761 void SAR32ItoR( x86IntRegType to, u8 from )
1775 /* sar imm8 to m32 */
1776 void SAR32ItoM( uptr to, u8 from )
1780 MEMADDR_OP(0, VAROP1(0xD1), false, 7, to, 0);
1784 MEMADDR_OP(0, VAROP1(0xC1), false, 7, to, 1);
1790 void SAR32CLtoR( x86IntRegType to )
1798 void SAR16ItoR( x86IntRegType to, u8 from )
1813 void ROR32ItoR( x86IntRegType to,u8 from )
1818 write8( 0xc8 | to );
1823 write8( 0xc8 | to );
1828 void RCR32ItoR( x86IntRegType to, u8 from )
1833 write8( 0xd8 | to );
1838 write8( 0xd8 | to );
1844 void SHLD32ItoR( x86IntRegType to, x86IntRegType from, u8 shift )
1849 ModRM( 3, from, to );
1854 void SHRD32ItoR( x86IntRegType to, x86IntRegType from, u8 shift )
1859 ModRM( 3, from, to );
1863 ////////////////////////////////////
1864 // logical instructions /
1865 ////////////////////////////////////
1867 /* or imm32 to r32 */
1868 void OR64ItoR( x86IntRegType to, u32 from )
1881 void OR64MtoR( x86IntRegType to, uptr from )
1883 MEMADDR_OP(1, VAROP1(0x0B), true, to, from, 0);
1887 void OR64RtoR( x86IntRegType to, x86IntRegType from )
1891 ModRM( 3, from, to );
1895 void OR64RtoM(uptr to, x86IntRegType from )
1897 MEMADDR_OP(1, VAROP1(0x09), true, from, to, 0);
1900 /* or imm32 to r32 */
1901 void OR32ItoR( x86IntRegType to, u32 from )
1914 /* or imm32 to m32 */
1915 void OR32ItoM(uptr to, u32 from )
1917 MEMADDR_OP(0, VAROP1(0x81), false, 1, to, 4);
1922 void OR32RtoR( x86IntRegType to, x86IntRegType from )
1926 ModRM( 3, from, to );
1930 void OR32RtoM(uptr to, x86IntRegType from )
1932 MEMADDR_OP(0, VAROP1(0x09), true, from, to, 0);
1936 void OR32MtoR( x86IntRegType to, uptr from )
1938 MEMADDR_OP(0, VAROP1(0x0B), true, to, from, 0);
1942 void OR16RtoR( x86IntRegType to, x86IntRegType from )
1947 ModRM( 3, from, to );
1951 void OR16ItoR( x86IntRegType to, u16 from )
1966 void OR16ItoM( uptr to, u16 from )
1968 MEMADDR_OP(0, VAROP2(0x66, 0x81), false, 1, to, 2);
1973 void OR16MtoR( x86IntRegType to, uptr from )
1975 MEMADDR_OP(0, VAROP2(0x66, 0x0B), true, to, from, 0);
1979 void OR16RtoM( uptr to, x86IntRegType from )
1981 MEMADDR_OP(0, VAROP2(0x66, 0x09), true, from, to, 0);
1985 void OR8RtoR( x86IntRegType to, x86IntRegType from )
1989 ModRM( 3, from, to );
1993 void OR8RtoM( uptr to, x86IntRegType from )
1995 MEMADDR_OP(0, VAROP1(0x08), true, from, to, 0);
1999 void OR8ItoM( uptr to, u8 from )
2001 MEMADDR_OP(0, VAROP1(0x80), false, 1, to, 1);
2006 void OR8MtoR( x86IntRegType to, uptr from )
2008 MEMADDR_OP(0, VAROP1(0x0A), true, to, from, 0);
2011 /* xor imm32 to r64 */
2012 void XOR64ItoR( x86IntRegType to, u32 from )
2024 /* xor r64 to r64 */
2025 void XOR64RtoR( x86IntRegType to, x86IntRegType from )
2029 ModRM( 3, from, to );
2032 /* xor m64 to r64 */
2033 void XOR64MtoR( x86IntRegType to, uptr from )
2035 MEMADDR_OP(1, VAROP1(0x33), true, to, from, 0);
2038 /* xor r64 to m64 */
2039 void XOR64RtoM( uptr to, x86IntRegType from )
2041 MEMADDR_OP(1, VAROP1(0x31), true, from, to, 0);
2044 /* xor imm32 to r32 */
2045 void XOR32ItoR( x86IntRegType to, u32 from )
2058 /* xor imm32 to m32 */
2059 void XOR32ItoM( uptr to, u32 from )
2061 MEMADDR_OP(0, VAROP1(0x81), false, 6, to, 4);
2065 /* xor r32 to r32 */
2066 void XOR32RtoR( x86IntRegType to, x86IntRegType from )
2070 ModRM( 3, from, to );
2073 /* xor r16 to r16 */
2074 void XOR16RtoR( x86IntRegType to, x86IntRegType from )
2079 ModRM( 3, from, to );
2082 /* xor r32 to m32 */
2083 void XOR32RtoM( uptr to, x86IntRegType from )
2085 MEMADDR_OP(0, VAROP1(0x31), true, from, to, 0);
2088 /* xor m32 to r32 */
2089 void XOR32MtoR( x86IntRegType to, uptr from )
2091 MEMADDR_OP(0, VAROP1(0x33), true, to, from, 0);
2095 void XOR16ItoR( x86IntRegType to, u16 from )
2110 void XOR16RtoM( uptr to, x86IntRegType from )
2112 MEMADDR_OP(0, VAROP2(0x66, 0x31), true, from, to, 0);
2115 /* and imm32 to r64 */
2116 void AND64I32toR( x86IntRegType to, u32 from )
2123 ModRM( 3, 0x4, to );
2128 /* and m64 to r64 */
2129 void AND64MtoR( x86IntRegType to, uptr from )
2131 MEMADDR_OP(1, VAROP1(0x23), true, to, from, 0);
2134 /* and r64 to m64 */
2135 void AND64RtoM( uptr to, x86IntRegType from )
2137 MEMADDR_OP(1, VAROP1(0x21), true, from, to, 0);
2140 /* and r64 to r64 */
2141 void AND64RtoR( x86IntRegType to, x86IntRegType from )
2145 ModRM( 3, from, to );
2148 /* and imm32 to m64 */
2149 void AND64I32toM( uptr to, u32 from )
2151 MEMADDR_OP(1, VAROP1(0x81), false, 4, to, 4);
2155 /* and imm32 to r32 */
2156 void AND32ItoR( x86IntRegType to, u32 from )
2163 ModRM( 3, 0x4, to );
2168 /* and sign ext imm8 to r32 */
2169 void AND32I8toR( x86IntRegType to, u8 from )
2173 ModRM( 3, 0x4, to );
2177 /* and imm32 to m32 */
2178 void AND32ItoM( uptr to, u32 from )
2180 MEMADDR_OP(0, VAROP1(0x81), false, 4, to, 4);
2184 /* and sign ext imm8 to m32 */
2185 void AND32I8toM( uptr to, u8 from )
2187 MEMADDR_OP(0, VAROP1(0x83), false, 4, to, 1);
2191 /* and r32 to r32 */
2192 void AND32RtoR( x86IntRegType to, x86IntRegType from )
2196 ModRM( 3, from, to );
2199 /* and r32 to m32 */
2200 void AND32RtoM( uptr to, x86IntRegType from )
2202 MEMADDR_OP(0, VAROP1(0x21), true, from, to, 0);
2205 /* and m32 to r32 */
2206 void AND32MtoR( x86IntRegType to, uptr from )
2208 MEMADDR_OP(0, VAROP1(0x23), true, to, from, 0);
2212 void AND16RtoR( x86IntRegType to, x86IntRegType from )
2217 ModRM( 3, to, from );
2220 /* and imm16 to r16 */
2221 void AND16ItoR( x86IntRegType to, u16 from )
2229 ModRM( 3, 0x4, to );
2234 /* and imm16 to m16 */
2235 void AND16ItoM( uptr to, u16 from )
2237 MEMADDR_OP(0, VAROP2(0x66, 0x81), false, 4, to, 2);
2241 /* and r16 to m16 */
2242 void AND16RtoM( uptr to, x86IntRegType from )
2244 MEMADDR_OP(0, VAROP2(0x66, 0x21), true, from, to, 0);
2247 /* and m16 to r16 */
2248 void AND16MtoR( x86IntRegType to, uptr from )
2250 MEMADDR_OP(0, VAROP2(0x66, 0x23), true, to, from, 0);
2253 /* and imm8 to r8 */
2254 void AND8ItoR( x86IntRegType to, u8 from )
2261 ModRM( 3, 0x4, to );
2266 /* and imm8 to m8 */
2267 void AND8ItoM( uptr to, u8 from )
2269 MEMADDR_OP(0, VAROP1(0x80), false, 4, to, 1);
2274 void AND8RtoR( x86IntRegType to, x86IntRegType from )
2278 ModRM( 3, to, from );
2282 void AND8RtoM( uptr to, x86IntRegType from )
2284 MEMADDR_OP(0, VAROP1(0x20), true, from, to, 0);
2288 void AND8MtoR( x86IntRegType to, uptr from )
2290 MEMADDR_OP(0, VAROP1(0x22), true, to, from, 0);
2294 void NOT64R( x86IntRegType from )
2298 ModRM( 3, 2, from );
2302 void NOT32R( x86IntRegType from )
2306 ModRM( 3, 2, from );
2310 void NOT32M( uptr from )
2312 MEMADDR_OP(0, VAROP1(0xF7), false, 2, from, 0);
2316 void NEG64R( x86IntRegType from )
2320 ModRM( 3, 3, from );
2324 void NEG32R( x86IntRegType from )
2328 ModRM( 3, 3, from );
2331 void NEG32M( uptr from )
2333 MEMADDR_OP(0, VAROP1(0xF7), false, 3, from, 0);
2337 void NEG16R( x86IntRegType from )
2342 ModRM( 3, 3, from );
2345 ////////////////////////////////////
2346 // jump instructions /
2347 ////////////////////////////////////
2349 u8* JMP( uptr to ) {
2350 uptr jump = ( x86Ptr - (s8*)to ) - 1;
2352 if ( jump > 0x7f ) {
2353 assert( to <= 0xffffffff );
2354 return (u8*)JMP32( to );
2356 return (u8*)JMP8( to );
2369 u32* JMP32( uptr to )
2371 assert(SPTR32((sptr)to));
2373 write32( (sptr)to );
2374 return (u32*)(x86Ptr - 4 );
2378 void JMPR( x86IntRegType to )
2386 void JMP32M( uptr to )
2389 MEMADDR_OP(0, VAROP1(0xFF), false, 4, to, 0);
2394 return J8Rel( 0x7A, to );
2399 return J8Rel( 0x7B, to );
2404 return J8Rel( 0x74, to );
2410 return J8Rel( 0x74, to );
2416 return J8Rel( 0x78, to );
2422 return J8Rel( 0x79, to );
2428 return J8Rel( 0x7F, to );
2434 return J8Rel( 0x7D, to );
2440 return J8Rel( 0x7C, to );
2446 return J8Rel( 0x77, to );
2451 return J8Rel( 0x73, to );
2457 return J8Rel( 0x72, to );
2463 return J8Rel( 0x76, to );
2469 return J8Rel( 0x7E, to );
2475 return J8Rel( 0x75, to );
2481 return J8Rel( 0x75, to );
2487 return J8Rel( 0x7E, to );
2493 return J8Rel( 0x7C, to );
2499 return J8Rel( 0x7D, to );
2505 return J8Rel( 0x7F, to );
2511 return J8Rel( 0x70, to );
2517 return J8Rel( 0x71, to );
2523 return J16Rel( 0x82, to );
2529 return J32Rel( 0x82, to );
2535 return J32Rel( 0x84, to );
2541 return J32Rel( 0x84, to );
2547 return J32Rel( 0x8F, to );
2551 u32* JGE32( u32 to )
2553 return J32Rel( 0x8D, to );
2559 return J32Rel( 0x8C, to );
2563 u32* JLE32( u32 to )
2565 return J32Rel( 0x8E, to );
2569 u32* JAE32( u32 to )
2571 return J32Rel( 0x83, to );
2575 u32* JNE32( u32 to )
2577 return J32Rel( 0x85, to );
2581 u32* JNZ32( u32 to )
2583 return J32Rel( 0x85, to );
2587 u32* JNG32( u32 to )
2589 return J32Rel( 0x8E, to );
2593 u32* JNGE32( u32 to )
2595 return J32Rel( 0x8C, to );
2599 u32* JNL32( u32 to )
2601 return J32Rel( 0x8D, to );
2605 u32* JNLE32( u32 to )
2607 return J32Rel( 0x8F, to );
2613 return J32Rel( 0x80, to );
2617 u32* JNO32( u32 to )
2619 return J32Rel( 0x81, to );
2625 return J32Rel( 0x88, to );
2630 void CALLFunc( uptr func )
2632 sptr p = MEMADDR_(func, 5);
2639 MOV64ItoR(X86_TEMP, func);
2645 void CALL32( s32 to )
2652 void CALL32R( x86IntRegType to )
2660 void CALL64R( x86IntRegType to )
2667 ////////////////////////////////////
2668 // misc instructions /
2669 ////////////////////////////////////
2671 /* cmp imm32 to r64 */
2672 void CMP64I32toR( x86IntRegType to, u32 from )
2685 /* cmp m64 to r64 */
2686 void CMP64MtoR( x86IntRegType to, uptr from )
2688 MEMADDR_OP(1, VAROP1(0x3B), true, 2, from, 0);
2692 void CMP64RtoR( x86IntRegType to, x86IntRegType from )
2696 ModRM( 3, from, to );
2699 /* cmp imm32 to r32 */
2700 void CMP32ItoR( x86IntRegType to, u32 from )
2713 /* cmp imm32 to m32 */
2714 void CMP32ItoM( uptr to, u32 from )
2716 MEMADDR_OP(0, VAROP1(0x81), false, 7, to, 4);
2720 /* cmp r32 to r32 */
2721 void CMP32RtoR( x86IntRegType to, x86IntRegType from )
2725 ModRM( 3, from, to );
2728 /* cmp m32 to r32 */
2729 void CMP32MtoR( x86IntRegType to, uptr from )
2731 MEMADDR_OP(0, VAROP1(0x3B), true, to, from, 0);
2734 // cmp imm8 to [r32]
2735 void CMP32I8toRm( x86IntRegType to, u8 from)
2743 // cmp imm32 to [r32+off]
2744 void CMP32I8toRmOffset8( x86IntRegType to, u8 from, u8 off)
2753 // cmp imm8 to [r32]
2754 void CMP32I8toM( uptr to, u8 from)
2756 MEMADDR_OP(0, VAROP1(0x83), false, 7, to, 1);
2760 /* cmp imm16 to r16 */
2761 void CMP16ItoR( x86IntRegType to, u16 from )
2777 /* cmp imm16 to m16 */
2778 void CMP16ItoM( uptr to, u16 from )
2780 MEMADDR_OP(0, VAROP2(0x66, 0x81), false, 7, to, 2);
2784 /* cmp r16 to r16 */
2785 void CMP16RtoR( x86IntRegType to, x86IntRegType from )
2790 ModRM( 3, from, to );
2793 /* cmp m16 to r16 */
2794 void CMP16MtoR( x86IntRegType to, uptr from )
2796 MEMADDR_OP(0, VAROP2(0x66, 0x3B), true, to, from, 0);
2800 void CMP8ItoR( x86IntRegType to, u8 from )
2816 void CMP8MtoR( x86IntRegType to, uptr from )
2818 MEMADDR_OP(0, VAROP1(0x3A), true, to, from, 0);
2821 /* test r64 to r64 */
2822 void TEST64RtoR( x86IntRegType to, x86IntRegType from )
2826 ModRM( 3, from, to );
2829 /* test imm32 to r32 */
2830 void TEST32ItoR( x86IntRegType to, u32 from )
2845 void TEST32ItoM( uptr to, u32 from )
2847 MEMADDR_OP(0, VAROP1(0xF7), false, 0, to, 4);
2851 /* test r32 to r32 */
2852 void TEST32RtoR( x86IntRegType to, x86IntRegType from )
2856 ModRM( 3, from, to );
2859 // test imm32 to [r32]
2860 void TEST32ItoRm( x86IntRegType to, u32 from )
2868 // test imm16 to r16
2869 void TEST16ItoR( x86IntRegType to, u16 from )
2886 void TEST16RtoR( x86IntRegType to, x86IntRegType from )
2891 ModRM( 3, from, to );
2895 void TEST8ItoR( x86IntRegType to, u8 from )
2911 void TEST8ItoM( uptr to, u8 from )
2913 MEMADDR_OP(0, VAROP1(0xF6), false, 0, to, 1);
2918 void SETS8R( x86IntRegType to )
2924 void SETL8R( x86IntRegType to )
2930 void SETGE8R( x86IntRegType to ) { SET8R(0x9d, to); }
2932 void SETG8R( x86IntRegType to ) { SET8R(0x9f, to); }
2934 void SETA8R( x86IntRegType to ) { SET8R(0x97, to); }
2936 void SETAE8R( x86IntRegType to ) { SET8R(0x99, to); }
2938 void SETB8R( x86IntRegType to ) { SET8R( 0x92, to ); }
2940 void SETNZ8R( x86IntRegType to ) { SET8R( 0x95, to ); }
2942 void SETZ8R( x86IntRegType to ) { SET8R(0x94, to); }
2944 void SETE8R( x86IntRegType to ) { SET8R(0x94, to); }
2947 void PUSH32I( u32 from )
2949 //X86_64ASSERT(); //becomes sign extended in x86_64
2957 void PUSH64R( x86IntRegType from )
2960 //write8( 0x51 | from );
2961 write8( 0x50 | from );
2965 void PUSH64M( uptr from )
2967 MEMADDR_OP(0, VAROP1(0xFF), false, 6, from, 0);
2971 void POP64R( x86IntRegType from ) {
2973 //write8( 0x59 | from );
2974 write8( 0x58 | from );
2977 void PUSHR(x86IntRegType from) { PUSH64R(from); }
2978 void POPR(x86IntRegType from) { POP64R(from); }
2983 void PUSH32R( x86IntRegType from ) { write8( 0x50 | from ); }
2986 void PUSH32M( uptr from )
2988 MEMADDR_OP(0, VAROP1(0xFF), false, 6, from, 0);
2992 void POP32R( x86IntRegType from ) { write8( 0x58 | from ); }
2995 void PUSHA32( void ) { write8( 0x60 ); }
2998 void POPA32( void ) { write8( 0x61 ); }
3000 void PUSHR(x86IntRegType from) { PUSH32R(from); }
3001 void POPR(x86IntRegType from) { POP32R(from); }
3007 void PUSHFD( void ) { write8( 0x9C ); }
3009 void POPFD( void ) { write8( 0x9D ); }
3011 void RET( void ) { write8( 0xC3 ); }
3012 void RET2( void ) { write16( 0xc3f3 ); }
3014 void CBW( void ) { write16( 0x9866 ); }
3015 void CWD( void ) { write8( 0x98 ); }
3016 void CDQ( void ) { write8( 0x99 ); }
3017 void CWDE() { write8(0x98); }
3020 void CDQE( void ) { RexR(1,0); write8( 0x98 ); }
3023 void LAHF() { write8(0x9f); }
3024 void SAHF() { write8(0x9e); }
3026 void BT32ItoR( x86IntRegType to, x86IntRegType from )
3029 write8( 0xE0 | to );
3033 void BSRRtoR(x86IntRegType to, x86IntRegType from)
3036 ModRM( 3, from, to );
3039 void BSWAP32R( x86IntRegType to )
3042 write8( 0xC8 + to );
3045 // to = from + offset
3046 void LEA16RtoR(x86IntRegType to, x86IntRegType from, u16 offset)
3049 LEA32RtoR(to, from, offset);
3052 void LEA32RtoR(x86IntRegType to, x86IntRegType from, u32 offset)
3057 if( (from&7) == ESP ) {
3062 else if( offset < 128 ) {
3074 if( offset == 0 && from != EBP && from!=ESP ) {
3077 else if( offset < 128 ) {
3088 // to = from0 + from1
3089 void LEA16RRtoR(x86IntRegType to, x86IntRegType from0, x86IntRegType from1)
3092 LEA32RRtoR(to, from0, from1);
3095 void LEA32RRtoR(x86IntRegType to, x86IntRegType from0, x86IntRegType from1)
3097 RexRXB(0, to, from0, from1);
3100 if( (from1&7) == EBP ) {
3102 ModRM(0, from0, from1);
3107 ModRM(0, from0, from1);
3111 // to = from << scale (max is 3)
3112 void LEA16RStoR(x86IntRegType to, x86IntRegType from, u32 scale)
3115 LEA32RStoR(to, from, scale);
3118 void LEA32RStoR(x86IntRegType to, x86IntRegType from, u32 scale)
3121 SHL32ItoR(to, scale);
3126 RexRXB(0,to,from,0);
3129 ModRM(scale, from, 5);
3133 assert( to != ESP );
3134 MOV32RtoR(to, from);
3135 LEA32RStoR(to, to, scale);