sourcepawn/jit/x86/jit_x86.h
author David Anderson <dvander@alliedmods.net>
Mon Aug 12 00:22:54 2013 +0100 (2013-08-12)
changeset 3990 c7fb79059d7a
parent 3989 b73dae36a0da
child 3991 a93a52306572
permissions -rw-r--r--
Eliminate InfoVars::cip (bug 5844 part 7, r=ds).
     1 /**
     2  * vim: set ts=4 sw=4 tw=99 et:
     3  * =============================================================================
     4  * SourceMod
     5  * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
     6  * =============================================================================
     7  *
     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.
    11  * 
    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
    15  * details.
    16  *
    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/>.
    19  *
    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>.
    28  *
    29  * Version: $Id$
    30  */
    31 
    32 #ifndef _INCLUDE_SOURCEPAWN_JIT_X86_H_
    33 #define _INCLUDE_SOURCEPAWN_JIT_X86_H_
    34 
    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"
    44 #include "opcodes.h"
    45 
    46 using namespace SourcePawn;
    47 
    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
    52 
    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
    57 
    58 #define sDIMEN_MAX              5    //this must mirror what the compiler has.
    59 
    60 #define GET_CONTEXT(c)  ((IPluginContext *)c->vm[JITVARS_BASECTX])
    61 
    62 typedef struct tracker_s
    63 {
    64   size_t size; 
    65   ucell_t *pBase; 
    66   ucell_t *pCur;
    67 } tracker_t;
    68 
    69 typedef struct funcinfo_s
    70 {
    71   unsigned int magic;
    72   unsigned int index;
    73 } funcinfo_t;
    74 
    75 typedef struct functracker_s
    76 {
    77   unsigned int num_functions;
    78   unsigned int code_size;
    79 } functracker_t;
    80 
    81 struct CallThunk
    82 {
    83   Label call;
    84   cell_t pcode_offset;
    85 
    86   CallThunk(cell_t pcode_offset)
    87     : pcode_offset(pcode_offset)
    88   {
    89   }
    90 };
    91 
    92 class CompData : public ICompilation
    93 {
    94 public:
    95   CompData() 
    96   : profile(0),
    97     inline_level(0)
    98   {
    99   };
   100   bool SetOption(const char *key, const char *val);
   101   void Abort();
   102 public:
   103   cell_t cur_func;            /* current func pcode offset */
   104   /* Options */
   105   int profile;                /* profiling flags */
   106   int inline_level;           /* inline optimization level */
   107   /* Per-compilation properties */
   108   unsigned int func_idx;      /* current function index */
   109 };
   110 
   111 class Compiler
   112 {
   113  public:
   114   Compiler(BaseRuntime *rt, cell_t pcode_offs);
   115   ~Compiler();
   116 
   117   JitFunction *emit(int *errp);
   118 
   119  private:
   120   bool setup(cell_t pcode_offs);
   121   bool emitOp(OPCODE op);
   122   cell_t readCell();
   123 
   124  private:
   125   Label *labelAt(size_t offset);
   126   bool emitCall();
   127   bool emitNativeCall(OPCODE op);
   128   bool emitSwitch();
   129   void emitGenArray(bool autozero);
   130   void emitCallThunks();
   131   void emitCheckAddress(Register reg);
   132   void emitErrorPath(Label *dest, int code);
   133   void emitErrorPaths();
   134 
   135   ExternalAddress cipAddr() {
   136     sp_context_t *ctx = rt_->GetBaseContext()->GetCtx();
   137     return ExternalAddress(&ctx->cip);
   138   }
   139 
   140  private:
   141   AssemblerX86 masm;
   142   BaseRuntime *rt_;
   143   const sp_plugin_t *plugin_;
   144   int error_;
   145   uint32_t pcode_start_;
   146   cell_t *code_start_;
   147   cell_t *cip_;
   148   cell_t *code_end_;
   149   Label *jump_map_;
   150 
   151   // Errors
   152   Label error_bounds_;
   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_;
   160   Label extern_error_;
   161 
   162   ke::Vector<CallThunk *> thunks_; //:TODO: free
   163 };
   164 
   165 class JITX86
   166 {
   167  public:
   168   JITX86();
   169 
   170  public:
   171   bool InitializeJIT();
   172   void ShutdownJIT();
   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);
   182 
   183  public:
   184   ExternalAddress GetUniversalReturn() {
   185       return ExternalAddress(m_pJitReturn);
   186   }
   187   void *AllocCode(size_t size);
   188   void FreeCode(void *code);
   189 
   190  private:
   191   void *m_pJitEntry;         /* Entry function */
   192   void *m_pJitReturn;        /* Universal return address */
   193 };
   194 
   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;
   202 
   203 struct InfoVars {
   204     ucell_t frm;
   205     ucell_t hp;
   206     void *esp;
   207 };
   208 
   209 #define AMX_INFO_FRAME          offsetof(InfoVars, frm)
   210 #define AMX_INFO_HEAP           offsetof(InfoVars, hp)
   211 #define AMX_INFO_NSTACK         offsetof(InfoVars, esp)
   212 
   213 extern Knight::KeCodeCache *g_pCodeCache;
   214 extern JITX86 g_Jit;
   215 
   216 #endif //_INCLUDE_SOURCEPAWN_JIT_X86_H_