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
;
539 append_condition (tr
, cond
)
543 PreconditionList
*pl
=
544 (PreconditionList
*) xmalloc (sizeof (PreconditionList
));
545 PreconditionList
*prev
= tr
->conditions
;
546 PreconditionList
*nxt
;
566 append_value_condition (tr
, cmp
, op1
, op2
)
572 Precondition
*cond
= (Precondition
*) xmalloc (sizeof (Precondition
));
576 cond
->typ
= OP_OPERAND
;
578 append_condition (tr
, cond
);
583 append_constant_value_condition (tr
, cmp
, op1
, cnst
)
589 Precondition
*cond
= (Precondition
*) xmalloc (sizeof (Precondition
));
593 cond
->typ
= OP_CONSTANT
;
594 cond
->op_data
= cnst
;
595 append_condition (tr
, cond
);
600 append_build_insn (tr
, bi
)
604 BuildInstr
*prev
= tr
->to_instr
;
628 BuildOp
*prev
= bi
->ops
;
647 append_literal_op (bi
, op1
, litnum
)
652 BuildOp
*b_op
= (BuildOp
*) xmalloc (sizeof (BuildOp
));
655 b_op
->typ
= OP_LITERAL
;
656 b_op
->op_data
= litnum
;
658 append_op (bi
, b_op
);
663 append_label_op (bi
, op1
, labnum
)
668 BuildOp
*b_op
= (BuildOp
*) xmalloc (sizeof (BuildOp
));
671 b_op
->typ
= OP_LABEL
;
672 b_op
->op_data
= labnum
;
674 append_op (bi
, b_op
);
679 append_constant_op (bi
, op1
, 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 (bi
, op1
, src_op
)
700 BuildOp
*b_op
= (BuildOp
*) xmalloc (sizeof (BuildOp
));
703 b_op
->typ
= OP_OPERAND
;
704 b_op
->op_data
= src_op
;
706 append_op (bi
, b_op
);
710 /* These could be generated but are not currently. */
713 append_user_fn_field_op (bi
, op1
, typ
, src_op
)
719 BuildOp
*b_op
= (BuildOp
*) xmalloc (sizeof (BuildOp
));
723 b_op
->op_data
= src_op
;
725 append_op (bi
, b_op
);
729 /* These operand functions are the semantics of user-defined
730 operand functions. */
733 operand_function_HI24S (a
)
737 return (a
& (~0xff)) + 0x100;
739 return (a
& (~0xff));
744 operand_function_F32MINUS (a
)
752 operand_function_LOW8 (a
)
756 return (a
& 0xff) | ~0xff;
763 xg_has_userdef_op_fn (op
)
768 case OP_OPERAND_F32MINUS
:
769 case OP_OPERAND_LOW8
:
770 case OP_OPERAND_HI24S
:
780 xg_apply_userdef_op_fn (op
, a
)
786 case OP_OPERAND_F32MINUS
:
787 return operand_function_F32MINUS (a
);
788 case OP_OPERAND_LOW8
:
789 return operand_function_LOW8 (a
);
790 case OP_OPERAND_HI24S
:
791 return operand_function_HI24S (a
);
799 /* Generate a transition table. */
802 enter_opname_n (name
, len
)
808 for (op
= local_opnames
; op
!= NULL
; op
= op
->next
)
810 if (strlen (op
->opname
) == len
&& strncmp (op
->opname
, name
, len
) == 0)
813 op
= (opname_e
*) xmalloc (sizeof (opname_e
));
814 op
->opname
= (char *) xmalloc (len
+ 1);
815 strncpy (op
->opname
, name
, len
);
816 op
->opname
[len
] = '\0';
827 for (op
= local_opnames
; op
!= NULL
; op
= op
->next
)
829 if (strcmp (op
->opname
, name
) == 0)
832 op
= (opname_e
*) xmalloc (sizeof (opname_e
));
833 op
->opname
= strdup (name
);
853 while (m
->head
!= NULL
)
864 same_operand_name (m1
, m2
)
865 const opname_map_e
*m1
;
866 const opname_map_e
*m2
;
868 if (m1
->operand_name
== NULL
|| m1
->operand_name
== NULL
)
870 return (m1
->operand_name
== m2
->operand_name
);
875 get_opmatch (map
, operand_name
)
877 const char *operand_name
;
881 for (m
= map
->head
; m
!= NULL
; m
= m
->next
)
883 if (strcmp (m
->operand_name
, operand_name
) == 0)
892 const opname_map_e
*m1
;
894 return (m1
->operand_name
== NULL
);
900 const opname_map_e
*m1
;
902 assert (m1
->operand_name
== NULL
);
903 return m1
->constant_value
;
908 init_precond_list (l
)
917 clear_precond_list (l
)
922 while (l
->head
!= NULL
)
936 t
->opcode_name
= NULL
;
937 init_opname_map (&t
->operand_map
);
945 clear_opname_map (&t
->operand_map
);
950 init_insn_pattern (p
)
953 init_insn_templ (&p
->t
);
954 init_precond_list (&p
->preconds
);
959 clear_insn_pattern (p
)
962 clear_insn_templ (&p
->t
);
963 clear_precond_list (&p
->preconds
);
982 while (r
->head
!= NULL
)
986 clear_insn_templ (&e
->t
);
993 insn_templ_operand_count (t
)
997 const opname_map_e
*op
;
999 for (op
= t
->operand_map
.head
; op
!= NULL
; op
= op
->next
, ++i
)
1005 /* Convert a string to a number. E.G.: parse_constant("10", &num) */
1008 parse_constant (in
, val_p
)
1021 if (*p
>= '0' && *p
<= '9')
1022 val
= val
* 10 + (*p
- '0');
1032 /* Match a pattern like "foo1" with
1033 parse_id_constant("foo1", "foo", &num).
1034 This may also be used to just match a number. */
1037 parse_id_constant (in
, name
, val_p
)
1042 unsigned namelen
= 0;
1049 namelen
= strlen (name
);
1051 if (name
!= NULL
&& strncmp (in
, name
, namelen
) != 0)
1055 return parse_constant (p
, val_p
);
1060 parse_special_fn (name
, fn_name_p
, arg_name_p
)
1062 const char **fn_name_p
;
1063 const char **arg_name_p
;
1068 p_start
= strchr (name
, '(');
1069 if (p_start
== NULL
)
1072 p_end
= strchr (p_start
, ')');
1077 if (p_end
[1] != '\0')
1080 *fn_name_p
= enter_opname_n (name
, p_start
- name
);
1081 *arg_name_p
= enter_opname_n (p_start
+ 1, p_end
- p_start
- 1);
1099 trim_whitespace (in
)
1102 char *last_white
= NULL
;
1105 while (p
&& *p
!= '\0')
1109 if (last_white
== NULL
)
1124 /* Split a string into component strings where "c" is the
1125 delimiter. Place the result in the split_rec. */
1128 split_string (rec
, in
, c
, elide_whitespace
)
1132 bfd_boolean elide_whitespace
;
1138 while (p
!= NULL
&& *p
!= '\0')
1148 if (rec
->count
== 0)
1151 rec
->vec
= (char **) xmalloc (sizeof (char *) * cnt
);
1152 for (i
= 0; i
< cnt
; i
++)
1156 for (i
= 0; i
< cnt
; i
++)
1162 if (elide_whitespace
)
1167 rec
->vec
[i
] = strdup (q
);
1171 rec
->vec
[i
] = (char *) xmalloc (sizeof (char) * (len
+ 1));
1172 strncpy (rec
->vec
[i
], q
, len
);
1173 rec
->vec
[i
][len
] = '\0';
1177 if (elide_whitespace
)
1178 trim_whitespace (rec
->vec
[i
]);
1184 clear_split_rec (rec
)
1189 for (i
= 0; i
< rec
->count
; ++i
)
1198 init_split_rec (rec
)
1206 /* Parse an instruction template like "insn op1, op2, op3". */
1209 parse_insn_templ (s
, t
)
1214 /* First find the first whitespace. */
1215 size_t insn_name_len
;
1219 init_split_rec (&oprec
);
1222 insn_name_len
= strcspn (s
, " ");
1223 if (insn_name_len
== 0)
1226 init_insn_templ (t
);
1227 t
->opcode_name
= enter_opname_n (p
, insn_name_len
);
1229 p
= p
+ insn_name_len
;
1231 /* Split by ',' and skip beginning and trailing whitespace. */
1232 split_string (&oprec
, p
, ',', TRUE
);
1234 for (i
= 0; i
< oprec
.count
; i
++)
1236 const char *opname
= oprec
.vec
[i
];
1237 opname_map_e
*e
= (opname_map_e
*) xmalloc (sizeof (opname_map_e
));
1239 e
->operand_name
= NULL
;
1240 e
->constant_value
= 0;
1243 /* If it begins with a number, assume that it is a number. */
1244 if (opname
&& opname
[0] >= '0' && opname
[0] <= '9')
1248 if (parse_constant (opname
, &val
))
1249 e
->constant_value
= val
;
1253 clear_split_rec (&oprec
);
1254 clear_insn_templ (t
);
1259 e
->operand_name
= enter_opname (oprec
.vec
[i
]);
1261 *t
->operand_map
.tail
= e
;
1262 t
->operand_map
.tail
= &e
->next
;
1264 clear_split_rec (&oprec
);
1270 parse_precond (s
, precond
)
1274 /* All preconditions are currently of the form:
1275 a == b or a != b or a == k (where k is a constant).
1276 Later we may use some special functions like DENSITY == 1
1277 to identify when density is available. */
1281 precond
->opname1
= NULL
;
1282 precond
->opval1
= 0;
1283 precond
->cmpop
= OP_EQUAL
;
1284 precond
->opname2
= NULL
;
1285 precond
->opval2
= 0;
1286 precond
->next
= NULL
;
1290 len
= strcspn (p
, " !=");
1295 precond
->opname1
= enter_opname_n (p
, len
);
1299 /* Check for "==" and "!=". */
1300 if (strncmp (p
, "==", 2) == 0)
1301 precond
->cmpop
= OP_EQUAL
;
1302 else if (strncmp (p
, "!=", 2) == 0)
1303 precond
->cmpop
= OP_NOTEQUAL
;
1310 /* No trailing whitespace from earlier parsing. */
1311 if (p
[0] >= '0' && p
[0] <= '9')
1314 if (parse_constant (p
, &val
))
1315 precond
->opval2
= val
;
1320 precond
->opname2
= enter_opname (p
);
1325 /* Parse a string like:
1326 "insn op1, op2, op3, op4 | op1 != op2 | op2 == op3 | op4 == 1".
1327 I.E., instruction "insn" with 4 operands where operand 1 and 2 are not
1328 the same and operand 2 and 3 are the same and operand 4 is 1. */
1331 parse_insn_pattern (in
, insn
)
1339 init_split_rec (&rec
);
1340 init_insn_pattern (insn
);
1342 split_string (&rec
, in
, '|', TRUE
);
1346 clear_split_rec (&rec
);
1350 if (!parse_insn_templ (rec
.vec
[0], &insn
->t
))
1352 clear_split_rec (&rec
);
1356 for (i
= 1; i
< rec
.count
; i
++)
1358 precond_e
*cond
= (precond_e
*) xmalloc (sizeof (precond_e
));
1360 if (!parse_precond (rec
.vec
[i
], cond
))
1362 clear_split_rec (&rec
);
1363 clear_insn_pattern (insn
);
1367 /* Append the condition. */
1368 *insn
->preconds
.tail
= cond
;
1369 insn
->preconds
.tail
= &cond
->next
;
1372 clear_split_rec (&rec
);
1378 parse_insn_repl (in
, r_p
)
1382 /* This is a list of instruction templates separated by ';'. */
1386 split_string (&rec
, in
, ';', TRUE
);
1388 for (i
= 0; i
< rec
.count
; i
++)
1390 insn_repl_e
*e
= (insn_repl_e
*) xmalloc (sizeof (insn_repl_e
));
1394 if (!parse_insn_templ (rec
.vec
[i
], &e
->t
))
1397 clear_insn_repl (r_p
);
1401 r_p
->tail
= &e
->next
;
1408 build_transition (initial_insn
, replace_insns
, from_string
, to_string
)
1409 insn_pattern
*initial_insn
;
1410 insn_repl
*replace_insns
;
1411 const char *from_string
;
1412 const char *to_string
;
1414 TransitionRule
*tr
= NULL
;
1415 xtensa_opcode opcode
;
1416 xtensa_isa isa
= xtensa_default_isa
;
1423 unsigned label_count
= 0;
1424 unsigned max_label_count
= 0;
1425 bfd_boolean has_label
= FALSE
;
1426 unsigned literal_count
= 0;
1428 opcode
= xtensa_opcode_lookup (isa
, initial_insn
->t
.opcode_name
);
1429 if (opcode
== XTENSA_UNDEFINED
)
1431 /* It is OK to not be able to translate some of these opcodes. */
1433 as_warn (_("Invalid opcode '%s' in transition rule '%s'\n"),
1434 initial_insn
->t
.opcode_name
, to_string
);
1440 if (xtensa_num_operands (isa
, opcode
)
1441 != (int) insn_templ_operand_count (&initial_insn
->t
))
1443 /* This is also OK because there are opcodes that
1444 have different numbers of operands on different
1445 architecture variations. */
1447 as_fatal (_("opcode %s mismatched operand count %d != expected %d"),
1448 xtensa_opcode_name (isa
, opcode
),
1449 xtensa_num_operands (isa
, opcode
),
1450 insn_templ_operand_count (&initial_insn
->t
));
1455 tr
= (TransitionRule
*) xmalloc (sizeof (TransitionRule
));
1456 tr
->opcode
= opcode
;
1457 tr
->conditions
= NULL
;
1458 tr
->to_instr
= NULL
;
1460 /* Build the conditions. First, equivalent operand condition.... */
1461 for (op1
= initial_insn
->t
.operand_map
.head
; op1
!= NULL
; op1
= op1
->next
)
1463 for (op2
= op1
->next
; op2
!= NULL
; op2
= op2
->next
)
1465 if (same_operand_name (op1
, op2
))
1467 append_value_condition (tr
, OP_EQUAL
,
1468 op1
->operand_num
, op2
->operand_num
);
1473 /* Now the condition that an operand value must be a constant.... */
1474 for (op1
= initial_insn
->t
.operand_map
.head
; op1
!= NULL
; op1
= op1
->next
)
1476 if (op_is_constant (op1
))
1478 append_constant_value_condition (tr
,
1481 op_get_constant (op1
));
1486 /* Now add the explicit preconditions listed after the "|" in the spec.
1487 These are currently very limited, so we do a special case
1488 parse for them. We expect spaces, opname != opname. */
1489 for (precond
= initial_insn
->preconds
.head
;
1491 precond
= precond
->next
)
1496 if (precond
->opname1
)
1498 op1
= get_opmatch (&initial_insn
->t
.operand_map
, precond
->opname1
);
1501 as_fatal (_("opcode '%s': no bound opname '%s' "
1502 "for precondition in '%s'"),
1503 xtensa_opcode_name (isa
, opcode
),
1504 precond
->opname1
, from_string
);
1509 if (precond
->opname2
)
1511 op2
= get_opmatch (&initial_insn
->t
.operand_map
, precond
->opname2
);
1514 as_fatal (_("opcode '%s': no bound opname '%s' "
1515 "for precondition in %s"),
1516 xtensa_opcode_name (isa
, opcode
),
1517 precond
->opname2
, from_string
);
1522 if (op1
== NULL
&& op2
== NULL
)
1524 as_fatal (_("opcode '%s': precondition only contains "
1525 "constants in '%s'"),
1526 xtensa_opcode_name (isa
, opcode
), from_string
);
1529 else if (op1
!= NULL
&& op2
!= NULL
)
1530 append_value_condition (tr
, precond
->cmpop
,
1531 op1
->operand_num
, op2
->operand_num
);
1532 else if (op2
== NULL
)
1533 append_constant_value_condition (tr
, precond
->cmpop
,
1534 op1
->operand_num
, precond
->opval1
);
1536 append_constant_value_condition (tr
, precond
->cmpop
,
1537 op2
->operand_num
, precond
->opval2
);
1540 /* Generate the replacement instructions. Some of these
1541 "instructions" are actually labels and literals. The literals
1542 must be defined in order 0..n and a literal must be defined
1543 (e.g., "LITERAL0 %imm") before use (e.g., "%LITERAL0"). The
1544 labels must be defined in order, but they can be used before they
1545 are defined. Also there are a number of special operands (e.g.,
1548 for (r
= replace_insns
->head
; r
!= NULL
; r
= r
->next
)
1551 const char *opcode_name
;
1552 size_t operand_count
;
1555 const char *fn_name
;
1556 const char *operand_arg_name
;
1558 bi
= (BuildInstr
*) xmalloc (sizeof (BuildInstr
));
1559 append_build_insn (tr
, bi
);
1562 bi
->opcode
= XTENSA_UNDEFINED
;
1566 opcode_name
= r
->t
.opcode_name
;
1567 operand_count
= insn_templ_operand_count (&r
->t
);
1569 if (parse_id_constant (opcode_name
, "LITERAL", &idnum
))
1571 bi
->typ
= INSTR_LITERAL_DEF
;
1573 if (idnum
!= literal_count
)
1574 as_fatal (_("generated literals must be numbered consecutively"));
1576 if (operand_count
!= 1)
1577 as_fatal (_("expected one operand for generated literal"));
1580 else if (parse_id_constant (opcode_name
, "LABEL", &idnum
))
1582 bi
->typ
= INSTR_LABEL_DEF
;
1584 if (idnum
!= label_count
)
1585 as_fatal (_("generated labels must be numbered consecutively"));
1587 if (operand_count
!= 0)
1588 as_fatal (_("expected 0 operands for generated label"));
1592 bi
->typ
= INSTR_INSTR
;
1593 bi
->opcode
= xtensa_opcode_lookup (isa
, r
->t
.opcode_name
);
1594 if (bi
->opcode
== XTENSA_UNDEFINED
)
1596 /* Check for the right number of ops. */
1597 if (xtensa_num_operands (isa
, bi
->opcode
)
1598 != (int) operand_count
)
1599 as_fatal (_("opcode '%s': replacement does not have %d ops"),
1600 opcode_name
, xtensa_num_operands (isa
, bi
->opcode
));
1603 for (op
= r
->t
.operand_map
.head
; op
!= NULL
; op
= op
->next
)
1607 if (op_is_constant (op
))
1608 append_constant_op (bi
, op
->operand_num
, op_get_constant (op
));
1609 else if (parse_id_constant (op
->operand_name
, "%LITERAL", &idnum
))
1611 if (idnum
>= literal_count
)
1612 as_fatal (_("opcode %s: replacement "
1613 "literal %d >= literal_count(%d)"),
1614 opcode_name
, idnum
, literal_count
);
1615 append_literal_op (bi
, op
->operand_num
, idnum
);
1617 else if (parse_id_constant (op
->operand_name
, "%LABEL", &idnum
))
1620 if (idnum
> max_label_count
)
1621 max_label_count
= idnum
;
1622 append_label_op (bi
, op
->operand_num
, idnum
);
1624 else if (parse_id_constant (op
->operand_name
, "a", &idnum
))
1625 append_constant_op (bi
, op
->operand_num
, idnum
);
1626 else if (op
->operand_name
[0] == '%')
1628 opname_map_e
*orig_op
;
1629 orig_op
= get_opmatch (&initial_insn
->t
.operand_map
,
1631 if (orig_op
== NULL
)
1633 as_fatal (_("opcode %s: unidentified operand '%s' in '%s'"),
1634 opcode_name
, op
->operand_name
, to_string
);
1636 append_constant_op (bi
, op
->operand_num
, 0);
1639 append_field_op (bi
, op
->operand_num
, orig_op
->operand_num
);
1641 else if (parse_special_fn (op
->operand_name
,
1642 &fn_name
, &operand_arg_name
))
1644 opname_map_e
*orig_op
;
1645 OpType typ
= OP_CONSTANT
;
1647 if (strcmp (fn_name
, "LOW8") == 0)
1648 typ
= OP_OPERAND_LOW8
;
1649 else if (strcmp (fn_name
, "HI24S") == 0)
1650 typ
= OP_OPERAND_HI24S
;
1651 else if (strcmp (fn_name
, "F32MINUS") == 0)
1652 typ
= OP_OPERAND_F32MINUS
;
1654 as_fatal (_("unknown user defined function %s"), fn_name
);
1656 orig_op
= get_opmatch (&initial_insn
->t
.operand_map
,
1658 if (orig_op
== NULL
)
1660 as_fatal (_("opcode %s: unidentified operand '%s' in '%s'"),
1661 opcode_name
, op
->operand_name
, to_string
);
1662 append_constant_op (bi
, op
->operand_num
, 0);
1665 append_user_fn_field_op (bi
, op
->operand_num
,
1666 typ
, orig_op
->operand_num
);
1670 as_fatal (_("opcode %s: could not parse operand '%s' in '%s'"),
1671 opcode_name
, op
->operand_name
, to_string
);
1672 append_constant_op (bi
, op
->operand_num
, 0);
1676 if (has_label
&& max_label_count
>= label_count
)
1678 as_fatal (_("opcode %s: replacement label %d >= label_count(%d)"),
1679 xtensa_opcode_name (isa
, opcode
),
1680 max_label_count
, label_count
);
1689 build_transition_table (transitions
, transition_count
)
1690 const string_pattern_pair
*transitions
;
1691 size_t transition_count
;
1693 TransitionTable
*table
= NULL
;
1694 int num_opcodes
= xtensa_num_opcodes (xtensa_default_isa
);
1701 /* Otherwise, build it now. */
1702 table
= (TransitionTable
*) xmalloc (sizeof (TransitionTable
));
1703 table
->num_opcodes
= num_opcodes
;
1705 (TransitionList
**) xmalloc (sizeof (TransitionTable
*) * num_opcodes
);
1707 for (i
= 0; i
< num_opcodes
; i
++)
1708 table
->table
[i
] = NULL
;
1710 for (tnum
= 0; tnum
< transition_count
; tnum
++)
1712 const char *from_string
= transitions
[tnum
].pattern
;
1713 const char *to_string
= transitions
[tnum
].replacement
;
1715 insn_pattern initial_insn
;
1716 insn_repl replace_insns
;
1719 init_insn_pattern (&initial_insn
);
1720 if (!parse_insn_pattern (from_string
, &initial_insn
))
1722 as_fatal (_("could not parse INSN_PATTERN '%s'"), from_string
);
1723 clear_insn_pattern (&initial_insn
);
1727 init_insn_repl (&replace_insns
);
1728 if (!parse_insn_repl (to_string
, &replace_insns
))
1730 as_fatal (_("could not parse INSN_REPL '%s'"), to_string
);
1731 clear_insn_pattern (&initial_insn
);
1732 clear_insn_repl (&replace_insns
);
1736 tr
= build_transition (&initial_insn
, &replace_insns
,
1737 from_string
, to_string
);
1739 append_transition (table
, tr
->opcode
, tr
);
1741 clear_insn_repl (&replace_insns
);
1742 clear_insn_pattern (&initial_insn
);
1748 extern TransitionTable
*
1749 xg_build_widen_table ()
1751 static TransitionTable
*table
= NULL
;
1753 table
= build_transition_table (widen_spec_list
, WIDEN_COUNT
);
1758 extern TransitionTable
*
1759 xg_build_simplify_table ()
1761 static TransitionTable
*table
= NULL
;
1763 table
= build_transition_table (simplify_spec_list
, SIMPLIFY_COUNT
);