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 */