1 /* Table of relaxations for Xtensa assembly.
2 Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009
3 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
22 /* This file contains the code for generating runtime data structures
23 for relaxation pattern matching from statically specified strings.
24 Each action contains an instruction pattern to match and
25 preconditions for the match as well as an expansion if the pattern
26 matches. The preconditions can specify that two operands are the
27 same or an operand is a specific constant or register. The expansion
28 uses the bound variables from the pattern to specify that specific
29 operands from the pattern should be used in the result.
31 The code determines whether the condition applies to a constant or
32 a register depending on the type of the operand. You may get
33 unexpected results if you don't match the rule against the operand
36 The patterns match a language like:
38 INSN_PATTERN ::= INSN_TEMPL ( '|' PRECOND )* ( '?' OPTIONPRED )*
39 INSN_TEMPL ::= OPCODE ' ' [ OPERAND (',' OPERAND)* ]
41 OPERAND ::= CONSTANT | VARIABLE | SPECIALFN '(' VARIABLE ')'
42 SPECIALFN ::= 'HI24S' | 'F32MINUS' | 'LOW8'
45 PRECOND ::= OPERAND CMPOP OPERAND
47 OPTIONPRED ::= OPTIONNAME ('+' OPTIONNAME)
48 OPTIONNAME ::= '"' id '"'
50 The replacement language
51 INSN_REPL ::= INSN_LABEL_LIT ( ';' INSN_LABEL_LIT )*
52 INSN_LABEL_LIT ::= INSN_TEMPL
56 The operands in a PRECOND must be constants or variables bound by
59 The configuration options define a predicate on the availability of
60 options which must be TRUE for this rule to be valid. Examples are
61 requiring "density" for replacements with density instructions,
62 requiring "const16" for replacements that require const16
63 instructions, etc. The names are interpreted by the assembler to a
64 truth value for a particular frag.
66 The operands in the INSN_REPL must be constants, variables bound in
67 the associated INSN_PATTERN, special variables that are bound in
68 the INSN_REPL by LABEL or LITERAL definitions, or special value
69 manipulation functions.
71 A simple example of a replacement pattern:
72 {"movi.n %as,%imm", "movi %as,%imm"} would convert the narrow
73 movi.n instruction to the wide movi instruction.
75 A more complex example of a branch around:
76 {"beqz %as,%label", "bnez %as,%LABEL;j %label;LABEL"}
77 would convert a branch to a negated branch to the following instruction
78 with a jump to the original label.
80 An Xtensa-specific example that generates a literal:
81 {"movi %at,%imm", "LITERAL %imm; l32r %at,%LITERAL"}
82 will convert a movi instruction to an l32r of a literal
83 literal defined in the literal pool.
85 Even more complex is a conversion of a load with immediate offset
86 to a load of a freshly generated literal, an explicit add and
87 a load with 0 offset. This transformation is only valid, though
88 when the first and second operands are not the same as specified
89 by the "| %at!=%as" precondition clause.
90 {"l32i %at,%as,%imm | %at!=%as",
91 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l32i %at,%at,0"}
93 There is special case for loop instructions here, but because we do
94 not currently have the ability to represent the difference of two
95 symbols, the conversion requires special code in the assembler to
96 write the operands of the addi/addmi pair representing the
97 difference of the old and new loop end label. */
100 #include "xtensa-isa.h"
101 #include "xtensa-relax.h"
103 #include "xtensa-config.h"
105 #ifndef XCHAL_HAVE_WIDE_BRANCHES
106 #define XCHAL_HAVE_WIDE_BRANCHES 0
109 /* Imported from bfd. */
110 extern xtensa_isa xtensa_default_isa
;
112 /* The opname_list is a small list of names that we use for opcode and
113 operand variable names to simplify ownership of these commonly used
114 strings. Strings entered in the table can be compared by pointer
117 typedef struct opname_list_struct opname_list
;
118 typedef opname_list opname_e
;
120 struct opname_list_struct
126 static opname_list
*local_opnames
= NULL
;
129 /* The "opname_map" and its element structure "opname_map_e" are used
130 for binding an operand number to a name or a constant. */
132 typedef struct opname_map_e_struct opname_map_e
;
133 typedef struct opname_map_struct opname_map
;
135 struct opname_map_e_struct
137 const char *operand_name
; /* If null, then use constant_value. */
139 unsigned constant_value
;
143 struct opname_map_struct
149 /* The "precond_list" and its element structure "precond_e" represents
150 explicit preconditions comparing operand variables and constants.
151 In the "precond_e" structure, a variable is identified by the name
152 in the "opname" field. If that field is NULL, then the operand
153 is the constant in field "opval". */
155 typedef struct precond_e_struct precond_e
;
156 typedef struct precond_list_struct precond_list
;
158 struct precond_e_struct
168 struct precond_list_struct
175 /* The insn_templ represents the INSN_TEMPL instruction template. It
176 is an opcode name with a list of operands. These are used for
177 instruction patterns and replacement patterns. */
179 typedef struct insn_templ_struct insn_templ
;
180 struct insn_templ_struct
182 const char *opcode_name
;
183 opname_map operand_map
;
187 /* The insn_pattern represents an INSN_PATTERN instruction pattern.
188 It is an instruction template with preconditions that specify when
189 it actually matches a given instruction. */
191 typedef struct insn_pattern_struct insn_pattern
;
192 struct insn_pattern_struct
195 precond_list preconds
;
196 ReqOptionList
*options
;
200 /* The "insn_repl" and associated element structure "insn_repl_e"
201 instruction replacement list is a list of
202 instructions/LITERALS/LABELS with constant operands or operands
203 with names bound to the operand names in the associated pattern. */
205 typedef struct insn_repl_e_struct insn_repl_e
;
206 struct insn_repl_e_struct
212 typedef struct insn_repl_struct insn_repl
;
213 struct insn_repl_struct
220 /* The split_rec is a vector of allocated char * pointers. */
222 typedef struct split_rec_struct split_rec
;
223 struct split_rec_struct
229 /* The "string_pattern_pair" is a set of pairs containing instruction
230 patterns and replacement strings. */
232 typedef struct string_pattern_pair_struct string_pattern_pair
;
233 struct string_pattern_pair_struct
236 const char *replacement
;
240 /* The widen_spec_list is a list of valid substitutions that generate
241 wider representations. These are generally used to specify
242 replacements for instructions whose immediates do not fit their
243 encodings. A valid transition may require multiple steps of
244 one-to-one instruction replacements with a final multiple
245 instruction replacement. As an example, here are the transitions
246 required to replace an 'addi.n' with an 'addi', 'addmi'.
251 => addmi a4, 0x1000, addi a4, 0x10.
253 See the comments in xg_assembly_relax for some important details
254 regarding how these chains must be built. */
256 static string_pattern_pair widen_spec_list
[] =
258 {"add.n %ar,%as,%at ? IsaUseDensityInstruction", "add %ar,%as,%at"},
259 {"addi.n %ar,%as,%imm ? IsaUseDensityInstruction", "addi %ar,%as,%imm"},
260 {"beqz.n %as,%label ? IsaUseDensityInstruction", "beqz %as,%label"},
261 {"bnez.n %as,%label ? IsaUseDensityInstruction", "bnez %as,%label"},
262 {"l32i.n %at,%as,%imm ? IsaUseDensityInstruction", "l32i %at,%as,%imm"},
263 {"mov.n %at,%as ? IsaUseDensityInstruction", "or %at,%as,%as"},
264 {"movi.n %as,%imm ? IsaUseDensityInstruction", "movi %as,%imm"},
265 {"nop.n ? IsaUseDensityInstruction ? realnop", "nop"},
266 {"nop.n ? IsaUseDensityInstruction ? no-realnop", "or 1,1,1"},
267 {"ret.n %as ? IsaUseDensityInstruction", "ret %as"},
268 {"retw.n %as ? IsaUseDensityInstruction", "retw %as"},
269 {"s32i.n %at,%as,%imm ? IsaUseDensityInstruction", "s32i %at,%as,%imm"},
270 {"srli %at,%as,%imm", "extui %at,%as,%imm,F32MINUS(%imm)"},
271 {"slli %ar,%as,0", "or %ar,%as,%as"},
273 /* Widening with literals or const16. */
274 {"movi %at,%imm ? IsaUseL32R ",
275 "LITERAL %imm; l32r %at,%LITERAL"},
276 {"movi %at,%imm ? IsaUseConst16",
277 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm)"},
279 {"addi %ar,%as,%imm", "addmi %ar,%as,%imm"},
280 /* LOW8 is the low 8 bits of the Immed
281 MID8S is the middle 8 bits of the Immed */
282 {"addmi %ar,%as,%imm", "addmi %ar,%as,HI24S(%imm); addi %ar,%ar,LOW8(%imm)"},
284 /* In the end convert to either an l32r or const16. */
285 {"addmi %ar,%as,%imm | %ar!=%as ? IsaUseL32R",
286 "LITERAL %imm; l32r %ar,%LITERAL; add %ar,%as,%ar"},
287 {"addmi %ar,%as,%imm | %ar!=%as ? IsaUseConst16",
288 "const16 %ar,HI16U(%imm); const16 %ar,LOW16U(%imm); add %ar,%as,%ar"},
290 /* Widening the load instructions with too-large immediates */
291 {"l8ui %at,%as,%imm | %at!=%as ? IsaUseL32R",
292 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l8ui %at,%at,0"},
293 {"l16si %at,%as,%imm | %at!=%as ? IsaUseL32R",
294 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l16si %at,%at,0"},
295 {"l16ui %at,%as,%imm | %at!=%as ? IsaUseL32R",
296 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l16ui %at,%at,0"},
297 {"l32i %at,%as,%imm | %at!=%as ? IsaUseL32R",
298 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l32i %at,%at,0"},
300 /* Widening load instructions with const16s. */
301 {"l8ui %at,%as,%imm | %at!=%as ? IsaUseConst16",
302 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l8ui %at,%at,0"},
303 {"l16si %at,%as,%imm | %at!=%as ? IsaUseConst16",
304 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l16si %at,%at,0"},
305 {"l16ui %at,%as,%imm | %at!=%as ? IsaUseConst16",
306 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l16ui %at,%at,0"},
307 {"l32i %at,%as,%imm | %at!=%as ? IsaUseConst16",
308 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l32i %at,%at,0"},
310 /* This is only PART of the loop instruction. In addition,
311 hardcoded into its use is a modification of the final operand in
312 the instruction in bytes 9 and 12. */
313 {"loop %as,%label | %as!=1 ? IsaUseLoops",
315 "rsr.lend %as;" /* LEND */
316 "wsr.lbeg %as;" /* LBEG */
317 "addi %as, %as, 0;" /* lo8(%label-%LABEL1) */
318 "addmi %as, %as, 0;" /* mid8(%label-%LABEL1) */
321 "rsr.lcount %as;" /* LCOUNT */
322 "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */
324 {"loopgtz %as,%label | %as!=1 ? IsaUseLoops",
327 "loopgtz %as,%LABEL;"
328 "rsr.lend %as;" /* LEND */
329 "wsr.lbeg %as;" /* LBEG */
330 "addi %as, %as, 0;" /* lo8(%label-%LABEL1) */
331 "addmi %as, %as, 0;" /* mid8(%label-%LABEL1) */
334 "rsr.lcount %as;" /* LCOUNT */
335 "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */
337 {"loopnez %as,%label | %as!=1 ? IsaUseLoops",
339 "loopnez %as,%LABEL;"
340 "rsr.lend %as;" /* LEND */
341 "wsr.lbeg %as;" /* LBEG */
342 "addi %as, %as, 0;" /* lo8(%label-%LABEL1) */
343 "addmi %as, %as, 0;" /* mid8(%label-%LABEL1) */
346 "rsr.lcount %as;" /* LCOUNT */
347 "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */
350 /* Relaxing to wide branches. Order is important here. With wide
351 branches, there is more than one correct relaxation for an
352 out-of-range branch. Put the wide branch relaxations first in the
353 table since they are more efficient than the branch-around
356 {"beqz %as,%label ? IsaUseWideBranches", "WIDE.beqz %as,%label"},
357 {"bnez %as,%label ? IsaUseWideBranches", "WIDE.bnez %as,%label"},
358 {"bgez %as,%label ? IsaUseWideBranches", "WIDE.bgez %as,%label"},
359 {"bltz %as,%label ? IsaUseWideBranches", "WIDE.bltz %as,%label"},
360 {"beqi %as,%imm,%label ? IsaUseWideBranches", "WIDE.beqi %as,%imm,%label"},
361 {"bnei %as,%imm,%label ? IsaUseWideBranches", "WIDE.bnei %as,%imm,%label"},
362 {"bgei %as,%imm,%label ? IsaUseWideBranches", "WIDE.bgei %as,%imm,%label"},
363 {"blti %as,%imm,%label ? IsaUseWideBranches", "WIDE.blti %as,%imm,%label"},
364 {"bgeui %as,%imm,%label ? IsaUseWideBranches", "WIDE.bgeui %as,%imm,%label"},
365 {"bltui %as,%imm,%label ? IsaUseWideBranches", "WIDE.bltui %as,%imm,%label"},
366 {"bbci %as,%imm,%label ? IsaUseWideBranches", "WIDE.bbci %as,%imm,%label"},
367 {"bbsi %as,%imm,%label ? IsaUseWideBranches", "WIDE.bbsi %as,%imm,%label"},
368 {"beq %as,%at,%label ? IsaUseWideBranches", "WIDE.beq %as,%at,%label"},
369 {"bne %as,%at,%label ? IsaUseWideBranches", "WIDE.bne %as,%at,%label"},
370 {"bge %as,%at,%label ? IsaUseWideBranches", "WIDE.bge %as,%at,%label"},
371 {"blt %as,%at,%label ? IsaUseWideBranches", "WIDE.blt %as,%at,%label"},
372 {"bgeu %as,%at,%label ? IsaUseWideBranches", "WIDE.bgeu %as,%at,%label"},
373 {"bltu %as,%at,%label ? IsaUseWideBranches", "WIDE.bltu %as,%at,%label"},
374 {"bany %as,%at,%label ? IsaUseWideBranches", "WIDE.bany %as,%at,%label"},
375 {"bnone %as,%at,%label ? IsaUseWideBranches", "WIDE.bnone %as,%at,%label"},
376 {"ball %as,%at,%label ? IsaUseWideBranches", "WIDE.ball %as,%at,%label"},
377 {"bnall %as,%at,%label ? IsaUseWideBranches", "WIDE.bnall %as,%at,%label"},
378 {"bbc %as,%at,%label ? IsaUseWideBranches", "WIDE.bbc %as,%at,%label"},
379 {"bbs %as,%at,%label ? IsaUseWideBranches", "WIDE.bbs %as,%at,%label"},
381 /* Widening branch comparisons eq/ne to zero. Prefer relaxing to narrow
382 branches if the density option is available. */
383 {"beqz %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%LABEL;j %label;LABEL"},
384 {"bnez %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%LABEL;j %label;LABEL"},
385 {"beqz %as,%label", "bnez %as,%LABEL;j %label;LABEL"},
386 {"bnez %as,%label", "beqz %as,%LABEL;j %label;LABEL"},
387 {"WIDE.beqz %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%LABEL;j %label;LABEL"},
388 {"WIDE.bnez %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%LABEL;j %label;LABEL"},
389 {"WIDE.beqz %as,%label", "bnez %as,%LABEL;j %label;LABEL"},
390 {"WIDE.bnez %as,%label", "beqz %as,%LABEL;j %label;LABEL"},
392 /* Widening expect-taken branches. */
393 {"beqzt %as,%label ? IsaUsePredictedBranches", "bnez %as,%LABEL;j %label;LABEL"},
394 {"bnezt %as,%label ? IsaUsePredictedBranches", "beqz %as,%LABEL;j %label;LABEL"},
395 {"beqt %as,%at,%label ? IsaUsePredictedBranches", "bne %as,%at,%LABEL;j %label;LABEL"},
396 {"bnet %as,%at,%label ? IsaUsePredictedBranches", "beq %as,%at,%LABEL;j %label;LABEL"},
398 /* Widening branches from the Xtensa boolean option. */
399 {"bt %bs,%label ? IsaUseBooleans", "bf %bs,%LABEL;j %label;LABEL"},
400 {"bf %bs,%label ? IsaUseBooleans", "bt %bs,%LABEL;j %label;LABEL"},
402 /* Other branch-around-jump widenings. */
403 {"bgez %as,%label", "bltz %as,%LABEL;j %label;LABEL"},
404 {"bltz %as,%label", "bgez %as,%LABEL;j %label;LABEL"},
405 {"beqi %as,%imm,%label", "bnei %as,%imm,%LABEL;j %label;LABEL"},
406 {"bnei %as,%imm,%label", "beqi %as,%imm,%LABEL;j %label;LABEL"},
407 {"bgei %as,%imm,%label", "blti %as,%imm,%LABEL;j %label;LABEL"},
408 {"blti %as,%imm,%label", "bgei %as,%imm,%LABEL;j %label;LABEL"},
409 {"bgeui %as,%imm,%label", "bltui %as,%imm,%LABEL;j %label;LABEL"},
410 {"bltui %as,%imm,%label", "bgeui %as,%imm,%LABEL;j %label;LABEL"},
411 {"bbci %as,%imm,%label", "bbsi %as,%imm,%LABEL;j %label;LABEL"},
412 {"bbsi %as,%imm,%label", "bbci %as,%imm,%LABEL;j %label;LABEL"},
413 {"beq %as,%at,%label", "bne %as,%at,%LABEL;j %label;LABEL"},
414 {"bne %as,%at,%label", "beq %as,%at,%LABEL;j %label;LABEL"},
415 {"bge %as,%at,%label", "blt %as,%at,%LABEL;j %label;LABEL"},
416 {"blt %as,%at,%label", "bge %as,%at,%LABEL;j %label;LABEL"},
417 {"bgeu %as,%at,%label", "bltu %as,%at,%LABEL;j %label;LABEL"},
418 {"bltu %as,%at,%label", "bgeu %as,%at,%LABEL;j %label;LABEL"},
419 {"bany %as,%at,%label", "bnone %as,%at,%LABEL;j %label;LABEL"},
420 {"bnone %as,%at,%label", "bany %as,%at,%LABEL;j %label;LABEL"},
421 {"ball %as,%at,%label", "bnall %as,%at,%LABEL;j %label;LABEL"},
422 {"bnall %as,%at,%label", "ball %as,%at,%LABEL;j %label;LABEL"},
423 {"bbc %as,%at,%label", "bbs %as,%at,%LABEL;j %label;LABEL"},
424 {"bbs %as,%at,%label", "bbc %as,%at,%LABEL;j %label;LABEL"},
426 {"WIDE.bgez %as,%label", "bltz %as,%LABEL;j %label;LABEL"},
427 {"WIDE.bltz %as,%label", "bgez %as,%LABEL;j %label;LABEL"},
428 {"WIDE.beqi %as,%imm,%label", "bnei %as,%imm,%LABEL;j %label;LABEL"},
429 {"WIDE.bnei %as,%imm,%label", "beqi %as,%imm,%LABEL;j %label;LABEL"},
430 {"WIDE.bgei %as,%imm,%label", "blti %as,%imm,%LABEL;j %label;LABEL"},
431 {"WIDE.blti %as,%imm,%label", "bgei %as,%imm,%LABEL;j %label;LABEL"},
432 {"WIDE.bgeui %as,%imm,%label", "bltui %as,%imm,%LABEL;j %label;LABEL"},
433 {"WIDE.bltui %as,%imm,%label", "bgeui %as,%imm,%LABEL;j %label;LABEL"},
434 {"WIDE.bbci %as,%imm,%label", "bbsi %as,%imm,%LABEL;j %label;LABEL"},
435 {"WIDE.bbsi %as,%imm,%label", "bbci %as,%imm,%LABEL;j %label;LABEL"},
436 {"WIDE.beq %as,%at,%label", "bne %as,%at,%LABEL;j %label;LABEL"},
437 {"WIDE.bne %as,%at,%label", "beq %as,%at,%LABEL;j %label;LABEL"},
438 {"WIDE.bge %as,%at,%label", "blt %as,%at,%LABEL;j %label;LABEL"},
439 {"WIDE.blt %as,%at,%label", "bge %as,%at,%LABEL;j %label;LABEL"},
440 {"WIDE.bgeu %as,%at,%label", "bltu %as,%at,%LABEL;j %label;LABEL"},
441 {"WIDE.bltu %as,%at,%label", "bgeu %as,%at,%LABEL;j %label;LABEL"},
442 {"WIDE.bany %as,%at,%label", "bnone %as,%at,%LABEL;j %label;LABEL"},
443 {"WIDE.bnone %as,%at,%label", "bany %as,%at,%LABEL;j %label;LABEL"},
444 {"WIDE.ball %as,%at,%label", "bnall %as,%at,%LABEL;j %label;LABEL"},
445 {"WIDE.bnall %as,%at,%label", "ball %as,%at,%LABEL;j %label;LABEL"},
446 {"WIDE.bbc %as,%at,%label", "bbs %as,%at,%LABEL;j %label;LABEL"},
447 {"WIDE.bbs %as,%at,%label", "bbc %as,%at,%LABEL;j %label;LABEL"},
449 /* Expanding calls with literals. */
450 {"call0 %label,%ar0 ? IsaUseL32R",
451 "LITERAL %label; l32r a0,%LITERAL; callx0 a0,%ar0"},
452 {"call4 %label,%ar4 ? IsaUseL32R",
453 "LITERAL %label; l32r a4,%LITERAL; callx4 a4,%ar4"},
454 {"call8 %label,%ar8 ? IsaUseL32R",
455 "LITERAL %label; l32r a8,%LITERAL; callx8 a8,%ar8"},
456 {"call12 %label,%ar12 ? IsaUseL32R",
457 "LITERAL %label; l32r a12,%LITERAL; callx12 a12,%ar12"},
459 /* Expanding calls with const16. */
460 {"call0 %label,%ar0 ? IsaUseConst16",
461 "const16 a0,HI16U(%label); const16 a0,LOW16U(%label); callx0 a0,%ar0"},
462 {"call4 %label,%ar4 ? IsaUseConst16",
463 "const16 a4,HI16U(%label); const16 a4,LOW16U(%label); callx4 a4,%ar4"},
464 {"call8 %label,%ar8 ? IsaUseConst16",
465 "const16 a8,HI16U(%label); const16 a8,LOW16U(%label); callx8 a8,%ar8"},
466 {"call12 %label,%ar12 ? IsaUseConst16",
467 "const16 a12,HI16U(%label); const16 a12,LOW16U(%label); callx12 a12,%ar12"},
469 /* Expanding j.l with literals. */
470 {"j %label ? FREEREG ? IsaUseL32R",
471 "LITERAL %label; l32r FREEREG,%LITERAL; jx FREEREG"},
472 /* Expanding j.l with const16. */
473 {"j %label ? FREEREG ? IsaUseConst16",
474 "const16 FREEREG,HI16U(%label); const16 FREEREG,LOW16U(%label); jx FREEREG"},
477 #define WIDEN_COUNT (sizeof (widen_spec_list) / sizeof (string_pattern_pair))
480 /* The simplify_spec_list specifies simplifying transformations that
481 will reduce the instruction width or otherwise simplify an
482 instruction. These are usually applied before relaxation in the
483 assembler. It is always legal to simplify. Even for "addi as, 0",
484 the "addi.n as, 0" will eventually be widened back to an "addi 0"
485 after the widening table is applied. Note: The usage of this table
486 has changed somewhat so that it is entirely specific to "narrowing"
487 instructions to use the density option. This table is not used at
488 all when the density option is not available. */
490 string_pattern_pair simplify_spec_list
[] =
492 {"add %ar,%as,%at ? IsaUseDensityInstruction", "add.n %ar,%as,%at"},
493 {"addi.n %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"},
494 {"addi %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"},
495 {"addi %ar,%as,%imm ? IsaUseDensityInstruction", "addi.n %ar,%as,%imm"},
496 {"addmi %ar,%as,%imm ? IsaUseDensityInstruction", "addi.n %ar,%as,%imm"},
497 {"beqz %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%label"},
498 {"bnez %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%label"},
499 {"l32i %at,%as,%imm ? IsaUseDensityInstruction", "l32i.n %at,%as,%imm"},
500 {"movi %as,%imm ? IsaUseDensityInstruction", "movi.n %as,%imm"},
501 {"nop ? realnop ? IsaUseDensityInstruction", "nop.n"},
502 {"or %ar,%as,%at | %ar==%as | %as==%at ? IsaUseDensityInstruction", "nop.n"},
503 {"or %ar,%as,%at | %ar!=%as | %as==%at ? IsaUseDensityInstruction", "mov.n %ar,%as"},
504 {"ret %as ? IsaUseDensityInstruction", "ret.n %as"},
505 {"retw %as ? IsaUseDensityInstruction", "retw.n %as"},
506 {"s32i %at,%as,%imm ? IsaUseDensityInstruction", "s32i.n %at,%as,%imm"},
507 {"slli %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"}
510 #define SIMPLIFY_COUNT \
511 (sizeof (simplify_spec_list) / sizeof (string_pattern_pair))
514 /* Externally visible functions. */
516 extern bfd_boolean
xg_has_userdef_op_fn (OpType
);
517 extern long xg_apply_userdef_op_fn (OpType
, long);
521 append_transition (TransitionTable
*tt
,
522 xtensa_opcode opcode
,
524 transition_cmp_fn cmp
)
526 TransitionList
*tl
= (TransitionList
*) xmalloc (sizeof (TransitionList
));
527 TransitionList
*prev
;
528 TransitionList
**t_p
;
529 gas_assert (tt
!= NULL
);
530 gas_assert (opcode
< tt
->num_opcodes
);
532 prev
= tt
->table
[opcode
];
537 tt
->table
[opcode
] = tl
;
541 for (t_p
= &tt
->table
[opcode
]; (*t_p
) != NULL
; t_p
= &(*t_p
)->next
)
543 if (cmp
&& cmp (t
, (*t_p
)->rule
) < 0)
545 /* Insert it here. */
556 append_condition (TransitionRule
*tr
, Precondition
*cond
)
558 PreconditionList
*pl
=
559 (PreconditionList
*) xmalloc (sizeof (PreconditionList
));
560 PreconditionList
*prev
= tr
->conditions
;
561 PreconditionList
*nxt
;
581 append_value_condition (TransitionRule
*tr
,
586 Precondition
*cond
= (Precondition
*) xmalloc (sizeof (Precondition
));
590 cond
->typ
= OP_OPERAND
;
592 append_condition (tr
, cond
);
597 append_constant_value_condition (TransitionRule
*tr
,
602 Precondition
*cond
= (Precondition
*) xmalloc (sizeof (Precondition
));
606 cond
->typ
= OP_CONSTANT
;
607 cond
->op_data
= cnst
;
608 append_condition (tr
, cond
);
613 append_build_insn (TransitionRule
*tr
, BuildInstr
*bi
)
615 BuildInstr
*prev
= tr
->to_instr
;
635 append_op (BuildInstr
*bi
, BuildOp
*b_op
)
637 BuildOp
*prev
= bi
->ops
;
656 append_literal_op (BuildInstr
*bi
, unsigned op1
, unsigned src_op
)
658 BuildOp
*b_op
= (BuildOp
*) xmalloc (sizeof (BuildOp
));
661 b_op
->typ
= OP_LITERAL
;
662 b_op
->op_data
= src_op
;
664 append_op (bi
, b_op
);
669 append_label_op (BuildInstr
*bi
, unsigned op1
)
671 BuildOp
*b_op
= (BuildOp
*) xmalloc (sizeof (BuildOp
));
674 b_op
->typ
= OP_LABEL
;
677 append_op (bi
, b_op
);
682 append_constant_op (BuildInstr
*bi
, unsigned op1
, unsigned cnst
)
684 BuildOp
*b_op
= (BuildOp
*) xmalloc (sizeof (BuildOp
));
687 b_op
->typ
= OP_CONSTANT
;
688 b_op
->op_data
= cnst
;
690 append_op (bi
, b_op
);
695 append_field_op (BuildInstr
*bi
, unsigned op1
, unsigned src_op
)
697 BuildOp
*b_op
= (BuildOp
*) xmalloc (sizeof (BuildOp
));
700 b_op
->typ
= OP_OPERAND
;
701 b_op
->op_data
= src_op
;
703 append_op (bi
, b_op
);
707 /* These could be generated but are not currently. */
710 append_user_fn_field_op (BuildInstr
*bi
,
715 BuildOp
*b_op
= (BuildOp
*) xmalloc (sizeof (BuildOp
));
719 b_op
->op_data
= src_op
;
721 append_op (bi
, b_op
);
725 /* These operand functions are the semantics of user-defined
726 operand functions. */
729 operand_function_HI24S (long a
)
732 return (a
& (~0xff)) + 0x100;
734 return (a
& (~0xff));
739 operand_function_F32MINUS (long a
)
746 operand_function_LOW8 (long a
)
749 return (a
& 0xff) | ~0xff;
756 operand_function_LOW16U (long a
)
763 operand_function_HI16U (long a
)
765 unsigned long b
= a
& 0xffff0000;
766 return (long) (b
>> 16);
771 xg_has_userdef_op_fn (OpType op
)
775 case OP_OPERAND_F32MINUS
:
776 case OP_OPERAND_LOW8
:
777 case OP_OPERAND_HI24S
:
778 case OP_OPERAND_LOW16U
:
779 case OP_OPERAND_HI16U
:
789 xg_apply_userdef_op_fn (OpType op
, long a
)
793 case OP_OPERAND_F32MINUS
:
794 return operand_function_F32MINUS (a
);
795 case OP_OPERAND_LOW8
:
796 return operand_function_LOW8 (a
);
797 case OP_OPERAND_HI24S
:
798 return operand_function_HI24S (a
);
799 case OP_OPERAND_LOW16U
:
800 return operand_function_LOW16U (a
);
801 case OP_OPERAND_HI16U
:
802 return operand_function_HI16U (a
);
810 /* Generate a transition table. */
813 enter_opname_n (const char *name
, int len
)
817 for (op
= local_opnames
; op
!= NULL
; op
= op
->next
)
819 if (strlen (op
->opname
) == (unsigned) len
820 && strncmp (op
->opname
, name
, len
) == 0)
823 op
= (opname_e
*) xmalloc (sizeof (opname_e
));
824 op
->opname
= (char *) xmalloc (len
+ 1);
825 strncpy (op
->opname
, name
, len
);
826 op
->opname
[len
] = '\0';
832 enter_opname (const char *name
)
836 for (op
= local_opnames
; op
!= NULL
; op
= op
->next
)
838 if (strcmp (op
->opname
, name
) == 0)
841 op
= (opname_e
*) xmalloc (sizeof (opname_e
));
842 op
->opname
= xstrdup (name
);
848 init_opname_map (opname_map
*m
)
856 clear_opname_map (opname_map
*m
)
860 while (m
->head
!= NULL
)
871 same_operand_name (const opname_map_e
*m1
, const opname_map_e
*m2
)
873 if (m1
->operand_name
== NULL
|| m1
->operand_name
== NULL
)
875 return (m1
->operand_name
== m2
->operand_name
);
879 static opname_map_e
*
880 get_opmatch (opname_map
*map
, const char *operand_name
)
884 for (m
= map
->head
; m
!= NULL
; m
= m
->next
)
886 if (strcmp (m
->operand_name
, operand_name
) == 0)
894 op_is_constant (const opname_map_e
*m1
)
896 return (m1
->operand_name
== NULL
);
901 op_get_constant (const opname_map_e
*m1
)
903 gas_assert (m1
->operand_name
== NULL
);
904 return m1
->constant_value
;
909 init_precond_list (precond_list
*l
)
917 clear_precond_list (precond_list
*l
)
921 while (l
->head
!= NULL
)
932 init_insn_templ (insn_templ
*t
)
934 t
->opcode_name
= NULL
;
935 init_opname_map (&t
->operand_map
);
940 clear_insn_templ (insn_templ
*t
)
942 clear_opname_map (&t
->operand_map
);
947 init_insn_pattern (insn_pattern
*p
)
949 init_insn_templ (&p
->t
);
950 init_precond_list (&p
->preconds
);
956 clear_insn_pattern (insn_pattern
*p
)
958 clear_insn_templ (&p
->t
);
959 clear_precond_list (&p
->preconds
);
964 init_insn_repl (insn_repl
*r
)
972 clear_insn_repl (insn_repl
*r
)
976 while (r
->head
!= NULL
)
980 clear_insn_templ (&e
->t
);
987 insn_templ_operand_count (const insn_templ
*t
)
990 const opname_map_e
*op
;
992 for (op
= t
->operand_map
.head
; op
!= NULL
; op
= op
->next
, i
++)
998 /* Convert a string to a number. E.G.: parse_constant("10", &num) */
1001 parse_constant (const char *in
, unsigned *val_p
)
1012 if (*p
>= '0' && *p
<= '9')
1013 val
= val
* 10 + (*p
- '0');
1024 parse_special_fn (const char *name
,
1025 const char **fn_name_p
,
1026 const char **arg_name_p
)
1031 p_start
= strchr (name
, '(');
1032 if (p_start
== NULL
)
1035 p_end
= strchr (p_start
, ')');
1040 if (p_end
[1] != '\0')
1043 *fn_name_p
= enter_opname_n (name
, p_start
- name
);
1044 *arg_name_p
= enter_opname_n (p_start
+ 1, p_end
- p_start
- 1);
1050 skip_white (const char *p
)
1061 trim_whitespace (char *in
)
1063 char *last_white
= NULL
;
1066 while (p
&& *p
!= '\0')
1070 if (last_white
== NULL
)
1085 /* Split a string into component strings where "c" is the
1086 delimiter. Place the result in the split_rec. */
1089 split_string (split_rec
*rec
,
1092 bfd_boolean elide_whitespace
)
1098 while (p
!= NULL
&& *p
!= '\0')
1108 if (rec
->count
== 0)
1111 rec
->vec
= (char **) xmalloc (sizeof (char *) * cnt
);
1112 for (i
= 0; i
< cnt
; i
++)
1116 for (i
= 0; i
< cnt
; i
++)
1122 if (elide_whitespace
)
1127 rec
->vec
[i
] = xstrdup (q
);
1131 rec
->vec
[i
] = (char *) xmalloc (sizeof (char) * (len
+ 1));
1132 strncpy (rec
->vec
[i
], q
, len
);
1133 rec
->vec
[i
][len
] = '\0';
1137 if (elide_whitespace
)
1138 trim_whitespace (rec
->vec
[i
]);
1144 clear_split_rec (split_rec
*rec
)
1148 for (i
= 0; i
< rec
->count
; i
++)
1156 /* Initialize a split record. The split record must be initialized
1157 before split_string is called. */
1160 init_split_rec (split_rec
*rec
)
1167 /* Parse an instruction template like "insn op1, op2, op3". */
1170 parse_insn_templ (const char *s
, insn_templ
*t
)
1177 /* First find the first whitespace. */
1179 init_split_rec (&oprec
);
1182 insn_name_len
= strcspn (s
, " ");
1183 if (insn_name_len
== 0)
1186 init_insn_templ (t
);
1187 t
->opcode_name
= enter_opname_n (p
, insn_name_len
);
1189 p
= p
+ insn_name_len
;
1191 /* Split by ',' and skip beginning and trailing whitespace. */
1192 split_string (&oprec
, p
, ',', TRUE
);
1194 for (i
= 0; i
< oprec
.count
; i
++)
1196 const char *opname
= oprec
.vec
[i
];
1197 opname_map_e
*e
= (opname_map_e
*) xmalloc (sizeof (opname_map_e
));
1199 e
->operand_name
= NULL
;
1200 e
->constant_value
= 0;
1203 /* If it begins with a number, assume that it is a number. */
1204 if (opname
&& opname
[0] >= '0' && opname
[0] <= '9')
1208 if (parse_constant (opname
, &val
))
1209 e
->constant_value
= val
;
1213 clear_split_rec (&oprec
);
1214 clear_insn_templ (t
);
1219 e
->operand_name
= enter_opname (oprec
.vec
[i
]);
1221 *t
->operand_map
.tail
= e
;
1222 t
->operand_map
.tail
= &e
->next
;
1224 clear_split_rec (&oprec
);
1230 parse_precond (const char *s
, precond_e
*precond
)
1232 /* All preconditions are currently of the form:
1233 a == b or a != b or a == k (where k is a constant).
1234 Later we may use some special functions like DENSITY == 1
1235 to identify when density is available. */
1239 precond
->opname1
= NULL
;
1240 precond
->opval1
= 0;
1241 precond
->cmpop
= OP_EQUAL
;
1242 precond
->opname2
= NULL
;
1243 precond
->opval2
= 0;
1244 precond
->next
= NULL
;
1248 len
= strcspn (p
, " !=");
1253 precond
->opname1
= enter_opname_n (p
, len
);
1257 /* Check for "==" and "!=". */
1258 if (strncmp (p
, "==", 2) == 0)
1259 precond
->cmpop
= OP_EQUAL
;
1260 else if (strncmp (p
, "!=", 2) == 0)
1261 precond
->cmpop
= OP_NOTEQUAL
;
1268 /* No trailing whitespace from earlier parsing. */
1269 if (p
[0] >= '0' && p
[0] <= '9')
1272 if (parse_constant (p
, &val
))
1273 precond
->opval2
= val
;
1278 precond
->opname2
= enter_opname (p
);
1284 clear_req_or_option_list (ReqOrOption
**r_p
)
1289 free ((*r_p
)->option_name
);
1290 clear_req_or_option_list (&(*r_p
)->next
);
1296 clear_req_option_list (ReqOption
**r_p
)
1301 clear_req_or_option_list (&(*r_p
)->or_option_terms
);
1302 clear_req_option_list (&(*r_p
)->next
);
1307 static ReqOrOption
*
1308 clone_req_or_option_list (ReqOrOption
*req_or_option
)
1310 ReqOrOption
*new_req_or_option
;
1312 if (req_or_option
== NULL
)
1315 new_req_or_option
= (ReqOrOption
*) xmalloc (sizeof (ReqOrOption
));
1316 new_req_or_option
->option_name
= xstrdup (req_or_option
->option_name
);
1317 new_req_or_option
->is_true
= req_or_option
->is_true
;
1318 new_req_or_option
->next
= NULL
;
1319 new_req_or_option
->next
= clone_req_or_option_list (req_or_option
->next
);
1320 return new_req_or_option
;
1325 clone_req_option_list (ReqOption
*req_option
)
1327 ReqOption
*new_req_option
;
1329 if (req_option
== NULL
)
1332 new_req_option
= (ReqOption
*) xmalloc (sizeof (ReqOption
));
1333 new_req_option
->or_option_terms
= NULL
;
1334 new_req_option
->next
= NULL
;
1335 new_req_option
->or_option_terms
=
1336 clone_req_or_option_list (req_option
->or_option_terms
);
1337 new_req_option
->next
= clone_req_option_list (req_option
->next
);
1338 return new_req_option
;
1343 parse_option_cond (const char *s
, ReqOption
*option
)
1346 split_rec option_term_rec
;
1348 /* All option or conditions are of the form:
1349 optionA + no-optionB + ...
1350 "Ands" are divided by "?". */
1352 init_split_rec (&option_term_rec
);
1353 split_string (&option_term_rec
, s
, '+', TRUE
);
1355 if (option_term_rec
.count
== 0)
1357 clear_split_rec (&option_term_rec
);
1361 for (i
= 0; i
< option_term_rec
.count
; i
++)
1363 char *option_name
= option_term_rec
.vec
[i
];
1364 bfd_boolean is_true
= TRUE
;
1368 if (strncmp (option_name
, "no-", 3) == 0)
1370 option_name
= xstrdup (&option_name
[3]);
1374 option_name
= xstrdup (option_name
);
1376 req
= (ReqOrOption
*) xmalloc (sizeof (ReqOrOption
));
1377 req
->option_name
= option_name
;
1378 req
->is_true
= is_true
;
1381 /* Append to list. */
1382 for (r_p
= &option
->or_option_terms
; (*r_p
) != NULL
;
1383 r_p
= &(*r_p
)->next
)
1391 /* Parse a string like:
1392 "insn op1, op2, op3, op4 | op1 != op2 | op2 == op3 | op4 == 1".
1393 I.E., instruction "insn" with 4 operands where operand 1 and 2 are not
1394 the same and operand 2 and 3 are the same and operand 4 is 1.
1398 "insn op1 | op1 == 1 / density + boolean / no-useroption".
1399 i.e. instruction "insn" with 1 operands where operand 1 is 1
1400 when "density" or "boolean" options are available and
1401 "useroption" is not available.
1403 Because the current implementation of this parsing scheme uses
1404 split_string, it requires that '|' and '?' are only used as
1405 delimiters for predicates and required options. */
1408 parse_insn_pattern (const char *in
, insn_pattern
*insn
)
1411 split_rec optionrec
;
1414 init_insn_pattern (insn
);
1416 init_split_rec (&optionrec
);
1417 split_string (&optionrec
, in
, '?', TRUE
);
1418 if (optionrec
.count
== 0)
1420 clear_split_rec (&optionrec
);
1424 init_split_rec (&rec
);
1426 split_string (&rec
, optionrec
.vec
[0], '|', TRUE
);
1430 clear_split_rec (&rec
);
1431 clear_split_rec (&optionrec
);
1435 if (!parse_insn_templ (rec
.vec
[0], &insn
->t
))
1437 clear_split_rec (&rec
);
1438 clear_split_rec (&optionrec
);
1442 for (i
= 1; i
< rec
.count
; i
++)
1444 precond_e
*cond
= (precond_e
*) xmalloc (sizeof (precond_e
));
1446 if (!parse_precond (rec
.vec
[i
], cond
))
1448 clear_split_rec (&rec
);
1449 clear_split_rec (&optionrec
);
1450 clear_insn_pattern (insn
);
1454 /* Append the condition. */
1455 *insn
->preconds
.tail
= cond
;
1456 insn
->preconds
.tail
= &cond
->next
;
1459 for (i
= 1; i
< optionrec
.count
; i
++)
1461 /* Handle the option conditions. */
1463 ReqOption
*req_option
= (ReqOption
*) xmalloc (sizeof (ReqOption
));
1464 req_option
->or_option_terms
= NULL
;
1465 req_option
->next
= NULL
;
1467 if (!parse_option_cond (optionrec
.vec
[i
], req_option
))
1469 clear_split_rec (&rec
);
1470 clear_split_rec (&optionrec
);
1471 clear_insn_pattern (insn
);
1472 clear_req_option_list (&req_option
);
1476 /* Append the condition. */
1477 for (r_p
= &insn
->options
; (*r_p
) != NULL
; r_p
= &(*r_p
)->next
)
1480 (*r_p
) = req_option
;
1483 clear_split_rec (&rec
);
1484 clear_split_rec (&optionrec
);
1490 parse_insn_repl (const char *in
, insn_repl
*r_p
)
1492 /* This is a list of instruction templates separated by ';'. */
1496 split_string (&rec
, in
, ';', TRUE
);
1498 for (i
= 0; i
< rec
.count
; i
++)
1500 insn_repl_e
*e
= (insn_repl_e
*) xmalloc (sizeof (insn_repl_e
));
1504 if (!parse_insn_templ (rec
.vec
[i
], &e
->t
))
1507 clear_insn_repl (r_p
);
1511 r_p
->tail
= &e
->next
;
1518 transition_applies (insn_pattern
*initial_insn
,
1519 const char *from_string ATTRIBUTE_UNUSED
,
1520 const char *to_string ATTRIBUTE_UNUSED
)
1522 ReqOption
*req_option
;
1524 for (req_option
= initial_insn
->options
;
1526 req_option
= req_option
->next
)
1528 ReqOrOption
*req_or_option
= req_option
->or_option_terms
;
1530 if (req_or_option
== NULL
1531 || req_or_option
->next
!= NULL
)
1534 if (strncmp (req_or_option
->option_name
, "IsaUse", 6) == 0)
1536 bfd_boolean option_available
= FALSE
;
1537 char *option_name
= req_or_option
->option_name
+ 6;
1538 if (!strcmp (option_name
, "DensityInstruction"))
1539 option_available
= (XCHAL_HAVE_DENSITY
== 1);
1540 else if (!strcmp (option_name
, "L32R"))
1541 option_available
= (XCHAL_HAVE_L32R
== 1);
1542 else if (!strcmp (option_name
, "Const16"))
1543 option_available
= (XCHAL_HAVE_CONST16
== 1);
1544 else if (!strcmp (option_name
, "Loops"))
1545 option_available
= (XCHAL_HAVE_LOOPS
== 1);
1546 else if (!strcmp (option_name
, "WideBranches"))
1548 = (XCHAL_HAVE_WIDE_BRANCHES
== 1 && produce_flix
== FLIX_ALL
);
1549 else if (!strcmp (option_name
, "PredictedBranches"))
1551 = (XCHAL_HAVE_PREDICTED_BRANCHES
== 1
1552 && produce_flix
== FLIX_ALL
);
1553 else if (!strcmp (option_name
, "Booleans"))
1554 option_available
= (XCHAL_HAVE_BOOLEANS
== 1);
1556 as_warn (_("invalid configuration option '%s' in transition rule '%s'"),
1557 req_or_option
->option_name
, from_string
);
1558 if ((option_available
^ req_or_option
->is_true
) != 0)
1561 else if (strcmp (req_or_option
->option_name
, "realnop") == 0)
1563 bfd_boolean nop_available
=
1564 (xtensa_opcode_lookup (xtensa_default_isa
, "nop")
1565 != XTENSA_UNDEFINED
);
1566 if ((nop_available
^ req_or_option
->is_true
) != 0)
1575 wide_branch_opcode (const char *opcode_name
,
1577 xtensa_opcode
*popcode
)
1579 xtensa_isa isa
= xtensa_default_isa
;
1580 xtensa_opcode opcode
;
1581 static char wbr_name_buf
[20];
1583 if (strncmp (opcode_name
, "WIDE.", 5) != 0)
1586 strcpy (wbr_name_buf
, opcode_name
+ 5);
1587 strcat (wbr_name_buf
, suffix
);
1588 opcode
= xtensa_opcode_lookup (isa
, wbr_name_buf
);
1589 if (opcode
!= XTENSA_UNDEFINED
)
1599 static TransitionRule
*
1600 build_transition (insn_pattern
*initial_insn
,
1601 insn_repl
*replace_insns
,
1602 const char *from_string
,
1603 const char *to_string
)
1605 TransitionRule
*tr
= NULL
;
1606 xtensa_opcode opcode
;
1607 xtensa_isa isa
= xtensa_default_isa
;
1608 BuildInstr
*literal_bi
;
1616 if (!wide_branch_opcode (initial_insn
->t
.opcode_name
, ".w18", &opcode
)
1617 && !wide_branch_opcode (initial_insn
->t
.opcode_name
, ".w15", &opcode
))
1618 opcode
= xtensa_opcode_lookup (isa
, initial_insn
->t
.opcode_name
);
1620 if (opcode
== XTENSA_UNDEFINED
)
1622 /* It is OK to not be able to translate some of these opcodes. */
1627 if (xtensa_opcode_num_operands (isa
, opcode
)
1628 != insn_templ_operand_count (&initial_insn
->t
))
1630 /* This is also OK because there are opcodes that
1631 have different numbers of operands on different
1632 architecture variations. */
1636 tr
= (TransitionRule
*) xmalloc (sizeof (TransitionRule
));
1637 tr
->opcode
= opcode
;
1638 tr
->conditions
= NULL
;
1639 tr
->to_instr
= NULL
;
1641 /* Build the conditions. First, equivalent operand condition.... */
1642 for (op1
= initial_insn
->t
.operand_map
.head
; op1
!= NULL
; op1
= op1
->next
)
1644 for (op2
= op1
->next
; op2
!= NULL
; op2
= op2
->next
)
1646 if (same_operand_name (op1
, op2
))
1648 append_value_condition (tr
, OP_EQUAL
,
1649 op1
->operand_num
, op2
->operand_num
);
1654 /* Now the condition that an operand value must be a constant.... */
1655 for (op1
= initial_insn
->t
.operand_map
.head
; op1
!= NULL
; op1
= op1
->next
)
1657 if (op_is_constant (op1
))
1659 append_constant_value_condition (tr
,
1662 op_get_constant (op1
));
1667 /* Now add the explicit preconditions listed after the "|" in the spec.
1668 These are currently very limited, so we do a special case
1669 parse for them. We expect spaces, opname != opname. */
1670 for (precond
= initial_insn
->preconds
.head
;
1672 precond
= precond
->next
)
1677 if (precond
->opname1
)
1679 op1
= get_opmatch (&initial_insn
->t
.operand_map
, precond
->opname1
);
1681 as_fatal (_("opcode '%s': no bound opname '%s' "
1682 "for precondition in '%s'"),
1683 xtensa_opcode_name (isa
, opcode
),
1684 precond
->opname1
, from_string
);
1687 if (precond
->opname2
)
1689 op2
= get_opmatch (&initial_insn
->t
.operand_map
, precond
->opname2
);
1691 as_fatal (_("opcode '%s': no bound opname '%s' "
1692 "for precondition in %s"),
1693 xtensa_opcode_name (isa
, opcode
),
1694 precond
->opname2
, from_string
);
1697 if (op1
== NULL
&& op2
== NULL
)
1698 as_fatal (_("opcode '%s': precondition only contains "
1699 "constants in '%s'"),
1700 xtensa_opcode_name (isa
, opcode
), from_string
);
1701 else if (op1
!= NULL
&& op2
!= NULL
)
1702 append_value_condition (tr
, precond
->cmpop
,
1703 op1
->operand_num
, op2
->operand_num
);
1704 else if (op2
== NULL
)
1705 append_constant_value_condition (tr
, precond
->cmpop
,
1706 op1
->operand_num
, precond
->opval2
);
1708 append_constant_value_condition (tr
, precond
->cmpop
,
1709 op2
->operand_num
, precond
->opval1
);
1712 tr
->options
= clone_req_option_list (initial_insn
->options
);
1714 /* Generate the replacement instructions. Some of these
1715 "instructions" are actually labels and literals. There can be at
1716 most one literal and at most one label. A literal must be defined
1717 (e.g., "LITERAL %imm") before use (e.g., "%LITERAL"). The labels
1718 can be used before they are defined. Also there are a number of
1719 special operands (e.g., HI24S). */
1722 for (r
= replace_insns
->head
; r
!= NULL
; r
= r
->next
)
1725 const char *opcode_name
;
1728 const char *fn_name
;
1729 const char *operand_arg_name
;
1731 bi
= (BuildInstr
*) xmalloc (sizeof (BuildInstr
));
1732 append_build_insn (tr
, bi
);
1734 bi
->opcode
= XTENSA_UNDEFINED
;
1738 opcode_name
= r
->t
.opcode_name
;
1739 operand_count
= insn_templ_operand_count (&r
->t
);
1741 if (strcmp (opcode_name
, "LITERAL") == 0)
1743 bi
->typ
= INSTR_LITERAL_DEF
;
1744 if (operand_count
!= 1)
1745 as_fatal (_("expected one operand for generated literal"));
1748 else if (strcmp (opcode_name
, "LABEL") == 0)
1750 bi
->typ
= INSTR_LABEL_DEF
;
1751 if (operand_count
!= 0)
1752 as_fatal (_("expected 0 operands for generated label"));
1756 bi
->typ
= INSTR_INSTR
;
1757 if (wide_branch_opcode (opcode_name
, ".w18", &bi
->opcode
)
1758 || wide_branch_opcode (opcode_name
, ".w15", &bi
->opcode
))
1759 opcode_name
= xtensa_opcode_name (isa
, bi
->opcode
);
1761 bi
->opcode
= xtensa_opcode_lookup (isa
, opcode_name
);
1763 if (bi
->opcode
== XTENSA_UNDEFINED
)
1765 as_warn (_("invalid opcode '%s' in transition rule '%s'"),
1766 opcode_name
, to_string
);
1770 /* Check for the right number of ops. */
1771 if (xtensa_opcode_num_operands (isa
, bi
->opcode
)
1772 != (int) operand_count
)
1773 as_fatal (_("opcode '%s': replacement does not have %d ops"),
1775 xtensa_opcode_num_operands (isa
, bi
->opcode
));
1778 for (op
= r
->t
.operand_map
.head
; op
!= NULL
; op
= op
->next
)
1782 if (op_is_constant (op
))
1783 append_constant_op (bi
, op
->operand_num
, op_get_constant (op
));
1784 else if (strcmp (op
->operand_name
, "%LITERAL") == 0)
1786 if (! literal_bi
|| ! literal_bi
->ops
|| literal_bi
->ops
->next
)
1787 as_fatal (_("opcode '%s': cannot find literal definition"),
1789 append_literal_op (bi
, op
->operand_num
,
1790 literal_bi
->ops
->op_data
);
1792 else if (strcmp (op
->operand_name
, "%LABEL") == 0)
1793 append_label_op (bi
, op
->operand_num
);
1794 else if (op
->operand_name
[0] == 'a'
1795 && parse_constant (op
->operand_name
+ 1, &idnum
))
1796 append_constant_op (bi
, op
->operand_num
, idnum
);
1797 else if (op
->operand_name
[0] == '%')
1799 opname_map_e
*orig_op
;
1800 orig_op
= get_opmatch (&initial_insn
->t
.operand_map
,
1802 if (orig_op
== NULL
)
1803 as_fatal (_("opcode %s: unidentified operand '%s' in '%s'"),
1804 opcode_name
, op
->operand_name
, to_string
);
1805 append_field_op (bi
, op
->operand_num
, orig_op
->operand_num
);
1807 else if (strcmp (op
->operand_name
, "FREEREG") == 0)
1809 append_user_fn_field_op (bi
, op
->operand_num
, OP_FREEREG
, 0);
1811 else if (parse_special_fn (op
->operand_name
,
1812 &fn_name
, &operand_arg_name
))
1814 opname_map_e
*orig_op
;
1815 OpType typ
= OP_CONSTANT
;
1817 if (strcmp (fn_name
, "LOW8") == 0)
1818 typ
= OP_OPERAND_LOW8
;
1819 else if (strcmp (fn_name
, "HI24S") == 0)
1820 typ
= OP_OPERAND_HI24S
;
1821 else if (strcmp (fn_name
, "F32MINUS") == 0)
1822 typ
= OP_OPERAND_F32MINUS
;
1823 else if (strcmp (fn_name
, "LOW16U") == 0)
1824 typ
= OP_OPERAND_LOW16U
;
1825 else if (strcmp (fn_name
, "HI16U") == 0)
1826 typ
= OP_OPERAND_HI16U
;
1828 as_fatal (_("unknown user-defined function %s"), fn_name
);
1830 orig_op
= get_opmatch (&initial_insn
->t
.operand_map
,
1832 if (orig_op
== NULL
)
1833 as_fatal (_("opcode %s: unidentified operand '%s' in '%s'"),
1834 opcode_name
, op
->operand_name
, to_string
);
1835 append_user_fn_field_op (bi
, op
->operand_num
,
1836 typ
, orig_op
->operand_num
);
1839 as_fatal (_("opcode %s: could not parse operand '%s' in '%s'"),
1840 opcode_name
, op
->operand_name
, to_string
);
1848 static TransitionTable
*
1849 build_transition_table (const string_pattern_pair
*transitions
,
1850 int transition_count
,
1851 transition_cmp_fn cmp
)
1853 TransitionTable
*table
= NULL
;
1854 int num_opcodes
= xtensa_isa_num_opcodes (xtensa_default_isa
);
1860 /* Otherwise, build it now. */
1861 table
= (TransitionTable
*) xmalloc (sizeof (TransitionTable
));
1862 table
->num_opcodes
= num_opcodes
;
1864 (TransitionList
**) xmalloc (sizeof (TransitionTable
*) * num_opcodes
);
1866 for (i
= 0; i
< num_opcodes
; i
++)
1867 table
->table
[i
] = NULL
;
1869 for (tnum
= 0; tnum
< transition_count
; tnum
++)
1871 const char *from_string
= transitions
[tnum
].pattern
;
1872 const char *to_string
= transitions
[tnum
].replacement
;
1874 insn_pattern initial_insn
;
1875 insn_repl replace_insns
;
1878 init_insn_pattern (&initial_insn
);
1879 if (!parse_insn_pattern (from_string
, &initial_insn
))
1880 as_fatal (_("could not parse INSN_PATTERN '%s'"), from_string
);
1882 init_insn_repl (&replace_insns
);
1883 if (!parse_insn_repl (to_string
, &replace_insns
))
1884 as_fatal (_("could not parse INSN_REPL '%s'"), to_string
);
1886 if (transition_applies (&initial_insn
, from_string
, to_string
))
1888 tr
= build_transition (&initial_insn
, &replace_insns
,
1889 from_string
, to_string
);
1891 append_transition (table
, tr
->opcode
, tr
, cmp
);
1895 as_warn (_("could not build transition for %s => %s"),
1896 from_string
, to_string
);
1901 clear_insn_repl (&replace_insns
);
1902 clear_insn_pattern (&initial_insn
);
1908 extern TransitionTable
*
1909 xg_build_widen_table (transition_cmp_fn cmp
)
1911 static TransitionTable
*table
= NULL
;
1913 table
= build_transition_table (widen_spec_list
, WIDEN_COUNT
, cmp
);
1918 extern TransitionTable
*
1919 xg_build_simplify_table (transition_cmp_fn cmp
)
1921 static TransitionTable
*table
= NULL
;
1923 table
= build_transition_table (simplify_spec_list
, SIMPLIFY_COUNT
, cmp
);