2 * vim: set ts=4 sw=4 tw=99 et:
3 * =============================================================================
5 * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
6 * =============================================================================
8 * This program is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, version 3.0, as published by the
10 * Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to link the
21 * code of this program (as well as its derivative works) to "Half-Life 2," the
22 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
23 * by the Valve Corporation. You must obey the GNU General Public License in
24 * all respects for all other code used. Additionally, AlliedModders LLC grants
25 * this exception to all derivative works. AlliedModders LLC defines further
26 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
27 * or <http://www.sourcemod.net/license.php>.
32 #ifndef _INCLUDE_SOURCEPAWN_JIT_X86_H_
33 #define _INCLUDE_SOURCEPAWN_JIT_X86_H_
35 #include <sp_vm_types.h>
36 #include <sp_vm_api.h>
37 #include <KeCodeAllocator.h>
38 #include <macro-assembler-x86.h>
39 #include <ke_vector.h>
40 #include "jit_shared.h"
41 #include "BaseRuntime.h"
42 #include "jit_function.h"
45 using namespace SourcePawn;
47 #define JIT_INLINE_ERRORCHECKS (1<<0)
48 #define JIT_INLINE_NATIVES (1<<1)
49 #define STACK_MARGIN 64 //8 parameters of safety, I guess
50 #define JIT_FUNCMAGIC 0x214D4148 //magic function offset
52 #define JITVARS_TRACKER 0 //important: don't change this to avoid trouble
53 #define JITVARS_BASECTX 1 //important: don't change this aWOAWOGJQG I LIKE HAM
54 #define JITVARS_PROFILER 2 //profiler
55 #define JITVARS_PLUGIN 3 //sp_plugin_t
57 #define sDIMEN_MAX 5 //this must mirror what the compiler has.
59 #define GET_CONTEXT(c) ((IPluginContext *)c->vm[JITVARS_BASECTX])
61 typedef struct tracker_s
68 typedef struct funcinfo_s
74 typedef struct functracker_s
76 unsigned int num_functions;
77 unsigned int code_size;
85 CallThunk(cell_t pcode_offset)
86 : pcode_offset(pcode_offset)
91 class CompData : public ICompilation
99 bool SetOption(const char *key, const char *val);
102 cell_t cur_func; /* current func pcode offset */
104 int profile; /* profiling flags */
105 int inline_level; /* inline optimization level */
106 /* Per-compilation properties */
107 unsigned int func_idx; /* current function index */
113 Compiler(BaseRuntime *rt, cell_t pcode_offs);
116 JitFunction *emit(int *errp);
119 bool setup(cell_t pcode_offs);
120 bool emitOp(OPCODE op);
124 Label *labelAt(size_t offset);
126 bool emitNativeCall(OPCODE op);
128 void emitGenArray(bool autozero);
129 void emitCallThunks();
130 void emitCheckAddress(Register reg);
131 void emitErrorPath(Label *dest, int code);
132 void emitErrorPaths();
137 const sp_plugin_t *plugin_;
139 uint32_t pcode_start_;
147 Label error_heap_low_;
148 Label error_heap_min_;
149 Label error_stack_low_;
150 Label error_stack_min_;
151 Label error_divide_by_zero_;
152 Label error_memaccess_;
153 Label error_integer_overflow_;
156 ke::Vector<CallThunk *> thunks_; //:TODO: free
165 bool InitializeJIT();
167 ICompilation *StartCompilation(BaseRuntime *runtime);
168 ICompilation *StartCompilation();
169 void SetupContextVars(BaseRuntime *runtime, BaseContext *pCtx, sp_context_t *ctx);
170 void FreeContextVars(sp_context_t *ctx);
171 SPVM_NATIVE_FUNC CreateFakeNative(SPVM_FAKENATIVE_FUNC callback, void *pData);
172 void DestroyFakeNative(SPVM_NATIVE_FUNC func);
173 JitFunction *CompileFunction(BaseRuntime *runtime, cell_t pcode_offs, int *err);
174 ICompilation *ApplyOptions(ICompilation *_IN, ICompilation *_OUT);
175 int InvokeFunction(BaseRuntime *runtime, JitFunction *fn, cell_t *result);
178 ExternalAddress GetUniversalReturn() {
179 return ExternalAddress(m_pJitReturn);
181 void *AllocCode(size_t size);
182 void FreeCode(void *code);
185 void *m_pJitEntry; /* Entry function */
186 void *m_pJitReturn; /* Universal return address */
189 const Register pri = eax;
190 const Register alt = edx;
191 const Register stk = edi;
192 const Register dat = ebp;
193 const Register tmp = ecx;
194 const Register info = esi;
195 const Register frm = ebx;
209 #define AMX_INFO_FRAME offsetof(InfoVars, frm)
210 #define AMX_INFO_HEAP offsetof(InfoVars, hp)
211 #define AMX_INFO_RETVAL offsetof(InfoVars, rval)
212 #define AMX_INFO_CONTEXT offsetof(InfoVars, ctx)
213 #define AMX_INFO_STACKTOP offsetof(InfoVars, stp)
214 #define AMX_INFO_CIP offsetof(InfoVars, cip)
215 #define AMX_INFO_DATASIZE offsetof(InfoVars, data_size)
216 #define AMX_INFO_MEMORY offsetof(InfoVars, memory)
217 #define AMX_INFO_NSTACK offsetof(InfoVars, esp)
219 extern Knight::KeCodeCache *g_pCodeCache;
222 #endif //_INCLUDE_SOURCEPAWN_JIT_X86_H_