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 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 */

View File

@ -1,5 +1,6 @@
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#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 <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 ************************************
* 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()

View File

@ -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_

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"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath="..\opcode_switch.inc"
>
</File>
</Filter>
<Filter
Name="SDK"

View File

@ -109,20 +109,20 @@ typedef enum
OP_RETN, //DONE
OP_CALL,
OP_CALL_PRI,
OP_JUMP,
OP_JREL,
OP_JZER,
OP_JNZ,
OP_JEQ,
OP_JNEQ,
OP_JLESS,
OP_JLEQ,
OP_JGRTR,
OP_JGEQ,
OP_JSLESS,
OP_JSLEQ,
OP_JSGRTR,
OP_JSGEQ,
OP_JUMP, //DONE
OP_JREL, //DONE
OP_JZER, //DONE
OP_JNZ, //DONE
OP_JEQ, //DONE
OP_JNEQ, //DONE
OP_JLESS, //DONE
OP_JLEQ, //DONE
OP_JGRTR, //DONE
OP_JGEQ, //DONE
OP_JSLESS, //DONE
OP_JSLEQ, //DONE
OP_JSGRTR, //DONE
OP_JSGEQ, //DONE
OP_SHL, //DONE
OP_SHR, //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
jitcode_t oldptr = jit->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();