added floating point optimizations to the JIT

standarised a bit more x86_macros.h
some asm optimizations to bintools extension

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40837
This commit is contained in:
Borja Ferrer 2007-05-22 15:15:51 +00:00
parent 307181de8d
commit e60940834b
9 changed files with 852 additions and 129 deletions

View File

@ -34,7 +34,7 @@ static cell_t sm_float(IPluginContext *pCtx, const cell_t *params)
static cell_t sm_FloatAbs(IPluginContext *pCtx, const cell_t *params) static cell_t sm_FloatAbs(IPluginContext *pCtx, const cell_t *params)
{ {
float val = sp_ctof(params[1]); float val = sp_ctof(params[1]);
val = (val >= 0) ? val : -val; val = (val >= 0.0f) ? val : -val;
return sp_ftoc(val); return sp_ftoc(val);
} }
@ -87,11 +87,11 @@ static cell_t sm_Logarithm(IPluginContext *pCtx, const cell_t *params)
float val = sp_ctof(params[1]); float val = sp_ctof(params[1]);
float base = sp_ctof(params[2]); float base = sp_ctof(params[2]);
if ((val <= 0) || (base <= 0)) if ((val <= 0.0f) || (base <= 0.0f))
{ {
return pCtx->ThrowNativeError("Cannot evaluate the logarithm of zero or a negative number (val:%f base:%f)", val, base); return pCtx->ThrowNativeError("Cannot evaluate the logarithm of zero or a negative number (val:%f base:%f)", val, base);
} }
if (base == 10.0) if (base == 10.0f)
{ {
val = log10(val); val = log10(val);
} else { } else {
@ -120,7 +120,7 @@ static cell_t sm_SquareRoot(IPluginContext *pCtx, const cell_t *params)
{ {
float val = sp_ctof(params[1]); float val = sp_ctof(params[1]);
if (val < 0.0) if (val < 0.0f)
{ {
return pCtx->ThrowNativeError("Cannot evaluate the square root of a negative number (val:%f)", val); return pCtx->ThrowNativeError("Cannot evaluate the square root of a negative number (val:%f)", val);
} }
@ -128,38 +128,39 @@ static cell_t sm_SquareRoot(IPluginContext *pCtx, const cell_t *params)
return sp_ftoc(sqrt(val)); return sp_ftoc(sqrt(val));
} }
static cell_t sm_FloatRound(IPluginContext *pCtx, const cell_t *params) static cell_t sm_RountToNearest(IPluginContext *pCtx, const cell_t *params)
{ {
float val = sp_ctof(params[1]); float val = sp_ctof(params[1]);
val = (float)floor(val + 0.5f);
switch (params[2]) return static_cast<int>(val);
{ }
case 1:
{ static cell_t sm_RoundToFloor(IPluginContext *pCtx, const cell_t *params)
{
float val = sp_ctof(params[1]);
val = floor(val); val = floor(val);
break;
} return static_cast<int>(val);
case 2: }
{
static cell_t sm_RoundToCeil(IPluginContext *pCtx, const cell_t *params)
{
float val = sp_ctof(params[1]);
val = ceil(val); val = ceil(val);
break;
} return static_cast<int>(val);
case 3: }
{
if (val >= 0.0) static cell_t sm_RoundToZero(IPluginContext *pCtx, const cell_t *params)
{
float val = sp_ctof(params[1]);
if (val >= 0.0f)
{ {
val = floor(val); val = floor(val);
} else { } else {
val = ceil(val); val = ceil(val);
} }
break;
}
default:
{
val = (float)floor(val + 0.5);
break;
}
}
return static_cast<int>(val); return static_cast<int>(val);
} }
@ -237,7 +238,10 @@ REGISTER_NATIVES(floatnatives)
{"FloatAdd", sm_FloatAdd}, {"FloatAdd", sm_FloatAdd},
{"FloatSub", sm_FloatSub}, {"FloatSub", sm_FloatSub},
{"FloatFraction", sm_FloatFraction}, {"FloatFraction", sm_FloatFraction},
{"FloatRound", sm_FloatRound}, {"RoundToZero", sm_RoundToZero},
{"RoundToCeil", sm_RoundToCeil},
{"RoundToFloor", sm_RoundToFloor},
{"RountToNearest", sm_RountToNearest},
{"FloatCompare", sm_FloatCompare}, {"FloatCompare", sm_FloatCompare},
{"SquareRoot", sm_SquareRoot}, {"SquareRoot", sm_SquareRoot},
{"Pow", sm_Pow}, {"Pow", sm_Pow},

View File

@ -116,17 +116,15 @@ inline void Write_PushPOD(JitWriter *jit, const PassEncode *pEnc)
{ {
case 1: case 1:
{ {
//xor reg, reg //movzx reg, BYTE PTR [ebx+<offset>]
//mov reg, BYTE PTR [ebx+<offset>]
//push reg //push reg
IA32_Xor_Reg_Rm(jit, reg, reg, MOD_REG);
if (pEnc->offset < SCHAR_MAX) if (pEnc->offset < SCHAR_MAX)
{ {
IA32_Mov_Reg8_Rm8_Disp8(jit, reg, REG_EBX, (jit_int8_t)pEnc->offset); IA32_Movzx_Reg32_Rm8_Disp8(jit, reg, REG_EBX, (jit_int8_t)pEnc->offset);
} else if (!pEnc->offset) { } else if (!pEnc->offset) {
IA32_Mov_Reg8_Rm8(jit, reg, REG_EBX, MOD_MEM_REG); IA32_Movzx_Reg32_Rm8(jit, reg, REG_EBX, MOD_MEM_REG);
} else { } else {
IA32_Mov_Reg8_Rm8_Disp32(jit, reg, REG_EBX, pEnc->offset); IA32_Movzx_Reg32_Rm8_Disp32(jit, reg, REG_EBX, pEnc->offset);
} }
IA32_Push_Reg(jit, reg); IA32_Push_Reg(jit, reg);
@ -135,18 +133,16 @@ inline void Write_PushPOD(JitWriter *jit, const PassEncode *pEnc)
} }
case 2: case 2:
{ {
//xor reg, reg //movzx reg, WORD PTR [ebx+<offset>]
//mov reg, WORD PTR [ebx+<offset>]
//push reg //push reg
IA32_Xor_Reg_Rm(jit, reg, reg, MOD_REG);
jit->write_ubyte(IA32_16BIT_PREFIX); jit->write_ubyte(IA32_16BIT_PREFIX);
if (pEnc->offset < SCHAR_MAX) if (pEnc->offset < SCHAR_MAX)
{ {
IA32_Mov_Reg_Rm_Disp8(jit, reg, REG_EBX, (jit_int8_t)pEnc->offset); IA32_Movzx_Reg32_Rm16_Disp8(jit, reg, REG_EBX, (jit_int8_t)pEnc->offset);
} else if (!pEnc->offset) { } else if (!pEnc->offset) {
IA32_Mov_Reg_Rm(jit, reg, REG_EBX, MOD_MEM_REG); IA32_Movzx_Reg32_Rm16(jit, reg, REG_EBX, MOD_MEM_REG);
} else { } else {
IA32_Mov_Reg_Rm_Disp32(jit, reg, REG_EBX, pEnc->offset); IA32_Movzx_Reg32_Rm16_Disp32(jit, reg, REG_EBX, pEnc->offset);
} }
IA32_Push_Reg(jit, reg); IA32_Push_Reg(jit, reg);
@ -234,11 +230,13 @@ inline void Write_PushFloat(JitWriter *jit, const PassEncode *pEnc)
if (pEnc->offset < SCHAR_MAX) if (pEnc->offset < SCHAR_MAX)
{ {
IA32_Fld_Mem32_Disp8(jit, REG_EBX, (jit_int8_t)pEnc->offset); IA32_Fld_Mem32_Disp8(jit, REG_EBX, (jit_int8_t)pEnc->offset);
} else if (!pEnc->offset) {
IA32_Fld_Mem32(jit, REG_EBX);
} else { } else {
IA32_Fld_Mem32_Disp32(jit, REG_EBX, pEnc->offset); IA32_Fld_Mem32_Disp32(jit, REG_EBX, pEnc->offset);
} }
IA32_Push_Reg(jit, _DecodeRegister3(g_RegDecoder++)); IA32_Push_Reg(jit, _DecodeRegister3(g_RegDecoder++));
IA32_Fstp_Mem32(jit, REG_ESP, REG_NOIDX, NOSCALE); IA32_Fstp_Mem32_ESP(jit);
g_StackUsage += 4; g_StackUsage += 4;
break; break;
} }
@ -250,11 +248,13 @@ inline void Write_PushFloat(JitWriter *jit, const PassEncode *pEnc)
if (pEnc->offset < SCHAR_MAX) if (pEnc->offset < SCHAR_MAX)
{ {
IA32_Fld_Mem64_Disp8(jit, REG_EBX, (jit_int8_t)pEnc->offset); IA32_Fld_Mem64_Disp8(jit, REG_EBX, (jit_int8_t)pEnc->offset);
} else if (!pEnc->offset) {
IA32_Fld_Mem64(jit, REG_EBX);
} else { } else {
IA32_Fld_Mem64_Disp32(jit, REG_EBX, pEnc->offset); IA32_Fld_Mem64_Disp32(jit, REG_EBX, pEnc->offset);
} }
IA32_Sub_Rm_Imm8(jit, REG_ESP, 8, MOD_REG); IA32_Sub_Rm_Imm8(jit, REG_ESP, 8, MOD_REG);
IA32_Fstp_Mem64(jit, REG_ESP, REG_NOIDX, NOSCALE); IA32_Fstp_Mem64_ESP(jit);
g_StackUsage += 8; g_StackUsage += 8;
break; break;
} }
@ -449,13 +449,13 @@ inline void Write_MovRet2Buf(JitWriter *jit, const PassInfo *pRet)
case 4: case 4:
{ {
//fstp DWORD PTR [edi] //fstp DWORD PTR [edi]
IA32_Fstp_Mem32(jit, REG_EDI, REG_NOIDX, NOSCALE); IA32_Fstp_Mem32(jit, REG_EDI);
break; break;
} }
case 8: case 8:
{ {
//fstp QWORD PTR [edi] //fstp QWORD PTR [edi]
IA32_Fstp_Mem64(jit, REG_EDI, REG_NOIDX, NOSCALE); IA32_Fstp_Mem64(jit, REG_EDI);
break; break;
} }
} }

View File

@ -18,17 +18,6 @@
#endif #endif
#define _float_included #define _float_included
/**
* Different methods of rounding.
*/
enum floatround_method
{
floatround_round = 0, /**< Standard IEEE rounding */
floatround_floor, /**< Next lowest integer value. */
floatround_ceil, /**< Next highest integer value. */
floatround_tozero /** Closest integer to zero. */
};
/** /**
* Converts an integer into a floating point value. * Converts an integer into a floating point value.
* *
@ -82,13 +71,36 @@ native Float:FloatSub(Float:oper1, Float:oper2);
native Float:FloatFraction(Float:value); native Float:FloatFraction(Float:value);
/** /**
* Rounds a float into an integer number. * Rounds a float to the closest integer to zero.
* *
* @param value Input value to be rounded. * @param value Input value to be rounded.
* @param method Rounding method to use.
* @return Rounded value. * @return Rounded value.
*/ */
native FloatRound(Float:value, floatround_method:method=floatround_round); native RoundToZero(Float:value);
/**
* Rounds a float to the next highest integer value.
*
* @param value Input value to be rounded.
* @return Rounded value.
*/
native RoundToCeil(Float:value);
/**
* Rounds a float to the next lowest integer value.
*
* @param value Input value to be rounded.
* @return Rounded value.
*/
native RoundToFloor(Float:value);
/**
* Standard IEEE rounding.
*
* @param value Input value to be rounded.
* @return Rounded value.
*/
native RountToNearest(Float:value);
/** /**
* Compares two floats. * Compares two floats.

View File

@ -91,7 +91,7 @@
#define IA32_MOV_REG_IMM 0xB8 // encoding is +r <imm32> #define IA32_MOV_REG_IMM 0xB8 // encoding is +r <imm32>
#define IA32_MOV_RM8_REG 0x88 // encoding is /r #define IA32_MOV_RM8_REG 0x88 // encoding is /r
#define IA32_MOV_RM_REG 0x89 // encoding is /r #define IA32_MOV_RM_REG 0x89 // encoding is /r
#define IA32_MOV_REG_MEM 0x8B // encoding is /r #define IA32_MOV_REG_RM 0x8B // encoding is /r
#define IA32_MOV_REG8_RM8 0x8A // encoding is /r #define IA32_MOV_REG8_RM8 0x8A // encoding is /r
#define IA32_MOV_RM8_REG8 0x88 // encoding is /r #define IA32_MOV_RM8_REG8 0x88 // encoding is /r
#define IA32_MOV_RM_IMM32 0xC7 // encoding is /0 #define IA32_MOV_RM_IMM32 0xC7 // encoding is /0
@ -130,11 +130,14 @@
#define IA32_SHL_RM_IMM8 0xC1 // encoding is /4 <ib> #define IA32_SHL_RM_IMM8 0xC1 // encoding is /4 <ib>
#define IA32_SHL_RM_1 0xD1 // encoding is /4 #define IA32_SHL_RM_1 0xD1 // encoding is /4
#define IA32_SAR_RM_CL 0xD3 // encoding is /7 #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_SHR_RM_CL 0xD3 // encoding is /5
#define IA32_SHL_RM_CL 0xD3 // encoding is /4 #define IA32_SHL_RM_CL 0xD3 // encoding is /4
#define IA32_SAR_RM_IMM8 0xC1 // encoding is /7 <ib> #define IA32_SAR_RM_IMM8 0xC1 // encoding is /7 <ib>
#define IA32_SETCC_RM8_1 0x0F // opcode part 1 #define IA32_SETCC_RM8_1 0x0F // opcode part 1
#define IA32_SETCC_RM8_2 0x90 // encoding is +cc /0 (8bits) #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_XCHG_EAX_REG 0x90 // encoding is +r
#define IA32_LEA_REG_MEM 0x8D // encoding is /r #define IA32_LEA_REG_MEM 0x8D // encoding is /r
#define IA32_POP_REG 0x58 // encoding is +r #define IA32_POP_REG 0x58 // encoding is +r
@ -155,6 +158,25 @@
#define IA32_FSTP_MEM64 0xDD // encoding is /3 #define IA32_FSTP_MEM64 0xDD // encoding is /3
#define IA32_FLD_MEM32 0xD9 // encoding is /0 #define IA32_FLD_MEM32 0xD9 // encoding is /0
#define IA32_FLD_MEM64 0xDD // 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) inline jit_uint8_t ia32_modrm(jit_uint8_t mode, jit_uint8_t reg, jit_uint8_t rm)
{ {
@ -183,11 +205,9 @@ inline jit_uint8_t ia32_sib(jit_uint8_t mode, jit_uint8_t index, jit_uint8_t bas
* INCREMENT/DECREMENT * * INCREMENT/DECREMENT *
***********************/ ***********************/
inline void IA32_Inc_Rm_Disp32(JitWriter *jit, jit_uint8_t reg, jit_int32_t disp) inline void IA32_Inc_Reg(JitWriter *jit, jit_uint8_t reg)
{ {
jit->write_ubyte(IA32_INC_RM); jit->write_ubyte(IA32_INC_REG+reg);
jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, reg));
jit->write_int32(disp);
} }
inline void IA32_Inc_Rm_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp) inline void IA32_Inc_Rm_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp)
@ -197,6 +217,13 @@ inline void IA32_Inc_Rm_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp)
jit->write_byte(disp); 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) 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_INC_RM);
@ -204,16 +231,9 @@ inline void IA32_Inc_Rm_Disp_Reg(JitWriter *jit, jit_uint8_t base, jit_uint8_t r
jit->write_ubyte(ia32_sib(scale, reg, base)); jit->write_ubyte(ia32_sib(scale, reg, base));
} }
inline void IA32_Inc_Reg(JitWriter *jit, jit_uint8_t reg) inline void IA32_Dec_Reg(JitWriter *jit, jit_uint8_t reg)
{ {
jit->write_ubyte(IA32_INC_REG+reg); jit->write_ubyte(IA32_DEC_REG+reg);
}
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_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp) inline void IA32_Dec_Rm_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp)
@ -223,6 +243,13 @@ inline void IA32_Dec_Rm_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp)
jit->write_byte(disp); 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) 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_DEC_RM);
@ -230,11 +257,6 @@ inline void IA32_Dec_Rm_Disp_Reg(JitWriter *jit, jit_uint8_t base, jit_uint8_t r
jit->write_ubyte(ia32_sib(scale, reg, base)); 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);
}
/**************** /****************
* BINARY LOGIC * * BINARY LOGIC *
****************/ ****************/
@ -251,10 +273,11 @@ inline void IA32_Xor_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, j
jit->write_ubyte(ia32_modrm(dest_mode, dest, src)); jit->write_ubyte(ia32_modrm(dest_mode, dest, src));
} }
inline void IA32_Xor_Eax_Imm32(JitWriter *jit, jit_int32_t value) 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_EAX_IMM32); jit->write_ubyte(IA32_XOR_RM_IMM8);
jit->write_int32(value); 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) inline void IA32_Xor_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int32_t value)
@ -264,11 +287,10 @@ inline void IA32_Xor_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode,
jit->write_int32(value); jit->write_int32(value);
} }
inline void IA32_Xor_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int8_t value) inline void IA32_Xor_Eax_Imm32(JitWriter *jit, jit_int32_t value)
{ {
jit->write_ubyte(IA32_XOR_RM_IMM8); jit->write_ubyte(IA32_XOR_EAX_IMM32);
jit->write_ubyte(ia32_modrm(mode, 6, reg)); jit->write_int32(value);
jit->write_byte(value);
} }
inline void IA32_Neg_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) inline void IA32_Neg_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
@ -289,16 +311,17 @@ inline void IA32_And_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, j
jit->write_ubyte(ia32_modrm(mode, dest, src)); jit->write_ubyte(ia32_modrm(mode, dest, src));
} }
inline void IA32_And_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_int32_t c) inline void IA32_And_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int32_t value)
{ {
if (reg == REG_EAX)
{
jit->write_ubyte(IA32_AND_EAX_IMM32);
} else {
jit->write_ubyte(IA32_AND_RM_IMM32); jit->write_ubyte(IA32_AND_RM_IMM32);
jit->write_ubyte(ia32_modrm(MOD_REG, 4, reg)); jit->write_ubyte(ia32_modrm(mode, 4, reg));
} jit->write_int32(value);
jit->write_int32(c); }
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) inline void IA32_Not_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
@ -346,6 +369,12 @@ inline void IA32_Sar_Rm_CL(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
jit->write_ubyte(ia32_modrm(mode, 7, reg)); 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) 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_SHR_RM_CL);
@ -731,7 +760,7 @@ inline void IA32_Push_Rm_Disp8_ESP(JitWriter *jit, jit_int8_t disp8)
inline void IA32_Mov_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) 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_MEM); jit->write_ubyte(IA32_MOV_REG_RM);
jit->write_ubyte(ia32_modrm(mode, dest, src)); jit->write_ubyte(ia32_modrm(mode, dest, src));
} }
@ -741,9 +770,16 @@ inline void IA32_Mov_Reg8_Rm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src,
jit->write_ubyte(ia32_modrm(mode, dest, src)); 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) 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_MEM); jit->write_ubyte(IA32_MOV_REG_RM);
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src)); jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src));
jit->write_byte(disp); jit->write_byte(disp);
} }
@ -757,7 +793,7 @@ inline void IA32_Mov_Reg8_Rm8_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_
inline void IA32_Mov_Reg_Esp_Disp8(JitWriter *jit, jit_uint8_t dest, jit_int8_t disp) inline void IA32_Mov_Reg_Esp_Disp8(JitWriter *jit, jit_uint8_t dest, jit_int8_t disp)
{ {
jit->write_ubyte(IA32_MOV_REG_MEM); jit->write_ubyte(IA32_MOV_REG_RM);
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB)); jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB));
jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
jit->write_byte(disp); jit->write_byte(disp);
@ -765,7 +801,7 @@ inline void IA32_Mov_Reg_Esp_Disp8(JitWriter *jit, jit_uint8_t dest, jit_int8_t
inline void IA32_Mov_Reg_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t 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_MEM); jit->write_ubyte(IA32_MOV_REG_RM);
jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, src)); jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, src));
jit->write_int32(disp); jit->write_int32(disp);
} }
@ -783,7 +819,7 @@ inline void IA32_Mov_Reg_Rm_Disp_Reg(JitWriter *jit,
jit_uint8_t src_index, jit_uint8_t src_index,
jit_uint8_t src_scale) jit_uint8_t src_scale)
{ {
jit->write_ubyte(IA32_MOV_REG_MEM); jit->write_ubyte(IA32_MOV_REG_RM);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest, REG_SIB)); jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest, REG_SIB));
jit->write_ubyte(ia32_sib(src_scale, src_index, src_base)); jit->write_ubyte(ia32_sib(src_scale, src_index, src_base));
} }
@ -795,7 +831,7 @@ inline void IA32_Mov_Reg_Rm_Disp_Reg_Disp8(JitWriter *jit,
jit_uint8_t src_scale, jit_uint8_t src_scale,
jit_int8_t disp8) jit_int8_t disp8)
{ {
jit->write_ubyte(IA32_MOV_REG_MEM); jit->write_ubyte(IA32_MOV_REG_RM);
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB)); jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB));
jit->write_ubyte(ia32_sib(src_scale, src_index, src_base)); jit->write_ubyte(ia32_sib(src_scale, src_index, src_base));
jit->write_byte(disp8); jit->write_byte(disp8);
@ -807,7 +843,7 @@ inline void IA32_Mov_Reg_RmEBP_Disp_Reg(JitWriter *jit,
jit_uint8_t src_index, jit_uint8_t src_index,
jit_uint8_t src_scale) jit_uint8_t src_scale)
{ {
jit->write_ubyte(IA32_MOV_REG_MEM); jit->write_ubyte(IA32_MOV_REG_RM);
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB)); jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB));
jit->write_ubyte(ia32_sib(src_scale, src_index, src_base)); jit->write_ubyte(ia32_sib(src_scale, src_index, src_base));
jit->write_byte(0); jit->write_byte(0);
@ -829,6 +865,13 @@ inline void IA32_Mov_Rm8_Reg8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src,
jit->write_ubyte(ia32_modrm(mode, src, dest)); 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) 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_MOV_RM_REG);
@ -893,6 +936,13 @@ inline jitoffs_t IA32_Mov_Reg_Imm32(JitWriter *jit, jit_uint8_t dest, jit_int32_
return offs; 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, inline void IA32_Mov_Rm_Imm32_Disp8(JitWriter *jit,
jit_uint8_t dest, jit_uint8_t dest,
jit_int32_t val, jit_int32_t val,
@ -904,13 +954,6 @@ inline void IA32_Mov_Rm_Imm32_Disp8(JitWriter *jit,
jit->write_int32(val); jit->write_int32(val);
} }
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_Disp32(JitWriter *jit, inline void IA32_Mov_Rm_Imm32_Disp32(JitWriter *jit,
jit_uint8_t dest, jit_uint8_t dest,
jit_int32_t val, jit_int32_t val,
@ -935,52 +978,232 @@ inline void IA32_Mov_RmEBP_Imm32_Disp_Reg(JitWriter *jit,
jit->write_int32(val); 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 * Floating Point Instructions
*/ */
inline void IA32_Fstp_Mem32(JitWriter *jit, jit_uint8_t dest_base, jit_uint8_t dest_index, jit_uint8_t dest_scale) 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_FSTP_MEM32);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 3, REG_SIB)); jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 3, REG_SIB));
jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base)); jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
} }
inline void IA32_Fstp_Mem64(JitWriter *jit, jit_uint8_t dest_base, jit_uint8_t dest_index, jit_uint8_t dest_scale) inline void IA32_Fstp_Mem64_ESP(JitWriter *jit)
{ {
jit->write_ubyte(IA32_FSTP_MEM64); jit->write_ubyte(IA32_FSTP_MEM64);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 3, REG_SIB)); jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 3, REG_SIB));
jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base)); jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
} }
inline void IA32_Fld_Mem32_Disp8(JitWriter *jit, jit_uint8_t dest, jit_int8_t val) 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_FLD_MEM32);
jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, dest)); 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); jit->write_byte(val);
} }
inline void IA32_Fld_Mem64_Disp8(JitWriter *jit, jit_uint8_t dest, jit_int8_t 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_FLD_MEM64);
jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, dest)); jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, src));
jit->write_byte(val); jit->write_byte(val);
} }
inline void IA32_Fld_Mem32_Disp32(JitWriter *jit, jit_uint8_t dest, jit_int32_t 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_FLD_MEM32);
jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, dest)); jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, src));
jit->write_int32(val); jit->write_int32(val);
} }
inline void IA32_Fld_Mem64_Disp32(JitWriter *jit, jit_uint8_t dest, jit_int32_t 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_FLD_MEM64);
jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, dest)); jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, src));
jit->write_int32(val); 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 * Branching/Jumping
*/ */
@ -1207,6 +1430,21 @@ inline void IA32_SetCC_Rm8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t cond)
jit->write_ubyte(ia32_modrm(MOD_REG, 0, reg)); 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) inline void IA32_Cmpsb(JitWriter *jit)
{ {
jit->write_ubyte(IA32_CMPSB); jit->write_ubyte(IA32_CMPSB);

View File

@ -1136,12 +1136,12 @@ inline void WriteOp_Lodb_I(JitWriter *jit)
{ {
case 1: case 1:
{ {
IA32_And_Rm_Imm32(jit, AMX_REG_PRI, 0x000000FF); IA32_And_Eax_Imm32(jit, 0x000000FF);
break; break;
} }
case 2: case 2:
{ {
IA32_And_Rm_Imm32(jit, AMX_REG_PRI, 0x0000FFFF); IA32_And_Eax_Imm32(jit, 0x0000FFFF);
break; break;
} }
} }
@ -1328,7 +1328,6 @@ inline void WriteOp_Break(JitWriter *jit)
jit->set_outputpos(wr); jit->set_outputpos(wr);
jit->write_uint32((uint32_t)(wr)); jit->write_uint32((uint32_t)(wr));
jit->set_outputpos(save); jit->set_outputpos(save);
wr = IA32_Call_Imm32(jit, 0); wr = IA32_Call_Imm32(jit, 0);
IA32_Write_Jump32(jit, wr, data->jit_break); IA32_Write_Jump32(jit, wr, data->jit_break);
} }
@ -1781,6 +1780,323 @@ inline void WriteOp_Stradjust_Pri(JitWriter *jit)
IA32_Sar_Rm_Imm8(jit, AMX_REG_PRI, 2, MOD_REG); IA32_Sar_Rm_Imm8(jit, AMX_REG_PRI, 2, MOD_REG);
} }
inline void WriteOp_FloatAbs(JitWriter *jit)
{
//mov eax, [edi]
//and eax, 0x7FFFFFFF
IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_STK, MOD_MEM_REG);
IA32_And_Eax_Imm32(jit, 0x7FFFFFFF);
/* Rectify the stack */
//add edi, 4
IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
}
inline void WriteOp_Float(JitWriter *jit)
{
//fild [edi]
//push eax
//fstp [esp]
//pop eax
IA32_Fild_Mem32(jit, AMX_REG_STK);
IA32_Push_Reg(jit, AMX_REG_PRI);
IA32_Fstp_Mem32_ESP(jit);
IA32_Pop_Reg(jit, AMX_REG_PRI);
/* Rectify the stack */
//add edi, 4
IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
}
inline void WriteOp_FloatAdd(JitWriter *jit)
{
//push eax
//fld [edi]
//fadd [edi+4]
//fstp [esp]
//pop eax
IA32_Push_Reg(jit, AMX_REG_PRI);
IA32_Fld_Mem32(jit, AMX_REG_STK);
IA32_Fadd_Mem32_Disp8(jit, AMX_REG_STK, 4);
IA32_Fstp_Mem32_ESP(jit);
IA32_Pop_Reg(jit, AMX_REG_PRI);
/* Rectify the stack */
//add edi, 8
IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 8, MOD_REG);
}
inline void WriteOp_FloatSub(JitWriter *jit)
{
//push eax
//fld [edi]
//fsub [edi+4]
//fstp [esp]
//pop eax
IA32_Push_Reg(jit, AMX_REG_PRI);
IA32_Fld_Mem32(jit, AMX_REG_STK);
IA32_Fsub_Mem32_Disp8(jit, AMX_REG_STK, 4);
IA32_Fstp_Mem32_ESP(jit);
IA32_Pop_Reg(jit, AMX_REG_PRI);
/* Rectify the stack */
//add edi, 8
IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 8, MOD_REG);
}
inline void WriteOp_FloatMul(JitWriter *jit)
{
//push eax
//fld [edi]
//fmul [edi+4]
//fstp [esp]
//pop eax
IA32_Push_Reg(jit, AMX_REG_PRI);
IA32_Fld_Mem32(jit, AMX_REG_STK);
IA32_Fmul_Mem32_Disp8(jit, AMX_REG_STK, 4);
IA32_Fstp_Mem32_ESP(jit);
IA32_Pop_Reg(jit, AMX_REG_PRI);
/* Rectify the stack */
//add edi, 8
IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 8, MOD_REG);
}
inline void WriteOp_FloatDiv(JitWriter *jit)
{
//push eax
//fld [edi]
//fdiv [edi+4]
//fstp [esp]
//pop eax
IA32_Push_Reg(jit, AMX_REG_PRI);
IA32_Fld_Mem32(jit, AMX_REG_STK);
IA32_Fdiv_Mem32_Disp8(jit, AMX_REG_STK, 4);
IA32_Fstp_Mem32_ESP(jit);
IA32_Pop_Reg(jit, AMX_REG_PRI);
/* Rectify the stack */
//add edi, 8
IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 8, MOD_REG);
}
inline void WriteOp_RountToNearest(JitWriter *jit)
{
//push eax
//fld [edi]
//fstcw [esp]
//mov eax, [esp]
//push eax
//mov [esp+4], 0x3FF
//fadd st(0), st(0)
//fldcw [esp+4]
//push eax
//push 0x3F000000 ; 0.5f
//fadd [esp]
//fistp [esp+4]
//pop eax
//pop eax
//pop ecx
//sar eax, 1
//mov [esp], ecx
//fldcw [esp]
//add esp, 4
IA32_Push_Reg(jit, REG_EAX);
IA32_Fld_Mem32(jit, AMX_REG_STK);
IA32_Fstcw_Mem16_ESP(jit);
IA32_Mov_Reg_RmESP(jit, REG_EAX);
IA32_Push_Reg(jit, REG_EAX);
IA32_Mov_ESP_Disp8_Imm32(jit, 4, 0x3FF);
IA32_Fadd_FPUreg_ST0(jit, 0);
IA32_Fldcw_Mem16_Disp8_ESP(jit, 4);
IA32_Push_Reg(jit, REG_EAX);
IA32_Push_Imm32(jit, 0x3F000000);
IA32_Fadd_Mem32_ESP(jit);
IA32_Fistp_Mem32_Disp8_Esp(jit, 4);
IA32_Pop_Reg(jit, REG_EAX);
IA32_Pop_Reg(jit, AMX_REG_PRI);
IA32_Pop_Reg(jit, REG_ECX);
IA32_Sar_Rm_1(jit, REG_EAX, MOD_REG);
IA32_Mov_RmESP_Reg(jit, REG_ECX);
IA32_Fldcw_Mem16_ESP(jit);
IA32_Add_Rm_Imm8(jit, REG_ESP, 4, MOD_REG);
/* Rectify the stack */
//add edi, 4
IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
}
inline void WriteOp_RoundToFloor(JitWriter *jit)
{
//push eax
//fld [edi]
//fstcw [esp]
//mov eax, [esp]
//push eax
//mov [esp+4], 0x7FF
//fldcw [esp+4]
//push eax
//fistp [esp]
//pop eax
//pop ecx
//mov [esp], ecx
//fldcw [esp]
//add esp, 4
IA32_Push_Reg(jit, REG_EAX);
IA32_Fld_Mem32(jit, AMX_REG_STK);
IA32_Fstcw_Mem16_ESP(jit);
IA32_Mov_Reg_RmESP(jit, REG_EAX);
IA32_Push_Reg(jit, REG_EAX);
IA32_Mov_ESP_Disp8_Imm32(jit, 4, 0x7FF);
IA32_Fldcw_Mem16_Disp8_ESP(jit, 4);
IA32_Push_Reg(jit, REG_EAX);
IA32_Fistp_Mem32_ESP(jit);
IA32_Pop_Reg(jit, REG_EAX);
IA32_Pop_Reg(jit, REG_ECX);
IA32_Mov_RmESP_Reg(jit, REG_ECX);
IA32_Fldcw_Mem16_ESP(jit);
IA32_Add_Rm_Imm8(jit, REG_ESP, 4, MOD_REG);
/* Rectify the stack */
//add edi, 4
IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
}
inline void WriteOp_RoundToCeil(JitWriter *jit)
{
//push eax
//fld [edi]
//fstcw [esp]
//mov eax, [esp]
//push eax
//mov [esp+4], 0xBFF
//fldcw [esp+4]
//push eax
//fistp [esp]
//pop eax
//pop ecx
//mov [esp], ecx
//fldcw [esp]
//add esp, 4
IA32_Push_Reg(jit, REG_EAX);
IA32_Fld_Mem32(jit, AMX_REG_STK);
IA32_Fstcw_Mem16_ESP(jit);
IA32_Mov_Reg_RmESP(jit, REG_EAX);
IA32_Push_Reg(jit, REG_EAX);
IA32_Mov_ESP_Disp8_Imm32(jit, 4, 0xBFF);
IA32_Fldcw_Mem16_Disp8_ESP(jit, 4);
IA32_Push_Reg(jit, REG_EAX);
IA32_Fistp_Mem32_ESP(jit);
IA32_Pop_Reg(jit, REG_EAX);
IA32_Pop_Reg(jit, REG_ECX);
IA32_Mov_RmESP_Reg(jit, REG_ECX);
IA32_Fldcw_Mem16_ESP(jit);
IA32_Add_Rm_Imm8(jit, REG_ESP, 4, MOD_REG);
/* Rectify the stack */
//add edi, 4
IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
}
inline void WriteOp_RoundToZero(JitWriter *jit)
{
//push eax
//fld [edi]
//fstcw [esp]
//mov eax, [esp]
//push eax
//mov [esp+4], 0xFFF
//fldcw [esp+4]
//push eax
//fistp [esp]
//pop eax
//pop ecx
//mov [esp], ecx
//fldcw [esp]
//add esp, 4
IA32_Push_Reg(jit, REG_EAX);
IA32_Fld_Mem32(jit, AMX_REG_STK);
IA32_Fstcw_Mem16_ESP(jit);
IA32_Mov_Reg_RmESP(jit, REG_EAX);
IA32_Push_Reg(jit, REG_EAX);
IA32_Mov_ESP_Disp8_Imm32(jit, 4, 0xFFF);
IA32_Fldcw_Mem16_Disp8_ESP(jit, 4);
IA32_Push_Reg(jit, REG_EAX);
IA32_Fistp_Mem32_ESP(jit);
IA32_Pop_Reg(jit, REG_EAX);
IA32_Pop_Reg(jit, REG_ECX);
IA32_Mov_RmESP_Reg(jit, REG_ECX);
IA32_Fldcw_Mem16_ESP(jit);
IA32_Add_Rm_Imm8(jit, REG_ESP, 4, MOD_REG);
/* Rectify the stack */
//add edi, 4
IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
}
inline void WriteOp_FloatCompare(JitWriter *jit)
{
CompData *data = (CompData *)jit->data;
//fld [edi]
//fld [edi+4]
//fucomip st(0), st(1)
//mov ecx, <round_table>
//cmovz eax, [ecx+4]
//cmovb eax, [ecx+8]
//cmova eax, [ecx]
//fstp st(0)
IA32_Fld_Mem32(jit, AMX_REG_STK);
IA32_Fld_Mem32_Disp8(jit, AMX_REG_STK, 4);
IA32_Fucomip_ST0_FPUreg(jit, 1);
IA32_Mov_Reg_Imm32(jit, AMX_REG_TMP, (jit_int32_t)jit->outbase + data->jit_rounding_table);
IA32_CmovCC_Rm_Disp8(jit, AMX_REG_TMP, CC_Z, 4);
IA32_CmovCC_Rm_Disp8(jit, AMX_REG_TMP, CC_B, 8);
IA32_CmovCC_Rm(jit, AMX_REG_TMP, CC_A);
IA32_Fstp_FPUreg(jit, 0);
/* Rectify the stack */
//add edi, 8
IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 8, MOD_REG);
}
/************************************************* /*************************************************
************************************************* *************************************************
* JIT PROPER ************************************ * JIT PROPER ************************************
@ -1979,6 +2295,10 @@ jit_rewind:
Write_Check_VerifyAddr(jit, REG_EDX); Write_Check_VerifyAddr(jit, REG_EDX);
} }
/* Write the rounding table for the float compare opcode */
data->jit_rounding_table = jit->get_outputpos();
Write_RoundingTable(jit);
/* Actual code generation! */ /* Actual code generation! */
if (writer.outbase == NULL) if (writer.outbase == NULL)
{ {
@ -1998,6 +2318,22 @@ jit_rewind:
/* Now read the opcode and continue. */ /* Now read the opcode and continue. */
op = (OPCODE)writer.read_cell(); op = (OPCODE)writer.read_cell();
/* Patch the floating point natives with our opcodes */
if (op == OP_SYSREQ_N)
{
cell_t idx = writer.read_cell();
if (data->jit_float_table[idx].found)
{
writer.inptr -= 2;
*(writer.inptr++) = data->jit_float_table[idx].index;
*(writer.inptr++) = OP_NOP;
*(writer.inptr++) = OP_NOP;
op = (OPCODE)data->jit_float_table[idx].index;
} else {
writer.inptr--;
}
}
switch (op) switch (op)
{ {
#include "opcode_switch.inc" #include "opcode_switch.inc"
@ -2270,11 +2606,54 @@ void JITX86::FreeContext(sp_context_t *ctx)
ICompilation *JITX86::StartCompilation(sp_plugin_t *plugin) ICompilation *JITX86::StartCompilation(sp_plugin_t *plugin)
{ {
CompData *data = new CompData; CompData *data = new CompData;
uint32_t max_natives = plugin->info.natives_num;
const char *strbase = plugin->info.stringbase;
data->plugin = plugin; data->plugin = plugin;
data->inline_level = JIT_INLINE_ERRORCHECKS|JIT_INLINE_NATIVES; data->inline_level = JIT_INLINE_ERRORCHECKS|JIT_INLINE_NATIVES;
data->error_set = SP_ERROR_NONE; data->error_set = SP_ERROR_NONE;
data->jit_float_table = new floattbl_t[max_natives];
for (uint32_t i=0; i<max_natives; i++)
{
const char *name = strbase + plugin->info.natives[i].name;
if (!strcmp(name, "FloatAbs"))
{
data->jit_float_table[i].found = true;
data->jit_float_table[i].index = OP_FABS;
} else if (!strcmp(name, "FloatAdd")) {
data->jit_float_table[i].found = true;
data->jit_float_table[i].index = OP_FLOATADD;
} else if (!strcmp(name, "FloatSub")) {
data->jit_float_table[i].found = true;
data->jit_float_table[i].index = OP_FLOATSUB;
} else if (!strcmp(name, "FloatMul")) {
data->jit_float_table[i].found = true;
data->jit_float_table[i].index = OP_FLOATMUL;
} else if (!strcmp(name, "FloatDiv")) {
data->jit_float_table[i].found = true;
data->jit_float_table[i].index = OP_FLOATDIV;
} else if (!strcmp(name, "float")) {
data->jit_float_table[i].found = true;
data->jit_float_table[i].index = OP_FLOAT;
} else if (!strcmp(name, "FloatCompare")) {
data->jit_float_table[i].found = true;
data->jit_float_table[i].index = OP_FLOATCMP;
} else if (!strcmp(name, "RoundToZero")) {
data->jit_float_table[i].found = true;
data->jit_float_table[i].index = OP_RND_TO_ZERO;
} else if (!strcmp(name, "RoundToCeil")) {
data->jit_float_table[i].found = true;
data->jit_float_table[i].index = OP_RND_TO_CEIL;
} else if (!strcmp(name, "RoundToFloor")) {
data->jit_float_table[i].found = true;
data->jit_float_table[i].index = OP_RND_TO_FLOOR;
} else if (!strcmp(name, "RountToNearest")) {
data->jit_float_table[i].found = true;
data->jit_float_table[i].index = OP_RND_TO_NEAREST;
}
}
return data; return data;
} }
@ -2284,6 +2663,7 @@ void JITX86::AbortCompilation(ICompilation *co)
{ {
engine->BaseFree(((CompData *)co)->rebase); engine->BaseFree(((CompData *)co)->rebase);
} }
delete [] ((CompData *)co)->jit_float_table;
delete (CompData *)co; delete (CompData *)co;
} }

View File

@ -49,6 +49,17 @@ typedef struct functracker_s
unsigned int code_size; unsigned int code_size;
} functracker_t; } functracker_t;
struct floattbl_t
{
floattbl_t()
{
found = false;
index = 0;
}
bool found;
unsigned int index;
};
class CompData : public ICompilation class CompData : public ICompilation
{ {
public: public:
@ -80,6 +91,8 @@ public:
jitoffs_t jit_error_array_too_big; jitoffs_t jit_error_array_too_big;
jitoffs_t jit_extern_error; /* returning generic error */ jitoffs_t jit_extern_error; /* returning generic error */
jitoffs_t jit_sysreq_c; /* old version! */ jitoffs_t jit_sysreq_c; /* old version! */
jitoffs_t jit_rounding_table;
floattbl_t *jit_float_table;
uint32_t codesize; /* total codesize */ uint32_t codesize; /* total codesize */
}; };

View File

@ -799,3 +799,10 @@ int JIT_VerifyLowBoundTracker(sp_context_t *ctx)
return SP_ERROR_NONE; return SP_ERROR_NONE;
} }
void Write_RoundingTable(JitWriter *jit)
{
jit->write_int32(-1);
jit->write_int32(0);
jit->write_int32(1);
}

View File

@ -91,6 +91,11 @@ int JIT_VerifyOrAllocateTracker(sp_context_t *ctx);
*/ */
void WriteOp_Tracker_Push_Reg(JitWriter *jit, uint8_t reg); void WriteOp_Tracker_Push_Reg(JitWriter *jit, uint8_t reg);
/**
* Writes the rounding table for the float compare opcode.
*/
void Write_RoundingTable(JitWriter *jit);
/** /**
* Legend for Statuses: * Legend for Statuses:
* ****** *** ******** * ****** *** ********
@ -275,6 +280,17 @@ typedef enum
OP_GENARRAY, //VERIFIED OP_GENARRAY, //VERIFIED
OP_GENARRAY_Z, //-VERIFIED (not tested for 1D arrays) OP_GENARRAY_Z, //-VERIFIED (not tested for 1D arrays)
OP_STRADJUST_PRI, //VERIFIED OP_STRADJUST_PRI, //VERIFIED
OP_FABS, //VERIFIED
OP_FLOAT, //VERIFIED
OP_FLOATADD, //VERIFIED
OP_FLOATSUB, //VERIFIED
OP_FLOATMUL, //VERIFIED
OP_FLOATDIV, //VERIFIED
OP_RND_TO_NEAREST, //VERIFIED
OP_RND_TO_FLOOR, //VERIFIED
OP_RND_TO_CEIL, //VERIFIED
OP_RND_TO_ZERO, //VERIFIED
OP_FLOATCMP, //VERIFIED
/* ----- */ /* ----- */
OP_NUM_OPCODES OP_NUM_OPCODES
} OPCODE; } OPCODE;
@ -294,7 +310,7 @@ typedef enum
* EXEC FUNCTION * EXEC FUNCTION
* VERIFY ADDR * VERIFY ADDR
* *
* Oh and ALIGN all stuff that is called via CALL like what's done with PROC. * Oh and ALIGN to 16BYTES all stuff that is called via CALL and frequently used jump labels like what's done with PROC.
*/ */
#endif //_INCLUDE_SOURCEPAWN_JIT_X86_OPCODE_INFO_H_ #endif //_INCLUDE_SOURCEPAWN_JIT_X86_OPCODE_INFO_H_

View File

@ -678,6 +678,61 @@
WriteOp_Stradjust_Pri(jit); WriteOp_Stradjust_Pri(jit);
break; break;
} }
case OP_FABS:
{
WriteOp_FloatAbs(jit);
break;
}
case OP_FLOAT:
{
WriteOp_Float(jit);
break;
}
case OP_FLOATADD:
{
WriteOp_FloatAdd(jit);
break;
}
case OP_FLOATSUB:
{
WriteOp_FloatSub(jit);
break;
}
case OP_FLOATMUL:
{
WriteOp_FloatMul(jit);
break;
}
case OP_FLOATDIV:
{
WriteOp_FloatDiv(jit);
break;
}
case OP_RND_TO_NEAREST:
{
WriteOp_RountToNearest(jit);
break;
}
case OP_RND_TO_FLOOR:
{
WriteOp_RoundToFloor(jit);
break;
}
case OP_RND_TO_ZERO:
{
WriteOp_RoundToZero(jit);
break;
}
case OP_RND_TO_CEIL:
{
WriteOp_RoundToCeil(jit);
break;
}
case OP_FLOATCMP:
{
WriteOp_FloatCompare(jit);
break;
}
#if defined USE_UNGEN_OPCODES #if defined USE_UNGEN_OPCODES
#include "ungen_opcode_switch.inc" #include "ungen_opcode_switch.inc"
#endif #endif
@ -686,5 +741,3 @@
data->error_set = SP_ERROR_INVALID_INSTRUCTION; data->error_set = SP_ERROR_INVALID_INSTRUCTION;
break; break;
} }