--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401173
		
			
				
	
	
		
			1494 lines
		
	
	
		
			44 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1494 lines
		
	
	
		
			44 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /**
 | |
|  * vim: set ts=4 :
 | |
|  * ================================================================
 | |
|  * SourcePawn (C)2004-2007 AlliedModders LLC.  All rights reserved.
 | |
|  * ================================================================
 | |
|  *
 | |
|  * This file is not open source and may not be copied without explicit
 | |
|  * written permission of AlliedModders LLC.  This file may not be redistributed 
 | |
|  * in whole or significant part.
 | |
|  * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
 | |
|  *
 | |
|  * Version: $Id$
 | |
|  */
 | |
| 
 | |
| #ifndef _INCLUDE_JIT_X86_MACROS_H
 | |
| #define _INCLUDE_JIT_X86_MACROS_H
 | |
| 
 | |
| #include <limits.h>
 | |
| 
 | |
| //MOD R/M
 | |
| #define MOD_MEM_REG	0
 | |
| #define MOD_DISP8	1
 | |
| #define MOD_DISP32	2
 | |
| #define MOD_REG		3
 | |
| 
 | |
| //SIB
 | |
| #define NOSCALE		0
 | |
| #define	SCALE2		1
 | |
| #define	SCALE4		2
 | |
| #define SCALE8		3
 | |
| 
 | |
| //Register codes
 | |
| #define REG_EAX			0
 | |
| #define REG_ECX			1
 | |
| #define REG_EDX			2
 | |
| #define REG_EBX			3
 | |
| #define	REG_ESP			4
 | |
| #define	REG_SIB			4
 | |
| #define REG_NOIDX		4
 | |
| #define REG_IMM_BASE	5
 | |
| #define REG_EBP			5
 | |
| #define REG_ESI			6
 | |
| #define REG_EDI			7
 | |
| 
 | |
| #define IA32_16BIT_PREFIX	0x66
 | |
| 
 | |
| //condition codes (for example, Jcc opcodes)
 | |
| #define CC_B	0x2
 | |
| #define CC_NAE	CC_B
 | |
| #define CC_NB	0x3
 | |
| #define CC_AE	CC_NB
 | |
| #define CC_E	0x4
 | |
| #define CC_Z	CC_E
 | |
| #define CC_NE	0x5
 | |
| #define CC_NZ	CC_NE
 | |
| #define CC_NA	0x6
 | |
| #define CC_BE	CC_NA
 | |
| #define CC_A	0x7
 | |
| #define CC_NBE	CC_A
 | |
| #define CC_L	0xC
 | |
| #define CC_NGE	CC_L
 | |
| #define CC_NL	0xD
 | |
| #define CC_GE	CC_NL
 | |
| #define CC_NG	0xE
 | |
| #define CC_LE	CC_NG
 | |
| #define CC_G	0xF
 | |
| #define CC_NLE	CC_G
 | |
| 
 | |
| //Opcodes with encoding information
 | |
| #define IA32_XOR_RM_REG			0x31	// encoding is /r
 | |
| #define IA32_XOR_REG_RM			0x33	// encoding is /r
 | |
| #define IA32_XOR_EAX_IMM32		0x35	// encoding is /r
 | |
| #define IA32_XOR_RM_IMM32		0x81	// encoding is /6
 | |
| #define IA32_XOR_RM_IMM8		0x83	// encoding is /6
 | |
| #define IA32_ADD_RM_REG			0x01	// encoding is /r
 | |
| #define IA32_ADD_REG_RM			0x03	// encoding is /r
 | |
| #define IA32_ADD_RM_IMM32		0x81	// encoding is /0
 | |
| #define IA32_ADD_RM_IMM8		0x83	// encoding is /0
 | |
| #define IA32_ADD_EAX_IMM32		0x05	// no extra encoding
 | |
| #define IA32_SUB_RM_REG			0x29	// encoding is /r
 | |
| #define IA32_SUB_REG_RM			0x2B	// encoding is /r
 | |
| #define IA32_SUB_RM_IMM8		0x83	// encoding is /5 <imm8>
 | |
| #define IA32_SUB_RM_IMM32		0x81	// encoding is /5 <imm32>
 | |
| #define IA32_SBB_REG_RM			0x1B	// encoding is /r
 | |
| #define IA32_SBB_RM_IMM8		0x83	// encoding is <imm32>
 | |
| #define IA32_JMP_IMM32			0xE9	// encoding is imm32
 | |
| #define IA32_JMP_IMM8			0xEB	// encoding is imm8
 | |
| #define IA32_JMP_RM				0xFF	// encoding is /4
 | |
| #define IA32_CALL_IMM32			0xE8	// relative call, <imm32>
 | |
| #define IA32_CALL_RM			0xFF	// encoding is /2
 | |
| #define IA32_MOV_REG_IMM		0xB8	// encoding is +r <imm32>
 | |
| #define	IA32_MOV_RM8_REG		0x88	// encoding is /r
 | |
| #define	IA32_MOV_RM_REG			0x89	// encoding is /r
 | |
| #define	IA32_MOV_REG_RM			0x8B	// encoding is /r
 | |
| #define IA32_MOV_REG8_RM8		0x8A	// encoding is /r
 | |
| #define IA32_MOV_RM8_REG8		0x88	// encoding is /r
 | |
| #define IA32_MOV_RM_IMM32		0xC7	// encoding is /0
 | |
| #define IA32_CMP_RM_IMM32		0x81	// encoding is /7 <imm32>
 | |
| #define IA32_CMP_RM_IMM8		0x83	// encoding is /7 <imm8>
 | |
| #define IA32_CMP_AL_IMM32		0x3C	// no extra encoding
 | |
| #define IA32_CMP_EAX_IMM32		0x3D	// no extra encoding
 | |
| #define IA32_CMP_RM_REG			0x39	// encoding is /r
 | |
| #define IA32_CMP_REG_RM			0x3B	// encoding is /r
 | |
| #define IA32_CMPSB				0xA6	// no extra encoding
 | |
| #define IA32_TEST_RM_REG		0x85	// encoding is /r
 | |
| #define IA32_JCC_IMM			0x70	// encoding is +cc <imm8>
 | |
| #define IA32_JCC_IMM32_1		0x0F	// opcode part 1
 | |
| #define IA32_JCC_IMM32_2		0x80	// encoding is +cc <imm32>
 | |
| #define IA32_RET				0xC3	// no extra encoding
 | |
| #define IA32_RETN				0xC2	// encoding is <imm16> 
 | |
| #define IA32_NEG_RM				0xF7	// encoding is /3
 | |
| #define IA32_INC_REG			0x40	// encoding is +r
 | |
| #define IA32_INC_RM				0xFF	// encoding is /0
 | |
| #define IA32_DEC_REG			0x48	// encoding is +r
 | |
| #define IA32_DEC_RM				0xFF	// encoding is /1
 | |
| #define IA32_OR_REG_RM			0x0B	// encoding is /r
 | |
| #define IA32_AND_REG_RM			0x23	// encoding is /r
 | |
| #define IA32_AND_EAX_IMM32		0x25	// encoding is <imm32>
 | |
| #define IA32_AND_RM_IMM32		0x81	// encoding is /4
 | |
| #define IA32_AND_RM_IMM8		0x83	// encoding is /4
 | |
| #define IA32_NOT_RM				0xF7	// encoding is /2
 | |
| #define IA32_DIV_RM				0xF7	// encoding is /6
 | |
| #define IA32_MUL_RM				0xF7	// encoding is /4
 | |
| #define IA32_IDIV_RM			0xF7	// encoding is /7
 | |
| #define IA32_IMUL_RM			0xF7	// encoding is /5
 | |
| #define IA32_IMUL_REG_IMM32		0x69	// encoding is /r
 | |
| #define IA32_IMUL_REG_IMM8		0x6B	// encoding is /r
 | |
| #define IA32_IMUL_REG_RM_1		0x0F	// encoding is _2
 | |
| #define IA32_IMUL_REG_RM_2		0xAF	// encoding is /r
 | |
| #define IA32_SHR_RM_IMM8		0xC1	// encoding is /5 <ib>
 | |
| #define IA32_SHR_RM_1			0xD1	// encoding is /5
 | |
| #define IA32_SHL_RM_IMM8		0xC1	// encoding is /4 <ib>
 | |
| #define IA32_SHL_RM_1			0xD1	// encoding is /4
 | |
| #define IA32_SAR_RM_CL			0xD3	// encoding is /7
 | |
| #define IA32_SAR_RM_1			0xD1	// encoding is /7
 | |
| #define IA32_SHR_RM_CL			0xD3	// encoding is /5
 | |
| #define IA32_SHL_RM_CL			0xD3	// encoding is /4
 | |
| #define IA32_SAR_RM_IMM8		0xC1	// encoding is /7 <ib>
 | |
| #define IA32_SETCC_RM8_1		0x0F	// opcode part 1
 | |
| #define IA32_SETCC_RM8_2		0x90	// encoding is +cc /0 (8bits)
 | |
| #define IA32_CMOVCC_RM_1		0x0F	// opcode part 1
 | |
| #define IA32_CMOVCC_RM_2		0x40	// encoding is +cc /r
 | |
| #define IA32_XCHG_EAX_REG		0x90	// encoding is +r
 | |
| #define IA32_LEA_REG_MEM		0x8D	// encoding is /r
 | |
| #define IA32_POP_REG			0x58	// encoding is +r
 | |
| #define IA32_PUSH_REG			0x50	// encoding is +r
 | |
| #define IA32_PUSH_RM			0xFF	// encoding is /6
 | |
| #define IA32_PUSH_IMM32			0x68	// encoding is <imm32>
 | |
| #define IA32_PUSH_IMM8			0x6A	// encoding is <imm8>
 | |
| #define IA32_REP				0xF3	// no extra encoding
 | |
| #define IA32_MOVSD				0xA5	// no extra encoding
 | |
| #define IA32_MOVSB				0xA4	// no extra encoding
 | |
| #define IA32_STOSD				0xAB	// no extra encoding
 | |
| #define IA32_CLD				0xFC	// no extra encoding
 | |
| #define IA32_PUSHAD				0x60	// no extra encoding
 | |
| #define IA32_POPAD				0x61	// no extra encoding
 | |
| #define IA32_NOP				0x90	// no extra encoding
 | |
| #define IA32_INT3				0xCC	// no extra encoding
 | |
| #define IA32_FSTP_MEM32			0xD9	// encoding is /3
 | |
| #define IA32_FSTP_MEM64			0xDD	// encoding is /3
 | |
| #define IA32_FLD_MEM32			0xD9	// encoding is /0
 | |
| #define IA32_FLD_MEM64			0xDD	// encoding is /0
 | |
| #define IA32_FILD_MEM32			0xDB	// encoding is /0
 | |
| #define IA32_FADD_MEM32			0xD8	// encoding is /0
 | |
| #define IA32_FADD_FPREG_ST0_1	0xDC	// opcode part 1
 | |
| #define IA32_FADD_FPREG_ST0_2	0xC0	// encoding is +r
 | |
| #define IA32_FSUB_MEM32			0xD8	// encoding is /4
 | |
| #define IA32_FMUL_MEM32			0xD8	// encoding is /1
 | |
| #define IA32_FDIV_MEM32			0xD8	// encoding is /6
 | |
| #define IA32_FSTCW_MEM16_1		0x9B	// opcode part 1
 | |
| #define IA32_FSTCW_MEM16_2		0xD9	// encoding is /7
 | |
| #define IA32_FLDCW_MEM16		0xD9	// encoding is /5
 | |
| #define IA32_FISTP_MEM32		0xDB	// encoding is /3
 | |
| #define IA32_FUCOMIP_1			0xDF	// opcode part 1
 | |
| #define IA32_FUCOMIP_2			0xE8	// encoding is +r
 | |
| #define IA32_FSTP_FPREG_1		0xDD	// opcode part 1
 | |
| #define IA32_FSTP_FPREG_2		0xD8	// encoding is +r
 | |
| #define IA32_MOVZX_R32_RM8_1	0x0F	// opcode part 1
 | |
| #define IA32_MOVZX_R32_RM8_2	0xB6	// encoding is /r
 | |
| #define IA32_MOVZX_R32_RM16_1	0x0F	// opcode part 1
 | |
| #define IA32_MOVZX_R32_RM16_2	0xB7	// encoding is /r
 | |
| 
 | |
| inline jit_uint8_t ia32_modrm(jit_uint8_t mode, jit_uint8_t reg, jit_uint8_t rm)
 | |
| {
 | |
| 	jit_uint8_t modrm = (mode << 6);
 | |
| 
 | |
| 	modrm |= (reg << 3);
 | |
| 	modrm |= (rm);
 | |
| 
 | |
| 	return modrm;
 | |
| }
 | |
| 
 | |
| //mode is the scaling method - NOSCALE ... SCALE8
 | |
| //index is the register that is scaled
 | |
| //base is the base register
 | |
| inline jit_uint8_t ia32_sib(jit_uint8_t mode, jit_uint8_t index, jit_uint8_t base)
 | |
| {
 | |
| 	jit_uint8_t sib = (mode << 6);
 | |
| 
 | |
| 	sib |= (index << 3);
 | |
| 	sib |= (base);
 | |
| 
 | |
| 	return sib;
 | |
| }
 | |
| 
 | |
| /***********************
 | |
|  * INCREMENT/DECREMENT *
 | |
|  ***********************/
 | |
| 
 | |
| inline void IA32_Inc_Reg(JitWriter *jit, jit_uint8_t reg)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_INC_REG+reg);
 | |
| }
 | |
| 
 | |
| inline void IA32_Inc_Rm_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_INC_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, reg));
 | |
| 	jit->write_byte(disp);
 | |
| }
 | |
| 
 | |
| inline void IA32_Inc_Rm_Disp32(JitWriter *jit, jit_uint8_t reg, jit_int32_t disp)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_INC_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, reg));
 | |
| 	jit->write_int32(disp);
 | |
| }
 | |
| 
 | |
| inline void IA32_Inc_Rm_Disp_Reg(JitWriter *jit, jit_uint8_t base, jit_uint8_t reg, jit_uint8_t scale)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_INC_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 0, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(scale, reg, base));
 | |
| }
 | |
| 
 | |
| inline void IA32_Dec_Reg(JitWriter *jit, jit_uint8_t reg)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_DEC_REG+reg);
 | |
| }
 | |
| 
 | |
| inline void IA32_Dec_Rm_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_DEC_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, 1, reg));
 | |
| 	jit->write_byte(disp);
 | |
| }
 | |
| 
 | |
| inline void IA32_Dec_Rm_Disp32(JitWriter *jit, jit_uint8_t reg, jit_int32_t disp)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_DEC_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP32, 1, reg));
 | |
| 	jit->write_int32(disp);
 | |
| }
 | |
| 
 | |
| inline void IA32_Dec_Rm_Disp_Reg(JitWriter *jit, jit_uint8_t base, jit_uint8_t reg, jit_uint8_t scale)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_DEC_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 1, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(scale, reg, base));
 | |
| }
 | |
| 
 | |
| /****************
 | |
|  * BINARY LOGIC *
 | |
|  ****************/
 | |
| 
 | |
| inline void IA32_Xor_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t dest_mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_XOR_RM_REG);
 | |
| 	jit->write_ubyte(ia32_modrm(dest_mode, src, dest));
 | |
| }
 | |
| 
 | |
| inline void IA32_Xor_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t dest_mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_XOR_REG_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(dest_mode, dest, src));
 | |
| }
 | |
| 
 | |
| inline void IA32_Xor_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int8_t value)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_XOR_RM_IMM8);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 6, reg));
 | |
| 	jit->write_byte(value);
 | |
| }
 | |
| 
 | |
| inline void IA32_Xor_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int32_t value)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_XOR_RM_IMM32);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 6, reg));
 | |
| 	jit->write_int32(value);
 | |
| }
 | |
| 
 | |
| inline void IA32_Xor_Eax_Imm32(JitWriter *jit, jit_int32_t value)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_XOR_EAX_IMM32);
 | |
| 	jit->write_int32(value);
 | |
| }
 | |
| 
 | |
| inline void IA32_Neg_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_NEG_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 3, reg));
 | |
| }
 | |
| 
 | |
| inline void IA32_Or_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_OR_REG_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, dest, src));
 | |
| }
 | |
| 
 | |
| inline void IA32_And_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_AND_REG_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, dest, src));
 | |
| }
 | |
| 
 | |
| inline void IA32_And_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int32_t value)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_AND_RM_IMM32);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 4, reg));
 | |
| 	jit->write_int32(value);
 | |
| }
 | |
| 
 | |
| inline void IA32_And_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int8_t value)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_AND_RM_IMM8);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 4, reg));
 | |
| 	jit->write_byte(value);
 | |
| }
 | |
| 
 | |
| inline void IA32_And_Eax_Imm32(JitWriter *jit, jit_int32_t value)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_AND_EAX_IMM32);
 | |
| 	jit->write_int32(value);
 | |
| }
 | |
| 
 | |
| inline void IA32_Not_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_NOT_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 2, reg));
 | |
| }
 | |
| 
 | |
| inline void IA32_Shr_Rm_Imm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t value, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_SHR_RM_IMM8);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 5, dest));
 | |
| 	jit->write_ubyte(value);
 | |
| }
 | |
| 
 | |
| inline void IA32_Shr_Rm_1(JitWriter *jit, jit_uint8_t dest, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_SHR_RM_1);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 5, dest));
 | |
| }
 | |
| 
 | |
| inline void IA32_Shl_Rm_Imm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t value, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_SHL_RM_IMM8);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 4, dest));
 | |
| 	jit->write_ubyte(value);
 | |
| }
 | |
| 
 | |
| inline void IA32_Shl_Rm_1(JitWriter *jit, jit_uint8_t dest, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_SHL_RM_1);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 4, dest));
 | |
| }
 | |
| 
 | |
| inline void IA32_Sar_Rm_Imm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t value, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_SAR_RM_IMM8);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 7, dest));
 | |
| 	jit->write_ubyte(value);
 | |
| }
 | |
| 
 | |
| inline void IA32_Sar_Rm_CL(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_SAR_RM_CL);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 7, reg));
 | |
| }
 | |
| 
 | |
| inline void IA32_Sar_Rm_1(JitWriter *jit, jit_uint8_t dest, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_SAR_RM_1);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 7, dest));
 | |
| }
 | |
| 
 | |
| inline void IA32_Shr_Rm_CL(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_SHR_RM_CL);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 5, reg));
 | |
| }
 | |
| 
 | |
| inline void IA32_Shl_Rm_CL(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_SHL_RM_CL);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 4, reg));
 | |
| }
 | |
| 
 | |
| inline void IA32_Xchg_Eax_Reg(JitWriter *jit, jit_uint8_t reg)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_XCHG_EAX_REG+reg);
 | |
| }
 | |
| 
 | |
| /**********************
 | |
|  * ARITHMETIC (BASIC) *
 | |
|  **********************/
 | |
| 
 | |
| inline void IA32_Add_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_ADD_RM_REG);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, src, dest));
 | |
| }
 | |
| 
 | |
| inline void IA32_Add_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_ADD_REG_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, dest, src));
 | |
| }
 | |
| 
 | |
| inline void IA32_Add_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_int8_t value, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_ADD_RM_IMM8);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 0, reg));
 | |
| 	jit->write_byte(value);
 | |
| }
 | |
| 
 | |
| inline void IA32_Add_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_int32_t value, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_ADD_RM_IMM32);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 0, reg));
 | |
| 	jit->write_int32(value);
 | |
| }
 | |
| 
 | |
| inline void IA32_Add_Eax_Imm32(JitWriter *jit, jit_int32_t value)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_ADD_EAX_IMM32);
 | |
| 	jit->write_int32(value);
 | |
| }
 | |
| 
 | |
| inline void IA32_Sub_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_SUB_RM_REG);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, src, dest));
 | |
| }
 | |
| 
 | |
| inline void IA32_Sub_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_SUB_REG_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, dest, src));
 | |
| }
 | |
| 
 | |
| inline void IA32_Sub_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp8)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_SUB_REG_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src));
 | |
| 	jit->write_byte(disp8);
 | |
| }
 | |
| 
 | |
| inline void IA32_Sub_Rm_Reg_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp8)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_SUB_RM_REG);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, src, dest));
 | |
| 	jit->write_byte(disp8);
 | |
| }
 | |
| 
 | |
| inline void IA32_Sub_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_int8_t val, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_SUB_RM_IMM8);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 5, reg));
 | |
| 	jit->write_byte(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Sub_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_int32_t val, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_SUB_RM_IMM32);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 5, reg));
 | |
| 	jit->write_int32(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Sbb_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_SBB_REG_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, dest, src));
 | |
| }
 | |
| 
 | |
| inline void IA32_Sbb_Rm_Imm8(JitWriter *jit, jit_uint8_t dest, jit_int8_t value, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_SBB_RM_IMM8);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 3, dest));
 | |
| 	jit->write_byte(value);
 | |
| }
 | |
| 
 | |
| inline void IA32_Div_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_DIV_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 6, reg));
 | |
| }
 | |
| 
 | |
| inline void IA32_IDiv_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_IDIV_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 7, reg));
 | |
| }
 | |
| 
 | |
| inline void IA32_Mul_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MUL_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 4, reg));
 | |
| }
 | |
| 
 | |
| inline void IA32_IMul_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_IMUL_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 5, reg));
 | |
| }
 | |
| 
 | |
| inline void IA32_IMul_Reg_Imm8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int8_t value)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_IMUL_REG_IMM8);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 0, reg));
 | |
| 	jit->write_byte(value);
 | |
| }
 | |
| 
 | |
| inline void IA32_IMul_Reg_Imm32(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int32_t value)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_IMUL_REG_IMM32);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 0, reg));
 | |
| 	jit->write_int32(value);
 | |
| }
 | |
| 
 | |
| inline void IA32_IMul_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_IMUL_REG_RM_1);
 | |
| 	jit->write_ubyte(IA32_IMUL_REG_RM_2);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, dest, src));
 | |
| }
 | |
| 
 | |
| inline void IA32_Add_Rm_Reg_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_ADD_RM_REG);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, src, dest));
 | |
| 	jit->write_byte(disp);
 | |
| }
 | |
| 
 | |
| inline void IA32_Add_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_ADD_REG_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src));
 | |
| 	jit->write_byte(disp);
 | |
| }
 | |
| 
 | |
| inline void IA32_Add_Rm_Imm8_Disp8(JitWriter *jit, 
 | |
| 							 jit_uint8_t dest, 
 | |
| 							 jit_int8_t val, 
 | |
| 							 jit_int8_t disp8)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_ADD_RM_IMM8);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, dest));
 | |
| 	jit->write_byte(disp8);
 | |
| 	jit->write_byte(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Add_Rm_Imm32_Disp8(JitWriter *jit, 
 | |
| 							 jit_uint8_t dest, 
 | |
| 							 jit_int32_t val, 
 | |
| 							 jit_int8_t disp8)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_ADD_RM_IMM32);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, dest));
 | |
| 	jit->write_byte(disp8);
 | |
| 	jit->write_int32(val);
 | |
| }
 | |
| 
 | |
| inline jitoffs_t IA32_Add_Rm_Imm32_Later(JitWriter *jit, 
 | |
| 									jit_uint8_t dest, 
 | |
| 									jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_ADD_RM_IMM32);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 0, dest));
 | |
| 	jitoffs_t ptr = jit->get_outputpos();
 | |
| 	jit->write_int32(0);
 | |
| 	return ptr;
 | |
| }
 | |
| 
 | |
| inline void IA32_Add_Rm_Imm8_Disp32(JitWriter *jit, 
 | |
| 							jit_uint8_t dest, 
 | |
| 							jit_int8_t val, 
 | |
| 							jit_int32_t disp32)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_ADD_RM_IMM8);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, dest));
 | |
| 	jit->write_int32(disp32);
 | |
| 	jit->write_byte(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Add_RmEBP_Imm8_Disp_Reg(JitWriter *jit, 
 | |
| 								jit_uint8_t dest_base, 
 | |
| 								jit_uint8_t dest_index,
 | |
| 								jit_uint8_t dest_scale,
 | |
| 								jit_int8_t val)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_ADD_RM_IMM8);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base));
 | |
| 	jit->write_byte(0);
 | |
| 	jit->write_byte(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Sub_Rm_Imm8_Disp8(JitWriter *jit, 
 | |
| 							jit_uint8_t dest, 
 | |
| 							jit_int8_t val, 
 | |
| 							jit_int8_t disp8)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_SUB_RM_IMM8);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, 5, dest));
 | |
| 	jit->write_byte(disp8);
 | |
| 	jit->write_byte(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Sub_Rm_Imm8_Disp32(JitWriter *jit, 
 | |
| 							 jit_uint8_t dest, 
 | |
| 							 jit_int8_t val, 
 | |
| 							 jit_int32_t disp32)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_SUB_RM_IMM8);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP32, 5, dest));
 | |
| 	jit->write_int32(disp32);
 | |
| 	jit->write_byte(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Sub_RmEBP_Imm8_Disp_Reg(JitWriter *jit, 
 | |
| 							   jit_uint8_t dest_base, 
 | |
| 							   jit_uint8_t dest_index,
 | |
| 							   jit_uint8_t dest_scale,
 | |
| 							   jit_int8_t val)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_SUB_RM_IMM8);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, 5, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base));
 | |
| 	jit->write_byte(0);
 | |
| 	jit->write_byte(val);
 | |
| }
 | |
| 
 | |
| /**
 | |
| * Memory Instructions
 | |
| */
 | |
| 
 | |
| inline void IA32_Lea_Reg_DispRegMult(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_uint8_t src_index, jit_uint8_t scale)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_LEA_REG_MEM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(scale, src_index, src_base));
 | |
| }
 | |
| 
 | |
| inline void IA32_Lea_Reg_DispEBPRegMult(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_uint8_t src_index, jit_uint8_t scale)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_LEA_REG_MEM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(scale, src_index, src_base));
 | |
| 	jit->write_byte(0);
 | |
| }
 | |
| 
 | |
| inline void IA32_Lea_Reg_DispRegMultImm8(JitWriter *jit, 
 | |
| 							  jit_uint8_t dest, 
 | |
| 							  jit_uint8_t src_base, 
 | |
| 							  jit_uint8_t src_index, 
 | |
| 							  jit_uint8_t scale, 
 | |
| 							  jit_int8_t val)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_LEA_REG_MEM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(scale, src_index, src_base));
 | |
| 	jit->write_byte(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Lea_Reg_DispRegMultImm32(JitWriter *jit, 
 | |
| 										 jit_uint8_t dest, 
 | |
| 										 jit_uint8_t src_base, 
 | |
| 										 jit_uint8_t src_index, 
 | |
| 										 jit_uint8_t scale, 
 | |
| 										 jit_int32_t val)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_LEA_REG_MEM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(scale, src_index, src_base));
 | |
| 	jit->write_int32(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Lea_Reg_RegMultImm32(JitWriter *jit, 
 | |
| 										jit_uint8_t dest, 
 | |
| 										jit_uint8_t src_index, 
 | |
| 										jit_uint8_t scale, 
 | |
| 										jit_int32_t val)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_LEA_REG_MEM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(scale, src_index, REG_IMM_BASE));
 | |
| 	jit->write_int32(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Lea_DispRegImm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_int8_t val)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_LEA_REG_MEM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src_base));
 | |
| 	jit->write_byte(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Lea_DispRegImm32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_int32_t val)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_LEA_REG_MEM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, src_base));
 | |
| 	jit->write_int32(val);
 | |
| }
 | |
| 
 | |
| /**
 | |
| * Stack Instructions
 | |
| */
 | |
| 
 | |
| inline void IA32_Pop_Reg(JitWriter *jit, jit_uint8_t reg)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_POP_REG+reg);
 | |
| }
 | |
| 
 | |
| inline void IA32_Push_Reg(JitWriter *jit, jit_uint8_t reg)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_PUSH_REG+reg);
 | |
| }
 | |
| 
 | |
| inline void IA32_Push_Imm8(JitWriter *jit, jit_int8_t val)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_PUSH_IMM8);
 | |
| 	jit->write_byte(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Push_Imm32(JitWriter *jit, jit_int32_t val)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_PUSH_IMM32);
 | |
| 	jit->write_int32(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Pushad(JitWriter *jit)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_PUSHAD);
 | |
| }
 | |
| 
 | |
| inline void IA32_Popad(JitWriter *jit)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_POPAD);
 | |
| }
 | |
| 
 | |
| inline void IA32_Push_Rm_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp8)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_PUSH_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, 6, reg));
 | |
| 	jit->write_byte(disp8);
 | |
| }
 | |
| 
 | |
| inline void IA32_Push_Rm_Disp8_ESP(JitWriter *jit, jit_int8_t disp8)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_PUSH_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, 6, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
 | |
| 	jit->write_byte(disp8);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Moving from REGISTER/MEMORY to REGISTER
 | |
|  */
 | |
| 
 | |
| inline void IA32_Mov_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOV_REG_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, dest, src));
 | |
| }
 | |
| 
 | |
| inline void IA32_Mov_Reg8_Rm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOV_REG8_RM8);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, dest, src));
 | |
| }
 | |
| 
 | |
| inline void IA32_Mov_Reg_RmESP(JitWriter *jit, jit_uint8_t dest)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOV_REG_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest, REG_ESP));
 | |
| 	jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
 | |
| }
 | |
| 
 | |
| inline void IA32_Mov_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOV_REG_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src));
 | |
| 	jit->write_byte(disp);
 | |
| }
 | |
| 
 | |
| inline void IA32_Mov_Reg8_Rm8_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOV_REG8_RM8);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src));
 | |
| 	jit->write_byte(disp);
 | |
| }
 | |
| 
 | |
| inline void IA32_Mov_Reg_Esp_Disp8(JitWriter *jit, jit_uint8_t dest, jit_int8_t disp)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOV_REG_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
 | |
| 	jit->write_byte(disp);
 | |
| }
 | |
| 
 | |
| inline void IA32_Mov_Reg_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOV_REG_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, src));
 | |
| 	jit->write_int32(disp);
 | |
| }
 | |
| 
 | |
| inline void IA32_Mov_Reg8_Rm8_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOV_REG8_RM8);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, src));
 | |
| 	jit->write_int32(disp);
 | |
| }
 | |
| 
 | |
| inline void IA32_Mov_Reg_Rm_Disp_Reg(JitWriter *jit, 
 | |
| 							jit_uint8_t dest, 
 | |
| 							jit_uint8_t src_base, 
 | |
| 							jit_uint8_t src_index,
 | |
| 							jit_uint8_t src_scale)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOV_REG_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(src_scale, src_index, src_base));
 | |
| }
 | |
| 
 | |
| inline void IA32_Mov_Reg_Rm_Disp_Reg_Disp8(JitWriter *jit, 
 | |
| 									 jit_uint8_t dest, 
 | |
| 									 jit_uint8_t src_base, 
 | |
| 									 jit_uint8_t src_index,
 | |
| 									 jit_uint8_t src_scale,
 | |
| 									 jit_int8_t disp8)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOV_REG_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(src_scale, src_index, src_base));
 | |
| 	jit->write_byte(disp8);
 | |
| }
 | |
| 
 | |
| inline void IA32_Mov_Reg_RmEBP_Disp_Reg(JitWriter *jit, 
 | |
| 									 jit_uint8_t dest, 
 | |
| 									 jit_uint8_t src_base, 
 | |
| 									 jit_uint8_t src_index,
 | |
| 									 jit_uint8_t src_scale)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOV_REG_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(src_scale, src_index, src_base));
 | |
| 	jit->write_byte(0);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Moving from REGISTER to REGISTER/MEMORY
 | |
|  */
 | |
| 
 | |
| inline void IA32_Mov_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOV_RM_REG);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, src, dest));
 | |
| }
 | |
| 
 | |
| inline void IA32_Mov_Rm8_Reg8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOV_RM8_REG8);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, src, dest));
 | |
| }
 | |
| 
 | |
| inline void IA32_Mov_RmESP_Reg(JitWriter *jit, jit_uint8_t src)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOV_RM_REG);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_MEM_REG, src, REG_ESP));
 | |
| 	jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
 | |
| }
 | |
| 
 | |
| inline void IA32_Mov_Rm_Reg_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOV_RM_REG);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, src, dest));
 | |
| 	jit->write_byte(disp);
 | |
| }
 | |
| 
 | |
| inline void IA32_Mov_Rm_Reg_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOV_RM_REG);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP32, src, dest));
 | |
| 	jit->write_int32(disp);
 | |
| }
 | |
| 
 | |
| inline void IA32_Mov_RmEBP_Reg_Disp_Reg(JitWriter *jit, 
 | |
| 							  jit_uint8_t dest_base, 
 | |
| 							  jit_uint8_t dest_index,
 | |
| 							  jit_uint8_t dest_scale,
 | |
| 							  jit_uint8_t src)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOV_RM_REG);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, src, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base));
 | |
| 	jit->write_byte(0);
 | |
| }
 | |
| 
 | |
| inline void IA32_Mov_Rm8EBP_Reg_Disp_Reg(JitWriter *jit, 
 | |
| 									 jit_uint8_t dest_base, 
 | |
| 									 jit_uint8_t dest_index,
 | |
| 									 jit_uint8_t dest_scale,
 | |
| 									 jit_uint8_t src)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOV_RM8_REG);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, src, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base));
 | |
| 	jit->write_byte(0);
 | |
| }
 | |
| 
 | |
| inline void IA32_Mov_Rm16EBP_Reg_Disp_Reg(JitWriter *jit, 
 | |
| 									  jit_uint8_t dest_base, 
 | |
| 									  jit_uint8_t dest_index,
 | |
| 									  jit_uint8_t dest_scale,
 | |
| 									  jit_uint8_t src)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_16BIT_PREFIX);
 | |
| 	jit->write_ubyte(IA32_MOV_RM_REG);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, src, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base));
 | |
| 	jit->write_byte(0);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Moving from IMMEDIATE to REGISTER
 | |
|  */
 | |
| 
 | |
| inline jitoffs_t IA32_Mov_Reg_Imm32(JitWriter *jit, jit_uint8_t dest, jit_int32_t num)
 | |
| {
 | |
| 	jitoffs_t offs;
 | |
| 	jit->write_ubyte(IA32_MOV_REG_IMM+dest);
 | |
| 	offs = jit->get_outputpos();
 | |
| 	jit->write_int32(num);
 | |
| 	return offs;
 | |
| }
 | |
| 
 | |
| inline void IA32_Mov_Rm_Imm32(JitWriter *jit, jit_uint8_t dest, jit_int32_t val, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOV_RM_IMM32);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 0, dest));
 | |
| 	jit->write_int32(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Mov_Rm_Imm32_Disp8(JitWriter *jit, 
 | |
| 							 jit_uint8_t dest, 
 | |
| 							 jit_int32_t val, 
 | |
| 							 jit_int8_t disp8)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOV_RM_IMM32);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, dest));
 | |
| 	jit->write_byte(disp8);
 | |
| 	jit->write_int32(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Mov_Rm_Imm32_Disp32(JitWriter *jit, 
 | |
| 							 jit_uint8_t dest, 
 | |
| 							 jit_int32_t val, 
 | |
| 							 jit_int32_t disp32)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOV_RM_IMM32);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, dest));
 | |
| 	jit->write_int32(disp32);
 | |
| 	jit->write_int32(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Mov_RmEBP_Imm32_Disp_Reg(JitWriter *jit, 
 | |
| 								jit_uint8_t dest_base, 
 | |
| 								jit_uint8_t dest_index, 
 | |
| 								jit_uint8_t dest_scale, 
 | |
| 								jit_int32_t val)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOV_RM_IMM32);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base));
 | |
| 	jit->write_byte(0);
 | |
| 	jit->write_int32(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Mov_ESP_Disp8_Imm32(JitWriter *jit, jit_int8_t disp8, jit_int32_t val)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOV_RM_IMM32);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
 | |
| 	jit->write_byte(disp8);
 | |
| 	jit->write_int32(val);
 | |
| }
 | |
| 
 | |
| /**
 | |
| * Floating Point Instructions
 | |
| */
 | |
| 
 | |
| inline void IA32_Fstcw_Mem16_ESP(JitWriter *jit)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FSTCW_MEM16_1);
 | |
| 	jit->write_ubyte(IA32_FSTCW_MEM16_2);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 7, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
 | |
| }
 | |
| 
 | |
| inline void IA32_Fldcw_Mem16_ESP(JitWriter *jit)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FLDCW_MEM16);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 5, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
 | |
| }
 | |
| 
 | |
| inline void IA32_Fldcw_Mem16_Disp8_ESP(JitWriter *jit, jit_int8_t disp8)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FLDCW_MEM16);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, 5, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
 | |
| 	jit->write_byte(disp8);
 | |
| }
 | |
| 
 | |
| inline void IA32_Fistp_Mem32_ESP(JitWriter *jit)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FISTP_MEM32);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 3, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
 | |
| }
 | |
| 
 | |
| inline void IA32_Fistp_Mem32_Disp8_Esp(JitWriter *jit, jit_int8_t disp8)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FISTP_MEM32);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, 3, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
 | |
| 	jit->write_byte(disp8);
 | |
| }
 | |
| 
 | |
| inline void IA32_Fucomip_ST0_FPUreg(JitWriter *jit, jit_uint8_t reg)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FUCOMIP_1);
 | |
| 	jit->write_ubyte(IA32_FUCOMIP_2+reg);
 | |
| }
 | |
| 
 | |
| inline void IA32_Fadd_FPUreg_ST0(JitWriter *jit, jit_uint8_t reg)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FADD_FPREG_ST0_1);
 | |
| 	jit->write_ubyte(IA32_FADD_FPREG_ST0_2+reg);
 | |
| }
 | |
| 
 | |
| inline void IA32_Fadd_Mem32_Disp8(JitWriter *jit, jit_uint8_t src, jit_int8_t val)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FADD_MEM32);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, src));
 | |
| 	jit->write_byte(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Fadd_Mem32_ESP(JitWriter *jit)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FADD_MEM32);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 0, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
 | |
| }
 | |
| 
 | |
| inline void IA32_Fsub_Mem32_Disp8(JitWriter *jit, jit_uint8_t src, jit_int8_t val)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FSUB_MEM32);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, 4, src));
 | |
| 	jit->write_byte(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Fmul_Mem32_Disp8(JitWriter *jit, jit_uint8_t src, jit_int8_t val)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FMUL_MEM32);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, 1, src));
 | |
| 	jit->write_byte(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Fdiv_Mem32_Disp8(JitWriter *jit, jit_uint8_t src, jit_int8_t val)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FDIV_MEM32);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, 6, src));
 | |
| 	jit->write_byte(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Fild_Mem32(JitWriter *jit, jit_uint8_t src)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FILD_MEM32);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 0, src));
 | |
| }
 | |
| 
 | |
| inline void IA32_Fstp_Mem32(JitWriter *jit, jit_uint8_t dest)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FSTP_MEM32);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 3, dest));
 | |
| }
 | |
| 
 | |
| inline void IA32_Fstp_Mem64(JitWriter *jit, jit_uint8_t dest)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FSTP_MEM64);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 3, dest));
 | |
| }
 | |
| 
 | |
| inline void IA32_Fstp_Mem32_ESP(JitWriter *jit)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FSTP_MEM32);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 3, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
 | |
| }
 | |
| 
 | |
| inline void IA32_Fstp_Mem64_ESP(JitWriter *jit)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FSTP_MEM64);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 3, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
 | |
| }
 | |
| 
 | |
| inline void IA32_Fstp_FPUreg(JitWriter *jit, jit_uint8_t reg)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FSTP_FPREG_1);
 | |
| 	jit->write_ubyte(IA32_FSTP_FPREG_2+reg);
 | |
| }
 | |
| 
 | |
| inline void IA32_Fld_Mem32(JitWriter *jit, jit_uint8_t src)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FLD_MEM32);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 0, src));
 | |
| }
 | |
| 
 | |
| inline void IA32_Fld_Mem64(JitWriter *jit, jit_uint8_t src)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FLD_MEM64);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 0, src));
 | |
| }
 | |
| 
 | |
| inline void IA32_Fld_Mem32_Disp8(JitWriter *jit, jit_uint8_t src, jit_int8_t val)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FLD_MEM32);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, src));
 | |
| 	jit->write_byte(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Fld_Mem64_Disp8(JitWriter *jit, jit_uint8_t src, jit_int8_t val)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FLD_MEM64);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, src));
 | |
| 	jit->write_byte(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Fld_Mem32_Disp32(JitWriter *jit, jit_uint8_t src, jit_int32_t val)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FLD_MEM32);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, src));
 | |
| 	jit->write_int32(val);
 | |
| }
 | |
| 
 | |
| inline void IA32_Fld_Mem64_Disp32(JitWriter *jit, jit_uint8_t src, jit_int32_t val)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_FLD_MEM64);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, src));
 | |
| 	jit->write_int32(val);
 | |
| }
 | |
| 
 | |
| /**
 | |
| * Move data with zero extend
 | |
| */
 | |
| 
 | |
| inline void IA32_Movzx_Reg32_Rm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOVZX_R32_RM8_1);
 | |
| 	jit->write_ubyte(IA32_MOVZX_R32_RM8_2);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, dest, src));
 | |
| }
 | |
| 
 | |
| inline void IA32_Movzx_Reg32_Rm8_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOVZX_R32_RM8_1);
 | |
| 	jit->write_ubyte(IA32_MOVZX_R32_RM8_2);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src));
 | |
| 	jit->write_byte(disp);
 | |
| }
 | |
| 
 | |
| inline void IA32_Movzx_Reg32_Rm8_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOVZX_R32_RM8_1);
 | |
| 	jit->write_ubyte(IA32_MOVZX_R32_RM8_2);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, src));
 | |
| 	jit->write_int32(disp);
 | |
| }
 | |
| 
 | |
| inline void IA32_Movzx_Reg32_Rm16(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOVZX_R32_RM16_1);
 | |
| 	jit->write_ubyte(IA32_MOVZX_R32_RM16_2);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, dest, src));
 | |
| }
 | |
| 
 | |
| inline void IA32_Movzx_Reg32_Rm16_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOVZX_R32_RM16_1);
 | |
| 	jit->write_ubyte(IA32_MOVZX_R32_RM16_2);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src));
 | |
| 	jit->write_byte(disp);
 | |
| }
 | |
| 
 | |
| inline void IA32_Movzx_Reg32_Rm16_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOVZX_R32_RM16_1);
 | |
| 	jit->write_ubyte(IA32_MOVZX_R32_RM16_2);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, src));
 | |
| 	jit->write_int32(disp);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Branching/Jumping
 | |
|  */
 | |
| 
 | |
| inline jitoffs_t IA32_Jump_Cond_Imm8(JitWriter *jit, jit_uint8_t cond, jit_int8_t disp)
 | |
| {
 | |
| 	jitoffs_t ptr;
 | |
| 	jit->write_ubyte(IA32_JCC_IMM+cond);
 | |
| 	ptr = jit->get_outputpos();
 | |
| 	jit->write_byte(disp);
 | |
| 	return ptr;
 | |
| }
 | |
| 
 | |
| inline jitoffs_t IA32_Jump_Imm32(JitWriter *jit, jit_int32_t disp)
 | |
| {
 | |
| 	jitoffs_t ptr;
 | |
| 	jit->write_ubyte(IA32_JMP_IMM32);
 | |
| 	ptr = jit->get_outputpos();
 | |
| 	jit->write_int32(disp);
 | |
| 	return ptr;
 | |
| }
 | |
| 
 | |
| inline jitoffs_t IA32_Jump_Imm8(JitWriter *jit, jit_int8_t disp)
 | |
| {
 | |
| 	jitoffs_t ptr;
 | |
| 	jit->write_ubyte(IA32_JMP_IMM8);
 | |
| 	ptr = jit->get_outputpos();
 | |
| 	jit->write_byte(disp);
 | |
| 	return ptr;
 | |
| }
 | |
| 
 | |
| inline jitoffs_t IA32_Jump_Cond_Imm32(JitWriter *jit, jit_uint8_t cond, jit_int32_t disp)
 | |
| {
 | |
| 	jitoffs_t ptr;
 | |
| 	jit->write_ubyte(IA32_JCC_IMM32_1);
 | |
| 	jit->write_ubyte(IA32_JCC_IMM32_2+cond);
 | |
| 	ptr = jit->get_outputpos();
 | |
| 	jit->write_int32(disp);
 | |
| 	return ptr;
 | |
| }
 | |
| 
 | |
| inline void IA32_Jump_Reg(JitWriter *jit, jit_uint8_t reg)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_JMP_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_REG, 4, reg));
 | |
| }
 | |
| 
 | |
| inline void IA32_Jump_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_JMP_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 4, reg));
 | |
| }
 | |
| 
 | |
| inline jitoffs_t IA32_Call_Imm32(JitWriter *jit, jit_int32_t disp)
 | |
| {
 | |
| 	jitoffs_t ptr;
 | |
| 	jit->write_ubyte(IA32_CALL_IMM32);
 | |
| 	ptr = jit->get_outputpos();
 | |
| 	jit->write_int32(disp);
 | |
| 	return ptr;
 | |
| }
 | |
| 
 | |
| inline void IA32_Call_Reg(JitWriter *jit, jit_uint8_t reg)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_CALL_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_REG, 2, reg));
 | |
| }
 | |
| 
 | |
| inline void IA32_Write_Jump8(JitWriter *jit, jitoffs_t jmp, jitoffs_t target)
 | |
| {
 | |
| 	//save old ptr
 | |
| 	jitcode_t oldptr = jit->outptr;
 | |
| 	//get relative difference
 | |
| 	jit_int8_t diff = (target - (jmp + 1));
 | |
| 	//overwrite old value
 | |
| 	jit->outptr = jit->outbase + jmp;
 | |
| 	jit->write_byte(diff);
 | |
| 	//restore old ptr
 | |
| 	jit->outptr = oldptr;
 | |
| }
 | |
| 
 | |
| inline void IA32_Write_Jump32(JitWriter *jit, jitoffs_t jmp, jitoffs_t target)
 | |
| {
 | |
| 	//save old ptr
 | |
| 	jitcode_t oldptr = jit->outptr;
 | |
| 	//get relative difference
 | |
| 	jit_int32_t diff = (target - (jmp + 4));
 | |
| 	//overwrite old value
 | |
| 	jit->outptr = jit->outbase + jmp;
 | |
| 	jit->write_int32(diff);
 | |
| 	//restore old ptr
 | |
| 	jit->outptr = oldptr;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Corrects a jump using an absolute offset, not a relative one.
 | |
|  */
 | |
| inline void IA32_Write_Jump32_Abs(JitWriter *jit, jitoffs_t jmp, void *target)
 | |
| {
 | |
| 	//save old ptr
 | |
| 	jitcode_t oldptr = jit->outptr;
 | |
| 	//get relative difference
 | |
| 	long diff = ((long)target - ((long)jit->outbase + jmp + 4));
 | |
| 	//overwrite old value
 | |
| 	jit->outptr = jit->outbase + jmp;
 | |
| 	jit->write_int32(diff);
 | |
| 	//restore old ptr
 | |
| 	jit->outptr = oldptr;
 | |
| }
 | |
| 
 | |
| /* For writing and auto-calculating an absolute target */
 | |
| inline void IA32_Jump_Imm32_Abs(JitWriter *jit, jitoffs_t target)
 | |
| {
 | |
| 	/* :TODO: this should work, but does it? */
 | |
| 	jit->write_ubyte(IA32_JMP_IMM32);
 | |
| 	IA32_Write_Jump32(jit, jit->get_outputpos(), target);
 | |
| 	jit->outptr += 4;
 | |
| }
 | |
| 
 | |
| inline void IA32_Jump_Cond_Imm32_Abs(JitWriter *jit, jit_uint8_t cond, jitoffs_t target)
 | |
| {
 | |
| 	/* :TODO: this should work, but does it? */
 | |
| 	jit->write_ubyte(IA32_JCC_IMM32_1);
 | |
| 	jit->write_ubyte(IA32_JCC_IMM32_2+cond);
 | |
| 	IA32_Write_Jump32(jit, jit->get_outputpos(), target);
 | |
| 	jit->outptr += 4;
 | |
| }
 | |
| 
 | |
| inline void IA32_Send_Jump8_Here(JitWriter *jit, jitoffs_t jmp)
 | |
| {
 | |
| 	jitoffs_t curptr = jit->get_outputpos();
 | |
| 	IA32_Write_Jump8(jit, jmp, curptr);
 | |
| }
 | |
| 
 | |
| inline void IA32_Send_Jump32_Here(JitWriter *jit, jitoffs_t jmp)
 | |
| {
 | |
| 	jitoffs_t curptr = jit->get_outputpos();
 | |
| 	IA32_Write_Jump32(jit, jmp, curptr);
 | |
| }
 | |
| 
 | |
| inline void IA32_Return(JitWriter *jit)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_RET);
 | |
| }
 | |
| 
 | |
| inline void IA32_Return_Popstack(JitWriter *jit, unsigned short bytes)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_RETN);
 | |
| 	jit->write_ushort(bytes);
 | |
| }
 | |
| 
 | |
| inline void IA32_Test_Rm_Reg(JitWriter *jit, jit_uint8_t reg1, jit_uint8_t reg2, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_TEST_RM_REG);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, reg2, reg1));
 | |
| }
 | |
| 
 | |
| inline void IA32_Cmp_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_CMP_RM_REG);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, src, dest));
 | |
| }
 | |
| 
 | |
| inline void IA32_Cmp_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_CMP_REG_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, dest, src));
 | |
| }
 | |
| 
 | |
| inline void IA32_Cmp_Reg_Rm_ESP(JitWriter *jit, jit_uint8_t cmpreg)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_CMP_REG_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_MEM_REG, cmpreg, REG_SIB));
 | |
| 	jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
 | |
| }
 | |
| 
 | |
| inline void IA32_Cmp_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t reg1, jit_uint8_t reg2, jit_int8_t disp8)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_CMP_REG_RM);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, reg1, reg2));
 | |
| 	jit->write_byte(disp8);
 | |
| }
 | |
| 
 | |
| inline void IA32_Cmp_Rm_Imm8(JitWriter *jit, jit_uint8_t mode, jit_uint8_t rm, jit_int8_t imm8)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_CMP_RM_IMM8);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 7, rm));
 | |
| 	jit->write_byte(imm8);
 | |
| }
 | |
| 
 | |
| inline void IA32_Cmp_Rm_Imm32(JitWriter *jit, jit_uint8_t mode, jit_uint8_t rm, jit_int32_t imm32)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_CMP_RM_IMM32);
 | |
| 	jit->write_ubyte(ia32_modrm(mode, 7, rm));
 | |
| 	jit->write_int32(imm32);
 | |
| }
 | |
| 
 | |
| inline void IA32_Cmp_Rm_Imm32_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp8, jit_int32_t imm32)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_CMP_RM_IMM32);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, 7, reg));
 | |
| 	jit->write_byte(disp8);
 | |
| 	jit->write_int32(imm32);
 | |
| }
 | |
| 
 | |
| inline void IA32_Cmp_Rm_Disp8_Imm8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp, jit_int8_t imm8)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_CMP_RM_IMM8);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, 7, reg));
 | |
| 	jit->write_byte(disp);
 | |
| 	jit->write_byte(imm8);
 | |
| }
 | |
| 
 | |
| inline void IA32_Cmp_Al_Imm8(JitWriter *jit, jit_int8_t value)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_CMP_AL_IMM32);
 | |
| 	jit->write_byte(value);
 | |
| }
 | |
| 
 | |
| inline void IA32_Cmp_Eax_Imm32(JitWriter *jit, jit_int32_t value)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_CMP_EAX_IMM32);
 | |
| 	jit->write_int32(value);
 | |
| }
 | |
| 
 | |
| inline void IA32_SetCC_Rm8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t cond)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_SETCC_RM8_1);
 | |
| 	jit->write_ubyte(IA32_SETCC_RM8_2+cond);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_REG, 0, reg));
 | |
| }
 | |
| 
 | |
| inline void IA32_CmovCC_Rm(JitWriter *jit, jit_uint8_t src, jit_uint8_t cond)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_CMOVCC_RM_1);
 | |
| 	jit->write_ubyte(IA32_CMOVCC_RM_2+cond);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 0, src));
 | |
| }
 | |
| 
 | |
| inline void IA32_CmovCC_Rm_Disp8(JitWriter *jit, jit_uint8_t src, jit_uint8_t cond, jit_int8_t disp)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_CMOVCC_RM_1);
 | |
| 	jit->write_ubyte(IA32_CMOVCC_RM_2+cond);
 | |
| 	jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, src));
 | |
| 	jit->write_byte(disp);
 | |
| }
 | |
| 
 | |
| inline void IA32_Cmpsb(JitWriter *jit)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_CMPSB);
 | |
| }
 | |
| 
 | |
| inline void IA32_Rep(JitWriter *jit)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_REP);
 | |
| }
 | |
| 
 | |
| inline void IA32_Movsd(JitWriter *jit)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOVSD);
 | |
| }
 | |
| 
 | |
| inline void IA32_Movsb(JitWriter *jit)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_MOVSB);
 | |
| }
 | |
| 
 | |
| inline void IA32_Stosd(JitWriter *jit)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_STOSD);
 | |
| }
 | |
| 
 | |
| inline void IA32_Cld(JitWriter *jit)
 | |
| {
 | |
| 	jit->write_ubyte(IA32_CLD);
 | |
| }
 | |
| 
 | |
| #endif //_INCLUDE_JIT_X86_MACROS_H
 |