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