1 /* Table of relaxations for Xtensa assembly.
2 Copyright (C) 2003-2016 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
= (TransitionList
*) xmalloc (sizeof (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
=
558 (PreconditionList
*) xmalloc (sizeof (PreconditionList
));
559 PreconditionList
*prev
= tr
->conditions
;
560 PreconditionList
*nxt
;
580 append_value_condition (TransitionRule
*tr
,
585 Precondition
*cond
= (Precondition
*) xmalloc (sizeof (Precondition
));
589 cond
->typ
= OP_OPERAND
;
591 append_condition (tr
, cond
);
596 append_constant_value_condition (TransitionRule
*tr
,
601 Precondition
*cond
= (Precondition
*) xmalloc (sizeof (Precondition
));
605 cond
->typ
= OP_CONSTANT
;
606 cond
->op_data
= cnst
;
607 append_condition (tr
, cond
);
612 append_build_insn (TransitionRule
*tr
, BuildInstr
*bi
)
614 BuildInstr
*prev
= tr
->to_instr
;
634 append_op (BuildInstr
*bi
, BuildOp
*b_op
)
636 BuildOp
*prev
= bi
->ops
;
655 append_literal_op (BuildInstr
*bi
, unsigned op1
, unsigned src_op
)
657 BuildOp
*b_op
= (BuildOp
*) xmalloc (sizeof (BuildOp
));
660 b_op
->typ
= OP_LITERAL
;
661 b_op
->op_data
= src_op
;
663 append_op (bi
, b_op
);
668 append_label_op (BuildInstr
*bi
, unsigned op1
)
670 BuildOp
*b_op
= (BuildOp
*) xmalloc (sizeof (BuildOp
));
673 b_op
->typ
= OP_LABEL
;
676 append_op (bi
, b_op
);
681 append_constant_op (BuildInstr
*bi
, unsigned op1
, unsigned cnst
)
683 BuildOp
*b_op
= (BuildOp
*) xmalloc (sizeof (BuildOp
));
686 b_op
->typ
= OP_CONSTANT
;
687 b_op
->op_data
= cnst
;
689 append_op (bi
, b_op
);
694 append_field_op (BuildInstr
*bi
, unsigned op1
, unsigned src_op
)
696 BuildOp
*b_op
= (BuildOp
*) xmalloc (sizeof (BuildOp
));
699 b_op
->typ
= OP_OPERAND
;
700 b_op
->op_data
= src_op
;
702 append_op (bi
, b_op
);
706 /* These could be generated but are not currently. */
709 append_user_fn_field_op (BuildInstr
*bi
,
714 BuildOp
*b_op
= (BuildOp
*) xmalloc (sizeof (BuildOp
));
718 b_op
->op_data
= src_op
;
720 append_op (bi
, b_op
);
724 /* These operand functions are the semantics of user-defined
725 operand functions. */
728 operand_function_HI24S (long a
)
731 return (a
& (~0xff)) + 0x100;
733 return (a
& (~0xff));
738 operand_function_F32MINUS (long a
)
745 operand_function_LOW8 (long a
)
748 return (a
& 0xff) | ~0xff;
755 operand_function_LOW16U (long a
)
762 operand_function_HI16U (long a
)
764 unsigned long b
= a
& 0xffff0000;
765 return (long) (b
>> 16);
770 xg_has_userdef_op_fn (OpType op
)
774 case OP_OPERAND_F32MINUS
:
775 case OP_OPERAND_LOW8
:
776 case OP_OPERAND_HI24S
:
777 case OP_OPERAND_LOW16U
:
778 case OP_OPERAND_HI16U
:
788 xg_apply_userdef_op_fn (OpType op
, long a
)
792 case OP_OPERAND_F32MINUS
:
793 return operand_function_F32MINUS (a
);
794 case OP_OPERAND_LOW8
:
795 return operand_function_LOW8 (a
);
796 case OP_OPERAND_HI24S
:
797 return operand_function_HI24S (a
);
798 case OP_OPERAND_LOW16U
:
799 return operand_function_LOW16U (a
);
800 case OP_OPERAND_HI16U
:
801 return operand_function_HI16U (a
);
809 /* Generate a transition table. */
812 enter_opname_n (const char *name
, int len
)
816 for (op
= local_opnames
; op
!= NULL
; op
= op
->next
)
818 if (strlen (op
->opname
) == (unsigned) len
819 && strncmp (op
->opname
, name
, len
) == 0)
822 op
= (opname_e
*) xmalloc (sizeof (opname_e
));
823 op
->opname
= xmemdup0 (name
, len
);
829 enter_opname (const char *name
)
833 for (op
= local_opnames
; op
!= NULL
; op
= op
->next
)
835 if (strcmp (op
->opname
, name
) == 0)
838 op
= (opname_e
*) xmalloc (sizeof (opname_e
));
839 op
->opname
= xstrdup (name
);
845 init_opname_map (opname_map
*m
)
853 clear_opname_map (opname_map
*m
)
857 while (m
->head
!= NULL
)
868 same_operand_name (const opname_map_e
*m1
, const opname_map_e
*m2
)
870 if (m1
->operand_name
== NULL
|| m2
->operand_name
== NULL
)
872 return (m1
->operand_name
== m2
->operand_name
);
876 static opname_map_e
*
877 get_opmatch (opname_map
*map
, const char *operand_name
)
881 for (m
= map
->head
; m
!= NULL
; m
= m
->next
)
883 if (strcmp (m
->operand_name
, operand_name
) == 0)
891 op_is_constant (const opname_map_e
*m1
)
893 return (m1
->operand_name
== NULL
);
898 op_get_constant (const opname_map_e
*m1
)
900 gas_assert (m1
->operand_name
== NULL
);
901 return m1
->constant_value
;
906 init_precond_list (precond_list
*l
)
914 clear_precond_list (precond_list
*l
)
918 while (l
->head
!= NULL
)
929 init_insn_templ (insn_templ
*t
)
931 t
->opcode_name
= NULL
;
932 init_opname_map (&t
->operand_map
);
937 clear_insn_templ (insn_templ
*t
)
939 clear_opname_map (&t
->operand_map
);
944 init_insn_pattern (insn_pattern
*p
)
946 init_insn_templ (&p
->t
);
947 init_precond_list (&p
->preconds
);
953 clear_insn_pattern (insn_pattern
*p
)
955 clear_insn_templ (&p
->t
);
956 clear_precond_list (&p
->preconds
);
961 init_insn_repl (insn_repl
*r
)
969 clear_insn_repl (insn_repl
*r
)
973 while (r
->head
!= NULL
)
977 clear_insn_templ (&e
->t
);
984 insn_templ_operand_count (const insn_templ
*t
)
987 const opname_map_e
*op
;
989 for (op
= t
->operand_map
.head
; op
!= NULL
; op
= op
->next
, i
++)
995 /* Convert a string to a number. E.G.: parse_constant("10", &num) */
998 parse_constant (const char *in
, unsigned *val_p
)
1009 if (*p
>= '0' && *p
<= '9')
1010 val
= val
* 10 + (*p
- '0');
1021 parse_special_fn (const char *name
,
1022 const char **fn_name_p
,
1023 const char **arg_name_p
)
1025 const char *p_start
;
1028 p_start
= strchr (name
, '(');
1029 if (p_start
== NULL
)
1032 p_end
= strchr (p_start
, ')');
1037 if (p_end
[1] != '\0')
1040 *fn_name_p
= enter_opname_n (name
, p_start
- name
);
1041 *arg_name_p
= enter_opname_n (p_start
+ 1, p_end
- p_start
- 1);
1047 skip_white (const char *p
)
1058 trim_whitespace (char *in
)
1060 char *last_white
= NULL
;
1063 while (p
&& *p
!= '\0')
1067 if (last_white
== NULL
)
1082 /* Split a string into component strings where "c" is the
1083 delimiter. Place the result in the split_rec. */
1086 split_string (split_rec
*rec
,
1089 bfd_boolean elide_whitespace
)
1095 while (p
!= NULL
&& *p
!= '\0')
1105 if (rec
->count
== 0)
1108 rec
->vec
= (char **) xmalloc (sizeof (char *) * cnt
);
1109 for (i
= 0; i
< cnt
; i
++)
1113 for (i
= 0; i
< cnt
; i
++)
1119 if (elide_whitespace
)
1124 rec
->vec
[i
] = xstrdup (q
);
1128 rec
->vec
[i
] = xmemdup0 (q
, len
);
1132 if (elide_whitespace
)
1133 trim_whitespace (rec
->vec
[i
]);
1139 clear_split_rec (split_rec
*rec
)
1143 for (i
= 0; i
< rec
->count
; i
++)
1151 /* Initialize a split record. The split record must be initialized
1152 before split_string is called. */
1155 init_split_rec (split_rec
*rec
)
1162 /* Parse an instruction template like "insn op1, op2, op3". */
1165 parse_insn_templ (const char *s
, insn_templ
*t
)
1172 /* First find the first whitespace. */
1174 init_split_rec (&oprec
);
1177 insn_name_len
= strcspn (s
, " ");
1178 if (insn_name_len
== 0)
1181 init_insn_templ (t
);
1182 t
->opcode_name
= enter_opname_n (p
, insn_name_len
);
1184 p
= p
+ insn_name_len
;
1186 /* Split by ',' and skip beginning and trailing whitespace. */
1187 split_string (&oprec
, p
, ',', TRUE
);
1189 for (i
= 0; i
< oprec
.count
; i
++)
1191 const char *opname
= oprec
.vec
[i
];
1192 opname_map_e
*e
= (opname_map_e
*) xmalloc (sizeof (opname_map_e
));
1194 e
->operand_name
= NULL
;
1195 e
->constant_value
= 0;
1198 /* If it begins with a number, assume that it is a number. */
1199 if (opname
&& opname
[0] >= '0' && opname
[0] <= '9')
1203 if (parse_constant (opname
, &val
))
1204 e
->constant_value
= val
;
1208 clear_split_rec (&oprec
);
1209 clear_insn_templ (t
);
1214 e
->operand_name
= enter_opname (oprec
.vec
[i
]);
1216 *t
->operand_map
.tail
= e
;
1217 t
->operand_map
.tail
= &e
->next
;
1219 clear_split_rec (&oprec
);
1225 parse_precond (const char *s
, precond_e
*precond
)
1227 /* All preconditions are currently of the form:
1228 a == b or a != b or a == k (where k is a constant).
1229 Later we may use some special functions like DENSITY == 1
1230 to identify when density is available. */
1234 precond
->opname1
= NULL
;
1235 precond
->opval1
= 0;
1236 precond
->cmpop
= OP_EQUAL
;
1237 precond
->opname2
= NULL
;
1238 precond
->opval2
= 0;
1239 precond
->next
= NULL
;
1243 len
= strcspn (p
, " !=");
1248 precond
->opname1
= enter_opname_n (p
, len
);
1252 /* Check for "==" and "!=". */
1253 if (strncmp (p
, "==", 2) == 0)
1254 precond
->cmpop
= OP_EQUAL
;
1255 else if (strncmp (p
, "!=", 2) == 0)
1256 precond
->cmpop
= OP_NOTEQUAL
;
1263 /* No trailing whitespace from earlier parsing. */
1264 if (p
[0] >= '0' && p
[0] <= '9')
1267 if (parse_constant (p
, &val
))
1268 precond
->opval2
= val
;
1273 precond
->opname2
= enter_opname (p
);
1279 clear_req_or_option_list (ReqOrOption
**r_p
)
1284 free ((*r_p
)->option_name
);
1285 clear_req_or_option_list (&(*r_p
)->next
);
1291 clear_req_option_list (ReqOption
**r_p
)
1296 clear_req_or_option_list (&(*r_p
)->or_option_terms
);
1297 clear_req_option_list (&(*r_p
)->next
);
1302 static ReqOrOption
*
1303 clone_req_or_option_list (ReqOrOption
*req_or_option
)
1305 ReqOrOption
*new_req_or_option
;
1307 if (req_or_option
== NULL
)
1310 new_req_or_option
= (ReqOrOption
*) xmalloc (sizeof (ReqOrOption
));
1311 new_req_or_option
->option_name
= xstrdup (req_or_option
->option_name
);
1312 new_req_or_option
->is_true
= req_or_option
->is_true
;
1313 new_req_or_option
->next
= NULL
;
1314 new_req_or_option
->next
= clone_req_or_option_list (req_or_option
->next
);
1315 return new_req_or_option
;
1320 clone_req_option_list (ReqOption
*req_option
)
1322 ReqOption
*new_req_option
;
1324 if (req_option
== NULL
)
1327 new_req_option
= (ReqOption
*) xmalloc (sizeof (ReqOption
));
1328 new_req_option
->or_option_terms
= NULL
;
1329 new_req_option
->next
= NULL
;
1330 new_req_option
->or_option_terms
=
1331 clone_req_or_option_list (req_option
->or_option_terms
);
1332 new_req_option
->next
= clone_req_option_list (req_option
->next
);
1333 return new_req_option
;
1338 parse_option_cond (const char *s
, ReqOption
*option
)
1341 split_rec option_term_rec
;
1343 /* All option or conditions are of the form:
1344 optionA + no-optionB + ...
1345 "Ands" are divided by "?". */
1347 init_split_rec (&option_term_rec
);
1348 split_string (&option_term_rec
, s
, '+', TRUE
);
1350 if (option_term_rec
.count
== 0)
1352 clear_split_rec (&option_term_rec
);
1356 for (i
= 0; i
< option_term_rec
.count
; i
++)
1358 char *option_name
= option_term_rec
.vec
[i
];
1359 bfd_boolean is_true
= TRUE
;
1363 if (strncmp (option_name
, "no-", 3) == 0)
1365 option_name
= xstrdup (&option_name
[3]);
1369 option_name
= xstrdup (option_name
);
1371 req
= (ReqOrOption
*) xmalloc (sizeof (ReqOrOption
));
1372 req
->option_name
= option_name
;
1373 req
->is_true
= is_true
;
1376 /* Append to list. */
1377 for (r_p
= &option
->or_option_terms
; (*r_p
) != NULL
;
1378 r_p
= &(*r_p
)->next
)
1386 /* Parse a string like:
1387 "insn op1, op2, op3, op4 | op1 != op2 | op2 == op3 | op4 == 1".
1388 I.E., instruction "insn" with 4 operands where operand 1 and 2 are not
1389 the same and operand 2 and 3 are the same and operand 4 is 1.
1393 "insn op1 | op1 == 1 / density + boolean / no-useroption".
1394 i.e. instruction "insn" with 1 operands where operand 1 is 1
1395 when "density" or "boolean" options are available and
1396 "useroption" is not available.
1398 Because the current implementation of this parsing scheme uses
1399 split_string, it requires that '|' and '?' are only used as
1400 delimiters for predicates and required options. */
1403 parse_insn_pattern (const char *in
, insn_pattern
*insn
)
1406 split_rec optionrec
;
1409 init_insn_pattern (insn
);
1411 init_split_rec (&optionrec
);
1412 split_string (&optionrec
, in
, '?', TRUE
);
1413 if (optionrec
.count
== 0)
1415 clear_split_rec (&optionrec
);
1419 init_split_rec (&rec
);
1421 split_string (&rec
, optionrec
.vec
[0], '|', TRUE
);
1425 clear_split_rec (&rec
);
1426 clear_split_rec (&optionrec
);
1430 if (!parse_insn_templ (rec
.vec
[0], &insn
->t
))
1432 clear_split_rec (&rec
);
1433 clear_split_rec (&optionrec
);
1437 for (i
= 1; i
< rec
.count
; i
++)
1439 precond_e
*cond
= (precond_e
*) xmalloc (sizeof (precond_e
));
1441 if (!parse_precond (rec
.vec
[i
], cond
))
1443 clear_split_rec (&rec
);
1444 clear_split_rec (&optionrec
);
1445 clear_insn_pattern (insn
);
1449 /* Append the condition. */
1450 *insn
->preconds
.tail
= cond
;
1451 insn
->preconds
.tail
= &cond
->next
;
1454 for (i
= 1; i
< optionrec
.count
; i
++)
1456 /* Handle the option conditions. */
1458 ReqOption
*req_option
= (ReqOption
*) xmalloc (sizeof (ReqOption
));
1459 req_option
->or_option_terms
= NULL
;
1460 req_option
->next
= NULL
;
1462 if (!parse_option_cond (optionrec
.vec
[i
], req_option
))
1464 clear_split_rec (&rec
);
1465 clear_split_rec (&optionrec
);
1466 clear_insn_pattern (insn
);
1467 clear_req_option_list (&req_option
);
1471 /* Append the condition. */
1472 for (r_p
= &insn
->options
; (*r_p
) != NULL
; r_p
= &(*r_p
)->next
)
1475 (*r_p
) = req_option
;
1478 clear_split_rec (&rec
);
1479 clear_split_rec (&optionrec
);
1485 parse_insn_repl (const char *in
, insn_repl
*r_p
)
1487 /* This is a list of instruction templates separated by ';'. */
1491 split_string (&rec
, in
, ';', TRUE
);
1493 for (i
= 0; i
< rec
.count
; i
++)
1495 insn_repl_e
*e
= (insn_repl_e
*) xmalloc (sizeof (insn_repl_e
));
1499 if (!parse_insn_templ (rec
.vec
[i
], &e
->t
))
1502 clear_insn_repl (r_p
);
1506 r_p
->tail
= &e
->next
;
1513 transition_applies (insn_pattern
*initial_insn
,
1514 const char *from_string ATTRIBUTE_UNUSED
,
1515 const char *to_string ATTRIBUTE_UNUSED
)
1517 ReqOption
*req_option
;
1519 for (req_option
= initial_insn
->options
;
1521 req_option
= req_option
->next
)
1523 ReqOrOption
*req_or_option
= req_option
->or_option_terms
;
1525 if (req_or_option
== NULL
1526 || req_or_option
->next
!= NULL
)
1529 if (strncmp (req_or_option
->option_name
, "IsaUse", 6) == 0)
1531 bfd_boolean option_available
= FALSE
;
1532 char *option_name
= req_or_option
->option_name
+ 6;
1533 if (!strcmp (option_name
, "DensityInstruction"))
1534 option_available
= (XCHAL_HAVE_DENSITY
== 1);
1535 else if (!strcmp (option_name
, "L32R"))
1536 option_available
= (XCHAL_HAVE_L32R
== 1);
1537 else if (!strcmp (option_name
, "Const16"))
1538 option_available
= (XCHAL_HAVE_CONST16
== 1);
1539 else if (!strcmp (option_name
, "Loops"))
1540 option_available
= (XCHAL_HAVE_LOOPS
== 1);
1541 else if (!strcmp (option_name
, "WideBranches"))
1543 = (XCHAL_HAVE_WIDE_BRANCHES
== 1 && produce_flix
== FLIX_ALL
);
1544 else if (!strcmp (option_name
, "PredictedBranches"))
1546 = (XCHAL_HAVE_PREDICTED_BRANCHES
== 1
1547 && produce_flix
== FLIX_ALL
);
1548 else if (!strcmp (option_name
, "Booleans"))
1549 option_available
= (XCHAL_HAVE_BOOLEANS
== 1);
1551 as_warn (_("invalid configuration option '%s' in transition rule '%s'"),
1552 req_or_option
->option_name
, from_string
);
1553 if ((option_available
^ req_or_option
->is_true
) != 0)
1556 else if (strcmp (req_or_option
->option_name
, "realnop") == 0)
1558 bfd_boolean nop_available
=
1559 (xtensa_opcode_lookup (xtensa_default_isa
, "nop")
1560 != XTENSA_UNDEFINED
);
1561 if ((nop_available
^ req_or_option
->is_true
) != 0)
1570 wide_branch_opcode (const char *opcode_name
,
1572 xtensa_opcode
*popcode
)
1574 xtensa_isa isa
= xtensa_default_isa
;
1575 xtensa_opcode opcode
;
1576 static char wbr_name_buf
[20];
1578 if (strncmp (opcode_name
, "WIDE.", 5) != 0)
1581 strcpy (wbr_name_buf
, opcode_name
+ 5);
1582 strcat (wbr_name_buf
, suffix
);
1583 opcode
= xtensa_opcode_lookup (isa
, wbr_name_buf
);
1584 if (opcode
!= XTENSA_UNDEFINED
)
1594 static TransitionRule
*
1595 build_transition (insn_pattern
*initial_insn
,
1596 insn_repl
*replace_insns
,
1597 const char *from_string
,
1598 const char *to_string
)
1600 TransitionRule
*tr
= NULL
;
1601 xtensa_opcode opcode
;
1602 xtensa_isa isa
= xtensa_default_isa
;
1603 BuildInstr
*literal_bi
;
1611 if (!wide_branch_opcode (initial_insn
->t
.opcode_name
, ".w18", &opcode
)
1612 && !wide_branch_opcode (initial_insn
->t
.opcode_name
, ".w15", &opcode
))
1613 opcode
= xtensa_opcode_lookup (isa
, initial_insn
->t
.opcode_name
);
1615 if (opcode
== XTENSA_UNDEFINED
)
1617 /* It is OK to not be able to translate some of these opcodes. */
1622 if (xtensa_opcode_num_operands (isa
, opcode
)
1623 != insn_templ_operand_count (&initial_insn
->t
))
1625 /* This is also OK because there are opcodes that
1626 have different numbers of operands on different
1627 architecture variations. */
1631 tr
= (TransitionRule
*) xmalloc (sizeof (TransitionRule
));
1632 tr
->opcode
= opcode
;
1633 tr
->conditions
= NULL
;
1634 tr
->to_instr
= NULL
;
1636 /* Build the conditions. First, equivalent operand condition.... */
1637 for (op1
= initial_insn
->t
.operand_map
.head
; op1
!= NULL
; op1
= op1
->next
)
1639 for (op2
= op1
->next
; op2
!= NULL
; op2
= op2
->next
)
1641 if (same_operand_name (op1
, op2
))
1643 append_value_condition (tr
, OP_EQUAL
,
1644 op1
->operand_num
, op2
->operand_num
);
1649 /* Now the condition that an operand value must be a constant.... */
1650 for (op1
= initial_insn
->t
.operand_map
.head
; op1
!= NULL
; op1
= op1
->next
)
1652 if (op_is_constant (op1
))
1654 append_constant_value_condition (tr
,
1657 op_get_constant (op1
));
1662 /* Now add the explicit preconditions listed after the "|" in the spec.
1663 These are currently very limited, so we do a special case
1664 parse for them. We expect spaces, opname != opname. */
1665 for (precond
= initial_insn
->preconds
.head
;
1667 precond
= precond
->next
)
1672 if (precond
->opname1
)
1674 op1
= get_opmatch (&initial_insn
->t
.operand_map
, precond
->opname1
);
1676 as_fatal (_("opcode '%s': no bound opname '%s' "
1677 "for precondition in '%s'"),
1678 xtensa_opcode_name (isa
, opcode
),
1679 precond
->opname1
, from_string
);
1682 if (precond
->opname2
)
1684 op2
= get_opmatch (&initial_insn
->t
.operand_map
, precond
->opname2
);
1686 as_fatal (_("opcode '%s': no bound opname '%s' "
1687 "for precondition in %s"),
1688 xtensa_opcode_name (isa
, opcode
),
1689 precond
->opname2
, from_string
);
1692 if (op1
== NULL
&& op2
== NULL
)
1693 as_fatal (_("opcode '%s': precondition only contains "
1694 "constants in '%s'"),
1695 xtensa_opcode_name (isa
, opcode
), from_string
);
1696 else if (op1
!= NULL
&& op2
!= NULL
)
1697 append_value_condition (tr
, precond
->cmpop
,
1698 op1
->operand_num
, op2
->operand_num
);
1699 else if (op2
== NULL
)
1700 append_constant_value_condition (tr
, precond
->cmpop
,
1701 op1
->operand_num
, precond
->opval2
);
1703 append_constant_value_condition (tr
, precond
->cmpop
,
1704 op2
->operand_num
, precond
->opval1
);
1707 tr
->options
= clone_req_option_list (initial_insn
->options
);
1709 /* Generate the replacement instructions. Some of these
1710 "instructions" are actually labels and literals. There can be at
1711 most one literal and at most one label. A literal must be defined
1712 (e.g., "LITERAL %imm") before use (e.g., "%LITERAL"). The labels
1713 can be used before they are defined. Also there are a number of
1714 special operands (e.g., HI24S). */
1717 for (r
= replace_insns
->head
; r
!= NULL
; r
= r
->next
)
1720 const char *opcode_name
;
1723 const char *fn_name
;
1724 const char *operand_arg_name
;
1726 bi
= (BuildInstr
*) xmalloc (sizeof (BuildInstr
));
1727 append_build_insn (tr
, bi
);
1729 bi
->opcode
= XTENSA_UNDEFINED
;
1733 opcode_name
= r
->t
.opcode_name
;
1734 operand_count
= insn_templ_operand_count (&r
->t
);
1736 if (strcmp (opcode_name
, "LITERAL") == 0)
1738 bi
->typ
= INSTR_LITERAL_DEF
;
1739 if (operand_count
!= 1)
1740 as_fatal (_("expected one operand for generated literal"));
1743 else if (strcmp (opcode_name
, "LABEL") == 0)
1745 bi
->typ
= INSTR_LABEL_DEF
;
1746 if (operand_count
!= 0)
1747 as_fatal (_("expected 0 operands for generated label"));
1751 bi
->typ
= INSTR_INSTR
;
1752 if (wide_branch_opcode (opcode_name
, ".w18", &bi
->opcode
)
1753 || wide_branch_opcode (opcode_name
, ".w15", &bi
->opcode
))
1754 opcode_name
= xtensa_opcode_name (isa
, bi
->opcode
);
1756 bi
->opcode
= xtensa_opcode_lookup (isa
, opcode_name
);
1758 if (bi
->opcode
== XTENSA_UNDEFINED
)
1760 as_warn (_("invalid opcode '%s' in transition rule '%s'"),
1761 opcode_name
, to_string
);
1765 /* Check for the right number of ops. */
1766 if (xtensa_opcode_num_operands (isa
, bi
->opcode
)
1767 != (int) operand_count
)
1768 as_fatal (_("opcode '%s': replacement does not have %d ops"),
1770 xtensa_opcode_num_operands (isa
, bi
->opcode
));
1773 for (op
= r
->t
.operand_map
.head
; op
!= NULL
; op
= op
->next
)
1777 if (op_is_constant (op
))
1778 append_constant_op (bi
, op
->operand_num
, op_get_constant (op
));
1779 else if (strcmp (op
->operand_name
, "%LITERAL") == 0)
1781 if (! literal_bi
|| ! literal_bi
->ops
|| literal_bi
->ops
->next
)
1782 as_fatal (_("opcode '%s': cannot find literal definition"),
1784 append_literal_op (bi
, op
->operand_num
,
1785 literal_bi
->ops
->op_data
);
1787 else if (strcmp (op
->operand_name
, "%LABEL") == 0)
1788 append_label_op (bi
, op
->operand_num
);
1789 else if (op
->operand_name
[0] == 'a'
1790 && parse_constant (op
->operand_name
+ 1, &idnum
))
1791 append_constant_op (bi
, op
->operand_num
, idnum
);
1792 else if (op
->operand_name
[0] == '%')
1794 opname_map_e
*orig_op
;
1795 orig_op
= get_opmatch (&initial_insn
->t
.operand_map
,
1797 if (orig_op
== NULL
)
1798 as_fatal (_("opcode %s: unidentified operand '%s' in '%s'"),
1799 opcode_name
, op
->operand_name
, to_string
);
1800 append_field_op (bi
, op
->operand_num
, orig_op
->operand_num
);
1802 else if (strcmp (op
->operand_name
, "FREEREG") == 0)
1804 append_user_fn_field_op (bi
, op
->operand_num
, OP_FREEREG
, 0);
1806 else if (parse_special_fn (op
->operand_name
,
1807 &fn_name
, &operand_arg_name
))
1809 opname_map_e
*orig_op
;
1810 OpType typ
= OP_CONSTANT
;
1812 if (strcmp (fn_name
, "LOW8") == 0)
1813 typ
= OP_OPERAND_LOW8
;
1814 else if (strcmp (fn_name
, "HI24S") == 0)
1815 typ
= OP_OPERAND_HI24S
;
1816 else if (strcmp (fn_name
, "F32MINUS") == 0)
1817 typ
= OP_OPERAND_F32MINUS
;
1818 else if (strcmp (fn_name
, "LOW16U") == 0)
1819 typ
= OP_OPERAND_LOW16U
;
1820 else if (strcmp (fn_name
, "HI16U") == 0)
1821 typ
= OP_OPERAND_HI16U
;
1823 as_fatal (_("unknown user-defined function %s"), fn_name
);
1825 orig_op
= get_opmatch (&initial_insn
->t
.operand_map
,
1827 if (orig_op
== NULL
)
1828 as_fatal (_("opcode %s: unidentified operand '%s' in '%s'"),
1829 opcode_name
, op
->operand_name
, to_string
);
1830 append_user_fn_field_op (bi
, op
->operand_num
,
1831 typ
, orig_op
->operand_num
);
1834 as_fatal (_("opcode %s: could not parse operand '%s' in '%s'"),
1835 opcode_name
, op
->operand_name
, to_string
);
1843 static TransitionTable
*
1844 build_transition_table (const string_pattern_pair
*transitions
,
1845 int transition_count
,
1846 transition_cmp_fn cmp
)
1848 TransitionTable
*table
= NULL
;
1849 int num_opcodes
= xtensa_isa_num_opcodes (xtensa_default_isa
);
1855 /* Otherwise, build it now. */
1856 table
= (TransitionTable
*) xmalloc (sizeof (TransitionTable
));
1857 table
->num_opcodes
= num_opcodes
;
1859 (TransitionList
**) xmalloc (sizeof (TransitionTable
*) * num_opcodes
);
1861 for (i
= 0; i
< num_opcodes
; i
++)
1862 table
->table
[i
] = NULL
;
1864 for (tnum
= 0; tnum
< transition_count
; tnum
++)
1866 const char *from_string
= transitions
[tnum
].pattern
;
1867 const char *to_string
= transitions
[tnum
].replacement
;
1869 insn_pattern initial_insn
;
1870 insn_repl replace_insns
;
1873 init_insn_pattern (&initial_insn
);
1874 if (!parse_insn_pattern (from_string
, &initial_insn
))
1875 as_fatal (_("could not parse INSN_PATTERN '%s'"), from_string
);
1877 init_insn_repl (&replace_insns
);
1878 if (!parse_insn_repl (to_string
, &replace_insns
))
1879 as_fatal (_("could not parse INSN_REPL '%s'"), to_string
);
1881 if (transition_applies (&initial_insn
, from_string
, to_string
))
1883 tr
= build_transition (&initial_insn
, &replace_insns
,
1884 from_string
, to_string
);
1886 append_transition (table
, tr
->opcode
, tr
, cmp
);
1890 as_warn (_("could not build transition for %s => %s"),
1891 from_string
, to_string
);
1896 clear_insn_repl (&replace_insns
);
1897 clear_insn_pattern (&initial_insn
);
1903 extern TransitionTable
*
1904 xg_build_widen_table (transition_cmp_fn cmp
)
1906 static TransitionTable
*table
= NULL
;
1908 table
= build_transition_table (widen_spec_list
, WIDEN_COUNT
, cmp
);
1913 extern TransitionTable
*
1914 xg_build_simplify_table (transition_cmp_fn cmp
)
1916 static TransitionTable
*table
= NULL
;
1918 table
= build_transition_table (simplify_spec_list
, SIMPLIFY_COUNT
, cmp
);