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 "sp_vm_basecontext.h"
43 #include "jit_function.h"
46 using namespace SourcePawn;
48 #define JIT_INLINE_ERRORCHECKS (1<<0)
49 #define JIT_INLINE_NATIVES (1<<1)
50 #define STACK_MARGIN 64 //8 parameters of safety, I guess
51 #define JIT_FUNCMAGIC 0x214D4148 //magic function offset
53 #define JITVARS_TRACKER 0 //important: don't change this to avoid trouble
54 #define JITVARS_BASECTX 1 //important: don't change this aWOAWOGJQG I LIKE HAM
55 #define JITVARS_PROFILER 2 //profiler
56 #define JITVARS_PLUGIN 3 //sp_plugin_t
58 #define sDIMEN_MAX 5 //this must mirror what the compiler has.
60 #define GET_CONTEXT(c) ((IPluginContext *)c->vm[JITVARS_BASECTX])
62 typedef struct tracker_s
69 typedef struct funcinfo_s
75 typedef struct functracker_s
77 unsigned int num_functions;
78 unsigned int code_size;
86 CallThunk(cell_t pcode_offset)
87 : pcode_offset(pcode_offset)
92 class CompData : public ICompilation
100 bool SetOption(const char *key, const char *val);
103 cell_t cur_func; /* current func pcode offset */
105 int profile; /* profiling flags */
106 int inline_level; /* inline optimization level */
107 /* Per-compilation properties */
108 unsigned int func_idx; /* current function index */
114 Compiler(BaseRuntime *rt, cell_t pcode_offs);
117 JitFunction *emit(int *errp);
120 bool setup(cell_t pcode_offs);
121 bool emitOp(OPCODE op);
125 Label *labelAt(size_t offset);
127 bool emitNativeCall(OPCODE op);
129 void emitGenArray(bool autozero);
130 void emitCallThunks();
131 void emitCheckAddress(Register reg);
132 void emitErrorPath(Label *dest, int code);
133 void emitErrorPaths();
135 ExternalAddress cipAddr() {
136 sp_context_t *ctx = rt_->GetBaseContext()->GetCtx();
137 return ExternalAddress(&ctx->cip);
143 const sp_plugin_t *plugin_;
145 uint32_t pcode_start_;
153 Label error_heap_low_;
154 Label error_heap_min_;
155 Label error_stack_low_;
156 Label error_stack_min_;
157 Label error_divide_by_zero_;
158 Label error_memaccess_;
159 Label error_integer_overflow_;
162 ke::Vector<CallThunk *> thunks_; //:TODO: free
171 bool InitializeJIT();
173 ICompilation *StartCompilation(BaseRuntime *runtime);
174 ICompilation *StartCompilation();
175 void SetupContextVars(BaseRuntime *runtime, BaseContext *pCtx, sp_context_t *ctx);
176 void FreeContextVars(sp_context_t *ctx);
177 SPVM_NATIVE_FUNC CreateFakeNative(SPVM_FAKENATIVE_FUNC callback, void *pData);
178 void DestroyFakeNative(SPVM_NATIVE_FUNC func);
179 JitFunction *CompileFunction(BaseRuntime *runtime, cell_t pcode_offs, int *err);
180 ICompilation *ApplyOptions(ICompilation *_IN, ICompilation *_OUT);
181 int InvokeFunction(BaseRuntime *runtime, JitFunction *fn, cell_t *result);
184 ExternalAddress GetUniversalReturn() {
185 return ExternalAddress(m_pJitReturn);
187 void *AllocCode(size_t size);
188 void FreeCode(void *code);
191 void *m_pJitEntry; /* Entry function */
192 void *m_pJitReturn; /* Universal return address */
195 const Register pri = eax;
196 const Register alt = edx;
197 const Register stk = edi;
198 const Register dat = ebp;
199 const Register tmp = ecx;
200 const Register info = esi;
201 const Register frm = ebx;
209 #define AMX_INFO_FRAME offsetof(InfoVars, frm)
210 #define AMX_INFO_HEAP offsetof(InfoVars, hp)
211 #define AMX_INFO_NSTACK offsetof(InfoVars, esp)
213 extern Knight::KeCodeCache *g_pCodeCache;
216 #endif //_INCLUDE_SOURCEPAWN_JIT_X86_H_