[PATCH 22/57][Arm][GAS] Add support for MVE instructions: vmlaldav, vmlalv, vmlsldav...
[binutils-gdb.git] / gas / config / xtensa-relax.c
blobdaf15d52c259ef7d2f257bebd3d26b6b316ccf45
1 /* Table of relaxations for Xtensa assembly.
2 Copyright (C) 2003-2019 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
21 /* This file contains the code for generating runtime data structures
22 for relaxation pattern matching from statically specified strings.
23 Each action contains an instruction pattern to match and
24 preconditions for the match as well as an expansion if the pattern
25 matches. The preconditions can specify that two operands are the
26 same or an operand is a specific constant or register. The expansion
27 uses the bound variables from the pattern to specify that specific
28 operands from the pattern should be used in the result.
30 The code determines whether the condition applies to a constant or
31 a register depending on the type of the operand. You may get
32 unexpected results if you don't match the rule against the operand
33 type correctly.
35 The patterns match a language like:
37 INSN_PATTERN ::= INSN_TEMPL ( '|' PRECOND )* ( '?' OPTIONPRED )*
38 INSN_TEMPL ::= OPCODE ' ' [ OPERAND (',' OPERAND)* ]
39 OPCODE ::= id
40 OPERAND ::= CONSTANT | VARIABLE | SPECIALFN '(' VARIABLE ')'
41 SPECIALFN ::= 'HI24S' | 'F32MINUS' | 'LOW8'
42 | 'HI16' | 'LOW16'
43 VARIABLE ::= '%' id
44 PRECOND ::= OPERAND CMPOP OPERAND
45 CMPOP ::= '==' | '!='
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
52 | 'LABEL'
53 | 'LITERAL' VARIABLE
55 The operands in a PRECOND must be constants or variables bound by
56 the INSN_PATTERN.
58 The configuration options define a predicate on the availability of
59 options which must be TRUE for this rule to be valid. Examples are
60 requiring "density" for replacements with density instructions,
61 requiring "const16" for replacements that require const16
62 instructions, etc. The names are interpreted by the assembler to a
63 truth value for a particular frag.
65 The operands in the INSN_REPL must be constants, variables bound in
66 the associated INSN_PATTERN, special variables that are bound in
67 the INSN_REPL by LABEL or LITERAL definitions, or special value
68 manipulation functions.
70 A simple example of a replacement pattern:
71 {"movi.n %as,%imm", "movi %as,%imm"} would convert the narrow
72 movi.n instruction to the wide movi instruction.
74 A more complex example of a branch around:
75 {"beqz %as,%label", "bnez %as,%LABEL;j %label;LABEL"}
76 would convert a branch to a negated branch to the following instruction
77 with a jump to the original label.
79 An Xtensa-specific example that generates a literal:
80 {"movi %at,%imm", "LITERAL %imm; l32r %at,%LITERAL"}
81 will convert a movi instruction to an l32r of a literal
82 literal defined in the literal pool.
84 Even more complex is a conversion of a load with immediate offset
85 to a load of a freshly generated literal, an explicit add and
86 a load with 0 offset. This transformation is only valid, though
87 when the first and second operands are not the same as specified
88 by the "| %at!=%as" precondition clause.
89 {"l32i %at,%as,%imm | %at!=%as",
90 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l32i %at,%at,0"} */
92 #include "as.h"
93 #include "xtensa-isa.h"
94 #include "xtensa-relax.h"
95 #include <stddef.h>
96 #include "xtensa-config.h"
98 #ifndef XCHAL_HAVE_WIDE_BRANCHES
99 #define XCHAL_HAVE_WIDE_BRANCHES 0
100 #endif
102 /* Imported from bfd. */
103 extern xtensa_isa xtensa_default_isa;
105 /* The opname_list is a small list of names that we use for opcode and
106 operand variable names to simplify ownership of these commonly used
107 strings. Strings entered in the table can be compared by pointer
108 equality. */
110 typedef struct opname_list_struct opname_list;
111 typedef opname_list opname_e;
113 struct opname_list_struct
115 char *opname;
116 opname_list *next;
119 static opname_list *local_opnames = NULL;
122 /* The "opname_map" and its element structure "opname_map_e" are used
123 for binding an operand number to a name or a constant. */
125 typedef struct opname_map_e_struct opname_map_e;
126 typedef struct opname_map_struct opname_map;
128 struct opname_map_e_struct
130 const char *operand_name; /* If null, then use constant_value. */
131 int operand_num;
132 unsigned constant_value;
133 opname_map_e *next;
136 struct opname_map_struct
138 opname_map_e *head;
139 opname_map_e **tail;
142 /* The "precond_list" and its element structure "precond_e" represents
143 explicit preconditions comparing operand variables and constants.
144 In the "precond_e" structure, a variable is identified by the name
145 in the "opname" field. If that field is NULL, then the operand
146 is the constant in field "opval". */
148 typedef struct precond_e_struct precond_e;
149 typedef struct precond_list_struct precond_list;
151 struct precond_e_struct
153 const char *opname1;
154 unsigned opval1;
155 CmpOp cmpop;
156 const char *opname2;
157 unsigned opval2;
158 precond_e *next;
161 struct precond_list_struct
163 precond_e *head;
164 precond_e **tail;
168 /* The insn_templ represents the INSN_TEMPL instruction template. It
169 is an opcode name with a list of operands. These are used for
170 instruction patterns and replacement patterns. */
172 typedef struct insn_templ_struct insn_templ;
173 struct insn_templ_struct
175 const char *opcode_name;
176 opname_map operand_map;
180 /* The insn_pattern represents an INSN_PATTERN instruction pattern.
181 It is an instruction template with preconditions that specify when
182 it actually matches a given instruction. */
184 typedef struct insn_pattern_struct insn_pattern;
185 struct insn_pattern_struct
187 insn_templ t;
188 precond_list preconds;
189 ReqOptionList *options;
193 /* The "insn_repl" and associated element structure "insn_repl_e"
194 instruction replacement list is a list of
195 instructions/LITERALS/LABELS with constant operands or operands
196 with names bound to the operand names in the associated pattern. */
198 typedef struct insn_repl_e_struct insn_repl_e;
199 struct insn_repl_e_struct
201 insn_templ t;
202 insn_repl_e *next;
205 typedef struct insn_repl_struct insn_repl;
206 struct insn_repl_struct
208 insn_repl_e *head;
209 insn_repl_e **tail;
213 /* The split_rec is a vector of allocated char * pointers. */
215 typedef struct split_rec_struct split_rec;
216 struct split_rec_struct
218 char **vec;
219 int count;
222 /* The "string_pattern_pair" is a set of pairs containing instruction
223 patterns and replacement strings. */
225 typedef struct string_pattern_pair_struct string_pattern_pair;
226 struct string_pattern_pair_struct
228 const char *pattern;
229 const char *replacement;
233 /* The widen_spec_list is a list of valid substitutions that generate
234 wider representations. These are generally used to specify
235 replacements for instructions whose immediates do not fit their
236 encodings. A valid transition may require multiple steps of
237 one-to-one instruction replacements with a final multiple
238 instruction replacement. As an example, here are the transitions
239 required to replace an 'addi.n' with an 'addi', 'addmi'.
241 addi.n a4, 0x1010
242 => addi a4, 0x1010
243 => addmi a4, 0x1010
244 => addmi a4, 0x1000, addi a4, 0x10.
246 See the comments in xg_assembly_relax for some important details
247 regarding how these chains must be built. */
249 static string_pattern_pair widen_spec_list[] =
251 {"add.n %ar,%as,%at ? IsaUseDensityInstruction", "add %ar,%as,%at"},
252 {"addi.n %ar,%as,%imm ? IsaUseDensityInstruction", "addi %ar,%as,%imm"},
253 {"beqz.n %as,%label ? IsaUseDensityInstruction", "beqz %as,%label"},
254 {"bnez.n %as,%label ? IsaUseDensityInstruction", "bnez %as,%label"},
255 {"l32i.n %at,%as,%imm ? IsaUseDensityInstruction", "l32i %at,%as,%imm"},
256 {"mov.n %at,%as ? IsaUseDensityInstruction", "or %at,%as,%as"},
257 {"movi.n %as,%imm ? IsaUseDensityInstruction", "movi %as,%imm"},
258 {"nop.n ? IsaUseDensityInstruction ? realnop", "nop"},
259 {"nop.n ? IsaUseDensityInstruction ? no-realnop", "or 1,1,1"},
260 {"ret.n %as ? IsaUseDensityInstruction", "ret %as"},
261 {"retw.n %as ? IsaUseDensityInstruction", "retw %as"},
262 {"s32i.n %at,%as,%imm ? IsaUseDensityInstruction", "s32i %at,%as,%imm"},
263 {"srli %at,%as,%imm", "extui %at,%as,%imm,F32MINUS(%imm)"},
264 {"slli %ar,%as,0", "or %ar,%as,%as"},
266 /* Widening with literals or const16. */
267 {"movi %at,%imm ? IsaUseL32R ",
268 "LITERAL %imm; l32r %at,%LITERAL"},
269 {"movi %at,%imm ? IsaUseConst16",
270 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm)"},
272 {"addi %ar,%as,%imm", "addmi %ar,%as,%imm"},
273 /* LOW8 is the low 8 bits of the Immed
274 MID8S is the middle 8 bits of the Immed */
275 {"addmi %ar,%as,%imm", "addmi %ar,%as,HI24S(%imm); addi %ar,%ar,LOW8(%imm)"},
277 /* In the end convert to either an l32r or const16. */
278 {"addmi %ar,%as,%imm | %ar!=%as ? IsaUseL32R",
279 "LITERAL %imm; l32r %ar,%LITERAL; add %ar,%as,%ar"},
280 {"addmi %ar,%as,%imm | %ar!=%as ? IsaUseConst16",
281 "const16 %ar,HI16U(%imm); const16 %ar,LOW16U(%imm); add %ar,%as,%ar"},
283 /* Widening the load instructions with too-large immediates */
284 {"l8ui %at,%as,%imm | %at!=%as ? IsaUseL32R",
285 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l8ui %at,%at,0"},
286 {"l16si %at,%as,%imm | %at!=%as ? IsaUseL32R",
287 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l16si %at,%at,0"},
288 {"l16ui %at,%as,%imm | %at!=%as ? IsaUseL32R",
289 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l16ui %at,%at,0"},
290 {"l32i %at,%as,%imm | %at!=%as ? IsaUseL32R",
291 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l32i %at,%at,0"},
293 /* Widening load instructions with const16s. */
294 {"l8ui %at,%as,%imm | %at!=%as ? IsaUseConst16",
295 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l8ui %at,%at,0"},
296 {"l16si %at,%as,%imm | %at!=%as ? IsaUseConst16",
297 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l16si %at,%at,0"},
298 {"l16ui %at,%as,%imm | %at!=%as ? IsaUseConst16",
299 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l16ui %at,%at,0"},
300 {"l32i %at,%as,%imm | %at!=%as ? IsaUseConst16",
301 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l32i %at,%at,0"},
303 /* Widening loops with literals. */
304 {"loop %as,%label | %as!=1 ? IsaUseLoops ? IsaUseL32R",
305 "loop %as,%LABEL;"
306 "rsr.lend %as;" /* LEND */
307 "wsr.lbeg %as;" /* LBEG */
308 "LITERAL %label;"
309 "l32r %as, %LITERAL;"
310 "nop;"
311 "wsr.lend %as;"
312 "isync;"
313 "rsr.lcount %as;" /* LCOUNT */
314 "addi %as, %as, 1;"
315 "LABEL"},
316 {"loopgtz %as,%label | %as!=1 ? IsaUseLoops ? IsaUseL32R",
317 "beqz %as,%label;"
318 "bltz %as,%label;"
319 "loopgtz %as,%LABEL;"
320 "rsr.lend %as;" /* LEND */
321 "wsr.lbeg %as;" /* LBEG */
322 "LITERAL %label;"
323 "l32r %as, %LITERAL;"
324 "nop;"
325 "wsr.lend %as;"
326 "isync;"
327 "rsr.lcount %as;" /* LCOUNT */
328 "addi %as, %as, 1;"
329 "LABEL"},
330 {"loopnez %as,%label | %as!=1 ? IsaUseLoops ? IsaUseL32R",
331 "beqz %as,%label;"
332 "loopnez %as,%LABEL;"
333 "rsr.lend %as;" /* LEND */
334 "wsr.lbeg %as;" /* LBEG */
335 "LITERAL %label;"
336 "l32r %as, %LITERAL;"
337 "nop;"
338 "wsr.lend %as;"
339 "isync;"
340 "rsr.lcount %as;" /* LCOUNT */
341 "addi %as, %as, 1;"
342 "LABEL"},
344 /* Widening loops with const16. */
345 {"loop %as,%label | %as!=1 ? IsaUseLoops ? IsaUseConst16",
346 "loop %as,%LABEL;"
347 "rsr.lend %as;" /* LEND */
348 "wsr.lbeg %as;" /* LBEG */
349 "const16 %as,HI16U(%label);"
350 "const16 %as,LOW16U(%label);"
351 "wsr.lend %as;"
352 "isync;"
353 "rsr.lcount %as;" /* LCOUNT */
354 "addi %as, %as, 1;"
355 "LABEL"},
356 {"loopgtz %as,%label | %as!=1 ? IsaUseLoops ? IsaUseConst16",
357 "beqz %as,%label;"
358 "bltz %as,%label;"
359 "loopgtz %as,%LABEL;"
360 "rsr.lend %as;" /* LEND */
361 "wsr.lbeg %as;" /* LBEG */
362 "const16 %as,HI16U(%label);"
363 "const16 %as,LOW16U(%label);"
364 "wsr.lend %as;"
365 "isync;"
366 "rsr.lcount %as;" /* LCOUNT */
367 "addi %as, %as, 1;"
368 "LABEL"},
369 {"loopnez %as,%label | %as!=1 ? IsaUseLoops ? IsaUseConst16",
370 "beqz %as,%label;"
371 "loopnez %as,%LABEL;"
372 "rsr.lend %as;" /* LEND */
373 "wsr.lbeg %as;" /* LBEG */
374 "const16 %as,HI16U(%label);"
375 "const16 %as,LOW16U(%label);"
376 "wsr.lend %as;"
377 "isync;"
378 "rsr.lcount %as;" /* LCOUNT */
379 "addi %as, %as, 1;"
380 "LABEL"},
382 /* Relaxing to wide branches. Order is important here. With wide
383 branches, there is more than one correct relaxation for an
384 out-of-range branch. Put the wide branch relaxations first in the
385 table since they are more efficient than the branch-around
386 relaxations. */
388 {"beqz %as,%label ? IsaUseWideBranches", "WIDE.beqz %as,%label"},
389 {"bnez %as,%label ? IsaUseWideBranches", "WIDE.bnez %as,%label"},
390 {"bgez %as,%label ? IsaUseWideBranches", "WIDE.bgez %as,%label"},
391 {"bltz %as,%label ? IsaUseWideBranches", "WIDE.bltz %as,%label"},
392 {"beqi %as,%imm,%label ? IsaUseWideBranches", "WIDE.beqi %as,%imm,%label"},
393 {"bnei %as,%imm,%label ? IsaUseWideBranches", "WIDE.bnei %as,%imm,%label"},
394 {"bgei %as,%imm,%label ? IsaUseWideBranches", "WIDE.bgei %as,%imm,%label"},
395 {"blti %as,%imm,%label ? IsaUseWideBranches", "WIDE.blti %as,%imm,%label"},
396 {"bgeui %as,%imm,%label ? IsaUseWideBranches", "WIDE.bgeui %as,%imm,%label"},
397 {"bltui %as,%imm,%label ? IsaUseWideBranches", "WIDE.bltui %as,%imm,%label"},
398 {"bbci %as,%imm,%label ? IsaUseWideBranches", "WIDE.bbci %as,%imm,%label"},
399 {"bbsi %as,%imm,%label ? IsaUseWideBranches", "WIDE.bbsi %as,%imm,%label"},
400 {"beq %as,%at,%label ? IsaUseWideBranches", "WIDE.beq %as,%at,%label"},
401 {"bne %as,%at,%label ? IsaUseWideBranches", "WIDE.bne %as,%at,%label"},
402 {"bge %as,%at,%label ? IsaUseWideBranches", "WIDE.bge %as,%at,%label"},
403 {"blt %as,%at,%label ? IsaUseWideBranches", "WIDE.blt %as,%at,%label"},
404 {"bgeu %as,%at,%label ? IsaUseWideBranches", "WIDE.bgeu %as,%at,%label"},
405 {"bltu %as,%at,%label ? IsaUseWideBranches", "WIDE.bltu %as,%at,%label"},
406 {"bany %as,%at,%label ? IsaUseWideBranches", "WIDE.bany %as,%at,%label"},
407 {"bnone %as,%at,%label ? IsaUseWideBranches", "WIDE.bnone %as,%at,%label"},
408 {"ball %as,%at,%label ? IsaUseWideBranches", "WIDE.ball %as,%at,%label"},
409 {"bnall %as,%at,%label ? IsaUseWideBranches", "WIDE.bnall %as,%at,%label"},
410 {"bbc %as,%at,%label ? IsaUseWideBranches", "WIDE.bbc %as,%at,%label"},
411 {"bbs %as,%at,%label ? IsaUseWideBranches", "WIDE.bbs %as,%at,%label"},
413 /* Widening branch comparisons eq/ne to zero. Prefer relaxing to narrow
414 branches if the density option is available. */
415 {"beqz %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%LABEL;j %label;LABEL"},
416 {"bnez %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%LABEL;j %label;LABEL"},
417 {"beqz %as,%label", "bnez %as,%LABEL;j %label;LABEL"},
418 {"bnez %as,%label", "beqz %as,%LABEL;j %label;LABEL"},
419 {"WIDE.beqz %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%LABEL;j %label;LABEL"},
420 {"WIDE.bnez %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%LABEL;j %label;LABEL"},
421 {"WIDE.beqz %as,%label", "bnez %as,%LABEL;j %label;LABEL"},
422 {"WIDE.bnez %as,%label", "beqz %as,%LABEL;j %label;LABEL"},
424 /* Widening expect-taken branches. */
425 {"beqzt %as,%label ? IsaUsePredictedBranches", "bnez %as,%LABEL;j %label;LABEL"},
426 {"bnezt %as,%label ? IsaUsePredictedBranches", "beqz %as,%LABEL;j %label;LABEL"},
427 {"beqt %as,%at,%label ? IsaUsePredictedBranches", "bne %as,%at,%LABEL;j %label;LABEL"},
428 {"bnet %as,%at,%label ? IsaUsePredictedBranches", "beq %as,%at,%LABEL;j %label;LABEL"},
430 /* Widening branches from the Xtensa boolean option. */
431 {"bt %bs,%label ? IsaUseBooleans", "bf %bs,%LABEL;j %label;LABEL"},
432 {"bf %bs,%label ? IsaUseBooleans", "bt %bs,%LABEL;j %label;LABEL"},
434 /* Other branch-around-jump widenings. */
435 {"bgez %as,%label", "bltz %as,%LABEL;j %label;LABEL"},
436 {"bltz %as,%label", "bgez %as,%LABEL;j %label;LABEL"},
437 {"beqi %as,%imm,%label", "bnei %as,%imm,%LABEL;j %label;LABEL"},
438 {"bnei %as,%imm,%label", "beqi %as,%imm,%LABEL;j %label;LABEL"},
439 {"bgei %as,%imm,%label", "blti %as,%imm,%LABEL;j %label;LABEL"},
440 {"blti %as,%imm,%label", "bgei %as,%imm,%LABEL;j %label;LABEL"},
441 {"bgeui %as,%imm,%label", "bltui %as,%imm,%LABEL;j %label;LABEL"},
442 {"bltui %as,%imm,%label", "bgeui %as,%imm,%LABEL;j %label;LABEL"},
443 {"bbci %as,%imm,%label", "bbsi %as,%imm,%LABEL;j %label;LABEL"},
444 {"bbsi %as,%imm,%label", "bbci %as,%imm,%LABEL;j %label;LABEL"},
445 {"beq %as,%at,%label", "bne %as,%at,%LABEL;j %label;LABEL"},
446 {"bne %as,%at,%label", "beq %as,%at,%LABEL;j %label;LABEL"},
447 {"bge %as,%at,%label", "blt %as,%at,%LABEL;j %label;LABEL"},
448 {"blt %as,%at,%label", "bge %as,%at,%LABEL;j %label;LABEL"},
449 {"bgeu %as,%at,%label", "bltu %as,%at,%LABEL;j %label;LABEL"},
450 {"bltu %as,%at,%label", "bgeu %as,%at,%LABEL;j %label;LABEL"},
451 {"bany %as,%at,%label", "bnone %as,%at,%LABEL;j %label;LABEL"},
452 {"bnone %as,%at,%label", "bany %as,%at,%LABEL;j %label;LABEL"},
453 {"ball %as,%at,%label", "bnall %as,%at,%LABEL;j %label;LABEL"},
454 {"bnall %as,%at,%label", "ball %as,%at,%LABEL;j %label;LABEL"},
455 {"bbc %as,%at,%label", "bbs %as,%at,%LABEL;j %label;LABEL"},
456 {"bbs %as,%at,%label", "bbc %as,%at,%LABEL;j %label;LABEL"},
458 {"WIDE.bgez %as,%label", "bltz %as,%LABEL;j %label;LABEL"},
459 {"WIDE.bltz %as,%label", "bgez %as,%LABEL;j %label;LABEL"},
460 {"WIDE.beqi %as,%imm,%label", "bnei %as,%imm,%LABEL;j %label;LABEL"},
461 {"WIDE.bnei %as,%imm,%label", "beqi %as,%imm,%LABEL;j %label;LABEL"},
462 {"WIDE.bgei %as,%imm,%label", "blti %as,%imm,%LABEL;j %label;LABEL"},
463 {"WIDE.blti %as,%imm,%label", "bgei %as,%imm,%LABEL;j %label;LABEL"},
464 {"WIDE.bgeui %as,%imm,%label", "bltui %as,%imm,%LABEL;j %label;LABEL"},
465 {"WIDE.bltui %as,%imm,%label", "bgeui %as,%imm,%LABEL;j %label;LABEL"},
466 {"WIDE.bbci %as,%imm,%label", "bbsi %as,%imm,%LABEL;j %label;LABEL"},
467 {"WIDE.bbsi %as,%imm,%label", "bbci %as,%imm,%LABEL;j %label;LABEL"},
468 {"WIDE.beq %as,%at,%label", "bne %as,%at,%LABEL;j %label;LABEL"},
469 {"WIDE.bne %as,%at,%label", "beq %as,%at,%LABEL;j %label;LABEL"},
470 {"WIDE.bge %as,%at,%label", "blt %as,%at,%LABEL;j %label;LABEL"},
471 {"WIDE.blt %as,%at,%label", "bge %as,%at,%LABEL;j %label;LABEL"},
472 {"WIDE.bgeu %as,%at,%label", "bltu %as,%at,%LABEL;j %label;LABEL"},
473 {"WIDE.bltu %as,%at,%label", "bgeu %as,%at,%LABEL;j %label;LABEL"},
474 {"WIDE.bany %as,%at,%label", "bnone %as,%at,%LABEL;j %label;LABEL"},
475 {"WIDE.bnone %as,%at,%label", "bany %as,%at,%LABEL;j %label;LABEL"},
476 {"WIDE.ball %as,%at,%label", "bnall %as,%at,%LABEL;j %label;LABEL"},
477 {"WIDE.bnall %as,%at,%label", "ball %as,%at,%LABEL;j %label;LABEL"},
478 {"WIDE.bbc %as,%at,%label", "bbs %as,%at,%LABEL;j %label;LABEL"},
479 {"WIDE.bbs %as,%at,%label", "bbc %as,%at,%LABEL;j %label;LABEL"},
481 /* Expanding calls with literals. */
482 {"call0 %label,%ar0 ? IsaUseL32R",
483 "LITERAL %label; l32r a0,%LITERAL; callx0 a0,%ar0"},
484 {"call4 %label,%ar4 ? IsaUseL32R",
485 "LITERAL %label; l32r a4,%LITERAL; callx4 a4,%ar4"},
486 {"call8 %label,%ar8 ? IsaUseL32R",
487 "LITERAL %label; l32r a8,%LITERAL; callx8 a8,%ar8"},
488 {"call12 %label,%ar12 ? IsaUseL32R",
489 "LITERAL %label; l32r a12,%LITERAL; callx12 a12,%ar12"},
491 /* Expanding calls with const16. */
492 {"call0 %label,%ar0 ? IsaUseConst16",
493 "const16 a0,HI16U(%label); const16 a0,LOW16U(%label); callx0 a0,%ar0"},
494 {"call4 %label,%ar4 ? IsaUseConst16",
495 "const16 a4,HI16U(%label); const16 a4,LOW16U(%label); callx4 a4,%ar4"},
496 {"call8 %label,%ar8 ? IsaUseConst16",
497 "const16 a8,HI16U(%label); const16 a8,LOW16U(%label); callx8 a8,%ar8"},
498 {"call12 %label,%ar12 ? IsaUseConst16",
499 "const16 a12,HI16U(%label); const16 a12,LOW16U(%label); callx12 a12,%ar12"},
501 /* Expanding j.l with literals. */
502 {"j %label ? FREEREG ? IsaUseL32R",
503 "LITERAL %label; l32r FREEREG,%LITERAL; jx FREEREG"},
504 /* Expanding j.l with const16. */
505 {"j %label ? FREEREG ? IsaUseConst16",
506 "const16 FREEREG,HI16U(%label); const16 FREEREG,LOW16U(%label); jx FREEREG"},
509 #define WIDEN_COUNT (sizeof (widen_spec_list) / sizeof (string_pattern_pair))
512 /* The simplify_spec_list specifies simplifying transformations that
513 will reduce the instruction width or otherwise simplify an
514 instruction. These are usually applied before relaxation in the
515 assembler. It is always legal to simplify. Even for "addi as, 0",
516 the "addi.n as, 0" will eventually be widened back to an "addi 0"
517 after the widening table is applied. Note: The usage of this table
518 has changed somewhat so that it is entirely specific to "narrowing"
519 instructions to use the density option. This table is not used at
520 all when the density option is not available. */
522 string_pattern_pair simplify_spec_list[] =
524 {"add %ar,%as,%at ? IsaUseDensityInstruction", "add.n %ar,%as,%at"},
525 {"addi.n %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"},
526 {"addi %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"},
527 {"addi %ar,%as,%imm ? IsaUseDensityInstruction", "addi.n %ar,%as,%imm"},
528 {"addmi %ar,%as,%imm ? IsaUseDensityInstruction", "addi.n %ar,%as,%imm"},
529 {"beqz %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%label"},
530 {"bnez %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%label"},
531 {"l32i %at,%as,%imm ? IsaUseDensityInstruction", "l32i.n %at,%as,%imm"},
532 {"movi %as,%imm ? IsaUseDensityInstruction", "movi.n %as,%imm"},
533 {"nop ? realnop ? IsaUseDensityInstruction", "nop.n"},
534 {"or %ar,%as,%at | %ar==%as | %as==%at ? IsaUseDensityInstruction", "nop.n"},
535 {"or %ar,%as,%at | %ar!=%as | %as==%at ? IsaUseDensityInstruction", "mov.n %ar,%as"},
536 {"ret %as ? IsaUseDensityInstruction", "ret.n %as"},
537 {"retw %as ? IsaUseDensityInstruction", "retw.n %as"},
538 {"s32i %at,%as,%imm ? IsaUseDensityInstruction", "s32i.n %at,%as,%imm"},
539 {"slli %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"}
542 #define SIMPLIFY_COUNT \
543 (sizeof (simplify_spec_list) / sizeof (string_pattern_pair))
546 /* Externally visible functions. */
548 extern bfd_boolean xg_has_userdef_op_fn (OpType);
549 extern long xg_apply_userdef_op_fn (OpType, long);
552 static void
553 append_transition (TransitionTable *tt,
554 xtensa_opcode opcode,
555 TransitionRule *t,
556 transition_cmp_fn cmp)
558 TransitionList *tl = XNEW (TransitionList);
559 TransitionList *prev;
560 TransitionList **t_p;
561 gas_assert (tt != NULL);
562 gas_assert (opcode < tt->num_opcodes);
564 prev = tt->table[opcode];
565 tl->rule = t;
566 tl->next = NULL;
567 if (prev == NULL)
569 tt->table[opcode] = tl;
570 return;
573 for (t_p = &tt->table[opcode]; (*t_p) != NULL; t_p = &(*t_p)->next)
575 if (cmp && cmp (t, (*t_p)->rule) < 0)
577 /* Insert it here. */
578 tl->next = *t_p;
579 *t_p = tl;
580 return;
583 (*t_p) = tl;
587 static void
588 append_condition (TransitionRule *tr, Precondition *cond)
590 PreconditionList *pl = XNEW (PreconditionList);
591 PreconditionList *prev = tr->conditions;
592 PreconditionList *nxt;
594 pl->precond = cond;
595 pl->next = NULL;
596 if (prev == NULL)
598 tr->conditions = pl;
599 return;
601 nxt = prev->next;
602 while (nxt != NULL)
604 prev = nxt;
605 nxt = nxt->next;
607 prev->next = pl;
611 static void
612 append_value_condition (TransitionRule *tr,
613 CmpOp cmp,
614 unsigned op1,
615 unsigned op2)
617 Precondition *cond = XNEW (Precondition);
619 cond->cmp = cmp;
620 cond->op_num = op1;
621 cond->typ = OP_OPERAND;
622 cond->op_data = op2;
623 append_condition (tr, cond);
627 static void
628 append_constant_value_condition (TransitionRule *tr,
629 CmpOp cmp,
630 unsigned op1,
631 unsigned cnst)
633 Precondition *cond = XNEW (Precondition);
635 cond->cmp = cmp;
636 cond->op_num = op1;
637 cond->typ = OP_CONSTANT;
638 cond->op_data = cnst;
639 append_condition (tr, cond);
643 static void
644 append_build_insn (TransitionRule *tr, BuildInstr *bi)
646 BuildInstr *prev = tr->to_instr;
647 BuildInstr *nxt;
649 bi->next = NULL;
650 if (prev == NULL)
652 tr->to_instr = bi;
653 return;
655 nxt = prev->next;
656 while (nxt != 0)
658 prev = nxt;
659 nxt = prev->next;
661 prev->next = bi;
665 static void
666 append_op (BuildInstr *bi, BuildOp *b_op)
668 BuildOp *prev = bi->ops;
669 BuildOp *nxt;
671 if (prev == NULL)
673 bi->ops = b_op;
674 return;
676 nxt = prev->next;
677 while (nxt != NULL)
679 prev = nxt;
680 nxt = nxt->next;
682 prev->next = b_op;
686 static void
687 append_literal_op (BuildInstr *bi, unsigned op1, unsigned src_op)
689 BuildOp *b_op = XNEW (BuildOp);
691 b_op->op_num = op1;
692 b_op->typ = OP_LITERAL;
693 b_op->op_data = src_op;
694 b_op->next = NULL;
695 append_op (bi, b_op);
699 static void
700 append_label_op (BuildInstr *bi, unsigned op1)
702 BuildOp *b_op = XNEW (BuildOp);
704 b_op->op_num = op1;
705 b_op->typ = OP_LABEL;
706 b_op->op_data = 0;
707 b_op->next = NULL;
708 append_op (bi, b_op);
712 static void
713 append_constant_op (BuildInstr *bi, unsigned op1, unsigned cnst)
715 BuildOp *b_op = XNEW (BuildOp);
717 b_op->op_num = op1;
718 b_op->typ = OP_CONSTANT;
719 b_op->op_data = cnst;
720 b_op->next = NULL;
721 append_op (bi, b_op);
725 static void
726 append_field_op (BuildInstr *bi, unsigned op1, unsigned src_op)
728 BuildOp *b_op = XNEW (BuildOp);
730 b_op->op_num = op1;
731 b_op->typ = OP_OPERAND;
732 b_op->op_data = src_op;
733 b_op->next = NULL;
734 append_op (bi, b_op);
738 /* These could be generated but are not currently. */
740 static void
741 append_user_fn_field_op (BuildInstr *bi,
742 unsigned op1,
743 OpType typ,
744 unsigned src_op)
746 BuildOp *b_op = XNEW (BuildOp);
748 b_op->op_num = op1;
749 b_op->typ = typ;
750 b_op->op_data = src_op;
751 b_op->next = NULL;
752 append_op (bi, b_op);
756 /* These operand functions are the semantics of user-defined
757 operand functions. */
759 static long
760 operand_function_HI24S (long a)
762 if (a & 0x80)
763 return (a & (~0xff)) + 0x100;
764 else
765 return (a & (~0xff));
769 static long
770 operand_function_F32MINUS (long a)
772 return (32 - a);
776 static long
777 operand_function_LOW8 (long a)
779 if (a & 0x80)
780 return (a & 0xff) | ~0xff;
781 else
782 return (a & 0xff);
786 static long
787 operand_function_LOW16U (long a)
789 return (a & 0xffff);
793 static long
794 operand_function_HI16U (long a)
796 unsigned long b = a & 0xffff0000;
797 return (long) (b >> 16);
801 bfd_boolean
802 xg_has_userdef_op_fn (OpType op)
804 switch (op)
806 case OP_OPERAND_F32MINUS:
807 case OP_OPERAND_LOW8:
808 case OP_OPERAND_HI24S:
809 case OP_OPERAND_LOW16U:
810 case OP_OPERAND_HI16U:
811 return TRUE;
812 default:
813 break;
815 return FALSE;
819 long
820 xg_apply_userdef_op_fn (OpType op, long a)
822 switch (op)
824 case OP_OPERAND_F32MINUS:
825 return operand_function_F32MINUS (a);
826 case OP_OPERAND_LOW8:
827 return operand_function_LOW8 (a);
828 case OP_OPERAND_HI24S:
829 return operand_function_HI24S (a);
830 case OP_OPERAND_LOW16U:
831 return operand_function_LOW16U (a);
832 case OP_OPERAND_HI16U:
833 return operand_function_HI16U (a);
834 default:
835 break;
837 return FALSE;
841 /* Generate a transition table. */
843 static const char *
844 enter_opname_n (const char *name, int len)
846 opname_e *op;
848 for (op = local_opnames; op != NULL; op = op->next)
850 if (strlen (op->opname) == (unsigned) len
851 && strncmp (op->opname, name, len) == 0)
852 return op->opname;
854 op = XNEW (opname_e);
855 op->opname = xmemdup0 (name, len);
856 return op->opname;
860 static const char *
861 enter_opname (const char *name)
863 opname_e *op;
865 for (op = local_opnames; op != NULL; op = op->next)
867 if (strcmp (op->opname, name) == 0)
868 return op->opname;
870 op = XNEW (opname_e);
871 op->opname = xstrdup (name);
872 return op->opname;
876 static void
877 init_opname_map (opname_map *m)
879 m->head = NULL;
880 m->tail = &m->head;
884 static void
885 clear_opname_map (opname_map *m)
887 opname_map_e *e;
889 while (m->head != NULL)
891 e = m->head;
892 m->head = e->next;
893 free (e);
895 m->tail = &m->head;
899 static bfd_boolean
900 same_operand_name (const opname_map_e *m1, const opname_map_e *m2)
902 if (m1->operand_name == NULL || m2->operand_name == NULL)
903 return FALSE;
904 return (m1->operand_name == m2->operand_name);
908 static opname_map_e *
909 get_opmatch (opname_map *map, const char *operand_name)
911 opname_map_e *m;
913 for (m = map->head; m != NULL; m = m->next)
915 if (strcmp (m->operand_name, operand_name) == 0)
916 return m;
918 return NULL;
922 static bfd_boolean
923 op_is_constant (const opname_map_e *m1)
925 return (m1->operand_name == NULL);
929 static unsigned
930 op_get_constant (const opname_map_e *m1)
932 gas_assert (m1->operand_name == NULL);
933 return m1->constant_value;
937 static void
938 init_precond_list (precond_list *l)
940 l->head = NULL;
941 l->tail = &l->head;
945 static void
946 clear_precond_list (precond_list *l)
948 precond_e *e;
950 while (l->head != NULL)
952 e = l->head;
953 l->head = e->next;
954 free (e);
956 l->tail = &l->head;
960 static void
961 init_insn_templ (insn_templ *t)
963 t->opcode_name = NULL;
964 init_opname_map (&t->operand_map);
968 static void
969 clear_insn_templ (insn_templ *t)
971 clear_opname_map (&t->operand_map);
975 static void
976 init_insn_pattern (insn_pattern *p)
978 init_insn_templ (&p->t);
979 init_precond_list (&p->preconds);
980 p->options = NULL;
984 static void
985 clear_insn_pattern (insn_pattern *p)
987 clear_insn_templ (&p->t);
988 clear_precond_list (&p->preconds);
992 static void
993 init_insn_repl (insn_repl *r)
995 r->head = NULL;
996 r->tail = &r->head;
1000 static void
1001 clear_insn_repl (insn_repl *r)
1003 insn_repl_e *e;
1005 while (r->head != NULL)
1007 e = r->head;
1008 r->head = e->next;
1009 clear_insn_templ (&e->t);
1011 r->tail = &r->head;
1015 static int
1016 insn_templ_operand_count (const insn_templ *t)
1018 int i = 0;
1019 const opname_map_e *op;
1021 for (op = t->operand_map.head; op != NULL; op = op->next, i++)
1023 return i;
1027 /* Convert a string to a number. E.G.: parse_constant("10", &num) */
1029 static bfd_boolean
1030 parse_constant (const char *in, unsigned *val_p)
1032 unsigned val = 0;
1033 const char *p;
1035 if (in == NULL)
1036 return FALSE;
1037 p = in;
1039 while (*p != '\0')
1041 if (*p >= '0' && *p <= '9')
1042 val = val * 10 + (*p - '0');
1043 else
1044 return FALSE;
1045 ++p;
1047 *val_p = val;
1048 return TRUE;
1052 static bfd_boolean
1053 parse_special_fn (const char *name,
1054 const char **fn_name_p,
1055 const char **arg_name_p)
1057 const char *p_start;
1058 const char *p_end;
1060 p_start = strchr (name, '(');
1061 if (p_start == NULL)
1062 return FALSE;
1064 p_end = strchr (p_start, ')');
1066 if (p_end == NULL)
1067 return FALSE;
1069 if (p_end[1] != '\0')
1070 return FALSE;
1072 *fn_name_p = enter_opname_n (name, p_start - name);
1073 *arg_name_p = enter_opname_n (p_start + 1, p_end - p_start - 1);
1074 return TRUE;
1078 static const char *
1079 skip_white (const char *p)
1081 if (p == NULL)
1082 return p;
1083 while (*p == ' ')
1084 ++p;
1085 return p;
1089 static void
1090 trim_whitespace (char *in)
1092 char *last_white = NULL;
1093 char *p = in;
1095 while (p && *p != '\0')
1097 while (*p == ' ')
1099 if (last_white == NULL)
1100 last_white = p;
1101 p++;
1103 if (*p != '\0')
1105 last_white = NULL;
1106 p++;
1109 if (last_white)
1110 *last_white = '\0';
1114 /* Split a string into component strings where "c" is the
1115 delimiter. Place the result in the split_rec. */
1117 static void
1118 split_string (split_rec *rec,
1119 const char *in,
1120 char c,
1121 bfd_boolean elide_whitespace)
1123 int cnt = 0;
1124 int i;
1125 const char *p = in;
1127 while (p != NULL && *p != '\0')
1129 cnt++;
1130 p = strchr (p, c);
1131 if (p)
1132 p++;
1134 rec->count = cnt;
1135 rec->vec = NULL;
1137 if (rec->count == 0)
1138 return;
1140 rec->vec = XNEWVEC (char *, cnt);
1141 for (i = 0; i < cnt; i++)
1142 rec->vec[i] = 0;
1144 p = in;
1145 for (i = 0; i < cnt; i++)
1147 const char *q;
1148 int len;
1150 q = p;
1151 if (elide_whitespace)
1152 q = skip_white (q);
1154 p = strchr (q, c);
1155 if (p == NULL)
1156 rec->vec[i] = xstrdup (q);
1157 else
1159 len = p - q;
1160 rec->vec[i] = xmemdup0 (q, len);
1161 p++;
1164 if (elide_whitespace)
1165 trim_whitespace (rec->vec[i]);
1170 static void
1171 clear_split_rec (split_rec *rec)
1173 int i;
1175 for (i = 0; i < rec->count; i++)
1176 free (rec->vec[i]);
1178 if (rec->count > 0)
1179 free (rec->vec);
1183 /* Initialize a split record. The split record must be initialized
1184 before split_string is called. */
1186 static void
1187 init_split_rec (split_rec *rec)
1189 rec->vec = NULL;
1190 rec->count = 0;
1194 /* Parse an instruction template like "insn op1, op2, op3". */
1196 static bfd_boolean
1197 parse_insn_templ (const char *s, insn_templ *t)
1199 const char *p = s;
1200 int insn_name_len;
1201 split_rec oprec;
1202 int i;
1204 /* First find the first whitespace. */
1206 init_split_rec (&oprec);
1208 p = skip_white (p);
1209 insn_name_len = strcspn (s, " ");
1210 if (insn_name_len == 0)
1211 return FALSE;
1213 init_insn_templ (t);
1214 t->opcode_name = enter_opname_n (p, insn_name_len);
1216 p = p + insn_name_len;
1218 /* Split by ',' and skip beginning and trailing whitespace. */
1219 split_string (&oprec, p, ',', TRUE);
1221 for (i = 0; i < oprec.count; i++)
1223 const char *opname = oprec.vec[i];
1224 opname_map_e *e = XNEW (opname_map_e);
1225 e->next = NULL;
1226 e->operand_name = NULL;
1227 e->constant_value = 0;
1228 e->operand_num = i;
1230 /* If it begins with a number, assume that it is a number. */
1231 if (opname && opname[0] >= '0' && opname[0] <= '9')
1233 unsigned val;
1235 if (parse_constant (opname, &val))
1236 e->constant_value = val;
1237 else
1239 free (e);
1240 clear_split_rec (&oprec);
1241 clear_insn_templ (t);
1242 return FALSE;
1245 else
1246 e->operand_name = enter_opname (oprec.vec[i]);
1248 *t->operand_map.tail = e;
1249 t->operand_map.tail = &e->next;
1251 clear_split_rec (&oprec);
1252 return TRUE;
1256 static bfd_boolean
1257 parse_precond (const char *s, precond_e *precond)
1259 /* All preconditions are currently of the form:
1260 a == b or a != b or a == k (where k is a constant).
1261 Later we may use some special functions like DENSITY == 1
1262 to identify when density is available. */
1264 const char *p = s;
1265 int len;
1266 precond->opname1 = NULL;
1267 precond->opval1 = 0;
1268 precond->cmpop = OP_EQUAL;
1269 precond->opname2 = NULL;
1270 precond->opval2 = 0;
1271 precond->next = NULL;
1273 p = skip_white (p);
1275 len = strcspn (p, " !=");
1277 if (len == 0)
1278 return FALSE;
1280 precond->opname1 = enter_opname_n (p, len);
1281 p = p + len;
1282 p = skip_white (p);
1284 /* Check for "==" and "!=". */
1285 if (strncmp (p, "==", 2) == 0)
1286 precond->cmpop = OP_EQUAL;
1287 else if (strncmp (p, "!=", 2) == 0)
1288 precond->cmpop = OP_NOTEQUAL;
1289 else
1290 return FALSE;
1292 p = p + 2;
1293 p = skip_white (p);
1295 /* No trailing whitespace from earlier parsing. */
1296 if (p[0] >= '0' && p[0] <= '9')
1298 unsigned val;
1299 if (parse_constant (p, &val))
1300 precond->opval2 = val;
1301 else
1302 return FALSE;
1304 else
1305 precond->opname2 = enter_opname (p);
1306 return TRUE;
1310 static void
1311 clear_req_or_option_list (ReqOrOption **r_p)
1313 if (*r_p == NULL)
1314 return;
1316 free ((*r_p)->option_name);
1317 clear_req_or_option_list (&(*r_p)->next);
1318 *r_p = NULL;
1322 static void
1323 clear_req_option_list (ReqOption **r_p)
1325 if (*r_p == NULL)
1326 return;
1328 clear_req_or_option_list (&(*r_p)->or_option_terms);
1329 clear_req_option_list (&(*r_p)->next);
1330 *r_p = NULL;
1334 static ReqOrOption *
1335 clone_req_or_option_list (ReqOrOption *req_or_option)
1337 ReqOrOption *new_req_or_option;
1339 if (req_or_option == NULL)
1340 return NULL;
1342 new_req_or_option = XNEW (ReqOrOption);
1343 new_req_or_option->option_name = xstrdup (req_or_option->option_name);
1344 new_req_or_option->is_true = req_or_option->is_true;
1345 new_req_or_option->next = NULL;
1346 new_req_or_option->next = clone_req_or_option_list (req_or_option->next);
1347 return new_req_or_option;
1351 static ReqOption *
1352 clone_req_option_list (ReqOption *req_option)
1354 ReqOption *new_req_option;
1356 if (req_option == NULL)
1357 return NULL;
1359 new_req_option = XNEW (ReqOption);
1360 new_req_option->or_option_terms = NULL;
1361 new_req_option->next = NULL;
1362 new_req_option->or_option_terms =
1363 clone_req_or_option_list (req_option->or_option_terms);
1364 new_req_option->next = clone_req_option_list (req_option->next);
1365 return new_req_option;
1369 static bfd_boolean
1370 parse_option_cond (const char *s, ReqOption *option)
1372 int i;
1373 split_rec option_term_rec;
1375 /* All option or conditions are of the form:
1376 optionA + no-optionB + ...
1377 "Ands" are divided by "?". */
1379 init_split_rec (&option_term_rec);
1380 split_string (&option_term_rec, s, '+', TRUE);
1382 if (option_term_rec.count == 0)
1384 clear_split_rec (&option_term_rec);
1385 return FALSE;
1388 for (i = 0; i < option_term_rec.count; i++)
1390 char *option_name = option_term_rec.vec[i];
1391 bfd_boolean is_true = TRUE;
1392 ReqOrOption *req;
1393 ReqOrOption **r_p;
1395 if (strncmp (option_name, "no-", 3) == 0)
1397 option_name = xstrdup (&option_name[3]);
1398 is_true = FALSE;
1400 else
1401 option_name = xstrdup (option_name);
1403 req = XNEW (ReqOrOption);
1404 req->option_name = option_name;
1405 req->is_true = is_true;
1406 req->next = NULL;
1408 /* Append to list. */
1409 for (r_p = &option->or_option_terms; (*r_p) != NULL;
1410 r_p = &(*r_p)->next)
1412 (*r_p) = req;
1414 return TRUE;
1418 /* Parse a string like:
1419 "insn op1, op2, op3, op4 | op1 != op2 | op2 == op3 | op4 == 1".
1420 I.E., instruction "insn" with 4 operands where operand 1 and 2 are not
1421 the same and operand 2 and 3 are the same and operand 4 is 1.
1425 "insn op1 | op1 == 1 / density + boolean / no-useroption".
1426 i.e. instruction "insn" with 1 operands where operand 1 is 1
1427 when "density" or "boolean" options are available and
1428 "useroption" is not available.
1430 Because the current implementation of this parsing scheme uses
1431 split_string, it requires that '|' and '?' are only used as
1432 delimiters for predicates and required options. */
1434 static bfd_boolean
1435 parse_insn_pattern (const char *in, insn_pattern *insn)
1437 split_rec rec;
1438 split_rec optionrec;
1439 int i;
1441 init_insn_pattern (insn);
1443 init_split_rec (&optionrec);
1444 split_string (&optionrec, in, '?', TRUE);
1445 if (optionrec.count == 0)
1447 clear_split_rec (&optionrec);
1448 return FALSE;
1451 init_split_rec (&rec);
1453 split_string (&rec, optionrec.vec[0], '|', TRUE);
1455 if (rec.count == 0)
1457 clear_split_rec (&rec);
1458 clear_split_rec (&optionrec);
1459 return FALSE;
1462 if (!parse_insn_templ (rec.vec[0], &insn->t))
1464 clear_split_rec (&rec);
1465 clear_split_rec (&optionrec);
1466 return FALSE;
1469 for (i = 1; i < rec.count; i++)
1471 precond_e *cond = XNEW (precond_e);
1473 if (!parse_precond (rec.vec[i], cond))
1475 clear_split_rec (&rec);
1476 clear_split_rec (&optionrec);
1477 clear_insn_pattern (insn);
1478 return FALSE;
1481 /* Append the condition. */
1482 *insn->preconds.tail = cond;
1483 insn->preconds.tail = &cond->next;
1486 for (i = 1; i < optionrec.count; i++)
1488 /* Handle the option conditions. */
1489 ReqOption **r_p;
1490 ReqOption *req_option = XNEW (ReqOption);
1491 req_option->or_option_terms = NULL;
1492 req_option->next = NULL;
1494 if (!parse_option_cond (optionrec.vec[i], req_option))
1496 clear_split_rec (&rec);
1497 clear_split_rec (&optionrec);
1498 clear_insn_pattern (insn);
1499 clear_req_option_list (&req_option);
1500 return FALSE;
1503 /* Append the condition. */
1504 for (r_p = &insn->options; (*r_p) != NULL; r_p = &(*r_p)->next)
1507 (*r_p) = req_option;
1510 clear_split_rec (&rec);
1511 clear_split_rec (&optionrec);
1512 return TRUE;
1516 static bfd_boolean
1517 parse_insn_repl (const char *in, insn_repl *r_p)
1519 /* This is a list of instruction templates separated by ';'. */
1520 split_rec rec;
1521 int i;
1523 split_string (&rec, in, ';', TRUE);
1525 for (i = 0; i < rec.count; i++)
1527 insn_repl_e *e = XNEW (insn_repl_e);
1529 e->next = NULL;
1531 if (!parse_insn_templ (rec.vec[i], &e->t))
1533 free (e);
1534 clear_insn_repl (r_p);
1535 return FALSE;
1537 *r_p->tail = e;
1538 r_p->tail = &e->next;
1540 return TRUE;
1544 static bfd_boolean
1545 transition_applies (insn_pattern *initial_insn,
1546 const char *from_string ATTRIBUTE_UNUSED,
1547 const char *to_string ATTRIBUTE_UNUSED)
1549 ReqOption *req_option;
1551 for (req_option = initial_insn->options;
1552 req_option != NULL;
1553 req_option = req_option->next)
1555 ReqOrOption *req_or_option = req_option->or_option_terms;
1557 if (req_or_option == NULL
1558 || req_or_option->next != NULL)
1559 continue;
1561 if (strncmp (req_or_option->option_name, "IsaUse", 6) == 0)
1563 bfd_boolean option_available = FALSE;
1564 char *option_name = req_or_option->option_name + 6;
1565 if (!strcmp (option_name, "DensityInstruction"))
1566 option_available = (XCHAL_HAVE_DENSITY == 1);
1567 else if (!strcmp (option_name, "L32R"))
1568 option_available = (XCHAL_HAVE_L32R == 1);
1569 else if (!strcmp (option_name, "Const16"))
1570 option_available = (XCHAL_HAVE_CONST16 == 1);
1571 else if (!strcmp (option_name, "Loops"))
1572 option_available = (XCHAL_HAVE_LOOPS == 1);
1573 else if (!strcmp (option_name, "WideBranches"))
1574 option_available
1575 = (XCHAL_HAVE_WIDE_BRANCHES == 1 && produce_flix == FLIX_ALL);
1576 else if (!strcmp (option_name, "PredictedBranches"))
1577 option_available
1578 = (XCHAL_HAVE_PREDICTED_BRANCHES == 1
1579 && produce_flix == FLIX_ALL);
1580 else if (!strcmp (option_name, "Booleans"))
1581 option_available = (XCHAL_HAVE_BOOLEANS == 1);
1582 else
1583 as_warn (_("invalid configuration option '%s' in transition rule '%s'"),
1584 req_or_option->option_name, from_string);
1585 if ((option_available ^ req_or_option->is_true) != 0)
1586 return FALSE;
1588 else if (strcmp (req_or_option->option_name, "realnop") == 0)
1590 bfd_boolean nop_available =
1591 (xtensa_opcode_lookup (xtensa_default_isa, "nop")
1592 != XTENSA_UNDEFINED);
1593 if ((nop_available ^ req_or_option->is_true) != 0)
1594 return FALSE;
1597 return TRUE;
1601 static bfd_boolean
1602 wide_branch_opcode (const char *opcode_name,
1603 const char *suffix,
1604 xtensa_opcode *popcode)
1606 xtensa_isa isa = xtensa_default_isa;
1607 xtensa_opcode opcode;
1608 static char wbr_name_buf[20];
1610 if (strncmp (opcode_name, "WIDE.", 5) != 0)
1611 return FALSE;
1613 strcpy (wbr_name_buf, opcode_name + 5);
1614 strcat (wbr_name_buf, suffix);
1615 opcode = xtensa_opcode_lookup (isa, wbr_name_buf);
1616 if (opcode != XTENSA_UNDEFINED)
1618 *popcode = opcode;
1619 return TRUE;
1622 return FALSE;
1626 static TransitionRule *
1627 build_transition (insn_pattern *initial_insn,
1628 insn_repl *replace_insns,
1629 const char *from_string,
1630 const char *to_string)
1632 TransitionRule *tr = NULL;
1633 xtensa_opcode opcode;
1634 xtensa_isa isa = xtensa_default_isa;
1635 BuildInstr *literal_bi;
1637 opname_map_e *op1;
1638 opname_map_e *op2;
1640 precond_e *precond;
1641 insn_repl_e *r;
1643 if (!wide_branch_opcode (initial_insn->t.opcode_name, ".w18", &opcode)
1644 && !wide_branch_opcode (initial_insn->t.opcode_name, ".w15", &opcode))
1645 opcode = xtensa_opcode_lookup (isa, initial_insn->t.opcode_name);
1647 if (opcode == XTENSA_UNDEFINED)
1649 /* It is OK to not be able to translate some of these opcodes. */
1650 return NULL;
1654 if (xtensa_opcode_num_operands (isa, opcode)
1655 != insn_templ_operand_count (&initial_insn->t))
1657 /* This is also OK because there are opcodes that
1658 have different numbers of operands on different
1659 architecture variations. */
1660 return NULL;
1663 tr = XNEW (TransitionRule);
1664 tr->opcode = opcode;
1665 tr->conditions = NULL;
1666 tr->to_instr = NULL;
1668 /* Build the conditions. First, equivalent operand condition.... */
1669 for (op1 = initial_insn->t.operand_map.head; op1 != NULL; op1 = op1->next)
1671 for (op2 = op1->next; op2 != NULL; op2 = op2->next)
1673 if (same_operand_name (op1, op2))
1675 append_value_condition (tr, OP_EQUAL,
1676 op1->operand_num, op2->operand_num);
1681 /* Now the condition that an operand value must be a constant.... */
1682 for (op1 = initial_insn->t.operand_map.head; op1 != NULL; op1 = op1->next)
1684 if (op_is_constant (op1))
1686 append_constant_value_condition (tr,
1687 OP_EQUAL,
1688 op1->operand_num,
1689 op_get_constant (op1));
1694 /* Now add the explicit preconditions listed after the "|" in the spec.
1695 These are currently very limited, so we do a special case
1696 parse for them. We expect spaces, opname != opname. */
1697 for (precond = initial_insn->preconds.head;
1698 precond != NULL;
1699 precond = precond->next)
1701 op1 = NULL;
1702 op2 = NULL;
1704 if (precond->opname1)
1706 op1 = get_opmatch (&initial_insn->t.operand_map, precond->opname1);
1707 if (op1 == NULL)
1708 as_fatal (_("opcode '%s': no bound opname '%s' "
1709 "for precondition in '%s'"),
1710 xtensa_opcode_name (isa, opcode),
1711 precond->opname1, from_string);
1714 if (precond->opname2)
1716 op2 = get_opmatch (&initial_insn->t.operand_map, precond->opname2);
1717 if (op2 == NULL)
1718 as_fatal (_("opcode '%s': no bound opname '%s' "
1719 "for precondition in '%s'"),
1720 xtensa_opcode_name (isa, opcode),
1721 precond->opname2, from_string);
1724 if (op1 == NULL && op2 == NULL)
1725 as_fatal (_("opcode '%s': precondition only contains "
1726 "constants in '%s'"),
1727 xtensa_opcode_name (isa, opcode), from_string);
1728 else if (op1 != NULL && op2 != NULL)
1729 append_value_condition (tr, precond->cmpop,
1730 op1->operand_num, op2->operand_num);
1731 else if (op2 == NULL)
1732 append_constant_value_condition (tr, precond->cmpop,
1733 op1->operand_num, precond->opval2);
1734 else
1735 append_constant_value_condition (tr, precond->cmpop,
1736 op2->operand_num, precond->opval1);
1739 tr->options = clone_req_option_list (initial_insn->options);
1741 /* Generate the replacement instructions. Some of these
1742 "instructions" are actually labels and literals. There can be at
1743 most one literal and at most one label. A literal must be defined
1744 (e.g., "LITERAL %imm") before use (e.g., "%LITERAL"). The labels
1745 can be used before they are defined. Also there are a number of
1746 special operands (e.g., HI24S). */
1748 literal_bi = NULL;
1749 for (r = replace_insns->head; r != NULL; r = r->next)
1751 BuildInstr *bi;
1752 const char *opcode_name;
1753 int operand_count;
1754 opname_map_e *op;
1755 const char *fn_name;
1756 const char *operand_arg_name;
1758 bi = XNEW (BuildInstr);
1759 append_build_insn (tr, bi);
1761 bi->opcode = XTENSA_UNDEFINED;
1762 bi->ops = NULL;
1763 bi->next = NULL;
1765 opcode_name = r->t.opcode_name;
1766 operand_count = insn_templ_operand_count (&r->t);
1768 if (strcmp (opcode_name, "LITERAL") == 0)
1770 bi->typ = INSTR_LITERAL_DEF;
1771 if (operand_count != 1)
1772 as_fatal (_("expected one operand for generated literal"));
1773 literal_bi = bi;
1775 else if (strcmp (opcode_name, "LABEL") == 0)
1777 bi->typ = INSTR_LABEL_DEF;
1778 if (operand_count != 0)
1779 as_fatal (_("expected 0 operands for generated label"));
1781 else
1783 bi->typ = INSTR_INSTR;
1784 if (wide_branch_opcode (opcode_name, ".w18", &bi->opcode)
1785 || wide_branch_opcode (opcode_name, ".w15", &bi->opcode))
1786 opcode_name = xtensa_opcode_name (isa, bi->opcode);
1787 else
1788 bi->opcode = xtensa_opcode_lookup (isa, opcode_name);
1790 if (bi->opcode == XTENSA_UNDEFINED)
1792 as_warn (_("invalid opcode '%s' in transition rule '%s'"),
1793 opcode_name, to_string);
1794 return NULL;
1797 /* Check for the right number of ops. */
1798 if (xtensa_opcode_num_operands (isa, bi->opcode)
1799 != (int) operand_count)
1800 as_fatal (ngettext ("opcode '%s': replacement does not have %d op",
1801 "opcode '%s': replacement does not have %d ops",
1802 xtensa_opcode_num_operands (isa, bi->opcode)),
1803 opcode_name,
1804 xtensa_opcode_num_operands (isa, bi->opcode));
1807 for (op = r->t.operand_map.head; op != NULL; op = op->next)
1809 unsigned idnum;
1811 if (op_is_constant (op))
1812 append_constant_op (bi, op->operand_num, op_get_constant (op));
1813 else if (strcmp (op->operand_name, "%LITERAL") == 0)
1815 if (! literal_bi || ! literal_bi->ops || literal_bi->ops->next)
1816 as_fatal (_("opcode '%s': cannot find literal definition"),
1817 opcode_name);
1818 append_literal_op (bi, op->operand_num,
1819 literal_bi->ops->op_data);
1821 else if (strcmp (op->operand_name, "%LABEL") == 0)
1822 append_label_op (bi, op->operand_num);
1823 else if (op->operand_name[0] == 'a'
1824 && parse_constant (op->operand_name + 1, &idnum))
1825 append_constant_op (bi, op->operand_num, idnum);
1826 else if (op->operand_name[0] == '%')
1828 opname_map_e *orig_op;
1829 orig_op = get_opmatch (&initial_insn->t.operand_map,
1830 op->operand_name);
1831 if (orig_op == NULL)
1832 as_fatal (_("opcode '%s': unidentified operand '%s' in '%s'"),
1833 opcode_name, op->operand_name, to_string);
1834 append_field_op (bi, op->operand_num, orig_op->operand_num);
1836 else if (strcmp (op->operand_name, "FREEREG") == 0)
1838 append_user_fn_field_op (bi, op->operand_num, OP_FREEREG, 0);
1840 else if (parse_special_fn (op->operand_name,
1841 &fn_name, &operand_arg_name))
1843 opname_map_e *orig_op;
1844 OpType typ = OP_CONSTANT;
1846 if (strcmp (fn_name, "LOW8") == 0)
1847 typ = OP_OPERAND_LOW8;
1848 else if (strcmp (fn_name, "HI24S") == 0)
1849 typ = OP_OPERAND_HI24S;
1850 else if (strcmp (fn_name, "F32MINUS") == 0)
1851 typ = OP_OPERAND_F32MINUS;
1852 else if (strcmp (fn_name, "LOW16U") == 0)
1853 typ = OP_OPERAND_LOW16U;
1854 else if (strcmp (fn_name, "HI16U") == 0)
1855 typ = OP_OPERAND_HI16U;
1856 else
1857 as_fatal (_("unknown user-defined function %s"), fn_name);
1859 orig_op = get_opmatch (&initial_insn->t.operand_map,
1860 operand_arg_name);
1861 if (orig_op == NULL)
1862 as_fatal (_("opcode '%s': unidentified operand '%s' in '%s'"),
1863 opcode_name, op->operand_name, to_string);
1864 append_user_fn_field_op (bi, op->operand_num,
1865 typ, orig_op->operand_num);
1867 else
1868 as_fatal (_("opcode '%s': could not parse operand '%s' in '%s'"),
1869 opcode_name, op->operand_name, to_string);
1873 return tr;
1877 static TransitionTable *
1878 build_transition_table (const string_pattern_pair *transitions,
1879 int transition_count,
1880 transition_cmp_fn cmp)
1882 TransitionTable *table = NULL;
1883 int num_opcodes = xtensa_isa_num_opcodes (xtensa_default_isa);
1884 int i, tnum;
1886 if (table != NULL)
1887 return table;
1889 /* Otherwise, build it now. */
1890 table = XNEW (TransitionTable);
1891 table->num_opcodes = num_opcodes;
1892 table->table = XNEWVEC (TransitionList *, num_opcodes);
1894 for (i = 0; i < num_opcodes; i++)
1895 table->table[i] = NULL;
1897 for (tnum = 0; tnum < transition_count; tnum++)
1899 const char *from_string = transitions[tnum].pattern;
1900 const char *to_string = transitions[tnum].replacement;
1902 insn_pattern initial_insn;
1903 insn_repl replace_insns;
1904 TransitionRule *tr;
1906 init_insn_pattern (&initial_insn);
1907 if (!parse_insn_pattern (from_string, &initial_insn))
1908 as_fatal (_("could not parse INSN_PATTERN '%s'"), from_string);
1910 init_insn_repl (&replace_insns);
1911 if (!parse_insn_repl (to_string, &replace_insns))
1912 as_fatal (_("could not parse INSN_REPL '%s'"), to_string);
1914 if (transition_applies (&initial_insn, from_string, to_string))
1916 tr = build_transition (&initial_insn, &replace_insns,
1917 from_string, to_string);
1918 if (tr)
1919 append_transition (table, tr->opcode, tr, cmp);
1920 else
1922 #if TENSILICA_DEBUG
1923 as_warn (_("could not build transition for %s => %s"),
1924 from_string, to_string);
1925 #endif
1929 clear_insn_repl (&replace_insns);
1930 clear_insn_pattern (&initial_insn);
1932 return table;
1936 extern TransitionTable *
1937 xg_build_widen_table (transition_cmp_fn cmp)
1939 static TransitionTable *table = NULL;
1940 if (table == NULL)
1941 table = build_transition_table (widen_spec_list, WIDEN_COUNT, cmp);
1942 return table;
1946 extern TransitionTable *
1947 xg_build_simplify_table (transition_cmp_fn cmp)
1949 static TransitionTable *table = NULL;
1950 if (table == NULL)
1951 table = build_transition_table (simplify_spec_list, SIMPLIFY_COUNT, cmp);
1952 return table;