1 /* Table of relaxations for Xtensa assembly.
2    Copyright 2003, 2004 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 2, 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   bfd_boolean is_true;
89   ReqOrOptionList *next;
90 };
91 
92 /* Operand types and constraints on operands:  */
93 
94 typedef enum op_type OpType;
95 typedef enum cmp_op CmpOp;
96 
97 enum op_type
98 {
99   OP_CONSTANT,
100   OP_OPERAND,
101   OP_OPERAND_LOW8,		/* Sign-extended low 8 bits of immed.  */
102   OP_OPERAND_HI24S,		/* High 24 bits of immed,
103 				   plus 0x100 if low 8 bits are signed.  */
104   OP_OPERAND_F32MINUS,		/* 32 - immed.  */
105   OP_OPERAND_LOW16U,		/* Low 16 bits of immed.  */
106   OP_OPERAND_HI16U,		/* High 16 bits of immed.  */
107   OP_LITERAL,
108   OP_LABEL
109 };
110 
111 enum cmp_op
112 {
113   OP_EQUAL,
114   OP_NOTEQUAL,
115 };
116 
117 struct precondition
118 {
119   CmpOp cmp;
120   int op_num;
121   OpType typ;			/* CONSTANT: op_data is a constant.
122 				   OPERAND: operand op_num must equal op_data.
123 				   Cannot be LITERAL or LABEL.  */
124   int op_data;
125 };
126 
127 
128 typedef struct build_op BuildOp;
129 
130 struct build_op
131 {
132   int op_num;
133   OpType typ;
134   unsigned op_data;		/* CONSTANT: op_data is the value to encode.
135 				   OPERAND: op_data is the field in the
136 				   source instruction to take the value from
137 				   and encode in the op_num field here.
138 				   LITERAL or LABEL: op_data is the ordinal
139 				   that identifies the appropriate one, i.e.,
140 				   there can be more than one literal or
141 				   label in an expansion.  */
142   BuildOp *next;
143 };
144 
145 typedef struct build_instr BuildInstr;
146 typedef enum instr_type InstrType;
147 
148 enum instr_type
149 {
150   INSTR_INSTR,
151   INSTR_LITERAL_DEF,
152   INSTR_LABEL_DEF
153 };
154 
155 struct build_instr
156 {
157   InstrType typ;
158   unsigned id;			/* LITERAL_DEF or LABEL_DEF: an ordinal to
159 				   identify which one.  */
160   xtensa_opcode opcode;		/* Unused for LITERAL_DEF or LABEL_DEF.  */
161   BuildOp *ops;
162   BuildInstr *next;
163 };
164 
165 struct transition_rule
166 {
167   xtensa_opcode opcode;
168   PreconditionList *conditions;
169   ReqOptionList *options;
170   BuildInstr *to_instr;
171 };
172 
173 typedef int (*transition_cmp_fn) (const TransitionRule *,
174 				  const TransitionRule *);
175 
176 extern TransitionTable *xg_build_simplify_table (transition_cmp_fn);
177 extern TransitionTable *xg_build_widen_table (transition_cmp_fn);
178 
179 extern bfd_boolean xg_has_userdef_op_fn (OpType);
180 extern long xg_apply_userdef_op_fn (OpType, long);
181 
182 #endif /* !XTENSA_RELAX_H */
183