From 2ada76752870beb1ac4b0fb92aae840f8f8673d8 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Thu, 21 Sep 2006 01:48:19 +0000 Subject: [PATCH] committed ret/retn --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%4089 --- sourcepawn/include/sp_vm_types.h | 5 +++ sourcepawn/vm/jit/x86/jit_x86.cpp | 46 ++++++++++++++++++++++++++ sourcepawn/vm/jit/x86/opcode_helpers.h | 4 +-- sourcepawn/vm/jit/x86/x86_macros.h | 13 ++++++++ 4 files changed, 66 insertions(+), 2 deletions(-) diff --git a/sourcepawn/include/sp_vm_types.h b/sourcepawn/include/sp_vm_types.h index 8de64699..3866174a 100644 --- a/sourcepawn/include/sp_vm_types.h +++ b/sourcepawn/include/sp_vm_types.h @@ -21,6 +21,10 @@ typedef int32_t cell_t; #define SP_ERR_STACKERR 9 /* Stack/Heap collision */ #define SP_ERR_NOTDEBUGGING 10 /* Debug mode was not on or debug section not found */ #define SP_ERR_INVALID_INSTRUCTION 11 /* Invalid instruction was encountered */ +#define SP_ERR_MEMACCESS 12 /* Invalid memory access */ +#define SP_ERR_STACKMIN 13 /* Stack went beyond its minimum value */ +#define SP_ERR_HEAPMIN 14 /* Heap went beyond its minimum value */ +#define SP_ERR_DIVIDE_BY_ZERO 15 /* Division by zero */ /********************************************** *** The following structures are reference structures. @@ -203,6 +207,7 @@ typedef struct sp_context_s cell_t alt; /* ALT register */ cell_t hp; /* heap pointer */ cell_t sp; /* stack pointer */ + cell_t frm; /* frame pointer */ int32_t err; /* error code */ uint32_t pushcount; /* push count */ /* context rebased database */ diff --git a/sourcepawn/vm/jit/x86/jit_x86.cpp b/sourcepawn/vm/jit/x86/jit_x86.cpp index 7318ccfe..e9577a60 100644 --- a/sourcepawn/vm/jit/x86/jit_x86.cpp +++ b/sourcepawn/vm/jit/x86/jit_x86.cpp @@ -1286,6 +1286,42 @@ inline void WriteOp_UDiv_Alt(JitWriter *jit) 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); + IA32_Add_Rm_Reg(jit, AMX_REG_FRM, AMX_REG_DAT, MOD_REG); + IA32_Return(jit); +} + +inline void WriteOp_Retn(JitWriter *jit) +{ + //mov ebx, [ebp] - get old frm + //mov ecx, [ebp+4] - get return eip + //add ebp, 8 - pop stack + //mov [esi+frm], ebx - restore frame pointer + //add ebx, edi - relocate + IA32_Mov_Reg_Rm(jit, AMX_REG_FRM, AMX_REG_STK, MOD_MEM_REG); + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_STK, 4); + IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 8, MOD_REG); + IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, AMX_REG_FRM, AMX_INFO_FRM); + IA32_Add_Rm_Reg(jit, AMX_REG_FRM, AMX_REG_DAT, MOD_REG); + + //add ebp, [ebp] - reduce by this # of params + //add ebp, 4 - pop one extra for the # itself + IA32_Add_Reg_Rm(jit, AMX_REG_STK, AMX_REG_STK, MOD_MEM_REG); + IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG); + + //jmp ecx - jump to return eip + IA32_Jump_Reg(jit, AMX_REG_TMP); +} + /************************************************* ************************************************* * JIT PROPER ************************************ @@ -2027,6 +2063,16 @@ IPluginContext *JITX86::CompileToContext(ICompilation *co, int *err) WriteOp_UDiv_Alt(jit); break; } + case OP_RET: + { + WriteOp_Ret(jit); + break; + } + case OP_RETN: + { + WriteOp_Retn(jit); + break; + } default: { AbortCompilation(co); diff --git a/sourcepawn/vm/jit/x86/opcode_helpers.h b/sourcepawn/vm/jit/x86/opcode_helpers.h index 51f8619c..0629a032 100644 --- a/sourcepawn/vm/jit/x86/opcode_helpers.h +++ b/sourcepawn/vm/jit/x86/opcode_helpers.h @@ -95,8 +95,8 @@ typedef enum OP_STACK, //DONE OP_HEAP, //DONE OP_PROC, //DONE - OP_RET, - OP_RETN, + OP_RET, //DONE + OP_RETN, //DONE OP_CALL, OP_CALL_PRI, OP_JUMP, diff --git a/sourcepawn/vm/jit/x86/x86_macros.h b/sourcepawn/vm/jit/x86/x86_macros.h index 66e22138..b5fcc8f1 100644 --- a/sourcepawn/vm/jit/x86/x86_macros.h +++ b/sourcepawn/vm/jit/x86/x86_macros.h @@ -407,6 +407,12 @@ inline void IA32_Add_Rm_Reg_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t jit->write_byte(disp); } +inline void IA32_Add_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) +{ + jit->write_ubyte(IA32_ADD_REG_RM); + jit->write_ubyte(ia32_modrm(mode, dest, src)); +} + inline void IA32_Add_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp) { jit->write_ubyte(IA32_ADD_REG_RM); @@ -664,6 +670,13 @@ inline void IA32_Mov_Rm_Imm32_Disp8(JitWriter *jit, jit->write_int32(val); } +inline void IA32_Mov_Rm_Imm32(JitWriter *jit, jit_uint8_t dest, jit_int32_t val, jit_uint8_t mode) +{ + jit->write_ubyte(IA32_MOV_RM_IMM32); + jit->write_ubyte(ia32_modrm(mode, 0, dest)); + jit->write_int32(val); +} + inline void IA32_Mov_Rm_Imm32_Disp32(JitWriter *jit, jit_uint8_t dest, jit_int32_t val,