PR 11225
[binutils/dougsmingw.git] / gas / config / xtensa-relax.c
blob681369e598f247cc89d3b9b2eca0848aca00d448
1 /* Table of relaxations for Xtensa assembly.
2 Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009
3 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
22 /* This file contains the code for generating runtime data structures
23 for relaxation pattern matching from statically specified strings.
24 Each action contains an instruction pattern to match and
25 preconditions for the match as well as an expansion if the pattern
26 matches. The preconditions can specify that two operands are the
27 same or an operand is a specific constant or register. The expansion
28 uses the bound variables from the pattern to specify that specific
29 operands from the pattern should be used in the result.
31 The code determines whether the condition applies to a constant or
32 a register depending on the type of the operand. You may get
33 unexpected results if you don't match the rule against the operand
34 type correctly.
36 The patterns match a language like:
38 INSN_PATTERN ::= INSN_TEMPL ( '|' PRECOND )* ( '?' OPTIONPRED )*
39 INSN_TEMPL ::= OPCODE ' ' [ OPERAND (',' OPERAND)* ]
40 OPCODE ::= id
41 OPERAND ::= CONSTANT | VARIABLE | SPECIALFN '(' VARIABLE ')'
42 SPECIALFN ::= 'HI24S' | 'F32MINUS' | 'LOW8'
43 | 'HI16' | 'LOW16'
44 VARIABLE ::= '%' id
45 PRECOND ::= OPERAND CMPOP OPERAND
46 CMPOP ::= '==' | '!='
47 OPTIONPRED ::= OPTIONNAME ('+' OPTIONNAME)
48 OPTIONNAME ::= '"' id '"'
50 The replacement language
51 INSN_REPL ::= INSN_LABEL_LIT ( ';' INSN_LABEL_LIT )*
52 INSN_LABEL_LIT ::= INSN_TEMPL
53 | 'LABEL'
54 | 'LITERAL' VARIABLE
56 The operands in a PRECOND must be constants or variables bound by
57 the INSN_PATTERN.
59 The configuration options define a predicate on the availability of
60 options which must be TRUE for this rule to be valid. Examples are
61 requiring "density" for replacements with density instructions,
62 requiring "const16" for replacements that require const16
63 instructions, etc. The names are interpreted by the assembler to a
64 truth value for a particular frag.
66 The operands in the INSN_REPL must be constants, variables bound in
67 the associated INSN_PATTERN, special variables that are bound in
68 the INSN_REPL by LABEL or LITERAL definitions, or special value
69 manipulation functions.
71 A simple example of a replacement pattern:
72 {"movi.n %as,%imm", "movi %as,%imm"} would convert the narrow
73 movi.n instruction to the wide movi instruction.
75 A more complex example of a branch around:
76 {"beqz %as,%label", "bnez %as,%LABEL;j %label;LABEL"}
77 would convert a branch to a negated branch to the following instruction
78 with a jump to the original label.
80 An Xtensa-specific example that generates a literal:
81 {"movi %at,%imm", "LITERAL %imm; l32r %at,%LITERAL"}
82 will convert a movi instruction to an l32r of a literal
83 literal defined in the literal pool.
85 Even more complex is a conversion of a load with immediate offset
86 to a load of a freshly generated literal, an explicit add and
87 a load with 0 offset. This transformation is only valid, though
88 when the first and second operands are not the same as specified
89 by the "| %at!=%as" precondition clause.
90 {"l32i %at,%as,%imm | %at!=%as",
91 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l32i %at,%at,0"}
93 There is special case for loop instructions here, but because we do
94 not currently have the ability to represent the difference of two
95 symbols, the conversion requires special code in the assembler to
96 write the operands of the addi/addmi pair representing the
97 difference of the old and new loop end label. */
99 #include "as.h"
100 #include "xtensa-isa.h"
101 #include "xtensa-relax.h"
102 #include <stddef.h>
103 #include "xtensa-config.h"
105 #ifndef XCHAL_HAVE_WIDE_BRANCHES
106 #define XCHAL_HAVE_WIDE_BRANCHES 0
107 #endif
109 /* Imported from bfd. */
110 extern xtensa_isa xtensa_default_isa;
112 /* The opname_list is a small list of names that we use for opcode and
113 operand variable names to simplify ownership of these commonly used
114 strings. Strings entered in the table can be compared by pointer
115 equality. */
117 typedef struct opname_list_struct opname_list;
118 typedef opname_list opname_e;
120 struct opname_list_struct
122 char *opname;
123 opname_list *next;
126 static opname_list *local_opnames = NULL;
129 /* The "opname_map" and its element structure "opname_map_e" are used
130 for binding an operand number to a name or a constant. */
132 typedef struct opname_map_e_struct opname_map_e;
133 typedef struct opname_map_struct opname_map;
135 struct opname_map_e_struct
137 const char *operand_name; /* If null, then use constant_value. */
138 int operand_num;
139 unsigned constant_value;
140 opname_map_e *next;
143 struct opname_map_struct
145 opname_map_e *head;
146 opname_map_e **tail;
149 /* The "precond_list" and its element structure "precond_e" represents
150 explicit preconditions comparing operand variables and constants.
151 In the "precond_e" structure, a variable is identified by the name
152 in the "opname" field. If that field is NULL, then the operand
153 is the constant in field "opval". */
155 typedef struct precond_e_struct precond_e;
156 typedef struct precond_list_struct precond_list;
158 struct precond_e_struct
160 const char *opname1;
161 unsigned opval1;
162 CmpOp cmpop;
163 const char *opname2;
164 unsigned opval2;
165 precond_e *next;
168 struct precond_list_struct
170 precond_e *head;
171 precond_e **tail;
175 /* The insn_templ represents the INSN_TEMPL instruction template. It
176 is an opcode name with a list of operands. These are used for
177 instruction patterns and replacement patterns. */
179 typedef struct insn_templ_struct insn_templ;
180 struct insn_templ_struct
182 const char *opcode_name;
183 opname_map operand_map;
187 /* The insn_pattern represents an INSN_PATTERN instruction pattern.
188 It is an instruction template with preconditions that specify when
189 it actually matches a given instruction. */
191 typedef struct insn_pattern_struct insn_pattern;
192 struct insn_pattern_struct
194 insn_templ t;
195 precond_list preconds;
196 ReqOptionList *options;
200 /* The "insn_repl" and associated element structure "insn_repl_e"
201 instruction replacement list is a list of
202 instructions/LITERALS/LABELS with constant operands or operands
203 with names bound to the operand names in the associated pattern. */
205 typedef struct insn_repl_e_struct insn_repl_e;
206 struct insn_repl_e_struct
208 insn_templ t;
209 insn_repl_e *next;
212 typedef struct insn_repl_struct insn_repl;
213 struct insn_repl_struct
215 insn_repl_e *head;
216 insn_repl_e **tail;
220 /* The split_rec is a vector of allocated char * pointers. */
222 typedef struct split_rec_struct split_rec;
223 struct split_rec_struct
225 char **vec;
226 int count;
229 /* The "string_pattern_pair" is a set of pairs containing instruction
230 patterns and replacement strings. */
232 typedef struct string_pattern_pair_struct string_pattern_pair;
233 struct string_pattern_pair_struct
235 const char *pattern;
236 const char *replacement;
240 /* The widen_spec_list is a list of valid substitutions that generate
241 wider representations. These are generally used to specify
242 replacements for instructions whose immediates do not fit their
243 encodings. A valid transition may require multiple steps of
244 one-to-one instruction replacements with a final multiple
245 instruction replacement. As an example, here are the transitions
246 required to replace an 'addi.n' with an 'addi', 'addmi'.
248 addi.n a4, 0x1010
249 => addi a4, 0x1010
250 => addmi a4, 0x1010
251 => addmi a4, 0x1000, addi a4, 0x10.
253 See the comments in xg_assembly_relax for some important details
254 regarding how these chains must be built. */
256 static string_pattern_pair widen_spec_list[] =
258 {"add.n %ar,%as,%at ? IsaUseDensityInstruction", "add %ar,%as,%at"},
259 {"addi.n %ar,%as,%imm ? IsaUseDensityInstruction", "addi %ar,%as,%imm"},
260 {"beqz.n %as,%label ? IsaUseDensityInstruction", "beqz %as,%label"},
261 {"bnez.n %as,%label ? IsaUseDensityInstruction", "bnez %as,%label"},
262 {"l32i.n %at,%as,%imm ? IsaUseDensityInstruction", "l32i %at,%as,%imm"},
263 {"mov.n %at,%as ? IsaUseDensityInstruction", "or %at,%as,%as"},
264 {"movi.n %as,%imm ? IsaUseDensityInstruction", "movi %as,%imm"},
265 {"nop.n ? IsaUseDensityInstruction ? realnop", "nop"},
266 {"nop.n ? IsaUseDensityInstruction ? no-realnop", "or 1,1,1"},
267 {"ret.n %as ? IsaUseDensityInstruction", "ret %as"},
268 {"retw.n %as ? IsaUseDensityInstruction", "retw %as"},
269 {"s32i.n %at,%as,%imm ? IsaUseDensityInstruction", "s32i %at,%as,%imm"},
270 {"srli %at,%as,%imm", "extui %at,%as,%imm,F32MINUS(%imm)"},
271 {"slli %ar,%as,0", "or %ar,%as,%as"},
273 /* Widening with literals or const16. */
274 {"movi %at,%imm ? IsaUseL32R ",
275 "LITERAL %imm; l32r %at,%LITERAL"},
276 {"movi %at,%imm ? IsaUseConst16",
277 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm)"},
279 {"addi %ar,%as,%imm", "addmi %ar,%as,%imm"},
280 /* LOW8 is the low 8 bits of the Immed
281 MID8S is the middle 8 bits of the Immed */
282 {"addmi %ar,%as,%imm", "addmi %ar,%as,HI24S(%imm); addi %ar,%ar,LOW8(%imm)"},
284 /* In the end convert to either an l32r or const16. */
285 {"addmi %ar,%as,%imm | %ar!=%as ? IsaUseL32R",
286 "LITERAL %imm; l32r %ar,%LITERAL; add %ar,%as,%ar"},
287 {"addmi %ar,%as,%imm | %ar!=%as ? IsaUseConst16",
288 "const16 %ar,HI16U(%imm); const16 %ar,LOW16U(%imm); add %ar,%as,%ar"},
290 /* Widening the load instructions with too-large immediates */
291 {"l8ui %at,%as,%imm | %at!=%as ? IsaUseL32R",
292 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l8ui %at,%at,0"},
293 {"l16si %at,%as,%imm | %at!=%as ? IsaUseL32R",
294 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l16si %at,%at,0"},
295 {"l16ui %at,%as,%imm | %at!=%as ? IsaUseL32R",
296 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l16ui %at,%at,0"},
297 {"l32i %at,%as,%imm | %at!=%as ? IsaUseL32R",
298 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l32i %at,%at,0"},
300 /* Widening load instructions with const16s. */
301 {"l8ui %at,%as,%imm | %at!=%as ? IsaUseConst16",
302 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l8ui %at,%at,0"},
303 {"l16si %at,%as,%imm | %at!=%as ? IsaUseConst16",
304 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l16si %at,%at,0"},
305 {"l16ui %at,%as,%imm | %at!=%as ? IsaUseConst16",
306 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l16ui %at,%at,0"},
307 {"l32i %at,%as,%imm | %at!=%as ? IsaUseConst16",
308 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l32i %at,%at,0"},
310 /* This is only PART of the loop instruction. In addition,
311 hardcoded into its use is a modification of the final operand in
312 the instruction in bytes 9 and 12. */
313 {"loop %as,%label | %as!=1 ? IsaUseLoops",
314 "loop %as,%LABEL;"
315 "rsr.lend %as;" /* LEND */
316 "wsr.lbeg %as;" /* LBEG */
317 "addi %as, %as, 0;" /* lo8(%label-%LABEL1) */
318 "addmi %as, %as, 0;" /* mid8(%label-%LABEL1) */
319 "wsr.lend %as;"
320 "isync;"
321 "rsr.lcount %as;" /* LCOUNT */
322 "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */
323 "LABEL"},
324 {"loopgtz %as,%label | %as!=1 ? IsaUseLoops",
325 "beqz %as,%label;"
326 "bltz %as,%label;"
327 "loopgtz %as,%LABEL;"
328 "rsr.lend %as;" /* LEND */
329 "wsr.lbeg %as;" /* LBEG */
330 "addi %as, %as, 0;" /* lo8(%label-%LABEL1) */
331 "addmi %as, %as, 0;" /* mid8(%label-%LABEL1) */
332 "wsr.lend %as;"
333 "isync;"
334 "rsr.lcount %as;" /* LCOUNT */
335 "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */
336 "LABEL"},
337 {"loopnez %as,%label | %as!=1 ? IsaUseLoops",
338 "beqz %as,%label;"
339 "loopnez %as,%LABEL;"
340 "rsr.lend %as;" /* LEND */
341 "wsr.lbeg %as;" /* LBEG */
342 "addi %as, %as, 0;" /* lo8(%label-%LABEL1) */
343 "addmi %as, %as, 0;" /* mid8(%label-%LABEL1) */
344 "wsr.lend %as;"
345 "isync;"
346 "rsr.lcount %as;" /* LCOUNT */
347 "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */
348 "LABEL"},
350 /* Relaxing to wide branches. Order is important here. With wide
351 branches, there is more than one correct relaxation for an
352 out-of-range branch. Put the wide branch relaxations first in the
353 table since they are more efficient than the branch-around
354 relaxations. */
356 {"beqz %as,%label ? IsaUseWideBranches", "WIDE.beqz %as,%label"},
357 {"bnez %as,%label ? IsaUseWideBranches", "WIDE.bnez %as,%label"},
358 {"bgez %as,%label ? IsaUseWideBranches", "WIDE.bgez %as,%label"},
359 {"bltz %as,%label ? IsaUseWideBranches", "WIDE.bltz %as,%label"},
360 {"beqi %as,%imm,%label ? IsaUseWideBranches", "WIDE.beqi %as,%imm,%label"},
361 {"bnei %as,%imm,%label ? IsaUseWideBranches", "WIDE.bnei %as,%imm,%label"},
362 {"bgei %as,%imm,%label ? IsaUseWideBranches", "WIDE.bgei %as,%imm,%label"},
363 {"blti %as,%imm,%label ? IsaUseWideBranches", "WIDE.blti %as,%imm,%label"},
364 {"bgeui %as,%imm,%label ? IsaUseWideBranches", "WIDE.bgeui %as,%imm,%label"},
365 {"bltui %as,%imm,%label ? IsaUseWideBranches", "WIDE.bltui %as,%imm,%label"},
366 {"bbci %as,%imm,%label ? IsaUseWideBranches", "WIDE.bbci %as,%imm,%label"},
367 {"bbsi %as,%imm,%label ? IsaUseWideBranches", "WIDE.bbsi %as,%imm,%label"},
368 {"beq %as,%at,%label ? IsaUseWideBranches", "WIDE.beq %as,%at,%label"},
369 {"bne %as,%at,%label ? IsaUseWideBranches", "WIDE.bne %as,%at,%label"},
370 {"bge %as,%at,%label ? IsaUseWideBranches", "WIDE.bge %as,%at,%label"},
371 {"blt %as,%at,%label ? IsaUseWideBranches", "WIDE.blt %as,%at,%label"},
372 {"bgeu %as,%at,%label ? IsaUseWideBranches", "WIDE.bgeu %as,%at,%label"},
373 {"bltu %as,%at,%label ? IsaUseWideBranches", "WIDE.bltu %as,%at,%label"},
374 {"bany %as,%at,%label ? IsaUseWideBranches", "WIDE.bany %as,%at,%label"},
375 {"bnone %as,%at,%label ? IsaUseWideBranches", "WIDE.bnone %as,%at,%label"},
376 {"ball %as,%at,%label ? IsaUseWideBranches", "WIDE.ball %as,%at,%label"},
377 {"bnall %as,%at,%label ? IsaUseWideBranches", "WIDE.bnall %as,%at,%label"},
378 {"bbc %as,%at,%label ? IsaUseWideBranches", "WIDE.bbc %as,%at,%label"},
379 {"bbs %as,%at,%label ? IsaUseWideBranches", "WIDE.bbs %as,%at,%label"},
381 /* Widening branch comparisons eq/ne to zero. Prefer relaxing to narrow
382 branches if the density option is available. */
383 {"beqz %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%LABEL;j %label;LABEL"},
384 {"bnez %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%LABEL;j %label;LABEL"},
385 {"beqz %as,%label", "bnez %as,%LABEL;j %label;LABEL"},
386 {"bnez %as,%label", "beqz %as,%LABEL;j %label;LABEL"},
387 {"WIDE.beqz %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%LABEL;j %label;LABEL"},
388 {"WIDE.bnez %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%LABEL;j %label;LABEL"},
389 {"WIDE.beqz %as,%label", "bnez %as,%LABEL;j %label;LABEL"},
390 {"WIDE.bnez %as,%label", "beqz %as,%LABEL;j %label;LABEL"},
392 /* Widening expect-taken branches. */
393 {"beqzt %as,%label ? IsaUsePredictedBranches", "bnez %as,%LABEL;j %label;LABEL"},
394 {"bnezt %as,%label ? IsaUsePredictedBranches", "beqz %as,%LABEL;j %label;LABEL"},
395 {"beqt %as,%at,%label ? IsaUsePredictedBranches", "bne %as,%at,%LABEL;j %label;LABEL"},
396 {"bnet %as,%at,%label ? IsaUsePredictedBranches", "beq %as,%at,%LABEL;j %label;LABEL"},
398 /* Widening branches from the Xtensa boolean option. */
399 {"bt %bs,%label ? IsaUseBooleans", "bf %bs,%LABEL;j %label;LABEL"},
400 {"bf %bs,%label ? IsaUseBooleans", "bt %bs,%LABEL;j %label;LABEL"},
402 /* Other branch-around-jump widenings. */
403 {"bgez %as,%label", "bltz %as,%LABEL;j %label;LABEL"},
404 {"bltz %as,%label", "bgez %as,%LABEL;j %label;LABEL"},
405 {"beqi %as,%imm,%label", "bnei %as,%imm,%LABEL;j %label;LABEL"},
406 {"bnei %as,%imm,%label", "beqi %as,%imm,%LABEL;j %label;LABEL"},
407 {"bgei %as,%imm,%label", "blti %as,%imm,%LABEL;j %label;LABEL"},
408 {"blti %as,%imm,%label", "bgei %as,%imm,%LABEL;j %label;LABEL"},
409 {"bgeui %as,%imm,%label", "bltui %as,%imm,%LABEL;j %label;LABEL"},
410 {"bltui %as,%imm,%label", "bgeui %as,%imm,%LABEL;j %label;LABEL"},
411 {"bbci %as,%imm,%label", "bbsi %as,%imm,%LABEL;j %label;LABEL"},
412 {"bbsi %as,%imm,%label", "bbci %as,%imm,%LABEL;j %label;LABEL"},
413 {"beq %as,%at,%label", "bne %as,%at,%LABEL;j %label;LABEL"},
414 {"bne %as,%at,%label", "beq %as,%at,%LABEL;j %label;LABEL"},
415 {"bge %as,%at,%label", "blt %as,%at,%LABEL;j %label;LABEL"},
416 {"blt %as,%at,%label", "bge %as,%at,%LABEL;j %label;LABEL"},
417 {"bgeu %as,%at,%label", "bltu %as,%at,%LABEL;j %label;LABEL"},
418 {"bltu %as,%at,%label", "bgeu %as,%at,%LABEL;j %label;LABEL"},
419 {"bany %as,%at,%label", "bnone %as,%at,%LABEL;j %label;LABEL"},
420 {"bnone %as,%at,%label", "bany %as,%at,%LABEL;j %label;LABEL"},
421 {"ball %as,%at,%label", "bnall %as,%at,%LABEL;j %label;LABEL"},
422 {"bnall %as,%at,%label", "ball %as,%at,%LABEL;j %label;LABEL"},
423 {"bbc %as,%at,%label", "bbs %as,%at,%LABEL;j %label;LABEL"},
424 {"bbs %as,%at,%label", "bbc %as,%at,%LABEL;j %label;LABEL"},
426 {"WIDE.bgez %as,%label", "bltz %as,%LABEL;j %label;LABEL"},
427 {"WIDE.bltz %as,%label", "bgez %as,%LABEL;j %label;LABEL"},
428 {"WIDE.beqi %as,%imm,%label", "bnei %as,%imm,%LABEL;j %label;LABEL"},
429 {"WIDE.bnei %as,%imm,%label", "beqi %as,%imm,%LABEL;j %label;LABEL"},
430 {"WIDE.bgei %as,%imm,%label", "blti %as,%imm,%LABEL;j %label;LABEL"},
431 {"WIDE.blti %as,%imm,%label", "bgei %as,%imm,%LABEL;j %label;LABEL"},
432 {"WIDE.bgeui %as,%imm,%label", "bltui %as,%imm,%LABEL;j %label;LABEL"},
433 {"WIDE.bltui %as,%imm,%label", "bgeui %as,%imm,%LABEL;j %label;LABEL"},
434 {"WIDE.bbci %as,%imm,%label", "bbsi %as,%imm,%LABEL;j %label;LABEL"},
435 {"WIDE.bbsi %as,%imm,%label", "bbci %as,%imm,%LABEL;j %label;LABEL"},
436 {"WIDE.beq %as,%at,%label", "bne %as,%at,%LABEL;j %label;LABEL"},
437 {"WIDE.bne %as,%at,%label", "beq %as,%at,%LABEL;j %label;LABEL"},
438 {"WIDE.bge %as,%at,%label", "blt %as,%at,%LABEL;j %label;LABEL"},
439 {"WIDE.blt %as,%at,%label", "bge %as,%at,%LABEL;j %label;LABEL"},
440 {"WIDE.bgeu %as,%at,%label", "bltu %as,%at,%LABEL;j %label;LABEL"},
441 {"WIDE.bltu %as,%at,%label", "bgeu %as,%at,%LABEL;j %label;LABEL"},
442 {"WIDE.bany %as,%at,%label", "bnone %as,%at,%LABEL;j %label;LABEL"},
443 {"WIDE.bnone %as,%at,%label", "bany %as,%at,%LABEL;j %label;LABEL"},
444 {"WIDE.ball %as,%at,%label", "bnall %as,%at,%LABEL;j %label;LABEL"},
445 {"WIDE.bnall %as,%at,%label", "ball %as,%at,%LABEL;j %label;LABEL"},
446 {"WIDE.bbc %as,%at,%label", "bbs %as,%at,%LABEL;j %label;LABEL"},
447 {"WIDE.bbs %as,%at,%label", "bbc %as,%at,%LABEL;j %label;LABEL"},
449 /* Expanding calls with literals. */
450 {"call0 %label,%ar0 ? IsaUseL32R",
451 "LITERAL %label; l32r a0,%LITERAL; callx0 a0,%ar0"},
452 {"call4 %label,%ar4 ? IsaUseL32R",
453 "LITERAL %label; l32r a4,%LITERAL; callx4 a4,%ar4"},
454 {"call8 %label,%ar8 ? IsaUseL32R",
455 "LITERAL %label; l32r a8,%LITERAL; callx8 a8,%ar8"},
456 {"call12 %label,%ar12 ? IsaUseL32R",
457 "LITERAL %label; l32r a12,%LITERAL; callx12 a12,%ar12"},
459 /* Expanding calls with const16. */
460 {"call0 %label,%ar0 ? IsaUseConst16",
461 "const16 a0,HI16U(%label); const16 a0,LOW16U(%label); callx0 a0,%ar0"},
462 {"call4 %label,%ar4 ? IsaUseConst16",
463 "const16 a4,HI16U(%label); const16 a4,LOW16U(%label); callx4 a4,%ar4"},
464 {"call8 %label,%ar8 ? IsaUseConst16",
465 "const16 a8,HI16U(%label); const16 a8,LOW16U(%label); callx8 a8,%ar8"},
466 {"call12 %label,%ar12 ? IsaUseConst16",
467 "const16 a12,HI16U(%label); const16 a12,LOW16U(%label); callx12 a12,%ar12"},
469 /* Expanding j.l with literals. */
470 {"j %label ? FREEREG ? IsaUseL32R",
471 "LITERAL %label; l32r FREEREG,%LITERAL; jx FREEREG"},
472 /* Expanding j.l with const16. */
473 {"j %label ? FREEREG ? IsaUseConst16",
474 "const16 FREEREG,HI16U(%label); const16 FREEREG,LOW16U(%label); jx FREEREG"},
477 #define WIDEN_COUNT (sizeof (widen_spec_list) / sizeof (string_pattern_pair))
480 /* The simplify_spec_list specifies simplifying transformations that
481 will reduce the instruction width or otherwise simplify an
482 instruction. These are usually applied before relaxation in the
483 assembler. It is always legal to simplify. Even for "addi as, 0",
484 the "addi.n as, 0" will eventually be widened back to an "addi 0"
485 after the widening table is applied. Note: The usage of this table
486 has changed somewhat so that it is entirely specific to "narrowing"
487 instructions to use the density option. This table is not used at
488 all when the density option is not available. */
490 string_pattern_pair simplify_spec_list[] =
492 {"add %ar,%as,%at ? IsaUseDensityInstruction", "add.n %ar,%as,%at"},
493 {"addi.n %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"},
494 {"addi %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"},
495 {"addi %ar,%as,%imm ? IsaUseDensityInstruction", "addi.n %ar,%as,%imm"},
496 {"addmi %ar,%as,%imm ? IsaUseDensityInstruction", "addi.n %ar,%as,%imm"},
497 {"beqz %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%label"},
498 {"bnez %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%label"},
499 {"l32i %at,%as,%imm ? IsaUseDensityInstruction", "l32i.n %at,%as,%imm"},
500 {"movi %as,%imm ? IsaUseDensityInstruction", "movi.n %as,%imm"},
501 {"nop ? realnop ? IsaUseDensityInstruction", "nop.n"},
502 {"or %ar,%as,%at | %ar==%as | %as==%at ? IsaUseDensityInstruction", "nop.n"},
503 {"or %ar,%as,%at | %ar!=%as | %as==%at ? IsaUseDensityInstruction", "mov.n %ar,%as"},
504 {"ret %as ? IsaUseDensityInstruction", "ret.n %as"},
505 {"retw %as ? IsaUseDensityInstruction", "retw.n %as"},
506 {"s32i %at,%as,%imm ? IsaUseDensityInstruction", "s32i.n %at,%as,%imm"},
507 {"slli %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"}
510 #define SIMPLIFY_COUNT \
511 (sizeof (simplify_spec_list) / sizeof (string_pattern_pair))
514 /* Externally visible functions. */
516 extern bfd_boolean xg_has_userdef_op_fn (OpType);
517 extern long xg_apply_userdef_op_fn (OpType, long);
520 static void
521 append_transition (TransitionTable *tt,
522 xtensa_opcode opcode,
523 TransitionRule *t,
524 transition_cmp_fn cmp)
526 TransitionList *tl = (TransitionList *) xmalloc (sizeof (TransitionList));
527 TransitionList *prev;
528 TransitionList **t_p;
529 gas_assert (tt != NULL);
530 gas_assert (opcode < tt->num_opcodes);
532 prev = tt->table[opcode];
533 tl->rule = t;
534 tl->next = NULL;
535 if (prev == NULL)
537 tt->table[opcode] = tl;
538 return;
541 for (t_p = &tt->table[opcode]; (*t_p) != NULL; t_p = &(*t_p)->next)
543 if (cmp && cmp (t, (*t_p)->rule) < 0)
545 /* Insert it here. */
546 tl->next = *t_p;
547 *t_p = tl;
548 return;
551 (*t_p) = tl;
555 static void
556 append_condition (TransitionRule *tr, Precondition *cond)
558 PreconditionList *pl =
559 (PreconditionList *) xmalloc (sizeof (PreconditionList));
560 PreconditionList *prev = tr->conditions;
561 PreconditionList *nxt;
563 pl->precond = cond;
564 pl->next = NULL;
565 if (prev == NULL)
567 tr->conditions = pl;
568 return;
570 nxt = prev->next;
571 while (nxt != NULL)
573 prev = nxt;
574 nxt = nxt->next;
576 prev->next = pl;
580 static void
581 append_value_condition (TransitionRule *tr,
582 CmpOp cmp,
583 unsigned op1,
584 unsigned op2)
586 Precondition *cond = (Precondition *) xmalloc (sizeof (Precondition));
588 cond->cmp = cmp;
589 cond->op_num = op1;
590 cond->typ = OP_OPERAND;
591 cond->op_data = op2;
592 append_condition (tr, cond);
596 static void
597 append_constant_value_condition (TransitionRule *tr,
598 CmpOp cmp,
599 unsigned op1,
600 unsigned cnst)
602 Precondition *cond = (Precondition *) xmalloc (sizeof (Precondition));
604 cond->cmp = cmp;
605 cond->op_num = op1;
606 cond->typ = OP_CONSTANT;
607 cond->op_data = cnst;
608 append_condition (tr, cond);
612 static void
613 append_build_insn (TransitionRule *tr, BuildInstr *bi)
615 BuildInstr *prev = tr->to_instr;
616 BuildInstr *nxt;
618 bi->next = NULL;
619 if (prev == NULL)
621 tr->to_instr = bi;
622 return;
624 nxt = prev->next;
625 while (nxt != 0)
627 prev = nxt;
628 nxt = prev->next;
630 prev->next = bi;
634 static void
635 append_op (BuildInstr *bi, BuildOp *b_op)
637 BuildOp *prev = bi->ops;
638 BuildOp *nxt;
640 if (prev == NULL)
642 bi->ops = b_op;
643 return;
645 nxt = prev->next;
646 while (nxt != NULL)
648 prev = nxt;
649 nxt = nxt->next;
651 prev->next = b_op;
655 static void
656 append_literal_op (BuildInstr *bi, unsigned op1, unsigned src_op)
658 BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
660 b_op->op_num = op1;
661 b_op->typ = OP_LITERAL;
662 b_op->op_data = src_op;
663 b_op->next = NULL;
664 append_op (bi, b_op);
668 static void
669 append_label_op (BuildInstr *bi, unsigned op1)
671 BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
673 b_op->op_num = op1;
674 b_op->typ = OP_LABEL;
675 b_op->op_data = 0;
676 b_op->next = NULL;
677 append_op (bi, b_op);
681 static void
682 append_constant_op (BuildInstr *bi, unsigned op1, unsigned cnst)
684 BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
686 b_op->op_num = op1;
687 b_op->typ = OP_CONSTANT;
688 b_op->op_data = cnst;
689 b_op->next = NULL;
690 append_op (bi, b_op);
694 static void
695 append_field_op (BuildInstr *bi, unsigned op1, unsigned src_op)
697 BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
699 b_op->op_num = op1;
700 b_op->typ = OP_OPERAND;
701 b_op->op_data = src_op;
702 b_op->next = NULL;
703 append_op (bi, b_op);
707 /* These could be generated but are not currently. */
709 static void
710 append_user_fn_field_op (BuildInstr *bi,
711 unsigned op1,
712 OpType typ,
713 unsigned src_op)
715 BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
717 b_op->op_num = op1;
718 b_op->typ = typ;
719 b_op->op_data = src_op;
720 b_op->next = NULL;
721 append_op (bi, b_op);
725 /* These operand functions are the semantics of user-defined
726 operand functions. */
728 static long
729 operand_function_HI24S (long a)
731 if (a & 0x80)
732 return (a & (~0xff)) + 0x100;
733 else
734 return (a & (~0xff));
738 static long
739 operand_function_F32MINUS (long a)
741 return (32 - a);
745 static long
746 operand_function_LOW8 (long a)
748 if (a & 0x80)
749 return (a & 0xff) | ~0xff;
750 else
751 return (a & 0xff);
755 static long
756 operand_function_LOW16U (long a)
758 return (a & 0xffff);
762 static long
763 operand_function_HI16U (long a)
765 unsigned long b = a & 0xffff0000;
766 return (long) (b >> 16);
770 bfd_boolean
771 xg_has_userdef_op_fn (OpType op)
773 switch (op)
775 case OP_OPERAND_F32MINUS:
776 case OP_OPERAND_LOW8:
777 case OP_OPERAND_HI24S:
778 case OP_OPERAND_LOW16U:
779 case OP_OPERAND_HI16U:
780 return TRUE;
781 default:
782 break;
784 return FALSE;
788 long
789 xg_apply_userdef_op_fn (OpType op, long a)
791 switch (op)
793 case OP_OPERAND_F32MINUS:
794 return operand_function_F32MINUS (a);
795 case OP_OPERAND_LOW8:
796 return operand_function_LOW8 (a);
797 case OP_OPERAND_HI24S:
798 return operand_function_HI24S (a);
799 case OP_OPERAND_LOW16U:
800 return operand_function_LOW16U (a);
801 case OP_OPERAND_HI16U:
802 return operand_function_HI16U (a);
803 default:
804 break;
806 return FALSE;
810 /* Generate a transition table. */
812 static const char *
813 enter_opname_n (const char *name, int len)
815 opname_e *op;
817 for (op = local_opnames; op != NULL; op = op->next)
819 if (strlen (op->opname) == (unsigned) len
820 && strncmp (op->opname, name, len) == 0)
821 return op->opname;
823 op = (opname_e *) xmalloc (sizeof (opname_e));
824 op->opname = (char *) xmalloc (len + 1);
825 strncpy (op->opname, name, len);
826 op->opname[len] = '\0';
827 return op->opname;
831 static const char *
832 enter_opname (const char *name)
834 opname_e *op;
836 for (op = local_opnames; op != NULL; op = op->next)
838 if (strcmp (op->opname, name) == 0)
839 return op->opname;
841 op = (opname_e *) xmalloc (sizeof (opname_e));
842 op->opname = xstrdup (name);
843 return op->opname;
847 static void
848 init_opname_map (opname_map *m)
850 m->head = NULL;
851 m->tail = &m->head;
855 static void
856 clear_opname_map (opname_map *m)
858 opname_map_e *e;
860 while (m->head != NULL)
862 e = m->head;
863 m->head = e->next;
864 free (e);
866 m->tail = &m->head;
870 static bfd_boolean
871 same_operand_name (const opname_map_e *m1, const opname_map_e *m2)
873 if (m1->operand_name == NULL || m1->operand_name == NULL)
874 return FALSE;
875 return (m1->operand_name == m2->operand_name);
879 static opname_map_e *
880 get_opmatch (opname_map *map, const char *operand_name)
882 opname_map_e *m;
884 for (m = map->head; m != NULL; m = m->next)
886 if (strcmp (m->operand_name, operand_name) == 0)
887 return m;
889 return NULL;
893 static bfd_boolean
894 op_is_constant (const opname_map_e *m1)
896 return (m1->operand_name == NULL);
900 static unsigned
901 op_get_constant (const opname_map_e *m1)
903 gas_assert (m1->operand_name == NULL);
904 return m1->constant_value;
908 static void
909 init_precond_list (precond_list *l)
911 l->head = NULL;
912 l->tail = &l->head;
916 static void
917 clear_precond_list (precond_list *l)
919 precond_e *e;
921 while (l->head != NULL)
923 e = l->head;
924 l->head = e->next;
925 free (e);
927 l->tail = &l->head;
931 static void
932 init_insn_templ (insn_templ *t)
934 t->opcode_name = NULL;
935 init_opname_map (&t->operand_map);
939 static void
940 clear_insn_templ (insn_templ *t)
942 clear_opname_map (&t->operand_map);
946 static void
947 init_insn_pattern (insn_pattern *p)
949 init_insn_templ (&p->t);
950 init_precond_list (&p->preconds);
951 p->options = NULL;
955 static void
956 clear_insn_pattern (insn_pattern *p)
958 clear_insn_templ (&p->t);
959 clear_precond_list (&p->preconds);
963 static void
964 init_insn_repl (insn_repl *r)
966 r->head = NULL;
967 r->tail = &r->head;
971 static void
972 clear_insn_repl (insn_repl *r)
974 insn_repl_e *e;
976 while (r->head != NULL)
978 e = r->head;
979 r->head = e->next;
980 clear_insn_templ (&e->t);
982 r->tail = &r->head;
986 static int
987 insn_templ_operand_count (const insn_templ *t)
989 int i = 0;
990 const opname_map_e *op;
992 for (op = t->operand_map.head; op != NULL; op = op->next, i++)
994 return i;
998 /* Convert a string to a number. E.G.: parse_constant("10", &num) */
1000 static bfd_boolean
1001 parse_constant (const char *in, unsigned *val_p)
1003 unsigned val = 0;
1004 const char *p;
1006 if (in == NULL)
1007 return FALSE;
1008 p = in;
1010 while (*p != '\0')
1012 if (*p >= '0' && *p <= '9')
1013 val = val * 10 + (*p - '0');
1014 else
1015 return FALSE;
1016 ++p;
1018 *val_p = val;
1019 return TRUE;
1023 static bfd_boolean
1024 parse_special_fn (const char *name,
1025 const char **fn_name_p,
1026 const char **arg_name_p)
1028 char *p_start;
1029 const char *p_end;
1031 p_start = strchr (name, '(');
1032 if (p_start == NULL)
1033 return FALSE;
1035 p_end = strchr (p_start, ')');
1037 if (p_end == NULL)
1038 return FALSE;
1040 if (p_end[1] != '\0')
1041 return FALSE;
1043 *fn_name_p = enter_opname_n (name, p_start - name);
1044 *arg_name_p = enter_opname_n (p_start + 1, p_end - p_start - 1);
1045 return TRUE;
1049 static const char *
1050 skip_white (const char *p)
1052 if (p == NULL)
1053 return p;
1054 while (*p == ' ')
1055 ++p;
1056 return p;
1060 static void
1061 trim_whitespace (char *in)
1063 char *last_white = NULL;
1064 char *p = in;
1066 while (p && *p != '\0')
1068 while (*p == ' ')
1070 if (last_white == NULL)
1071 last_white = p;
1072 p++;
1074 if (*p != '\0')
1076 last_white = NULL;
1077 p++;
1080 if (last_white)
1081 *last_white = '\0';
1085 /* Split a string into component strings where "c" is the
1086 delimiter. Place the result in the split_rec. */
1088 static void
1089 split_string (split_rec *rec,
1090 const char *in,
1091 char c,
1092 bfd_boolean elide_whitespace)
1094 int cnt = 0;
1095 int i;
1096 const char *p = in;
1098 while (p != NULL && *p != '\0')
1100 cnt++;
1101 p = strchr (p, c);
1102 if (p)
1103 p++;
1105 rec->count = cnt;
1106 rec->vec = NULL;
1108 if (rec->count == 0)
1109 return;
1111 rec->vec = (char **) xmalloc (sizeof (char *) * cnt);
1112 for (i = 0; i < cnt; i++)
1113 rec->vec[i] = 0;
1115 p = in;
1116 for (i = 0; i < cnt; i++)
1118 const char *q;
1119 int len;
1121 q = p;
1122 if (elide_whitespace)
1123 q = skip_white (q);
1125 p = strchr (q, c);
1126 if (p == NULL)
1127 rec->vec[i] = xstrdup (q);
1128 else
1130 len = p - q;
1131 rec->vec[i] = (char *) xmalloc (sizeof (char) * (len + 1));
1132 strncpy (rec->vec[i], q, len);
1133 rec->vec[i][len] = '\0';
1134 p++;
1137 if (elide_whitespace)
1138 trim_whitespace (rec->vec[i]);
1143 static void
1144 clear_split_rec (split_rec *rec)
1146 int i;
1148 for (i = 0; i < rec->count; i++)
1149 free (rec->vec[i]);
1151 if (rec->count > 0)
1152 free (rec->vec);
1156 /* Initialize a split record. The split record must be initialized
1157 before split_string is called. */
1159 static void
1160 init_split_rec (split_rec *rec)
1162 rec->vec = NULL;
1163 rec->count = 0;
1167 /* Parse an instruction template like "insn op1, op2, op3". */
1169 static bfd_boolean
1170 parse_insn_templ (const char *s, insn_templ *t)
1172 const char *p = s;
1173 int insn_name_len;
1174 split_rec oprec;
1175 int i;
1177 /* First find the first whitespace. */
1179 init_split_rec (&oprec);
1181 p = skip_white (p);
1182 insn_name_len = strcspn (s, " ");
1183 if (insn_name_len == 0)
1184 return FALSE;
1186 init_insn_templ (t);
1187 t->opcode_name = enter_opname_n (p, insn_name_len);
1189 p = p + insn_name_len;
1191 /* Split by ',' and skip beginning and trailing whitespace. */
1192 split_string (&oprec, p, ',', TRUE);
1194 for (i = 0; i < oprec.count; i++)
1196 const char *opname = oprec.vec[i];
1197 opname_map_e *e = (opname_map_e *) xmalloc (sizeof (opname_map_e));
1198 e->next = NULL;
1199 e->operand_name = NULL;
1200 e->constant_value = 0;
1201 e->operand_num = i;
1203 /* If it begins with a number, assume that it is a number. */
1204 if (opname && opname[0] >= '0' && opname[0] <= '9')
1206 unsigned val;
1208 if (parse_constant (opname, &val))
1209 e->constant_value = val;
1210 else
1212 free (e);
1213 clear_split_rec (&oprec);
1214 clear_insn_templ (t);
1215 return FALSE;
1218 else
1219 e->operand_name = enter_opname (oprec.vec[i]);
1221 *t->operand_map.tail = e;
1222 t->operand_map.tail = &e->next;
1224 clear_split_rec (&oprec);
1225 return TRUE;
1229 static bfd_boolean
1230 parse_precond (const char *s, precond_e *precond)
1232 /* All preconditions are currently of the form:
1233 a == b or a != b or a == k (where k is a constant).
1234 Later we may use some special functions like DENSITY == 1
1235 to identify when density is available. */
1237 const char *p = s;
1238 int len;
1239 precond->opname1 = NULL;
1240 precond->opval1 = 0;
1241 precond->cmpop = OP_EQUAL;
1242 precond->opname2 = NULL;
1243 precond->opval2 = 0;
1244 precond->next = NULL;
1246 p = skip_white (p);
1248 len = strcspn (p, " !=");
1250 if (len == 0)
1251 return FALSE;
1253 precond->opname1 = enter_opname_n (p, len);
1254 p = p + len;
1255 p = skip_white (p);
1257 /* Check for "==" and "!=". */
1258 if (strncmp (p, "==", 2) == 0)
1259 precond->cmpop = OP_EQUAL;
1260 else if (strncmp (p, "!=", 2) == 0)
1261 precond->cmpop = OP_NOTEQUAL;
1262 else
1263 return FALSE;
1265 p = p + 2;
1266 p = skip_white (p);
1268 /* No trailing whitespace from earlier parsing. */
1269 if (p[0] >= '0' && p[0] <= '9')
1271 unsigned val;
1272 if (parse_constant (p, &val))
1273 precond->opval2 = val;
1274 else
1275 return FALSE;
1277 else
1278 precond->opname2 = enter_opname (p);
1279 return TRUE;
1283 static void
1284 clear_req_or_option_list (ReqOrOption **r_p)
1286 if (*r_p == NULL)
1287 return;
1289 free ((*r_p)->option_name);
1290 clear_req_or_option_list (&(*r_p)->next);
1291 *r_p = NULL;
1295 static void
1296 clear_req_option_list (ReqOption **r_p)
1298 if (*r_p == NULL)
1299 return;
1301 clear_req_or_option_list (&(*r_p)->or_option_terms);
1302 clear_req_option_list (&(*r_p)->next);
1303 *r_p = NULL;
1307 static ReqOrOption *
1308 clone_req_or_option_list (ReqOrOption *req_or_option)
1310 ReqOrOption *new_req_or_option;
1312 if (req_or_option == NULL)
1313 return NULL;
1315 new_req_or_option = (ReqOrOption *) xmalloc (sizeof (ReqOrOption));
1316 new_req_or_option->option_name = xstrdup (req_or_option->option_name);
1317 new_req_or_option->is_true = req_or_option->is_true;
1318 new_req_or_option->next = NULL;
1319 new_req_or_option->next = clone_req_or_option_list (req_or_option->next);
1320 return new_req_or_option;
1324 static ReqOption *
1325 clone_req_option_list (ReqOption *req_option)
1327 ReqOption *new_req_option;
1329 if (req_option == NULL)
1330 return NULL;
1332 new_req_option = (ReqOption *) xmalloc (sizeof (ReqOption));
1333 new_req_option->or_option_terms = NULL;
1334 new_req_option->next = NULL;
1335 new_req_option->or_option_terms =
1336 clone_req_or_option_list (req_option->or_option_terms);
1337 new_req_option->next = clone_req_option_list (req_option->next);
1338 return new_req_option;
1342 static bfd_boolean
1343 parse_option_cond (const char *s, ReqOption *option)
1345 int i;
1346 split_rec option_term_rec;
1348 /* All option or conditions are of the form:
1349 optionA + no-optionB + ...
1350 "Ands" are divided by "?". */
1352 init_split_rec (&option_term_rec);
1353 split_string (&option_term_rec, s, '+', TRUE);
1355 if (option_term_rec.count == 0)
1357 clear_split_rec (&option_term_rec);
1358 return FALSE;
1361 for (i = 0; i < option_term_rec.count; i++)
1363 char *option_name = option_term_rec.vec[i];
1364 bfd_boolean is_true = TRUE;
1365 ReqOrOption *req;
1366 ReqOrOption **r_p;
1368 if (strncmp (option_name, "no-", 3) == 0)
1370 option_name = xstrdup (&option_name[3]);
1371 is_true = FALSE;
1373 else
1374 option_name = xstrdup (option_name);
1376 req = (ReqOrOption *) xmalloc (sizeof (ReqOrOption));
1377 req->option_name = option_name;
1378 req->is_true = is_true;
1379 req->next = NULL;
1381 /* Append to list. */
1382 for (r_p = &option->or_option_terms; (*r_p) != NULL;
1383 r_p = &(*r_p)->next)
1385 (*r_p) = req;
1387 return TRUE;
1391 /* Parse a string like:
1392 "insn op1, op2, op3, op4 | op1 != op2 | op2 == op3 | op4 == 1".
1393 I.E., instruction "insn" with 4 operands where operand 1 and 2 are not
1394 the same and operand 2 and 3 are the same and operand 4 is 1.
1398 "insn op1 | op1 == 1 / density + boolean / no-useroption".
1399 i.e. instruction "insn" with 1 operands where operand 1 is 1
1400 when "density" or "boolean" options are available and
1401 "useroption" is not available.
1403 Because the current implementation of this parsing scheme uses
1404 split_string, it requires that '|' and '?' are only used as
1405 delimiters for predicates and required options. */
1407 static bfd_boolean
1408 parse_insn_pattern (const char *in, insn_pattern *insn)
1410 split_rec rec;
1411 split_rec optionrec;
1412 int i;
1414 init_insn_pattern (insn);
1416 init_split_rec (&optionrec);
1417 split_string (&optionrec, in, '?', TRUE);
1418 if (optionrec.count == 0)
1420 clear_split_rec (&optionrec);
1421 return FALSE;
1424 init_split_rec (&rec);
1426 split_string (&rec, optionrec.vec[0], '|', TRUE);
1428 if (rec.count == 0)
1430 clear_split_rec (&rec);
1431 clear_split_rec (&optionrec);
1432 return FALSE;
1435 if (!parse_insn_templ (rec.vec[0], &insn->t))
1437 clear_split_rec (&rec);
1438 clear_split_rec (&optionrec);
1439 return FALSE;
1442 for (i = 1; i < rec.count; i++)
1444 precond_e *cond = (precond_e *) xmalloc (sizeof (precond_e));
1446 if (!parse_precond (rec.vec[i], cond))
1448 clear_split_rec (&rec);
1449 clear_split_rec (&optionrec);
1450 clear_insn_pattern (insn);
1451 return FALSE;
1454 /* Append the condition. */
1455 *insn->preconds.tail = cond;
1456 insn->preconds.tail = &cond->next;
1459 for (i = 1; i < optionrec.count; i++)
1461 /* Handle the option conditions. */
1462 ReqOption **r_p;
1463 ReqOption *req_option = (ReqOption *) xmalloc (sizeof (ReqOption));
1464 req_option->or_option_terms = NULL;
1465 req_option->next = NULL;
1467 if (!parse_option_cond (optionrec.vec[i], req_option))
1469 clear_split_rec (&rec);
1470 clear_split_rec (&optionrec);
1471 clear_insn_pattern (insn);
1472 clear_req_option_list (&req_option);
1473 return FALSE;
1476 /* Append the condition. */
1477 for (r_p = &insn->options; (*r_p) != NULL; r_p = &(*r_p)->next)
1480 (*r_p) = req_option;
1483 clear_split_rec (&rec);
1484 clear_split_rec (&optionrec);
1485 return TRUE;
1489 static bfd_boolean
1490 parse_insn_repl (const char *in, insn_repl *r_p)
1492 /* This is a list of instruction templates separated by ';'. */
1493 split_rec rec;
1494 int i;
1496 split_string (&rec, in, ';', TRUE);
1498 for (i = 0; i < rec.count; i++)
1500 insn_repl_e *e = (insn_repl_e *) xmalloc (sizeof (insn_repl_e));
1502 e->next = NULL;
1504 if (!parse_insn_templ (rec.vec[i], &e->t))
1506 free (e);
1507 clear_insn_repl (r_p);
1508 return FALSE;
1510 *r_p->tail = e;
1511 r_p->tail = &e->next;
1513 return TRUE;
1517 static bfd_boolean
1518 transition_applies (insn_pattern *initial_insn,
1519 const char *from_string ATTRIBUTE_UNUSED,
1520 const char *to_string ATTRIBUTE_UNUSED)
1522 ReqOption *req_option;
1524 for (req_option = initial_insn->options;
1525 req_option != NULL;
1526 req_option = req_option->next)
1528 ReqOrOption *req_or_option = req_option->or_option_terms;
1530 if (req_or_option == NULL
1531 || req_or_option->next != NULL)
1532 continue;
1534 if (strncmp (req_or_option->option_name, "IsaUse", 6) == 0)
1536 bfd_boolean option_available = FALSE;
1537 char *option_name = req_or_option->option_name + 6;
1538 if (!strcmp (option_name, "DensityInstruction"))
1539 option_available = (XCHAL_HAVE_DENSITY == 1);
1540 else if (!strcmp (option_name, "L32R"))
1541 option_available = (XCHAL_HAVE_L32R == 1);
1542 else if (!strcmp (option_name, "Const16"))
1543 option_available = (XCHAL_HAVE_CONST16 == 1);
1544 else if (!strcmp (option_name, "Loops"))
1545 option_available = (XCHAL_HAVE_LOOPS == 1);
1546 else if (!strcmp (option_name, "WideBranches"))
1547 option_available
1548 = (XCHAL_HAVE_WIDE_BRANCHES == 1 && produce_flix == FLIX_ALL);
1549 else if (!strcmp (option_name, "PredictedBranches"))
1550 option_available
1551 = (XCHAL_HAVE_PREDICTED_BRANCHES == 1
1552 && produce_flix == FLIX_ALL);
1553 else if (!strcmp (option_name, "Booleans"))
1554 option_available = (XCHAL_HAVE_BOOLEANS == 1);
1555 else
1556 as_warn (_("invalid configuration option '%s' in transition rule '%s'"),
1557 req_or_option->option_name, from_string);
1558 if ((option_available ^ req_or_option->is_true) != 0)
1559 return FALSE;
1561 else if (strcmp (req_or_option->option_name, "realnop") == 0)
1563 bfd_boolean nop_available =
1564 (xtensa_opcode_lookup (xtensa_default_isa, "nop")
1565 != XTENSA_UNDEFINED);
1566 if ((nop_available ^ req_or_option->is_true) != 0)
1567 return FALSE;
1570 return TRUE;
1574 static bfd_boolean
1575 wide_branch_opcode (const char *opcode_name,
1576 char *suffix,
1577 xtensa_opcode *popcode)
1579 xtensa_isa isa = xtensa_default_isa;
1580 xtensa_opcode opcode;
1581 static char wbr_name_buf[20];
1583 if (strncmp (opcode_name, "WIDE.", 5) != 0)
1584 return FALSE;
1586 strcpy (wbr_name_buf, opcode_name + 5);
1587 strcat (wbr_name_buf, suffix);
1588 opcode = xtensa_opcode_lookup (isa, wbr_name_buf);
1589 if (opcode != XTENSA_UNDEFINED)
1591 *popcode = opcode;
1592 return TRUE;
1595 return FALSE;
1599 static TransitionRule *
1600 build_transition (insn_pattern *initial_insn,
1601 insn_repl *replace_insns,
1602 const char *from_string,
1603 const char *to_string)
1605 TransitionRule *tr = NULL;
1606 xtensa_opcode opcode;
1607 xtensa_isa isa = xtensa_default_isa;
1608 BuildInstr *literal_bi;
1610 opname_map_e *op1;
1611 opname_map_e *op2;
1613 precond_e *precond;
1614 insn_repl_e *r;
1616 if (!wide_branch_opcode (initial_insn->t.opcode_name, ".w18", &opcode)
1617 && !wide_branch_opcode (initial_insn->t.opcode_name, ".w15", &opcode))
1618 opcode = xtensa_opcode_lookup (isa, initial_insn->t.opcode_name);
1620 if (opcode == XTENSA_UNDEFINED)
1622 /* It is OK to not be able to translate some of these opcodes. */
1623 return NULL;
1627 if (xtensa_opcode_num_operands (isa, opcode)
1628 != insn_templ_operand_count (&initial_insn->t))
1630 /* This is also OK because there are opcodes that
1631 have different numbers of operands on different
1632 architecture variations. */
1633 return NULL;
1636 tr = (TransitionRule *) xmalloc (sizeof (TransitionRule));
1637 tr->opcode = opcode;
1638 tr->conditions = NULL;
1639 tr->to_instr = NULL;
1641 /* Build the conditions. First, equivalent operand condition.... */
1642 for (op1 = initial_insn->t.operand_map.head; op1 != NULL; op1 = op1->next)
1644 for (op2 = op1->next; op2 != NULL; op2 = op2->next)
1646 if (same_operand_name (op1, op2))
1648 append_value_condition (tr, OP_EQUAL,
1649 op1->operand_num, op2->operand_num);
1654 /* Now the condition that an operand value must be a constant.... */
1655 for (op1 = initial_insn->t.operand_map.head; op1 != NULL; op1 = op1->next)
1657 if (op_is_constant (op1))
1659 append_constant_value_condition (tr,
1660 OP_EQUAL,
1661 op1->operand_num,
1662 op_get_constant (op1));
1667 /* Now add the explicit preconditions listed after the "|" in the spec.
1668 These are currently very limited, so we do a special case
1669 parse for them. We expect spaces, opname != opname. */
1670 for (precond = initial_insn->preconds.head;
1671 precond != NULL;
1672 precond = precond->next)
1674 op1 = NULL;
1675 op2 = NULL;
1677 if (precond->opname1)
1679 op1 = get_opmatch (&initial_insn->t.operand_map, precond->opname1);
1680 if (op1 == NULL)
1681 as_fatal (_("opcode '%s': no bound opname '%s' "
1682 "for precondition in '%s'"),
1683 xtensa_opcode_name (isa, opcode),
1684 precond->opname1, from_string);
1687 if (precond->opname2)
1689 op2 = get_opmatch (&initial_insn->t.operand_map, precond->opname2);
1690 if (op2 == NULL)
1691 as_fatal (_("opcode '%s': no bound opname '%s' "
1692 "for precondition in %s"),
1693 xtensa_opcode_name (isa, opcode),
1694 precond->opname2, from_string);
1697 if (op1 == NULL && op2 == NULL)
1698 as_fatal (_("opcode '%s': precondition only contains "
1699 "constants in '%s'"),
1700 xtensa_opcode_name (isa, opcode), from_string);
1701 else if (op1 != NULL && op2 != NULL)
1702 append_value_condition (tr, precond->cmpop,
1703 op1->operand_num, op2->operand_num);
1704 else if (op2 == NULL)
1705 append_constant_value_condition (tr, precond->cmpop,
1706 op1->operand_num, precond->opval2);
1707 else
1708 append_constant_value_condition (tr, precond->cmpop,
1709 op2->operand_num, precond->opval1);
1712 tr->options = clone_req_option_list (initial_insn->options);
1714 /* Generate the replacement instructions. Some of these
1715 "instructions" are actually labels and literals. There can be at
1716 most one literal and at most one label. A literal must be defined
1717 (e.g., "LITERAL %imm") before use (e.g., "%LITERAL"). The labels
1718 can be used before they are defined. Also there are a number of
1719 special operands (e.g., HI24S). */
1721 literal_bi = NULL;
1722 for (r = replace_insns->head; r != NULL; r = r->next)
1724 BuildInstr *bi;
1725 const char *opcode_name;
1726 int operand_count;
1727 opname_map_e *op;
1728 const char *fn_name;
1729 const char *operand_arg_name;
1731 bi = (BuildInstr *) xmalloc (sizeof (BuildInstr));
1732 append_build_insn (tr, bi);
1734 bi->opcode = XTENSA_UNDEFINED;
1735 bi->ops = NULL;
1736 bi->next = NULL;
1738 opcode_name = r->t.opcode_name;
1739 operand_count = insn_templ_operand_count (&r->t);
1741 if (strcmp (opcode_name, "LITERAL") == 0)
1743 bi->typ = INSTR_LITERAL_DEF;
1744 if (operand_count != 1)
1745 as_fatal (_("expected one operand for generated literal"));
1746 literal_bi = bi;
1748 else if (strcmp (opcode_name, "LABEL") == 0)
1750 bi->typ = INSTR_LABEL_DEF;
1751 if (operand_count != 0)
1752 as_fatal (_("expected 0 operands for generated label"));
1754 else
1756 bi->typ = INSTR_INSTR;
1757 if (wide_branch_opcode (opcode_name, ".w18", &bi->opcode)
1758 || wide_branch_opcode (opcode_name, ".w15", &bi->opcode))
1759 opcode_name = xtensa_opcode_name (isa, bi->opcode);
1760 else
1761 bi->opcode = xtensa_opcode_lookup (isa, opcode_name);
1763 if (bi->opcode == XTENSA_UNDEFINED)
1765 as_warn (_("invalid opcode '%s' in transition rule '%s'"),
1766 opcode_name, to_string);
1767 return NULL;
1770 /* Check for the right number of ops. */
1771 if (xtensa_opcode_num_operands (isa, bi->opcode)
1772 != (int) operand_count)
1773 as_fatal (_("opcode '%s': replacement does not have %d ops"),
1774 opcode_name,
1775 xtensa_opcode_num_operands (isa, bi->opcode));
1778 for (op = r->t.operand_map.head; op != NULL; op = op->next)
1780 unsigned idnum;
1782 if (op_is_constant (op))
1783 append_constant_op (bi, op->operand_num, op_get_constant (op));
1784 else if (strcmp (op->operand_name, "%LITERAL") == 0)
1786 if (! literal_bi || ! literal_bi->ops || literal_bi->ops->next)
1787 as_fatal (_("opcode '%s': cannot find literal definition"),
1788 opcode_name);
1789 append_literal_op (bi, op->operand_num,
1790 literal_bi->ops->op_data);
1792 else if (strcmp (op->operand_name, "%LABEL") == 0)
1793 append_label_op (bi, op->operand_num);
1794 else if (op->operand_name[0] == 'a'
1795 && parse_constant (op->operand_name + 1, &idnum))
1796 append_constant_op (bi, op->operand_num, idnum);
1797 else if (op->operand_name[0] == '%')
1799 opname_map_e *orig_op;
1800 orig_op = get_opmatch (&initial_insn->t.operand_map,
1801 op->operand_name);
1802 if (orig_op == NULL)
1803 as_fatal (_("opcode %s: unidentified operand '%s' in '%s'"),
1804 opcode_name, op->operand_name, to_string);
1805 append_field_op (bi, op->operand_num, orig_op->operand_num);
1807 else if (strcmp (op->operand_name, "FREEREG") == 0)
1809 append_user_fn_field_op (bi, op->operand_num, OP_FREEREG, 0);
1811 else if (parse_special_fn (op->operand_name,
1812 &fn_name, &operand_arg_name))
1814 opname_map_e *orig_op;
1815 OpType typ = OP_CONSTANT;
1817 if (strcmp (fn_name, "LOW8") == 0)
1818 typ = OP_OPERAND_LOW8;
1819 else if (strcmp (fn_name, "HI24S") == 0)
1820 typ = OP_OPERAND_HI24S;
1821 else if (strcmp (fn_name, "F32MINUS") == 0)
1822 typ = OP_OPERAND_F32MINUS;
1823 else if (strcmp (fn_name, "LOW16U") == 0)
1824 typ = OP_OPERAND_LOW16U;
1825 else if (strcmp (fn_name, "HI16U") == 0)
1826 typ = OP_OPERAND_HI16U;
1827 else
1828 as_fatal (_("unknown user-defined function %s"), fn_name);
1830 orig_op = get_opmatch (&initial_insn->t.operand_map,
1831 operand_arg_name);
1832 if (orig_op == NULL)
1833 as_fatal (_("opcode %s: unidentified operand '%s' in '%s'"),
1834 opcode_name, op->operand_name, to_string);
1835 append_user_fn_field_op (bi, op->operand_num,
1836 typ, orig_op->operand_num);
1838 else
1839 as_fatal (_("opcode %s: could not parse operand '%s' in '%s'"),
1840 opcode_name, op->operand_name, to_string);
1844 return tr;
1848 static TransitionTable *
1849 build_transition_table (const string_pattern_pair *transitions,
1850 int transition_count,
1851 transition_cmp_fn cmp)
1853 TransitionTable *table = NULL;
1854 int num_opcodes = xtensa_isa_num_opcodes (xtensa_default_isa);
1855 int i, tnum;
1857 if (table != NULL)
1858 return table;
1860 /* Otherwise, build it now. */
1861 table = (TransitionTable *) xmalloc (sizeof (TransitionTable));
1862 table->num_opcodes = num_opcodes;
1863 table->table =
1864 (TransitionList **) xmalloc (sizeof (TransitionTable *) * num_opcodes);
1866 for (i = 0; i < num_opcodes; i++)
1867 table->table[i] = NULL;
1869 for (tnum = 0; tnum < transition_count; tnum++)
1871 const char *from_string = transitions[tnum].pattern;
1872 const char *to_string = transitions[tnum].replacement;
1874 insn_pattern initial_insn;
1875 insn_repl replace_insns;
1876 TransitionRule *tr;
1878 init_insn_pattern (&initial_insn);
1879 if (!parse_insn_pattern (from_string, &initial_insn))
1880 as_fatal (_("could not parse INSN_PATTERN '%s'"), from_string);
1882 init_insn_repl (&replace_insns);
1883 if (!parse_insn_repl (to_string, &replace_insns))
1884 as_fatal (_("could not parse INSN_REPL '%s'"), to_string);
1886 if (transition_applies (&initial_insn, from_string, to_string))
1888 tr = build_transition (&initial_insn, &replace_insns,
1889 from_string, to_string);
1890 if (tr)
1891 append_transition (table, tr->opcode, tr, cmp);
1892 else
1894 #if TENSILICA_DEBUG
1895 as_warn (_("could not build transition for %s => %s"),
1896 from_string, to_string);
1897 #endif
1901 clear_insn_repl (&replace_insns);
1902 clear_insn_pattern (&initial_insn);
1904 return table;
1908 extern TransitionTable *
1909 xg_build_widen_table (transition_cmp_fn cmp)
1911 static TransitionTable *table = NULL;
1912 if (table == NULL)
1913 table = build_transition_table (widen_spec_list, WIDEN_COUNT, cmp);
1914 return table;
1918 extern TransitionTable *
1919 xg_build_simplify_table (transition_cmp_fn cmp)
1921 static TransitionTable *table = NULL;
1922 if (table == NULL)
1923 table = build_transition_table (simplify_spec_list, SIMPLIFY_COUNT, cmp);
1924 return table;