1 /* Table of relaxations for Xtensa assembly.
2 Copyright (C) 2003-2017 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
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)
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.
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. */
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.
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
35 The patterns match a language like:
37 INSN_PATTERN ::= INSN_TEMPL ( '|' PRECOND )* ( '?' OPTIONPRED )*
38 INSN_TEMPL ::= OPCODE ' ' [ OPERAND (',' OPERAND)* ]
40 OPERAND ::= CONSTANT | VARIABLE | SPECIALFN '(' VARIABLE ')'
41 SPECIALFN ::= 'HI24S' | 'F32MINUS' | 'LOW8'
44 PRECOND ::= OPERAND CMPOP OPERAND
46 OPTIONPRED ::= OPTIONNAME ('+' OPTIONNAME)
47 OPTIONNAME ::= '"' id '"'
49 The replacement language
50 INSN_REPL ::= INSN_LABEL_LIT ( ';' INSN_LABEL_LIT )*
51 INSN_LABEL_LIT ::= INSN_TEMPL
55 The operands in a PRECOND must be constants or variables bound by
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.
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.
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.
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.
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.
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"}
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. */
99 #include "xtensa-isa.h"
100 #include "xtensa-relax.h"
102 #include "xtensa-config.h"
104 #ifndef XCHAL_HAVE_WIDE_BRANCHES
105 #define XCHAL_HAVE_WIDE_BRANCHES 0
108 /* Imported from bfd. */
109 extern xtensa_isa xtensa_default_isa;
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
116 typedef struct opname_list_struct opname_list;
117 typedef opname_list opname_e;
119 struct opname_list_struct
125 static opname_list *local_opnames = NULL;
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. */
131 typedef struct opname_map_e_struct opname_map_e;
132 typedef struct opname_map_struct opname_map;
134 struct opname_map_e_struct
136 const char *operand_name; /* If null, then use constant_value. */
138 unsigned constant_value;
142 struct opname_map_struct
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". */
154 typedef struct precond_e_struct precond_e;
155 typedef struct precond_list_struct precond_list;
157 struct precond_e_struct
167 struct precond_list_struct
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. */
178 typedef struct insn_templ_struct insn_templ;
179 struct insn_templ_struct
181 const char *opcode_name;
182 opname_map operand_map;
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. */
190 typedef struct insn_pattern_struct insn_pattern;
191 struct insn_pattern_struct
194 precond_list preconds;
195 ReqOptionList *options;
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. */
204 typedef struct insn_repl_e_struct insn_repl_e;
205 struct insn_repl_e_struct
211 typedef struct insn_repl_struct insn_repl;
212 struct insn_repl_struct
219 /* The split_rec is a vector of allocated char * pointers. */
221 typedef struct split_rec_struct split_rec;
222 struct split_rec_struct
228 /* The "string_pattern_pair" is a set of pairs containing instruction
229 patterns and replacement strings. */
231 typedef struct string_pattern_pair_struct string_pattern_pair;
232 struct string_pattern_pair_struct
235 const char *replacement;
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'.
250 => addmi a4, 0x1000, addi a4, 0x10.
252 See the comments in xg_assembly_relax for some important details
253 regarding how these chains must be built. */
255 static string_pattern_pair widen_spec_list[] =
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"},
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)"},
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)"},
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"},
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"},
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"},
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",
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) */
320 "rsr.lcount %as;" /* LCOUNT */
321 "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */
323 {"loopgtz %as,%label | %as!=1 ? IsaUseLoops",
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) */
333 "rsr.lcount %as;" /* LCOUNT */
334 "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */
336 {"loopnez %as,%label | %as!=1 ? IsaUseLoops",
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) */
345 "rsr.lcount %as;" /* LCOUNT */
346 "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */
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
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"},
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"},
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"},
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"},
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"},
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"},
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"},
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"},
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"},
476 #define WIDEN_COUNT (sizeof (widen_spec_list) / sizeof (string_pattern_pair))
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. */
489 string_pattern_pair simplify_spec_list[] =
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"}
509 #define SIMPLIFY_COUNT \
510 (sizeof (simplify_spec_list) / sizeof (string_pattern_pair))
513 /* Externally visible functions. */
515 extern bfd_boolean xg_has_userdef_op_fn (OpType);
516 extern long xg_apply_userdef_op_fn (OpType, long);
520 append_transition (TransitionTable *tt,
521 xtensa_opcode opcode,
523 transition_cmp_fn cmp)
525 TransitionList *tl = XNEW (TransitionList);
526 TransitionList *prev;
527 TransitionList **t_p;
528 gas_assert (tt != NULL);
529 gas_assert (opcode < tt->num_opcodes);
531 prev = tt->table[opcode];
536 tt->table[opcode] = tl;
540 for (t_p = &tt->table[opcode]; (*t_p) != NULL; t_p = &(*t_p)->next)
542 if (cmp && cmp (t, (*t_p)->rule) < 0)
544 /* Insert it here. */
555 append_condition (TransitionRule *tr, Precondition *cond)
557 PreconditionList *pl = XNEW (PreconditionList);
558 PreconditionList *prev = tr->conditions;
559 PreconditionList *nxt;
579 append_value_condition (TransitionRule *tr,
584 Precondition *cond = XNEW (Precondition);
588 cond->typ = OP_OPERAND;
590 append_condition (tr, cond);
595 append_constant_value_condition (TransitionRule *tr,
600 Precondition *cond = XNEW (Precondition);
604 cond->typ = OP_CONSTANT;
605 cond->op_data = cnst;
606 append_condition (tr, cond);
611 append_build_insn (TransitionRule *tr, BuildInstr *bi)
613 BuildInstr *prev = tr->to_instr;
633 append_op (BuildInstr *bi, BuildOp *b_op)
635 BuildOp *prev = bi->ops;
654 append_literal_op (BuildInstr *bi, unsigned op1, unsigned src_op)
656 BuildOp *b_op = XNEW (BuildOp);
659 b_op->typ = OP_LITERAL;
660 b_op->op_data = src_op;
662 append_op (bi, b_op);
667 append_label_op (BuildInstr *bi, unsigned op1)
669 BuildOp *b_op = XNEW (BuildOp);
672 b_op->typ = OP_LABEL;
675 append_op (bi, b_op);
680 append_constant_op (BuildInstr *bi, unsigned op1, unsigned cnst)
682 BuildOp *b_op = XNEW (BuildOp);
685 b_op->typ = OP_CONSTANT;
686 b_op->op_data = cnst;
688 append_op (bi, b_op);
693 append_field_op (BuildInstr *bi, unsigned op1, unsigned src_op)
695 BuildOp *b_op = XNEW (BuildOp);
698 b_op->typ = OP_OPERAND;
699 b_op->op_data = src_op;
701 append_op (bi, b_op);
705 /* These could be generated but are not currently. */
708 append_user_fn_field_op (BuildInstr *bi,
713 BuildOp *b_op = XNEW (BuildOp);
717 b_op->op_data = src_op;
719 append_op (bi, b_op);
723 /* These operand functions are the semantics of user-defined
724 operand functions. */
727 operand_function_HI24S (long a)
730 return (a & (~0xff)) + 0x100;
732 return (a & (~0xff));
737 operand_function_F32MINUS (long a)
744 operand_function_LOW8 (long a)
747 return (a & 0xff) | ~0xff;
754 operand_function_LOW16U (long a)
761 operand_function_HI16U (long a)
763 unsigned long b = a & 0xffff0000;
764 return (long) (b >> 16);
769 xg_has_userdef_op_fn (OpType op)
773 case OP_OPERAND_F32MINUS:
774 case OP_OPERAND_LOW8:
775 case OP_OPERAND_HI24S:
776 case OP_OPERAND_LOW16U:
777 case OP_OPERAND_HI16U:
787 xg_apply_userdef_op_fn (OpType op, long a)
791 case OP_OPERAND_F32MINUS:
792 return operand_function_F32MINUS (a);
793 case OP_OPERAND_LOW8:
794 return operand_function_LOW8 (a);
795 case OP_OPERAND_HI24S:
796 return operand_function_HI24S (a);
797 case OP_OPERAND_LOW16U:
798 return operand_function_LOW16U (a);
799 case OP_OPERAND_HI16U:
800 return operand_function_HI16U (a);
808 /* Generate a transition table. */
811 enter_opname_n (const char *name, int len)
815 for (op = local_opnames; op != NULL; op = op->next)
817 if (strlen (op->opname) == (unsigned) len
818 && strncmp (op->opname, name, len) == 0)
821 op = XNEW (opname_e);
822 op->opname = xmemdup0 (name, len);
828 enter_opname (const char *name)
832 for (op = local_opnames; op != NULL; op = op->next)
834 if (strcmp (op->opname, name) == 0)
837 op = XNEW (opname_e);
838 op->opname = xstrdup (name);
844 init_opname_map (opname_map *m)
852 clear_opname_map (opname_map *m)
856 while (m->head != NULL)
867 same_operand_name (const opname_map_e *m1, const opname_map_e *m2)
869 if (m1->operand_name == NULL || m2->operand_name == NULL)
871 return (m1->operand_name == m2->operand_name);
875 static opname_map_e *
876 get_opmatch (opname_map *map, const char *operand_name)
880 for (m = map->head; m != NULL; m = m->next)
882 if (strcmp (m->operand_name, operand_name) == 0)
890 op_is_constant (const opname_map_e *m1)
892 return (m1->operand_name == NULL);
897 op_get_constant (const opname_map_e *m1)
899 gas_assert (m1->operand_name == NULL);
900 return m1->constant_value;
905 init_precond_list (precond_list *l)
913 clear_precond_list (precond_list *l)
917 while (l->head != NULL)
928 init_insn_templ (insn_templ *t)
930 t->opcode_name = NULL;
931 init_opname_map (&t->operand_map);
936 clear_insn_templ (insn_templ *t)
938 clear_opname_map (&t->operand_map);
943 init_insn_pattern (insn_pattern *p)
945 init_insn_templ (&p->t);
946 init_precond_list (&p->preconds);
952 clear_insn_pattern (insn_pattern *p)
954 clear_insn_templ (&p->t);
955 clear_precond_list (&p->preconds);
960 init_insn_repl (insn_repl *r)
968 clear_insn_repl (insn_repl *r)
972 while (r->head != NULL)
976 clear_insn_templ (&e->t);
983 insn_templ_operand_count (const insn_templ *t)
986 const opname_map_e *op;
988 for (op = t->operand_map.head; op != NULL; op = op->next, i++)
994 /* Convert a string to a number. E.G.: parse_constant("10", &num) */
997 parse_constant (const char *in, unsigned *val_p)
1008 if (*p >= '0' && *p <= '9')
1009 val = val * 10 + (*p - '0');
1020 parse_special_fn (const char *name,
1021 const char **fn_name_p,
1022 const char **arg_name_p)
1024 const char *p_start;
1027 p_start = strchr (name, '(');
1028 if (p_start == NULL)
1031 p_end = strchr (p_start, ')');
1036 if (p_end[1] != '\0')
1039 *fn_name_p = enter_opname_n (name, p_start - name);
1040 *arg_name_p = enter_opname_n (p_start + 1, p_end - p_start - 1);
1046 skip_white (const char *p)
1057 trim_whitespace (char *in)
1059 char *last_white = NULL;
1062 while (p && *p != '\0')
1066 if (last_white == NULL)
1081 /* Split a string into component strings where "c" is the
1082 delimiter. Place the result in the split_rec. */
1085 split_string (split_rec *rec,
1088 bfd_boolean elide_whitespace)
1094 while (p != NULL && *p != '\0')
1104 if (rec->count == 0)
1107 rec->vec = XNEWVEC (char *, cnt);
1108 for (i = 0; i < cnt; i++)
1112 for (i = 0; i < cnt; i++)
1118 if (elide_whitespace)
1123 rec->vec[i] = xstrdup (q);
1127 rec->vec[i] = xmemdup0 (q, len);
1131 if (elide_whitespace)
1132 trim_whitespace (rec->vec[i]);
1138 clear_split_rec (split_rec *rec)
1142 for (i = 0; i < rec->count; i++)
1150 /* Initialize a split record. The split record must be initialized
1151 before split_string is called. */
1154 init_split_rec (split_rec *rec)
1161 /* Parse an instruction template like "insn op1, op2, op3". */
1164 parse_insn_templ (const char *s, insn_templ *t)
1171 /* First find the first whitespace. */
1173 init_split_rec (&oprec);
1176 insn_name_len = strcspn (s, " ");
1177 if (insn_name_len == 0)
1180 init_insn_templ (t);
1181 t->opcode_name = enter_opname_n (p, insn_name_len);
1183 p = p + insn_name_len;
1185 /* Split by ',' and skip beginning and trailing whitespace. */
1186 split_string (&oprec, p, ',', TRUE);
1188 for (i = 0; i < oprec.count; i++)
1190 const char *opname = oprec.vec[i];
1191 opname_map_e *e = XNEW (opname_map_e);
1193 e->operand_name = NULL;
1194 e->constant_value = 0;
1197 /* If it begins with a number, assume that it is a number. */
1198 if (opname && opname[0] >= '0' && opname[0] <= '9')
1202 if (parse_constant (opname, &val))
1203 e->constant_value = val;
1207 clear_split_rec (&oprec);
1208 clear_insn_templ (t);
1213 e->operand_name = enter_opname (oprec.vec[i]);
1215 *t->operand_map.tail = e;
1216 t->operand_map.tail = &e->next;
1218 clear_split_rec (&oprec);
1224 parse_precond (const char *s, precond_e *precond)
1226 /* All preconditions are currently of the form:
1227 a == b or a != b or a == k (where k is a constant).
1228 Later we may use some special functions like DENSITY == 1
1229 to identify when density is available. */
1233 precond->opname1 = NULL;
1234 precond->opval1 = 0;
1235 precond->cmpop = OP_EQUAL;
1236 precond->opname2 = NULL;
1237 precond->opval2 = 0;
1238 precond->next = NULL;
1242 len = strcspn (p, " !=");
1247 precond->opname1 = enter_opname_n (p, len);
1251 /* Check for "==" and "!=". */
1252 if (strncmp (p, "==", 2) == 0)
1253 precond->cmpop = OP_EQUAL;
1254 else if (strncmp (p, "!=", 2) == 0)
1255 precond->cmpop = OP_NOTEQUAL;
1262 /* No trailing whitespace from earlier parsing. */
1263 if (p[0] >= '0' && p[0] <= '9')
1266 if (parse_constant (p, &val))
1267 precond->opval2 = val;
1272 precond->opname2 = enter_opname (p);
1278 clear_req_or_option_list (ReqOrOption **r_p)
1283 free ((*r_p)->option_name);
1284 clear_req_or_option_list (&(*r_p)->next);
1290 clear_req_option_list (ReqOption **r_p)
1295 clear_req_or_option_list (&(*r_p)->or_option_terms);
1296 clear_req_option_list (&(*r_p)->next);
1301 static ReqOrOption *
1302 clone_req_or_option_list (ReqOrOption *req_or_option)
1304 ReqOrOption *new_req_or_option;
1306 if (req_or_option == NULL)
1309 new_req_or_option = XNEW (ReqOrOption);
1310 new_req_or_option->option_name = xstrdup (req_or_option->option_name);
1311 new_req_or_option->is_true = req_or_option->is_true;
1312 new_req_or_option->next = NULL;
1313 new_req_or_option->next = clone_req_or_option_list (req_or_option->next);
1314 return new_req_or_option;
1319 clone_req_option_list (ReqOption *req_option)
1321 ReqOption *new_req_option;
1323 if (req_option == NULL)
1326 new_req_option = XNEW (ReqOption);
1327 new_req_option->or_option_terms = NULL;
1328 new_req_option->next = NULL;
1329 new_req_option->or_option_terms =
1330 clone_req_or_option_list (req_option->or_option_terms);
1331 new_req_option->next = clone_req_option_list (req_option->next);
1332 return new_req_option;
1337 parse_option_cond (const char *s, ReqOption *option)
1340 split_rec option_term_rec;
1342 /* All option or conditions are of the form:
1343 optionA + no-optionB + ...
1344 "Ands" are divided by "?". */
1346 init_split_rec (&option_term_rec);
1347 split_string (&option_term_rec, s, '+', TRUE);
1349 if (option_term_rec.count == 0)
1351 clear_split_rec (&option_term_rec);
1355 for (i = 0; i < option_term_rec.count; i++)
1357 char *option_name = option_term_rec.vec[i];
1358 bfd_boolean is_true = TRUE;
1362 if (strncmp (option_name, "no-", 3) == 0)
1364 option_name = xstrdup (&option_name[3]);
1368 option_name = xstrdup (option_name);
1370 req = XNEW (ReqOrOption);
1371 req->option_name = option_name;
1372 req->is_true = is_true;
1375 /* Append to list. */
1376 for (r_p = &option->or_option_terms; (*r_p) != NULL;
1377 r_p = &(*r_p)->next)
1385 /* Parse a string like:
1386 "insn op1, op2, op3, op4 | op1 != op2 | op2 == op3 | op4 == 1".
1387 I.E., instruction "insn" with 4 operands where operand 1 and 2 are not
1388 the same and operand 2 and 3 are the same and operand 4 is 1.
1392 "insn op1 | op1 == 1 / density + boolean / no-useroption".
1393 i.e. instruction "insn" with 1 operands where operand 1 is 1
1394 when "density" or "boolean" options are available and
1395 "useroption" is not available.
1397 Because the current implementation of this parsing scheme uses
1398 split_string, it requires that '|' and '?' are only used as
1399 delimiters for predicates and required options. */
1402 parse_insn_pattern (const char *in, insn_pattern *insn)
1405 split_rec optionrec;
1408 init_insn_pattern (insn);
1410 init_split_rec (&optionrec);
1411 split_string (&optionrec, in, '?', TRUE);
1412 if (optionrec.count == 0)
1414 clear_split_rec (&optionrec);
1418 init_split_rec (&rec);
1420 split_string (&rec, optionrec.vec[0], '|', TRUE);
1424 clear_split_rec (&rec);
1425 clear_split_rec (&optionrec);
1429 if (!parse_insn_templ (rec.vec[0], &insn->t))
1431 clear_split_rec (&rec);
1432 clear_split_rec (&optionrec);
1436 for (i = 1; i < rec.count; i++)
1438 precond_e *cond = XNEW (precond_e);
1440 if (!parse_precond (rec.vec[i], cond))
1442 clear_split_rec (&rec);
1443 clear_split_rec (&optionrec);
1444 clear_insn_pattern (insn);
1448 /* Append the condition. */
1449 *insn->preconds.tail = cond;
1450 insn->preconds.tail = &cond->next;
1453 for (i = 1; i < optionrec.count; i++)
1455 /* Handle the option conditions. */
1457 ReqOption *req_option = XNEW (ReqOption);
1458 req_option->or_option_terms = NULL;
1459 req_option->next = NULL;
1461 if (!parse_option_cond (optionrec.vec[i], req_option))
1463 clear_split_rec (&rec);
1464 clear_split_rec (&optionrec);
1465 clear_insn_pattern (insn);
1466 clear_req_option_list (&req_option);
1470 /* Append the condition. */
1471 for (r_p = &insn->options; (*r_p) != NULL; r_p = &(*r_p)->next)
1474 (*r_p) = req_option;
1477 clear_split_rec (&rec);
1478 clear_split_rec (&optionrec);
1484 parse_insn_repl (const char *in, insn_repl *r_p)
1486 /* This is a list of instruction templates separated by ';'. */
1490 split_string (&rec, in, ';', TRUE);
1492 for (i = 0; i < rec.count; i++)
1494 insn_repl_e *e = XNEW (insn_repl_e);
1498 if (!parse_insn_templ (rec.vec[i], &e->t))
1501 clear_insn_repl (r_p);
1505 r_p->tail = &e->next;
1512 transition_applies (insn_pattern *initial_insn,
1513 const char *from_string ATTRIBUTE_UNUSED,
1514 const char *to_string ATTRIBUTE_UNUSED)
1516 ReqOption *req_option;
1518 for (req_option = initial_insn->options;
1520 req_option = req_option->next)
1522 ReqOrOption *req_or_option = req_option->or_option_terms;
1524 if (req_or_option == NULL
1525 || req_or_option->next != NULL)
1528 if (strncmp (req_or_option->option_name, "IsaUse", 6) == 0)
1530 bfd_boolean option_available = FALSE;
1531 char *option_name = req_or_option->option_name + 6;
1532 if (!strcmp (option_name, "DensityInstruction"))
1533 option_available = (XCHAL_HAVE_DENSITY == 1);
1534 else if (!strcmp (option_name, "L32R"))
1535 option_available = (XCHAL_HAVE_L32R == 1);
1536 else if (!strcmp (option_name, "Const16"))
1537 option_available = (XCHAL_HAVE_CONST16 == 1);
1538 else if (!strcmp (option_name, "Loops"))
1539 option_available = (XCHAL_HAVE_LOOPS == 1);
1540 else if (!strcmp (option_name, "WideBranches"))
1542 = (XCHAL_HAVE_WIDE_BRANCHES == 1 && produce_flix == FLIX_ALL);
1543 else if (!strcmp (option_name, "PredictedBranches"))
1545 = (XCHAL_HAVE_PREDICTED_BRANCHES == 1
1546 && produce_flix == FLIX_ALL);
1547 else if (!strcmp (option_name, "Booleans"))
1548 option_available = (XCHAL_HAVE_BOOLEANS == 1);
1550 as_warn (_("invalid configuration option '%s' in transition rule '%s'"),
1551 req_or_option->option_name, from_string);
1552 if ((option_available ^ req_or_option->is_true) != 0)
1555 else if (strcmp (req_or_option->option_name, "realnop") == 0)
1557 bfd_boolean nop_available =
1558 (xtensa_opcode_lookup (xtensa_default_isa, "nop")
1559 != XTENSA_UNDEFINED);
1560 if ((nop_available ^ req_or_option->is_true) != 0)
1569 wide_branch_opcode (const char *opcode_name,
1571 xtensa_opcode *popcode)
1573 xtensa_isa isa = xtensa_default_isa;
1574 xtensa_opcode opcode;
1575 static char wbr_name_buf[20];
1577 if (strncmp (opcode_name, "WIDE.", 5) != 0)
1580 strcpy (wbr_name_buf, opcode_name + 5);
1581 strcat (wbr_name_buf, suffix);
1582 opcode = xtensa_opcode_lookup (isa, wbr_name_buf);
1583 if (opcode != XTENSA_UNDEFINED)
1593 static TransitionRule *
1594 build_transition (insn_pattern *initial_insn,
1595 insn_repl *replace_insns,
1596 const char *from_string,
1597 const char *to_string)
1599 TransitionRule *tr = NULL;
1600 xtensa_opcode opcode;
1601 xtensa_isa isa = xtensa_default_isa;
1602 BuildInstr *literal_bi;
1610 if (!wide_branch_opcode (initial_insn->t.opcode_name, ".w18", &opcode)
1611 && !wide_branch_opcode (initial_insn->t.opcode_name, ".w15", &opcode))
1612 opcode = xtensa_opcode_lookup (isa, initial_insn->t.opcode_name);
1614 if (opcode == XTENSA_UNDEFINED)
1616 /* It is OK to not be able to translate some of these opcodes. */
1621 if (xtensa_opcode_num_operands (isa, opcode)
1622 != insn_templ_operand_count (&initial_insn->t))
1624 /* This is also OK because there are opcodes that
1625 have different numbers of operands on different
1626 architecture variations. */
1630 tr = XNEW (TransitionRule);
1631 tr->opcode = opcode;
1632 tr->conditions = NULL;
1633 tr->to_instr = NULL;
1635 /* Build the conditions. First, equivalent operand condition.... */
1636 for (op1 = initial_insn->t.operand_map.head; op1 != NULL; op1 = op1->next)
1638 for (op2 = op1->next; op2 != NULL; op2 = op2->next)
1640 if (same_operand_name (op1, op2))
1642 append_value_condition (tr, OP_EQUAL,
1643 op1->operand_num, op2->operand_num);
1648 /* Now the condition that an operand value must be a constant.... */
1649 for (op1 = initial_insn->t.operand_map.head; op1 != NULL; op1 = op1->next)
1651 if (op_is_constant (op1))
1653 append_constant_value_condition (tr,
1656 op_get_constant (op1));
1661 /* Now add the explicit preconditions listed after the "|" in the spec.
1662 These are currently very limited, so we do a special case
1663 parse for them. We expect spaces, opname != opname. */
1664 for (precond = initial_insn->preconds.head;
1666 precond = precond->next)
1671 if (precond->opname1)
1673 op1 = get_opmatch (&initial_insn->t.operand_map, precond->opname1);
1675 as_fatal (_("opcode '%s': no bound opname '%s' "
1676 "for precondition in '%s'"),
1677 xtensa_opcode_name (isa, opcode),
1678 precond->opname1, from_string);
1681 if (precond->opname2)
1683 op2 = get_opmatch (&initial_insn->t.operand_map, precond->opname2);
1685 as_fatal (_("opcode '%s': no bound opname '%s' "
1686 "for precondition in '%s'"),
1687 xtensa_opcode_name (isa, opcode),
1688 precond->opname2, from_string);
1691 if (op1 == NULL && op2 == NULL)
1692 as_fatal (_("opcode '%s': precondition only contains "
1693 "constants in '%s'"),
1694 xtensa_opcode_name (isa, opcode), from_string);
1695 else if (op1 != NULL && op2 != NULL)
1696 append_value_condition (tr, precond->cmpop,
1697 op1->operand_num, op2->operand_num);
1698 else if (op2 == NULL)
1699 append_constant_value_condition (tr, precond->cmpop,
1700 op1->operand_num, precond->opval2);
1702 append_constant_value_condition (tr, precond->cmpop,
1703 op2->operand_num, precond->opval1);
1706 tr->options = clone_req_option_list (initial_insn->options);
1708 /* Generate the replacement instructions. Some of these
1709 "instructions" are actually labels and literals. There can be at
1710 most one literal and at most one label. A literal must be defined
1711 (e.g., "LITERAL %imm") before use (e.g., "%LITERAL"). The labels
1712 can be used before they are defined. Also there are a number of
1713 special operands (e.g., HI24S). */
1716 for (r = replace_insns->head; r != NULL; r = r->next)
1719 const char *opcode_name;
1722 const char *fn_name;
1723 const char *operand_arg_name;
1725 bi = XNEW (BuildInstr);
1726 append_build_insn (tr, bi);
1728 bi->opcode = XTENSA_UNDEFINED;
1732 opcode_name = r->t.opcode_name;
1733 operand_count = insn_templ_operand_count (&r->t);
1735 if (strcmp (opcode_name, "LITERAL") == 0)
1737 bi->typ = INSTR_LITERAL_DEF;
1738 if (operand_count != 1)
1739 as_fatal (_("expected one operand for generated literal"));
1742 else if (strcmp (opcode_name, "LABEL") == 0)
1744 bi->typ = INSTR_LABEL_DEF;
1745 if (operand_count != 0)
1746 as_fatal (_("expected 0 operands for generated label"));
1750 bi->typ = INSTR_INSTR;
1751 if (wide_branch_opcode (opcode_name, ".w18", &bi->opcode)
1752 || wide_branch_opcode (opcode_name, ".w15", &bi->opcode))
1753 opcode_name = xtensa_opcode_name (isa, bi->opcode);
1755 bi->opcode = xtensa_opcode_lookup (isa, opcode_name);
1757 if (bi->opcode == XTENSA_UNDEFINED)
1759 as_warn (_("invalid opcode '%s' in transition rule '%s'"),
1760 opcode_name, to_string);
1764 /* Check for the right number of ops. */
1765 if (xtensa_opcode_num_operands (isa, bi->opcode)
1766 != (int) operand_count)
1767 as_fatal (_("opcode '%s': replacement does not have %d ops"),
1769 xtensa_opcode_num_operands (isa, bi->opcode));
1772 for (op = r->t.operand_map.head; op != NULL; op = op->next)
1776 if (op_is_constant (op))
1777 append_constant_op (bi, op->operand_num, op_get_constant (op));
1778 else if (strcmp (op->operand_name, "%LITERAL") == 0)
1780 if (! literal_bi || ! literal_bi->ops || literal_bi->ops->next)
1781 as_fatal (_("opcode '%s': cannot find literal definition"),
1783 append_literal_op (bi, op->operand_num,
1784 literal_bi->ops->op_data);
1786 else if (strcmp (op->operand_name, "%LABEL") == 0)
1787 append_label_op (bi, op->operand_num);
1788 else if (op->operand_name[0] == 'a'
1789 && parse_constant (op->operand_name + 1, &idnum))
1790 append_constant_op (bi, op->operand_num, idnum);
1791 else if (op->operand_name[0] == '%')
1793 opname_map_e *orig_op;
1794 orig_op = get_opmatch (&initial_insn->t.operand_map,
1796 if (orig_op == NULL)
1797 as_fatal (_("opcode '%s': unidentified operand '%s' in '%s'"),
1798 opcode_name, op->operand_name, to_string);
1799 append_field_op (bi, op->operand_num, orig_op->operand_num);
1801 else if (strcmp (op->operand_name, "FREEREG") == 0)
1803 append_user_fn_field_op (bi, op->operand_num, OP_FREEREG, 0);
1805 else if (parse_special_fn (op->operand_name,
1806 &fn_name, &operand_arg_name))
1808 opname_map_e *orig_op;
1809 OpType typ = OP_CONSTANT;
1811 if (strcmp (fn_name, "LOW8") == 0)
1812 typ = OP_OPERAND_LOW8;
1813 else if (strcmp (fn_name, "HI24S") == 0)
1814 typ = OP_OPERAND_HI24S;
1815 else if (strcmp (fn_name, "F32MINUS") == 0)
1816 typ = OP_OPERAND_F32MINUS;
1817 else if (strcmp (fn_name, "LOW16U") == 0)
1818 typ = OP_OPERAND_LOW16U;
1819 else if (strcmp (fn_name, "HI16U") == 0)
1820 typ = OP_OPERAND_HI16U;
1822 as_fatal (_("unknown user-defined function %s"), fn_name);
1824 orig_op = get_opmatch (&initial_insn->t.operand_map,
1826 if (orig_op == NULL)
1827 as_fatal (_("opcode '%s': unidentified operand '%s' in '%s'"),
1828 opcode_name, op->operand_name, to_string);
1829 append_user_fn_field_op (bi, op->operand_num,
1830 typ, orig_op->operand_num);
1833 as_fatal (_("opcode '%s': could not parse operand '%s' in '%s'"),
1834 opcode_name, op->operand_name, to_string);
1842 static TransitionTable *
1843 build_transition_table (const string_pattern_pair *transitions,
1844 int transition_count,
1845 transition_cmp_fn cmp)
1847 TransitionTable *table = NULL;
1848 int num_opcodes = xtensa_isa_num_opcodes (xtensa_default_isa);
1854 /* Otherwise, build it now. */
1855 table = XNEW (TransitionTable);
1856 table->num_opcodes = num_opcodes;
1857 table->table = XNEWVEC (TransitionList *, num_opcodes);
1859 for (i = 0; i < num_opcodes; i++)
1860 table->table[i] = NULL;
1862 for (tnum = 0; tnum < transition_count; tnum++)
1864 const char *from_string = transitions[tnum].pattern;
1865 const char *to_string = transitions[tnum].replacement;
1867 insn_pattern initial_insn;
1868 insn_repl replace_insns;
1871 init_insn_pattern (&initial_insn);
1872 if (!parse_insn_pattern (from_string, &initial_insn))
1873 as_fatal (_("could not parse INSN_PATTERN '%s'"), from_string);
1875 init_insn_repl (&replace_insns);
1876 if (!parse_insn_repl (to_string, &replace_insns))
1877 as_fatal (_("could not parse INSN_REPL '%s'"), to_string);
1879 if (transition_applies (&initial_insn, from_string, to_string))
1881 tr = build_transition (&initial_insn, &replace_insns,
1882 from_string, to_string);
1884 append_transition (table, tr->opcode, tr, cmp);
1888 as_warn (_("could not build transition for %s => %s"),
1889 from_string, to_string);
1894 clear_insn_repl (&replace_insns);
1895 clear_insn_pattern (&initial_insn);
1901 extern TransitionTable *
1902 xg_build_widen_table (transition_cmp_fn cmp)
1904 static TransitionTable *table = NULL;
1906 table = build_transition_table (widen_spec_list, WIDEN_COUNT, cmp);
1911 extern TransitionTable *
1912 xg_build_simplify_table (transition_cmp_fn cmp)
1914 static TransitionTable *table = NULL;
1916 table = build_transition_table (simplify_spec_list, SIMPLIFY_COUNT, cmp);