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);
139 ExternalAddress hpAddr() {
140 sp_context_t *ctx = rt_->GetBaseContext()->GetCtx();
141 return ExternalAddress(&ctx->hp);
143 ExternalAddress frmAddr() {
144 sp_context_t *ctx = rt_->GetBaseContext()->GetCtx();
145 return ExternalAddress(&ctx->frm);
151 const sp_plugin_t *plugin_;
153 uint32_t pcode_start_;
161 Label error_heap_low_;
162 Label error_heap_min_;
163 Label error_stack_low_;
164 Label error_stack_min_;
165 Label error_divide_by_zero_;
166 Label error_memaccess_;
167 Label error_integer_overflow_;
170 ke::Vector<CallThunk *> thunks_; //:TODO: free
179 bool InitializeJIT();
181 ICompilation *StartCompilation(BaseRuntime *runtime);
182 ICompilation *StartCompilation();
183 void SetupContextVars(BaseRuntime *runtime, BaseContext *pCtx, sp_context_t *ctx);
184 void FreeContextVars(sp_context_t *ctx);
185 SPVM_NATIVE_FUNC CreateFakeNative(SPVM_FAKENATIVE_FUNC callback, void *pData);
186 void DestroyFakeNative(SPVM_NATIVE_FUNC func);
187 JitFunction *CompileFunction(BaseRuntime *runtime, cell_t pcode_offs, int *err);
188 ICompilation *ApplyOptions(ICompilation *_IN, ICompilation *_OUT);
189 int InvokeFunction(BaseRuntime *runtime, JitFunction *fn, cell_t *result);
192 ExternalAddress GetUniversalReturn() {
193 return ExternalAddress(m_pJitReturn);
195 void *AllocCode(size_t size);
196 void FreeCode(void *code);
199 void *m_pJitEntry; /* Entry function */
200 void *m_pJitReturn; /* Universal return address */
203 const Register pri = eax;
204 const Register alt = edx;
205 const Register stk = edi;
206 const Register dat = esi;
207 const Register tmp = ecx;
208 const Register frm = ebx;
210 extern Knight::KeCodeCache *g_pCodeCache;
213 #endif //_INCLUDE_SOURCEPAWN_JIT_X86_H_