1 /* Table of relaxations for Xtensa assembly.
2 Copyright 2003, 2004 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 2, 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, 59 Temple Place - Suite 330, Boston,
19 MA 02111-1307, 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
53 | 'LITERAL' num ' ' VARIABLE
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,%LABEL0;j %label;LABEL0"}
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", "LITERAL0 %imm; l32r %at,%LITERAL0"}
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 "LITERAL0 %imm; l32r %at,%LITERAL0; 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 /* Imported from bfd. */
105 extern xtensa_isa xtensa_default_isa;
107 /* The opname_list is a small list of names that we use for opcode and
108 operand variable names to simplify ownership of these commonly used
109 strings. Strings entered in the table can be compared by pointer
112 typedef struct opname_list_struct opname_list;
113 typedef opname_list opname_e;
115 struct opname_list_struct
121 static opname_list *local_opnames = NULL;
124 /* The "opname_map" and its element structure "opname_map_e" are used
125 for binding an operand number to a name or a constant. */
127 typedef struct opname_map_e_struct opname_map_e;
128 typedef struct opname_map_struct opname_map;
130 struct opname_map_e_struct
132 const char *operand_name; /* If null, then use constant_value. */
134 unsigned constant_value;
138 struct opname_map_struct
144 /* The "precond_list" and its element structure "precond_e" represents
145 explicit preconditions comparing operand variables and constants.
146 In the "precond_e" structure, a variable is identified by the name
147 in the "opname" field. If that field is NULL, then the operand
148 is the constant in field "opval". */
150 typedef struct precond_e_struct precond_e;
151 typedef struct precond_list_struct precond_list;
153 struct precond_e_struct
163 struct precond_list_struct
170 /* The insn_templ represents the INSN_TEMPL instruction template. It
171 is an opcode name with a list of operands. These are used for
172 instruction patterns and replacement patterns. */
174 typedef struct insn_templ_struct insn_templ;
175 struct insn_templ_struct
177 const char *opcode_name;
178 opname_map operand_map;
182 /* The insn_pattern represents an INSN_PATTERN instruction pattern.
183 It is an instruction template with preconditions that specify when
184 it actually matches a given instruction. */
186 typedef struct insn_pattern_struct insn_pattern;
187 struct insn_pattern_struct
190 precond_list preconds;
191 ReqOptionList *options;
195 /* The "insn_repl" and associated element structure "insn_repl_e"
196 instruction replacement list is a list of
197 instructions/LITERALS/LABELS with constant operands or operands
198 with names bound to the operand names in the associated pattern. */
200 typedef struct insn_repl_e_struct insn_repl_e;
201 struct insn_repl_e_struct
207 typedef struct insn_repl_struct insn_repl;
208 struct insn_repl_struct
215 /* The split_rec is a vector of allocated char * pointers. */
217 typedef struct split_rec_struct split_rec;
218 struct split_rec_struct
224 /* The "string_pattern_pair" is a set of pairs containing instruction
225 patterns and replacement strings. */
227 typedef struct string_pattern_pair_struct string_pattern_pair;
228 struct string_pattern_pair_struct
231 const char *replacement;
235 /* The widen_spec_list is a list of valid substitutions that generate
236 wider representations. These are generally used to specify
237 replacements for instructions whose immediates do not fit their
238 encodings. A valid transition may require multiple steps of
239 one-to-one instruction replacements with a final multiple
240 instruction replacement. As an example, here are the transitions
241 required to replace an 'addi.n' with an 'addi', 'addmi'.
246 => addmi a4, 0x1000, addi a4, 0x10. */
248 static string_pattern_pair widen_spec_list[] =
250 {"add.n %ar,%as,%at ? IsaUseDensityInstruction", "add %ar,%as,%at"},
251 {"addi.n %ar,%as,%imm ? IsaUseDensityInstruction", "addi %ar,%as,%imm"},
252 {"beqz.n %as,%label ? IsaUseDensityInstruction", "beqz %as,%label"},
253 {"bnez.n %as,%label ? IsaUseDensityInstruction", "bnez %as,%label"},
254 {"l32i.n %at,%as,%imm ? IsaUseDensityInstruction", "l32i %at,%as,%imm"},
255 {"mov.n %at,%as ? IsaUseDensityInstruction", "or %at,%as,%as"},
256 {"movi.n %as,%imm ? IsaUseDensityInstruction", "movi %as,%imm"},
257 {"nop.n ? IsaUseDensityInstruction ? realnop", "nop"},
258 {"nop.n ? IsaUseDensityInstruction ? no-realnop", "or 1,1,1"},
259 {"ret.n %as ? IsaUseDensityInstruction", "ret %as"},
260 {"retw.n %as ? IsaUseDensityInstruction", "retw %as"},
261 {"s32i.n %at,%as,%imm ? IsaUseDensityInstruction", "s32i %at,%as,%imm"},
262 {"srli %at,%as,%imm", "extui %at,%as,%imm,F32MINUS(%imm)"},
263 {"slli %ar,%as,0", "or %ar,%as,%as"},
265 /* Widening with literals or const16. */
266 {"movi %at,%imm ? IsaUseL32R ",
267 "LITERAL0 %imm; l32r %at,%LITERAL0"},
268 {"movi %at,%imm ? IsaUseConst16",
269 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm)"},
271 {"addi %ar,%as,%imm", "addmi %ar,%as,%imm"},
272 /* LOW8 is the low 8 bits of the Immed
273 MID8S is the middle 8 bits of the Immed */
274 {"addmi %ar,%as,%imm", "addmi %ar,%as,HI24S(%imm); addi %ar,%ar,LOW8(%imm)"},
276 /* In the end convert to either an l32r or const16. */
277 {"addmi %ar,%as,%imm | %ar!=%as ? IsaUseL32R",
278 "LITERAL0 %imm; l32r %ar,%LITERAL0; add %ar,%as,%ar"},
279 {"addmi %ar,%as,%imm | %ar!=%as ? IsaUseConst16",
280 "const16 %ar,HI16U(%imm); const16 %ar,LOW16U(%imm); add %ar,%as,%ar"},
282 /* Widening the load instructions with too-large immediates */
283 {"l8ui %at,%as,%imm | %at!=%as ? IsaUseL32R",
284 "LITERAL0 %imm; l32r %at,%LITERAL0; add %at,%at,%as; l8ui %at,%at,0"},
285 {"l16si %at,%as,%imm | %at!=%as ? IsaUseL32R",
286 "LITERAL0 %imm; l32r %at,%LITERAL0; add %at,%at,%as; l16si %at,%at,0"},
287 {"l16ui %at,%as,%imm | %at!=%as ? IsaUseL32R",
288 "LITERAL0 %imm; l32r %at,%LITERAL0; add %at,%at,%as; l16ui %at,%at,0"},
289 {"l32i %at,%as,%imm | %at!=%as ? IsaUseL32R",
290 "LITERAL0 %imm; l32r %at,%LITERAL0; add %at,%at,%as; l32i %at,%at,0"},
292 /* Widening load instructions with const16s. */
293 {"l8ui %at,%as,%imm | %at!=%as ? IsaUseConst16",
294 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l8ui %at,%at,0"},
295 {"l16si %at,%as,%imm | %at!=%as ? IsaUseConst16",
296 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l16si %at,%at,0"},
297 {"l16ui %at,%as,%imm | %at!=%as ? IsaUseConst16",
298 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l16ui %at,%at,0"},
299 {"l32i %at,%as,%imm | %at!=%as ? IsaUseConst16",
300 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l32i %at,%at,0"},
302 #if 0 /* Xtensa Synchronization Option not yet available */
303 {"l32ai %at,%as,%imm ? IsaUseL32R",
304 "LITERAL0 %imm; l32r %at,%LITERAL0; add.n %at,%at,%as; l32ai %at,%at,0"},
306 #if 0 /* Xtensa Speculation Option not yet available */
307 {"l32is %at,%as,%imm ? IsaUseL32R",
308 "LITERAL0 %imm; l32r %at,%LITERAL0; add.n %at,%at,%as; l32is %at,%at,0"},
311 /* This is only PART of the loop instruction. In addition,
312 hardcoded into its use is a modification of the final operand in
313 the instruction in bytes 9 and 12. */
314 {"loop %as,%label | %as!=1 ? IsaUseLoops",
316 "rsr.lend %as;" /* LEND */
317 "wsr.lbeg %as;" /* LBEG */
318 "addi %as, %as, 0;" /* lo8(%label-%LABEL1) */
319 "addmi %as, %as, 0;" /* mid8(%label-%LABEL1) */
322 "rsr.lcount %as;" /* LCOUNT */
323 "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */
325 {"loopgtz %as,%label | %as!=1 ? IsaUseLoops",
328 "loopgtz %as,%LABEL0;"
329 "rsr.lend %as;" /* LEND */
330 "wsr.lbeg %as;" /* LBEG */
331 "addi %as, %as, 0;" /* lo8(%label-%LABEL1) */
332 "addmi %as, %as, 0;" /* mid8(%label-%LABEL1) */
335 "rsr.lcount %as;" /* LCOUNT */
336 "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */
338 {"loopnez %as,%label | %as!=1 ? IsaUseLoops",
340 "loopnez %as,%LABEL0;"
341 "rsr.lend %as;" /* LEND */
342 "wsr.lbeg %as;" /* LBEG */
343 "addi %as, %as, 0;" /* lo8(%label-%LABEL1) */
344 "addmi %as, %as, 0;" /* mid8(%label-%LABEL1) */
347 "rsr.lcount %as;" /* LCOUNT */
348 "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */
351 {"beqz %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%LABEL0;j %label;LABEL0"},
352 {"bnez %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%LABEL0;j %label;LABEL0"},
353 {"beqz %as,%label", "bnez %as,%LABEL0;j %label;LABEL0"},
354 {"bnez %as,%label", "beqz %as,%LABEL0;j %label;LABEL0"},
355 {"beqzt %as,%label ? IsaUsePredictedBranches", "bnez %as,%LABEL0;j %label;LABEL0"},
356 {"bnezt %as,%label ? IsaUsePredictedBranches", "beqz %as,%LABEL0;j %label;LABEL0"},
358 {"bgez %as,%label", "bltz %as,%LABEL0;j %label;LABEL0"},
359 {"bltz %as,%label", "bgez %as,%LABEL0;j %label;LABEL0"},
360 {"beqi %as,%imm,%label", "bnei %as,%imm,%LABEL0;j %label;LABEL0"},
361 {"bnei %as,%imm,%label", "beqi %as,%imm,%LABEL0;j %label;LABEL0"},
362 {"bgei %as,%imm,%label", "blti %as,%imm,%LABEL0;j %label;LABEL0"},
363 {"blti %as,%imm,%label", "bgei %as,%imm,%LABEL0;j %label;LABEL0"},
364 {"bgeui %as,%imm,%label", "bltui %as,%imm,%LABEL0;j %label;LABEL0"},
365 {"bltui %as,%imm,%label", "bgeui %as,%imm,%LABEL0;j %label;LABEL0"},
366 {"bbci %as,%imm,%label", "bbsi %as,%imm,%LABEL0;j %label;LABEL0"},
367 {"bbsi %as,%imm,%label", "bbci %as,%imm,%LABEL0;j %label;LABEL0"},
368 {"beq %as,%at,%label", "bne %as,%at,%LABEL0;j %label;LABEL0"},
369 {"bne %as,%at,%label", "beq %as,%at,%LABEL0;j %label;LABEL0"},
370 {"beqt %as,%at,%label ? IsaUsePredictedBranches", "bne %as,%at,%LABEL0;j %label;LABEL0"},
371 {"bnet %as,%at,%label ? IsaUsePredictedBranches", "beq %as,%at,%LABEL0;j %label;LABEL0"},
372 {"bge %as,%at,%label", "blt %as,%at,%LABEL0;j %label;LABEL0"},
373 {"blt %as,%at,%label", "bge %as,%at,%LABEL0;j %label;LABEL0"},
374 {"bgeu %as,%at,%label", "bltu %as,%at,%LABEL0;j %label;LABEL0"},
375 {"bltu %as,%at,%label", "bgeu %as,%at,%LABEL0;j %label;LABEL0"},
376 {"bany %as,%at,%label", "bnone %as,%at,%LABEL0;j %label;LABEL0"},
378 {"bt %bs,%label ? IsaUseBooleans", "bf %bs,%LABEL0;j %label;LABEL0"},
379 {"bf %bs,%label ? IsaUseBooleans", "bt %bs,%LABEL0;j %label;LABEL0"},
381 {"bnone %as,%at,%label", "bany %as,%at,%LABEL0;j %label;LABEL0"},
382 {"ball %as,%at,%label", "bnall %as,%at,%LABEL0;j %label;LABEL0"},
383 {"bnall %as,%at,%label", "ball %as,%at,%LABEL0;j %label;LABEL0"},
384 {"bbc %as,%at,%label", "bbs %as,%at,%LABEL0;j %label;LABEL0"},
385 {"bbs %as,%at,%label", "bbc %as,%at,%LABEL0;j %label;LABEL0"},
387 /* Expanding calls with literals. */
388 {"call0 %label,%ar0 ? IsaUseL32R",
389 "LITERAL0 %label; l32r a0,%LITERAL0; callx0 a0,%ar0"},
390 {"call4 %label,%ar4 ? IsaUseL32R",
391 "LITERAL0 %label; l32r a4,%LITERAL0; callx4 a4,%ar4"},
392 {"call8 %label,%ar8 ? IsaUseL32R",
393 "LITERAL0 %label; l32r a8,%LITERAL0; callx8 a8,%ar8"},
394 {"call12 %label,%ar12 ? IsaUseL32R",
395 "LITERAL0 %label; l32r a12,%LITERAL0; callx12 a12,%ar12"},
397 /* Expanding calls with const16. */
398 {"call0 %label,%ar0 ? IsaUseConst16",
399 "const16 a0,HI16U(%label); const16 a0,LOW16U(%label); callx0 a0,%ar0"},
400 {"call4 %label,%ar4 ? IsaUseConst16",
401 "const16 a4,HI16U(%label); const16 a4,LOW16U(%label); callx4 a4,%ar4"},
402 {"call8 %label,%ar8 ? IsaUseConst16",
403 "const16 a8,HI16U(%label); const16 a8,LOW16U(%label); callx8 a8,%ar8"},
404 {"call12 %label,%ar12 ? IsaUseConst16",
405 "const16 a12,HI16U(%label); const16 a12,LOW16U(%label); callx12 a12,%ar12"}
408 #define WIDEN_COUNT (sizeof (widen_spec_list) / sizeof (string_pattern_pair))
411 /* The simplify_spec_list specifies simplifying transformations that
412 will reduce the instruction width or otherwise simplify an
413 instruction. These are usually applied before relaxation in the
414 assembler. It is always legal to simplify. Even for "addi as, 0",
415 the "addi.n as, 0" will eventually be widened back to an "addi 0"
416 after the widening table is applied. Note: The usage of this table
417 has changed somewhat so that it is entirely specific to "narrowing"
418 instructions to use the density option. This table is not used at
419 all when the density option is not available. */
421 string_pattern_pair simplify_spec_list[] =
423 {"add %ar,%as,%at ? IsaUseDensityInstruction", "add.n %ar,%as,%at"},
424 {"addi.n %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"},
425 {"addi %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"},
426 {"addi %ar,%as,%imm ? IsaUseDensityInstruction", "addi.n %ar,%as,%imm"},
427 {"addmi %ar,%as,%imm ? IsaUseDensityInstruction", "addi.n %ar,%as,%imm"},
428 {"beqz %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%label"},
429 {"bnez %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%label"},
430 {"l32i %at,%as,%imm ? IsaUseDensityInstruction", "l32i.n %at,%as,%imm"},
431 {"movi %as,%imm ? IsaUseDensityInstruction", "movi.n %as,%imm"},
432 {"nop ? realnop ? IsaUseDensityInstruction", "nop.n"},
433 {"or %ar,%as,%at | %ar==%as | %as==%at ? IsaUseDensityInstruction", "nop.n"},
434 {"or %ar,%as,%at | %ar!=%as | %as==%at ? IsaUseDensityInstruction", "mov.n %ar,%as"},
435 {"ret %as ? IsaUseDensityInstruction", "ret.n %as"},
436 {"retw %as ? IsaUseDensityInstruction", "retw.n %as"},
437 {"s32i %at,%as,%imm ? IsaUseDensityInstruction", "s32i.n %at,%as,%imm"},
438 {"slli %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"}
441 #define SIMPLIFY_COUNT \
442 (sizeof (simplify_spec_list) / sizeof (string_pattern_pair))
445 /* Transition generation helpers. */
447 static void append_transition
448 PARAMS ((TransitionTable *, xtensa_opcode, TransitionRule *,
450 static void append_condition
451 PARAMS ((TransitionRule *, Precondition *));
452 static void append_value_condition
453 PARAMS ((TransitionRule *, CmpOp, unsigned, unsigned));
454 static void append_constant_value_condition
455 PARAMS ((TransitionRule *, CmpOp, unsigned, unsigned));
456 static void append_build_insn
457 PARAMS ((TransitionRule *, BuildInstr *));
458 static void append_op
459 PARAMS ((BuildInstr *, BuildOp *));
460 static void append_literal_op
461 PARAMS ((BuildInstr *, unsigned, unsigned));
462 static void append_label_op
463 PARAMS ((BuildInstr *, unsigned, unsigned));
464 static void append_constant_op
465 PARAMS ((BuildInstr *, unsigned, unsigned));
466 static void append_field_op
467 PARAMS ((BuildInstr *, unsigned, unsigned));
468 static void append_user_fn_field_op
469 PARAMS ((BuildInstr *, unsigned, OpType, unsigned));
470 static long operand_function_HI24S
472 static long operand_function_F32MINUS
474 static long operand_function_LOW8
476 static long operand_function_LOW16U
478 static long operand_function_HI16U
481 /* Externally visible functions. */
483 extern bfd_boolean xg_has_userdef_op_fn
485 extern long xg_apply_userdef_op_fn
486 PARAMS ((OpType, long));
488 /* Parsing helpers. */
490 static const char *enter_opname_n
491 PARAMS ((const char *, int));
492 static const char *enter_opname
493 PARAMS ((const char *));
495 /* Construction and destruction. */
497 static void init_opname_map
498 PARAMS ((opname_map *));
499 static void clear_opname_map
500 PARAMS ((opname_map *));
501 static void init_precond_list
502 PARAMS ((precond_list *));
503 static void clear_precond_list
504 PARAMS ((precond_list *));
505 static void init_insn_templ
506 PARAMS ((insn_templ *));
507 static void clear_insn_templ
508 PARAMS ((insn_templ *));
509 static void init_insn_pattern
510 PARAMS ((insn_pattern *));
511 static void clear_insn_pattern
512 PARAMS ((insn_pattern *));
513 static void init_insn_repl
514 PARAMS ((insn_repl *));
515 static void clear_insn_repl
516 PARAMS ((insn_repl *));
517 static void init_split_rec
518 PARAMS ((split_rec *));
519 static void clear_split_rec
520 PARAMS ((split_rec *));
521 static void clear_req_or_option_list
522 PARAMS ((ReqOrOption **));
523 static void clear_req_option_list
524 PARAMS ((ReqOption **));
525 static ReqOrOption *clone_req_or_option_list
526 PARAMS ((ReqOrOption *));
527 static ReqOption *clone_req_option_list
528 PARAMS ((ReqOption *));
530 /* Operand and insn_templ helpers. */
532 static bfd_boolean same_operand_name
533 PARAMS ((const opname_map_e *, const opname_map_e *));
534 static opname_map_e *get_opmatch
535 PARAMS ((opname_map *, const char *));
536 static bfd_boolean op_is_constant
537 PARAMS ((const opname_map_e *));
538 static unsigned op_get_constant
539 PARAMS ((const opname_map_e *));
540 static int insn_templ_operand_count
541 PARAMS ((const insn_templ *));
543 /* Parsing helpers. */
545 static const char *skip_white
546 PARAMS ((const char *));
547 static void trim_whitespace
549 static void split_string
550 PARAMS ((split_rec *, const char *, char, bfd_boolean));
552 /* Language parsing. */
554 static bfd_boolean parse_insn_pattern
555 PARAMS ((const char *, insn_pattern *));
556 static bfd_boolean parse_insn_repl
557 PARAMS ((const char *, insn_repl *));
558 static bfd_boolean parse_insn_templ
559 PARAMS ((const char *, insn_templ *));
560 static bfd_boolean parse_special_fn
561 PARAMS ((const char *, const char **, const char **));
562 static bfd_boolean parse_precond
563 PARAMS ((const char *, precond_e *));
564 static bfd_boolean parse_constant
565 PARAMS ((const char *, unsigned *));
566 static bfd_boolean parse_id_constant
567 PARAMS ((const char *, const char *, unsigned *));
568 static bfd_boolean parse_option_cond
569 PARAMS ((const char *, ReqOption *));
571 /* Transition table building code. */
573 static bfd_boolean transition_applies
574 PARAMS ((insn_pattern *, const char *, const char *));
575 static TransitionRule *build_transition
576 PARAMS ((insn_pattern *, insn_repl *, const char *, const char *));
577 static TransitionTable *build_transition_table
578 PARAMS ((const string_pattern_pair *, int, transition_cmp_fn));
582 append_transition (tt, opcode, t, cmp)
584 xtensa_opcode opcode;
586 transition_cmp_fn cmp;
588 TransitionList *tl = (TransitionList *) xmalloc (sizeof (TransitionList));
589 TransitionList *prev;
590 TransitionList **t_p;
592 assert (opcode < tt->num_opcodes);
594 prev = tt->table[opcode];
599 tt->table[opcode] = tl;
603 for (t_p = &tt->table[opcode]; (*t_p) != NULL; t_p = &(*t_p)->next)
605 if (cmp && cmp (t, (*t_p)->rule) < 0)
607 /* Insert it here. */
618 append_condition (tr, cond)
622 PreconditionList *pl =
623 (PreconditionList *) xmalloc (sizeof (PreconditionList));
624 PreconditionList *prev = tr->conditions;
625 PreconditionList *nxt;
645 append_value_condition (tr, cmp, op1, op2)
651 Precondition *cond = (Precondition *) xmalloc (sizeof (Precondition));
655 cond->typ = OP_OPERAND;
657 append_condition (tr, cond);
662 append_constant_value_condition (tr, cmp, op1, cnst)
668 Precondition *cond = (Precondition *) xmalloc (sizeof (Precondition));
672 cond->typ = OP_CONSTANT;
673 cond->op_data = cnst;
674 append_condition (tr, cond);
679 append_build_insn (tr, bi)
683 BuildInstr *prev = tr->to_instr;
707 BuildOp *prev = bi->ops;
726 append_literal_op (bi, op1, litnum)
731 BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
734 b_op->typ = OP_LITERAL;
735 b_op->op_data = litnum;
737 append_op (bi, b_op);
742 append_label_op (bi, op1, labnum)
747 BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
750 b_op->typ = OP_LABEL;
751 b_op->op_data = labnum;
753 append_op (bi, b_op);
758 append_constant_op (bi, op1, cnst)
763 BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
766 b_op->typ = OP_CONSTANT;
767 b_op->op_data = cnst;
769 append_op (bi, b_op);
774 append_field_op (bi, op1, src_op)
779 BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
782 b_op->typ = OP_OPERAND;
783 b_op->op_data = src_op;
785 append_op (bi, b_op);
789 /* These could be generated but are not currently. */
792 append_user_fn_field_op (bi, op1, typ, src_op)
798 BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
802 b_op->op_data = src_op;
804 append_op (bi, b_op);
808 /* These operand functions are the semantics of user-defined
809 operand functions. */
812 operand_function_HI24S (a)
816 return (a & (~0xff)) + 0x100;
818 return (a & (~0xff));
823 operand_function_F32MINUS (a)
831 operand_function_LOW8 (a)
835 return (a & 0xff) | ~0xff;
842 operand_function_LOW16U (a)
850 operand_function_HI16U (a)
853 unsigned long b = a & 0xffff0000;
854 return (long) (b >> 16);
859 xg_has_userdef_op_fn (op)
864 case OP_OPERAND_F32MINUS:
865 case OP_OPERAND_LOW8:
866 case OP_OPERAND_HI24S:
867 case OP_OPERAND_LOW16U:
868 case OP_OPERAND_HI16U:
878 xg_apply_userdef_op_fn (op, a)
884 case OP_OPERAND_F32MINUS:
885 return operand_function_F32MINUS (a);
886 case OP_OPERAND_LOW8:
887 return operand_function_LOW8 (a);
888 case OP_OPERAND_HI24S:
889 return operand_function_HI24S (a);
890 case OP_OPERAND_LOW16U:
891 return operand_function_LOW16U (a);
892 case OP_OPERAND_HI16U:
893 return operand_function_HI16U (a);
901 /* Generate a transition table. */
904 enter_opname_n (name, len)
910 for (op = local_opnames; op != NULL; op = op->next)
912 if (strlen (op->opname) == (unsigned) len
913 && strncmp (op->opname, name, len) == 0)
916 op = (opname_e *) xmalloc (sizeof (opname_e));
917 op->opname = (char *) xmalloc (len + 1);
918 strncpy (op->opname, name, len);
919 op->opname[len] = '\0';
930 for (op = local_opnames; op != NULL; op = op->next)
932 if (strcmp (op->opname, name) == 0)
935 op = (opname_e *) xmalloc (sizeof (opname_e));
936 op->opname = xstrdup (name);
956 while (m->head != NULL)
967 same_operand_name (m1, m2)
968 const opname_map_e *m1;
969 const opname_map_e *m2;
971 if (m1->operand_name == NULL || m1->operand_name == NULL)
973 return (m1->operand_name == m2->operand_name);
978 get_opmatch (map, operand_name)
980 const char *operand_name;
984 for (m = map->head; m != NULL; m = m->next)
986 if (strcmp (m->operand_name, operand_name) == 0)
995 const opname_map_e *m1;
997 return (m1->operand_name == NULL);
1002 op_get_constant (m1)
1003 const opname_map_e *m1;
1005 assert (m1->operand_name == NULL);
1006 return m1->constant_value;
1011 init_precond_list (l)
1020 clear_precond_list (l)
1025 while (l->head != NULL)
1039 t->opcode_name = NULL;
1040 init_opname_map (&t->operand_map);
1045 clear_insn_templ (t)
1048 clear_opname_map (&t->operand_map);
1053 init_insn_pattern (p)
1056 init_insn_templ (&p->t);
1057 init_precond_list (&p->preconds);
1063 clear_insn_pattern (p)
1066 clear_insn_templ (&p->t);
1067 clear_precond_list (&p->preconds);
1086 while (r->head != NULL)
1090 clear_insn_templ (&e->t);
1097 insn_templ_operand_count (t)
1098 const insn_templ *t;
1101 const opname_map_e *op;
1103 for (op = t->operand_map.head; op != NULL; op = op->next, i++)
1109 /* Convert a string to a number. E.G.: parse_constant("10", &num) */
1112 parse_constant (in, val_p)
1125 if (*p >= '0' && *p <= '9')
1126 val = val * 10 + (*p - '0');
1136 /* Match a pattern like "foo1" with
1137 parse_id_constant("foo1", "foo", &num).
1138 This may also be used to just match a number. */
1141 parse_id_constant (in, name, val_p)
1146 unsigned namelen = 0;
1153 namelen = strlen (name);
1155 if (name != NULL && strncmp (in, name, namelen) != 0)
1159 return parse_constant (p, val_p);
1164 parse_special_fn (name, fn_name_p, arg_name_p)
1166 const char **fn_name_p;
1167 const char **arg_name_p;
1172 p_start = strchr (name, '(');
1173 if (p_start == NULL)
1176 p_end = strchr (p_start, ')');
1181 if (p_end[1] != '\0')
1184 *fn_name_p = enter_opname_n (name, p_start - name);
1185 *arg_name_p = enter_opname_n (p_start + 1, p_end - p_start - 1);
1203 trim_whitespace (in)
1206 char *last_white = NULL;
1209 while (p && *p != '\0')
1213 if (last_white == NULL)
1228 /* Split a string into component strings where "c" is the
1229 delimiter. Place the result in the split_rec. */
1232 split_string (rec, in, c, elide_whitespace)
1236 bfd_boolean elide_whitespace;
1242 while (p != NULL && *p != '\0')
1252 if (rec->count == 0)
1255 rec->vec = (char **) xmalloc (sizeof (char *) * cnt);
1256 for (i = 0; i < cnt; i++)
1260 for (i = 0; i < cnt; i++)
1266 if (elide_whitespace)
1271 rec->vec[i] = xstrdup (q);
1275 rec->vec[i] = (char *) xmalloc (sizeof (char) * (len + 1));
1276 strncpy (rec->vec[i], q, len);
1277 rec->vec[i][len] = '\0';
1281 if (elide_whitespace)
1282 trim_whitespace (rec->vec[i]);
1288 clear_split_rec (rec)
1293 for (i = 0; i < rec->count; i++)
1301 /* Initialize a split record. The split record must be initialized
1302 before split_string is called. */
1305 init_split_rec (rec)
1313 /* Parse an instruction template like "insn op1, op2, op3". */
1316 parse_insn_templ (s, t)
1325 /* First find the first whitespace. */
1327 init_split_rec (&oprec);
1330 insn_name_len = strcspn (s, " ");
1331 if (insn_name_len == 0)
1334 init_insn_templ (t);
1335 t->opcode_name = enter_opname_n (p, insn_name_len);
1337 p = p + insn_name_len;
1339 /* Split by ',' and skip beginning and trailing whitespace. */
1340 split_string (&oprec, p, ',', TRUE);
1342 for (i = 0; i < oprec.count; i++)
1344 const char *opname = oprec.vec[i];
1345 opname_map_e *e = (opname_map_e *) xmalloc (sizeof (opname_map_e));
1347 e->operand_name = NULL;
1348 e->constant_value = 0;
1351 /* If it begins with a number, assume that it is a number. */
1352 if (opname && opname[0] >= '0' && opname[0] <= '9')
1356 if (parse_constant (opname, &val))
1357 e->constant_value = val;
1361 clear_split_rec (&oprec);
1362 clear_insn_templ (t);
1367 e->operand_name = enter_opname (oprec.vec[i]);
1369 *t->operand_map.tail = e;
1370 t->operand_map.tail = &e->next;
1372 clear_split_rec (&oprec);
1378 parse_precond (s, precond)
1382 /* All preconditions are currently of the form:
1383 a == b or a != b or a == k (where k is a constant).
1384 Later we may use some special functions like DENSITY == 1
1385 to identify when density is available. */
1389 precond->opname1 = NULL;
1390 precond->opval1 = 0;
1391 precond->cmpop = OP_EQUAL;
1392 precond->opname2 = NULL;
1393 precond->opval2 = 0;
1394 precond->next = NULL;
1398 len = strcspn (p, " !=");
1403 precond->opname1 = enter_opname_n (p, len);
1407 /* Check for "==" and "!=". */
1408 if (strncmp (p, "==", 2) == 0)
1409 precond->cmpop = OP_EQUAL;
1410 else if (strncmp (p, "!=", 2) == 0)
1411 precond->cmpop = OP_NOTEQUAL;
1418 /* No trailing whitespace from earlier parsing. */
1419 if (p[0] >= '0' && p[0] <= '9')
1422 if (parse_constant (p, &val))
1423 precond->opval2 = val;
1428 precond->opname2 = enter_opname (p);
1434 clear_req_or_option_list (r_p)
1440 free ((*r_p)->option_name);
1441 clear_req_or_option_list (&(*r_p)->next);
1447 clear_req_option_list (r_p)
1453 clear_req_or_option_list (&(*r_p)->or_option_terms);
1454 clear_req_option_list (&(*r_p)->next);
1460 clone_req_or_option_list (req_or_option)
1461 ReqOrOption *req_or_option;
1463 ReqOrOption *new_req_or_option;
1465 if (req_or_option == NULL)
1468 new_req_or_option = (ReqOrOption *) xmalloc (sizeof (ReqOrOption));
1469 new_req_or_option->option_name = xstrdup (req_or_option->option_name);
1470 new_req_or_option->is_true = req_or_option->is_true;
1471 new_req_or_option->next = NULL;
1472 new_req_or_option->next = clone_req_or_option_list (req_or_option->next);
1473 return new_req_or_option;
1478 clone_req_option_list (req_option)
1479 ReqOption *req_option;
1481 ReqOption *new_req_option;
1483 if (req_option == NULL)
1486 new_req_option = (ReqOption *) xmalloc (sizeof (ReqOption));
1487 new_req_option->or_option_terms = NULL;
1488 new_req_option->next = NULL;
1489 new_req_option->or_option_terms =
1490 clone_req_or_option_list (req_option->or_option_terms);
1491 new_req_option->next = clone_req_option_list (req_option->next);
1492 return new_req_option;
1497 parse_option_cond (s, option)
1502 split_rec option_term_rec;
1504 /* All option or conditions are of the form:
1505 optionA + no-optionB + ...
1506 "Ands" are divided by "?". */
1508 init_split_rec (&option_term_rec);
1509 split_string (&option_term_rec, s, '+', TRUE);
1511 if (option_term_rec.count == 0)
1513 clear_split_rec (&option_term_rec);
1517 for (i = 0; i < option_term_rec.count; i++)
1519 char *option_name = option_term_rec.vec[i];
1520 bfd_boolean is_true = TRUE;
1524 if (strncmp (option_name, "no-", 3) == 0)
1526 option_name = xstrdup (&option_name[3]);
1530 option_name = xstrdup (option_name);
1532 req = (ReqOrOption *) xmalloc (sizeof (ReqOrOption));
1533 req->option_name = option_name;
1534 req->is_true = is_true;
1537 /* Append to list. */
1538 for (r_p = &option->or_option_terms; (*r_p) != NULL;
1539 r_p = &(*r_p)->next)
1547 /* Parse a string like:
1548 "insn op1, op2, op3, op4 | op1 != op2 | op2 == op3 | op4 == 1".
1549 I.E., instruction "insn" with 4 operands where operand 1 and 2 are not
1550 the same and operand 2 and 3 are the same and operand 4 is 1.
1554 "insn op1 | op1 == 1 / density + boolean / no-useroption".
1555 i.e. instruction "insn" with 1 operands where operand 1 is 1
1556 when "density" or "boolean" options are available and
1557 "useroption" is not available.
1559 Because the current implementation of this parsing scheme uses
1560 split_string, it requires that '|' and '?' are only used as
1561 delimiters for predicates and required options. */
1564 parse_insn_pattern (in, insn)
1569 split_rec optionrec;
1572 init_insn_pattern (insn);
1574 init_split_rec (&optionrec);
1575 split_string (&optionrec, in, '?', TRUE);
1576 if (optionrec.count == 0)
1578 clear_split_rec (&optionrec);
1582 init_split_rec (&rec);
1584 split_string (&rec, optionrec.vec[0], '|', TRUE);
1588 clear_split_rec (&rec);
1589 clear_split_rec (&optionrec);
1593 if (!parse_insn_templ (rec.vec[0], &insn->t))
1595 clear_split_rec (&rec);
1596 clear_split_rec (&optionrec);
1600 for (i = 1; i < rec.count; i++)
1602 precond_e *cond = (precond_e *) xmalloc (sizeof (precond_e));
1604 if (!parse_precond (rec.vec[i], cond))
1606 clear_split_rec (&rec);
1607 clear_split_rec (&optionrec);
1608 clear_insn_pattern (insn);
1612 /* Append the condition. */
1613 *insn->preconds.tail = cond;
1614 insn->preconds.tail = &cond->next;
1617 for (i = 1; i < optionrec.count; i++)
1619 /* Handle the option conditions. */
1621 ReqOption *req_option = (ReqOption *) xmalloc (sizeof (ReqOption));
1622 req_option->or_option_terms = NULL;
1623 req_option->next = NULL;
1625 if (!parse_option_cond (optionrec.vec[i], req_option))
1627 clear_split_rec (&rec);
1628 clear_split_rec (&optionrec);
1629 clear_insn_pattern (insn);
1630 clear_req_option_list (&req_option);
1634 /* Append the condition. */
1635 for (r_p = &insn->options; (*r_p) != NULL; r_p = &(*r_p)->next)
1638 (*r_p) = req_option;
1641 clear_split_rec (&rec);
1642 clear_split_rec (&optionrec);
1648 parse_insn_repl (in, r_p)
1652 /* This is a list of instruction templates separated by ';'. */
1656 split_string (&rec, in, ';', TRUE);
1658 for (i = 0; i < rec.count; i++)
1660 insn_repl_e *e = (insn_repl_e *) xmalloc (sizeof (insn_repl_e));
1664 if (!parse_insn_templ (rec.vec[i], &e->t))
1667 clear_insn_repl (r_p);
1671 r_p->tail = &e->next;
1678 transition_applies (initial_insn, from_string, to_string)
1679 insn_pattern *initial_insn;
1680 const char *from_string ATTRIBUTE_UNUSED;
1681 const char *to_string ATTRIBUTE_UNUSED;
1683 ReqOption *req_option;
1685 for (req_option = initial_insn->options;
1687 req_option = req_option->next)
1689 ReqOrOption *req_or_option = req_option->or_option_terms;
1691 if (req_or_option == NULL
1692 || req_or_option->next != NULL)
1695 if (strncmp (req_or_option->option_name, "IsaUse", 6) == 0)
1697 bfd_boolean option_available = FALSE;
1698 char *option_name = req_or_option->option_name + 6;
1699 if (!strcmp (option_name, "DensityInstruction"))
1700 option_available = (XCHAL_HAVE_DENSITY == 1);
1701 else if (!strcmp (option_name, "L32R"))
1702 option_available = (XCHAL_HAVE_L32R == 1);
1703 else if (!strcmp (option_name, "Const16"))
1704 option_available = (XCHAL_HAVE_CONST16 == 1);
1705 else if (!strcmp (option_name, "Loops"))
1706 option_available = (XCHAL_HAVE_LOOPS == 1);
1707 else if (!strcmp (option_name, "PredictedBranches"))
1708 option_available = (XCHAL_HAVE_PREDICTED_BRANCHES == 1);
1709 else if (!strcmp (option_name, "Booleans"))
1710 option_available = (XCHAL_HAVE_BOOLEANS == 1);
1712 as_warn (_("invalid configuration option '%s' in transition rule '%s'"),
1713 req_or_option->option_name, from_string);
1714 if ((option_available ^ req_or_option->is_true) != 0)
1717 else if (strcmp (req_or_option->option_name, "realnop") == 0)
1719 bfd_boolean nop_available =
1720 (xtensa_opcode_lookup (xtensa_default_isa, "nop")
1721 != XTENSA_UNDEFINED);
1722 if ((nop_available ^ req_or_option->is_true) != 0)
1731 build_transition (initial_insn, replace_insns, from_string, to_string)
1732 insn_pattern *initial_insn;
1733 insn_repl *replace_insns;
1734 const char *from_string;
1735 const char *to_string;
1737 TransitionRule *tr = NULL;
1738 xtensa_opcode opcode;
1739 xtensa_isa isa = xtensa_default_isa;
1746 unsigned label_count = 0;
1747 unsigned max_label_count = 0;
1748 bfd_boolean has_label = FALSE;
1749 unsigned literal_count = 0;
1751 opcode = xtensa_opcode_lookup (isa, initial_insn->t.opcode_name);
1752 if (opcode == XTENSA_UNDEFINED)
1754 /* It is OK to not be able to translate some of these opcodes. */
1756 as_warn (_("invalid opcode '%s' in transition rule '%s'"),
1757 initial_insn->t.opcode_name, from_string);
1763 if (xtensa_opcode_num_operands (isa, opcode)
1764 != insn_templ_operand_count (&initial_insn->t))
1766 /* This is also OK because there are opcodes that
1767 have different numbers of operands on different
1768 architecture variations. */
1770 as_fatal (_("opcode %s mismatched operand count %d != expected %d"),
1771 xtensa_opcode_name (isa, opcode),
1772 xtensa_num_operands (isa, opcode),
1773 insn_templ_operand_count (&initial_insn->t));
1778 tr = (TransitionRule *) xmalloc (sizeof (TransitionRule));
1779 tr->opcode = opcode;
1780 tr->conditions = NULL;
1781 tr->to_instr = NULL;
1783 /* Build the conditions. First, equivalent operand condition.... */
1784 for (op1 = initial_insn->t.operand_map.head; op1 != NULL; op1 = op1->next)
1786 for (op2 = op1->next; op2 != NULL; op2 = op2->next)
1788 if (same_operand_name (op1, op2))
1790 append_value_condition (tr, OP_EQUAL,
1791 op1->operand_num, op2->operand_num);
1796 /* Now the condition that an operand value must be a constant.... */
1797 for (op1 = initial_insn->t.operand_map.head; op1 != NULL; op1 = op1->next)
1799 if (op_is_constant (op1))
1801 append_constant_value_condition (tr,
1804 op_get_constant (op1));
1809 /* Now add the explicit preconditions listed after the "|" in the spec.
1810 These are currently very limited, so we do a special case
1811 parse for them. We expect spaces, opname != opname. */
1812 for (precond = initial_insn->preconds.head;
1814 precond = precond->next)
1819 if (precond->opname1)
1821 op1 = get_opmatch (&initial_insn->t.operand_map, precond->opname1);
1824 as_fatal (_("opcode '%s': no bound opname '%s' "
1825 "for precondition in '%s'"),
1826 xtensa_opcode_name (isa, opcode),
1827 precond->opname1, from_string);
1832 if (precond->opname2)
1834 op2 = get_opmatch (&initial_insn->t.operand_map, precond->opname2);
1837 as_fatal (_("opcode '%s': no bound opname '%s' "
1838 "for precondition in %s"),
1839 xtensa_opcode_name (isa, opcode),
1840 precond->opname2, from_string);
1845 if (op1 == NULL && op2 == NULL)
1847 as_fatal (_("opcode '%s': precondition only contains "
1848 "constants in '%s'"),
1849 xtensa_opcode_name (isa, opcode), from_string);
1852 else if (op1 != NULL && op2 != NULL)
1853 append_value_condition (tr, precond->cmpop,
1854 op1->operand_num, op2->operand_num);
1855 else if (op2 == NULL)
1856 append_constant_value_condition (tr, precond->cmpop,
1857 op1->operand_num, precond->opval2);
1859 append_constant_value_condition (tr, precond->cmpop,
1860 op2->operand_num, precond->opval1);
1863 tr->options = clone_req_option_list (initial_insn->options);
1865 /* Generate the replacement instructions. Some of these
1866 "instructions" are actually labels and literals. The literals
1867 must be defined in order 0..n and a literal must be defined
1868 (e.g., "LITERAL0 %imm") before use (e.g., "%LITERAL0"). The
1869 labels must be defined in order, but they can be used before they
1870 are defined. Also there are a number of special operands (e.g.,
1873 for (r = replace_insns->head; r != NULL; r = r->next)
1876 const char *opcode_name;
1880 const char *fn_name;
1881 const char *operand_arg_name;
1883 bi = (BuildInstr *) xmalloc (sizeof (BuildInstr));
1884 append_build_insn (tr, bi);
1887 bi->opcode = XTENSA_UNDEFINED;
1891 opcode_name = r->t.opcode_name;
1892 operand_count = insn_templ_operand_count (&r->t);
1894 if (parse_id_constant (opcode_name, "LITERAL", &idnum))
1896 bi->typ = INSTR_LITERAL_DEF;
1898 if (idnum != literal_count)
1899 as_fatal (_("generated literals must be numbered consecutively"));
1901 if (operand_count != 1)
1902 as_fatal (_("expected one operand for generated literal"));
1905 else if (parse_id_constant (opcode_name, "LABEL", &idnum))
1907 bi->typ = INSTR_LABEL_DEF;
1909 if (idnum != label_count)
1910 as_fatal (_("generated labels must be numbered consecutively"));
1912 if (operand_count != 0)
1913 as_fatal (_("expected 0 operands for generated label"));
1917 bi->typ = INSTR_INSTR;
1918 bi->opcode = xtensa_opcode_lookup (isa, r->t.opcode_name);
1919 if (bi->opcode == XTENSA_UNDEFINED)
1921 as_warn (_("invalid opcode '%s' in transition rule '%s'"),
1922 r->t.opcode_name, to_string);
1925 /* Check for the right number of ops. */
1926 if (xtensa_opcode_num_operands (isa, bi->opcode)
1927 != (int) operand_count)
1928 as_fatal (_("opcode '%s': replacement does not have %d ops"),
1930 xtensa_opcode_num_operands (isa, bi->opcode));
1933 for (op = r->t.operand_map.head; op != NULL; op = op->next)
1937 if (op_is_constant (op))
1938 append_constant_op (bi, op->operand_num, op_get_constant (op));
1939 else if (parse_id_constant (op->operand_name, "%LITERAL", &idnum))
1941 if (idnum >= literal_count)
1942 as_fatal (_("opcode %s: replacement "
1943 "literal %d >= literal_count(%d)"),
1944 opcode_name, idnum, literal_count);
1945 append_literal_op (bi, op->operand_num, idnum);
1947 else if (parse_id_constant (op->operand_name, "%LABEL", &idnum))
1950 if (idnum > max_label_count)
1951 max_label_count = idnum;
1952 append_label_op (bi, op->operand_num, idnum);
1954 else if (parse_id_constant (op->operand_name, "a", &idnum))
1955 append_constant_op (bi, op->operand_num, idnum);
1956 else if (op->operand_name[0] == '%')
1958 opname_map_e *orig_op;
1959 orig_op = get_opmatch (&initial_insn->t.operand_map,
1961 if (orig_op == NULL)
1963 as_fatal (_("opcode %s: unidentified operand '%s' in '%s'"),
1964 opcode_name, op->operand_name, to_string);
1966 append_constant_op (bi, op->operand_num, 0);
1969 append_field_op (bi, op->operand_num, orig_op->operand_num);
1971 else if (parse_special_fn (op->operand_name,
1972 &fn_name, &operand_arg_name))
1974 opname_map_e *orig_op;
1975 OpType typ = OP_CONSTANT;
1977 if (strcmp (fn_name, "LOW8") == 0)
1978 typ = OP_OPERAND_LOW8;
1979 else if (strcmp (fn_name, "HI24S") == 0)
1980 typ = OP_OPERAND_HI24S;
1981 else if (strcmp (fn_name, "F32MINUS") == 0)
1982 typ = OP_OPERAND_F32MINUS;
1983 else if (strcmp (fn_name, "LOW16U") == 0)
1984 typ = OP_OPERAND_LOW16U;
1985 else if (strcmp (fn_name, "HI16U") == 0)
1986 typ = OP_OPERAND_HI16U;
1988 as_fatal (_("unknown user-defined function %s"), fn_name);
1990 orig_op = get_opmatch (&initial_insn->t.operand_map,
1992 if (orig_op == NULL)
1994 as_fatal (_("opcode %s: unidentified operand '%s' in '%s'"),
1995 opcode_name, op->operand_name, to_string);
1996 append_constant_op (bi, op->operand_num, 0);
1999 append_user_fn_field_op (bi, op->operand_num,
2000 typ, orig_op->operand_num);
2004 as_fatal (_("opcode %s: could not parse operand '%s' in '%s'"),
2005 opcode_name, op->operand_name, to_string);
2006 append_constant_op (bi, op->operand_num, 0);
2010 if (has_label && max_label_count >= label_count)
2012 as_fatal (_("opcode %s: replacement label %d >= label_count(%d)"),
2013 xtensa_opcode_name (isa, opcode),
2014 max_label_count, label_count);
2023 build_transition_table (transitions, transition_count, cmp)
2024 const string_pattern_pair *transitions;
2025 int transition_count;
2026 transition_cmp_fn cmp;
2028 TransitionTable *table = NULL;
2029 int num_opcodes = xtensa_isa_num_opcodes (xtensa_default_isa);
2035 /* Otherwise, build it now. */
2036 table = (TransitionTable *) xmalloc (sizeof (TransitionTable));
2037 table->num_opcodes = num_opcodes;
2039 (TransitionList **) xmalloc (sizeof (TransitionTable *) * num_opcodes);
2041 for (i = 0; i < num_opcodes; i++)
2042 table->table[i] = NULL;
2044 for (tnum = 0; tnum < transition_count; tnum++)
2046 const char *from_string = transitions[tnum].pattern;
2047 const char *to_string = transitions[tnum].replacement;
2049 insn_pattern initial_insn;
2050 insn_repl replace_insns;
2053 init_insn_pattern (&initial_insn);
2054 if (!parse_insn_pattern (from_string, &initial_insn))
2056 as_fatal (_("could not parse INSN_PATTERN '%s'"), from_string);
2057 clear_insn_pattern (&initial_insn);
2061 init_insn_repl (&replace_insns);
2062 if (!parse_insn_repl (to_string, &replace_insns))
2064 as_fatal (_("could not parse INSN_REPL '%s'"), to_string);
2065 clear_insn_pattern (&initial_insn);
2066 clear_insn_repl (&replace_insns);
2070 if (transition_applies (&initial_insn, from_string, to_string))
2072 tr = build_transition (&initial_insn, &replace_insns,
2073 from_string, to_string);
2075 append_transition (table, tr->opcode, tr, cmp);
2079 as_warn (_("could not build transition for %s => %s"),
2080 from_string, to_string);
2085 clear_insn_repl (&replace_insns);
2086 clear_insn_pattern (&initial_insn);
2092 extern TransitionTable *
2093 xg_build_widen_table (cmp)
2094 transition_cmp_fn cmp;
2096 static TransitionTable *table = NULL;
2098 table = build_transition_table (widen_spec_list, WIDEN_COUNT, cmp);
2103 extern TransitionTable *
2104 xg_build_simplify_table (cmp)
2105 transition_cmp_fn cmp;
2107 static TransitionTable *table = NULL;
2109 table = build_transition_table (simplify_spec_list, SIMPLIFY_COUNT, cmp);