From 0503ac73b7e4c9ca254f1b4c43660915e63a476f Mon Sep 17 00:00:00 2001 From: David Anderson <dvander@alliedmods.net> Date: Wed, 20 Sep 2006 15:51:05 +0000 Subject: [PATCH] implemented some more opcode --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%4081 --- sourcepawn/vm/jit/jit_helpers.h | 8 ++ sourcepawn/vm/jit/x86/jit_x86.cpp | 117 ++++++++++++++++++++++- sourcepawn/vm/jit/x86/jit_x86.h | 4 +- sourcepawn/vm/jit/x86/opcode_helpers.cpp | 5 + sourcepawn/vm/jit/x86/opcode_helpers.h | 12 +-- sourcepawn/vm/jit/x86/x86_macros.h | 40 ++++++++ 6 files changed, 178 insertions(+), 8 deletions(-) diff --git a/sourcepawn/vm/jit/jit_helpers.h b/sourcepawn/vm/jit/jit_helpers.h index 5b74ce65..e7d79084 100644 --- a/sourcepawn/vm/jit/jit_helpers.h +++ b/sourcepawn/vm/jit/jit_helpers.h @@ -63,6 +63,14 @@ public: } outptr += sizeof(jit_int32_t); } + inline void write_uint32(jit_uint32_t c) + { + if (outptr) + { + *(jit_uint32_t *)outptr = c; + } + outptr += sizeof(jit_uint32_t); + } inline jitoffs_t jit_curpos() { return (outptr - outbase); diff --git a/sourcepawn/vm/jit/x86/jit_x86.cpp b/sourcepawn/vm/jit/x86/jit_x86.cpp index e7cc2885..ba292178 100644 --- a/sourcepawn/vm/jit/x86/jit_x86.cpp +++ b/sourcepawn/vm/jit/x86/jit_x86.cpp @@ -755,6 +755,15 @@ inline void WriteOp_Idxaddr(JitWriter *jit) IA32_Lea_Reg_DispRegMult(jit, AMX_REG_PRI, AMX_REG_ALT, AMX_REG_PRI, SCALE4); } +inline void WriteOp_Idxaddr_B(JitWriter *jit) +{ + cell_t val = jit->read_cell(); + //shl eax, <val> + //add eax, edx + IA32_Shl_Rm_Imm8(jit, AMX_REG_PRI, val, MOD_REG); + IA32_Add_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG); +} + inline void WriteOp_Sref_Pri(JitWriter *jit) { //mov ecx, [edi+<val>] @@ -1003,10 +1012,86 @@ inline void WriteOp_Const_S(JitWriter *jit) inline void WriteOp_Load_I(JitWriter *jit) { //mov eax, [edi+eax] - Write_Check_VerifyAddr(jit, REG_EAX, false); + Write_Check_VerifyAddr(jit, AMX_REG_PRI, false); IA32_Mov_Reg_Rm_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE); } +inline void WriteOp_Lodb_I(JitWriter *jit) +{ + Write_Check_VerifyAddr(jit, AMX_REG_PRI, false); + + //mov eax, [edi+eax] + IA32_Mov_Reg_Rm_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE); + + //and eax, <bitmask> + cell_t val = jit->read_cell(); + switch(val) + { + case 1: + { + IA32_And_Rm_Imm32(jit, AMX_REG_PRI, 0x000000FF); + break; + } + case 2: + { + IA32_And_Rm_Imm32(jit, AMX_REG_PRI, 0x0000FFFF); + break; + } + } +} + +inline void WriteOp_Stor_I(JitWriter *jit) +{ + //mov [edi+edx], eax + Write_Check_VerifyAddr(jit, AMX_REG_ALT, false); + IA32_Mov_Rm_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_ALT, NOSCALE, AMX_REG_PRI); +} + +inline void WriteOp_Strb_I(JitWriter *jit) +{ + Write_Check_VerifyAddr(jit, AMX_REG_ALT, false); + //mov [edi+edx], eax + cell_t val = jit->read_cell(); + switch (val) + { + case 1: + { + IA32_Mov_Rm8_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_ALT, NOSCALE, AMX_REG_PRI); + break; + } + case 2: + { + IA32_Mov_Rm16_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_ALT, NOSCALE, AMX_REG_PRI); + break; + } + case 3: + { + IA32_Mov_Rm_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_ALT, NOSCALE, AMX_REG_PRI); + break; + } + } +} + +inline void WriteOp_Lidx(JitWriter *jit) +{ + //lea eax, [edx+4*eax] + //mov eax, [edi+eax] + IA32_Lea_Reg_DispRegMult(jit, AMX_REG_PRI, AMX_REG_ALT, AMX_REG_PRI, SCALE4); + Write_Check_VerifyAddr(jit, AMX_REG_PRI, false); + IA32_Mov_Reg_Rm_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE); +} + +inline void WriteOp_Lidx_B(JitWriter *jit) +{ + cell_t val = jit->read_cell(); + //shl eax, <val> + //add eax, edx + //mov eax, [edi+eax] + IA32_Shl_Rm_Imm8(jit, AMX_REG_PRI, val, MOD_REG); + IA32_Add_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG); + Write_Check_VerifyAddr(jit, AMX_REG_PRI, false); + IA32_Mov_Reg_Rm_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE); +} /************************************************* ************************************************* @@ -1667,6 +1752,36 @@ IPluginContext *JITX86::CompileToContext(ICompilation *co, int *err) WriteOp_Load_I(jit); break; } + case OP_LODB_I: + { + WriteOp_Lodb_I(jit); + break; + } + case OP_STOR_I: + { + WriteOp_Stor_I(jit); + break; + } + case OP_STRB_I: + { + WriteOp_Strb_I(jit); + break; + } + case OP_LIDX: + { + WriteOp_Lidx(jit); + break; + } + case OP_LIDX_B: + { + WriteOp_Lidx_B(jit); + break; + } + case OP_IDXADDR_B: + { + WriteOp_Idxaddr_B(jit); + break; + } default: { AbortCompilation(co); diff --git a/sourcepawn/vm/jit/x86/jit_x86.h b/sourcepawn/vm/jit/x86/jit_x86.h index 0eb22f8f..5e53ee33 100644 --- a/sourcepawn/vm/jit/x86/jit_x86.h +++ b/sourcepawn/vm/jit/x86/jit_x86.h @@ -13,7 +13,8 @@ using namespace SourcePawn; class CompData : public ICompilation { public: - CompData() : plugin(NULL), debug(false), inline_level(3) + CompData() : plugin(NULL), + debug(false), inline_level(3), checks(true) { }; public: @@ -22,6 +23,7 @@ public: jitoffs_t jit_verify_addr_eax; jitoffs_t jit_verify_addr_edx; int inline_level; + bool checks; bool debug; }; diff --git a/sourcepawn/vm/jit/x86/opcode_helpers.cpp b/sourcepawn/vm/jit/x86/opcode_helpers.cpp index 0b5180f9..df8bde71 100644 --- a/sourcepawn/vm/jit/x86/opcode_helpers.cpp +++ b/sourcepawn/vm/jit/x86/opcode_helpers.cpp @@ -147,6 +147,11 @@ void Write_Check_VerifyAddr(JitWriter *jit, jit_uint8_t reg, bool firstcall) * The old JIT did not. */ + if (!data->checks) + { + return; + } + bool call = false; if (!(data->inline_level & JIT_INLINE_ERRORCHECKS)) { diff --git a/sourcepawn/vm/jit/x86/opcode_helpers.h b/sourcepawn/vm/jit/x86/opcode_helpers.h index 7cb8efd5..3fbc6801 100644 --- a/sourcepawn/vm/jit/x86/opcode_helpers.h +++ b/sourcepawn/vm/jit/x86/opcode_helpers.h @@ -42,7 +42,7 @@ typedef enum OP_LREF_S_PRI, //DONE OP_LREF_S_ALT, //DONE OP_LOAD_I, //DONE - OP_LODB_I, + OP_LODB_I, //DONE OP_CONST_PRI, //DONE OP_CONST_ALT, //DONE OP_ADDR_PRI, //DONE @@ -55,12 +55,12 @@ typedef enum OP_SREF_ALT, //DONE OP_SREF_S_PRI, //DONE OP_SREF_S_ALT, //DONE - OP_STOR_I, - OP_STRB_I, - OP_LIDX, - OP_LIDX_B, + OP_STOR_I, //DONE + OP_STRB_I, //DONE + OP_LIDX, //DONE + OP_LIDX_B, //DONE OP_IDXADDR, //DONE - OP_IDXADDR_B, + OP_IDXADDR_B, //DONE OP_ALIGN_PRI, //DONE OP_ALIGN_ALT, //DONE OP_LCTRL, diff --git a/sourcepawn/vm/jit/x86/x86_macros.h b/sourcepawn/vm/jit/x86/x86_macros.h index 067e6620..d12b86df 100644 --- a/sourcepawn/vm/jit/x86/x86_macros.h +++ b/sourcepawn/vm/jit/x86/x86_macros.h @@ -25,6 +25,8 @@ #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 @@ -65,6 +67,7 @@ #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_MEM 0x8B // encoding is /r #define IA32_MOV_RM_IMM32 0xC7 // encoding is /0 @@ -83,6 +86,8 @@ #define IA32_DEC_RM 0xFF // encoding is /1 #define IA32_OR_RM_REG 0x09 // encoding is /r #define IA32_AND_RM_REG 0x21 // encoding is /r +#define IA32_AND_EAX_IMM32 0x25 // encoding is <imm32> +#define IA32_AND_RM_IMM32 0x81 // 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 @@ -238,6 +243,18 @@ inline void IA32_And_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, j jit->write_ubyte(ia32_modrm(mode, src, dest)); } +inline void IA32_And_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_uint32_t c) +{ + if (reg == REG_EAX) + { + jit->write_ubyte(IA32_AND_EAX_IMM32); + } else { + jit->write_ubyte(IA32_AND_RM_IMM32); + jit->write_ubyte(ia32_modrm(MOD_REG, 4, reg)); + } + jit->write_uint32(c); +} + inline void IA32_Not_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) { jit->write_ubyte(IA32_NOT_RM); @@ -606,6 +623,29 @@ inline void IA32_Mov_Rm_Reg_Disp_Reg(JitWriter *jit, jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base)); } +inline void IA32_Mov_Rm8_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_MEM_REG, src, REG_SIB)); + jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base)); +} + +inline void IA32_Mov_Rm16_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_MEM_REG, src, REG_SIB)); + jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base)); +} + /** * Moving from IMMEDIATE to REGISTER */