1 /* Table of relaxations for Xtensa assembly.
2 Copyright 2003 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. The expansion uses the
27 bound variables from the pattern to specify that specific operands
28 from the pattern should be used in the result.
30 The patterns match a language like:
32 INSN_PATTERN ::= INSN_TEMPL ( '|' PRECOND )*
33 INSN_TEMPL ::= OPCODE ' ' [ OPERAND (',' OPERAND)* ]
35 OPERAND ::= CONSTANT | VARIABLE | SPECIALFN '(' VARIABLE ')'
36 SPECIALFN ::= 'HI24S' | 'F32MINUS' | 'LOW8'
38 PRECOND ::= OPERAND CMPOP OPERAND
41 The replacement language
42 INSN_REPL ::= INSN_LABEL_LIT ( ';' INSN_LABEL_LIT )*
43 INSN_LABEL_LIT ::= INSN_TEMPL
45 | 'LITERAL' num ' ' VARIABLE
47 The operands in a PRECOND must be constants or variables bound by
50 The operands in the INSN_REPL must be constants, variables bound in
51 the associated INSN_PATTERN, special variables that are bound in
52 the INSN_REPL by LABEL or LITERAL definitions, or special value
53 manipulation functions.
55 A simple example of a replacement pattern:
56 {"movi.n %as,%imm", "movi %as,%imm"} would convert the narrow
57 movi.n instruction to the wide movi instruction.
59 A more complex example of a branch around:
60 {"beqz %as,%label", "bnez %as,%LABEL0;j %label;LABEL0"}
61 would convert a branch to a negated branch to the following instruction
62 with a jump to the original label.
64 An Xtensa-specific example that generates a literal:
65 {"movi %at,%imm", "LITERAL0 %imm; l32r %at,%LITERAL0"}
66 will convert a movi instruction to an l32r of a literal
67 literal defined in the literal pool.
69 Even more complex is a conversion of a load with immediate offset
70 to a load of a freshly generated literal, an explicit add and
71 a load with 0 offset. This transformation is only valid, though
72 when the first and second operands are not the same as specified
73 by the "| %at!=%as" precondition clause.
74 {"l32i %at,%as,%imm | %at!=%as",
75 "LITERAL0 %imm; l32r %at,%LITERAL0; add %at,%at,%as; l32i %at,%at,0"}
77 There is special case for loop instructions here, but because we do
78 not currently have the ability to represent the difference of two
79 symbols, the conversion requires special code in the assembler to
80 write the operands of the addi/addmi pair representing the
81 difference of the old and new loop end label. */
84 #include "xtensa-isa.h"
85 #include "xtensa-relax.h"
88 /* Imported from bfd. */
89 extern xtensa_isa xtensa_default_isa;
92 /* The opname_list is a small list of names that we use for opcode and
93 operand variable names to simplify ownership of these commonly used
94 strings. Strings entered in the table can be compared by pointer
97 typedef struct opname_list_struct opname_list;
98 typedef opname_list opname_e;
100 struct opname_list_struct
106 static opname_list *local_opnames = NULL;
109 /* The "opname_map" and its element structure "opname_map_e" are used
110 for binding an operand number to a name or a constant. */
112 typedef struct opname_map_e_struct opname_map_e;
113 typedef struct opname_map_struct opname_map;
115 struct opname_map_e_struct
117 const char *operand_name; /* If null, then use constant_value. */
119 unsigned constant_value;
123 struct opname_map_struct
129 /* The "precond_list" and its element structure "precond_e" represents
130 explicit preconditions comparing operand variables and constants.
131 In the "precond_e" structure, a variable is identified by the name
132 in the "opname" field. If that field is NULL, then the operand
133 is the constant in field "opval". */
135 typedef struct precond_e_struct precond_e;
136 typedef struct precond_list_struct precond_list;
138 struct precond_e_struct
148 struct precond_list_struct
155 /* The insn_templ represents the INSN_TEMPL instruction template. It
156 is an opcode name with a list of operands. These are used for
157 instruction patterns and replacement patterns. */
159 typedef struct insn_templ_struct insn_templ;
160 struct insn_templ_struct
162 const char *opcode_name;
163 opname_map operand_map;
167 /* The insn_pattern represents an INSN_PATTERN instruction pattern.
168 It is an instruction template with preconditions that specify when
169 it actually matches a given instruction. */
171 typedef struct insn_pattern_struct insn_pattern;
172 struct insn_pattern_struct
175 precond_list preconds;
179 /* The "insn_repl" and associated element structure "insn_repl_e"
180 instruction replacement list is a list of
181 instructions/LITERALS/LABELS with constant operands or operands
182 with names bound to the operand names in the associated pattern. */
184 typedef struct insn_repl_e_struct insn_repl_e;
185 struct insn_repl_e_struct
191 typedef struct insn_repl_struct insn_repl;
192 struct insn_repl_struct
199 /* The split_rec is a vector of allocated char * pointers. */
201 typedef struct split_rec_struct split_rec;
202 struct split_rec_struct
208 /* The "string_pattern_pair" is a set of pairs containing instruction
209 patterns and replacement strings. */
211 typedef struct string_pattern_pair_struct string_pattern_pair;
212 struct string_pattern_pair_struct
215 const char *replacement;
219 /* The widen_spec_list is a list of valid substitutions that generate
220 wider representations. These are generally used to specify
221 replacements for instructions whose immediates do not fit their
222 encodings. A valid transition may require multiple steps of
223 one-to-one instruction replacements with a final multiple
224 instruction replacement. As an example, here are the transitions
225 required to replace an 'addi.n' with an 'addi', 'addmi'.
230 => addmi a4, 0x1000, addi a4, 0x10. */
232 static string_pattern_pair widen_spec_list[] =
234 {"add.n %ar,%as,%at", "add %ar,%as,%at"},
235 {"addi.n %ar,%as,%imm", "addi %ar,%as,%imm"},
236 {"beqz.n %as,%label", "beqz %as,%label"},
237 {"bnez.n %as,%label", "bnez %as,%label"},
238 {"l32i.n %at,%as,%imm", "l32i %at,%as,%imm"},
239 {"mov.n %at,%as", "or %at,%as,%as"},
240 {"movi.n %as,%imm", "movi %as,%imm"},
241 {"nop.n", "or 1,1,1"},
244 {"s32i.n %at,%as,%imm", "s32i %at,%as,%imm"},
245 {"srli %at,%as,%imm", "extui %at,%as,%imm,F32MINUS(%imm)"},
246 {"slli %ar,%as,0", "or %ar,%as,%as"},
247 /* Widening with literals */
248 {"movi %at,%imm", "LITERAL0 %imm; l32r %at,%LITERAL0"},
249 {"addi %ar,%as,%imm", "addmi %ar,%as,%imm"},
250 /* LOW8 is the low 8 bits of the Immed
251 MID8S is the middle 8 bits of the Immed */
252 {"addmi %ar,%as,%imm", "addmi %ar,%as,HI24S(%imm); addi %ar,%ar,LOW8(%imm)"},
253 {"addmi %ar,%as,%imm | %ar!=%as",
254 "LITERAL0 %imm; l32r %ar,%LITERAL0; add %ar,%as,%ar"},
256 /* Widening the load instructions with too-large immediates */
257 {"l8ui %at,%as,%imm | %at!=%as",
258 "LITERAL0 %imm; l32r %at,%LITERAL0; add %at,%at,%as; l8ui %at,%at,0"},
259 {"l16si %at,%as,%imm | %at!=%as",
260 "LITERAL0 %imm; l32r %at,%LITERAL0; add %at,%at,%as; l16si %at,%at,0"},
261 {"l16ui %at,%as,%imm | %at!=%as",
262 "LITERAL0 %imm; l32r %at,%LITERAL0; add %at,%at,%as; l16ui %at,%at,0"},
263 #if 0 /* Xtensa Synchronization Option not yet available */
264 {"l32ai %at,%as,%imm",
265 "LITERAL0 %imm; l32r %at,%LITERAL0; add.n %at,%at,%as; l32ai %at,%at,0"},
267 #if 0 /* Xtensa Speculation Option not yet available */
268 {"l32is %at,%as,%imm",
269 "LITERAL0 %imm; l32r %at,%LITERAL0; add.n %at,%at,%as; l32is %at,%at,0"},
271 {"l32i %at,%as,%imm | %at!=%as",
272 "LITERAL0 %imm; l32r %at,%LITERAL0; add %at,%at,%as; l32i %at,%at,0"},
274 /* This is only PART of the loop instruction. In addition, hard
275 coded into it's use is a modification of the final operand in the
276 instruction in bytes 9 and 12. */
279 "rsr %as, 1;" /* LEND */
280 "wsr %as, 0;" /* LBEG */
281 "addi %as, %as, 0;" /* lo8(%label-%LABEL1) */
282 "addmi %as, %as, 0;" /* mid8(%label-%LABEL1) */
285 "rsr %as, 2;" /* LCOUNT */
286 "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */
288 {"loopgtz %as,%label",
291 "loopgtz %as,%LABEL0;"
292 "rsr %as, 1;" /* LEND */
293 "wsr %as, 0;" /* LBEG */
294 "addi %as, %as, 0;" /* lo8(%label-%LABEL1) */
295 "addmi %as, %as, 0;" /* mid8(%label-%LABEL1) */
298 "rsr %as, 2;" /* LCOUNT */
299 "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */
301 {"loopnez %as,%label",
303 "loopnez %as,%LABEL0;"
304 "rsr %as, 1;" /* LEND */
305 "wsr %as, 0;" /* LBEG */
306 "addi %as, %as, 0;" /* lo8(%label-%LABEL1) */
307 "addmi %as, %as, 0;" /* mid8(%label-%LABEL1) */
310 "rsr %as, 2;" /* LCOUNT */
311 "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */
314 #if 0 /* no mechanism here to determine if Density Option is available */
315 {"beqz %as,%label", "bnez.n %as,%LABEL0;j %label;LABEL0"},
316 {"bnez %as,%label", "beqz.n %as,%LABEL0;j %label;LABEL0"},
318 {"beqz %as,%label", "bnez %as,%LABEL0;j %label;LABEL0"},
319 {"bnez %as,%label", "beqz %as,%LABEL0;j %label;LABEL0"},
322 {"bgez %as,%label", "bltz %as,%LABEL0;j %label;LABEL0"},
323 {"bltz %as,%label", "bgez %as,%LABEL0;j %label;LABEL0"},
324 {"beqi %as,%imm,%label", "bnei %as,%imm,%LABEL0;j %label;LABEL0"},
325 {"bnei %as,%imm,%label", "beqi %as,%imm,%LABEL0;j %label;LABEL0"},
326 {"bgei %as,%imm,%label", "blti %as,%imm,%LABEL0;j %label;LABEL0"},
327 {"blti %as,%imm,%label", "bgei %as,%imm,%LABEL0;j %label;LABEL0"},
328 {"bgeui %as,%imm,%label", "bltui %as,%imm,%LABEL0;j %label;LABEL0"},
329 {"bltui %as,%imm,%label", "bgeui %as,%imm,%LABEL0;j %label;LABEL0"},
330 {"bbci %as,%imm,%label", "bbsi %as,%imm,%LABEL0;j %label;LABEL0"},
331 {"bbsi %as,%imm,%label", "bbci %as,%imm,%LABEL0;j %label;LABEL0"},
332 {"beq %as,%at,%label", "bne %as,%at,%LABEL0;j %label;LABEL0"},
333 {"bne %as,%at,%label", "beq %as,%at,%LABEL0;j %label;LABEL0"},
334 {"bge %as,%at,%label", "blt %as,%at,%LABEL0;j %label;LABEL0"},
335 {"blt %as,%at,%label", "bge %as,%at,%LABEL0;j %label;LABEL0"},
336 {"bgeu %as,%at,%label", "bltu %as,%at,%LABEL0;j %label;LABEL0"},
337 {"bltu %as,%at,%label", "bgeu %as,%at,%LABEL0;j %label;LABEL0"},
338 {"bany %as,%at,%label", "bnone %as,%at,%LABEL0;j %label;LABEL0"},
339 #if 1 /* provide relaxations for Boolean Option */
340 {"bt %bs,%label", "bf %bs,%LABEL0;j %label;LABEL0"},
341 {"bf %bs,%label", "bt %bs,%LABEL0;j %label;LABEL0"},
343 {"bnone %as,%at,%label", "bany %as,%at,%LABEL0;j %label;LABEL0"},
344 {"ball %as,%at,%label", "bnall %as,%at,%LABEL0;j %label;LABEL0"},
345 {"bnall %as,%at,%label", "ball %as,%at,%LABEL0;j %label;LABEL0"},
346 {"bbc %as,%at,%label", "bbs %as,%at,%LABEL0;j %label;LABEL0"},
347 {"bbs %as,%at,%label", "bbc %as,%at,%LABEL0;j %label;LABEL0"},
348 {"call0 %label", "LITERAL0 %label; l32r a0,%LITERAL0; callx0 a0"},
349 {"call4 %label", "LITERAL0 %label; l32r a4,%LITERAL0; callx4 a4"},
350 {"call8 %label", "LITERAL0 %label; l32r a8,%LITERAL0; callx8 a8"},
351 {"call12 %label", "LITERAL0 %label; l32r a12,%LITERAL0; callx12 a12"}
354 #define WIDEN_COUNT (sizeof (widen_spec_list) / sizeof (string_pattern_pair))
357 /* The simplify_spec_list specifies simplifying transformations that
358 will reduce the instruction width or otherwise simplify an
359 instruction. These are usually applied before relaxation in the
360 assembler. It is always legal to simplify. Even for "addi as, 0",
361 the "addi.n as, 0" will eventually be widened back to an "addi 0"
362 after the widening table is applied. Note: The usage of this table
363 has changed somewhat so that it is entirely specific to "narrowing"
364 instructions to use the density option. This table is not used at
365 all when the density option is not available. */
367 string_pattern_pair simplify_spec_list[] =
369 {"add %ar,%as,%at", "add.n %ar,%as,%at"},
370 {"addi.n %ar,%as,0", "mov.n %ar,%as"},
371 {"addi %ar,%as,0", "mov.n %ar,%as"},
372 {"addi %ar,%as,%imm", "addi.n %ar,%as,%imm"},
373 {"addmi %ar,%as,%imm", "addi.n %ar,%as,%imm"},
374 {"beqz %as,%label", "beqz.n %as,%label"},
375 {"bnez %as,%label", "bnez.n %as,%label"},
376 {"l32i %at,%as,%imm", "l32i.n %at,%as,%imm"},
377 {"movi %as,%imm", "movi.n %as,%imm"},
378 {"or %ar,%as,%at | %as==%at", "mov.n %ar,%as"},
381 {"s32i %at,%as,%imm", "s32i.n %at,%as,%imm"},
382 {"slli %ar,%as,0", "mov.n %ar,%as"}
385 #define SIMPLIFY_COUNT \
386 (sizeof (simplify_spec_list) / sizeof (string_pattern_pair))
389 /* Transition generation helpers. */
391 static void append_transition
392 PARAMS ((TransitionTable *, xtensa_opcode, TransitionRule *));
393 static void append_condition
394 PARAMS ((TransitionRule *, Precondition *));
395 static void append_value_condition
396 PARAMS ((TransitionRule *, CmpOp, unsigned, unsigned));
397 static void append_constant_value_condition
398 PARAMS ((TransitionRule *, CmpOp, unsigned, unsigned));
399 static void append_build_insn
400 PARAMS ((TransitionRule *, BuildInstr *));
401 static void append_op
402 PARAMS ((BuildInstr *, BuildOp *));
403 static void append_literal_op
404 PARAMS ((BuildInstr *, unsigned, unsigned));
405 static void append_label_op
406 PARAMS ((BuildInstr *, unsigned, unsigned));
407 static void append_constant_op
408 PARAMS ((BuildInstr *, unsigned, unsigned));
409 static void append_field_op
410 PARAMS ((BuildInstr *, unsigned, unsigned));
411 static void append_user_fn_field_op
412 PARAMS ((BuildInstr *, unsigned, OpType, unsigned));
413 static long operand_function_HI24S
415 static long operand_function_F32MINUS
417 static long operand_function_LOW8
420 /* Externally visible functions. */
422 extern bfd_boolean xg_has_userdef_op_fn
424 extern long xg_apply_userdef_op_fn
425 PARAMS ((OpType, long));
427 /* Parsing helpers. */
429 static const char *enter_opname_n
430 PARAMS ((const char *, size_t));
431 static const char *enter_opname
432 PARAMS ((const char *));
434 /* Construction and destruction. */
436 static void init_opname_map
437 PARAMS ((opname_map *));
438 static void clear_opname_map
439 PARAMS ((opname_map *));
440 static void init_precond_list
441 PARAMS ((precond_list *));
442 static void clear_precond_list
443 PARAMS ((precond_list *));
444 static void init_insn_templ
445 PARAMS ((insn_templ *));
446 static void clear_insn_templ
447 PARAMS ((insn_templ *));
448 static void init_insn_pattern
449 PARAMS ((insn_pattern *));
450 static void clear_insn_pattern
451 PARAMS ((insn_pattern *));
452 static void init_insn_repl
453 PARAMS ((insn_repl *));
454 static void clear_insn_repl
455 PARAMS ((insn_repl *));
456 static void init_split_rec
457 PARAMS ((split_rec *));
458 static void clear_split_rec
459 PARAMS ((split_rec *));
461 /* Operand and insn_templ helpers. */
463 static bfd_boolean same_operand_name
464 PARAMS ((const opname_map_e *, const opname_map_e *));
465 static opname_map_e *get_opmatch
466 PARAMS ((opname_map *, const char *));
467 static bfd_boolean op_is_constant
468 PARAMS ((const opname_map_e *));
469 static unsigned op_get_constant
470 PARAMS ((const opname_map_e *));
471 static size_t insn_templ_operand_count
472 PARAMS ((const insn_templ *));
474 /* parsing helpers. */
476 static const char *skip_white
477 PARAMS ((const char *));
478 static void trim_whitespace
480 static void split_string
481 PARAMS ((split_rec *, const char *, char, bfd_boolean));
483 /* Language parsing. */
485 static bfd_boolean parse_insn_pattern
486 PARAMS ((const char *, insn_pattern *));
487 static bfd_boolean parse_insn_repl
488 PARAMS ((const char *, insn_repl *));
489 static bfd_boolean parse_insn_templ
490 PARAMS ((const char *, insn_templ *));
491 static bfd_boolean parse_special_fn
492 PARAMS ((const char *, const char **, const char **));
493 static bfd_boolean parse_precond
494 PARAMS ((const char *, precond_e *));
495 static bfd_boolean parse_constant
496 PARAMS ((const char *, unsigned *));
497 static bfd_boolean parse_id_constant
498 PARAMS ((const char *, const char *, unsigned *));
500 /* Transition table building code. */
502 static TransitionRule *build_transition
503 PARAMS ((insn_pattern *, insn_repl *, const char *, const char *));
504 static TransitionTable *build_transition_table
505 PARAMS ((const string_pattern_pair *, size_t));
509 append_transition (tt, opcode, t)
511 xtensa_opcode opcode;
514 TransitionList *tl = (TransitionList *) xmalloc (sizeof (TransitionList));
515 TransitionList *prev;
518 assert (opcode < tt->num_opcodes);
520 prev = tt->table[opcode];
525 tt->table[opcode] = tl;
540 append_condition (tr, cond)
544 PreconditionList *pl =
545 (PreconditionList *) xmalloc (sizeof (PreconditionList));
546 PreconditionList *prev = tr->conditions;
547 PreconditionList *nxt;
567 append_value_condition (tr, cmp, op1, op2)
573 Precondition *cond = (Precondition *) xmalloc (sizeof (Precondition));
577 cond->typ = OP_OPERAND;
579 append_condition (tr, cond);
584 append_constant_value_condition (tr, cmp, op1, cnst)
590 Precondition *cond = (Precondition *) xmalloc (sizeof (Precondition));
594 cond->typ = OP_CONSTANT;
595 cond->op_data = cnst;
596 append_condition (tr, cond);
601 append_build_insn (tr, bi)
605 BuildInstr *prev = tr->to_instr;
629 BuildOp *prev = bi->ops;
648 append_literal_op (bi, op1, litnum)
653 BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
656 b_op->typ = OP_LITERAL;
657 b_op->op_data = litnum;
659 append_op (bi, b_op);
664 append_label_op (bi, op1, labnum)
669 BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
672 b_op->typ = OP_LABEL;
673 b_op->op_data = labnum;
675 append_op (bi, b_op);
680 append_constant_op (bi, op1, cnst)
685 BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
688 b_op->typ = OP_CONSTANT;
689 b_op->op_data = cnst;
691 append_op (bi, b_op);
696 append_field_op (bi, op1, src_op)
701 BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
704 b_op->typ = OP_OPERAND;
705 b_op->op_data = src_op;
707 append_op (bi, b_op);
711 /* These could be generated but are not currently. */
714 append_user_fn_field_op (bi, op1, typ, src_op)
720 BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
724 b_op->op_data = src_op;
726 append_op (bi, b_op);
730 /* These operand functions are the semantics of user-defined
731 operand functions. */
734 operand_function_HI24S (a)
738 return (a & (~0xff)) + 0x100;
740 return (a & (~0xff));
745 operand_function_F32MINUS (a)
753 operand_function_LOW8 (a)
757 return (a & 0xff) | ~0xff;
764 xg_has_userdef_op_fn (op)
769 case OP_OPERAND_F32MINUS:
770 case OP_OPERAND_LOW8:
771 case OP_OPERAND_HI24S:
781 xg_apply_userdef_op_fn (op, a)
787 case OP_OPERAND_F32MINUS:
788 return operand_function_F32MINUS (a);
789 case OP_OPERAND_LOW8:
790 return operand_function_LOW8 (a);
791 case OP_OPERAND_HI24S:
792 return operand_function_HI24S (a);
800 /* Generate a transition table. */
803 enter_opname_n (name, len)
809 for (op = local_opnames; op != NULL; op = op->next)
811 if (strlen (op->opname) == len && strncmp (op->opname, name, len) == 0)
814 op = (opname_e *) xmalloc (sizeof (opname_e));
815 op->opname = (char *) xmalloc (len + 1);
816 strncpy (op->opname, name, len);
817 op->opname[len] = '\0';
828 for (op = local_opnames; op != NULL; op = op->next)
830 if (strcmp (op->opname, name) == 0)
833 op = (opname_e *) xmalloc (sizeof (opname_e));
834 op->opname = strdup (name);
854 while (m->head != NULL)
865 same_operand_name (m1, m2)
866 const opname_map_e *m1;
867 const opname_map_e *m2;
869 if (m1->operand_name == NULL || m1->operand_name == NULL)
871 return (m1->operand_name == m2->operand_name);
876 get_opmatch (map, operand_name)
878 const char *operand_name;
882 for (m = map->head; m != NULL; m = m->next)
884 if (strcmp (m->operand_name, operand_name) == 0)
893 const opname_map_e *m1;
895 return (m1->operand_name == NULL);
901 const opname_map_e *m1;
903 assert (m1->operand_name == NULL);
904 return m1->constant_value;
909 init_precond_list (l)
918 clear_precond_list (l)
923 while (l->head != NULL)
937 t->opcode_name = NULL;
938 init_opname_map (&t->operand_map);
946 clear_opname_map (&t->operand_map);
951 init_insn_pattern (p)
954 init_insn_templ (&p->t);
955 init_precond_list (&p->preconds);
960 clear_insn_pattern (p)
963 clear_insn_templ (&p->t);
964 clear_precond_list (&p->preconds);
983 while (r->head != NULL)
987 clear_insn_templ (&e->t);
994 insn_templ_operand_count (t)
998 const opname_map_e *op;
1000 for (op = t->operand_map.head; op != NULL; op = op->next, ++i)
1006 /* Convert a string to a number. E.G.: parse_constant("10", &num) */
1009 parse_constant (in, val_p)
1022 if (*p >= '0' && *p <= '9')
1023 val = val * 10 + (*p - '0');
1033 /* Match a pattern like "foo1" with
1034 parse_id_constant("foo1", "foo", &num).
1035 This may also be used to just match a number. */
1038 parse_id_constant (in, name, val_p)
1043 unsigned namelen = 0;
1050 namelen = strlen (name);
1052 if (name != NULL && strncmp (in, name, namelen) != 0)
1056 return parse_constant (p, val_p);
1061 parse_special_fn (name, fn_name_p, arg_name_p)
1063 const char **fn_name_p;
1064 const char **arg_name_p;
1069 p_start = strchr (name, '(');
1070 if (p_start == NULL)
1073 p_end = strchr (p_start, ')');
1078 if (p_end[1] != '\0')
1081 *fn_name_p = enter_opname_n (name, p_start - name);
1082 *arg_name_p = enter_opname_n (p_start + 1, p_end - p_start - 1);
1100 trim_whitespace (in)
1103 char *last_white = NULL;
1106 while (p && *p != '\0')
1110 if (last_white == NULL)
1125 /* Split a string into component strings where "c" is the
1126 delimiter. Place the result in the split_rec. */
1129 split_string (rec, in, c, elide_whitespace)
1133 bfd_boolean elide_whitespace;
1139 while (p != NULL && *p != '\0')
1149 if (rec->count == 0)
1152 rec->vec = (char **) xmalloc (sizeof (char *) * cnt);
1153 for (i = 0; i < cnt; i++)
1157 for (i = 0; i < cnt; i++)
1163 if (elide_whitespace)
1168 rec->vec[i] = strdup (q);
1172 rec->vec[i] = (char *) xmalloc (sizeof (char) * (len + 1));
1173 strncpy (rec->vec[i], q, len);
1174 rec->vec[i][len] = '\0';
1178 if (elide_whitespace)
1179 trim_whitespace (rec->vec[i]);
1185 clear_split_rec (rec)
1190 for (i = 0; i < rec->count; ++i)
1199 init_split_rec (rec)
1207 /* Parse an instruction template like "insn op1, op2, op3". */
1210 parse_insn_templ (s, t)
1215 /* First find the first whitespace. */
1216 size_t insn_name_len;
1220 init_split_rec (&oprec);
1223 insn_name_len = strcspn (s, " ");
1224 if (insn_name_len == 0)
1227 init_insn_templ (t);
1228 t->opcode_name = enter_opname_n (p, insn_name_len);
1230 p = p + insn_name_len;
1232 /* Split by ',' and skip beginning and trailing whitespace. */
1233 split_string (&oprec, p, ',', TRUE);
1235 for (i = 0; i < oprec.count; i++)
1237 const char *opname = oprec.vec[i];
1238 opname_map_e *e = (opname_map_e *) xmalloc (sizeof (opname_map_e));
1240 e->operand_name = NULL;
1241 e->constant_value = 0;
1244 /* If it begins with a number, assume that it is a number. */
1245 if (opname && opname[0] >= '0' && opname[0] <= '9')
1249 if (parse_constant (opname, &val))
1250 e->constant_value = val;
1254 clear_split_rec (&oprec);
1255 clear_insn_templ (t);
1260 e->operand_name = enter_opname (oprec.vec[i]);
1262 *t->operand_map.tail = e;
1263 t->operand_map.tail = &e->next;
1265 clear_split_rec (&oprec);
1271 parse_precond (s, precond)
1275 /* All preconditions are currently of the form:
1276 a == b or a != b or a == k (where k is a constant).
1277 Later we may use some special functions like DENSITY == 1
1278 to identify when density is available. */
1282 precond->opname1 = NULL;
1283 precond->opval1 = 0;
1284 precond->cmpop = OP_EQUAL;
1285 precond->opname2 = NULL;
1286 precond->opval2 = 0;
1287 precond->next = NULL;
1291 len = strcspn (p, " !=");
1296 precond->opname1 = enter_opname_n (p, len);
1300 /* Check for "==" and "!=". */
1301 if (strncmp (p, "==", 2) == 0)
1302 precond->cmpop = OP_EQUAL;
1303 else if (strncmp (p, "!=", 2) == 0)
1304 precond->cmpop = OP_NOTEQUAL;
1311 /* No trailing whitespace from earlier parsing. */
1312 if (p[0] >= '0' && p[0] <= '9')
1315 if (parse_constant (p, &val))
1316 precond->opval2 = val;
1321 precond->opname2 = enter_opname (p);
1326 /* Parse a string like:
1327 "insn op1, op2, op3, op4 | op1 != op2 | op2 == op3 | op4 == 1".
1328 I.E., instruction "insn" with 4 operands where operand 1 and 2 are not
1329 the same and operand 2 and 3 are the same and operand 4 is 1. */
1332 parse_insn_pattern (in, insn)
1340 init_split_rec (&rec);
1341 init_insn_pattern (insn);
1343 split_string (&rec, in, '|', TRUE);
1347 clear_split_rec (&rec);
1351 if (!parse_insn_templ (rec.vec[0], &insn->t))
1353 clear_split_rec (&rec);
1357 for (i = 1; i < rec.count; i++)
1359 precond_e *cond = (precond_e *) xmalloc (sizeof (precond_e));
1361 if (!parse_precond (rec.vec[i], cond))
1363 clear_split_rec (&rec);
1364 clear_insn_pattern (insn);
1368 /* Append the condition. */
1369 *insn->preconds.tail = cond;
1370 insn->preconds.tail = &cond->next;
1373 clear_split_rec (&rec);
1379 parse_insn_repl (in, r_p)
1383 /* This is a list of instruction templates separated by ';'. */
1387 split_string (&rec, in, ';', TRUE);
1389 for (i = 0; i < rec.count; i++)
1391 insn_repl_e *e = (insn_repl_e *) xmalloc (sizeof (insn_repl_e));
1395 if (!parse_insn_templ (rec.vec[i], &e->t))
1398 clear_insn_repl (r_p);
1402 r_p->tail = &e->next;
1409 build_transition (initial_insn, replace_insns, from_string, to_string)
1410 insn_pattern *initial_insn;
1411 insn_repl *replace_insns;
1412 const char *from_string;
1413 const char *to_string;
1415 TransitionRule *tr = NULL;
1416 xtensa_opcode opcode;
1417 xtensa_isa isa = xtensa_default_isa;
1424 unsigned label_count = 0;
1425 unsigned max_label_count = 0;
1426 bfd_boolean has_label = FALSE;
1427 unsigned literal_count = 0;
1429 opcode = xtensa_opcode_lookup (isa, initial_insn->t.opcode_name);
1430 if (opcode == XTENSA_UNDEFINED)
1432 /* It is OK to not be able to translate some of these opcodes. */
1434 as_warn (_("Invalid opcode '%s' in transition rule '%s'\n"),
1435 initial_insn->t.opcode_name, to_string);
1441 if (xtensa_num_operands (isa, opcode)
1442 != (int) insn_templ_operand_count (&initial_insn->t))
1444 /* This is also OK because there are opcodes that
1445 have different numbers of operands on different
1446 architecture variations. */
1448 as_fatal (_("opcode %s mismatched operand count %d != expected %d"),
1449 xtensa_opcode_name (isa, opcode),
1450 xtensa_num_operands (isa, opcode),
1451 insn_templ_operand_count (&initial_insn->t));
1456 tr = (TransitionRule *) xmalloc (sizeof (TransitionRule));
1457 tr->opcode = opcode;
1458 tr->conditions = NULL;
1459 tr->to_instr = NULL;
1461 /* Build the conditions. First, equivalent operand condition.... */
1462 for (op1 = initial_insn->t.operand_map.head; op1 != NULL; op1 = op1->next)
1464 for (op2 = op1->next; op2 != NULL; op2 = op2->next)
1466 if (same_operand_name (op1, op2))
1468 append_value_condition (tr, OP_EQUAL,
1469 op1->operand_num, op2->operand_num);
1474 /* Now the condition that an operand value must be a constant.... */
1475 for (op1 = initial_insn->t.operand_map.head; op1 != NULL; op1 = op1->next)
1477 if (op_is_constant (op1))
1479 append_constant_value_condition (tr,
1482 op_get_constant (op1));
1487 /* Now add the explicit preconditions listed after the "|" in the spec.
1488 These are currently very limited, so we do a special case
1489 parse for them. We expect spaces, opname != opname. */
1490 for (precond = initial_insn->preconds.head;
1492 precond = precond->next)
1497 if (precond->opname1)
1499 op1 = get_opmatch (&initial_insn->t.operand_map, precond->opname1);
1502 as_fatal (_("opcode '%s': no bound opname '%s' "
1503 "for precondition in '%s'"),
1504 xtensa_opcode_name (isa, opcode),
1505 precond->opname1, from_string);
1510 if (precond->opname2)
1512 op2 = get_opmatch (&initial_insn->t.operand_map, precond->opname2);
1515 as_fatal (_("opcode '%s': no bound opname '%s' "
1516 "for precondition in %s"),
1517 xtensa_opcode_name (isa, opcode),
1518 precond->opname2, from_string);
1523 if (op1 == NULL && op2 == NULL)
1525 as_fatal (_("opcode '%s': precondition only contains "
1526 "constants in '%s'"),
1527 xtensa_opcode_name (isa, opcode), from_string);
1530 else if (op1 != NULL && op2 != NULL)
1531 append_value_condition (tr, precond->cmpop,
1532 op1->operand_num, op2->operand_num);
1533 else if (op2 == NULL)
1534 append_constant_value_condition (tr, precond->cmpop,
1535 op1->operand_num, precond->opval1);
1537 append_constant_value_condition (tr, precond->cmpop,
1538 op2->operand_num, precond->opval2);
1541 /* Generate the replacement instructions. Some of these
1542 "instructions" are actually labels and literals. The literals
1543 must be defined in order 0..n and a literal must be defined
1544 (e.g., "LITERAL0 %imm") before use (e.g., "%LITERAL0"). The
1545 labels must be defined in order, but they can be used before they
1546 are defined. Also there are a number of special operands (e.g.,
1549 for (r = replace_insns->head; r != NULL; r = r->next)
1552 const char *opcode_name;
1553 size_t operand_count;
1556 const char *fn_name;
1557 const char *operand_arg_name;
1559 bi = (BuildInstr *) xmalloc (sizeof (BuildInstr));
1560 append_build_insn (tr, bi);
1563 bi->opcode = XTENSA_UNDEFINED;
1567 opcode_name = r->t.opcode_name;
1568 operand_count = insn_templ_operand_count (&r->t);
1570 if (parse_id_constant (opcode_name, "LITERAL", &idnum))
1572 bi->typ = INSTR_LITERAL_DEF;
1574 if (idnum != literal_count)
1575 as_fatal (_("generated literals must be numbered consecutively"));
1577 if (operand_count != 1)
1578 as_fatal (_("expected one operand for generated literal"));
1581 else if (parse_id_constant (opcode_name, "LABEL", &idnum))
1583 bi->typ = INSTR_LABEL_DEF;
1585 if (idnum != label_count)
1586 as_fatal (_("generated labels must be numbered consecutively"));
1588 if (operand_count != 0)
1589 as_fatal (_("expected 0 operands for generated label"));
1593 bi->typ = INSTR_INSTR;
1594 bi->opcode = xtensa_opcode_lookup (isa, r->t.opcode_name);
1595 if (bi->opcode == XTENSA_UNDEFINED)
1597 /* Check for the right number of ops. */
1598 if (xtensa_num_operands (isa, bi->opcode)
1599 != (int) operand_count)
1600 as_fatal (_("opcode '%s': replacement does not have %d ops"),
1601 opcode_name, xtensa_num_operands (isa, bi->opcode));
1604 for (op = r->t.operand_map.head; op != NULL; op = op->next)
1608 if (op_is_constant (op))
1609 append_constant_op (bi, op->operand_num, op_get_constant (op));
1610 else if (parse_id_constant (op->operand_name, "%LITERAL", &idnum))
1612 if (idnum >= literal_count)
1613 as_fatal (_("opcode %s: replacement "
1614 "literal %d >= literal_count(%d)"),
1615 opcode_name, idnum, literal_count);
1616 append_literal_op (bi, op->operand_num, idnum);
1618 else if (parse_id_constant (op->operand_name, "%LABEL", &idnum))
1621 if (idnum > max_label_count)
1622 max_label_count = idnum;
1623 append_label_op (bi, op->operand_num, idnum);
1625 else if (parse_id_constant (op->operand_name, "a", &idnum))
1626 append_constant_op (bi, op->operand_num, idnum);
1627 else if (op->operand_name[0] == '%')
1629 opname_map_e *orig_op;
1630 orig_op = get_opmatch (&initial_insn->t.operand_map,
1632 if (orig_op == NULL)
1634 as_fatal (_("opcode %s: unidentified operand '%s' in '%s'"),
1635 opcode_name, op->operand_name, to_string);
1637 append_constant_op (bi, op->operand_num, 0);
1640 append_field_op (bi, op->operand_num, orig_op->operand_num);
1642 else if (parse_special_fn (op->operand_name,
1643 &fn_name, &operand_arg_name))
1645 opname_map_e *orig_op;
1646 OpType typ = OP_CONSTANT;
1648 if (strcmp (fn_name, "LOW8") == 0)
1649 typ = OP_OPERAND_LOW8;
1650 else if (strcmp (fn_name, "HI24S") == 0)
1651 typ = OP_OPERAND_HI24S;
1652 else if (strcmp (fn_name, "F32MINUS") == 0)
1653 typ = OP_OPERAND_F32MINUS;
1655 as_fatal (_("unknown user defined function %s"), fn_name);
1657 orig_op = get_opmatch (&initial_insn->t.operand_map,
1659 if (orig_op == NULL)
1661 as_fatal (_("opcode %s: unidentified operand '%s' in '%s'"),
1662 opcode_name, op->operand_name, to_string);
1663 append_constant_op (bi, op->operand_num, 0);
1666 append_user_fn_field_op (bi, op->operand_num,
1667 typ, orig_op->operand_num);
1671 as_fatal (_("opcode %s: could not parse operand '%s' in '%s'"),
1672 opcode_name, op->operand_name, to_string);
1673 append_constant_op (bi, op->operand_num, 0);
1677 if (has_label && max_label_count >= label_count)
1679 as_fatal (_("opcode %s: replacement label %d >= label_count(%d)"),
1680 xtensa_opcode_name (isa, opcode),
1681 max_label_count, label_count);
1690 build_transition_table (transitions, transition_count)
1691 const string_pattern_pair *transitions;
1692 size_t transition_count;
1694 TransitionTable *table = NULL;
1695 int num_opcodes = xtensa_num_opcodes (xtensa_default_isa);
1702 /* Otherwise, build it now. */
1703 table = (TransitionTable *) xmalloc (sizeof (TransitionTable));
1704 table->num_opcodes = num_opcodes;
1706 (TransitionList **) xmalloc (sizeof (TransitionTable *) * num_opcodes);
1708 for (i = 0; i < num_opcodes; i++)
1709 table->table[i] = NULL;
1711 for (tnum = 0; tnum < transition_count; tnum++)
1713 const char *from_string = transitions[tnum].pattern;
1714 const char *to_string = transitions[tnum].replacement;
1716 insn_pattern initial_insn;
1717 insn_repl replace_insns;
1720 init_insn_pattern (&initial_insn);
1721 if (!parse_insn_pattern (from_string, &initial_insn))
1723 as_fatal (_("could not parse INSN_PATTERN '%s'"), from_string);
1724 clear_insn_pattern (&initial_insn);
1728 init_insn_repl (&replace_insns);
1729 if (!parse_insn_repl (to_string, &replace_insns))
1731 as_fatal (_("could not parse INSN_REPL '%s'"), to_string);
1732 clear_insn_pattern (&initial_insn);
1733 clear_insn_repl (&replace_insns);
1737 tr = build_transition (&initial_insn, &replace_insns,
1738 from_string, to_string);
1740 append_transition (table, tr->opcode, tr);
1742 clear_insn_repl (&replace_insns);
1743 clear_insn_pattern (&initial_insn);
1749 extern TransitionTable *
1750 xg_build_widen_table ()
1752 static TransitionTable *table = NULL;
1754 table = build_transition_table (widen_spec_list, WIDEN_COUNT);
1759 extern TransitionTable *
1760 xg_build_simplify_table ()
1762 static TransitionTable *table = NULL;
1764 table = build_transition_table (simplify_spec_list, SIMPLIFY_COUNT);