1  /* Table of relaxations for Xtensa assembly.
       2     Copyright (C) 2003-2023 Free Software Foundation, Inc.
       3  
       4     This file is part of GAS, the GNU Assembler.
       5  
       6     GAS is free software; you can redistribute it and/or modify
       7     it under the terms of the GNU General Public License as published by
       8     the Free Software Foundation; either version 3, or (at your option)
       9     any later version.
      10  
      11     GAS is distributed in the hope that it will be useful,
      12     but WITHOUT ANY WARRANTY; without even the implied warranty of
      13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14     GNU General Public License for more details.
      15  
      16     You should have received a copy of the GNU General Public License
      17     along with GAS; see the file COPYING.  If not, write to
      18     the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
      19     MA 02110-1301, USA.  */
      20  
      21  #ifndef XTENSA_RELAX_H
      22  #define XTENSA_RELAX_H
      23  
      24  #include "xtensa-isa.h"
      25  
      26  
      27  /* Data structures for the table-driven relaxations for Xtensa processors.
      28     See xtensa-relax.c for details.  */
      29  
      30  typedef struct transition_list TransitionList;
      31  typedef struct transition_table TransitionTable;
      32  typedef struct transition_rule TransitionRule;
      33  typedef struct precondition_list PreconditionList;
      34  typedef struct precondition Precondition;
      35  
      36  typedef struct req_or_option_list ReqOrOptionList;
      37  typedef struct req_or_option_list ReqOrOption;
      38  typedef struct req_option_list ReqOptionList;
      39  typedef struct req_option_list ReqOption;
      40  
      41  struct transition_table
      42  {
      43    int num_opcodes;
      44    TransitionList **table;	/* Possible transitions for each opcode.  */
      45  };
      46  
      47  struct transition_list
      48  {
      49    TransitionRule *rule;
      50    TransitionList *next;
      51  };
      52  
      53  struct precondition_list
      54  {
      55    Precondition *precond;
      56    PreconditionList *next;
      57  };
      58  
      59  
      60  /* The required options for a rule are represented with a two-level
      61     structure, with leaf expressions combined by logical ORs at the
      62     lower level, and the results then combined by logical ANDs at the
      63     top level.  The AND terms are linked in a list, and each one can
      64     contain a reference to a list of OR terms.  The leaf expressions,
      65     i.e., the OR options, can be negated by setting the is_true field
      66     to FALSE.  There are two classes of leaf expressions: (1) those
      67     that are properties of the Xtensa configuration and can be
      68     evaluated once when building the tables, and (2) those that depend
      69     of the state of directives or other settings that may vary during
      70     the assembly.  The following expressions may be used in group (1):
      71  
      72     IsaUse*:	Xtensa configuration settings.
      73     realnop:	TRUE if the instruction set includes a NOP instruction.
      74  
      75     There are currently no expressions in group (2), but they are still
      76     supported since there is a good chance they'll be needed again for
      77     something.  */
      78  
      79  struct req_option_list
      80  {
      81    ReqOrOptionList *or_option_terms;
      82    ReqOptionList *next;
      83  };
      84  
      85  struct req_or_option_list
      86  {
      87    char *option_name;
      88    bool is_true;
      89    ReqOrOptionList *next;
      90  };
      91  
      92  /* Operand types and constraints on operands:  */
      93  
      94  typedef enum op_type
      95  {
      96    OP_CONSTANT,
      97    OP_OPERAND,
      98    OP_OPERAND_LOW8,		/* Sign-extended low 8 bits of immed.  */
      99    OP_OPERAND_HI24S,		/* High 24 bits of immed,
     100  				   plus 0x100 if low 8 bits are signed.  */
     101    OP_OPERAND_F32MINUS,		/* 32 - immed.  */
     102    OP_OPERAND_LOW16U,		/* Low 16 bits of immed.  */
     103    OP_OPERAND_HI16U,		/* High 16 bits of immed.  */
     104    OP_LITERAL,
     105    OP_FREEREG,
     106    OP_LABEL
     107  } OpType;
     108  
     109  typedef enum cmp_op
     110  {
     111    OP_EQUAL,
     112    OP_NOTEQUAL,
     113  } CmpOp;
     114  
     115  struct precondition
     116  {
     117    CmpOp cmp;
     118    int op_num;
     119    OpType typ;			/* CONSTANT: op_data is a constant.
     120  				   OPERAND: operand op_num must equal op_data.
     121  				   Cannot be LITERAL or LABEL.  */
     122    int op_data;
     123  };
     124  
     125  
     126  typedef struct build_op BuildOp;
     127  
     128  struct build_op
     129  {
     130    int op_num;
     131    OpType typ;
     132    unsigned op_data;		/* CONSTANT: op_data is the value to encode.
     133  				   OPERAND: op_data is the field in the
     134  				   source instruction to take the value from
     135  				   and encode in the op_num field here.
     136  				   LITERAL: op_data is field in the source
     137  				   instruction that is stored in the literal.
     138  				   LABEL: unused.  */
     139    BuildOp *next;
     140  };
     141  
     142  typedef struct build_instr BuildInstr;
     143  
     144  typedef enum instr_type
     145  {
     146    INSTR_INSTR,
     147    INSTR_LITERAL_DEF,
     148    INSTR_LABEL_DEF
     149  } InstrType;
     150  
     151  struct build_instr
     152  {
     153    InstrType typ;
     154    xtensa_opcode opcode;		/* Unused for LITERAL_DEF or LABEL_DEF.  */
     155    BuildOp *ops;
     156    BuildInstr *next;
     157  };
     158  
     159  struct transition_rule
     160  {
     161    xtensa_opcode opcode;
     162    PreconditionList *conditions;
     163    ReqOptionList *options;
     164    BuildInstr *to_instr;
     165  };
     166  
     167  typedef int (*transition_cmp_fn) (const TransitionRule *,
     168  				  const TransitionRule *);
     169  
     170  extern TransitionTable *xg_build_simplify_table (transition_cmp_fn);
     171  extern TransitionTable *xg_build_widen_table (transition_cmp_fn);
     172  
     173  extern bool xg_has_userdef_op_fn (OpType);
     174  extern long xg_apply_userdef_op_fn (OpType, long);
     175  
     176  enum flix_level
     177  {
     178    FLIX_ALL,
     179    FLIX_NO_GENERATE,
     180    FLIX_NONE
     181  };
     182  
     183  extern enum flix_level produce_flix;
     184  
     185  #endif /* !XTENSA_RELAX_H */