1 /* Table of relaxations for Xtensa assembly.
2    Copyright (C) 2003-2014 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 /* This file contains the code for generating runtime data structures
22    for relaxation pattern matching from statically specified strings.
23    Each action contains an instruction pattern to match and
24    preconditions for the match as well as an expansion if the pattern
25    matches.  The preconditions can specify that two operands are the
26    same or an operand is a specific constant or register.  The expansion
27    uses the bound variables from the pattern to specify that specific
28    operands from the pattern should be used in the result.
29 
30    The code determines whether the condition applies to a constant or
31    a register depending on the type of the operand.  You may get
32    unexpected results if you don't match the rule against the operand
33    type correctly.
34 
35    The patterns match a language like:
36 
37    INSN_PATTERN ::= INSN_TEMPL ( '|' PRECOND )* ( '?' OPTIONPRED )*
38    INSN_TEMPL   ::= OPCODE ' ' [ OPERAND (',' OPERAND)* ]
39    OPCODE       ::=  id
40    OPERAND      ::= CONSTANT | VARIABLE | SPECIALFN '(' VARIABLE ')'
41    SPECIALFN    ::= 'HI24S' | 'F32MINUS' | 'LOW8'
42                     | 'HI16' | 'LOW16'
43    VARIABLE     ::= '%' id
44    PRECOND      ::= OPERAND CMPOP OPERAND
45    CMPOP        ::= '==' | '!='
46    OPTIONPRED   ::= OPTIONNAME ('+' OPTIONNAME)
47    OPTIONNAME   ::= '"' id '"'
48 
49    The replacement language
50    INSN_REPL      ::= INSN_LABEL_LIT ( ';' INSN_LABEL_LIT )*
51    INSN_LABEL_LIT ::= INSN_TEMPL
52                       | 'LABEL'
53                       | 'LITERAL' VARIABLE
54 
55    The operands in a PRECOND must be constants or variables bound by
56    the INSN_PATTERN.
57 
58    The configuration options define a predicate on the availability of
59    options which must be TRUE for this rule to be valid.  Examples are
60    requiring "density" for replacements with density instructions,
61    requiring "const16" for replacements that require const16
62    instructions, etc.  The names are interpreted by the assembler to a
63    truth value for a particular frag.
64 
65    The operands in the INSN_REPL must be constants, variables bound in
66    the associated INSN_PATTERN, special variables that are bound in
67    the INSN_REPL by LABEL or LITERAL definitions, or special value
68    manipulation functions.
69 
70    A simple example of a replacement pattern:
71    {"movi.n %as,%imm", "movi %as,%imm"} would convert the narrow
72    movi.n instruction to the wide movi instruction.
73 
74    A more complex example of a branch around:
75    {"beqz %as,%label", "bnez %as,%LABEL;j %label;LABEL"}
76    would convert a branch to a negated branch to the following instruction
77    with a jump to the original label.
78 
79    An Xtensa-specific example that generates a literal:
80    {"movi %at,%imm", "LITERAL %imm; l32r %at,%LITERAL"}
81    will convert a movi instruction to an l32r of a literal
82    literal defined in the literal pool.
83 
84    Even more complex is a conversion of a load with immediate offset
85    to a load of a freshly generated literal, an explicit add and
86    a load with 0 offset.  This transformation is only valid, though
87    when the first and second operands are not the same as specified
88    by the "| %at!=%as" precondition clause.
89    {"l32i %at,%as,%imm | %at!=%as",
90    "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l32i %at,%at,0"}
91 
92    There is special case for loop instructions here, but because we do
93    not currently have the ability to represent the difference of two
94    symbols, the conversion requires special code in the assembler to
95    write the operands of the addi/addmi pair representing the
96    difference of the old and new loop end label.  */
97 
98 #include "as.h"
99 #include "xtensa-isa.h"
100 #include "xtensa-relax.h"
101 #include <stddef.h>
102 #include "xtensa-config.h"
103 
104 #ifndef XCHAL_HAVE_WIDE_BRANCHES
105 #define XCHAL_HAVE_WIDE_BRANCHES 0
106 #endif
107 
108 /* Imported from bfd.  */
109 extern xtensa_isa xtensa_default_isa;
110 
111 /* The opname_list is a small list of names that we use for opcode and
112    operand variable names to simplify ownership of these commonly used
113    strings.  Strings entered in the table can be compared by pointer
114    equality.  */
115 
116 typedef struct opname_list_struct opname_list;
117 typedef opname_list opname_e;
118 
119 struct opname_list_struct
120 {
121   char *opname;
122   opname_list *next;
123 };
124 
125 static opname_list *local_opnames = NULL;
126 
127 
128 /* The "opname_map" and its element structure "opname_map_e" are used
129    for binding an operand number to a name or a constant.  */
130 
131 typedef struct opname_map_e_struct opname_map_e;
132 typedef struct opname_map_struct opname_map;
133 
134 struct opname_map_e_struct
135 {
136   const char *operand_name;	/* If null, then use constant_value.  */
137   int operand_num;
138   unsigned constant_value;
139   opname_map_e *next;
140 };
141 
142 struct opname_map_struct
143 {
144   opname_map_e *head;
145   opname_map_e **tail;
146 };
147 
148 /* The "precond_list" and its element structure "precond_e" represents
149    explicit preconditions comparing operand variables and constants.
150    In the "precond_e" structure, a variable is identified by the name
151    in the "opname" field.   If that field is NULL, then the operand
152    is the constant in field "opval".  */
153 
154 typedef struct precond_e_struct precond_e;
155 typedef struct precond_list_struct precond_list;
156 
157 struct precond_e_struct
158 {
159   const char *opname1;
160   unsigned opval1;
161   CmpOp cmpop;
162   const char *opname2;
163   unsigned opval2;
164   precond_e *next;
165 };
166 
167 struct precond_list_struct
168 {
169   precond_e *head;
170   precond_e **tail;
171 };
172 
173 
174 /* The insn_templ represents the INSN_TEMPL instruction template.  It
175    is an opcode name with a list of operands.  These are used for
176    instruction patterns and replacement patterns.  */
177 
178 typedef struct insn_templ_struct insn_templ;
179 struct insn_templ_struct
180 {
181   const char *opcode_name;
182   opname_map operand_map;
183 };
184 
185 
186 /* The insn_pattern represents an INSN_PATTERN instruction pattern.
187    It is an instruction template with preconditions that specify when
188    it actually matches a given instruction.  */
189 
190 typedef struct insn_pattern_struct insn_pattern;
191 struct insn_pattern_struct
192 {
193   insn_templ t;
194   precond_list preconds;
195   ReqOptionList *options;
196 };
197 
198 
199 /* The "insn_repl" and associated element structure "insn_repl_e"
200    instruction replacement list is a list of
201    instructions/LITERALS/LABELS with constant operands or operands
202    with names bound to the operand names in the associated pattern.  */
203 
204 typedef struct insn_repl_e_struct insn_repl_e;
205 struct insn_repl_e_struct
206 {
207   insn_templ t;
208   insn_repl_e *next;
209 };
210 
211 typedef struct insn_repl_struct insn_repl;
212 struct insn_repl_struct
213 {
214   insn_repl_e *head;
215   insn_repl_e **tail;
216 };
217 
218 
219 /* The split_rec is a vector of allocated char * pointers.  */
220 
221 typedef struct split_rec_struct split_rec;
222 struct split_rec_struct
223 {
224   char **vec;
225   int count;
226 };
227 
228 /* The "string_pattern_pair" is a set of pairs containing instruction
229    patterns and replacement strings.  */
230 
231 typedef struct string_pattern_pair_struct string_pattern_pair;
232 struct string_pattern_pair_struct
233 {
234   const char *pattern;
235   const char *replacement;
236 };
237 
238 
239 /* The widen_spec_list is a list of valid substitutions that generate
240    wider representations.  These are generally used to specify
241    replacements for instructions whose immediates do not fit their
242    encodings.  A valid transition may require multiple steps of
243    one-to-one instruction replacements with a final multiple
244    instruction replacement.  As an example, here are the transitions
245    required to replace an 'addi.n' with an 'addi', 'addmi'.
246 
247      addi.n a4, 0x1010
248      => addi a4, 0x1010
249      => addmi a4, 0x1010
250      => addmi a4, 0x1000, addi a4, 0x10.
251 
252    See the comments in xg_assembly_relax for some important details
253    regarding how these chains must be built.  */
254 
255 static string_pattern_pair widen_spec_list[] =
256 {
257   {"add.n %ar,%as,%at ? IsaUseDensityInstruction", "add %ar,%as,%at"},
258   {"addi.n %ar,%as,%imm ? IsaUseDensityInstruction", "addi %ar,%as,%imm"},
259   {"beqz.n %as,%label ? IsaUseDensityInstruction", "beqz %as,%label"},
260   {"bnez.n %as,%label ? IsaUseDensityInstruction", "bnez %as,%label"},
261   {"l32i.n %at,%as,%imm ? IsaUseDensityInstruction", "l32i %at,%as,%imm"},
262   {"mov.n %at,%as ? IsaUseDensityInstruction", "or %at,%as,%as"},
263   {"movi.n %as,%imm ? IsaUseDensityInstruction", "movi %as,%imm"},
264   {"nop.n ? IsaUseDensityInstruction ? realnop", "nop"},
265   {"nop.n ? IsaUseDensityInstruction ? no-realnop", "or 1,1,1"},
266   {"ret.n %as ? IsaUseDensityInstruction", "ret %as"},
267   {"retw.n %as ? IsaUseDensityInstruction", "retw %as"},
268   {"s32i.n %at,%as,%imm ? IsaUseDensityInstruction", "s32i %at,%as,%imm"},
269   {"srli %at,%as,%imm", "extui %at,%as,%imm,F32MINUS(%imm)"},
270   {"slli %ar,%as,0", "or %ar,%as,%as"},
271 
272   /* Widening with literals or const16.  */
273   {"movi %at,%imm ? IsaUseL32R ",
274    "LITERAL %imm; l32r %at,%LITERAL"},
275   {"movi %at,%imm ? IsaUseConst16",
276    "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm)"},
277 
278   {"addi %ar,%as,%imm", "addmi %ar,%as,%imm"},
279   /* LOW8 is the low 8 bits of the Immed
280      MID8S is the middle 8 bits of the Immed */
281   {"addmi %ar,%as,%imm", "addmi %ar,%as,HI24S(%imm); addi %ar,%ar,LOW8(%imm)"},
282 
283   /* In the end convert to either an l32r or const16.  */
284   {"addmi %ar,%as,%imm | %ar!=%as ? IsaUseL32R",
285    "LITERAL %imm; l32r %ar,%LITERAL; add %ar,%as,%ar"},
286   {"addmi %ar,%as,%imm | %ar!=%as ? IsaUseConst16",
287    "const16 %ar,HI16U(%imm); const16 %ar,LOW16U(%imm); add %ar,%as,%ar"},
288 
289   /* Widening the load instructions with too-large immediates */
290   {"l8ui %at,%as,%imm | %at!=%as ? IsaUseL32R",
291    "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l8ui %at,%at,0"},
292   {"l16si %at,%as,%imm | %at!=%as ? IsaUseL32R",
293    "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l16si %at,%at,0"},
294   {"l16ui %at,%as,%imm | %at!=%as ? IsaUseL32R",
295    "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l16ui %at,%at,0"},
296   {"l32i %at,%as,%imm | %at!=%as ? IsaUseL32R",
297    "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l32i %at,%at,0"},
298 
299   /* Widening load instructions with const16s.  */
300   {"l8ui %at,%as,%imm | %at!=%as ? IsaUseConst16",
301    "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l8ui %at,%at,0"},
302   {"l16si %at,%as,%imm | %at!=%as ? IsaUseConst16",
303    "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l16si %at,%at,0"},
304   {"l16ui %at,%as,%imm | %at!=%as ? IsaUseConst16",
305    "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l16ui %at,%at,0"},
306   {"l32i %at,%as,%imm | %at!=%as ? IsaUseConst16",
307    "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l32i %at,%at,0"},
308 
309   /* This is only PART of the loop instruction.  In addition,
310      hardcoded into its use is a modification of the final operand in
311      the instruction in bytes 9 and 12.  */
312   {"loop %as,%label | %as!=1 ? IsaUseLoops",
313    "loop %as,%LABEL;"
314    "rsr.lend    %as;"		/* LEND */
315    "wsr.lbeg    %as;"		/* LBEG */
316    "addi    %as, %as, 0;"	/* lo8(%label-%LABEL1) */
317    "addmi   %as, %as, 0;"	/* mid8(%label-%LABEL1) */
318    "wsr.lend    %as;"
319    "isync;"
320    "rsr.lcount    %as;"		/* LCOUNT */
321    "addi    %as, %as, 1;"	/* density -> addi.n %as, %as, 1 */
322    "LABEL"},
323   {"loopgtz %as,%label | %as!=1 ? IsaUseLoops",
324    "beqz    %as,%label;"
325    "bltz    %as,%label;"
326    "loopgtz %as,%LABEL;"
327    "rsr.lend    %as;"		/* LEND */
328    "wsr.lbeg    %as;"		/* LBEG */
329    "addi    %as, %as, 0;"	/* lo8(%label-%LABEL1) */
330    "addmi   %as, %as, 0;"	/* mid8(%label-%LABEL1) */
331    "wsr.lend    %as;"
332    "isync;"
333    "rsr.lcount    %as;"		/* LCOUNT */
334    "addi    %as, %as, 1;"	/* density -> addi.n %as, %as, 1 */
335    "LABEL"},
336   {"loopnez %as,%label | %as!=1 ? IsaUseLoops",
337    "beqz     %as,%label;"
338    "loopnez %as,%LABEL;"
339    "rsr.lend    %as;"		/* LEND */
340    "wsr.lbeg    %as;"		/* LBEG */
341    "addi    %as, %as, 0;"	/* lo8(%label-%LABEL1) */
342    "addmi   %as, %as, 0;"	/* mid8(%label-%LABEL1) */
343    "wsr.lend    %as;"
344    "isync;"
345    "rsr.lcount    %as;"		/* LCOUNT */
346    "addi    %as, %as, 1;"	/* density -> addi.n %as, %as, 1 */
347    "LABEL"},
348 
349   /* Relaxing to wide branches.  Order is important here.  With wide
350      branches, there is more than one correct relaxation for an
351      out-of-range branch.  Put the wide branch relaxations first in the
352      table since they are more efficient than the branch-around
353      relaxations.  */
354 
355   {"beqz %as,%label ? IsaUseWideBranches", "WIDE.beqz %as,%label"},
356   {"bnez %as,%label ? IsaUseWideBranches", "WIDE.bnez %as,%label"},
357   {"bgez %as,%label ? IsaUseWideBranches", "WIDE.bgez %as,%label"},
358   {"bltz %as,%label ? IsaUseWideBranches", "WIDE.bltz %as,%label"},
359   {"beqi %as,%imm,%label ? IsaUseWideBranches", "WIDE.beqi %as,%imm,%label"},
360   {"bnei %as,%imm,%label ? IsaUseWideBranches", "WIDE.bnei %as,%imm,%label"},
361   {"bgei %as,%imm,%label ? IsaUseWideBranches", "WIDE.bgei %as,%imm,%label"},
362   {"blti %as,%imm,%label ? IsaUseWideBranches", "WIDE.blti %as,%imm,%label"},
363   {"bgeui %as,%imm,%label ? IsaUseWideBranches", "WIDE.bgeui %as,%imm,%label"},
364   {"bltui %as,%imm,%label ? IsaUseWideBranches", "WIDE.bltui %as,%imm,%label"},
365   {"bbci %as,%imm,%label ? IsaUseWideBranches", "WIDE.bbci %as,%imm,%label"},
366   {"bbsi %as,%imm,%label ? IsaUseWideBranches", "WIDE.bbsi %as,%imm,%label"},
367   {"beq %as,%at,%label ? IsaUseWideBranches", "WIDE.beq %as,%at,%label"},
368   {"bne %as,%at,%label ? IsaUseWideBranches", "WIDE.bne %as,%at,%label"},
369   {"bge %as,%at,%label ? IsaUseWideBranches", "WIDE.bge %as,%at,%label"},
370   {"blt %as,%at,%label ? IsaUseWideBranches", "WIDE.blt %as,%at,%label"},
371   {"bgeu %as,%at,%label ? IsaUseWideBranches", "WIDE.bgeu %as,%at,%label"},
372   {"bltu %as,%at,%label ? IsaUseWideBranches", "WIDE.bltu %as,%at,%label"},
373   {"bany %as,%at,%label ? IsaUseWideBranches", "WIDE.bany %as,%at,%label"},
374   {"bnone %as,%at,%label ? IsaUseWideBranches", "WIDE.bnone %as,%at,%label"},
375   {"ball %as,%at,%label ? IsaUseWideBranches", "WIDE.ball %as,%at,%label"},
376   {"bnall %as,%at,%label ? IsaUseWideBranches", "WIDE.bnall %as,%at,%label"},
377   {"bbc %as,%at,%label ? IsaUseWideBranches", "WIDE.bbc %as,%at,%label"},
378   {"bbs %as,%at,%label ? IsaUseWideBranches", "WIDE.bbs %as,%at,%label"},
379 
380   /* Widening branch comparisons eq/ne to zero.  Prefer relaxing to narrow
381      branches if the density option is available.  */
382   {"beqz %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%LABEL;j %label;LABEL"},
383   {"bnez %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%LABEL;j %label;LABEL"},
384   {"beqz %as,%label", "bnez %as,%LABEL;j %label;LABEL"},
385   {"bnez %as,%label", "beqz %as,%LABEL;j %label;LABEL"},
386   {"WIDE.beqz %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%LABEL;j %label;LABEL"},
387   {"WIDE.bnez %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%LABEL;j %label;LABEL"},
388   {"WIDE.beqz %as,%label", "bnez %as,%LABEL;j %label;LABEL"},
389   {"WIDE.bnez %as,%label", "beqz %as,%LABEL;j %label;LABEL"},
390 
391   /* Widening expect-taken branches.  */
392   {"beqzt %as,%label ? IsaUsePredictedBranches", "bnez %as,%LABEL;j %label;LABEL"},
393   {"bnezt %as,%label ? IsaUsePredictedBranches", "beqz %as,%LABEL;j %label;LABEL"},
394   {"beqt %as,%at,%label ? IsaUsePredictedBranches", "bne %as,%at,%LABEL;j %label;LABEL"},
395   {"bnet %as,%at,%label ? IsaUsePredictedBranches", "beq %as,%at,%LABEL;j %label;LABEL"},
396 
397   /* Widening branches from the Xtensa boolean option.  */
398   {"bt %bs,%label ? IsaUseBooleans", "bf %bs,%LABEL;j %label;LABEL"},
399   {"bf %bs,%label ? IsaUseBooleans", "bt %bs,%LABEL;j %label;LABEL"},
400 
401   /* Other branch-around-jump widenings.  */
402   {"bgez %as,%label", "bltz %as,%LABEL;j %label;LABEL"},
403   {"bltz %as,%label", "bgez %as,%LABEL;j %label;LABEL"},
404   {"beqi %as,%imm,%label", "bnei %as,%imm,%LABEL;j %label;LABEL"},
405   {"bnei %as,%imm,%label", "beqi %as,%imm,%LABEL;j %label;LABEL"},
406   {"bgei %as,%imm,%label", "blti %as,%imm,%LABEL;j %label;LABEL"},
407   {"blti %as,%imm,%label", "bgei %as,%imm,%LABEL;j %label;LABEL"},
408   {"bgeui %as,%imm,%label", "bltui %as,%imm,%LABEL;j %label;LABEL"},
409   {"bltui %as,%imm,%label", "bgeui %as,%imm,%LABEL;j %label;LABEL"},
410   {"bbci %as,%imm,%label", "bbsi %as,%imm,%LABEL;j %label;LABEL"},
411   {"bbsi %as,%imm,%label", "bbci %as,%imm,%LABEL;j %label;LABEL"},
412   {"beq %as,%at,%label", "bne %as,%at,%LABEL;j %label;LABEL"},
413   {"bne %as,%at,%label", "beq %as,%at,%LABEL;j %label;LABEL"},
414   {"bge %as,%at,%label", "blt %as,%at,%LABEL;j %label;LABEL"},
415   {"blt %as,%at,%label", "bge %as,%at,%LABEL;j %label;LABEL"},
416   {"bgeu %as,%at,%label", "bltu %as,%at,%LABEL;j %label;LABEL"},
417   {"bltu %as,%at,%label", "bgeu %as,%at,%LABEL;j %label;LABEL"},
418   {"bany %as,%at,%label", "bnone %as,%at,%LABEL;j %label;LABEL"},
419   {"bnone %as,%at,%label", "bany %as,%at,%LABEL;j %label;LABEL"},
420   {"ball %as,%at,%label", "bnall %as,%at,%LABEL;j %label;LABEL"},
421   {"bnall %as,%at,%label", "ball %as,%at,%LABEL;j %label;LABEL"},
422   {"bbc %as,%at,%label", "bbs %as,%at,%LABEL;j %label;LABEL"},
423   {"bbs %as,%at,%label", "bbc %as,%at,%LABEL;j %label;LABEL"},
424 
425   {"WIDE.bgez %as,%label", "bltz %as,%LABEL;j %label;LABEL"},
426   {"WIDE.bltz %as,%label", "bgez %as,%LABEL;j %label;LABEL"},
427   {"WIDE.beqi %as,%imm,%label", "bnei %as,%imm,%LABEL;j %label;LABEL"},
428   {"WIDE.bnei %as,%imm,%label", "beqi %as,%imm,%LABEL;j %label;LABEL"},
429   {"WIDE.bgei %as,%imm,%label", "blti %as,%imm,%LABEL;j %label;LABEL"},
430   {"WIDE.blti %as,%imm,%label", "bgei %as,%imm,%LABEL;j %label;LABEL"},
431   {"WIDE.bgeui %as,%imm,%label", "bltui %as,%imm,%LABEL;j %label;LABEL"},
432   {"WIDE.bltui %as,%imm,%label", "bgeui %as,%imm,%LABEL;j %label;LABEL"},
433   {"WIDE.bbci %as,%imm,%label", "bbsi %as,%imm,%LABEL;j %label;LABEL"},
434   {"WIDE.bbsi %as,%imm,%label", "bbci %as,%imm,%LABEL;j %label;LABEL"},
435   {"WIDE.beq %as,%at,%label", "bne %as,%at,%LABEL;j %label;LABEL"},
436   {"WIDE.bne %as,%at,%label", "beq %as,%at,%LABEL;j %label;LABEL"},
437   {"WIDE.bge %as,%at,%label", "blt %as,%at,%LABEL;j %label;LABEL"},
438   {"WIDE.blt %as,%at,%label", "bge %as,%at,%LABEL;j %label;LABEL"},
439   {"WIDE.bgeu %as,%at,%label", "bltu %as,%at,%LABEL;j %label;LABEL"},
440   {"WIDE.bltu %as,%at,%label", "bgeu %as,%at,%LABEL;j %label;LABEL"},
441   {"WIDE.bany %as,%at,%label", "bnone %as,%at,%LABEL;j %label;LABEL"},
442   {"WIDE.bnone %as,%at,%label", "bany %as,%at,%LABEL;j %label;LABEL"},
443   {"WIDE.ball %as,%at,%label", "bnall %as,%at,%LABEL;j %label;LABEL"},
444   {"WIDE.bnall %as,%at,%label", "ball %as,%at,%LABEL;j %label;LABEL"},
445   {"WIDE.bbc %as,%at,%label", "bbs %as,%at,%LABEL;j %label;LABEL"},
446   {"WIDE.bbs %as,%at,%label", "bbc %as,%at,%LABEL;j %label;LABEL"},
447 
448   /* Expanding calls with literals.  */
449   {"call0 %label,%ar0 ? IsaUseL32R",
450    "LITERAL %label; l32r a0,%LITERAL; callx0 a0,%ar0"},
451   {"call4 %label,%ar4 ? IsaUseL32R",
452    "LITERAL %label; l32r a4,%LITERAL; callx4 a4,%ar4"},
453   {"call8 %label,%ar8 ? IsaUseL32R",
454    "LITERAL %label; l32r a8,%LITERAL; callx8 a8,%ar8"},
455   {"call12 %label,%ar12 ? IsaUseL32R",
456    "LITERAL %label; l32r a12,%LITERAL; callx12 a12,%ar12"},
457 
458   /* Expanding calls with const16.  */
459   {"call0 %label,%ar0 ? IsaUseConst16",
460    "const16 a0,HI16U(%label); const16 a0,LOW16U(%label); callx0 a0,%ar0"},
461   {"call4 %label,%ar4 ? IsaUseConst16",
462    "const16 a4,HI16U(%label); const16 a4,LOW16U(%label); callx4 a4,%ar4"},
463   {"call8 %label,%ar8 ? IsaUseConst16",
464    "const16 a8,HI16U(%label); const16 a8,LOW16U(%label); callx8 a8,%ar8"},
465   {"call12 %label,%ar12 ? IsaUseConst16",
466    "const16 a12,HI16U(%label); const16 a12,LOW16U(%label); callx12 a12,%ar12"},
467 
468   /* Expanding j.l with literals.  */
469   {"j %label ? FREEREG ? IsaUseL32R",
470    "LITERAL %label; l32r FREEREG,%LITERAL; jx FREEREG"},
471   /* Expanding j.l with const16.  */
472   {"j %label ? FREEREG ? IsaUseConst16",
473    "const16 FREEREG,HI16U(%label); const16 FREEREG,LOW16U(%label); jx FREEREG"},
474 };
475 
476 #define WIDEN_COUNT (sizeof (widen_spec_list) / sizeof (string_pattern_pair))
477 
478 
479 /* The simplify_spec_list specifies simplifying transformations that
480    will reduce the instruction width or otherwise simplify an
481    instruction.  These are usually applied before relaxation in the
482    assembler.  It is always legal to simplify.  Even for "addi as, 0",
483    the "addi.n as, 0" will eventually be widened back to an "addi 0"
484    after the widening table is applied.  Note: The usage of this table
485    has changed somewhat so that it is entirely specific to "narrowing"
486    instructions to use the density option.  This table is not used at
487    all when the density option is not available.  */
488 
489 string_pattern_pair simplify_spec_list[] =
490 {
491   {"add %ar,%as,%at ? IsaUseDensityInstruction", "add.n %ar,%as,%at"},
492   {"addi.n %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"},
493   {"addi %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"},
494   {"addi %ar,%as,%imm ? IsaUseDensityInstruction", "addi.n %ar,%as,%imm"},
495   {"addmi %ar,%as,%imm ? IsaUseDensityInstruction", "addi.n %ar,%as,%imm"},
496   {"beqz %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%label"},
497   {"bnez %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%label"},
498   {"l32i %at,%as,%imm ? IsaUseDensityInstruction", "l32i.n %at,%as,%imm"},
499   {"movi %as,%imm ? IsaUseDensityInstruction", "movi.n %as,%imm"},
500   {"nop ? realnop ? IsaUseDensityInstruction", "nop.n"},
501   {"or %ar,%as,%at | %ar==%as | %as==%at ? IsaUseDensityInstruction", "nop.n"},
502   {"or %ar,%as,%at | %ar!=%as | %as==%at ? IsaUseDensityInstruction", "mov.n %ar,%as"},
503   {"ret %as ? IsaUseDensityInstruction", "ret.n %as"},
504   {"retw %as ? IsaUseDensityInstruction", "retw.n %as"},
505   {"s32i %at,%as,%imm ? IsaUseDensityInstruction", "s32i.n %at,%as,%imm"},
506   {"slli %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"}
507 };
508 
509 #define SIMPLIFY_COUNT \
510   (sizeof (simplify_spec_list) / sizeof (string_pattern_pair))
511 
512 
513 /* Externally visible functions.  */
514 
515 extern bfd_boolean xg_has_userdef_op_fn (OpType);
516 extern long xg_apply_userdef_op_fn (OpType, long);
517 
518 
519 static void
append_transition(TransitionTable * tt,xtensa_opcode opcode,TransitionRule * t,transition_cmp_fn cmp)520 append_transition (TransitionTable *tt,
521 		   xtensa_opcode opcode,
522 		   TransitionRule *t,
523 		   transition_cmp_fn cmp)
524 {
525   TransitionList *tl = (TransitionList *) xmalloc (sizeof (TransitionList));
526   TransitionList *prev;
527   TransitionList **t_p;
528   gas_assert (tt != NULL);
529   gas_assert (opcode < tt->num_opcodes);
530 
531   prev = tt->table[opcode];
532   tl->rule = t;
533   tl->next = NULL;
534   if (prev == NULL)
535     {
536       tt->table[opcode] = tl;
537       return;
538     }
539 
540   for (t_p = &tt->table[opcode]; (*t_p) != NULL; t_p = &(*t_p)->next)
541     {
542       if (cmp && cmp (t, (*t_p)->rule) < 0)
543 	{
544 	  /* Insert it here.  */
545 	  tl->next = *t_p;
546 	  *t_p = tl;
547 	  return;
548 	}
549     }
550   (*t_p) = tl;
551 }
552 
553 
554 static void
append_condition(TransitionRule * tr,Precondition * cond)555 append_condition (TransitionRule *tr, Precondition *cond)
556 {
557   PreconditionList *pl =
558     (PreconditionList *) xmalloc (sizeof (PreconditionList));
559   PreconditionList *prev = tr->conditions;
560   PreconditionList *nxt;
561 
562   pl->precond = cond;
563   pl->next = NULL;
564   if (prev == NULL)
565     {
566       tr->conditions = pl;
567       return;
568     }
569   nxt = prev->next;
570   while (nxt != NULL)
571     {
572       prev = nxt;
573       nxt = nxt->next;
574     }
575   prev->next = pl;
576 }
577 
578 
579 static void
append_value_condition(TransitionRule * tr,CmpOp cmp,unsigned op1,unsigned op2)580 append_value_condition (TransitionRule *tr,
581 			CmpOp cmp,
582 			unsigned op1,
583 			unsigned op2)
584 {
585   Precondition *cond = (Precondition *) xmalloc (sizeof (Precondition));
586 
587   cond->cmp = cmp;
588   cond->op_num = op1;
589   cond->typ = OP_OPERAND;
590   cond->op_data = op2;
591   append_condition (tr, cond);
592 }
593 
594 
595 static void
append_constant_value_condition(TransitionRule * tr,CmpOp cmp,unsigned op1,unsigned cnst)596 append_constant_value_condition (TransitionRule *tr,
597 				 CmpOp cmp,
598 				 unsigned op1,
599 				 unsigned cnst)
600 {
601   Precondition *cond = (Precondition *) xmalloc (sizeof (Precondition));
602 
603   cond->cmp = cmp;
604   cond->op_num = op1;
605   cond->typ = OP_CONSTANT;
606   cond->op_data = cnst;
607   append_condition (tr, cond);
608 }
609 
610 
611 static void
append_build_insn(TransitionRule * tr,BuildInstr * bi)612 append_build_insn (TransitionRule *tr, BuildInstr *bi)
613 {
614   BuildInstr *prev = tr->to_instr;
615   BuildInstr *nxt;
616 
617   bi->next = NULL;
618   if (prev == NULL)
619     {
620       tr->to_instr = bi;
621       return;
622     }
623   nxt = prev->next;
624   while (nxt != 0)
625     {
626       prev = nxt;
627       nxt = prev->next;
628     }
629   prev->next = bi;
630 }
631 
632 
633 static void
append_op(BuildInstr * bi,BuildOp * b_op)634 append_op (BuildInstr *bi, BuildOp *b_op)
635 {
636   BuildOp *prev = bi->ops;
637   BuildOp *nxt;
638 
639   if (prev == NULL)
640     {
641       bi->ops = b_op;
642       return;
643     }
644   nxt = prev->next;
645   while (nxt != NULL)
646     {
647       prev = nxt;
648       nxt = nxt->next;
649     }
650   prev->next = b_op;
651 }
652 
653 
654 static void
append_literal_op(BuildInstr * bi,unsigned op1,unsigned src_op)655 append_literal_op (BuildInstr *bi, unsigned op1, unsigned src_op)
656 {
657   BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
658 
659   b_op->op_num = op1;
660   b_op->typ = OP_LITERAL;
661   b_op->op_data = src_op;
662   b_op->next = NULL;
663   append_op (bi, b_op);
664 }
665 
666 
667 static void
append_label_op(BuildInstr * bi,unsigned op1)668 append_label_op (BuildInstr *bi, unsigned op1)
669 {
670   BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
671 
672   b_op->op_num = op1;
673   b_op->typ = OP_LABEL;
674   b_op->op_data = 0;
675   b_op->next = NULL;
676   append_op (bi, b_op);
677 }
678 
679 
680 static void
append_constant_op(BuildInstr * bi,unsigned op1,unsigned cnst)681 append_constant_op (BuildInstr *bi, unsigned op1, unsigned cnst)
682 {
683   BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
684 
685   b_op->op_num = op1;
686   b_op->typ = OP_CONSTANT;
687   b_op->op_data = cnst;
688   b_op->next = NULL;
689   append_op (bi, b_op);
690 }
691 
692 
693 static void
append_field_op(BuildInstr * bi,unsigned op1,unsigned src_op)694 append_field_op (BuildInstr *bi, unsigned op1, unsigned src_op)
695 {
696   BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
697 
698   b_op->op_num = op1;
699   b_op->typ = OP_OPERAND;
700   b_op->op_data = src_op;
701   b_op->next = NULL;
702   append_op (bi, b_op);
703 }
704 
705 
706 /* These could be generated but are not currently.  */
707 
708 static void
append_user_fn_field_op(BuildInstr * bi,unsigned op1,OpType typ,unsigned src_op)709 append_user_fn_field_op (BuildInstr *bi,
710 			 unsigned op1,
711 			 OpType typ,
712 			 unsigned src_op)
713 {
714   BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
715 
716   b_op->op_num = op1;
717   b_op->typ = typ;
718   b_op->op_data = src_op;
719   b_op->next = NULL;
720   append_op (bi, b_op);
721 }
722 
723 
724 /* These operand functions are the semantics of user-defined
725    operand functions.  */
726 
727 static long
operand_function_HI24S(long a)728 operand_function_HI24S (long a)
729 {
730   if (a & 0x80)
731     return (a & (~0xff)) + 0x100;
732   else
733     return (a & (~0xff));
734 }
735 
736 
737 static long
operand_function_F32MINUS(long a)738 operand_function_F32MINUS (long a)
739 {
740   return (32 - a);
741 }
742 
743 
744 static long
operand_function_LOW8(long a)745 operand_function_LOW8 (long a)
746 {
747   if (a & 0x80)
748     return (a & 0xff) | ~0xff;
749   else
750     return (a & 0xff);
751 }
752 
753 
754 static long
operand_function_LOW16U(long a)755 operand_function_LOW16U (long a)
756 {
757   return (a & 0xffff);
758 }
759 
760 
761 static long
operand_function_HI16U(long a)762 operand_function_HI16U (long a)
763 {
764   unsigned long b = a & 0xffff0000;
765   return (long) (b >> 16);
766 }
767 
768 
769 bfd_boolean
xg_has_userdef_op_fn(OpType op)770 xg_has_userdef_op_fn (OpType op)
771 {
772   switch (op)
773     {
774     case OP_OPERAND_F32MINUS:
775     case OP_OPERAND_LOW8:
776     case OP_OPERAND_HI24S:
777     case OP_OPERAND_LOW16U:
778     case OP_OPERAND_HI16U:
779       return TRUE;
780     default:
781       break;
782     }
783   return FALSE;
784 }
785 
786 
787 long
xg_apply_userdef_op_fn(OpType op,long a)788 xg_apply_userdef_op_fn (OpType op, long a)
789 {
790   switch (op)
791     {
792     case OP_OPERAND_F32MINUS:
793       return operand_function_F32MINUS (a);
794     case OP_OPERAND_LOW8:
795       return operand_function_LOW8 (a);
796     case OP_OPERAND_HI24S:
797       return operand_function_HI24S (a);
798     case OP_OPERAND_LOW16U:
799       return operand_function_LOW16U (a);
800     case OP_OPERAND_HI16U:
801       return operand_function_HI16U (a);
802     default:
803       break;
804     }
805   return FALSE;
806 }
807 
808 
809 /* Generate a transition table.  */
810 
811 static const char *
enter_opname_n(const char * name,int len)812 enter_opname_n (const char *name, int len)
813 {
814   opname_e *op;
815 
816   for (op = local_opnames; op != NULL; op = op->next)
817     {
818       if (strlen (op->opname) == (unsigned) len
819 	  && strncmp (op->opname, name, len) == 0)
820 	return op->opname;
821     }
822   op = (opname_e *) xmalloc (sizeof (opname_e));
823   op->opname = (char *) xmalloc (len + 1);
824   strncpy (op->opname, name, len);
825   op->opname[len] = '\0';
826   return op->opname;
827 }
828 
829 
830 static const char *
enter_opname(const char * name)831 enter_opname (const char *name)
832 {
833   opname_e *op;
834 
835   for (op = local_opnames; op != NULL; op = op->next)
836     {
837       if (strcmp (op->opname, name) == 0)
838 	return op->opname;
839     }
840   op = (opname_e *) xmalloc (sizeof (opname_e));
841   op->opname = xstrdup (name);
842   return op->opname;
843 }
844 
845 
846 static void
init_opname_map(opname_map * m)847 init_opname_map (opname_map *m)
848 {
849   m->head = NULL;
850   m->tail = &m->head;
851 }
852 
853 
854 static void
clear_opname_map(opname_map * m)855 clear_opname_map (opname_map *m)
856 {
857   opname_map_e *e;
858 
859   while (m->head != NULL)
860     {
861       e = m->head;
862       m->head = e->next;
863       free (e);
864     }
865   m->tail = &m->head;
866 }
867 
868 
869 static bfd_boolean
same_operand_name(const opname_map_e * m1,const opname_map_e * m2)870 same_operand_name (const opname_map_e *m1, const opname_map_e *m2)
871 {
872   if (m1->operand_name == NULL || m1->operand_name == NULL)
873     return FALSE;
874   return (m1->operand_name == m2->operand_name);
875 }
876 
877 
878 static opname_map_e *
get_opmatch(opname_map * map,const char * operand_name)879 get_opmatch (opname_map *map, const char *operand_name)
880 {
881   opname_map_e *m;
882 
883   for (m = map->head; m != NULL; m = m->next)
884     {
885       if (strcmp (m->operand_name, operand_name) == 0)
886 	return m;
887     }
888   return NULL;
889 }
890 
891 
892 static bfd_boolean
op_is_constant(const opname_map_e * m1)893 op_is_constant (const opname_map_e *m1)
894 {
895   return (m1->operand_name == NULL);
896 }
897 
898 
899 static unsigned
op_get_constant(const opname_map_e * m1)900 op_get_constant (const opname_map_e *m1)
901 {
902   gas_assert (m1->operand_name == NULL);
903   return m1->constant_value;
904 }
905 
906 
907 static void
init_precond_list(precond_list * l)908 init_precond_list (precond_list *l)
909 {
910   l->head = NULL;
911   l->tail = &l->head;
912 }
913 
914 
915 static void
clear_precond_list(precond_list * l)916 clear_precond_list (precond_list *l)
917 {
918   precond_e *e;
919 
920   while (l->head != NULL)
921     {
922       e = l->head;
923       l->head = e->next;
924       free (e);
925     }
926   l->tail = &l->head;
927 }
928 
929 
930 static void
init_insn_templ(insn_templ * t)931 init_insn_templ (insn_templ *t)
932 {
933   t->opcode_name = NULL;
934   init_opname_map (&t->operand_map);
935 }
936 
937 
938 static void
clear_insn_templ(insn_templ * t)939 clear_insn_templ (insn_templ *t)
940 {
941   clear_opname_map (&t->operand_map);
942 }
943 
944 
945 static void
init_insn_pattern(insn_pattern * p)946 init_insn_pattern (insn_pattern *p)
947 {
948   init_insn_templ (&p->t);
949   init_precond_list (&p->preconds);
950   p->options = NULL;
951 }
952 
953 
954 static void
clear_insn_pattern(insn_pattern * p)955 clear_insn_pattern (insn_pattern *p)
956 {
957   clear_insn_templ (&p->t);
958   clear_precond_list (&p->preconds);
959 }
960 
961 
962 static void
init_insn_repl(insn_repl * r)963 init_insn_repl (insn_repl *r)
964 {
965   r->head = NULL;
966   r->tail = &r->head;
967 }
968 
969 
970 static void
clear_insn_repl(insn_repl * r)971 clear_insn_repl (insn_repl *r)
972 {
973   insn_repl_e *e;
974 
975   while (r->head != NULL)
976     {
977       e = r->head;
978       r->head = e->next;
979       clear_insn_templ (&e->t);
980     }
981   r->tail = &r->head;
982 }
983 
984 
985 static int
insn_templ_operand_count(const insn_templ * t)986 insn_templ_operand_count (const insn_templ *t)
987 {
988   int i = 0;
989   const opname_map_e *op;
990 
991   for (op = t->operand_map.head; op != NULL; op = op->next, i++)
992     ;
993   return i;
994 }
995 
996 
997 /* Convert a string to a number.  E.G.: parse_constant("10", &num) */
998 
999 static bfd_boolean
parse_constant(const char * in,unsigned * val_p)1000 parse_constant (const char *in, unsigned *val_p)
1001 {
1002   unsigned val = 0;
1003   const char *p;
1004 
1005   if (in == NULL)
1006     return FALSE;
1007   p = in;
1008 
1009   while (*p != '\0')
1010     {
1011       if (*p >= '0' && *p <= '9')
1012 	val = val * 10 + (*p - '0');
1013       else
1014 	return FALSE;
1015       ++p;
1016     }
1017   *val_p = val;
1018   return TRUE;
1019 }
1020 
1021 
1022 static bfd_boolean
parse_special_fn(const char * name,const char ** fn_name_p,const char ** arg_name_p)1023 parse_special_fn (const char *name,
1024 		  const char **fn_name_p,
1025 		  const char **arg_name_p)
1026 {
1027   char *p_start;
1028   const char *p_end;
1029 
1030   p_start = strchr (name, '(');
1031   if (p_start == NULL)
1032     return FALSE;
1033 
1034   p_end = strchr (p_start, ')');
1035 
1036   if (p_end == NULL)
1037     return FALSE;
1038 
1039   if (p_end[1] != '\0')
1040     return FALSE;
1041 
1042   *fn_name_p = enter_opname_n (name, p_start - name);
1043   *arg_name_p = enter_opname_n (p_start + 1, p_end - p_start - 1);
1044   return TRUE;
1045 }
1046 
1047 
1048 static const char *
skip_white(const char * p)1049 skip_white (const char *p)
1050 {
1051   if (p == NULL)
1052     return p;
1053   while (*p == ' ')
1054     ++p;
1055   return p;
1056 }
1057 
1058 
1059 static void
trim_whitespace(char * in)1060 trim_whitespace (char *in)
1061 {
1062   char *last_white = NULL;
1063   char *p = in;
1064 
1065   while (p && *p != '\0')
1066     {
1067       while (*p == ' ')
1068 	{
1069 	  if (last_white == NULL)
1070 	    last_white = p;
1071 	  p++;
1072 	}
1073       if (*p != '\0')
1074 	{
1075 	  last_white = NULL;
1076 	  p++;
1077 	}
1078     }
1079   if (last_white)
1080     *last_white = '\0';
1081 }
1082 
1083 
1084 /* Split a string into component strings where "c" is the
1085    delimiter.  Place the result in the split_rec.  */
1086 
1087 static void
split_string(split_rec * rec,const char * in,char c,bfd_boolean elide_whitespace)1088 split_string (split_rec *rec,
1089 	      const char *in,
1090 	      char c,
1091 	      bfd_boolean elide_whitespace)
1092 {
1093   int cnt = 0;
1094   int i;
1095   const char *p = in;
1096 
1097   while (p != NULL && *p != '\0')
1098     {
1099       cnt++;
1100       p = strchr (p, c);
1101       if (p)
1102 	p++;
1103     }
1104   rec->count = cnt;
1105   rec->vec = NULL;
1106 
1107   if (rec->count == 0)
1108     return;
1109 
1110   rec->vec = (char **) xmalloc (sizeof (char *) * cnt);
1111   for (i = 0; i < cnt; i++)
1112     rec->vec[i] = 0;
1113 
1114   p = in;
1115   for (i = 0; i < cnt; i++)
1116     {
1117       const char *q;
1118       int len;
1119 
1120       q = p;
1121       if (elide_whitespace)
1122 	q = skip_white (q);
1123 
1124       p = strchr (q, c);
1125       if (p == NULL)
1126 	rec->vec[i] = xstrdup (q);
1127       else
1128 	{
1129 	  len = p - q;
1130 	  rec->vec[i] = (char *) xmalloc (sizeof (char) * (len + 1));
1131 	  strncpy (rec->vec[i], q, len);
1132 	  rec->vec[i][len] = '\0';
1133 	  p++;
1134 	}
1135 
1136       if (elide_whitespace)
1137 	trim_whitespace (rec->vec[i]);
1138     }
1139 }
1140 
1141 
1142 static void
clear_split_rec(split_rec * rec)1143 clear_split_rec (split_rec *rec)
1144 {
1145   int i;
1146 
1147   for (i = 0; i < rec->count; i++)
1148     free (rec->vec[i]);
1149 
1150   if (rec->count > 0)
1151     free (rec->vec);
1152 }
1153 
1154 
1155 /* Initialize a split record.  The split record must be initialized
1156    before split_string is called.  */
1157 
1158 static void
init_split_rec(split_rec * rec)1159 init_split_rec (split_rec *rec)
1160 {
1161   rec->vec = NULL;
1162   rec->count = 0;
1163 }
1164 
1165 
1166 /* Parse an instruction template like "insn op1, op2, op3".  */
1167 
1168 static bfd_boolean
parse_insn_templ(const char * s,insn_templ * t)1169 parse_insn_templ (const char *s, insn_templ *t)
1170 {
1171   const char *p = s;
1172   int insn_name_len;
1173   split_rec oprec;
1174   int i;
1175 
1176   /* First find the first whitespace.  */
1177 
1178   init_split_rec (&oprec);
1179 
1180   p = skip_white (p);
1181   insn_name_len = strcspn (s, " ");
1182   if (insn_name_len == 0)
1183     return FALSE;
1184 
1185   init_insn_templ (t);
1186   t->opcode_name = enter_opname_n (p, insn_name_len);
1187 
1188   p = p + insn_name_len;
1189 
1190   /* Split by ',' and skip beginning and trailing whitespace.  */
1191   split_string (&oprec, p, ',', TRUE);
1192 
1193   for (i = 0; i < oprec.count; i++)
1194     {
1195       const char *opname = oprec.vec[i];
1196       opname_map_e *e = (opname_map_e *) xmalloc (sizeof (opname_map_e));
1197       e->next = NULL;
1198       e->operand_name = NULL;
1199       e->constant_value = 0;
1200       e->operand_num = i;
1201 
1202       /* If it begins with a number, assume that it is a number.  */
1203       if (opname && opname[0] >= '0' && opname[0] <= '9')
1204 	{
1205 	  unsigned val;
1206 
1207 	  if (parse_constant (opname, &val))
1208 	    e->constant_value = val;
1209 	  else
1210 	    {
1211 	      free (e);
1212 	      clear_split_rec (&oprec);
1213 	      clear_insn_templ (t);
1214 	      return FALSE;
1215 	    }
1216 	}
1217       else
1218 	e->operand_name = enter_opname (oprec.vec[i]);
1219 
1220       *t->operand_map.tail = e;
1221       t->operand_map.tail = &e->next;
1222     }
1223   clear_split_rec (&oprec);
1224   return TRUE;
1225 }
1226 
1227 
1228 static bfd_boolean
parse_precond(const char * s,precond_e * precond)1229 parse_precond (const char *s, precond_e *precond)
1230 {
1231   /* All preconditions are currently of the form:
1232      a == b or a != b or a == k (where k is a constant).
1233      Later we may use some special functions like DENSITY == 1
1234      to identify when density is available.  */
1235 
1236   const char *p = s;
1237   int len;
1238   precond->opname1 = NULL;
1239   precond->opval1 = 0;
1240   precond->cmpop = OP_EQUAL;
1241   precond->opname2 = NULL;
1242   precond->opval2 = 0;
1243   precond->next = NULL;
1244 
1245   p = skip_white (p);
1246 
1247   len = strcspn (p, " !=");
1248 
1249   if (len == 0)
1250     return FALSE;
1251 
1252   precond->opname1 = enter_opname_n (p, len);
1253   p = p + len;
1254   p = skip_white (p);
1255 
1256   /* Check for "==" and "!=".  */
1257   if (strncmp (p, "==", 2) == 0)
1258     precond->cmpop = OP_EQUAL;
1259   else if (strncmp (p, "!=", 2) == 0)
1260     precond->cmpop = OP_NOTEQUAL;
1261   else
1262     return FALSE;
1263 
1264   p = p + 2;
1265   p = skip_white (p);
1266 
1267   /* No trailing whitespace from earlier parsing.  */
1268   if (p[0] >= '0' && p[0] <= '9')
1269     {
1270       unsigned val;
1271       if (parse_constant (p, &val))
1272 	precond->opval2 = val;
1273       else
1274 	return FALSE;
1275     }
1276   else
1277     precond->opname2 = enter_opname (p);
1278   return TRUE;
1279 }
1280 
1281 
1282 static void
clear_req_or_option_list(ReqOrOption ** r_p)1283 clear_req_or_option_list (ReqOrOption **r_p)
1284 {
1285   if (*r_p == NULL)
1286     return;
1287 
1288   free ((*r_p)->option_name);
1289   clear_req_or_option_list (&(*r_p)->next);
1290   *r_p = NULL;
1291 }
1292 
1293 
1294 static void
clear_req_option_list(ReqOption ** r_p)1295 clear_req_option_list (ReqOption **r_p)
1296 {
1297   if (*r_p == NULL)
1298     return;
1299 
1300   clear_req_or_option_list (&(*r_p)->or_option_terms);
1301   clear_req_option_list (&(*r_p)->next);
1302   *r_p = NULL;
1303 }
1304 
1305 
1306 static ReqOrOption *
clone_req_or_option_list(ReqOrOption * req_or_option)1307 clone_req_or_option_list (ReqOrOption *req_or_option)
1308 {
1309   ReqOrOption *new_req_or_option;
1310 
1311   if (req_or_option == NULL)
1312     return NULL;
1313 
1314   new_req_or_option = (ReqOrOption *) xmalloc (sizeof (ReqOrOption));
1315   new_req_or_option->option_name = xstrdup (req_or_option->option_name);
1316   new_req_or_option->is_true = req_or_option->is_true;
1317   new_req_or_option->next = NULL;
1318   new_req_or_option->next = clone_req_or_option_list (req_or_option->next);
1319   return new_req_or_option;
1320 }
1321 
1322 
1323 static ReqOption *
clone_req_option_list(ReqOption * req_option)1324 clone_req_option_list (ReqOption *req_option)
1325 {
1326   ReqOption *new_req_option;
1327 
1328   if (req_option == NULL)
1329     return NULL;
1330 
1331   new_req_option = (ReqOption *) xmalloc (sizeof (ReqOption));
1332   new_req_option->or_option_terms = NULL;
1333   new_req_option->next = NULL;
1334   new_req_option->or_option_terms =
1335     clone_req_or_option_list (req_option->or_option_terms);
1336   new_req_option->next = clone_req_option_list (req_option->next);
1337   return new_req_option;
1338 }
1339 
1340 
1341 static bfd_boolean
parse_option_cond(const char * s,ReqOption * option)1342 parse_option_cond (const char *s, ReqOption *option)
1343 {
1344   int i;
1345   split_rec option_term_rec;
1346 
1347   /* All option or conditions are of the form:
1348      optionA + no-optionB + ...
1349      "Ands" are divided by "?".  */
1350 
1351   init_split_rec (&option_term_rec);
1352   split_string (&option_term_rec, s, '+', TRUE);
1353 
1354   if (option_term_rec.count == 0)
1355     {
1356       clear_split_rec (&option_term_rec);
1357       return FALSE;
1358     }
1359 
1360   for (i = 0; i < option_term_rec.count; i++)
1361     {
1362       char *option_name = option_term_rec.vec[i];
1363       bfd_boolean is_true = TRUE;
1364       ReqOrOption *req;
1365       ReqOrOption **r_p;
1366 
1367       if (strncmp (option_name, "no-", 3) == 0)
1368 	{
1369 	  option_name = xstrdup (&option_name[3]);
1370 	  is_true = FALSE;
1371 	}
1372       else
1373 	option_name = xstrdup (option_name);
1374 
1375       req = (ReqOrOption *) xmalloc (sizeof (ReqOrOption));
1376       req->option_name = option_name;
1377       req->is_true = is_true;
1378       req->next = NULL;
1379 
1380       /* Append to list.  */
1381       for (r_p = &option->or_option_terms; (*r_p) != NULL;
1382 	   r_p = &(*r_p)->next)
1383 	;
1384       (*r_p) = req;
1385     }
1386   return TRUE;
1387 }
1388 
1389 
1390 /* Parse a string like:
1391    "insn op1, op2, op3, op4 | op1 != op2 | op2 == op3 | op4 == 1".
1392    I.E., instruction "insn" with 4 operands where operand 1 and 2 are not
1393    the same and operand 2 and 3 are the same and operand 4 is 1.
1394 
1395    or:
1396 
1397    "insn op1 | op1 == 1 / density + boolean / no-useroption".
1398    i.e. instruction "insn" with 1 operands where operand 1 is 1
1399    when "density" or "boolean" options are available and
1400    "useroption" is not available.
1401 
1402    Because the current implementation of this parsing scheme uses
1403    split_string, it requires that '|' and '?' are only used as
1404    delimiters for predicates and required options.  */
1405 
1406 static bfd_boolean
parse_insn_pattern(const char * in,insn_pattern * insn)1407 parse_insn_pattern (const char *in, insn_pattern *insn)
1408 {
1409   split_rec rec;
1410   split_rec optionrec;
1411   int i;
1412 
1413   init_insn_pattern (insn);
1414 
1415   init_split_rec (&optionrec);
1416   split_string (&optionrec, in, '?', TRUE);
1417   if (optionrec.count == 0)
1418     {
1419       clear_split_rec (&optionrec);
1420       return FALSE;
1421     }
1422 
1423   init_split_rec (&rec);
1424 
1425   split_string (&rec, optionrec.vec[0], '|', TRUE);
1426 
1427   if (rec.count == 0)
1428     {
1429       clear_split_rec (&rec);
1430       clear_split_rec (&optionrec);
1431       return FALSE;
1432     }
1433 
1434   if (!parse_insn_templ (rec.vec[0], &insn->t))
1435     {
1436       clear_split_rec (&rec);
1437       clear_split_rec (&optionrec);
1438       return FALSE;
1439     }
1440 
1441   for (i = 1; i < rec.count; i++)
1442     {
1443       precond_e *cond = (precond_e *) xmalloc (sizeof (precond_e));
1444 
1445       if (!parse_precond (rec.vec[i], cond))
1446 	{
1447 	  clear_split_rec (&rec);
1448 	  clear_split_rec (&optionrec);
1449 	  clear_insn_pattern (insn);
1450 	  return FALSE;
1451 	}
1452 
1453       /* Append the condition.  */
1454       *insn->preconds.tail = cond;
1455       insn->preconds.tail = &cond->next;
1456     }
1457 
1458   for (i = 1; i < optionrec.count; i++)
1459     {
1460       /* Handle the option conditions.  */
1461       ReqOption **r_p;
1462       ReqOption *req_option = (ReqOption *) xmalloc (sizeof (ReqOption));
1463       req_option->or_option_terms = NULL;
1464       req_option->next = NULL;
1465 
1466       if (!parse_option_cond (optionrec.vec[i], req_option))
1467 	{
1468 	  clear_split_rec (&rec);
1469 	  clear_split_rec (&optionrec);
1470 	  clear_insn_pattern (insn);
1471 	  clear_req_option_list (&req_option);
1472 	  return FALSE;
1473 	}
1474 
1475       /* Append the condition.  */
1476       for (r_p = &insn->options; (*r_p) != NULL; r_p = &(*r_p)->next)
1477 	;
1478 
1479       (*r_p) = req_option;
1480     }
1481 
1482   clear_split_rec (&rec);
1483   clear_split_rec (&optionrec);
1484   return TRUE;
1485 }
1486 
1487 
1488 static bfd_boolean
parse_insn_repl(const char * in,insn_repl * r_p)1489 parse_insn_repl (const char *in, insn_repl *r_p)
1490 {
1491   /* This is a list of instruction templates separated by ';'.  */
1492   split_rec rec;
1493   int i;
1494 
1495   split_string (&rec, in, ';', TRUE);
1496 
1497   for (i = 0; i < rec.count; i++)
1498     {
1499       insn_repl_e *e = (insn_repl_e *) xmalloc (sizeof (insn_repl_e));
1500 
1501       e->next = NULL;
1502 
1503       if (!parse_insn_templ (rec.vec[i], &e->t))
1504 	{
1505 	  free (e);
1506 	  clear_insn_repl (r_p);
1507 	  return FALSE;
1508 	}
1509       *r_p->tail = e;
1510       r_p->tail = &e->next;
1511     }
1512   return TRUE;
1513 }
1514 
1515 
1516 static bfd_boolean
transition_applies(insn_pattern * initial_insn,const char * from_string ATTRIBUTE_UNUSED,const char * to_string ATTRIBUTE_UNUSED)1517 transition_applies (insn_pattern *initial_insn,
1518 		    const char *from_string ATTRIBUTE_UNUSED,
1519 		    const char *to_string ATTRIBUTE_UNUSED)
1520 {
1521   ReqOption *req_option;
1522 
1523   for (req_option = initial_insn->options;
1524        req_option != NULL;
1525        req_option = req_option->next)
1526     {
1527       ReqOrOption *req_or_option = req_option->or_option_terms;
1528 
1529       if (req_or_option == NULL
1530 	  || req_or_option->next != NULL)
1531 	continue;
1532 
1533       if (strncmp (req_or_option->option_name, "IsaUse", 6) == 0)
1534 	{
1535 	  bfd_boolean option_available = FALSE;
1536 	  char *option_name = req_or_option->option_name + 6;
1537 	  if (!strcmp (option_name, "DensityInstruction"))
1538 	    option_available = (XCHAL_HAVE_DENSITY == 1);
1539 	  else if (!strcmp (option_name, "L32R"))
1540 	    option_available = (XCHAL_HAVE_L32R == 1);
1541 	  else if (!strcmp (option_name, "Const16"))
1542 	    option_available = (XCHAL_HAVE_CONST16 == 1);
1543 	  else if (!strcmp (option_name, "Loops"))
1544 	    option_available = (XCHAL_HAVE_LOOPS == 1);
1545 	  else if (!strcmp (option_name, "WideBranches"))
1546 	    option_available
1547 	      = (XCHAL_HAVE_WIDE_BRANCHES == 1 && produce_flix == FLIX_ALL);
1548 	  else if (!strcmp (option_name, "PredictedBranches"))
1549 	    option_available
1550 	      = (XCHAL_HAVE_PREDICTED_BRANCHES == 1
1551 		 && produce_flix == FLIX_ALL);
1552 	  else if (!strcmp (option_name, "Booleans"))
1553 	    option_available = (XCHAL_HAVE_BOOLEANS == 1);
1554 	  else
1555 	    as_warn (_("invalid configuration option '%s' in transition rule '%s'"),
1556 		     req_or_option->option_name, from_string);
1557 	  if ((option_available ^ req_or_option->is_true) != 0)
1558 	    return FALSE;
1559 	}
1560       else if (strcmp (req_or_option->option_name, "realnop") == 0)
1561 	{
1562 	  bfd_boolean nop_available =
1563 	    (xtensa_opcode_lookup (xtensa_default_isa, "nop")
1564 	     != XTENSA_UNDEFINED);
1565 	  if ((nop_available ^ req_or_option->is_true) != 0)
1566 	    return FALSE;
1567 	}
1568     }
1569   return TRUE;
1570 }
1571 
1572 
1573 static bfd_boolean
wide_branch_opcode(const char * opcode_name,char * suffix,xtensa_opcode * popcode)1574 wide_branch_opcode (const char *opcode_name,
1575 		    char *suffix,
1576 		    xtensa_opcode *popcode)
1577 {
1578   xtensa_isa isa = xtensa_default_isa;
1579   xtensa_opcode opcode;
1580   static char wbr_name_buf[20];
1581 
1582   if (strncmp (opcode_name, "WIDE.", 5) != 0)
1583     return FALSE;
1584 
1585   strcpy (wbr_name_buf, opcode_name + 5);
1586   strcat (wbr_name_buf, suffix);
1587   opcode = xtensa_opcode_lookup (isa, wbr_name_buf);
1588   if (opcode != XTENSA_UNDEFINED)
1589     {
1590       *popcode = opcode;
1591       return TRUE;
1592     }
1593 
1594   return FALSE;
1595 }
1596 
1597 
1598 static TransitionRule *
build_transition(insn_pattern * initial_insn,insn_repl * replace_insns,const char * from_string,const char * to_string)1599 build_transition (insn_pattern *initial_insn,
1600 		  insn_repl *replace_insns,
1601 		  const char *from_string,
1602 		  const char *to_string)
1603 {
1604   TransitionRule *tr = NULL;
1605   xtensa_opcode opcode;
1606   xtensa_isa isa = xtensa_default_isa;
1607   BuildInstr *literal_bi;
1608 
1609   opname_map_e *op1;
1610   opname_map_e *op2;
1611 
1612   precond_e *precond;
1613   insn_repl_e *r;
1614 
1615   if (!wide_branch_opcode (initial_insn->t.opcode_name, ".w18", &opcode)
1616       && !wide_branch_opcode (initial_insn->t.opcode_name, ".w15", &opcode))
1617     opcode = xtensa_opcode_lookup (isa, initial_insn->t.opcode_name);
1618 
1619   if (opcode == XTENSA_UNDEFINED)
1620     {
1621       /* It is OK to not be able to translate some of these opcodes.  */
1622       return NULL;
1623     }
1624 
1625 
1626   if (xtensa_opcode_num_operands (isa, opcode)
1627       != insn_templ_operand_count (&initial_insn->t))
1628     {
1629       /* This is also OK because there are opcodes that
1630 	 have different numbers of operands on different
1631 	 architecture variations.  */
1632       return NULL;
1633     }
1634 
1635   tr = (TransitionRule *) xmalloc (sizeof (TransitionRule));
1636   tr->opcode = opcode;
1637   tr->conditions = NULL;
1638   tr->to_instr = NULL;
1639 
1640   /* Build the conditions. First, equivalent operand condition....  */
1641   for (op1 = initial_insn->t.operand_map.head; op1 != NULL; op1 = op1->next)
1642     {
1643       for (op2 = op1->next; op2 != NULL; op2 = op2->next)
1644 	{
1645 	  if (same_operand_name (op1, op2))
1646 	    {
1647 	      append_value_condition (tr, OP_EQUAL,
1648 				      op1->operand_num, op2->operand_num);
1649 	    }
1650 	}
1651     }
1652 
1653   /* Now the condition that an operand value must be a constant....  */
1654   for (op1 = initial_insn->t.operand_map.head; op1 != NULL; op1 = op1->next)
1655     {
1656       if (op_is_constant (op1))
1657 	{
1658 	  append_constant_value_condition (tr,
1659 					   OP_EQUAL,
1660 					   op1->operand_num,
1661 					   op_get_constant (op1));
1662 	}
1663     }
1664 
1665 
1666   /* Now add the explicit preconditions listed after the "|" in the spec.
1667      These are currently very limited, so we do a special case
1668      parse for them.  We expect spaces, opname != opname.  */
1669   for (precond = initial_insn->preconds.head;
1670        precond != NULL;
1671        precond = precond->next)
1672     {
1673       op1 = NULL;
1674       op2 = NULL;
1675 
1676       if (precond->opname1)
1677 	{
1678 	  op1 = get_opmatch (&initial_insn->t.operand_map, precond->opname1);
1679 	  if (op1 == NULL)
1680 	    as_fatal (_("opcode '%s': no bound opname '%s' "
1681 			"for precondition in '%s'"),
1682 		      xtensa_opcode_name (isa, opcode),
1683 		      precond->opname1, from_string);
1684 	}
1685 
1686       if (precond->opname2)
1687 	{
1688 	  op2 = get_opmatch (&initial_insn->t.operand_map, precond->opname2);
1689 	  if (op2 == NULL)
1690 	    as_fatal (_("opcode '%s': no bound opname '%s' "
1691 			"for precondition in %s"),
1692 		      xtensa_opcode_name (isa, opcode),
1693 		      precond->opname2, from_string);
1694 	}
1695 
1696       if (op1 == NULL && op2 == NULL)
1697 	as_fatal (_("opcode '%s': precondition only contains "
1698 		    "constants in '%s'"),
1699 		  xtensa_opcode_name (isa, opcode), from_string);
1700       else if (op1 != NULL && op2 != NULL)
1701 	append_value_condition (tr, precond->cmpop,
1702 				op1->operand_num, op2->operand_num);
1703       else if (op2 == NULL)
1704 	append_constant_value_condition (tr, precond->cmpop,
1705 					 op1->operand_num, precond->opval2);
1706       else
1707 	append_constant_value_condition (tr, precond->cmpop,
1708 					 op2->operand_num, precond->opval1);
1709     }
1710 
1711   tr->options = clone_req_option_list (initial_insn->options);
1712 
1713   /* Generate the replacement instructions.  Some of these
1714      "instructions" are actually labels and literals.  There can be at
1715      most one literal and at most one label.  A literal must be defined
1716      (e.g., "LITERAL %imm") before use (e.g., "%LITERAL").  The labels
1717      can be used before they are defined.  Also there are a number of
1718      special operands (e.g., HI24S).  */
1719 
1720   literal_bi = NULL;
1721   for (r = replace_insns->head; r != NULL; r = r->next)
1722     {
1723       BuildInstr *bi;
1724       const char *opcode_name;
1725       int operand_count;
1726       opname_map_e *op;
1727       const char *fn_name;
1728       const char *operand_arg_name;
1729 
1730       bi = (BuildInstr *) xmalloc (sizeof (BuildInstr));
1731       append_build_insn (tr, bi);
1732 
1733       bi->opcode = XTENSA_UNDEFINED;
1734       bi->ops = NULL;
1735       bi->next = NULL;
1736 
1737       opcode_name = r->t.opcode_name;
1738       operand_count = insn_templ_operand_count (&r->t);
1739 
1740       if (strcmp (opcode_name, "LITERAL") == 0)
1741 	{
1742 	  bi->typ = INSTR_LITERAL_DEF;
1743 	  if (operand_count != 1)
1744 	    as_fatal (_("expected one operand for generated literal"));
1745 	  literal_bi = bi;
1746 	}
1747       else if (strcmp (opcode_name, "LABEL") == 0)
1748 	{
1749 	  bi->typ = INSTR_LABEL_DEF;
1750 	  if (operand_count != 0)
1751 	    as_fatal (_("expected 0 operands for generated label"));
1752 	}
1753       else
1754 	{
1755 	  bi->typ = INSTR_INSTR;
1756 	  if (wide_branch_opcode (opcode_name, ".w18", &bi->opcode)
1757 	      || wide_branch_opcode (opcode_name, ".w15", &bi->opcode))
1758 	    opcode_name = xtensa_opcode_name (isa, bi->opcode);
1759 	  else
1760 	    bi->opcode = xtensa_opcode_lookup (isa, opcode_name);
1761 
1762 	  if (bi->opcode == XTENSA_UNDEFINED)
1763 	    {
1764 	      as_warn (_("invalid opcode '%s' in transition rule '%s'"),
1765 		       opcode_name, to_string);
1766 	      return NULL;
1767 	    }
1768 
1769 	  /* Check for the right number of ops.  */
1770 	  if (xtensa_opcode_num_operands (isa, bi->opcode)
1771 	      != (int) operand_count)
1772 	    as_fatal (_("opcode '%s': replacement does not have %d ops"),
1773 		      opcode_name,
1774 		      xtensa_opcode_num_operands (isa, bi->opcode));
1775 	}
1776 
1777       for (op = r->t.operand_map.head; op != NULL; op = op->next)
1778 	{
1779 	  unsigned idnum;
1780 
1781 	  if (op_is_constant (op))
1782 	    append_constant_op (bi, op->operand_num, op_get_constant (op));
1783 	  else if (strcmp (op->operand_name, "%LITERAL") == 0)
1784 	    {
1785 	      if (! literal_bi || ! literal_bi->ops || literal_bi->ops->next)
1786 		as_fatal (_("opcode '%s': cannot find literal definition"),
1787 			  opcode_name);
1788 	      append_literal_op (bi, op->operand_num,
1789 				 literal_bi->ops->op_data);
1790 	    }
1791 	  else if (strcmp (op->operand_name, "%LABEL") == 0)
1792 	    append_label_op (bi, op->operand_num);
1793 	  else if (op->operand_name[0] == 'a'
1794 		   && parse_constant (op->operand_name + 1, &idnum))
1795 	    append_constant_op (bi, op->operand_num, idnum);
1796 	  else if (op->operand_name[0] == '%')
1797 	    {
1798 	      opname_map_e *orig_op;
1799 	      orig_op = get_opmatch (&initial_insn->t.operand_map,
1800 				     op->operand_name);
1801 	      if (orig_op == NULL)
1802 		as_fatal (_("opcode %s: unidentified operand '%s' in '%s'"),
1803 			  opcode_name, op->operand_name, to_string);
1804 	      append_field_op (bi, op->operand_num, orig_op->operand_num);
1805 	    }
1806 	  else if (strcmp (op->operand_name, "FREEREG") == 0)
1807 	    {
1808 	      append_user_fn_field_op (bi, op->operand_num, OP_FREEREG, 0);
1809 	    }
1810 	  else if (parse_special_fn (op->operand_name,
1811 				     &fn_name, &operand_arg_name))
1812 	    {
1813 	      opname_map_e *orig_op;
1814 	      OpType typ = OP_CONSTANT;
1815 
1816 	      if (strcmp (fn_name, "LOW8") == 0)
1817 		typ = OP_OPERAND_LOW8;
1818 	      else if (strcmp (fn_name, "HI24S") == 0)
1819 		typ = OP_OPERAND_HI24S;
1820 	      else if (strcmp (fn_name, "F32MINUS") == 0)
1821 		typ = OP_OPERAND_F32MINUS;
1822 	      else if (strcmp (fn_name, "LOW16U") == 0)
1823 		typ = OP_OPERAND_LOW16U;
1824 	      else if (strcmp (fn_name, "HI16U") == 0)
1825 		typ = OP_OPERAND_HI16U;
1826 	      else
1827 		as_fatal (_("unknown user-defined function %s"), fn_name);
1828 
1829 	      orig_op = get_opmatch (&initial_insn->t.operand_map,
1830 				     operand_arg_name);
1831 	      if (orig_op == NULL)
1832 		as_fatal (_("opcode %s: unidentified operand '%s' in '%s'"),
1833 			  opcode_name, op->operand_name, to_string);
1834 	      append_user_fn_field_op (bi, op->operand_num,
1835 				       typ, orig_op->operand_num);
1836 	    }
1837 	  else
1838 	    as_fatal (_("opcode %s: could not parse operand '%s' in '%s'"),
1839 		      opcode_name, op->operand_name, to_string);
1840 	}
1841     }
1842 
1843   return tr;
1844 }
1845 
1846 
1847 static TransitionTable *
build_transition_table(const string_pattern_pair * transitions,int transition_count,transition_cmp_fn cmp)1848 build_transition_table (const string_pattern_pair *transitions,
1849 			int transition_count,
1850 			transition_cmp_fn cmp)
1851 {
1852   TransitionTable *table = NULL;
1853   int num_opcodes = xtensa_isa_num_opcodes (xtensa_default_isa);
1854   int i, tnum;
1855 
1856   if (table != NULL)
1857     return table;
1858 
1859   /* Otherwise, build it now.  */
1860   table = (TransitionTable *) xmalloc (sizeof (TransitionTable));
1861   table->num_opcodes = num_opcodes;
1862   table->table =
1863     (TransitionList **) xmalloc (sizeof (TransitionTable *) * num_opcodes);
1864 
1865   for (i = 0; i < num_opcodes; i++)
1866     table->table[i] = NULL;
1867 
1868   for (tnum = 0; tnum < transition_count; tnum++)
1869     {
1870       const char *from_string = transitions[tnum].pattern;
1871       const char *to_string = transitions[tnum].replacement;
1872 
1873       insn_pattern initial_insn;
1874       insn_repl replace_insns;
1875       TransitionRule *tr;
1876 
1877       init_insn_pattern (&initial_insn);
1878       if (!parse_insn_pattern (from_string, &initial_insn))
1879 	as_fatal (_("could not parse INSN_PATTERN '%s'"), from_string);
1880 
1881       init_insn_repl (&replace_insns);
1882       if (!parse_insn_repl (to_string, &replace_insns))
1883 	as_fatal (_("could not parse INSN_REPL '%s'"), to_string);
1884 
1885       if (transition_applies (&initial_insn, from_string, to_string))
1886 	{
1887 	  tr = build_transition (&initial_insn, &replace_insns,
1888 				 from_string, to_string);
1889 	  if (tr)
1890 	    append_transition (table, tr->opcode, tr, cmp);
1891 	  else
1892 	    {
1893 #if TENSILICA_DEBUG
1894 	      as_warn (_("could not build transition for %s => %s"),
1895 		       from_string, to_string);
1896 #endif
1897 	    }
1898 	}
1899 
1900       clear_insn_repl (&replace_insns);
1901       clear_insn_pattern (&initial_insn);
1902     }
1903   return table;
1904 }
1905 
1906 
1907 extern TransitionTable *
xg_build_widen_table(transition_cmp_fn cmp)1908 xg_build_widen_table (transition_cmp_fn cmp)
1909 {
1910   static TransitionTable *table = NULL;
1911   if (table == NULL)
1912     table = build_transition_table (widen_spec_list, WIDEN_COUNT, cmp);
1913   return table;
1914 }
1915 
1916 
1917 extern TransitionTable *
xg_build_simplify_table(transition_cmp_fn cmp)1918 xg_build_simplify_table (transition_cmp_fn cmp)
1919 {
1920   static TransitionTable *table = NULL;
1921   if (table == NULL)
1922     table = build_transition_table (simplify_spec_list, SIMPLIFY_COUNT, cmp);
1923   return table;
1924 }
1925