Automatic date update in version.in
[binutils-gdb.git] / gas / config / xtensa-relax.c
blobe44f30eb8925ca64707f7347213776e1bca88291
1 /* Table of relaxations for Xtensa assembly.
2 Copyright (C) 2003-2024 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-dynconfig.h"
98 /* Imported from bfd. */
99 extern xtensa_isa xtensa_default_isa;
101 /* The opname_list is a small list of names that we use for opcode and
102 operand variable names to simplify ownership of these commonly used
103 strings. Strings entered in the table can be compared by pointer
104 equality. */
106 typedef struct opname_list_struct opname_list;
107 typedef opname_list opname_e;
109 struct opname_list_struct
111 char *opname;
112 opname_list *next;
115 static opname_list *local_opnames = NULL;
118 /* The "opname_map" and its element structure "opname_map_e" are used
119 for binding an operand number to a name or a constant. */
121 typedef struct opname_map_e_struct opname_map_e;
122 typedef struct opname_map_struct opname_map;
124 struct opname_map_e_struct
126 const char *operand_name; /* If null, then use constant_value. */
127 int operand_num;
128 unsigned constant_value;
129 opname_map_e *next;
132 struct opname_map_struct
134 opname_map_e *head;
135 opname_map_e **tail;
138 /* The "precond_list" and its element structure "precond_e" represents
139 explicit preconditions comparing operand variables and constants.
140 In the "precond_e" structure, a variable is identified by the name
141 in the "opname" field. If that field is NULL, then the operand
142 is the constant in field "opval". */
144 typedef struct precond_e_struct precond_e;
145 typedef struct precond_list_struct precond_list;
147 struct precond_e_struct
149 const char *opname1;
150 unsigned opval1;
151 CmpOp cmpop;
152 const char *opname2;
153 unsigned opval2;
154 precond_e *next;
157 struct precond_list_struct
159 precond_e *head;
160 precond_e **tail;
164 /* The insn_templ represents the INSN_TEMPL instruction template. It
165 is an opcode name with a list of operands. These are used for
166 instruction patterns and replacement patterns. */
168 typedef struct insn_templ_struct insn_templ;
169 struct insn_templ_struct
171 const char *opcode_name;
172 opname_map operand_map;
176 /* The insn_pattern represents an INSN_PATTERN instruction pattern.
177 It is an instruction template with preconditions that specify when
178 it actually matches a given instruction. */
180 typedef struct insn_pattern_struct insn_pattern;
181 struct insn_pattern_struct
183 insn_templ t;
184 precond_list preconds;
185 ReqOptionList *options;
189 /* The "insn_repl" and associated element structure "insn_repl_e"
190 instruction replacement list is a list of
191 instructions/LITERALS/LABELS with constant operands or operands
192 with names bound to the operand names in the associated pattern. */
194 typedef struct insn_repl_e_struct insn_repl_e;
195 struct insn_repl_e_struct
197 insn_templ t;
198 insn_repl_e *next;
201 typedef struct insn_repl_struct insn_repl;
202 struct insn_repl_struct
204 insn_repl_e *head;
205 insn_repl_e **tail;
209 /* The split_rec is a vector of allocated char * pointers. */
211 typedef struct split_rec_struct split_rec;
212 struct split_rec_struct
214 char **vec;
215 int count;
218 /* The "string_pattern_pair" is a set of pairs containing instruction
219 patterns and replacement strings. */
221 typedef struct string_pattern_pair_struct string_pattern_pair;
222 struct string_pattern_pair_struct
224 const char *pattern;
225 const char *replacement;
229 /* The widen_spec_list is a list of valid substitutions that generate
230 wider representations. These are generally used to specify
231 replacements for instructions whose immediates do not fit their
232 encodings. A valid transition may require multiple steps of
233 one-to-one instruction replacements with a final multiple
234 instruction replacement. As an example, here are the transitions
235 required to replace an 'addi.n' with an 'addi', 'addmi'.
237 addi.n a4, 0x1010
238 => addi a4, 0x1010
239 => addmi a4, 0x1010
240 => addmi a4, 0x1000, addi a4, 0x10.
242 See the comments in xg_assembly_relax for some important details
243 regarding how these chains must be built. */
245 static string_pattern_pair widen_spec_list[] =
247 {"add.n %ar,%as,%at ? IsaUseDensityInstruction", "add %ar,%as,%at"},
248 {"addi.n %ar,%as,%imm ? IsaUseDensityInstruction", "addi %ar,%as,%imm"},
249 {"beqz.n %as,%label ? IsaUseDensityInstruction", "beqz %as,%label"},
250 {"bnez.n %as,%label ? IsaUseDensityInstruction", "bnez %as,%label"},
251 {"l32i.n %at,%as,%imm ? IsaUseDensityInstruction", "l32i %at,%as,%imm"},
252 {"mov.n %at,%as ? IsaUseDensityInstruction", "or %at,%as,%as"},
253 {"movi.n %as,%imm ? IsaUseDensityInstruction", "movi %as,%imm"},
254 {"nop.n ? IsaUseDensityInstruction ? realnop", "nop"},
255 {"nop.n ? IsaUseDensityInstruction ? no-realnop", "or 1,1,1"},
256 {"ret.n %as ? IsaUseDensityInstruction", "ret %as"},
257 {"retw.n %as ? IsaUseDensityInstruction", "retw %as"},
258 {"s32i.n %at,%as,%imm ? IsaUseDensityInstruction", "s32i %at,%as,%imm"},
259 {"srli %at,%as,%imm", "extui %at,%as,%imm,F32MINUS(%imm)"},
260 {"slli %ar,%as,0", "or %ar,%as,%as"},
262 /* Widening with literals or const16. */
263 {"movi %at,%imm ? IsaUseL32R ",
264 "LITERAL %imm; l32r %at,%LITERAL"},
265 {"movi %at,%imm ? IsaUseConst16",
266 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm)"},
268 {"addi %ar,%as,%imm", "addmi %ar,%as,%imm"},
269 /* LOW8 is the low 8 bits of the Immed
270 MID8S is the middle 8 bits of the Immed */
271 {"addmi %ar,%as,%imm", "addmi %ar,%as,HI24S(%imm); addi %ar,%ar,LOW8(%imm)"},
273 /* In the end convert to either an l32r or const16. */
274 {"addmi %ar,%as,%imm | %ar!=%as ? IsaUseL32R",
275 "LITERAL %imm; l32r %ar,%LITERAL; add %ar,%as,%ar"},
276 {"addmi %ar,%as,%imm | %ar!=%as ? IsaUseConst16",
277 "const16 %ar,HI16U(%imm); const16 %ar,LOW16U(%imm); add %ar,%as,%ar"},
279 /* Widening the load instructions with too-large immediates */
280 {"l8ui %at,%as,%imm | %at!=%as ? IsaUseL32R",
281 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l8ui %at,%at,0"},
282 {"l16si %at,%as,%imm | %at!=%as ? IsaUseL32R",
283 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l16si %at,%at,0"},
284 {"l16ui %at,%as,%imm | %at!=%as ? IsaUseL32R",
285 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l16ui %at,%at,0"},
286 {"l32i %at,%as,%imm | %at!=%as ? IsaUseL32R",
287 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l32i %at,%at,0"},
289 /* Widening load instructions with const16s. */
290 {"l8ui %at,%as,%imm | %at!=%as ? IsaUseConst16",
291 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l8ui %at,%at,0"},
292 {"l16si %at,%as,%imm | %at!=%as ? IsaUseConst16",
293 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l16si %at,%at,0"},
294 {"l16ui %at,%as,%imm | %at!=%as ? IsaUseConst16",
295 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l16ui %at,%at,0"},
296 {"l32i %at,%as,%imm | %at!=%as ? IsaUseConst16",
297 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l32i %at,%at,0"},
299 /* Widening loops with literals. */
300 {"loop %as,%label | %as!=1 ? IsaUseLoops ? IsaUseL32R",
301 "loop %as,%LABEL;"
302 "rsr.lend %as;" /* LEND */
303 "wsr.lbeg %as;" /* LBEG */
304 "LITERAL %label;"
305 "l32r %as, %LITERAL;"
306 "nop;"
307 "wsr.lend %as;"
308 "isync;"
309 "rsr.lcount %as;" /* LCOUNT */
310 "addi %as, %as, 1;"
311 "LABEL"},
312 {"loopgtz %as,%label | %as!=1 ? IsaUseLoops ? IsaUseL32R",
313 "beqz %as,%label;"
314 "bltz %as,%label;"
315 "loopgtz %as,%LABEL;"
316 "rsr.lend %as;" /* LEND */
317 "wsr.lbeg %as;" /* LBEG */
318 "LITERAL %label;"
319 "l32r %as, %LITERAL;"
320 "nop;"
321 "wsr.lend %as;"
322 "isync;"
323 "rsr.lcount %as;" /* LCOUNT */
324 "addi %as, %as, 1;"
325 "LABEL"},
326 {"loopnez %as,%label | %as!=1 ? IsaUseLoops ? IsaUseL32R",
327 "beqz %as,%label;"
328 "loopnez %as,%LABEL;"
329 "rsr.lend %as;" /* LEND */
330 "wsr.lbeg %as;" /* LBEG */
331 "LITERAL %label;"
332 "l32r %as, %LITERAL;"
333 "nop;"
334 "wsr.lend %as;"
335 "isync;"
336 "rsr.lcount %as;" /* LCOUNT */
337 "addi %as, %as, 1;"
338 "LABEL"},
340 /* Widening loops with const16. */
341 {"loop %as,%label | %as!=1 ? IsaUseLoops ? IsaUseConst16",
342 "loop %as,%LABEL;"
343 "rsr.lend %as;" /* LEND */
344 "wsr.lbeg %as;" /* LBEG */
345 "const16 %as,HI16U(%label);"
346 "const16 %as,LOW16U(%label);"
347 "wsr.lend %as;"
348 "isync;"
349 "rsr.lcount %as;" /* LCOUNT */
350 "addi %as, %as, 1;"
351 "LABEL"},
352 {"loopgtz %as,%label | %as!=1 ? IsaUseLoops ? IsaUseConst16",
353 "beqz %as,%label;"
354 "bltz %as,%label;"
355 "loopgtz %as,%LABEL;"
356 "rsr.lend %as;" /* LEND */
357 "wsr.lbeg %as;" /* LBEG */
358 "const16 %as,HI16U(%label);"
359 "const16 %as,LOW16U(%label);"
360 "wsr.lend %as;"
361 "isync;"
362 "rsr.lcount %as;" /* LCOUNT */
363 "addi %as, %as, 1;"
364 "LABEL"},
365 {"loopnez %as,%label | %as!=1 ? IsaUseLoops ? IsaUseConst16",
366 "beqz %as,%label;"
367 "loopnez %as,%LABEL;"
368 "rsr.lend %as;" /* LEND */
369 "wsr.lbeg %as;" /* LBEG */
370 "const16 %as,HI16U(%label);"
371 "const16 %as,LOW16U(%label);"
372 "wsr.lend %as;"
373 "isync;"
374 "rsr.lcount %as;" /* LCOUNT */
375 "addi %as, %as, 1;"
376 "LABEL"},
378 /* Relaxing to wide branches. Order is important here. With wide
379 branches, there is more than one correct relaxation for an
380 out-of-range branch. Put the wide branch relaxations first in the
381 table since they are more efficient than the branch-around
382 relaxations. */
384 {"beqz %as,%label ? IsaUseWideBranches", "WIDE.beqz %as,%label"},
385 {"bnez %as,%label ? IsaUseWideBranches", "WIDE.bnez %as,%label"},
386 {"bgez %as,%label ? IsaUseWideBranches", "WIDE.bgez %as,%label"},
387 {"bltz %as,%label ? IsaUseWideBranches", "WIDE.bltz %as,%label"},
388 {"beqi %as,%imm,%label ? IsaUseWideBranches", "WIDE.beqi %as,%imm,%label"},
389 {"bnei %as,%imm,%label ? IsaUseWideBranches", "WIDE.bnei %as,%imm,%label"},
390 {"bgei %as,%imm,%label ? IsaUseWideBranches", "WIDE.bgei %as,%imm,%label"},
391 {"blti %as,%imm,%label ? IsaUseWideBranches", "WIDE.blti %as,%imm,%label"},
392 {"bgeui %as,%imm,%label ? IsaUseWideBranches", "WIDE.bgeui %as,%imm,%label"},
393 {"bltui %as,%imm,%label ? IsaUseWideBranches", "WIDE.bltui %as,%imm,%label"},
394 {"bbci %as,%imm,%label ? IsaUseWideBranches", "WIDE.bbci %as,%imm,%label"},
395 {"bbsi %as,%imm,%label ? IsaUseWideBranches", "WIDE.bbsi %as,%imm,%label"},
396 {"beq %as,%at,%label ? IsaUseWideBranches", "WIDE.beq %as,%at,%label"},
397 {"bne %as,%at,%label ? IsaUseWideBranches", "WIDE.bne %as,%at,%label"},
398 {"bge %as,%at,%label ? IsaUseWideBranches", "WIDE.bge %as,%at,%label"},
399 {"blt %as,%at,%label ? IsaUseWideBranches", "WIDE.blt %as,%at,%label"},
400 {"bgeu %as,%at,%label ? IsaUseWideBranches", "WIDE.bgeu %as,%at,%label"},
401 {"bltu %as,%at,%label ? IsaUseWideBranches", "WIDE.bltu %as,%at,%label"},
402 {"bany %as,%at,%label ? IsaUseWideBranches", "WIDE.bany %as,%at,%label"},
403 {"bnone %as,%at,%label ? IsaUseWideBranches", "WIDE.bnone %as,%at,%label"},
404 {"ball %as,%at,%label ? IsaUseWideBranches", "WIDE.ball %as,%at,%label"},
405 {"bnall %as,%at,%label ? IsaUseWideBranches", "WIDE.bnall %as,%at,%label"},
406 {"bbc %as,%at,%label ? IsaUseWideBranches", "WIDE.bbc %as,%at,%label"},
407 {"bbs %as,%at,%label ? IsaUseWideBranches", "WIDE.bbs %as,%at,%label"},
409 /* Widening branch comparisons eq/ne to zero. Prefer relaxing to narrow
410 branches if the density option is available. */
411 {"beqz %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%LABEL;j %label;LABEL"},
412 {"bnez %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%LABEL;j %label;LABEL"},
413 {"beqz %as,%label", "bnez %as,%LABEL;j %label;LABEL"},
414 {"bnez %as,%label", "beqz %as,%LABEL;j %label;LABEL"},
415 {"WIDE.beqz %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%LABEL;j %label;LABEL"},
416 {"WIDE.bnez %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%LABEL;j %label;LABEL"},
417 {"WIDE.beqz %as,%label", "bnez %as,%LABEL;j %label;LABEL"},
418 {"WIDE.bnez %as,%label", "beqz %as,%LABEL;j %label;LABEL"},
420 /* Widening expect-taken branches. */
421 {"beqzt %as,%label ? IsaUsePredictedBranches", "bnez %as,%LABEL;j %label;LABEL"},
422 {"bnezt %as,%label ? IsaUsePredictedBranches", "beqz %as,%LABEL;j %label;LABEL"},
423 {"beqt %as,%at,%label ? IsaUsePredictedBranches", "bne %as,%at,%LABEL;j %label;LABEL"},
424 {"bnet %as,%at,%label ? IsaUsePredictedBranches", "beq %as,%at,%LABEL;j %label;LABEL"},
426 /* Widening branches from the Xtensa boolean option. */
427 {"bt %bs,%label ? IsaUseBooleans", "bf %bs,%LABEL;j %label;LABEL"},
428 {"bf %bs,%label ? IsaUseBooleans", "bt %bs,%LABEL;j %label;LABEL"},
430 /* Other branch-around-jump widenings. */
431 {"bgez %as,%label", "bltz %as,%LABEL;j %label;LABEL"},
432 {"bltz %as,%label", "bgez %as,%LABEL;j %label;LABEL"},
433 {"beqi %as,%imm,%label", "bnei %as,%imm,%LABEL;j %label;LABEL"},
434 {"bnei %as,%imm,%label", "beqi %as,%imm,%LABEL;j %label;LABEL"},
435 {"bgei %as,%imm,%label", "blti %as,%imm,%LABEL;j %label;LABEL"},
436 {"blti %as,%imm,%label", "bgei %as,%imm,%LABEL;j %label;LABEL"},
437 {"bgeui %as,%imm,%label", "bltui %as,%imm,%LABEL;j %label;LABEL"},
438 {"bltui %as,%imm,%label", "bgeui %as,%imm,%LABEL;j %label;LABEL"},
439 {"bbci %as,%imm,%label", "bbsi %as,%imm,%LABEL;j %label;LABEL"},
440 {"bbsi %as,%imm,%label", "bbci %as,%imm,%LABEL;j %label;LABEL"},
441 {"beq %as,%at,%label", "bne %as,%at,%LABEL;j %label;LABEL"},
442 {"bne %as,%at,%label", "beq %as,%at,%LABEL;j %label;LABEL"},
443 {"bge %as,%at,%label", "blt %as,%at,%LABEL;j %label;LABEL"},
444 {"blt %as,%at,%label", "bge %as,%at,%LABEL;j %label;LABEL"},
445 {"bgeu %as,%at,%label", "bltu %as,%at,%LABEL;j %label;LABEL"},
446 {"bltu %as,%at,%label", "bgeu %as,%at,%LABEL;j %label;LABEL"},
447 {"bany %as,%at,%label", "bnone %as,%at,%LABEL;j %label;LABEL"},
448 {"bnone %as,%at,%label", "bany %as,%at,%LABEL;j %label;LABEL"},
449 {"ball %as,%at,%label", "bnall %as,%at,%LABEL;j %label;LABEL"},
450 {"bnall %as,%at,%label", "ball %as,%at,%LABEL;j %label;LABEL"},
451 {"bbc %as,%at,%label", "bbs %as,%at,%LABEL;j %label;LABEL"},
452 {"bbs %as,%at,%label", "bbc %as,%at,%LABEL;j %label;LABEL"},
454 {"WIDE.bgez %as,%label", "bltz %as,%LABEL;j %label;LABEL"},
455 {"WIDE.bltz %as,%label", "bgez %as,%LABEL;j %label;LABEL"},
456 {"WIDE.beqi %as,%imm,%label", "bnei %as,%imm,%LABEL;j %label;LABEL"},
457 {"WIDE.bnei %as,%imm,%label", "beqi %as,%imm,%LABEL;j %label;LABEL"},
458 {"WIDE.bgei %as,%imm,%label", "blti %as,%imm,%LABEL;j %label;LABEL"},
459 {"WIDE.blti %as,%imm,%label", "bgei %as,%imm,%LABEL;j %label;LABEL"},
460 {"WIDE.bgeui %as,%imm,%label", "bltui %as,%imm,%LABEL;j %label;LABEL"},
461 {"WIDE.bltui %as,%imm,%label", "bgeui %as,%imm,%LABEL;j %label;LABEL"},
462 {"WIDE.bbci %as,%imm,%label", "bbsi %as,%imm,%LABEL;j %label;LABEL"},
463 {"WIDE.bbsi %as,%imm,%label", "bbci %as,%imm,%LABEL;j %label;LABEL"},
464 {"WIDE.beq %as,%at,%label", "bne %as,%at,%LABEL;j %label;LABEL"},
465 {"WIDE.bne %as,%at,%label", "beq %as,%at,%LABEL;j %label;LABEL"},
466 {"WIDE.bge %as,%at,%label", "blt %as,%at,%LABEL;j %label;LABEL"},
467 {"WIDE.blt %as,%at,%label", "bge %as,%at,%LABEL;j %label;LABEL"},
468 {"WIDE.bgeu %as,%at,%label", "bltu %as,%at,%LABEL;j %label;LABEL"},
469 {"WIDE.bltu %as,%at,%label", "bgeu %as,%at,%LABEL;j %label;LABEL"},
470 {"WIDE.bany %as,%at,%label", "bnone %as,%at,%LABEL;j %label;LABEL"},
471 {"WIDE.bnone %as,%at,%label", "bany %as,%at,%LABEL;j %label;LABEL"},
472 {"WIDE.ball %as,%at,%label", "bnall %as,%at,%LABEL;j %label;LABEL"},
473 {"WIDE.bnall %as,%at,%label", "ball %as,%at,%LABEL;j %label;LABEL"},
474 {"WIDE.bbc %as,%at,%label", "bbs %as,%at,%LABEL;j %label;LABEL"},
475 {"WIDE.bbs %as,%at,%label", "bbc %as,%at,%LABEL;j %label;LABEL"},
477 /* Expanding calls with literals. */
478 {"call0 %label,%ar0 ? IsaUseL32R",
479 "LITERAL %label; l32r a0,%LITERAL; callx0 a0,%ar0"},
480 {"call4 %label,%ar4 ? IsaUseL32R",
481 "LITERAL %label; l32r a4,%LITERAL; callx4 a4,%ar4"},
482 {"call8 %label,%ar8 ? IsaUseL32R",
483 "LITERAL %label; l32r a8,%LITERAL; callx8 a8,%ar8"},
484 {"call12 %label,%ar12 ? IsaUseL32R",
485 "LITERAL %label; l32r a12,%LITERAL; callx12 a12,%ar12"},
487 /* Expanding calls with const16. */
488 {"call0 %label,%ar0 ? IsaUseConst16",
489 "const16 a0,HI16U(%label); const16 a0,LOW16U(%label); callx0 a0,%ar0"},
490 {"call4 %label,%ar4 ? IsaUseConst16",
491 "const16 a4,HI16U(%label); const16 a4,LOW16U(%label); callx4 a4,%ar4"},
492 {"call8 %label,%ar8 ? IsaUseConst16",
493 "const16 a8,HI16U(%label); const16 a8,LOW16U(%label); callx8 a8,%ar8"},
494 {"call12 %label,%ar12 ? IsaUseConst16",
495 "const16 a12,HI16U(%label); const16 a12,LOW16U(%label); callx12 a12,%ar12"},
497 /* Expanding j.l with literals. */
498 {"j %label ? FREEREG ? IsaUseL32R",
499 "LITERAL %label; l32r FREEREG,%LITERAL; jx FREEREG"},
500 /* Expanding j.l with const16. */
501 {"j %label ? FREEREG ? IsaUseConst16",
502 "const16 FREEREG,HI16U(%label); const16 FREEREG,LOW16U(%label); jx FREEREG"},
505 #define WIDEN_COUNT (sizeof (widen_spec_list) / sizeof (string_pattern_pair))
508 /* The simplify_spec_list specifies simplifying transformations that
509 will reduce the instruction width or otherwise simplify an
510 instruction. These are usually applied before relaxation in the
511 assembler. It is always legal to simplify. Even for "addi as, 0",
512 the "addi.n as, 0" will eventually be widened back to an "addi 0"
513 after the widening table is applied. Note: The usage of this table
514 has changed somewhat so that it is entirely specific to "narrowing"
515 instructions to use the density option. This table is not used at
516 all when the density option is not available. */
518 string_pattern_pair simplify_spec_list[] =
520 {"add %ar,%as,%at ? IsaUseDensityInstruction", "add.n %ar,%as,%at"},
521 {"addi.n %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"},
522 {"addi %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"},
523 {"addi %ar,%as,%imm ? IsaUseDensityInstruction", "addi.n %ar,%as,%imm"},
524 {"addmi %ar,%as,%imm ? IsaUseDensityInstruction", "addi.n %ar,%as,%imm"},
525 {"beqz %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%label"},
526 {"bnez %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%label"},
527 {"l32i %at,%as,%imm ? IsaUseDensityInstruction", "l32i.n %at,%as,%imm"},
528 {"movi %as,%imm ? IsaUseDensityInstruction", "movi.n %as,%imm"},
529 {"nop ? realnop ? IsaUseDensityInstruction", "nop.n"},
530 {"or %ar,%as,%at | %ar==%as | %as==%at ? IsaUseDensityInstruction", "nop.n"},
531 {"or %ar,%as,%at | %ar!=%as | %as==%at ? IsaUseDensityInstruction", "mov.n %ar,%as"},
532 {"ret %as ? IsaUseDensityInstruction", "ret.n %as"},
533 {"retw %as ? IsaUseDensityInstruction", "retw.n %as"},
534 {"s32i %at,%as,%imm ? IsaUseDensityInstruction", "s32i.n %at,%as,%imm"},
535 {"slli %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"}
538 #define SIMPLIFY_COUNT \
539 (sizeof (simplify_spec_list) / sizeof (string_pattern_pair))
542 /* Externally visible functions. */
544 extern bool xg_has_userdef_op_fn (OpType);
545 extern long xg_apply_userdef_op_fn (OpType, long);
548 static void
549 append_transition (TransitionTable *tt,
550 xtensa_opcode opcode,
551 TransitionRule *t,
552 transition_cmp_fn cmp)
554 TransitionList *tl = XNEW (TransitionList);
555 TransitionList *prev;
556 TransitionList **t_p;
557 gas_assert (tt != NULL);
558 gas_assert (opcode < tt->num_opcodes);
560 prev = tt->table[opcode];
561 tl->rule = t;
562 tl->next = NULL;
563 if (prev == NULL)
565 tt->table[opcode] = tl;
566 return;
569 for (t_p = &tt->table[opcode]; (*t_p) != NULL; t_p = &(*t_p)->next)
571 if (cmp && cmp (t, (*t_p)->rule) < 0)
573 /* Insert it here. */
574 tl->next = *t_p;
575 *t_p = tl;
576 return;
579 (*t_p) = tl;
583 static void
584 append_condition (TransitionRule *tr, Precondition *cond)
586 PreconditionList *pl = XNEW (PreconditionList);
587 PreconditionList *prev = tr->conditions;
588 PreconditionList *nxt;
590 pl->precond = cond;
591 pl->next = NULL;
592 if (prev == NULL)
594 tr->conditions = pl;
595 return;
597 nxt = prev->next;
598 while (nxt != NULL)
600 prev = nxt;
601 nxt = nxt->next;
603 prev->next = pl;
607 static void
608 append_value_condition (TransitionRule *tr,
609 CmpOp cmp,
610 unsigned op1,
611 unsigned op2)
613 Precondition *cond = XNEW (Precondition);
615 cond->cmp = cmp;
616 cond->op_num = op1;
617 cond->typ = OP_OPERAND;
618 cond->op_data = op2;
619 append_condition (tr, cond);
623 static void
624 append_constant_value_condition (TransitionRule *tr,
625 CmpOp cmp,
626 unsigned op1,
627 unsigned cnst)
629 Precondition *cond = XNEW (Precondition);
631 cond->cmp = cmp;
632 cond->op_num = op1;
633 cond->typ = OP_CONSTANT;
634 cond->op_data = cnst;
635 append_condition (tr, cond);
639 static void
640 append_build_insn (TransitionRule *tr, BuildInstr *bi)
642 BuildInstr *prev = tr->to_instr;
643 BuildInstr *nxt;
645 bi->next = NULL;
646 if (prev == NULL)
648 tr->to_instr = bi;
649 return;
651 nxt = prev->next;
652 while (nxt != 0)
654 prev = nxt;
655 nxt = prev->next;
657 prev->next = bi;
661 static void
662 append_op (BuildInstr *bi, BuildOp *b_op)
664 BuildOp *prev = bi->ops;
665 BuildOp *nxt;
667 if (prev == NULL)
669 bi->ops = b_op;
670 return;
672 nxt = prev->next;
673 while (nxt != NULL)
675 prev = nxt;
676 nxt = nxt->next;
678 prev->next = b_op;
682 static void
683 append_literal_op (BuildInstr *bi, unsigned op1, unsigned src_op)
685 BuildOp *b_op = XNEW (BuildOp);
687 b_op->op_num = op1;
688 b_op->typ = OP_LITERAL;
689 b_op->op_data = src_op;
690 b_op->next = NULL;
691 append_op (bi, b_op);
695 static void
696 append_label_op (BuildInstr *bi, unsigned op1)
698 BuildOp *b_op = XNEW (BuildOp);
700 b_op->op_num = op1;
701 b_op->typ = OP_LABEL;
702 b_op->op_data = 0;
703 b_op->next = NULL;
704 append_op (bi, b_op);
708 static void
709 append_constant_op (BuildInstr *bi, unsigned op1, unsigned cnst)
711 BuildOp *b_op = XNEW (BuildOp);
713 b_op->op_num = op1;
714 b_op->typ = OP_CONSTANT;
715 b_op->op_data = cnst;
716 b_op->next = NULL;
717 append_op (bi, b_op);
721 static void
722 append_field_op (BuildInstr *bi, unsigned op1, unsigned src_op)
724 BuildOp *b_op = XNEW (BuildOp);
726 b_op->op_num = op1;
727 b_op->typ = OP_OPERAND;
728 b_op->op_data = src_op;
729 b_op->next = NULL;
730 append_op (bi, b_op);
734 /* These could be generated but are not currently. */
736 static void
737 append_user_fn_field_op (BuildInstr *bi,
738 unsigned op1,
739 OpType typ,
740 unsigned src_op)
742 BuildOp *b_op = XNEW (BuildOp);
744 b_op->op_num = op1;
745 b_op->typ = typ;
746 b_op->op_data = src_op;
747 b_op->next = NULL;
748 append_op (bi, b_op);
752 /* These operand functions are the semantics of user-defined
753 operand functions. */
755 static long
756 operand_function_HI24S (long a)
758 if (a & 0x80)
759 return (a & (~0xff)) + 0x100;
760 else
761 return (a & (~0xff));
765 static long
766 operand_function_F32MINUS (long a)
768 return (32 - a);
772 static long
773 operand_function_LOW8 (long a)
775 if (a & 0x80)
776 return (a & 0xff) | ~0xff;
777 else
778 return (a & 0xff);
782 static long
783 operand_function_LOW16U (long a)
785 return (a & 0xffff);
789 static long
790 operand_function_HI16U (long a)
792 unsigned long b = a & 0xffff0000;
793 return (long) (b >> 16);
797 bool
798 xg_has_userdef_op_fn (OpType op)
800 switch (op)
802 case OP_OPERAND_F32MINUS:
803 case OP_OPERAND_LOW8:
804 case OP_OPERAND_HI24S:
805 case OP_OPERAND_LOW16U:
806 case OP_OPERAND_HI16U:
807 return true;
808 default:
809 break;
811 return false;
815 long
816 xg_apply_userdef_op_fn (OpType op, long a)
818 switch (op)
820 case OP_OPERAND_F32MINUS:
821 return operand_function_F32MINUS (a);
822 case OP_OPERAND_LOW8:
823 return operand_function_LOW8 (a);
824 case OP_OPERAND_HI24S:
825 return operand_function_HI24S (a);
826 case OP_OPERAND_LOW16U:
827 return operand_function_LOW16U (a);
828 case OP_OPERAND_HI16U:
829 return operand_function_HI16U (a);
830 default:
831 break;
833 return false;
837 /* Generate a transition table. */
839 static const char *
840 enter_opname_n (const char *name, int len)
842 opname_e *op;
844 for (op = local_opnames; op != NULL; op = op->next)
846 if (strlen (op->opname) == (unsigned) len
847 && strncmp (op->opname, name, len) == 0)
848 return op->opname;
850 op = XNEW (opname_e);
851 op->opname = xmemdup0 (name, len);
852 return op->opname;
856 static const char *
857 enter_opname (const char *name)
859 opname_e *op;
861 for (op = local_opnames; op != NULL; op = op->next)
863 if (strcmp (op->opname, name) == 0)
864 return op->opname;
866 op = XNEW (opname_e);
867 op->opname = xstrdup (name);
868 return op->opname;
872 static void
873 init_opname_map (opname_map *m)
875 m->head = NULL;
876 m->tail = &m->head;
880 static void
881 clear_opname_map (opname_map *m)
883 opname_map_e *e;
885 while (m->head != NULL)
887 e = m->head;
888 m->head = e->next;
889 free (e);
891 m->tail = &m->head;
895 static bool
896 same_operand_name (const opname_map_e *m1, const opname_map_e *m2)
898 if (m1->operand_name == NULL || m2->operand_name == NULL)
899 return false;
900 return (m1->operand_name == m2->operand_name);
904 static opname_map_e *
905 get_opmatch (opname_map *map, const char *operand_name)
907 opname_map_e *m;
909 for (m = map->head; m != NULL; m = m->next)
911 if (strcmp (m->operand_name, operand_name) == 0)
912 return m;
914 return NULL;
918 static bool
919 op_is_constant (const opname_map_e *m1)
921 return (m1->operand_name == NULL);
925 static unsigned
926 op_get_constant (const opname_map_e *m1)
928 gas_assert (m1->operand_name == NULL);
929 return m1->constant_value;
933 static void
934 init_precond_list (precond_list *l)
936 l->head = NULL;
937 l->tail = &l->head;
941 static void
942 clear_precond_list (precond_list *l)
944 precond_e *e;
946 while (l->head != NULL)
948 e = l->head;
949 l->head = e->next;
950 free (e);
952 l->tail = &l->head;
956 static void
957 init_insn_templ (insn_templ *t)
959 t->opcode_name = NULL;
960 init_opname_map (&t->operand_map);
964 static void
965 clear_insn_templ (insn_templ *t)
967 clear_opname_map (&t->operand_map);
971 static void
972 init_insn_pattern (insn_pattern *p)
974 init_insn_templ (&p->t);
975 init_precond_list (&p->preconds);
976 p->options = NULL;
980 static void
981 clear_insn_pattern (insn_pattern *p)
983 clear_insn_templ (&p->t);
984 clear_precond_list (&p->preconds);
988 static void
989 init_insn_repl (insn_repl *r)
991 r->head = NULL;
992 r->tail = &r->head;
996 static void
997 clear_insn_repl (insn_repl *r)
999 insn_repl_e *e;
1001 while (r->head != NULL)
1003 e = r->head;
1004 r->head = e->next;
1005 clear_insn_templ (&e->t);
1007 r->tail = &r->head;
1011 static int
1012 insn_templ_operand_count (const insn_templ *t)
1014 int i = 0;
1015 const opname_map_e *op;
1017 for (op = t->operand_map.head; op != NULL; op = op->next, i++)
1019 return i;
1023 /* Convert a string to a number. E.G.: parse_constant("10", &num) */
1025 static bool
1026 parse_constant (const char *in, unsigned *val_p)
1028 unsigned val = 0;
1029 const char *p;
1031 if (in == NULL)
1032 return false;
1033 p = in;
1035 while (*p != '\0')
1037 if (*p >= '0' && *p <= '9')
1038 val = val * 10 + (*p - '0');
1039 else
1040 return false;
1041 ++p;
1043 *val_p = val;
1044 return true;
1048 static bool
1049 parse_special_fn (const char *name,
1050 const char **fn_name_p,
1051 const char **arg_name_p)
1053 const char *p_start;
1054 const char *p_end;
1056 p_start = strchr (name, '(');
1057 if (p_start == NULL)
1058 return false;
1060 p_end = strchr (p_start, ')');
1062 if (p_end == NULL)
1063 return false;
1065 if (p_end[1] != '\0')
1066 return false;
1068 *fn_name_p = enter_opname_n (name, p_start - name);
1069 *arg_name_p = enter_opname_n (p_start + 1, p_end - p_start - 1);
1070 return true;
1074 static const char *
1075 skip_white (const char *p)
1077 if (p == NULL)
1078 return p;
1079 while (*p == ' ')
1080 ++p;
1081 return p;
1085 static void
1086 trim_whitespace (char *in)
1088 char *last_white = NULL;
1089 char *p = in;
1091 while (p && *p != '\0')
1093 while (*p == ' ')
1095 if (last_white == NULL)
1096 last_white = p;
1097 p++;
1099 if (*p != '\0')
1101 last_white = NULL;
1102 p++;
1105 if (last_white)
1106 *last_white = '\0';
1110 /* Split a string into component strings where "c" is the
1111 delimiter. Place the result in the split_rec. */
1113 static void
1114 split_string (split_rec *rec,
1115 const char *in,
1116 char c,
1117 bool elide_whitespace)
1119 int cnt = 0;
1120 int i;
1121 const char *p = in;
1123 while (p != NULL && *p != '\0')
1125 cnt++;
1126 p = strchr (p, c);
1127 if (p)
1128 p++;
1130 rec->count = cnt;
1131 rec->vec = NULL;
1133 if (rec->count == 0)
1134 return;
1136 rec->vec = XNEWVEC (char *, cnt);
1137 for (i = 0; i < cnt; i++)
1138 rec->vec[i] = 0;
1140 p = in;
1141 for (i = 0; i < cnt; i++)
1143 const char *q;
1144 int len;
1146 q = p;
1147 if (elide_whitespace)
1148 q = skip_white (q);
1150 p = strchr (q, c);
1151 if (p == NULL)
1152 rec->vec[i] = xstrdup (q);
1153 else
1155 len = p - q;
1156 rec->vec[i] = xmemdup0 (q, len);
1157 p++;
1160 if (elide_whitespace)
1161 trim_whitespace (rec->vec[i]);
1166 static void
1167 clear_split_rec (split_rec *rec)
1169 int i;
1171 for (i = 0; i < rec->count; i++)
1172 free (rec->vec[i]);
1174 if (rec->count > 0)
1175 free (rec->vec);
1179 /* Initialize a split record. The split record must be initialized
1180 before split_string is called. */
1182 static void
1183 init_split_rec (split_rec *rec)
1185 rec->vec = NULL;
1186 rec->count = 0;
1190 /* Parse an instruction template like "insn op1, op2, op3". */
1192 static bool
1193 parse_insn_templ (const char *s, insn_templ *t)
1195 const char *p = s;
1196 int insn_name_len;
1197 split_rec oprec;
1198 int i;
1200 /* First find the first whitespace. */
1202 init_split_rec (&oprec);
1204 p = skip_white (p);
1205 insn_name_len = strcspn (s, " ");
1206 if (insn_name_len == 0)
1207 return false;
1209 init_insn_templ (t);
1210 t->opcode_name = enter_opname_n (p, insn_name_len);
1212 p = p + insn_name_len;
1214 /* Split by ',' and skip beginning and trailing whitespace. */
1215 split_string (&oprec, p, ',', true);
1217 for (i = 0; i < oprec.count; i++)
1219 const char *opname = oprec.vec[i];
1220 opname_map_e *e = XNEW (opname_map_e);
1221 e->next = NULL;
1222 e->operand_name = NULL;
1223 e->constant_value = 0;
1224 e->operand_num = i;
1226 /* If it begins with a number, assume that it is a number. */
1227 if (opname && opname[0] >= '0' && opname[0] <= '9')
1229 unsigned val;
1231 if (parse_constant (opname, &val))
1232 e->constant_value = val;
1233 else
1235 free (e);
1236 clear_split_rec (&oprec);
1237 clear_insn_templ (t);
1238 return false;
1241 else
1242 e->operand_name = enter_opname (oprec.vec[i]);
1244 *t->operand_map.tail = e;
1245 t->operand_map.tail = &e->next;
1247 clear_split_rec (&oprec);
1248 return true;
1252 static bool
1253 parse_precond (const char *s, precond_e *precond)
1255 /* All preconditions are currently of the form:
1256 a == b or a != b or a == k (where k is a constant).
1257 Later we may use some special functions like DENSITY == 1
1258 to identify when density is available. */
1260 const char *p = s;
1261 int len;
1262 precond->opname1 = NULL;
1263 precond->opval1 = 0;
1264 precond->cmpop = OP_EQUAL;
1265 precond->opname2 = NULL;
1266 precond->opval2 = 0;
1267 precond->next = NULL;
1269 p = skip_white (p);
1271 len = strcspn (p, " !=");
1273 if (len == 0)
1274 return false;
1276 precond->opname1 = enter_opname_n (p, len);
1277 p = p + len;
1278 p = skip_white (p);
1280 /* Check for "==" and "!=". */
1281 if (startswith (p, "=="))
1282 precond->cmpop = OP_EQUAL;
1283 else if (startswith (p, "!="))
1284 precond->cmpop = OP_NOTEQUAL;
1285 else
1286 return false;
1288 p = p + 2;
1289 p = skip_white (p);
1291 /* No trailing whitespace from earlier parsing. */
1292 if (p[0] >= '0' && p[0] <= '9')
1294 unsigned val;
1295 if (parse_constant (p, &val))
1296 precond->opval2 = val;
1297 else
1298 return false;
1300 else
1301 precond->opname2 = enter_opname (p);
1302 return true;
1306 static void
1307 clear_req_or_option_list (ReqOrOption **r_p)
1309 if (*r_p == NULL)
1310 return;
1312 free ((*r_p)->option_name);
1313 clear_req_or_option_list (&(*r_p)->next);
1314 *r_p = NULL;
1318 static void
1319 clear_req_option_list (ReqOption **r_p)
1321 if (*r_p == NULL)
1322 return;
1324 clear_req_or_option_list (&(*r_p)->or_option_terms);
1325 clear_req_option_list (&(*r_p)->next);
1326 *r_p = NULL;
1330 static ReqOrOption *
1331 clone_req_or_option_list (ReqOrOption *req_or_option)
1333 ReqOrOption *new_req_or_option;
1335 if (req_or_option == NULL)
1336 return NULL;
1338 new_req_or_option = XNEW (ReqOrOption);
1339 new_req_or_option->option_name = xstrdup (req_or_option->option_name);
1340 new_req_or_option->is_true = req_or_option->is_true;
1341 new_req_or_option->next = NULL;
1342 new_req_or_option->next = clone_req_or_option_list (req_or_option->next);
1343 return new_req_or_option;
1347 static ReqOption *
1348 clone_req_option_list (ReqOption *req_option)
1350 ReqOption *new_req_option;
1352 if (req_option == NULL)
1353 return NULL;
1355 new_req_option = XNEW (ReqOption);
1356 new_req_option->or_option_terms = NULL;
1357 new_req_option->next = NULL;
1358 new_req_option->or_option_terms =
1359 clone_req_or_option_list (req_option->or_option_terms);
1360 new_req_option->next = clone_req_option_list (req_option->next);
1361 return new_req_option;
1365 static bool
1366 parse_option_cond (const char *s, ReqOption *option)
1368 int i;
1369 split_rec option_term_rec;
1371 /* All option or conditions are of the form:
1372 optionA + no-optionB + ...
1373 "Ands" are divided by "?". */
1375 init_split_rec (&option_term_rec);
1376 split_string (&option_term_rec, s, '+', true);
1378 if (option_term_rec.count == 0)
1380 clear_split_rec (&option_term_rec);
1381 return false;
1384 for (i = 0; i < option_term_rec.count; i++)
1386 char *option_name = option_term_rec.vec[i];
1387 bool is_true = true;
1388 ReqOrOption *req;
1389 ReqOrOption **r_p;
1391 if (startswith (option_name, "no-"))
1393 option_name = xstrdup (&option_name[3]);
1394 is_true = false;
1396 else
1397 option_name = xstrdup (option_name);
1399 req = XNEW (ReqOrOption);
1400 req->option_name = option_name;
1401 req->is_true = is_true;
1402 req->next = NULL;
1404 /* Append to list. */
1405 for (r_p = &option->or_option_terms; (*r_p) != NULL;
1406 r_p = &(*r_p)->next)
1408 (*r_p) = req;
1410 return true;
1414 /* Parse a string like:
1415 "insn op1, op2, op3, op4 | op1 != op2 | op2 == op3 | op4 == 1".
1416 I.E., instruction "insn" with 4 operands where operand 1 and 2 are not
1417 the same and operand 2 and 3 are the same and operand 4 is 1.
1421 "insn op1 | op1 == 1 / density + boolean / no-useroption".
1422 i.e. instruction "insn" with 1 operands where operand 1 is 1
1423 when "density" or "boolean" options are available and
1424 "useroption" is not available.
1426 Because the current implementation of this parsing scheme uses
1427 split_string, it requires that '|' and '?' are only used as
1428 delimiters for predicates and required options. */
1430 static bool
1431 parse_insn_pattern (const char *in, insn_pattern *insn)
1433 split_rec rec;
1434 split_rec optionrec;
1435 int i;
1437 init_insn_pattern (insn);
1439 init_split_rec (&optionrec);
1440 split_string (&optionrec, in, '?', true);
1441 if (optionrec.count == 0)
1443 clear_split_rec (&optionrec);
1444 return false;
1447 init_split_rec (&rec);
1449 split_string (&rec, optionrec.vec[0], '|', true);
1451 if (rec.count == 0)
1453 clear_split_rec (&rec);
1454 clear_split_rec (&optionrec);
1455 return false;
1458 if (!parse_insn_templ (rec.vec[0], &insn->t))
1460 clear_split_rec (&rec);
1461 clear_split_rec (&optionrec);
1462 return false;
1465 for (i = 1; i < rec.count; i++)
1467 precond_e *cond = XNEW (precond_e);
1469 if (!parse_precond (rec.vec[i], cond))
1471 clear_split_rec (&rec);
1472 clear_split_rec (&optionrec);
1473 clear_insn_pattern (insn);
1474 return false;
1477 /* Append the condition. */
1478 *insn->preconds.tail = cond;
1479 insn->preconds.tail = &cond->next;
1482 for (i = 1; i < optionrec.count; i++)
1484 /* Handle the option conditions. */
1485 ReqOption **r_p;
1486 ReqOption *req_option = XNEW (ReqOption);
1487 req_option->or_option_terms = NULL;
1488 req_option->next = NULL;
1490 if (!parse_option_cond (optionrec.vec[i], req_option))
1492 clear_split_rec (&rec);
1493 clear_split_rec (&optionrec);
1494 clear_insn_pattern (insn);
1495 clear_req_option_list (&req_option);
1496 return false;
1499 /* Append the condition. */
1500 for (r_p = &insn->options; (*r_p) != NULL; r_p = &(*r_p)->next)
1503 (*r_p) = req_option;
1506 clear_split_rec (&rec);
1507 clear_split_rec (&optionrec);
1508 return true;
1512 static bool
1513 parse_insn_repl (const char *in, insn_repl *r_p)
1515 /* This is a list of instruction templates separated by ';'. */
1516 split_rec rec;
1517 int i;
1519 split_string (&rec, in, ';', true);
1521 for (i = 0; i < rec.count; i++)
1523 insn_repl_e *e = XNEW (insn_repl_e);
1525 e->next = NULL;
1527 if (!parse_insn_templ (rec.vec[i], &e->t))
1529 free (e);
1530 clear_insn_repl (r_p);
1531 return false;
1533 *r_p->tail = e;
1534 r_p->tail = &e->next;
1536 return true;
1540 static bool
1541 transition_applies (insn_pattern *initial_insn,
1542 const char *from_string ATTRIBUTE_UNUSED,
1543 const char *to_string ATTRIBUTE_UNUSED)
1545 ReqOption *req_option;
1547 for (req_option = initial_insn->options;
1548 req_option != NULL;
1549 req_option = req_option->next)
1551 ReqOrOption *req_or_option = req_option->or_option_terms;
1553 if (req_or_option == NULL
1554 || req_or_option->next != NULL)
1555 continue;
1557 if (startswith (req_or_option->option_name, "IsaUse"))
1559 bool option_available = false;
1560 char *option_name = req_or_option->option_name + 6;
1561 if (!strcmp (option_name, "DensityInstruction"))
1562 option_available = (XCHAL_HAVE_DENSITY == 1);
1563 else if (!strcmp (option_name, "L32R"))
1564 option_available = (XCHAL_HAVE_L32R == 1);
1565 else if (!strcmp (option_name, "Const16"))
1566 option_available = (XCHAL_HAVE_CONST16 == 1);
1567 else if (!strcmp (option_name, "Loops"))
1568 option_available = (XCHAL_HAVE_LOOPS == 1);
1569 else if (!strcmp (option_name, "WideBranches"))
1570 option_available
1571 = (XCHAL_HAVE_WIDE_BRANCHES == 1 && produce_flix == FLIX_ALL);
1572 else if (!strcmp (option_name, "PredictedBranches"))
1573 option_available
1574 = (XCHAL_HAVE_PREDICTED_BRANCHES == 1
1575 && produce_flix == FLIX_ALL);
1576 else if (!strcmp (option_name, "Booleans"))
1577 option_available = (XCHAL_HAVE_BOOLEANS == 1);
1578 else
1579 as_warn (_("invalid configuration option '%s' in transition rule '%s'"),
1580 req_or_option->option_name, from_string);
1581 if ((option_available ^ req_or_option->is_true) != 0)
1582 return false;
1584 else if (strcmp (req_or_option->option_name, "realnop") == 0)
1586 bool nop_available =
1587 (xtensa_opcode_lookup (xtensa_default_isa, "nop")
1588 != XTENSA_UNDEFINED);
1589 if ((nop_available ^ req_or_option->is_true) != 0)
1590 return false;
1593 return true;
1597 static bool
1598 wide_branch_opcode (const char *opcode_name,
1599 const char *suffix,
1600 xtensa_opcode *popcode)
1602 xtensa_isa isa = xtensa_default_isa;
1603 xtensa_opcode opcode;
1604 static char wbr_name_buf[20];
1606 if (!startswith (opcode_name, "WIDE."))
1607 return false;
1609 strcpy (wbr_name_buf, opcode_name + 5);
1610 strcat (wbr_name_buf, suffix);
1611 opcode = xtensa_opcode_lookup (isa, wbr_name_buf);
1612 if (opcode != XTENSA_UNDEFINED)
1614 *popcode = opcode;
1615 return true;
1618 return false;
1622 static TransitionRule *
1623 build_transition (insn_pattern *initial_insn,
1624 insn_repl *replace_insns,
1625 const char *from_string,
1626 const char *to_string)
1628 TransitionRule *tr = NULL;
1629 xtensa_opcode opcode;
1630 xtensa_isa isa = xtensa_default_isa;
1631 BuildInstr *literal_bi;
1633 opname_map_e *op1;
1634 opname_map_e *op2;
1636 precond_e *precond;
1637 insn_repl_e *r;
1639 if (!wide_branch_opcode (initial_insn->t.opcode_name, ".w18", &opcode)
1640 && !wide_branch_opcode (initial_insn->t.opcode_name, ".w15", &opcode))
1641 opcode = xtensa_opcode_lookup (isa, initial_insn->t.opcode_name);
1643 if (opcode == XTENSA_UNDEFINED)
1645 /* It is OK to not be able to translate some of these opcodes. */
1646 return NULL;
1650 if (xtensa_opcode_num_operands (isa, opcode)
1651 != insn_templ_operand_count (&initial_insn->t))
1653 /* This is also OK because there are opcodes that
1654 have different numbers of operands on different
1655 architecture variations. */
1656 return NULL;
1659 tr = XNEW (TransitionRule);
1660 tr->opcode = opcode;
1661 tr->conditions = NULL;
1662 tr->to_instr = NULL;
1664 /* Build the conditions. First, equivalent operand condition.... */
1665 for (op1 = initial_insn->t.operand_map.head; op1 != NULL; op1 = op1->next)
1667 for (op2 = op1->next; op2 != NULL; op2 = op2->next)
1669 if (same_operand_name (op1, op2))
1671 append_value_condition (tr, OP_EQUAL,
1672 op1->operand_num, op2->operand_num);
1677 /* Now the condition that an operand value must be a constant.... */
1678 for (op1 = initial_insn->t.operand_map.head; op1 != NULL; op1 = op1->next)
1680 if (op_is_constant (op1))
1682 append_constant_value_condition (tr,
1683 OP_EQUAL,
1684 op1->operand_num,
1685 op_get_constant (op1));
1690 /* Now add the explicit preconditions listed after the "|" in the spec.
1691 These are currently very limited, so we do a special case
1692 parse for them. We expect spaces, opname != opname. */
1693 for (precond = initial_insn->preconds.head;
1694 precond != NULL;
1695 precond = precond->next)
1697 op1 = NULL;
1698 op2 = NULL;
1700 if (precond->opname1)
1702 op1 = get_opmatch (&initial_insn->t.operand_map, precond->opname1);
1703 if (op1 == NULL)
1704 as_fatal (_("opcode '%s': no bound opname '%s' "
1705 "for precondition in '%s'"),
1706 xtensa_opcode_name (isa, opcode),
1707 precond->opname1, from_string);
1710 if (precond->opname2)
1712 op2 = get_opmatch (&initial_insn->t.operand_map, precond->opname2);
1713 if (op2 == NULL)
1714 as_fatal (_("opcode '%s': no bound opname '%s' "
1715 "for precondition in '%s'"),
1716 xtensa_opcode_name (isa, opcode),
1717 precond->opname2, from_string);
1720 if (op1 == NULL && op2 == NULL)
1721 as_fatal (_("opcode '%s': precondition only contains "
1722 "constants in '%s'"),
1723 xtensa_opcode_name (isa, opcode), from_string);
1724 else if (op1 != NULL && op2 != NULL)
1725 append_value_condition (tr, precond->cmpop,
1726 op1->operand_num, op2->operand_num);
1727 else if (op2 == NULL)
1728 append_constant_value_condition (tr, precond->cmpop,
1729 op1->operand_num, precond->opval2);
1730 else
1731 append_constant_value_condition (tr, precond->cmpop,
1732 op2->operand_num, precond->opval1);
1735 tr->options = clone_req_option_list (initial_insn->options);
1737 /* Generate the replacement instructions. Some of these
1738 "instructions" are actually labels and literals. There can be at
1739 most one literal and at most one label. A literal must be defined
1740 (e.g., "LITERAL %imm") before use (e.g., "%LITERAL"). The labels
1741 can be used before they are defined. Also there are a number of
1742 special operands (e.g., HI24S). */
1744 literal_bi = NULL;
1745 for (r = replace_insns->head; r != NULL; r = r->next)
1747 BuildInstr *bi;
1748 const char *opcode_name;
1749 int operand_count;
1750 opname_map_e *op;
1751 const char *fn_name;
1752 const char *operand_arg_name;
1754 bi = XNEW (BuildInstr);
1755 append_build_insn (tr, bi);
1757 bi->opcode = XTENSA_UNDEFINED;
1758 bi->ops = NULL;
1759 bi->next = NULL;
1761 opcode_name = r->t.opcode_name;
1762 operand_count = insn_templ_operand_count (&r->t);
1764 if (strcmp (opcode_name, "LITERAL") == 0)
1766 bi->typ = INSTR_LITERAL_DEF;
1767 if (operand_count != 1)
1768 as_fatal (_("expected one operand for generated literal"));
1769 literal_bi = bi;
1771 else if (strcmp (opcode_name, "LABEL") == 0)
1773 bi->typ = INSTR_LABEL_DEF;
1774 if (operand_count != 0)
1775 as_fatal (_("expected 0 operands for generated label"));
1777 else
1779 bi->typ = INSTR_INSTR;
1780 if (wide_branch_opcode (opcode_name, ".w18", &bi->opcode)
1781 || wide_branch_opcode (opcode_name, ".w15", &bi->opcode))
1782 opcode_name = xtensa_opcode_name (isa, bi->opcode);
1783 else
1784 bi->opcode = xtensa_opcode_lookup (isa, opcode_name);
1786 if (bi->opcode == XTENSA_UNDEFINED)
1788 as_warn (_("invalid opcode '%s' in transition rule '%s'"),
1789 opcode_name, to_string);
1790 return NULL;
1793 /* Check for the right number of ops. */
1794 if (xtensa_opcode_num_operands (isa, bi->opcode)
1795 != (int) operand_count)
1796 as_fatal (ngettext ("opcode '%s': replacement does not have %d op",
1797 "opcode '%s': replacement does not have %d ops",
1798 xtensa_opcode_num_operands (isa, bi->opcode)),
1799 opcode_name,
1800 xtensa_opcode_num_operands (isa, bi->opcode));
1803 for (op = r->t.operand_map.head; op != NULL; op = op->next)
1805 unsigned idnum;
1807 if (op_is_constant (op))
1808 append_constant_op (bi, op->operand_num, op_get_constant (op));
1809 else if (strcmp (op->operand_name, "%LITERAL") == 0)
1811 if (! literal_bi || ! literal_bi->ops || literal_bi->ops->next)
1812 as_fatal (_("opcode '%s': cannot find literal definition"),
1813 opcode_name);
1814 append_literal_op (bi, op->operand_num,
1815 literal_bi->ops->op_data);
1817 else if (strcmp (op->operand_name, "%LABEL") == 0)
1818 append_label_op (bi, op->operand_num);
1819 else if (op->operand_name[0] == 'a'
1820 && parse_constant (op->operand_name + 1, &idnum))
1821 append_constant_op (bi, op->operand_num, idnum);
1822 else if (op->operand_name[0] == '%')
1824 opname_map_e *orig_op;
1825 orig_op = get_opmatch (&initial_insn->t.operand_map,
1826 op->operand_name);
1827 if (orig_op == NULL)
1828 as_fatal (_("opcode '%s': unidentified operand '%s' in '%s'"),
1829 opcode_name, op->operand_name, to_string);
1830 append_field_op (bi, op->operand_num, orig_op->operand_num);
1832 else if (strcmp (op->operand_name, "FREEREG") == 0)
1834 append_user_fn_field_op (bi, op->operand_num, OP_FREEREG, 0);
1836 else if (parse_special_fn (op->operand_name,
1837 &fn_name, &operand_arg_name))
1839 opname_map_e *orig_op;
1840 OpType typ = OP_CONSTANT;
1842 if (strcmp (fn_name, "LOW8") == 0)
1843 typ = OP_OPERAND_LOW8;
1844 else if (strcmp (fn_name, "HI24S") == 0)
1845 typ = OP_OPERAND_HI24S;
1846 else if (strcmp (fn_name, "F32MINUS") == 0)
1847 typ = OP_OPERAND_F32MINUS;
1848 else if (strcmp (fn_name, "LOW16U") == 0)
1849 typ = OP_OPERAND_LOW16U;
1850 else if (strcmp (fn_name, "HI16U") == 0)
1851 typ = OP_OPERAND_HI16U;
1852 else
1853 as_fatal (_("unknown user-defined function %s"), fn_name);
1855 orig_op = get_opmatch (&initial_insn->t.operand_map,
1856 operand_arg_name);
1857 if (orig_op == NULL)
1858 as_fatal (_("opcode '%s': unidentified operand '%s' in '%s'"),
1859 opcode_name, op->operand_name, to_string);
1860 append_user_fn_field_op (bi, op->operand_num,
1861 typ, orig_op->operand_num);
1863 else
1864 as_fatal (_("opcode '%s': could not parse operand '%s' in '%s'"),
1865 opcode_name, op->operand_name, to_string);
1869 return tr;
1873 static TransitionTable *
1874 build_transition_table (const string_pattern_pair *transitions,
1875 int transition_count,
1876 transition_cmp_fn cmp)
1878 TransitionTable *table = NULL;
1879 int num_opcodes = xtensa_isa_num_opcodes (xtensa_default_isa);
1880 int i, tnum;
1882 if (table != NULL)
1883 return table;
1885 /* Otherwise, build it now. */
1886 table = XNEW (TransitionTable);
1887 table->num_opcodes = num_opcodes;
1888 table->table = XNEWVEC (TransitionList *, num_opcodes);
1890 for (i = 0; i < num_opcodes; i++)
1891 table->table[i] = NULL;
1893 for (tnum = 0; tnum < transition_count; tnum++)
1895 const char *from_string = transitions[tnum].pattern;
1896 const char *to_string = transitions[tnum].replacement;
1898 insn_pattern initial_insn;
1899 insn_repl replace_insns;
1900 TransitionRule *tr;
1902 init_insn_pattern (&initial_insn);
1903 if (!parse_insn_pattern (from_string, &initial_insn))
1904 as_fatal (_("could not parse INSN_PATTERN '%s'"), from_string);
1906 init_insn_repl (&replace_insns);
1907 if (!parse_insn_repl (to_string, &replace_insns))
1908 as_fatal (_("could not parse INSN_REPL '%s'"), to_string);
1910 if (transition_applies (&initial_insn, from_string, to_string))
1912 tr = build_transition (&initial_insn, &replace_insns,
1913 from_string, to_string);
1914 if (tr)
1915 append_transition (table, tr->opcode, tr, cmp);
1916 else
1918 #if TENSILICA_DEBUG
1919 as_warn (_("could not build transition for %s => %s"),
1920 from_string, to_string);
1921 #endif
1925 clear_insn_repl (&replace_insns);
1926 clear_insn_pattern (&initial_insn);
1928 return table;
1932 extern TransitionTable *
1933 xg_build_widen_table (transition_cmp_fn cmp)
1935 static TransitionTable *table = NULL;
1936 if (table == NULL)
1937 table = build_transition_table (widen_spec_list, WIDEN_COUNT, cmp);
1938 return table;
1942 extern TransitionTable *
1943 xg_build_simplify_table (transition_cmp_fn cmp)
1945 static TransitionTable *table = NULL;
1946 if (table == NULL)
1947 table = build_transition_table (simplify_spec_list, SIMPLIFY_COUNT, cmp);
1948 return table;