github.com/goccy/go-jit@v0.0.0-20200514131505-ff78d45cf6af/internal/ccall/jit-reg-alloc.h (about)

     1  /*
     2   * jit-reg-alloc.h - Register allocation routines for the JIT.
     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_REG_ALLOC_H
    24  #define	_JIT_REG_ALLOC_H
    25  
    26  #include "jit-rules.h"
    27  #include "jit-reg-class.h"
    28  
    29  #ifdef	__cplusplus
    30  extern	"C" {
    31  #endif
    32  
    33  /*
    34   * The maximum number of values per instruction.
    35   */
    36  #define _JIT_REGS_VALUE_MAX		3
    37  
    38  /*
    39   * The maximum number of temporaries per instruction.
    40   */
    41  #define _JIT_REGS_SCRATCH_MAX		6
    42  
    43  /*
    44   * Flags for _jit_regs_init().
    45   */
    46  #define _JIT_REGS_TERNARY		0x0001
    47  #define _JIT_REGS_BRANCH		0x0002
    48  #define _JIT_REGS_COPY			0x0004
    49  #define _JIT_REGS_FREE_DEST		0x0008
    50  #define _JIT_REGS_COMMUTATIVE		0x0010
    51  #define _JIT_REGS_STACK			0x0020
    52  #define _JIT_REGS_X87_ARITH		0x0040
    53  #define _JIT_REGS_REVERSIBLE		0X0080
    54  
    55  /*
    56   * Flags for _jit_regs_init_dest(), _jit_regs_init_value1(), and
    57   * _jit_regs_init_value2().
    58   */
    59  #define _JIT_REGS_CLOBBER		0x0001
    60  #define _JIT_REGS_EARLY_CLOBBER		0x0002
    61  
    62  /*
    63   * Flags returned by _jit_regs_select_insn().
    64   */
    65  #define _JIT_REGS_NO_POP		0x0001
    66  #define _JIT_REGS_FLIP_ARGS		0x0002
    67  #define _JIT_REGS_REVERSE		0x0004
    68  
    69  /*
    70   * Contains register assignment data for single operand.
    71   */
    72  typedef struct
    73  {
    74  	jit_value_t	value;
    75  	int		reg;
    76  	int		other_reg;
    77  	int		stack_reg;
    78  	_jit_regclass_t	*regclass;
    79  	unsigned	live : 1;
    80  	unsigned	used : 1;
    81  	unsigned	clobber : 1;
    82  	unsigned	early_clobber : 1;
    83  	unsigned	duplicate : 1;
    84  	unsigned	thrash : 1;
    85  	unsigned	store : 1;
    86  	unsigned	load : 1;
    87  	unsigned	copy : 1;
    88  	unsigned	kill : 1;
    89  
    90  } _jit_regdesc_t;
    91  
    92  /*
    93   * Contains scratch register assignment data.
    94   */
    95  typedef struct
    96  {
    97  	int		reg;
    98  	_jit_regclass_t	*regclass;
    99  
   100  } _jit_scratch_t;
   101  
   102  /*
   103   * Contains register assignment data for instruction.
   104   */
   105  typedef struct
   106  {
   107  	_jit_regdesc_t	descs[_JIT_REGS_VALUE_MAX];
   108  	_jit_scratch_t	scratch[_JIT_REGS_SCRATCH_MAX];
   109  	int		num_scratch;
   110  
   111  	unsigned	ternary : 1;
   112  	unsigned	branch : 1;
   113  	unsigned	copy : 1;
   114  	unsigned	commutative : 1;
   115  	unsigned	free_dest : 1;
   116  
   117  #ifdef JIT_REG_STACK
   118  	unsigned	on_stack : 1;
   119  	unsigned	x87_arith : 1;
   120  	unsigned	reversible : 1;
   121  
   122  	unsigned	no_pop : 1;
   123  	unsigned	flip_args : 1;
   124  #endif
   125  
   126  	/* The input value index that is going to be overwritten
   127  	   by the destination value. For ordinary binary and unary
   128  	   opcodes it is equal to 1, for notes and three-address
   129  	   opcodes it is equal to 0, and for some x87 instructions
   130  	   it could be equal to 2.  */
   131  	int		dest_input_index;
   132  
   133  	jit_regused_t	assigned;
   134  	jit_regused_t	clobber;
   135  
   136  #ifdef JIT_REG_STACK
   137  	int		wanted_stack_count;
   138  	int		loaded_stack_count;
   139  #endif
   140  
   141  } _jit_regs_t;
   142  
   143  int _jit_regs_lookup(char *name);
   144  void _jit_regs_alloc_global(jit_gencode_t gen, jit_function_t func);
   145  void _jit_regs_init_for_block(jit_gencode_t gen);
   146  void _jit_regs_spill_all(jit_gencode_t gen);
   147  void _jit_regs_set_incoming(jit_gencode_t gen, int reg, jit_value_t value);
   148  void _jit_regs_set_outgoing(jit_gencode_t gen, int reg, jit_value_t value);
   149  void _jit_regs_clear_all_outgoing(jit_gencode_t gen);
   150  void _jit_regs_force_out(jit_gencode_t gen, jit_value_t value, int is_dest);
   151  int _jit_regs_load_value(jit_gencode_t gen, jit_value_t value, int destroy, int used_again);
   152  
   153  void _jit_regs_init(jit_gencode_t gen, _jit_regs_t *regs, int flags);
   154  
   155  void _jit_regs_init_dest(_jit_regs_t *regs, jit_insn_t insn,
   156  			 int flags, _jit_regclass_t *regclass);
   157  void _jit_regs_init_value1(_jit_regs_t *regs, jit_insn_t insn,
   158  			   int flags, _jit_regclass_t *regclass);
   159  void _jit_regs_init_value2(_jit_regs_t *regs, jit_insn_t insn,
   160  			   int flags, _jit_regclass_t *regclass);
   161  void _jit_regs_add_scratch(_jit_regs_t *regs, _jit_regclass_t *regclass);
   162  
   163  void _jit_regs_set_dest(jit_gencode_t gen, _jit_regs_t *regs, int reg, int other_reg);
   164  void _jit_regs_set_value1(jit_gencode_t gen, _jit_regs_t *regs, int reg, int other_reg);
   165  void _jit_regs_set_value2(jit_gencode_t gen, _jit_regs_t *regs, int reg, int other_reg);
   166  void _jit_regs_set_scratch(jit_gencode_t gen, _jit_regs_t *regs, int index, int reg);
   167  
   168  void _jit_regs_clobber(_jit_regs_t *regs, int reg);
   169  void _jit_regs_clobber_class(jit_gencode_t gen, _jit_regs_t *regs, _jit_regclass_t *regclass);
   170  void _jit_regs_clobber_all(jit_gencode_t gen, _jit_regs_t *regs);
   171  
   172  void _jit_regs_assign(jit_gencode_t gen, _jit_regs_t *regs);
   173  void _jit_regs_gen(jit_gencode_t gen, _jit_regs_t *regs);
   174  #ifdef JIT_REG_STACK
   175  int _jit_regs_select(_jit_regs_t *regs);
   176  #endif
   177  
   178  void _jit_regs_commit(jit_gencode_t gen, _jit_regs_t *regs);
   179  
   180  int _jit_regs_get_dest(_jit_regs_t *regs);
   181  int _jit_regs_get_value1(_jit_regs_t *regs);
   182  int _jit_regs_get_value2(_jit_regs_t *regs);
   183  int _jit_regs_get_dest_other(_jit_regs_t *regs);
   184  int _jit_regs_get_value1_other(_jit_regs_t *regs);
   185  int _jit_regs_get_value2_other(_jit_regs_t *regs);
   186  int _jit_regs_get_scratch(_jit_regs_t *regs, int index);
   187  
   188  void _jit_regs_begin(jit_gencode_t gen, _jit_regs_t *regs, int space);
   189  
   190  #ifdef	__cplusplus
   191  };
   192  #endif
   193  
   194  #endif	/* _JIT_REG_ALLOC_H */