From 968692755bbc4ad0cbdad0a46b436582cf55c03b Mon Sep 17 00:00:00 2001 From: David Anderson Date: Sat, 23 Sep 2006 04:11:01 +0000 Subject: [PATCH] merged in the easy relocation requiring opcodes --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%4096 --- sourcepawn/vm/jit/jit_helpers.h | 6 + sourcepawn/vm/jit/x86/jit_x86.cpp | 892 +++++---------------- sourcepawn/vm/jit/x86/jit_x86.h | 9 +- sourcepawn/vm/jit/x86/msvc8/jit-x86.vcproj | 4 + sourcepawn/vm/jit/x86/opcode_helpers.h | 28 +- sourcepawn/vm/jit/x86/opcode_switch.inc | 724 +++++++++++++++++ sourcepawn/vm/jit/x86/x86_macros.h | 20 +- 7 files changed, 990 insertions(+), 693 deletions(-) create mode 100644 sourcepawn/vm/jit/x86/opcode_switch.inc diff --git a/sourcepawn/vm/jit/jit_helpers.h b/sourcepawn/vm/jit/jit_helpers.h index 43e6bd58..d0bf929d 100644 --- a/sourcepawn/vm/jit/jit_helpers.h +++ b/sourcepawn/vm/jit/jit_helpers.h @@ -23,6 +23,7 @@ typedef unsigned __int64 jit_uint64_t; typedef char * jitcode_t; typedef unsigned int jitoffs_t; +typedef signed int jitrel_t; class JitWriter { @@ -79,8 +80,13 @@ public: { outptr = outbase + offs; } + inline jitoffs_t inputrel() + { + return (jitoffs_t)((char *)inptr - (char *)inbase); + } public: cell_t *inptr; /* input pointer */ + cell_t *inbase; /* input base */ jitcode_t outbase; /* output pointer */ jitcode_t outptr; /* output base */ SourcePawn::ICompilation *data; /* compiler live info */ diff --git a/sourcepawn/vm/jit/x86/jit_x86.cpp b/sourcepawn/vm/jit/x86/jit_x86.cpp index 1a302586..b69ea6d5 100644 --- a/sourcepawn/vm/jit/x86/jit_x86.cpp +++ b/sourcepawn/vm/jit/x86/jit_x86.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "jit_x86.h" #include "opcode_helpers.h" #include "x86_macros.h" @@ -1398,15 +1399,165 @@ inline void WriteOp_Break(JitWriter *jit) } } +inline void WriteOp_JRel(JitWriter *jit) +{ + //jmp ;relative jump + cell_t cip_offs = jit->read_cell(); + + /* Note that since code size calculation has to be done in the same + * phase as building relocation information, we cannot know the jump size + * beforehand. Thus, we always write full 32bit jumps for safety. + */ + jitoffs_t jmp = IA32_Jump_Imm32(jit, 0); + IA32_Write_Jump32(jit, jmp, RelocLookup(jit, cip_offs)); +} + +inline void WriteOp_Jump(JitWriter *jit) +{ + //jmp + cell_t amx_offs = jit->read_cell(); + + IA32_Jump_Imm32_Abs(jit, RelocLookup(jit, amx_offs, false)); +} + +inline void WriteOp_Jzer(JitWriter *jit) +{ + //test eax, eax + //jz + cell_t target = jit->read_cell(); + IA32_Test_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_PRI, MOD_REG); + IA32_Jump_Imm32_Abs(jit, RelocLookup(jit, target, false)); + IA32_Jump_Cond_Imm32_Abs(jit, CC_Z, RelocLookup(jit, target, false)); +} + +inline void WriteOp_Jnz(JitWriter *jit) +{ + //test eax, eax + //jnz + cell_t target = jit->read_cell(); + IA32_Test_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_PRI, MOD_REG); + IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, RelocLookup(jit, target, false)); +} + +inline void WriteOp_Jeq(JitWriter *jit) +{ + //cmp eax, edx + //je + cell_t target = jit->read_cell(); + IA32_Cmp_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG); + IA32_Jump_Cond_Imm32_Abs(jit, CC_E, RelocLookup(jit, target, false)); +} + +inline void WriteOp_Jneq(JitWriter *jit) +{ + //cmp eax, edx + //jne + cell_t target = jit->read_cell(); + IA32_Cmp_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG); + IA32_Jump_Cond_Imm32(jit, CC_NE, RelocLookup(jit, target, false)); +} + +inline void WriteOp_Jless(JitWriter *jit) +{ + //cmp eax, edx + //jb + cell_t target = jit->read_cell(); + IA32_Cmp_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG); + IA32_Jump_Cond_Imm32(jit, CC_B, RelocLookup(jit, target, false)); +} + +inline void WriteOp_Jleq(JitWriter *jit) +{ + //cmp eax, edx + //jbe + cell_t target = jit->read_cell(); + IA32_Cmp_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG); + IA32_Jump_Cond_Imm32(jit, CC_BE, RelocLookup(jit, target, false)); +} + +inline void WriteOp_Jgrtr(JitWriter *jit) +{ + //cmp eax, edx + //ja + cell_t target = jit->read_cell(); + IA32_Cmp_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG); + IA32_Jump_Cond_Imm32(jit, CC_A, RelocLookup(jit, target, false)); +} + +inline void WriteOp_Jgeq(JitWriter *jit) +{ + //cmp eax, edx + //jae + cell_t target = jit->read_cell(); + IA32_Cmp_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG); + IA32_Jump_Cond_Imm32(jit, CC_AE, RelocLookup(jit, target, false)); +} + +inline void WriteOp_Jsless(JitWriter *jit) +{ + //cmp eax, edx + //jl + cell_t target = jit->read_cell(); + IA32_Cmp_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG); + IA32_Jump_Cond_Imm32(jit, CC_L, RelocLookup(jit, target, false)); +} + +inline void WriteOp_Jsleq(JitWriter *jit) +{ + //cmp eax, edx + //jle + cell_t target = jit->read_cell(); + IA32_Cmp_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG); + IA32_Jump_Cond_Imm32(jit, CC_LE, RelocLookup(jit, target, false)); +} + +inline void WriteOp_JsGrtr(JitWriter *jit) +{ + //cmp eax, edx + //jg + cell_t target = jit->read_cell(); + IA32_Cmp_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG); + IA32_Jump_Cond_Imm32(jit, CC_G, RelocLookup(jit, target, false)); +} + +inline void WriteOp_JsGeq(JitWriter *jit) +{ + //cmp eax, edx + //jge + cell_t target = jit->read_cell(); + IA32_Cmp_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG); + IA32_Jump_Cond_Imm32(jit, CC_GE, RelocLookup(jit, target, false)); +} /************************************************* ************************************************* * JIT PROPER ************************************ - * The rest of the from now on is the JIT engine * + * The rest from now on is the JIT engine * ************************************************* *************************************************/ +jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative) +{ + if (jit->outptr) + { + CompData *data = (CompData *)jit->data; + if (relative) + { + /* The actual offset is EIP relative. We need to relocate it. + * Note that this assumes that we're pointing to the next op. + */ + pcode_offs += jit->inputrel(); + } + /* Offset must always be 1)positive and 2)less than the codesize */ + assert(pcode_offs >= 0 && (uint32_t)pcode_offs < data->codesize); + /* Do the lookup in the native dictionary. */ + return *(jitoffs_t *)(data->rebase + pcode_offs); + } else { + return 0; + } +} + IPluginContext *JITX86::CompileToContext(ICompilation *co, int *err) { CompData *data = (CompData *)co; @@ -1418,7 +1569,6 @@ IPluginContext *JITX86::CompileToContext(ICompilation *co, int *err) uint8_t *end_cip = plugin->pcode + plugin->pcode_size; OPCODE op; int op_c; - uint32_t reloc_count = 0; /* FIRST PASS (light load) - Get initial opcode information */ for (cip = code; cip < end_cip;) @@ -1440,7 +1590,7 @@ IPluginContext *JITX86::CompileToContext(ICompilation *co, int *err) *err = SP_ERR_INVALID_INSTRUCTION; return NULL; } else if (op_c == -2) { - reloc_count++; + /* :TODO: get rid of this block */ cip += sizeof(cell_t); } else if (op_c == -1) { switch (op) @@ -1449,7 +1599,6 @@ IPluginContext *JITX86::CompileToContext(ICompilation *co, int *err) { ucell_t num = *(ucell_t *)cip; cip += sizeof(cell_t); - reloc_count += (num + 1); cip += ((2*num) + 1) * sizeof(cell_t); break; } @@ -1476,13 +1625,16 @@ IPluginContext *JITX86::CompileToContext(ICompilation *co, int *err) /* Initial code is written "blank," * so we can check the exact memory usage. */ - writer.inptr = (cell_t *)code; + data->codesize = plugin->pcode_size; + writer.inbase = (cell_t *)code; writer.outptr = NULL; writer.outbase = NULL; + data->rebase = (jitcode_t *)engine->BaseAlloc(plugin->pcode_size); -//:TODO: Jump back here once finished! - + /* Jump back here for second pass */ +jit_rewind: /* Initialize pass vars */ + writer.inptr = writer.inbase; data->jit_chkmargin_heap = 0; data->jit_verify_addr_eax = 0; data->jit_verify_addr_edx = 0; @@ -1511,684 +1663,70 @@ IPluginContext *JITX86::CompileToContext(ICompilation *co, int *err) data->jit_bounds = jitpos; } - /* Begin opcode browsing */ - for (; writer.inptr <= endptr;) + if (writer.outbase == NULL) { - op = (OPCODE)writer.read_cell(); - switch (op) + /******* + * SECOND PASS - get opcode sizes+info + *******/ + jitoffs_t pcode_offs; + jitoffs_t native_offs; + + for (; writer.inptr <= endptr;) { - case OP_MOVE_PRI: - { - WriteOp_Move_Pri(jit); - break; - } - case OP_MOVE_ALT: - { - WriteOp_Move_Alt(jit); - break; - } - case OP_XCHG: - { - WriteOp_Xchg(jit); - break; - } - case OP_PUSH: - { - WriteOp_Push(jit); - break; - } - case OP_PUSH_S: - { - WriteOp_Push_S(jit); - break; - } - case OP_PUSH2_C: - { - WriteOp_Push2_C(jit); - break; - } - case OP_PUSH3_C: - { - WriteOp_Push3(jit); - break; - } - case OP_PUSH4_C: - { - WriteOp_Push4_C(jit); - break; - } - case OP_PUSH5_C: - { - WriteOp_Push5_C(jit); - break; - } - case OP_PUSH2_ADR: - { - WriteOp_Push2_Adr(jit); - break; - } - case OP_PUSH3_ADR: - { - WriteOp_Push3_Adr(jit); - break; - } - case OP_PUSH4_ADR: - { - WriteOp_Push4_Adr(jit); - break; - } - case OP_PUSH5_ADR: - { - WriteOp_Push5_Adr(jit); - break; - } - case OP_PUSH2_S: - { - WriteOp_Push2_S(jit); - break; - } - case OP_PUSH3_S: - { - WriteOp_Push3_S(jit); - break; - } - case OP_PUSH4_S: - { - WriteOp_Push4_S(jit); - break; - } - case OP_PUSH5_S: - { - WriteOp_Push5_S(jit); - break; - } - case OP_PUSH5: - { - WriteOp_Push5(jit); - break; - } - case OP_PUSH4: - { - WriteOp_Push4(jit); - break; - } - case OP_PUSH3: - { - WriteOp_Push3(jit); - break; - } - case OP_PUSH2: - { - WriteOp_Push2(jit); - break; - } - case OP_ZERO_PRI: - { - WriteOp_Zero_Pri(jit); - break; - } - case OP_ZERO_ALT: - { - WriteOp_Zero_Alt(jit); - break; - } - case OP_PROC: - { - WriteOp_Proc(jit); - break; - } - case OP_SHL: - { - WriteOp_Shl(jit); - break; - } - case OP_SHR: - { - WriteOp_Shr(jit); - break; - } - case OP_SSHR: - { - WriteOp_Sshr(jit); - break; - } - case OP_SHL_C_PRI: - { - WriteOp_Shl_C_Pri(jit); - break; - } - case OP_SHL_C_ALT: - { - WriteOp_Shl_C_Alt(jit); - break; - } - case OP_SHR_C_PRI: - { - WriteOp_Shr_C_Pri(jit); - break; - } - case OP_SHR_C_ALT: - { - WriteOp_Shr_C_Alt(jit); - break; - } - case OP_SMUL: - { - WriteOp_SMul(jit); - break; - } - case OP_UMUL: - { - WriteOp_UMul(jit); - break; - } - case OP_ADD: - { - WriteOp_Add(jit); - break; - } - case OP_SUB: - { - WriteOp_Sub(jit); - break; - } - case OP_SUB_ALT: - { - WriteOp_Sub_Alt(jit); - break; - } - case OP_NOP: - { - /* do nothing */ - break; - } - case OP_NOT: - { - WriteOp_Not(jit); - break; - } - case OP_NEG: - { - WriteOp_Neg(jit); - break; - } - case OP_XOR: - { - WriteOp_Xor(jit); - break; - } - case OP_OR: - { - WriteOp_Or(jit); - break; - } - case OP_AND: - { - WriteOp_And(jit); - break; - } - case OP_INVERT: - { - WriteOp_Invert(jit); - break; - } - case OP_ADD_C: - { - WriteOp_Add_C(jit); - break; - } - case OP_SMUL_C: - { - WriteOp_SMul_C(jit); - break; - } - case OP_SIGN_PRI: - { - WriteOp_Sign_Pri(jit); - break; - } - case OP_SIGN_ALT: - { - WriteOp_Sign_Alt(jit); - break; - } - case OP_EQ: - { - WriteOp_Eq(jit); - break; - } - case OP_NEQ: - { - WriteOp_Neq(jit); - break; - } - case OP_LESS: - { - WriteOp_Less(jit); - break; - } - case OP_LEQ: - { - WriteOp_Leq(jit); - break; - } - case OP_GRTR: - { - WriteOp_Grtr(jit); - break; - } - case OP_GEQ: - { - WriteOp_Geq(jit); - break; - } - case OP_SLESS: - { - WriteOp_Sless(jit); - break; - } - case OP_SLEQ: - { - WriteOp_Sleq(jit); - break; - } - case OP_SGRTR: - { - WriteOp_Sgrtr(jit); - break; - } - case OP_SGEQ: - { - WriteOp_Sgeq(jit); - break; - } - case OP_EQ_C_PRI: - { - WriteOp_Eq_C_Pri(jit); - break; - } - case OP_EQ_C_ALT: - { - WriteOp_Eq_C_Alt(jit); - break; - } - case OP_INC_PRI: - { - WriteOp_Inc_Pri(jit); - break; - } - case OP_INC_ALT: - { - WriteOp_Inc_Alt(jit); - break; - } - case OP_INC: - { - WriteOp_Inc(jit); - break; - } - case OP_INC_S: - { - WriteOp_Inc_S(jit); - break; - } - case OP_INC_I: - { - WriteOp_Inc_I(jit); - break; - } - case OP_DEC_PRI: - { - WriteOp_Dec_Pri(jit); - break; - } - case OP_DEC_ALT: - { - WriteOp_Dec_Alt(jit); - break; - } - case OP_DEC: - { - WriteOp_Dec(jit); - break; - } - case OP_DEC_S: - { - WriteOp_Dec_S(jit); - break; - } - case OP_DEC_I: - { - WriteOp_Dec_I(jit); - break; - } - case OP_LOAD_PRI: - { - WriteOp_Load_Pri(jit); - break; - } - case OP_LOAD_ALT: - { - WriteOp_Load_Alt(jit); - break; - } - case OP_LOAD_S_PRI: - { - WriteOp_Load_S_Pri(jit); - break; - } - case OP_LOAD_S_ALT: - { - WriteOp_Load_S_Alt(jit); - break; - } - case OP_LREF_PRI: - { - WriteOp_Lref_Pri(jit); - break; - } - case OP_LREF_ALT: - { - WriteOp_Lref_Alt(jit); - break; - } - case OP_LREF_S_PRI: - { - WriteOp_Lref_Pri(jit); - break; - } - case OP_LREF_S_ALT: - { - WriteOp_Lref_Alt(jit); - break; - } - case OP_CONST_PRI: - { - WriteOp_Const_Pri(jit); - break; - } - case OP_CONST_ALT: - { - WriteOp_Const_Alt(jit); - break; - } - case OP_ADDR_PRI: - { - WriteOp_Addr_Pri(jit); - break; - } - case OP_ADDR_ALT: - { - WriteOp_Addr_Alt(jit); - break; - } - case OP_STOR_PRI: - { - WriteOp_Stor_Pri(jit); - break; - } - case OP_STOR_ALT: - { - WriteOp_Stor_Alt(jit); - break; - } - case OP_STOR_S_PRI: - { - WriteOp_Stor_S_Pri(jit); - break; - } - case OP_STOR_S_ALT: - { - WriteOp_Stor_S_Alt(jit); - break; - } - case OP_IDXADDR: - { - WriteOp_Idxaddr(jit); - break; - } - case OP_SREF_PRI: - { - WriteOp_Sref_Pri(jit); - break; - } - case OP_SREF_ALT: - { - WriteOp_Sref_Alt(jit); - break; - } - case OP_SREF_S_PRI: - { - WriteOp_Sref_S_Pri(jit); - break; - } - case OP_SREF_S_ALT: - { - WriteOp_Sref_S_Alt(jit); - break; - } - case OP_ALIGN_PRI: - { - WriteOp_Align_Pri(jit); - break; - } - case OP_ALIGN_ALT: - { - WriteOp_Align_Alt(jit); - break; - } - case OP_POP_PRI: - { - WriteOp_Pop_Pri(jit); - break; - } - case OP_POP_ALT: - { - WriteOp_Pop_Alt(jit); - break; - } - case OP_SWAP_PRI: - { - WriteOp_Swap_Pri(jit); - break; - } - case OP_SWAP_ALT: - { - WriteOp_Swap_Alt(jit); - break; - } - case OP_PUSH_ADR: - { - WriteOp_PushAddr(jit); - break; - } - case OP_MOVS: - { - WriteOp_Movs(jit); - break; - } - case OP_FILL: - { - WriteOp_Fill(jit); - break; - } - case OP_HEAP_PRI: - { - WriteOp_Heap_Pri(jit); - break; - } - case OP_PUSH_HEAP_C: - { - WriteOp_Push_Heap_C(jit); - break; - } - case OP_POP_HEAP_PRI: - { - WriteOp_Pop_Heap_Pri(jit); - break; - } - case OP_PUSH_C: - { - WriteOp_Push_C(jit); - break; - } - case OP_ZERO: - { - WriteOp_Zero(jit); - break; - } - case OP_ZERO_S: - { - WriteOp_Zero_S(jit); - break; - } - case OP_PUSH_PRI: - { - WriteOp_Push_Pri(jit); - break; - } - case OP_PUSH_ALT: - { - WriteOp_Push_Alt(jit); - break; - } - case OP_LOAD_BOTH: - { - WriteOp_Load_Both(jit); - break; - } - case OP_LOAD_S_BOTH: - { - WriteOp_Load_S_Both(jit); - break; - } - case OP_CONST: - { - WriteOp_Const(jit); - break; - } - case OP_CONST_S: - { - WriteOp_Const_S(jit); - break; - } - case OP_LOAD_I: - { - 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; - } - case OP_LCTRL: - { - WriteOp_Lctrl(jit); - break; - } - case OP_SCTRL: - { - WriteOp_Sctrl(jit); - break; - } - case OP_STACK: - { - WriteOp_Stack(jit); - break; - } - case OP_HEAP: - { - WriteOp_Heap(jit); - break; - } - case OP_SDIV: - { - WriteOp_SDiv(jit); - break; - } - case OP_SDIV_ALT: - { - WriteOp_SDiv_Alt(jit); - break; - } - case OP_UDIV: - { - WriteOp_UDiv(jit); - break; - } - case OP_UDIV_ALT: - { - WriteOp_UDiv_Alt(jit); - break; - } - case OP_RET: - { - WriteOp_Ret(jit); - break; - } - case OP_RETN: - { - WriteOp_Retn(jit); - break; - } - case OP_CMPS: - { - WriteOp_Cmps(jit); - break; - } - case OP_BOUNDS: - { - WriteOp_Bounds(jit); - break; - } - case OP_HALT: - { - WriteOp_Halt(jit); - break; - } - case OP_BREAK: - { - WriteOp_Break(jit); - break; - } - default: - { - AbortCompilation(co); - *err = SP_ERR_INVALID_INSTRUCTION; - return NULL; + /* Store the native offset into the rebase memory. + * This large chunk of memory lets us do an instant lookup + * based on an original pcode offset. + */ + pcode_offs = (jitoffs_t)((uint8_t *)writer.inptr - code); + native_offs = jit->jit_curpos(); + *((jitoffs_t *)(data->rebase + pcode_offs)) = native_offs; + + /* Now read the opcode and continue. */ + op = (OPCODE)writer.read_cell(); + switch (op) + { + #include "opcode_switch.inc" + } + } + + /* the total codesize is now known! */ + uint32_t mem = writer.jit_curpos(); + writer.outbase = new char[mem]; + writer.outptr = writer.outbase; + /* go back for third pass */ + goto jit_rewind; + } else { + /******* + * THIRD PASS - write opcode info + *******/ + for (; writer.inptr <= endptr;) + { + op = (OPCODE)writer.read_cell(); + switch (op) + { + #include "opcode_switch.inc" } } } + sp_context_t *ctx = new sp_context_t; + memset(ctx, 0, sizeof(sp_context_t)); + + ctx->context = engine->CreateBaseContext(ctx); + ctx->data = new uint8_t[plugin->memory]; + memcpy(ctx->data, plugin->data, plugin->data_size); + ctx->flags = (data->debug ? SPFLAG_PLUGIN_DEBUG : 0); + ctx->heapbase = plugin->data_size; + ctx->hp = ctx->heapbase; + ctx->memory = plugin->memory; + ctx->plugin = plugin; + ctx->vmbase = this; + + /* :TODO: the rest of this */ + *err = SP_ERR_NONE; - return NULL; + return ctx->context; } const char *JITX86::GetVMName() diff --git a/sourcepawn/vm/jit/x86/jit_x86.h b/sourcepawn/vm/jit/x86/jit_x86.h index dd619892..01febc4f 100644 --- a/sourcepawn/vm/jit/x86/jit_x86.h +++ b/sourcepawn/vm/jit/x86/jit_x86.h @@ -15,17 +15,20 @@ class CompData : public ICompilation { public: CompData() : plugin(NULL), - debug(false), inline_level(3), checks(true) + debug(false), inline_level(3), checks(true), + rebase(NULL) { }; public: sp_plugin_t *plugin; + jitcode_t *rebase; jitoffs_t jit_return; jitoffs_t jit_verify_addr_eax; jitoffs_t jit_verify_addr_edx; jitoffs_t jit_chkmargin_heap; jitoffs_t jit_bounds; jitoffs_t jit_break; + uint32_t codesize; int inline_level; bool checks; bool debug; @@ -45,6 +48,8 @@ public: int ContextExecute(sp_context_t *ctx, uint32_t code_idx, cell_t *result); }; +jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative=false); + #define AMX_REG_PRI REG_EAX #define AMX_REG_ALT REG_EDX #define AMX_REG_STK REG_EBP @@ -61,4 +66,6 @@ public: #define AMX_INFO_STACKTOP 16 //relocated #define AMX_INFO_HEAPLOW 20 //not relocated +extern ISourcePawnEngine *engine; + #endif //_INCLUDE_SOURCEPAWN_JIT_X86_H_ diff --git a/sourcepawn/vm/jit/x86/msvc8/jit-x86.vcproj b/sourcepawn/vm/jit/x86/msvc8/jit-x86.vcproj index f5607836..1f3f4973 100644 --- a/sourcepawn/vm/jit/x86/msvc8/jit-x86.vcproj +++ b/sourcepawn/vm/jit/x86/msvc8/jit-x86.vcproj @@ -223,6 +223,10 @@ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" > + + outptr; //get relative difference - jit_int32_t diff = (target - (jmp + 1)); + jit_int32_t diff = (target - (jmp + 4)); //overwrite old value jit->outptr = jit->outbase + jmp; jit->write_int32(diff); @@ -821,6 +821,24 @@ inline void IA32_Write_Jump32(JitWriter *jit, jitoffs_t jmp, jitoffs_t target) 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->jit_curpos(), 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->jit_curpos(), target); + jit->outptr += 4; +} + inline void IA32_Send_Jump8_Here(JitWriter *jit, jitoffs_t jmp) { jitoffs_t curptr = jit->jit_curpos();