merged in the easy relocation requiring opcodes

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%4096
This commit is contained in:
David Anderson 2006-09-23 04:11:01 +00:00
parent 845ae65797
commit 968692755b
7 changed files with 990 additions and 693 deletions

View File

@ -23,6 +23,7 @@ typedef unsigned __int64 jit_uint64_t;
typedef char * jitcode_t; typedef char * jitcode_t;
typedef unsigned int jitoffs_t; typedef unsigned int jitoffs_t;
typedef signed int jitrel_t;
class JitWriter class JitWriter
{ {
@ -79,8 +80,13 @@ public:
{ {
outptr = outbase + offs; outptr = outbase + offs;
} }
inline jitoffs_t inputrel()
{
return (jitoffs_t)((char *)inptr - (char *)inbase);
}
public: public:
cell_t *inptr; /* input pointer */ cell_t *inptr; /* input pointer */
cell_t *inbase; /* input base */
jitcode_t outbase; /* output pointer */ jitcode_t outbase; /* output pointer */
jitcode_t outptr; /* output base */ jitcode_t outptr; /* output base */
SourcePawn::ICompilation *data; /* compiler live info */ SourcePawn::ICompilation *data; /* compiler live info */

View File

@ -1,5 +1,6 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h>
#include "jit_x86.h" #include "jit_x86.h"
#include "opcode_helpers.h" #include "opcode_helpers.h"
#include "x86_macros.h" #include "x86_macros.h"
@ -1398,15 +1399,165 @@ inline void WriteOp_Break(JitWriter *jit)
} }
} }
inline void WriteOp_JRel(JitWriter *jit)
{
//jmp <offs> ;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 <offs>
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 <target>
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 <target>
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 <target>
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 <target>
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 <target>
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 <target>
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 <target>
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 <target>
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 <target>
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 <target>
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 <target>
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 <target>
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 ************************************ * 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) IPluginContext *JITX86::CompileToContext(ICompilation *co, int *err)
{ {
CompData *data = (CompData *)co; CompData *data = (CompData *)co;
@ -1418,7 +1569,6 @@ IPluginContext *JITX86::CompileToContext(ICompilation *co, int *err)
uint8_t *end_cip = plugin->pcode + plugin->pcode_size; uint8_t *end_cip = plugin->pcode + plugin->pcode_size;
OPCODE op; OPCODE op;
int op_c; int op_c;
uint32_t reloc_count = 0;
/* FIRST PASS (light load) - Get initial opcode information */ /* FIRST PASS (light load) - Get initial opcode information */
for (cip = code; cip < end_cip;) for (cip = code; cip < end_cip;)
@ -1440,7 +1590,7 @@ IPluginContext *JITX86::CompileToContext(ICompilation *co, int *err)
*err = SP_ERR_INVALID_INSTRUCTION; *err = SP_ERR_INVALID_INSTRUCTION;
return NULL; return NULL;
} else if (op_c == -2) { } else if (op_c == -2) {
reloc_count++; /* :TODO: get rid of this block */
cip += sizeof(cell_t); cip += sizeof(cell_t);
} else if (op_c == -1) { } else if (op_c == -1) {
switch (op) switch (op)
@ -1449,7 +1599,6 @@ IPluginContext *JITX86::CompileToContext(ICompilation *co, int *err)
{ {
ucell_t num = *(ucell_t *)cip; ucell_t num = *(ucell_t *)cip;
cip += sizeof(cell_t); cip += sizeof(cell_t);
reloc_count += (num + 1);
cip += ((2*num) + 1) * sizeof(cell_t); cip += ((2*num) + 1) * sizeof(cell_t);
break; break;
} }
@ -1476,13 +1625,16 @@ IPluginContext *JITX86::CompileToContext(ICompilation *co, int *err)
/* Initial code is written "blank," /* Initial code is written "blank,"
* so we can check the exact memory usage. * 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.outptr = NULL;
writer.outbase = 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 */ /* Initialize pass vars */
writer.inptr = writer.inbase;
data->jit_chkmargin_heap = 0; data->jit_chkmargin_heap = 0;
data->jit_verify_addr_eax = 0; data->jit_verify_addr_eax = 0;
data->jit_verify_addr_edx = 0; data->jit_verify_addr_edx = 0;
@ -1511,684 +1663,70 @@ IPluginContext *JITX86::CompileToContext(ICompilation *co, int *err)
data->jit_bounds = jitpos; data->jit_bounds = jitpos;
} }
/* Begin opcode browsing */ if (writer.outbase == NULL)
for (; writer.inptr <= endptr;)
{ {
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: /* Store the native offset into the rebase memory.
{ * This large chunk of memory lets us do an instant lookup
WriteOp_Move_Pri(jit); * based on an original pcode offset.
break; */
} pcode_offs = (jitoffs_t)((uint8_t *)writer.inptr - code);
case OP_MOVE_ALT: native_offs = jit->jit_curpos();
{ *((jitoffs_t *)(data->rebase + pcode_offs)) = native_offs;
WriteOp_Move_Alt(jit);
break; /* Now read the opcode and continue. */
} op = (OPCODE)writer.read_cell();
case OP_XCHG: switch (op)
{ {
WriteOp_Xchg(jit); #include "opcode_switch.inc"
break; }
} }
case OP_PUSH:
{ /* the total codesize is now known! */
WriteOp_Push(jit); uint32_t mem = writer.jit_curpos();
break; writer.outbase = new char[mem];
} writer.outptr = writer.outbase;
case OP_PUSH_S: /* go back for third pass */
{ goto jit_rewind;
WriteOp_Push_S(jit); } else {
break; /*******
} * THIRD PASS - write opcode info
case OP_PUSH2_C: *******/
{ for (; writer.inptr <= endptr;)
WriteOp_Push2_C(jit); {
break; op = (OPCODE)writer.read_cell();
} switch (op)
case OP_PUSH3_C: {
{ #include "opcode_switch.inc"
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;
} }
} }
} }
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; *err = SP_ERR_NONE;
return NULL; return ctx->context;
} }
const char *JITX86::GetVMName() const char *JITX86::GetVMName()

View File

@ -15,17 +15,20 @@ class CompData : public ICompilation
{ {
public: public:
CompData() : plugin(NULL), CompData() : plugin(NULL),
debug(false), inline_level(3), checks(true) debug(false), inline_level(3), checks(true),
rebase(NULL)
{ {
}; };
public: public:
sp_plugin_t *plugin; sp_plugin_t *plugin;
jitcode_t *rebase;
jitoffs_t jit_return; jitoffs_t jit_return;
jitoffs_t jit_verify_addr_eax; jitoffs_t jit_verify_addr_eax;
jitoffs_t jit_verify_addr_edx; jitoffs_t jit_verify_addr_edx;
jitoffs_t jit_chkmargin_heap; jitoffs_t jit_chkmargin_heap;
jitoffs_t jit_bounds; jitoffs_t jit_bounds;
jitoffs_t jit_break; jitoffs_t jit_break;
uint32_t codesize;
int inline_level; int inline_level;
bool checks; bool checks;
bool debug; bool debug;
@ -45,6 +48,8 @@ public:
int ContextExecute(sp_context_t *ctx, uint32_t code_idx, cell_t *result); 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_PRI REG_EAX
#define AMX_REG_ALT REG_EDX #define AMX_REG_ALT REG_EDX
#define AMX_REG_STK REG_EBP #define AMX_REG_STK REG_EBP
@ -61,4 +66,6 @@ public:
#define AMX_INFO_STACKTOP 16 //relocated #define AMX_INFO_STACKTOP 16 //relocated
#define AMX_INFO_HEAPLOW 20 //not relocated #define AMX_INFO_HEAPLOW 20 //not relocated
extern ISourcePawnEngine *engine;
#endif //_INCLUDE_SOURCEPAWN_JIT_X86_H_ #endif //_INCLUDE_SOURCEPAWN_JIT_X86_H_

View File

@ -223,6 +223,10 @@
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" 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}" UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
> >
<File
RelativePath="..\opcode_switch.inc"
>
</File>
</Filter> </Filter>
<Filter <Filter
Name="SDK" Name="SDK"

View File

@ -109,20 +109,20 @@ typedef enum
OP_RETN, //DONE OP_RETN, //DONE
OP_CALL, OP_CALL,
OP_CALL_PRI, OP_CALL_PRI,
OP_JUMP, OP_JUMP, //DONE
OP_JREL, OP_JREL, //DONE
OP_JZER, OP_JZER, //DONE
OP_JNZ, OP_JNZ, //DONE
OP_JEQ, OP_JEQ, //DONE
OP_JNEQ, OP_JNEQ, //DONE
OP_JLESS, OP_JLESS, //DONE
OP_JLEQ, OP_JLEQ, //DONE
OP_JGRTR, OP_JGRTR, //DONE
OP_JGEQ, OP_JGEQ, //DONE
OP_JSLESS, OP_JSLESS, //DONE
OP_JSLEQ, OP_JSLEQ, //DONE
OP_JSGRTR, OP_JSGRTR, //DONE
OP_JSGEQ, OP_JSGEQ, //DONE
OP_SHL, //DONE OP_SHL, //DONE
OP_SHR, //DONE OP_SHR, //DONE
OP_SSHR, //DONE OP_SSHR, //DONE

View File

@ -0,0 +1,724 @@
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;
}
case OP_JREL:
{
WriteOp_JRel(jit);
break;
}
case OP_JUMP:
{
WriteOp_Jump(jit);
break;
}
case OP_JZER:
{
WriteOp_Jzer(jit);
break;
}
case OP_JNZ:
{
WriteOp_Jnz(jit);
break;
}
case OP_JEQ:
{
WriteOp_Jeq(jit);
break;
}
case OP_JNEQ:
{
WriteOp_Jneq(jit);
break;
}
case OP_JLESS:
{
WriteOp_Jless(jit);
break;
}
case OP_JLEQ:
{
WriteOp_Jeq(jit);
break;
}
case OP_JGRTR:
{
WriteOp_Jgrtr(jit);
break;
}
case OP_JGEQ:
{
WriteOp_Jgeq(jit);
break;
}
case OP_JSLESS:
{
WriteOp_Jsless(jit);
break;
}
case OP_JSLEQ:
{
WriteOp_Jsleq(jit);
break;
}
default:
{
assert(0);
}

View File

@ -813,7 +813,7 @@ inline void IA32_Write_Jump32(JitWriter *jit, jitoffs_t jmp, jitoffs_t target)
//save old ptr //save old ptr
jitcode_t oldptr = jit->outptr; jitcode_t oldptr = jit->outptr;
//get relative difference //get relative difference
jit_int32_t diff = (target - (jmp + 1)); jit_int32_t diff = (target - (jmp + 4));
//overwrite old value //overwrite old value
jit->outptr = jit->outbase + jmp; jit->outptr = jit->outbase + jmp;
jit->write_int32(diff); jit->write_int32(diff);
@ -821,6 +821,24 @@ inline void IA32_Write_Jump32(JitWriter *jit, jitoffs_t jmp, jitoffs_t target)
jit->outptr = oldptr; 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) inline void IA32_Send_Jump8_Here(JitWriter *jit, jitoffs_t jmp)
{ {
jitoffs_t curptr = jit->jit_curpos(); jitoffs_t curptr = jit->jit_curpos();