github.com/goccy/go-jit@v0.0.0-20200514131505-ff78d45cf6af/internal/ccall/jit-rules.h (about) 1 /* 2 * jit-rules.h - Rules that define the characteristics of the back-end. 3 * 4 * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 * 6 * This file is part of the libjit library. 7 * 8 * The libjit library is free software: you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public License 10 * as published by the Free Software Foundation, either version 2.1 of 11 * the License, or (at your option) any later version. 12 * 13 * The libjit library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with the libjit library. If not, see 20 * <http://www.gnu.org/licenses/>. 21 */ 22 23 #ifndef _JIT_RULES_H 24 #define _JIT_RULES_H 25 26 #include "jit-config.h" 27 28 #ifdef __cplusplus 29 extern "C" { 30 #endif 31 32 /* 33 * Information about a register. 34 */ 35 typedef struct 36 { 37 const char *name; /* Name of the register, for debugging */ 38 short cpu_reg; /* CPU register number */ 39 short other_reg; /* Other register for a "long" pair, or -1 */ 40 int flags; /* Flags that define the register type */ 41 42 } jit_reginfo_t; 43 44 /* 45 * Register information flags. 46 */ 47 #define JIT_REG_WORD (1 << 0) /* Can be used for word values */ 48 #define JIT_REG_LONG (1 << 1) /* Can be used for long values */ 49 #define JIT_REG_FLOAT32 (1 << 2) /* Can be used for float32 values */ 50 #define JIT_REG_FLOAT64 (1 << 3) /* Can be used for float64 values */ 51 #define JIT_REG_NFLOAT (1 << 4) /* Can be used for nfloat values */ 52 #define JIT_REG_FRAME (1 << 5) /* Contains frame pointer */ 53 #define JIT_REG_STACK_PTR (1 << 6) /* Contains CPU stack pointer */ 54 #define JIT_REG_FIXED (1 << 7) /* Fixed use; not for allocation */ 55 #define JIT_REG_CALL_USED (1 << 8) /* Destroyed by a call */ 56 #define JIT_REG_IN_STACK (1 << 9) /* Middle of stack-like allocation */ 57 #define JIT_REG_GLOBAL (1 << 10) /* Candidate for global allocation */ 58 #define JIT_REG_ALL (JIT_REG_WORD | JIT_REG_LONG \ 59 | JIT_REG_FLOAT32 | JIT_REG_FLOAT64 \ 60 | JIT_REG_NFLOAT) 61 62 /* 63 * Include definitions that are specific to the backend. 64 */ 65 #if defined(JIT_BACKEND_INTERP) 66 # include "jit-rules-interp.h" 67 #elif defined(JIT_BACKEND_ALPHA) 68 # include "jit-rules-alpha.h" 69 #elif defined(JIT_BACKEND_ARM) 70 # include "jit-rules-arm.h" 71 #elif defined(JIT_BACKEND_X86) 72 # include "jit-rules-x86.h" 73 #elif defined(JIT_BACKEND_X86_64) 74 # include "jit-rules-x86-64.h" 75 #else 76 # error "unknown jit backend type" 77 #endif 78 79 /* 80 * The information blocks for all registers in the system. 81 */ 82 extern jit_reginfo_t const _jit_reg_info[JIT_NUM_REGS]; 83 84 /* 85 * Macros for getting register information 86 */ 87 88 /* Get register name. */ 89 #define jit_reg_name(reg) (_jit_reg_info[reg].name) 90 91 /* Get register flags. */ 92 #define jit_reg_flags(reg) (_jit_reg_info[reg].flags) 93 94 /* Get CPU register number for machine instruction encoding. */ 95 #define jit_reg_code(reg) (_jit_reg_info[reg].cpu_reg) 96 97 /* Given the first register of a register pair get the other one. */ 98 #define jit_reg_other_reg(reg) (_jit_reg_info[reg].other_reg) 99 100 /* Given a register find if a value of the specified type requires 101 * a register pair. Return the other register of the pair if it is 102 * required and return -1 otherwise. */ 103 #if defined(JIT_NATIVE_INT32) && !defined(JIT_BACKEND_INTERP) 104 # define jit_reg_get_pair(type,reg) _jit_reg_get_pair(type, reg) 105 #else 106 # define jit_reg_get_pair(type,reg) (-1) 107 #endif 108 109 /* 110 * Manipulate register usage masks. The backend may override these 111 * definitions if it has more registers than can fit in a "jit_uint". 112 */ 113 #if !defined(jit_regused_init) 114 115 typedef jit_uint jit_regused_t; 116 117 #define jit_regused_init (0) 118 #define jit_regused_init_used (~0) 119 120 #define jit_reg_is_used(mask,reg) (((mask) & (((jit_uint)1) << (reg))) != 0) 121 122 #define jit_reg_set_used(mask,reg) ((mask) |= (((jit_uint)1) << (reg))) 123 124 #define jit_reg_clear_used(mask,reg) ((mask) &= ~(((jit_uint)1) << (reg))) 125 126 #endif /* !defined(jit_regused_init) */ 127 128 /* 129 * Information about a register's contents. 130 */ 131 #define JIT_MAX_REG_VALUES 8 132 typedef struct jit_regcontents jit_regcontents_t; 133 struct jit_regcontents 134 { 135 /* List of values that are currently stored in this register */ 136 jit_value_t values[JIT_MAX_REG_VALUES]; 137 int num_values; 138 139 /* Current age of this register. Older registers are reclaimed first */ 140 int age; 141 142 /* Flag that indicates if this register is holding the first 143 word of a double-word long value (32-bit platforms only) */ 144 char is_long_start; 145 146 /* Flag that indicates if this register is holding the second 147 word of a double-word long value (32-bit platforms only) */ 148 char is_long_end; 149 150 /* Flag that indicates if the register holds a valid value, 151 but there are no actual "jit_value_t" objects associated */ 152 char used_for_temp; 153 }; 154 155 /* 156 * Code generation information. 157 */ 158 typedef struct jit_gencode *jit_gencode_t; 159 struct jit_gencode 160 { 161 jit_context_t context; /* Context this position is attached to */ 162 unsigned char *ptr; /* Current code pointer */ 163 unsigned char *mem_start; /* Available space start */ 164 unsigned char *mem_limit; /* Available space limit */ 165 unsigned char *code_start; /* Real code start */ 166 unsigned char *code_end; /* Real code end */ 167 jit_regused_t permanent; /* Permanently allocated global regs */ 168 jit_regused_t touched; /* All registers that were touched */ 169 jit_regused_t inhibit; /* Temporarily inhibited registers */ 170 jit_regcontents_t contents[JIT_NUM_REGS]; /* Contents of each register */ 171 int current_age; /* Current age value for registers */ 172 #ifdef JIT_REG_STACK 173 int reg_stack_top; /* Current register stack top */ 174 #endif 175 #ifdef jit_extra_gen_state 176 jit_extra_gen_state; /* CPU-specific extra information */ 177 #endif 178 void *epilog_fixup; /* Fixup list for function epilogs */ 179 int stack_changed; /* Stack top changed since entry */ 180 jit_varint_encoder_t offset_encoder; /* Bytecode offset encoder */ 181 }; 182 183 /* 184 * ELF machine type and ABI information. 185 */ 186 typedef struct jit_elf_info jit_elf_info_t; 187 struct jit_elf_info 188 { 189 int machine; 190 int abi; 191 int abi_version; 192 }; 193 194 /* 195 * External function defintions. 196 */ 197 198 /* 199 * Determine if there is sufficient space in the code cache. 200 * If not throws JIT_RESULT_CACHE_FULL exception. 201 */ 202 void _jit_gen_check_space(jit_gencode_t gen, int space); 203 204 /* 205 * Allocate a memory chunk for data. 206 */ 207 void *_jit_gen_alloc(jit_gencode_t gen, unsigned long size); 208 209 void _jit_init_backend(void); 210 void _jit_gen_get_elf_info(jit_elf_info_t *info); 211 int _jit_create_entry_insns(jit_function_t func); 212 int _jit_create_call_setup_insns 213 (jit_function_t func, jit_type_t signature, 214 jit_value_t *args, unsigned int num_args, 215 int is_nested, jit_value_t parent_frame, jit_value_t *struct_return, int flags); 216 int _jit_setup_indirect_pointer(jit_function_t func, jit_value_t value); 217 int _jit_create_call_return_insns 218 (jit_function_t func, jit_type_t signature, 219 jit_value_t *args, unsigned int num_args, 220 jit_value_t return_value, int is_nested); 221 int _jit_opcode_is_supported(int opcode); 222 void *_jit_gen_prolog(jit_gencode_t gen, jit_function_t func, void *buf); 223 void _jit_gen_epilog(jit_gencode_t gen, jit_function_t func); 224 void *_jit_gen_redirector(jit_gencode_t gen, jit_function_t func); 225 void _jit_gen_spill_reg(jit_gencode_t gen, int reg, 226 int other_reg, jit_value_t value); 227 void _jit_gen_free_reg(jit_gencode_t gen, int reg, 228 int other_reg, int value_used); 229 void _jit_gen_load_value 230 (jit_gencode_t gen, int reg, int other_reg, jit_value_t value); 231 void _jit_gen_spill_global(jit_gencode_t gen, int reg, jit_value_t value); 232 void _jit_gen_load_global(jit_gencode_t gen, int reg, jit_value_t value); 233 void _jit_gen_exch_top(jit_gencode_t gen, int reg); 234 void _jit_gen_move_top(jit_gencode_t gen, int reg); 235 void _jit_gen_spill_top(jit_gencode_t gen, int reg, jit_value_t value, int pop); 236 void _jit_gen_fix_value(jit_value_t value); 237 void _jit_gen_insn(jit_gencode_t gen, jit_function_t func, 238 jit_block_t block, jit_insn_t insn); 239 void _jit_gen_start_block(jit_gencode_t gen, jit_block_t block); 240 void _jit_gen_end_block(jit_gencode_t gen, jit_block_t block); 241 int _jit_gen_is_global_candidate(jit_type_t type); 242 243 #if defined(JIT_NATIVE_INT32) && !defined(JIT_BACKEND_INTERP) 244 int _jit_reg_get_pair(jit_type_t type, int reg); 245 #endif 246 247 /* 248 * Determine the byte number within a "jit_int" where the low 249 * order byte can be found. 250 */ 251 int _jit_int_lowest_byte(void); 252 253 /* 254 * Determine the byte number within a "jit_int" where the low 255 * order short can be found. 256 */ 257 int _jit_int_lowest_short(void); 258 259 /* 260 * Determine the byte number within a "jit_nint" where the low 261 * order byte can be found. 262 */ 263 int _jit_nint_lowest_byte(void); 264 265 /* 266 * Determine the byte number within a "jit_nint" where the low 267 * order short can be found. 268 */ 269 int _jit_nint_lowest_short(void); 270 271 /* 272 * Determine the byte number within a "jit_nint" where the low 273 * order int can be found. 274 */ 275 int _jit_nint_lowest_int(void); 276 277 #ifdef __cplusplus 278 }; 279 #endif 280 281 #endif /* _JIT_RULES_H */