sourcemod/public/jit/x86/x86_macros.h
Scott Ehlert 251cced1f8 Spring Cleaning, Part Ichi (1)
Various minor things done to project files
Updated sample extension project file and updated makefile to the new unified version (more changes likely on the way)
Updated regex project file and makefile

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401971
2008-03-30 07:00:22 +00:00

1511 lines
45 KiB
C

/**
* vim: set ts=4 :
* =============================================================================
* SourcePawn JIT SDK
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* 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