reorganized ungen opcode stuff
fixed mislabeled ungen ops, then added appropriate notes added executable memory functions to API compilation results in an sp_context_t, not a BaseContext now renamed FreeContextVars() to FreeContext() other minor changes --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%4098
This commit is contained in:
parent
b1c6a06d15
commit
55b590cb8e
@ -59,7 +59,7 @@ namespace SourcePawn
|
|||||||
virtual void FreeBaseContext(IPluginContext *ctx) =0;
|
virtual void FreeBaseContext(IPluginContext *ctx) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates memory.
|
* Allocates large blocks of temporary memory.
|
||||||
*
|
*
|
||||||
* @param size Size of memory to allocate.
|
* @param size Size of memory to allocate.
|
||||||
* @return Pointer to memory, NULL if allocation failed.
|
* @return Pointer to memory, NULL if allocation failed.
|
||||||
@ -72,6 +72,21 @@ namespace SourcePawn
|
|||||||
* @param mem Memory address to free.
|
* @param mem Memory address to free.
|
||||||
*/
|
*/
|
||||||
virtual void BaseFree(void *memory) =0;
|
virtual void BaseFree(void *memory) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocates executable memory.
|
||||||
|
*
|
||||||
|
* @param size Size of memory to allocate.
|
||||||
|
* @return Pointer to memory, NULL if allocation failed.
|
||||||
|
*/
|
||||||
|
virtual void *ExecAlloc(size_t size) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees executable memory.
|
||||||
|
*
|
||||||
|
* @param mem Address to free.
|
||||||
|
*/
|
||||||
|
virtual void ExecFree(void *address) =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ICompilation
|
class ICompilation
|
||||||
@ -107,14 +122,14 @@ namespace SourcePawn
|
|||||||
virtual bool SetCompilationOption(ICompilation *co, const char *key, const char *val) =0;
|
virtual bool SetCompilationOption(ICompilation *co, const char *key, const char *val) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finalizes a compilation into a new IContext.
|
* Finalizes a compilation into a new sp_context_t.
|
||||||
* Note: This will free the ICompilation pointer.
|
* Note: This will free the ICompilation pointer.
|
||||||
*
|
*
|
||||||
* @param co Compilation pointer.
|
* @param co Compilation pointer.
|
||||||
* @param err Filled with error code on exit.
|
* @param err Filled with error code on exit.
|
||||||
* @return New plugin context.
|
* @return New plugin context.
|
||||||
*/
|
*/
|
||||||
virtual IPluginContext *CompileToContext(ICompilation *co, int *err) =0;
|
virtual sp_context_t *CompileToContext(ICompilation *co, int *err) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Aborts a compilation and frees the ICompilation pointer.
|
* Aborts a compilation and frees the ICompilation pointer.
|
||||||
@ -128,7 +143,7 @@ namespace SourcePawn
|
|||||||
*
|
*
|
||||||
* @param ctx Context structure pointer.
|
* @param ctx Context structure pointer.
|
||||||
*/
|
*/
|
||||||
virtual void FreeContextVars(sp_context_t *ctx) =0;
|
virtual void FreeContext(sp_context_t *ctx) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls the "execute" function on a context.
|
* Calls the "execute" function on a context.
|
||||||
|
@ -201,7 +201,7 @@ typedef int (*SPVM_DEBUGBREAK)(SourcePawn::IPluginContext *, uint32_t, uint32_t)
|
|||||||
typedef struct sp_context_s
|
typedef struct sp_context_s
|
||||||
{
|
{
|
||||||
/* general/parent information */
|
/* general/parent information */
|
||||||
void *base; /* base of generated code and memory */
|
void *codebase; /* base of generated code and memory */
|
||||||
sp_plugin_t *plugin; /* pointer back to parent information */
|
sp_plugin_t *plugin; /* pointer back to parent information */
|
||||||
SourcePawn::IPluginContext *context; /* pointer to IPluginContext */
|
SourcePawn::IPluginContext *context; /* pointer to IPluginContext */
|
||||||
SourcePawn::IVirtualMachine *vmbase; /* pointer to IVirtualMachine */
|
SourcePawn::IVirtualMachine *vmbase; /* pointer to IVirtualMachine */
|
||||||
|
@ -5,6 +5,10 @@
|
|||||||
#include "opcode_helpers.h"
|
#include "opcode_helpers.h"
|
||||||
#include "x86_macros.h"
|
#include "x86_macros.h"
|
||||||
|
|
||||||
|
#if defined USE_UNGEN_OPCODES
|
||||||
|
#include "ungen_opcodes.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
inline void WriteOp_Move_Pri(JitWriter *jit)
|
inline void WriteOp_Move_Pri(JitWriter *jit)
|
||||||
{
|
{
|
||||||
//mov eax, edx
|
//mov eax, edx
|
||||||
@ -231,6 +235,27 @@ inline void WriteOp_Proc(JitWriter *jit)
|
|||||||
IA32_Sub_Rm_Reg(jit, AMX_INFO_FRM, AMX_REG_DAT, MOD_MEM_REG);
|
IA32_Sub_Rm_Reg(jit, AMX_INFO_FRM, AMX_REG_DAT, MOD_MEM_REG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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, (jit_uint8_t)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);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void WriteOp_Idxaddr_B(JitWriter *jit)
|
||||||
|
{
|
||||||
|
//shl eax, <val>
|
||||||
|
//add eax, edx
|
||||||
|
cell_t val = jit->read_cell();
|
||||||
|
IA32_Shl_Rm_Imm8(jit, AMX_REG_PRI, (jit_uint8_t)val, MOD_REG);
|
||||||
|
IA32_Add_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
|
||||||
|
}
|
||||||
|
|
||||||
inline void WriteOp_Shl(JitWriter *jit)
|
inline void WriteOp_Shl(JitWriter *jit)
|
||||||
{
|
{
|
||||||
//mov ecx, edx
|
//mov ecx, edx
|
||||||
@ -293,18 +318,6 @@ inline void WriteOp_SMul(JitWriter *jit)
|
|||||||
IA32_Mov_Rm_Reg(jit, AMX_REG_ALT, AMX_REG_TMP, MOD_REG);
|
IA32_Mov_Rm_Reg(jit, AMX_REG_ALT, AMX_REG_TMP, MOD_REG);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
inline void WriteOp_UMul(JitWriter *jit)
|
|
||||||
{
|
|
||||||
//mov ecx, edx
|
|
||||||
//mul edx
|
|
||||||
//mov edx, ecx
|
|
||||||
IA32_Mov_Rm_Reg(jit, AMX_REG_TMP, AMX_REG_ALT, MOD_REG);
|
|
||||||
IA32_Mul_Rm(jit, AMX_REG_ALT, MOD_REG);
|
|
||||||
IA32_Mov_Rm_Reg(jit, AMX_REG_ALT, AMX_REG_TMP, MOD_REG);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline void WriteOp_Not(JitWriter *jit)
|
inline void WriteOp_Not(JitWriter *jit)
|
||||||
{
|
{
|
||||||
//test eax, eax
|
//test eax, eax
|
||||||
@ -401,54 +414,6 @@ inline void WriteOp_Neq(JitWriter *jit)
|
|||||||
IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_NE);
|
IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_NE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
inline void WriteOp_Less(JitWriter *jit)
|
|
||||||
{
|
|
||||||
//cmp eax, edx ; PRI < ALT ? (unsigned)
|
|
||||||
//mov eax, 0
|
|
||||||
//setb al
|
|
||||||
IA32_Cmp_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
|
|
||||||
IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
|
|
||||||
IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_B);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
inline void WriteOp_Leq(JitWriter *jit)
|
|
||||||
{
|
|
||||||
//cmp eax, edx ; PRI <= ALT ? (unsigned)
|
|
||||||
//mov eax, 0
|
|
||||||
//setbe al
|
|
||||||
IA32_Cmp_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
|
|
||||||
IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
|
|
||||||
IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_BE);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
inline void WriteOp_Grtr(JitWriter *jit)
|
|
||||||
{
|
|
||||||
//cmp eax, edx ; PRI > ALT ? (unsigned)
|
|
||||||
//mov eax, 0
|
|
||||||
//seta al
|
|
||||||
IA32_Cmp_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
|
|
||||||
IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
|
|
||||||
IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_A);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
inline void WriteOp_Geq(JitWriter *jit)
|
|
||||||
{
|
|
||||||
//cmp eax, edx ; PRI >= ALT ? (unsigned)
|
|
||||||
//mov eax, 0
|
|
||||||
//setae al
|
|
||||||
IA32_Cmp_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
|
|
||||||
IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
|
|
||||||
IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_AE);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline void WriteOp_Sless(JitWriter *jit)
|
inline void WriteOp_Sless(JitWriter *jit)
|
||||||
{
|
{
|
||||||
//cmp eax, edx ; PRI < ALT ? (signed)
|
//cmp eax, edx ; PRI < ALT ? (signed)
|
||||||
@ -633,7 +598,6 @@ inline void WriteOp_Load_S_Alt(JitWriter *jit)
|
|||||||
IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_ALT, AMX_REG_FRM, val);
|
IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_ALT, AMX_REG_FRM, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
inline void WriteOp_Lref_Pri(JitWriter *jit)
|
inline void WriteOp_Lref_Pri(JitWriter *jit)
|
||||||
{
|
{
|
||||||
//mov eax, [edi+<val>]
|
//mov eax, [edi+<val>]
|
||||||
@ -645,9 +609,7 @@ inline void WriteOp_Lref_Pri(JitWriter *jit)
|
|||||||
IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_PRI, AMX_REG_DAT, val);
|
IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_PRI, AMX_REG_DAT, val);
|
||||||
IA32_Mov_Reg_Rm_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
|
IA32_Mov_Reg_Rm_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
inline void WriteOp_Lref_Alt(JitWriter *jit)
|
inline void WriteOp_Lref_Alt(JitWriter *jit)
|
||||||
{
|
{
|
||||||
//mov edx, [edi+<val>]
|
//mov edx, [edi+<val>]
|
||||||
@ -659,9 +621,7 @@ inline void WriteOp_Lref_Alt(JitWriter *jit)
|
|||||||
IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_ALT, AMX_REG_DAT, val);
|
IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_ALT, AMX_REG_DAT, val);
|
||||||
IA32_Mov_Reg_Rm_Disp_Reg(jit, AMX_REG_ALT, AMX_REG_DAT, AMX_REG_ALT, NOSCALE);
|
IA32_Mov_Reg_Rm_Disp_Reg(jit, AMX_REG_ALT, AMX_REG_DAT, AMX_REG_ALT, NOSCALE);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
inline void WriteOp_Lref_S_Pri(JitWriter *jit)
|
inline void WriteOp_Lref_S_Pri(JitWriter *jit)
|
||||||
{
|
{
|
||||||
//mov eax, [ebx+<val>]
|
//mov eax, [ebx+<val>]
|
||||||
@ -673,9 +633,7 @@ inline void WriteOp_Lref_S_Pri(JitWriter *jit)
|
|||||||
IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_PRI, AMX_REG_FRM, val);
|
IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_PRI, AMX_REG_FRM, val);
|
||||||
IA32_Mov_Reg_Rm_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
|
IA32_Mov_Reg_Rm_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
inline void WriteOp_Lref_S_Alt(JitWriter *jit)
|
inline void WriteOp_Lref_S_Alt(JitWriter *jit)
|
||||||
{
|
{
|
||||||
//mov edx, [ebx+<val>]
|
//mov edx, [ebx+<val>]
|
||||||
@ -687,7 +645,6 @@ inline void WriteOp_Lref_S_Alt(JitWriter *jit)
|
|||||||
IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_ALT, AMX_REG_FRM, val);
|
IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_ALT, AMX_REG_FRM, val);
|
||||||
IA32_Mov_Reg_Rm_Disp_Reg(jit, AMX_REG_ALT, AMX_REG_DAT, AMX_REG_ALT, NOSCALE);
|
IA32_Mov_Reg_Rm_Disp_Reg(jit, AMX_REG_ALT, AMX_REG_DAT, AMX_REG_ALT, NOSCALE);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
inline void WriteOp_Const_Pri(JitWriter *jit)
|
inline void WriteOp_Const_Pri(JitWriter *jit)
|
||||||
{
|
{
|
||||||
@ -773,18 +730,6 @@ inline void WriteOp_Idxaddr(JitWriter *jit)
|
|||||||
IA32_Lea_Reg_DispRegMult(jit, AMX_REG_PRI, AMX_REG_ALT, AMX_REG_PRI, SCALE4);
|
IA32_Lea_Reg_DispRegMult(jit, AMX_REG_PRI, AMX_REG_ALT, AMX_REG_PRI, SCALE4);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
inline void WriteOp_Idxaddr_B(JitWriter *jit)
|
|
||||||
{
|
|
||||||
//shl eax, <val>
|
|
||||||
//add eax, edx
|
|
||||||
cell_t val = jit->read_cell();
|
|
||||||
IA32_Shl_Rm_Imm8(jit, AMX_REG_PRI, (jit_uint8_t)val, MOD_REG);
|
|
||||||
IA32_Add_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
inline void WriteOp_Sref_Pri(JitWriter *jit)
|
inline void WriteOp_Sref_Pri(JitWriter *jit)
|
||||||
{
|
{
|
||||||
//mov ecx, [edi+<val>]
|
//mov ecx, [edi+<val>]
|
||||||
@ -796,9 +741,7 @@ inline void WriteOp_Sref_Pri(JitWriter *jit)
|
|||||||
IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_DAT, val);
|
IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_DAT, val);
|
||||||
IA32_Mov_Rm_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_TMP, NOSCALE, AMX_REG_PRI);
|
IA32_Mov_Rm_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_TMP, NOSCALE, AMX_REG_PRI);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
inline void WriteOp_Sref_Alt(JitWriter *jit)
|
inline void WriteOp_Sref_Alt(JitWriter *jit)
|
||||||
{
|
{
|
||||||
//mov ecx, [edi+<val>]
|
//mov ecx, [edi+<val>]
|
||||||
@ -810,9 +753,7 @@ inline void WriteOp_Sref_Alt(JitWriter *jit)
|
|||||||
IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_DAT, val);
|
IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_DAT, val);
|
||||||
IA32_Mov_Rm_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_TMP, NOSCALE, AMX_REG_ALT);
|
IA32_Mov_Rm_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_TMP, NOSCALE, AMX_REG_ALT);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
inline void WriteOp_Sref_S_Pri(JitWriter *jit)
|
inline void WriteOp_Sref_S_Pri(JitWriter *jit)
|
||||||
{
|
{
|
||||||
//mov ecx, [ebx+<val>]
|
//mov ecx, [ebx+<val>]
|
||||||
@ -824,9 +765,7 @@ inline void WriteOp_Sref_S_Pri(JitWriter *jit)
|
|||||||
IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_FRM, val);
|
IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_FRM, val);
|
||||||
IA32_Mov_Rm_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_TMP, NOSCALE, AMX_REG_PRI);
|
IA32_Mov_Rm_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_TMP, NOSCALE, AMX_REG_PRI);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
inline void WriteOp_Sref_S_Alt(JitWriter *jit)
|
inline void WriteOp_Sref_S_Alt(JitWriter *jit)
|
||||||
{
|
{
|
||||||
//mov ecx, [ebx+<val>]
|
//mov ecx, [ebx+<val>]
|
||||||
@ -838,31 +777,6 @@ inline void WriteOp_Sref_S_Alt(JitWriter *jit)
|
|||||||
IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_FRM, val);
|
IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_FRM, val);
|
||||||
IA32_Mov_Rm_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_TMP, NOSCALE, AMX_REG_ALT);
|
IA32_Mov_Rm_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_TMP, NOSCALE, AMX_REG_ALT);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
inline void WriteOp_Align_Pri(JitWriter *jit)
|
|
||||||
{
|
|
||||||
//xor eax, <cellsize - val>
|
|
||||||
cell_t val = sizeof(cell_t) - jit->read_cell();
|
|
||||||
if (val < SCHAR_MAX && val > SCHAR_MIN)
|
|
||||||
IA32_Xor_Rm_Imm8(jit, AMX_REG_PRI, MOD_REG, (jit_int8_t)val);
|
|
||||||
else
|
|
||||||
IA32_Xor_Eax_Imm32(jit, val);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
inline void WriteOp_Align_Alt(JitWriter *jit)
|
|
||||||
{
|
|
||||||
//xor edx, <cellsize - val>
|
|
||||||
cell_t val = sizeof(cell_t) - jit->read_cell();
|
|
||||||
if (val < SCHAR_MAX && val > SCHAR_MIN)
|
|
||||||
IA32_Xor_Rm_Imm8(jit, AMX_REG_ALT, MOD_REG, (jit_int8_t)val);
|
|
||||||
else
|
|
||||||
IA32_Xor_Rm_Imm32(jit, AMX_REG_ALT, MOD_REG, val);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline void WriteOp_Pop_Pri(JitWriter *jit)
|
inline void WriteOp_Pop_Pri(JitWriter *jit)
|
||||||
{
|
{
|
||||||
@ -963,39 +877,6 @@ inline void WriteOp_Movs(JitWriter *jit)
|
|||||||
IA32_Pop_Reg(jit, REG_ESI);
|
IA32_Pop_Reg(jit, REG_ESI);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
inline void WriteOp_Cmps(JitWriter *jit)
|
|
||||||
{
|
|
||||||
//push edi
|
|
||||||
//push esi
|
|
||||||
//lea esi, [edi+edx]
|
|
||||||
//lea edi, [edi+eax]
|
|
||||||
IA32_Push_Reg(jit, REG_EDI);
|
|
||||||
IA32_Push_Reg(jit, REG_ESI);
|
|
||||||
IA32_Lea_Reg_DispRegMult(jit, REG_ESI, AMX_REG_DAT, AMX_REG_ALT, NOSCALE);
|
|
||||||
IA32_Lea_Reg_DispRegMult(jit, REG_EDI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
|
|
||||||
|
|
||||||
//xor eax, eax
|
|
||||||
//repe cmpsb
|
|
||||||
//je :cmps1
|
|
||||||
IA32_Xor_Rm_Reg(jit, REG_EAX, REG_EAX, MOD_REG);
|
|
||||||
IA32_Cmpsb(jit);
|
|
||||||
jitoffs_t jmp = IA32_Jump_Cond_Imm8(jit, CC_E, 0);
|
|
||||||
|
|
||||||
//sbb eax, eax
|
|
||||||
//sbb eax, -1
|
|
||||||
IA32_Sbb_Rm_Reg(jit, REG_EAX, REG_EAX, MOD_REG);
|
|
||||||
IA32_Sbb_Eax_Imm32(jit, -1);//:TODO: use imm8 here
|
|
||||||
|
|
||||||
//:cmps1
|
|
||||||
//pop esi
|
|
||||||
//pop edi
|
|
||||||
IA32_Send_Jump8_Here(jit, jmp);
|
|
||||||
IA32_Pop_Reg(jit, REG_ESI);
|
|
||||||
IA32_Pop_Reg(jit, REG_EDI);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline void WriteOp_Fill(JitWriter *jit)
|
inline void WriteOp_Fill(JitWriter *jit)
|
||||||
{
|
{
|
||||||
//add edi, edx
|
//add edi, edx
|
||||||
@ -1099,32 +980,6 @@ inline void WriteOp_Load_I(JitWriter *jit)
|
|||||||
IA32_Mov_Reg_Rm_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
|
IA32_Mov_Reg_Rm_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
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);//:TODO: replace with AND EAX, imm32
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
IA32_And_Rm_Imm32(jit, AMX_REG_PRI, 0x0000FFFF);//:TODO: replace with AND EAX, imm32
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline void WriteOp_Stor_I(JitWriter *jit)
|
inline void WriteOp_Stor_I(JitWriter *jit)
|
||||||
{
|
{
|
||||||
//mov [edi+edx], eax
|
//mov [edi+edx], eax
|
||||||
@ -1132,33 +987,6 @@ inline void WriteOp_Stor_I(JitWriter *jit)
|
|||||||
IA32_Mov_Rm_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_ALT, NOSCALE, AMX_REG_PRI);
|
IA32_Mov_Rm_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_ALT, NOSCALE, AMX_REG_PRI);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
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 4:
|
|
||||||
{
|
|
||||||
IA32_Mov_Rm_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_ALT, NOSCALE, AMX_REG_PRI);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline void WriteOp_Lidx(JitWriter *jit)
|
inline void WriteOp_Lidx(JitWriter *jit)
|
||||||
{
|
{
|
||||||
//lea eax, [edx+4*eax]
|
//lea eax, [edx+4*eax]
|
||||||
@ -1168,119 +996,6 @@ inline void WriteOp_Lidx(JitWriter *jit)
|
|||||||
IA32_Mov_Reg_Rm_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
|
IA32_Mov_Reg_Rm_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
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, (jit_uint8_t)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);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
inline void WriteOp_Lctrl(JitWriter *jit)
|
|
||||||
{
|
|
||||||
cell_t val = jit->read_cell();
|
|
||||||
switch (val)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
{
|
|
||||||
//mov ecx, [esi+ctx]
|
|
||||||
//mov eax, [ecx+<offs>]
|
|
||||||
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
|
|
||||||
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_TMP, offsetof(sp_context_t, base));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
//mov eax, edi
|
|
||||||
IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_DAT, MOD_REG);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
//mov eax, [esi+hea]
|
|
||||||
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_INFO, AMX_INFO_HEAP);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 3:
|
|
||||||
{
|
|
||||||
//mov ecx, [esi+ctx]
|
|
||||||
//mov eax, [ecx+ctx.memory]
|
|
||||||
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
|
|
||||||
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_TMP, offsetof(sp_context_t, memory));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 4:
|
|
||||||
{
|
|
||||||
//mov eax, ebp
|
|
||||||
//sub eax, edi - unrelocate
|
|
||||||
IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_STK, MOD_REG);
|
|
||||||
IA32_Sub_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, MOD_REG);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 5:
|
|
||||||
{
|
|
||||||
//mov eax, [esi+frm]
|
|
||||||
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_INFO, AMX_INFO_FRM);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 6:
|
|
||||||
{
|
|
||||||
//mov eax, [cip]
|
|
||||||
jitoffs_t imm32 = IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
|
|
||||||
jitoffs_t save = jit->jit_curpos();
|
|
||||||
jit->setpos(imm32);
|
|
||||||
jit->write_int32((uint32_t)(jit->outbase + save));
|
|
||||||
jit->setpos(save);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
inline void WriteOp_Sctrl(JitWriter *jit)
|
|
||||||
{
|
|
||||||
cell_t val = jit->read_cell();
|
|
||||||
switch (val)
|
|
||||||
{
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
//mov [esi+hea], eax
|
|
||||||
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, AMX_INFO_HEAP, AMX_REG_PRI);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 4:
|
|
||||||
{
|
|
||||||
//lea ebp, [edi+eax]
|
|
||||||
IA32_Lea_Reg_DispRegMult(jit, AMX_REG_STK, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 5:
|
|
||||||
{
|
|
||||||
//mov ebx, eax - overwrite frm
|
|
||||||
//mov frm, eax - overwrite stacked frame
|
|
||||||
//add ebx, edi - relocate local frm //:TODO: use LEA here!!!
|
|
||||||
IA32_Mov_Reg_Rm(jit, AMX_REG_FRM, AMX_REG_PRI, MOD_REG);
|
|
||||||
IA32_Mov_Rm_Reg(jit, AMX_INFO_FRM, AMX_REG_PRI, MOD_MEM_REG);
|
|
||||||
IA32_Add_Rm_Reg(jit, AMX_REG_FRM, AMX_REG_DAT, MOD_REG);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 6:
|
|
||||||
{
|
|
||||||
IA32_Jump_Reg(jit, AMX_REG_PRI);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline void WriteOp_Stack(JitWriter *jit)
|
inline void WriteOp_Stack(JitWriter *jit)
|
||||||
{
|
{
|
||||||
//mov edx, ebp
|
//mov edx, ebp
|
||||||
@ -1337,50 +1052,6 @@ inline void WriteOp_SDiv_Alt(JitWriter *jit)
|
|||||||
IA32_IDiv_Rm(jit, AMX_REG_TMP, MOD_REG);
|
IA32_IDiv_Rm(jit, AMX_REG_TMP, MOD_REG);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
inline void WriteOp_UDiv(JitWriter *jit)
|
|
||||||
{
|
|
||||||
//mov ecx, edx
|
|
||||||
//xor edx, edx
|
|
||||||
//div ecx
|
|
||||||
IA32_Mov_Rm_Reg(jit, AMX_REG_TMP, AMX_REG_ALT, MOD_REG);
|
|
||||||
IA32_Xor_Rm_Reg(jit, AMX_REG_ALT, AMX_REG_ALT, MOD_REG);
|
|
||||||
Write_Check_DivZero(jit, AMX_REG_TMP);
|
|
||||||
IA32_Div_Rm(jit, AMX_REG_TMP, MOD_REG);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
inline void WriteOp_UDiv_Alt(JitWriter *jit)
|
|
||||||
{
|
|
||||||
//mov ecx, eax
|
|
||||||
//mov eax, edx
|
|
||||||
//xor edx, edx
|
|
||||||
//div ecx
|
|
||||||
IA32_Mov_Rm_Reg(jit, AMX_REG_TMP, AMX_REG_PRI, MOD_REG);
|
|
||||||
IA32_Mov_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
|
|
||||||
IA32_Xor_Rm_Reg(jit, AMX_REG_ALT, AMX_REG_ALT, MOD_REG);
|
|
||||||
Write_Check_DivZero(jit, AMX_REG_TMP);
|
|
||||||
IA32_Div_Rm(jit, AMX_REG_TMP, MOD_REG);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
inline void WriteOp_Ret(JitWriter *jit)
|
|
||||||
{
|
|
||||||
//mov ebx, [ebp] - get old FRM
|
|
||||||
//add ebp, 4 - pop stack
|
|
||||||
//mov [esi+frm], ebx - restore
|
|
||||||
//add ebx, edi - relocate
|
|
||||||
//ret
|
|
||||||
IA32_Mov_Reg_Rm(jit, AMX_REG_FRM, AMX_REG_STK, MOD_MEM_REG);
|
|
||||||
IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
|
|
||||||
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_INFO, AMX_REG_FRM, AMX_INFO_FRM);//:TODO: this is wrong!
|
|
||||||
IA32_Add_Rm_Reg(jit, AMX_REG_FRM, AMX_REG_DAT, MOD_REG);
|
|
||||||
IA32_Return(jit);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline void WriteOp_Retn(JitWriter *jit)
|
inline void WriteOp_Retn(JitWriter *jit)
|
||||||
{
|
{
|
||||||
//mov ebx, [ebp] - get old frm
|
//mov ebx, [ebp] - get old frm
|
||||||
@ -1449,21 +1120,6 @@ inline void WriteOp_Break(JitWriter *jit)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline void WriteOp_Jump(JitWriter *jit)
|
inline void WriteOp_Jump(JitWriter *jit)
|
||||||
{
|
{
|
||||||
//jmp <offs>
|
//jmp <offs>
|
||||||
@ -1508,50 +1164,6 @@ inline void WriteOp_Jneq(JitWriter *jit)
|
|||||||
IA32_Jump_Cond_Imm32(jit, CC_NE, RelocLookup(jit, target, false));
|
IA32_Jump_Cond_Imm32(jit, CC_NE, RelocLookup(jit, target, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline void WriteOp_Jsless(JitWriter *jit)
|
inline void WriteOp_Jsless(JitWriter *jit)
|
||||||
{
|
{
|
||||||
//cmp eax, edx
|
//cmp eax, edx
|
||||||
@ -1617,7 +1229,7 @@ jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IPluginContext *JITX86::CompileToContext(ICompilation *co, int *err)
|
sp_context_t *JITX86::CompileToContext(ICompilation *co, int *err)
|
||||||
{
|
{
|
||||||
CompData *data = (CompData *)co;
|
CompData *data = (CompData *)co;
|
||||||
sp_plugin_t *plugin = data->plugin;
|
sp_plugin_t *plugin = data->plugin;
|
||||||
@ -1750,7 +1362,7 @@ jit_rewind:
|
|||||||
|
|
||||||
/* the total codesize is now known! */
|
/* the total codesize is now known! */
|
||||||
uint32_t mem = writer.jit_curpos();
|
uint32_t mem = writer.jit_curpos();
|
||||||
writer.outbase = new char[mem];
|
writer.outbase = (jitcode_t)engine->ExecAlloc(mem);
|
||||||
writer.outptr = writer.outbase;
|
writer.outptr = writer.outbase;
|
||||||
/* go back for third pass */
|
/* go back for third pass */
|
||||||
goto jit_rewind;
|
goto jit_rewind;
|
||||||
@ -1768,29 +1380,31 @@ jit_rewind:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******
|
/*************
|
||||||
* Context Setup
|
* FOURTH PASS - Context Setup
|
||||||
*******/
|
*************/
|
||||||
|
|
||||||
sp_context_t *ctx = new sp_context_t;
|
sp_context_t *ctx = new sp_context_t;
|
||||||
memset(ctx, 0, sizeof(sp_context_t));
|
memset(ctx, 0, sizeof(sp_context_t));
|
||||||
|
|
||||||
ctx->base = plugin->base;
|
/* setup basics */
|
||||||
|
ctx->codebase = writer.outbase;
|
||||||
ctx->plugin = plugin;
|
ctx->plugin = plugin;
|
||||||
ctx->context = engine->CreateBaseContext(ctx);
|
|
||||||
ctx->vmbase = this;
|
ctx->vmbase = this;
|
||||||
ctx->flags = (data->debug ? SPFLAG_PLUGIN_DEBUG : 0);
|
ctx->flags = (data->debug ? SPFLAG_PLUGIN_DEBUG : 0);
|
||||||
|
|
||||||
|
/* setup memory */
|
||||||
ctx->data = new uint8_t[plugin->memory];
|
ctx->data = new uint8_t[plugin->memory];
|
||||||
memcpy(ctx->data, plugin->data, plugin->data_size);
|
memcpy(ctx->data, plugin->data, plugin->data_size);
|
||||||
ctx->memory = plugin->memory;
|
ctx->memory = plugin->memory;
|
||||||
ctx->heapbase = plugin->data_size;
|
ctx->heapbase = plugin->data_size;
|
||||||
|
|
||||||
ctx->hp = ctx->heapbase;
|
ctx->hp = ctx->heapbase;
|
||||||
ctx->sp = ctx->memory - sizeof(cell_t);
|
ctx->sp = ctx->memory - sizeof(cell_t);
|
||||||
|
|
||||||
const char *strbase = plugin->info.stringbase;
|
const char *strbase = plugin->info.stringbase;
|
||||||
uint32_t max, iter;
|
uint32_t max, iter;
|
||||||
|
|
||||||
|
/* relocate public info */
|
||||||
if ((max = plugin->info.publics_num))
|
if ((max = plugin->info.publics_num))
|
||||||
{
|
{
|
||||||
ctx->publics = new sp_public_t[max];
|
ctx->publics = new sp_public_t[max];
|
||||||
@ -1801,6 +1415,7 @@ jit_rewind:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* relocate pubvar info */
|
||||||
if ((max = plugin->info.pubvars_num))
|
if ((max = plugin->info.pubvars_num))
|
||||||
{
|
{
|
||||||
uint8_t *dat = ctx->data;
|
uint8_t *dat = ctx->data;
|
||||||
@ -1812,21 +1427,26 @@ jit_rewind:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* relocate native info */
|
||||||
if ((max = plugin->info.natives_num))
|
if ((max = plugin->info.natives_num))
|
||||||
{
|
{
|
||||||
ctx->natives = new sp_native_t[max];
|
ctx->natives = new sp_native_t[max];
|
||||||
for (iter=0; iter<max; iter++)
|
for (iter=0; iter<max; iter++)
|
||||||
{
|
{
|
||||||
ctx->natives[iter].name = strbase + plugin->info.natives[iter].name;
|
ctx->natives[iter].name = strbase + plugin->info.natives[iter].name;
|
||||||
//ctx->natives[iter].pfn = SP_NoExecNative; :TODO:
|
ctx->natives[iter].pfn = NULL;
|
||||||
ctx->natives[iter].status = SP_NATIVE_NONE;
|
ctx->natives[iter].status = SP_NATIVE_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we're debugging, make sure we copy the necessary info.
|
||||||
|
*/
|
||||||
|
if (data->debug)
|
||||||
|
{
|
||||||
strbase = plugin->debug.stringbase;
|
strbase = plugin->debug.stringbase;
|
||||||
|
|
||||||
if (plugin->flags & SP_FLAG_DEBUG)
|
/* relocate files */
|
||||||
{
|
|
||||||
max = plugin->debug.files_num;
|
max = plugin->debug.files_num;
|
||||||
ctx->files = new sp_debug_file_t[max];
|
ctx->files = new sp_debug_file_t[max];
|
||||||
for (iter=0; iter<max; iter++)
|
for (iter=0; iter<max; iter++)
|
||||||
@ -1835,6 +1455,7 @@ jit_rewind:
|
|||||||
ctx->files[iter].name = strbase + plugin->debug.files[iter].name;
|
ctx->files[iter].name = strbase + plugin->debug.files[iter].name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* relocate lines */
|
||||||
max = plugin->debug.lines_num;
|
max = plugin->debug.lines_num;
|
||||||
ctx->lines = new sp_debug_line_t[max];
|
ctx->lines = new sp_debug_line_t[max];
|
||||||
for (iter=0; iter<max; iter++)
|
for (iter=0; iter<max; iter++)
|
||||||
@ -1843,6 +1464,7 @@ jit_rewind:
|
|||||||
ctx->lines[iter].line = plugin->debug.lines[iter].line;
|
ctx->lines[iter].line = plugin->debug.lines[iter].line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* relocate arrays */
|
||||||
sp_fdbg_symbol_t *sym;
|
sp_fdbg_symbol_t *sym;
|
||||||
sp_fdbg_arraydim_t *arr;
|
sp_fdbg_arraydim_t *arr;
|
||||||
uint8_t *cursor = (uint8_t *)(plugin->debug.symbols);
|
uint8_t *cursor = (uint8_t *)(plugin->debug.symbols);
|
||||||
@ -1872,9 +1494,13 @@ jit_rewind:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* clean up relocation+compilation memory */
|
||||||
|
engine->BaseFree(data->rebase);
|
||||||
|
delete data;
|
||||||
|
|
||||||
*err = SP_ERR_NONE;
|
*err = SP_ERR_NONE;
|
||||||
|
|
||||||
return ctx->context;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *JITX86::GetVMName()
|
const char *JITX86::GetVMName()
|
||||||
@ -1882,6 +1508,26 @@ const char *JITX86::GetVMName()
|
|||||||
return "JIT (x86)";
|
return "JIT (x86)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int JITX86::ContextExecute(sp_context_t *ctx, uint32_t code_idx, cell_t *result)
|
||||||
|
{
|
||||||
|
typedef int (*CONTEXT_EXECUTE)(sp_context_t *, uint32_t, cell_t *);
|
||||||
|
CONTEXT_EXECUTE fn = (CONTEXT_EXECUTE)ctx->codebase;
|
||||||
|
return fn(ctx, code_idx, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JITX86::FreeContext(sp_context_t *ctx)
|
||||||
|
{
|
||||||
|
engine->ExecFree(ctx->codebase);
|
||||||
|
delete [] ctx->data;
|
||||||
|
delete [] ctx->files;
|
||||||
|
delete [] ctx->lines;
|
||||||
|
delete [] ctx->natives;
|
||||||
|
delete [] ctx->publics;
|
||||||
|
delete [] ctx->pubvars;
|
||||||
|
delete [] ctx->symbols;
|
||||||
|
delete ctx;
|
||||||
|
}
|
||||||
|
|
||||||
ICompilation *JITX86::StartCompilation(sp_plugin_t *plugin)
|
ICompilation *JITX86::StartCompilation(sp_plugin_t *plugin)
|
||||||
{
|
{
|
||||||
CompData *data = new CompData;
|
CompData *data = new CompData;
|
||||||
|
@ -42,9 +42,9 @@ public:
|
|||||||
const char *GetVMName() =0;
|
const char *GetVMName() =0;
|
||||||
ICompilation *StartCompilation(sp_plugin_t *plugin);
|
ICompilation *StartCompilation(sp_plugin_t *plugin);
|
||||||
bool SetCompilationOption(ICompilation *co, const char *key, const char *val) ;
|
bool SetCompilationOption(ICompilation *co, const char *key, const char *val) ;
|
||||||
IPluginContext *CompileToContext(ICompilation *co, int *err);
|
sp_context_t *CompileToContext(ICompilation *co, int *err);
|
||||||
void AbortCompilation(ICompilation *co);
|
void AbortCompilation(ICompilation *co);
|
||||||
void FreeContextVars(sp_context_t *ctx);
|
void FreeContext(sp_context_t *ctx);
|
||||||
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -213,6 +213,10 @@
|
|||||||
RelativePath="..\opcode_helpers.h"
|
RelativePath="..\opcode_helpers.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ungen_opcodes.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\x86_macros.h"
|
RelativePath="..\x86_macros.h"
|
||||||
>
|
>
|
||||||
@ -227,6 +231,10 @@
|
|||||||
RelativePath="..\opcode_switch.inc"
|
RelativePath="..\opcode_switch.inc"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ungen_opcode_switch.inc"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="SDK"
|
Name="SDK"
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
int OpAdvTable[OP_NUM_OPCODES];
|
int OpAdvTable[OP_NUM_OPCODES];
|
||||||
|
|
||||||
jitoffs_t Write_Execute_Function(JitWriter *jit, bool never_inline)
|
jitoffs_t Write_Execute_Function(JitWriter *jit)
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The variables we're passed in:
|
* The variables we're passed in:
|
||||||
@ -79,7 +79,7 @@ jitoffs_t Write_Execute_Function(JitWriter *jit, bool never_inline)
|
|||||||
//mov edx, [eax+<offs>] - get alt
|
//mov edx, [eax+<offs>] - get alt
|
||||||
//mov eax, [eax+<offs>] - get pri
|
//mov eax, [eax+<offs>] - get pri
|
||||||
IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, REG_EBP, 12);
|
IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, REG_EBP, 12);
|
||||||
IA32_Add_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, base));
|
IA32_Add_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, codebase));
|
||||||
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_ALT, REG_EAX, offsetof(sp_context_t, alt));
|
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_ALT, REG_EAX, offsetof(sp_context_t, alt));
|
||||||
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, REG_EAX, offsetof(sp_context_t, pri));
|
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, REG_EAX, offsetof(sp_context_t, pri));
|
||||||
|
|
||||||
@ -503,7 +503,6 @@ JITX86::JITX86()
|
|||||||
OpAdvTable[OP_LREF_ALT] = sizeof(cell_t);
|
OpAdvTable[OP_LREF_ALT] = sizeof(cell_t);
|
||||||
OpAdvTable[OP_LREF_S_PRI] = sizeof(cell_t);
|
OpAdvTable[OP_LREF_S_PRI] = sizeof(cell_t);
|
||||||
OpAdvTable[OP_LREF_S_ALT] = sizeof(cell_t);
|
OpAdvTable[OP_LREF_S_ALT] = sizeof(cell_t);
|
||||||
OpAdvTable[OP_LODB_I] = sizeof(cell_t);
|
|
||||||
OpAdvTable[OP_CONST_PRI] = sizeof(cell_t);
|
OpAdvTable[OP_CONST_PRI] = sizeof(cell_t);
|
||||||
OpAdvTable[OP_CONST_ALT] = sizeof(cell_t);
|
OpAdvTable[OP_CONST_ALT] = sizeof(cell_t);
|
||||||
OpAdvTable[OP_ADDR_PRI] = sizeof(cell_t);
|
OpAdvTable[OP_ADDR_PRI] = sizeof(cell_t);
|
||||||
@ -516,19 +515,13 @@ JITX86::JITX86()
|
|||||||
OpAdvTable[OP_SREF_ALT] = sizeof(cell_t);
|
OpAdvTable[OP_SREF_ALT] = sizeof(cell_t);
|
||||||
OpAdvTable[OP_SREF_S_PRI] = sizeof(cell_t);
|
OpAdvTable[OP_SREF_S_PRI] = sizeof(cell_t);
|
||||||
OpAdvTable[OP_SREF_S_ALT] = sizeof(cell_t);
|
OpAdvTable[OP_SREF_S_ALT] = sizeof(cell_t);
|
||||||
OpAdvTable[OP_STRB_I] = sizeof(cell_t);
|
|
||||||
OpAdvTable[OP_LIDX_B] = sizeof(cell_t);
|
OpAdvTable[OP_LIDX_B] = sizeof(cell_t);
|
||||||
OpAdvTable[OP_IDXADDR_B] = sizeof(cell_t);
|
OpAdvTable[OP_IDXADDR_B] = sizeof(cell_t);
|
||||||
OpAdvTable[OP_ALIGN_PRI] = sizeof(cell_t);
|
|
||||||
OpAdvTable[OP_ALIGN_ALT] = sizeof(cell_t);
|
|
||||||
OpAdvTable[OP_LCTRL] = sizeof(cell_t);
|
|
||||||
OpAdvTable[OP_SCTRL] = sizeof(cell_t);
|
|
||||||
OpAdvTable[OP_PUSH_C] = sizeof(cell_t);
|
OpAdvTable[OP_PUSH_C] = sizeof(cell_t);
|
||||||
OpAdvTable[OP_PUSH] = sizeof(cell_t);
|
OpAdvTable[OP_PUSH] = sizeof(cell_t);
|
||||||
OpAdvTable[OP_PUSH_S] = sizeof(cell_t);
|
OpAdvTable[OP_PUSH_S] = sizeof(cell_t);
|
||||||
OpAdvTable[OP_STACK] = sizeof(cell_t);
|
OpAdvTable[OP_STACK] = sizeof(cell_t);
|
||||||
OpAdvTable[OP_HEAP] = sizeof(cell_t);
|
OpAdvTable[OP_HEAP] = sizeof(cell_t);
|
||||||
OpAdvTable[OP_JREL] = sizeof(cell_t);
|
|
||||||
OpAdvTable[OP_SHL_C_PRI] = sizeof(cell_t);
|
OpAdvTable[OP_SHL_C_PRI] = sizeof(cell_t);
|
||||||
OpAdvTable[OP_SHL_C_ALT] = sizeof(cell_t);
|
OpAdvTable[OP_SHL_C_ALT] = sizeof(cell_t);
|
||||||
OpAdvTable[OP_SHR_C_PRI] = sizeof(cell_t);
|
OpAdvTable[OP_SHR_C_PRI] = sizeof(cell_t);
|
||||||
@ -544,7 +537,6 @@ JITX86::JITX86()
|
|||||||
OpAdvTable[OP_DEC] = sizeof(cell_t);
|
OpAdvTable[OP_DEC] = sizeof(cell_t);
|
||||||
OpAdvTable[OP_DEC_S] = sizeof(cell_t);
|
OpAdvTable[OP_DEC_S] = sizeof(cell_t);
|
||||||
OpAdvTable[OP_MOVS] = sizeof(cell_t);
|
OpAdvTable[OP_MOVS] = sizeof(cell_t);
|
||||||
OpAdvTable[OP_CMPS] = sizeof(cell_t);
|
|
||||||
OpAdvTable[OP_FILL] = sizeof(cell_t);
|
OpAdvTable[OP_FILL] = sizeof(cell_t);
|
||||||
OpAdvTable[OP_HALT] = sizeof(cell_t);
|
OpAdvTable[OP_HALT] = sizeof(cell_t);
|
||||||
OpAdvTable[OP_BOUNDS] = sizeof(cell_t);
|
OpAdvTable[OP_BOUNDS] = sizeof(cell_t);
|
||||||
@ -574,9 +566,6 @@ JITX86::JITX86()
|
|||||||
OpAdvTable[OP_SMUL] = 0;
|
OpAdvTable[OP_SMUL] = 0;
|
||||||
OpAdvTable[OP_SDIV] = 0;
|
OpAdvTable[OP_SDIV] = 0;
|
||||||
OpAdvTable[OP_SDIV_ALT] = 0;
|
OpAdvTable[OP_SDIV_ALT] = 0;
|
||||||
OpAdvTable[OP_UMUL] = 0;
|
|
||||||
OpAdvTable[OP_UDIV] = 0;
|
|
||||||
OpAdvTable[OP_UDIV_ALT] = 0;
|
|
||||||
OpAdvTable[OP_ADD] = 0;
|
OpAdvTable[OP_ADD] = 0;
|
||||||
OpAdvTable[OP_SUB] = 0;
|
OpAdvTable[OP_SUB] = 0;
|
||||||
OpAdvTable[OP_SUB_ALT] = 0;
|
OpAdvTable[OP_SUB_ALT] = 0;
|
||||||
@ -592,10 +581,6 @@ JITX86::JITX86()
|
|||||||
OpAdvTable[OP_SIGN_ALT] = 0;
|
OpAdvTable[OP_SIGN_ALT] = 0;
|
||||||
OpAdvTable[OP_EQ] = 0;
|
OpAdvTable[OP_EQ] = 0;
|
||||||
OpAdvTable[OP_NEQ] = 0;
|
OpAdvTable[OP_NEQ] = 0;
|
||||||
OpAdvTable[OP_LESS] = 0;
|
|
||||||
OpAdvTable[OP_LEQ] = 0;
|
|
||||||
OpAdvTable[OP_GRTR] = 0;
|
|
||||||
OpAdvTable[OP_GEQ] = 0;
|
|
||||||
OpAdvTable[OP_SLESS] = 0;
|
OpAdvTable[OP_SLESS] = 0;
|
||||||
OpAdvTable[OP_SLEQ] = 0;
|
OpAdvTable[OP_SLEQ] = 0;
|
||||||
OpAdvTable[OP_SGRTR] = 0;
|
OpAdvTable[OP_SGRTR] = 0;
|
||||||
@ -622,10 +607,6 @@ JITX86::JITX86()
|
|||||||
OpAdvTable[OP_JNZ] = -2;
|
OpAdvTable[OP_JNZ] = -2;
|
||||||
OpAdvTable[OP_JEQ] = -2;
|
OpAdvTable[OP_JEQ] = -2;
|
||||||
OpAdvTable[OP_JNEQ] = -2;
|
OpAdvTable[OP_JNEQ] = -2;
|
||||||
OpAdvTable[OP_JLESS] = -2;
|
|
||||||
OpAdvTable[OP_JLEQ] = -2;
|
|
||||||
OpAdvTable[OP_JGRTR] = -2;
|
|
||||||
OpAdvTable[OP_JGEQ] = -2;
|
|
||||||
OpAdvTable[OP_JSLESS] = -2;
|
OpAdvTable[OP_JSLESS] = -2;
|
||||||
OpAdvTable[OP_JSLEQ] = -2;
|
OpAdvTable[OP_JSLEQ] = -2;
|
||||||
OpAdvTable[OP_JSGRTR] = -2;
|
OpAdvTable[OP_JSGRTR] = -2;
|
||||||
@ -633,6 +614,7 @@ JITX86::JITX86()
|
|||||||
OpAdvTable[OP_SWITCH] = -2;
|
OpAdvTable[OP_SWITCH] = -2;
|
||||||
|
|
||||||
/* opcodes that are totally invalid */
|
/* opcodes that are totally invalid */
|
||||||
|
/* :TODO: make an alternate table if USE_UNGEN_OPCODES is on? */
|
||||||
OpAdvTable[OP_FILE] = -3;
|
OpAdvTable[OP_FILE] = -3;
|
||||||
OpAdvTable[OP_SYMBOL] = -3;
|
OpAdvTable[OP_SYMBOL] = -3;
|
||||||
OpAdvTable[OP_LINE] = -3;
|
OpAdvTable[OP_LINE] = -3;
|
||||||
@ -641,4 +623,24 @@ JITX86::JITX86()
|
|||||||
OpAdvTable[OP_SYSREQ_D] = -3;
|
OpAdvTable[OP_SYSREQ_D] = -3;
|
||||||
OpAdvTable[OP_SYSREQ_ND] = -3;
|
OpAdvTable[OP_SYSREQ_ND] = -3;
|
||||||
OpAdvTable[OP_PUSH_R] = -3;
|
OpAdvTable[OP_PUSH_R] = -3;
|
||||||
|
OpAdvTable[OP_LODB_I] = -3;
|
||||||
|
OpAdvTable[OP_STRB_I] = -3;
|
||||||
|
OpAdvTable[OP_LCTRL] = -3;
|
||||||
|
OpAdvTable[OP_SCTRL] = -3;
|
||||||
|
OpAdvTable[OP_ALIGN_PRI] = -3;
|
||||||
|
OpAdvTable[OP_ALIGN_ALT] = -3;
|
||||||
|
OpAdvTable[OP_JREL] = -3;
|
||||||
|
OpAdvTable[OP_CMPS] = -3;
|
||||||
|
OpAdvTable[OP_UMUL] = -3;
|
||||||
|
OpAdvTable[OP_UDIV] = -3;
|
||||||
|
OpAdvTable[OP_UDIV_ALT] = -3;
|
||||||
|
OpAdvTable[OP_LESS] = -3;
|
||||||
|
OpAdvTable[OP_LEQ] = -3;
|
||||||
|
OpAdvTable[OP_GRTR] = -3;
|
||||||
|
OpAdvTable[OP_GEQ] = -3;
|
||||||
|
OpAdvTable[OP_JLESS] = -3;
|
||||||
|
OpAdvTable[OP_JLEQ] = -3;
|
||||||
|
OpAdvTable[OP_JGRTR] = -3;
|
||||||
|
OpAdvTable[OP_JGEQ] = -3;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -63,12 +63,12 @@ typedef enum
|
|||||||
OP_LOAD_ALT, //DONE
|
OP_LOAD_ALT, //DONE
|
||||||
OP_LOAD_S_PRI, //DONE
|
OP_LOAD_S_PRI, //DONE
|
||||||
OP_LOAD_S_ALT, //DONE
|
OP_LOAD_S_ALT, //DONE
|
||||||
OP_LREF_PRI, //UNSUPPORTED
|
OP_LREF_PRI, // !GEN :TODO: we will need this for dynarrays
|
||||||
OP_LREF_ALT, //UNSUPPORTED
|
OP_LREF_ALT, // !GEN :TODO: we will need this for dynarrays
|
||||||
OP_LREF_S_PRI, //UNSUPPORTED
|
OP_LREF_S_PRI, //DONE
|
||||||
OP_LREF_S_ALT, //UNSUPPORTED
|
OP_LREF_S_ALT, //DONE
|
||||||
OP_LOAD_I, //DONE
|
OP_LOAD_I, //DONE
|
||||||
OP_LODB_I, //UNSUPPORTED
|
OP_LODB_I, // !GEN :TODO: - only used for pack access - drop support in compiler first
|
||||||
OP_CONST_PRI, //DONE
|
OP_CONST_PRI, //DONE
|
||||||
OP_CONST_ALT, //DONE
|
OP_CONST_ALT, //DONE
|
||||||
OP_ADDR_PRI, //DONE
|
OP_ADDR_PRI, //DONE
|
||||||
@ -77,26 +77,26 @@ typedef enum
|
|||||||
OP_STOR_ALT, //DONE
|
OP_STOR_ALT, //DONE
|
||||||
OP_STOR_S_PRI, //DONE
|
OP_STOR_S_PRI, //DONE
|
||||||
OP_STOR_S_ALT, //DONE
|
OP_STOR_S_ALT, //DONE
|
||||||
OP_SREF_PRI, //UNSUPPORTED
|
OP_SREF_PRI, //DONE
|
||||||
OP_SREF_ALT, //UNSUPPORTED
|
OP_SREF_ALT, //DONE
|
||||||
OP_SREF_S_PRI, //UNSUPPORTED
|
OP_SREF_S_PRI, // !GEN :TODO: we will need this for dynarrays
|
||||||
OP_SREF_S_ALT, //UNSUPPORTED
|
OP_SREF_S_ALT, // !GEN :TODO: we will need this for dynarrays
|
||||||
OP_STOR_I, //DONE
|
OP_STOR_I, //DONE
|
||||||
OP_STRB_I, //UNSUPPORTED
|
OP_STRB_I, // !GEN :TODO: - only used for pack access, drop support in compiler first
|
||||||
OP_LIDX, //DONE
|
OP_LIDX, //DONE
|
||||||
OP_LIDX_B, //UNSUPPORTED
|
OP_LIDX_B, //DONE
|
||||||
OP_IDXADDR, //DONE
|
OP_IDXADDR, //DONE
|
||||||
OP_IDXADDR_B, //UNSUPPORTED
|
OP_IDXADDR_B, //DONE
|
||||||
OP_ALIGN_PRI, //UNSUPPORTED
|
OP_ALIGN_PRI, // !GEN :TODO: - only used for pack access, drop support in compiler first
|
||||||
OP_ALIGN_ALT, //UNSUPPORTED
|
OP_ALIGN_ALT, // !GEN :TODO: - only used for pack access, drop support in compiler first
|
||||||
OP_LCTRL, //UNSUPPORTED
|
OP_LCTRL, // !GEN
|
||||||
OP_SCTRL, //UNSUPPORTED
|
OP_SCTRL, // !GEN
|
||||||
OP_MOVE_PRI, //DONE
|
OP_MOVE_PRI, //DONE
|
||||||
OP_MOVE_ALT, //DONE
|
OP_MOVE_ALT, //DONE
|
||||||
OP_XCHG, //DONE
|
OP_XCHG, //DONE
|
||||||
OP_PUSH_PRI, //DONE
|
OP_PUSH_PRI, //DONE
|
||||||
OP_PUSH_ALT, //DONE
|
OP_PUSH_ALT, //DONE
|
||||||
OP_PUSH_R, //DEPRECATED
|
OP_PUSH_R, // !GEN DEPRECATED
|
||||||
OP_PUSH_C, //DONE
|
OP_PUSH_C, //DONE
|
||||||
OP_PUSH, //DONE
|
OP_PUSH, //DONE
|
||||||
OP_PUSH_S, //DONE
|
OP_PUSH_S, //DONE
|
||||||
@ -105,20 +105,20 @@ typedef enum
|
|||||||
OP_STACK, //DONE
|
OP_STACK, //DONE
|
||||||
OP_HEAP, //DONE
|
OP_HEAP, //DONE
|
||||||
OP_PROC, //DONE
|
OP_PROC, //DONE
|
||||||
OP_RET, //UNSUPPORTED
|
OP_RET, // !GEN
|
||||||
OP_RETN, //DONE
|
OP_RETN, //DONE
|
||||||
OP_CALL,
|
OP_CALL,
|
||||||
OP_CALL_PRI,
|
OP_CALL_PRI, // !GEN
|
||||||
OP_JUMP, //DONE
|
OP_JUMP, //DONE
|
||||||
OP_JREL, //UNSUPPORTED
|
OP_JREL, // !GEN
|
||||||
OP_JZER, //DONE
|
OP_JZER, //DONE
|
||||||
OP_JNZ, //DONE
|
OP_JNZ, //DONE
|
||||||
OP_JEQ, //DONE
|
OP_JEQ, //DONE
|
||||||
OP_JNEQ, //DONE
|
OP_JNEQ, //DONE
|
||||||
OP_JLESS, //UNSUPPORTED
|
OP_JLESS, // !GEN
|
||||||
OP_JLEQ, //UNSUPPORTED
|
OP_JLEQ, // !GEN
|
||||||
OP_JGRTR, //UNSUPPORTED
|
OP_JGRTR, // !GEN
|
||||||
OP_JGEQ, //UNSUPPORTED
|
OP_JGEQ, // !GEN
|
||||||
OP_JSLESS, //DONE
|
OP_JSLESS, //DONE
|
||||||
OP_JSLEQ, //DONE
|
OP_JSLEQ, //DONE
|
||||||
OP_JSGRTR, //DONE
|
OP_JSGRTR, //DONE
|
||||||
@ -133,9 +133,9 @@ typedef enum
|
|||||||
OP_SMUL, //DONE
|
OP_SMUL, //DONE
|
||||||
OP_SDIV, //DONE
|
OP_SDIV, //DONE
|
||||||
OP_SDIV_ALT, //DONE
|
OP_SDIV_ALT, //DONE
|
||||||
OP_UMUL, //UNSUPPORTED
|
OP_UMUL, // !GEN
|
||||||
OP_UDIV, //UNSUPPORTED
|
OP_UDIV, // !GEN
|
||||||
OP_UDIV_ALT, //UNSUPPORTED
|
OP_UDIV_ALT, // !GEN
|
||||||
OP_ADD, //DONE
|
OP_ADD, //DONE
|
||||||
OP_SUB, //DONE
|
OP_SUB, //DONE
|
||||||
OP_SUB_ALT, //DONE
|
OP_SUB_ALT, //DONE
|
||||||
@ -155,10 +155,10 @@ typedef enum
|
|||||||
OP_SIGN_ALT, //DONE
|
OP_SIGN_ALT, //DONE
|
||||||
OP_EQ, //DONE
|
OP_EQ, //DONE
|
||||||
OP_NEQ, //DONE
|
OP_NEQ, //DONE
|
||||||
OP_LESS, //UNSUPPORTED
|
OP_LESS, // !GEN
|
||||||
OP_LEQ, //UNSUPPORTED
|
OP_LEQ, // !GEN
|
||||||
OP_GRTR, //UNSUPPORTED
|
OP_GRTR, // !GEN
|
||||||
OP_GEQ, //UNSUPPORTED
|
OP_GEQ, // !GEN
|
||||||
OP_SLESS, //DONE
|
OP_SLESS, //DONE
|
||||||
OP_SLEQ, //DONE
|
OP_SLEQ, //DONE
|
||||||
OP_SGRTR, //DONE
|
OP_SGRTR, //DONE
|
||||||
@ -176,17 +176,17 @@ typedef enum
|
|||||||
OP_DEC_S, //DONE
|
OP_DEC_S, //DONE
|
||||||
OP_DEC_I, //DONE
|
OP_DEC_I, //DONE
|
||||||
OP_MOVS, //DONE
|
OP_MOVS, //DONE
|
||||||
OP_CMPS, //UNSUPPORTED
|
OP_CMPS, // !GEN
|
||||||
OP_FILL, //DONE
|
OP_FILL, //DONE
|
||||||
OP_HALT, //DONE
|
OP_HALT, //DONE
|
||||||
OP_BOUNDS, //DONE
|
OP_BOUNDS, //DONE
|
||||||
OP_SYSREQ_PRI,
|
OP_SYSREQ_PRI, // !GEN
|
||||||
OP_SYSREQ_C,
|
OP_SYSREQ_C,
|
||||||
OP_FILE, //DEPRECATED
|
OP_FILE, // !GEN DEPRECATED
|
||||||
OP_LINE, //DEPRECATED
|
OP_LINE, // !GEN DEPRECATED
|
||||||
OP_SYMBOL, //DEPRECATED
|
OP_SYMBOL, // !GEN DEPRECATED
|
||||||
OP_SRANGE, //DEPRECATED
|
OP_SRANGE, // !GEN DEPRECATED
|
||||||
OP_JUMP_PRI,
|
OP_JUMP_PRI, // !GEN
|
||||||
OP_SWITCH,
|
OP_SWITCH,
|
||||||
OP_CASETBL,
|
OP_CASETBL,
|
||||||
OP_SWAP_PRI, //DONE
|
OP_SWAP_PRI, //DONE
|
||||||
@ -194,7 +194,7 @@ typedef enum
|
|||||||
OP_PUSH_ADR, //DONE
|
OP_PUSH_ADR, //DONE
|
||||||
OP_NOP, //DONE
|
OP_NOP, //DONE
|
||||||
OP_SYSREQ_N,
|
OP_SYSREQ_N,
|
||||||
OP_SYMTAG, //DEPRECATED
|
OP_SYMTAG, // !GEN DEPRECATED
|
||||||
OP_BREAK, //DONE
|
OP_BREAK, //DONE
|
||||||
OP_PUSH2_C, //DONE
|
OP_PUSH2_C, //DONE
|
||||||
OP_PUSH2, //DONE
|
OP_PUSH2, //DONE
|
||||||
@ -217,8 +217,8 @@ typedef enum
|
|||||||
OP_CONST, //DONE
|
OP_CONST, //DONE
|
||||||
OP_CONST_S, //DONE
|
OP_CONST_S, //DONE
|
||||||
/* ----- */
|
/* ----- */
|
||||||
OP_SYSREQ_D, //UNSUPPORTED
|
OP_SYSREQ_D, // !GEN UNSUPPORT
|
||||||
OP_SYSREQ_ND, //UNSUPPORTED
|
OP_SYSREQ_ND, // !GEN UNSUPPORT
|
||||||
/* ----- */
|
/* ----- */
|
||||||
OP_HEAP_PRI, //DONE
|
OP_HEAP_PRI, //DONE
|
||||||
OP_PUSH_HEAP_C, //DONE
|
OP_PUSH_HEAP_C, //DONE
|
||||||
|
@ -158,13 +158,6 @@
|
|||||||
WriteOp_SMul(jit);
|
WriteOp_SMul(jit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_UMUL:
|
|
||||||
{
|
|
||||||
WriteOp_UMul(jit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
case OP_ADD:
|
case OP_ADD:
|
||||||
{
|
{
|
||||||
WriteOp_Add(jit);
|
WriteOp_Add(jit);
|
||||||
@ -245,34 +238,6 @@
|
|||||||
WriteOp_Neq(jit);
|
WriteOp_Neq(jit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_LESS:
|
|
||||||
{
|
|
||||||
WriteOp_Less(jit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_LEQ:
|
|
||||||
{
|
|
||||||
WriteOp_Leq(jit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_GRTR:
|
|
||||||
{
|
|
||||||
WriteOp_Grtr(jit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_GEQ:
|
|
||||||
{
|
|
||||||
WriteOp_Geq(jit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
case OP_SLESS:
|
case OP_SLESS:
|
||||||
{
|
{
|
||||||
WriteOp_Sless(jit);
|
WriteOp_Sless(jit);
|
||||||
@ -373,34 +338,26 @@
|
|||||||
WriteOp_Load_S_Alt(jit);
|
WriteOp_Load_S_Alt(jit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_LREF_PRI:
|
case OP_LREF_PRI:
|
||||||
{
|
{
|
||||||
WriteOp_Lref_Pri(jit);
|
WriteOp_Lref_Pri(jit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_LREF_ALT:
|
case OP_LREF_ALT:
|
||||||
{
|
{
|
||||||
WriteOp_Lref_Alt(jit);
|
WriteOp_Lref_Alt(jit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_LREF_S_PRI:
|
case OP_LREF_S_PRI:
|
||||||
{
|
{
|
||||||
WriteOp_Lref_Pri(jit);
|
WriteOp_Lref_Pri(jit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_LREF_S_ALT:
|
case OP_LREF_S_ALT:
|
||||||
{
|
{
|
||||||
WriteOp_Lref_Alt(jit);
|
WriteOp_Lref_Alt(jit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
case OP_CONST_PRI:
|
case OP_CONST_PRI:
|
||||||
{
|
{
|
||||||
WriteOp_Const_Pri(jit);
|
WriteOp_Const_Pri(jit);
|
||||||
@ -446,48 +403,26 @@
|
|||||||
WriteOp_Idxaddr(jit);
|
WriteOp_Idxaddr(jit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_SREF_PRI:
|
case OP_SREF_PRI:
|
||||||
{
|
{
|
||||||
WriteOp_Sref_Pri(jit);
|
WriteOp_Sref_Pri(jit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_SREF_ALT:
|
case OP_SREF_ALT:
|
||||||
{
|
{
|
||||||
WriteOp_Sref_Alt(jit);
|
WriteOp_Sref_Alt(jit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_SREF_S_PRI:
|
case OP_SREF_S_PRI:
|
||||||
{
|
{
|
||||||
WriteOp_Sref_S_Pri(jit);
|
WriteOp_Sref_S_Pri(jit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_SREF_S_ALT:
|
case OP_SREF_S_ALT:
|
||||||
{
|
{
|
||||||
WriteOp_Sref_S_Alt(jit);
|
WriteOp_Sref_S_Alt(jit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_ALIGN_PRI:
|
|
||||||
{
|
|
||||||
WriteOp_Align_Pri(jit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_ALIGN_ALT:
|
|
||||||
{
|
|
||||||
WriteOp_Align_Alt(jit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
case OP_POP_PRI:
|
case OP_POP_PRI:
|
||||||
{
|
{
|
||||||
WriteOp_Pop_Pri(jit);
|
WriteOp_Pop_Pri(jit);
|
||||||
@ -588,58 +523,26 @@
|
|||||||
WriteOp_Load_I(jit);
|
WriteOp_Load_I(jit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_LODB_I:
|
|
||||||
{
|
|
||||||
WriteOp_Lodb_I(jit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
case OP_STOR_I:
|
case OP_STOR_I:
|
||||||
{
|
{
|
||||||
WriteOp_Stor_I(jit);
|
WriteOp_Stor_I(jit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_STRB_I:
|
|
||||||
{
|
|
||||||
WriteOp_Strb_I(jit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
case OP_LIDX:
|
case OP_LIDX:
|
||||||
{
|
{
|
||||||
WriteOp_Lidx(jit);
|
WriteOp_Lidx(jit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_LIDX_B:
|
case OP_LIDX_B:
|
||||||
{
|
{
|
||||||
WriteOp_Lidx_B(jit);
|
WriteOp_Lidx_B(jit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_IDXADDR_B:
|
case OP_IDXADDR_B:
|
||||||
{
|
{
|
||||||
WriteOp_Idxaddr_B(jit);
|
WriteOp_Idxaddr_B(jit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_LCTRL:
|
|
||||||
{
|
|
||||||
WriteOp_Lctrl(jit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_SCTRL:
|
|
||||||
{
|
|
||||||
WriteOp_Sctrl(jit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
case OP_STACK:
|
case OP_STACK:
|
||||||
{
|
{
|
||||||
WriteOp_Stack(jit);
|
WriteOp_Stack(jit);
|
||||||
@ -660,39 +563,11 @@
|
|||||||
WriteOp_SDiv_Alt(jit);
|
WriteOp_SDiv_Alt(jit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_UDIV:
|
|
||||||
{
|
|
||||||
WriteOp_UDiv(jit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_UDIV_ALT:
|
|
||||||
{
|
|
||||||
WriteOp_UDiv_Alt(jit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_RET:
|
|
||||||
{
|
|
||||||
WriteOp_Ret(jit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
case OP_RETN:
|
case OP_RETN:
|
||||||
{
|
{
|
||||||
WriteOp_Retn(jit);
|
WriteOp_Retn(jit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_CMPS:
|
|
||||||
{
|
|
||||||
WriteOp_Cmps(jit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
case OP_BOUNDS:
|
case OP_BOUNDS:
|
||||||
{
|
{
|
||||||
WriteOp_Bounds(jit);
|
WriteOp_Bounds(jit);
|
||||||
@ -708,13 +583,6 @@
|
|||||||
WriteOp_Break(jit);
|
WriteOp_Break(jit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_JREL:
|
|
||||||
{
|
|
||||||
WriteOp_JRel(jit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
case OP_JUMP:
|
case OP_JUMP:
|
||||||
{
|
{
|
||||||
WriteOp_Jump(jit);
|
WriteOp_Jump(jit);
|
||||||
@ -740,34 +608,6 @@
|
|||||||
WriteOp_Jneq(jit);
|
WriteOp_Jneq(jit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_JLESS:
|
|
||||||
{
|
|
||||||
WriteOp_Jless(jit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_JLEQ:
|
|
||||||
{
|
|
||||||
WriteOp_Jeq(jit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_JGRTR:
|
|
||||||
{
|
|
||||||
WriteOp_Jgrtr(jit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef UNSUPPORTED
|
|
||||||
case OP_JGEQ:
|
|
||||||
{
|
|
||||||
WriteOp_Jgeq(jit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
case OP_JSLESS:
|
case OP_JSLESS:
|
||||||
{
|
{
|
||||||
WriteOp_Jsless(jit);
|
WriteOp_Jsless(jit);
|
||||||
@ -778,6 +618,9 @@
|
|||||||
WriteOp_Jsleq(jit);
|
WriteOp_Jsleq(jit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#if defined USE_UNGEN_OPCODES
|
||||||
|
#include "ungen_opcode_switch.inc"
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
assert(0);
|
assert(0);
|
||||||
|
100
sourcepawn/vm/jit/x86/ungen_opcode_switch.inc
Normal file
100
sourcepawn/vm/jit/x86/ungen_opcode_switch.inc
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
case OP_UMUL:
|
||||||
|
{
|
||||||
|
WriteOp_UMul(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_ALIGN_PRI:
|
||||||
|
{
|
||||||
|
WriteOp_Align_Pri(jit);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OP_ALIGN_ALT:
|
||||||
|
{
|
||||||
|
WriteOp_Align_Alt(jit);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OP_LODB_I:
|
||||||
|
{
|
||||||
|
WriteOp_Lodb_I(jit);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OP_STRB_I:
|
||||||
|
{
|
||||||
|
WriteOp_Strb_I(jit);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OP_LCTRL:
|
||||||
|
{
|
||||||
|
WriteOp_Lctrl(jit);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OP_SCTRL:
|
||||||
|
{
|
||||||
|
WriteOp_Sctrl(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_CMPS:
|
||||||
|
{
|
||||||
|
WriteOp_Cmps(jit);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OP_JREL:
|
||||||
|
{
|
||||||
|
WriteOp_JRel(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;
|
||||||
|
}
|
336
sourcepawn/vm/jit/x86/ungen_opcodes.h
Normal file
336
sourcepawn/vm/jit/x86/ungen_opcodes.h
Normal file
@ -0,0 +1,336 @@
|
|||||||
|
#ifndef _INCLUDE_SOURCEPAWN_JIT_X86_UNGEN_OPCODES_H_
|
||||||
|
#define _INCLUDE_SOURCEPAWN_JIT_X86_UNGEN_OPCODES_H_
|
||||||
|
|
||||||
|
inline void WriteOp_UMul(JitWriter *jit)
|
||||||
|
{
|
||||||
|
//mov ecx, edx
|
||||||
|
//mul edx
|
||||||
|
//mov edx, ecx
|
||||||
|
IA32_Mov_Rm_Reg(jit, AMX_REG_TMP, AMX_REG_ALT, MOD_REG);
|
||||||
|
IA32_Mul_Rm(jit, AMX_REG_ALT, MOD_REG);
|
||||||
|
IA32_Mov_Rm_Reg(jit, AMX_REG_ALT, AMX_REG_TMP, MOD_REG);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void WriteOp_Less(JitWriter *jit)
|
||||||
|
{
|
||||||
|
//cmp eax, edx ; PRI < ALT ? (unsigned)
|
||||||
|
//mov eax, 0
|
||||||
|
//setb al
|
||||||
|
IA32_Cmp_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
|
||||||
|
IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
|
||||||
|
IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_B);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void WriteOp_Leq(JitWriter *jit)
|
||||||
|
{
|
||||||
|
//cmp eax, edx ; PRI <= ALT ? (unsigned)
|
||||||
|
//mov eax, 0
|
||||||
|
//setbe al
|
||||||
|
IA32_Cmp_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
|
||||||
|
IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
|
||||||
|
IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_BE);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void WriteOp_Grtr(JitWriter *jit)
|
||||||
|
{
|
||||||
|
//cmp eax, edx ; PRI > ALT ? (unsigned)
|
||||||
|
//mov eax, 0
|
||||||
|
//seta al
|
||||||
|
IA32_Cmp_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
|
||||||
|
IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
|
||||||
|
IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_A);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void WriteOp_Geq(JitWriter *jit)
|
||||||
|
{
|
||||||
|
//cmp eax, edx ; PRI >= ALT ? (unsigned)
|
||||||
|
//mov eax, 0
|
||||||
|
//setae al
|
||||||
|
IA32_Cmp_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
|
||||||
|
IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
|
||||||
|
IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_AE);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void WriteOp_Align_Pri(JitWriter *jit)
|
||||||
|
{
|
||||||
|
//xor eax, <cellsize - val>
|
||||||
|
cell_t val = sizeof(cell_t) - jit->read_cell();
|
||||||
|
if (val < SCHAR_MAX && val > SCHAR_MIN)
|
||||||
|
IA32_Xor_Rm_Imm8(jit, AMX_REG_PRI, MOD_REG, (jit_int8_t)val);
|
||||||
|
else
|
||||||
|
IA32_Xor_Eax_Imm32(jit, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void WriteOp_Align_Alt(JitWriter *jit)
|
||||||
|
{
|
||||||
|
//xor edx, <cellsize - val>
|
||||||
|
cell_t val = sizeof(cell_t) - jit->read_cell();
|
||||||
|
if (val < SCHAR_MAX && val > SCHAR_MIN)
|
||||||
|
IA32_Xor_Rm_Imm8(jit, AMX_REG_ALT, MOD_REG, (jit_int8_t)val);
|
||||||
|
else
|
||||||
|
IA32_Xor_Rm_Imm32(jit, AMX_REG_ALT, MOD_REG, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void WriteOp_Cmps(JitWriter *jit)
|
||||||
|
{
|
||||||
|
//push edi
|
||||||
|
//push esi
|
||||||
|
//lea esi, [edi+edx]
|
||||||
|
//lea edi, [edi+eax]
|
||||||
|
IA32_Push_Reg(jit, REG_EDI);
|
||||||
|
IA32_Push_Reg(jit, REG_ESI);
|
||||||
|
IA32_Lea_Reg_DispRegMult(jit, REG_ESI, AMX_REG_DAT, AMX_REG_ALT, NOSCALE);
|
||||||
|
IA32_Lea_Reg_DispRegMult(jit, REG_EDI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
|
||||||
|
|
||||||
|
//xor eax, eax
|
||||||
|
//repe cmpsb
|
||||||
|
//je :cmps1
|
||||||
|
IA32_Xor_Rm_Reg(jit, REG_EAX, REG_EAX, MOD_REG);
|
||||||
|
IA32_Cmpsb(jit);
|
||||||
|
jitoffs_t jmp = IA32_Jump_Cond_Imm8(jit, CC_E, 0);
|
||||||
|
|
||||||
|
//sbb eax, eax
|
||||||
|
//sbb eax, -1
|
||||||
|
IA32_Sbb_Rm_Reg(jit, REG_EAX, REG_EAX, MOD_REG);
|
||||||
|
IA32_Sbb_Eax_Imm32(jit, -1);//:TODO: use imm8 here
|
||||||
|
|
||||||
|
//:cmps1
|
||||||
|
//pop esi
|
||||||
|
//pop edi
|
||||||
|
IA32_Send_Jump8_Here(jit, jmp);
|
||||||
|
IA32_Pop_Reg(jit, REG_ESI);
|
||||||
|
IA32_Pop_Reg(jit, REG_EDI);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);//:TODO: replace with AND EAX, imm32
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
IA32_And_Rm_Imm32(jit, AMX_REG_PRI, 0x0000FFFF);//:TODO: replace with AND EAX, imm32
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 4:
|
||||||
|
{
|
||||||
|
IA32_Mov_Rm_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_ALT, NOSCALE, AMX_REG_PRI);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void WriteOp_Lctrl(JitWriter *jit)
|
||||||
|
{
|
||||||
|
cell_t val = jit->read_cell();
|
||||||
|
switch (val)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
//mov ecx, [esi+ctx]
|
||||||
|
//mov eax, [ecx+<offs>]
|
||||||
|
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
|
||||||
|
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_TMP, offsetof(sp_context_t, base));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
//mov eax, edi
|
||||||
|
IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_DAT, MOD_REG);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
//mov eax, [esi+hea]
|
||||||
|
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_INFO, AMX_INFO_HEAP);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
//mov ecx, [esi+ctx]
|
||||||
|
//mov eax, [ecx+ctx.memory]
|
||||||
|
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
|
||||||
|
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_TMP, offsetof(sp_context_t, memory));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
//mov eax, ebp
|
||||||
|
//sub eax, edi - unrelocate
|
||||||
|
IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_STK, MOD_REG);
|
||||||
|
IA32_Sub_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, MOD_REG);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 5:
|
||||||
|
{
|
||||||
|
//mov eax, [esi+frm]
|
||||||
|
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_INFO, AMX_INFO_FRM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 6:
|
||||||
|
{
|
||||||
|
//mov eax, [cip]
|
||||||
|
jitoffs_t imm32 = IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
|
||||||
|
jitoffs_t save = jit->jit_curpos();
|
||||||
|
jit->setpos(imm32);
|
||||||
|
jit->write_int32((uint32_t)(jit->outbase + save));
|
||||||
|
jit->setpos(save);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void WriteOp_Sctrl(JitWriter *jit)
|
||||||
|
{
|
||||||
|
cell_t val = jit->read_cell();
|
||||||
|
switch (val)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
//mov [esi+hea], eax
|
||||||
|
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, AMX_INFO_HEAP, AMX_REG_PRI);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
//lea ebp, [edi+eax]
|
||||||
|
IA32_Lea_Reg_DispRegMult(jit, AMX_REG_STK, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 5:
|
||||||
|
{
|
||||||
|
//mov ebx, eax - overwrite frm
|
||||||
|
//mov frm, eax - overwrite stacked frame
|
||||||
|
//add ebx, edi - relocate local frm //:TODO: use LEA here!!!
|
||||||
|
IA32_Mov_Reg_Rm(jit, AMX_REG_FRM, AMX_REG_PRI, MOD_REG);
|
||||||
|
IA32_Mov_Rm_Reg(jit, AMX_INFO_FRM, AMX_REG_PRI, MOD_MEM_REG);
|
||||||
|
IA32_Add_Rm_Reg(jit, AMX_REG_FRM, AMX_REG_DAT, MOD_REG);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 6:
|
||||||
|
{
|
||||||
|
IA32_Jump_Reg(jit, AMX_REG_PRI);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void WriteOp_UDiv(JitWriter *jit)
|
||||||
|
{
|
||||||
|
//mov ecx, edx
|
||||||
|
//xor edx, edx
|
||||||
|
//div ecx
|
||||||
|
IA32_Mov_Rm_Reg(jit, AMX_REG_TMP, AMX_REG_ALT, MOD_REG);
|
||||||
|
IA32_Xor_Rm_Reg(jit, AMX_REG_ALT, AMX_REG_ALT, MOD_REG);
|
||||||
|
Write_Check_DivZero(jit, AMX_REG_TMP);
|
||||||
|
IA32_Div_Rm(jit, AMX_REG_TMP, MOD_REG);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void WriteOp_UDiv_Alt(JitWriter *jit)
|
||||||
|
{
|
||||||
|
//mov ecx, eax
|
||||||
|
//mov eax, edx
|
||||||
|
//xor edx, edx
|
||||||
|
//div ecx
|
||||||
|
IA32_Mov_Rm_Reg(jit, AMX_REG_TMP, AMX_REG_PRI, MOD_REG);
|
||||||
|
IA32_Mov_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
|
||||||
|
IA32_Xor_Rm_Reg(jit, AMX_REG_ALT, AMX_REG_ALT, MOD_REG);
|
||||||
|
Write_Check_DivZero(jit, AMX_REG_TMP);
|
||||||
|
IA32_Div_Rm(jit, AMX_REG_TMP, MOD_REG);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void WriteOp_Ret(JitWriter *jit)
|
||||||
|
{
|
||||||
|
//mov ebx, [ebp] - get old FRM
|
||||||
|
//add ebp, 4 - pop stack
|
||||||
|
//mov [esi+frm], ebx - restore
|
||||||
|
//add ebx, edi - relocate
|
||||||
|
//ret
|
||||||
|
IA32_Mov_Reg_Rm(jit, AMX_REG_FRM, AMX_REG_STK, MOD_MEM_REG);
|
||||||
|
IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
|
||||||
|
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_INFO, AMX_REG_FRM, AMX_INFO_FRM);//:TODO: this is wrong!
|
||||||
|
IA32_Add_Rm_Reg(jit, AMX_REG_FRM, AMX_REG_DAT, MOD_REG);
|
||||||
|
IA32_Return(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_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));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //_INCLUDE_SOURCEPAWN_JIT_X86_UNGEN_OPCODES_H_
|
@ -6,8 +6,39 @@
|
|||||||
#include "zlib/zlib.h"
|
#include "zlib/zlib.h"
|
||||||
#include "sp_vm_basecontext.h"
|
#include "sp_vm_basecontext.h"
|
||||||
|
|
||||||
|
#if defined WIN32
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#else if defined __GNUC__
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace SourcePawn;
|
using namespace SourcePawn;
|
||||||
|
|
||||||
|
void *SourcePawnEngine::ExecAlloc(size_t size)
|
||||||
|
{
|
||||||
|
#if defined WIN32
|
||||||
|
return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||||
|
#else if defined __GNUC__
|
||||||
|
void *base = memalign(sysconf(_SC_PAGESIZE), size);
|
||||||
|
if (mprotect(base, size, PROT_READ|PROT_WRITE|PROT_EXEC) != 0)
|
||||||
|
{
|
||||||
|
free(base);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return base;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void SourcePawnEngine::ExecFree(void *address)
|
||||||
|
{
|
||||||
|
#if defined WIN32
|
||||||
|
VirtualFree(address, 0, MEM_RELEASE);
|
||||||
|
#else if defined __GNUC__
|
||||||
|
free(address);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void *SourcePawnEngine::BaseAlloc(size_t size)
|
void *SourcePawnEngine::BaseAlloc(size_t size)
|
||||||
{
|
{
|
||||||
return malloc(size);
|
return malloc(size);
|
||||||
@ -28,7 +59,7 @@ void SourcePawnEngine::FreeBaseContext(IPluginContext *ctx)
|
|||||||
sp_context_t *_ctx = ctx->GetContext();
|
sp_context_t *_ctx = ctx->GetContext();
|
||||||
IVirtualMachine *vm = ctx->GetVirtualMachine();
|
IVirtualMachine *vm = ctx->GetVirtualMachine();
|
||||||
|
|
||||||
vm->FreeContextVars(_ctx);
|
vm->FreeContext(_ctx);
|
||||||
|
|
||||||
delete ctx;
|
delete ctx;
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,22 @@ namespace SourcePawn
|
|||||||
* @param mem Memory address to free.
|
* @param mem Memory address to free.
|
||||||
*/
|
*/
|
||||||
void BaseFree(void *memory);
|
void BaseFree(void *memory);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocates executable memory.
|
||||||
|
*
|
||||||
|
* @param size Size of memory to allocate.
|
||||||
|
* @return Pointer to memory, NULL if allocation failed.
|
||||||
|
*/
|
||||||
|
void *ExecAlloc(size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees executable memory.
|
||||||
|
*
|
||||||
|
* @param mem Address to free.
|
||||||
|
*/
|
||||||
|
void ExecFree(void *address);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user