sourcepawn/jit/x86/jit_x86.h
author David Anderson <dvander@alliedmods.net>
Sun Aug 11 11:30:27 2013 -0700 (2013-08-11)
changeset 3984 d94a0d3bc008
parent 3982 be7835a7c28f
child 3985 f1e2d9a7a276
permissions -rw-r--r--
Clean up INFO register structure (bug 5844 part 1, 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 "jit_function.h"
    43 #include "opcodes.h"
    44 
    45 using namespace SourcePawn;
    46 
    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
    51 
    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
    56 
    57 #define sDIMEN_MAX              5    //this must mirror what the compiler has.
    58 
    59 #define GET_CONTEXT(c)  ((IPluginContext *)c->vm[JITVARS_BASECTX])
    60 
    61 typedef struct tracker_s
    62 {
    63   size_t size; 
    64   ucell_t *pBase; 
    65   ucell_t *pCur;
    66 } tracker_t;
    67 
    68 typedef struct funcinfo_s
    69 {
    70   unsigned int magic;
    71   unsigned int index;
    72 } funcinfo_t;
    73 
    74 typedef struct functracker_s
    75 {
    76   unsigned int num_functions;
    77   unsigned int code_size;
    78 } functracker_t;
    79 
    80 struct CallThunk
    81 {
    82   Label call;
    83   cell_t pcode_offset;
    84 
    85   CallThunk(cell_t pcode_offset)
    86     : pcode_offset(pcode_offset)
    87   {
    88   }
    89 };
    90 
    91 class CompData : public ICompilation
    92 {
    93 public:
    94   CompData() 
    95   : profile(0),
    96     inline_level(0)
    97   {
    98   };
    99   bool SetOption(const char *key, const char *val);
   100   void Abort();
   101 public:
   102   cell_t cur_func;            /* current func pcode offset */
   103   /* Options */
   104   int profile;                /* profiling flags */
   105   int inline_level;           /* inline optimization level */
   106   /* Per-compilation properties */
   107   unsigned int func_idx;      /* current function index */
   108 };
   109 
   110 class Compiler
   111 {
   112  public:
   113   Compiler(BaseRuntime *rt, cell_t pcode_offs);
   114   ~Compiler();
   115 
   116   JitFunction *emit(int *errp);
   117 
   118  private:
   119   bool setup(cell_t pcode_offs);
   120   bool emitOp(OPCODE op);
   121   cell_t readCell();
   122 
   123  private:
   124   Label *labelAt(size_t offset);
   125   bool emitCall();
   126   bool emitNativeCall(OPCODE op);
   127   bool emitSwitch();
   128   void emitGenArray(bool autozero);
   129   void emitCallThunks();
   130   void emitCheckAddress(Register reg);
   131   void emitErrorPath(Label *dest, int code);
   132   void emitErrorPaths();
   133 
   134  private:
   135   AssemblerX86 masm;
   136   BaseRuntime *rt_;
   137   const sp_plugin_t *plugin_;
   138   int error_;
   139   uint32_t pcode_start_;
   140   cell_t *code_start_;
   141   cell_t *cip_;
   142   cell_t *code_end_;
   143   Label *jump_map_;
   144 
   145   // Errors
   146   Label error_bounds_;
   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_;
   154   Label extern_error_;
   155 
   156   ke::Vector<CallThunk *> thunks_; //:TODO: free
   157 };
   158 
   159 class JITX86
   160 {
   161  public:
   162   JITX86();
   163 
   164  public:
   165   bool InitializeJIT();
   166   void ShutdownJIT();
   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);
   176 
   177  public:
   178   ExternalAddress GetUniversalReturn() {
   179       return ExternalAddress(m_pJitReturn);
   180   }
   181   void *AllocCode(size_t size);
   182   void FreeCode(void *code);
   183 
   184  private:
   185   void *m_pJitEntry;         /* Entry function */
   186   void *m_pJitReturn;        /* Universal return address */
   187 };
   188 
   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;
   196 
   197 struct InfoVars {
   198     ucell_t frm;
   199     ucell_t hp;
   200     cell_t *rval;
   201     sp_context_t *ctx;
   202     uint8_t *stp;
   203     ucell_t cip;
   204     size_t data_size;
   205     uint8_t *memory;
   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_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)
   218 
   219 extern Knight::KeCodeCache *g_pCodeCache;
   220 extern JITX86 g_Jit;
   221 
   222 #endif //_INCLUDE_SOURCEPAWN_JIT_X86_H_