bfd ChangeLog
[deliverable/binutils-gdb.git] / gas / config / xtensa-relax.c
1 /* Table of relaxations for Xtensa assembly.
2 Copyright 2003, 2004 Free Software Foundation, Inc.
3
4 This file is part of GAS, the GNU Assembler.
5
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
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.
15
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
19 MA 02111-1307, USA. */
20
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.
29
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.
34
35 The patterns match a language like:
36
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 '"'
48
49 The replacement language
50 INSN_REPL ::= INSN_LABEL_LIT ( ';' INSN_LABEL_LIT )*
51 INSN_LABEL_LIT ::= INSN_TEMPL
52 | 'LABEL' num
53 | 'LITERAL' num ' ' VARIABLE
54
55 The operands in a PRECOND must be constants or variables bound by
56 the INSN_PATTERN.
57
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.
64
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.
69
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.
73
74 A more complex example of a branch around:
75 {"beqz %as,%label", "bnez %as,%LABEL0;j %label;LABEL0"}
76 would convert a branch to a negated branch to the following instruction
77 with a jump to the original label.
78
79 An Xtensa-specific example that generates a literal:
80 {"movi %at,%imm", "LITERAL0 %imm; l32r %at,%LITERAL0"}
81 will convert a movi instruction to an l32r of a literal
82 literal defined in the literal pool.
83
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 "LITERAL0 %imm; l32r %at,%LITERAL0; add %at,%at,%as; l32i %at,%at,0"}
91
92 There is special case for loop instructions here, but because we do
93 not currently have the ability to represent the difference of two
94 symbols, the conversion requires special code in the assembler to
95 write the operands of the addi/addmi pair representing the
96 difference of the old and new loop end label. */
97
98 #include "as.h"
99 #include "xtensa-isa.h"
100 #include "xtensa-relax.h"
101 #include <stddef.h>
102 #include "xtensa-config.h"
103
104 /* Imported from bfd. */
105 extern xtensa_isa xtensa_default_isa;
106
107 /* The opname_list is a small list of names that we use for opcode and
108 operand variable names to simplify ownership of these commonly used
109 strings. Strings entered in the table can be compared by pointer
110 equality. */
111
112 typedef struct opname_list_struct opname_list;
113 typedef opname_list opname_e;
114
115 struct opname_list_struct
116 {
117 char *opname;
118 opname_list *next;
119 };
120
121 static opname_list *local_opnames = NULL;
122
123
124 /* The "opname_map" and its element structure "opname_map_e" are used
125 for binding an operand number to a name or a constant. */
126
127 typedef struct opname_map_e_struct opname_map_e;
128 typedef struct opname_map_struct opname_map;
129
130 struct opname_map_e_struct
131 {
132 const char *operand_name; /* If null, then use constant_value. */
133 int operand_num;
134 unsigned constant_value;
135 opname_map_e *next;
136 };
137
138 struct opname_map_struct
139 {
140 opname_map_e *head;
141 opname_map_e **tail;
142 };
143
144 /* The "precond_list" and its element structure "precond_e" represents
145 explicit preconditions comparing operand variables and constants.
146 In the "precond_e" structure, a variable is identified by the name
147 in the "opname" field. If that field is NULL, then the operand
148 is the constant in field "opval". */
149
150 typedef struct precond_e_struct precond_e;
151 typedef struct precond_list_struct precond_list;
152
153 struct precond_e_struct
154 {
155 const char *opname1;
156 unsigned opval1;
157 CmpOp cmpop;
158 const char *opname2;
159 unsigned opval2;
160 precond_e *next;
161 };
162
163 struct precond_list_struct
164 {
165 precond_e *head;
166 precond_e **tail;
167 };
168
169
170 /* The insn_templ represents the INSN_TEMPL instruction template. It
171 is an opcode name with a list of operands. These are used for
172 instruction patterns and replacement patterns. */
173
174 typedef struct insn_templ_struct insn_templ;
175 struct insn_templ_struct
176 {
177 const char *opcode_name;
178 opname_map operand_map;
179 };
180
181
182 /* The insn_pattern represents an INSN_PATTERN instruction pattern.
183 It is an instruction template with preconditions that specify when
184 it actually matches a given instruction. */
185
186 typedef struct insn_pattern_struct insn_pattern;
187 struct insn_pattern_struct
188 {
189 insn_templ t;
190 precond_list preconds;
191 ReqOptionList *options;
192 };
193
194
195 /* The "insn_repl" and associated element structure "insn_repl_e"
196 instruction replacement list is a list of
197 instructions/LITERALS/LABELS with constant operands or operands
198 with names bound to the operand names in the associated pattern. */
199
200 typedef struct insn_repl_e_struct insn_repl_e;
201 struct insn_repl_e_struct
202 {
203 insn_templ t;
204 insn_repl_e *next;
205 };
206
207 typedef struct insn_repl_struct insn_repl;
208 struct insn_repl_struct
209 {
210 insn_repl_e *head;
211 insn_repl_e **tail;
212 };
213
214
215 /* The split_rec is a vector of allocated char * pointers. */
216
217 typedef struct split_rec_struct split_rec;
218 struct split_rec_struct
219 {
220 char **vec;
221 int count;
222 };
223
224 /* The "string_pattern_pair" is a set of pairs containing instruction
225 patterns and replacement strings. */
226
227 typedef struct string_pattern_pair_struct string_pattern_pair;
228 struct string_pattern_pair_struct
229 {
230 const char *pattern;
231 const char *replacement;
232 };
233
234 \f
235 /* The widen_spec_list is a list of valid substitutions that generate
236 wider representations. These are generally used to specify
237 replacements for instructions whose immediates do not fit their
238 encodings. A valid transition may require multiple steps of
239 one-to-one instruction replacements with a final multiple
240 instruction replacement. As an example, here are the transitions
241 required to replace an 'addi.n' with an 'addi', 'addmi'.
242
243 addi.n a4, 0x1010
244 => addi a4, 0x1010
245 => addmi a4, 0x1010
246 => addmi a4, 0x1000, addi a4, 0x10. */
247
248 static string_pattern_pair widen_spec_list[] =
249 {
250 {"add.n %ar,%as,%at ? IsaUseDensityInstruction", "add %ar,%as,%at"},
251 {"addi.n %ar,%as,%imm ? IsaUseDensityInstruction", "addi %ar,%as,%imm"},
252 {"beqz.n %as,%label ? IsaUseDensityInstruction", "beqz %as,%label"},
253 {"bnez.n %as,%label ? IsaUseDensityInstruction", "bnez %as,%label"},
254 {"l32i.n %at,%as,%imm ? IsaUseDensityInstruction", "l32i %at,%as,%imm"},
255 {"mov.n %at,%as ? IsaUseDensityInstruction", "or %at,%as,%as"},
256 {"movi.n %as,%imm ? IsaUseDensityInstruction", "movi %as,%imm"},
257 {"nop.n ? IsaUseDensityInstruction ? realnop", "nop"},
258 {"nop.n ? IsaUseDensityInstruction ? no-realnop", "or 1,1,1"},
259 {"ret.n %as ? IsaUseDensityInstruction", "ret %as"},
260 {"retw.n %as ? IsaUseDensityInstruction", "retw %as"},
261 {"s32i.n %at,%as,%imm ? IsaUseDensityInstruction", "s32i %at,%as,%imm"},
262 {"srli %at,%as,%imm", "extui %at,%as,%imm,F32MINUS(%imm)"},
263 {"slli %ar,%as,0", "or %ar,%as,%as"},
264
265 /* Widening with literals or const16. */
266 {"movi %at,%imm ? IsaUseL32R ",
267 "LITERAL0 %imm; l32r %at,%LITERAL0"},
268 {"movi %at,%imm ? IsaUseConst16",
269 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm)"},
270
271 {"addi %ar,%as,%imm", "addmi %ar,%as,%imm"},
272 /* LOW8 is the low 8 bits of the Immed
273 MID8S is the middle 8 bits of the Immed */
274 {"addmi %ar,%as,%imm", "addmi %ar,%as,HI24S(%imm); addi %ar,%ar,LOW8(%imm)"},
275
276 /* In the end convert to either an l32r or const16. */
277 {"addmi %ar,%as,%imm | %ar!=%as ? IsaUseL32R",
278 "LITERAL0 %imm; l32r %ar,%LITERAL0; add %ar,%as,%ar"},
279 {"addmi %ar,%as,%imm | %ar!=%as ? IsaUseConst16",
280 "const16 %ar,HI16U(%imm); const16 %ar,LOW16U(%imm); add %ar,%as,%ar"},
281
282 /* Widening the load instructions with too-large immediates */
283 {"l8ui %at,%as,%imm | %at!=%as ? IsaUseL32R",
284 "LITERAL0 %imm; l32r %at,%LITERAL0; add %at,%at,%as; l8ui %at,%at,0"},
285 {"l16si %at,%as,%imm | %at!=%as ? IsaUseL32R",
286 "LITERAL0 %imm; l32r %at,%LITERAL0; add %at,%at,%as; l16si %at,%at,0"},
287 {"l16ui %at,%as,%imm | %at!=%as ? IsaUseL32R",
288 "LITERAL0 %imm; l32r %at,%LITERAL0; add %at,%at,%as; l16ui %at,%at,0"},
289 {"l32i %at,%as,%imm | %at!=%as ? IsaUseL32R",
290 "LITERAL0 %imm; l32r %at,%LITERAL0; add %at,%at,%as; l32i %at,%at,0"},
291
292 /* Widening load instructions with const16s. */
293 {"l8ui %at,%as,%imm | %at!=%as ? IsaUseConst16",
294 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l8ui %at,%at,0"},
295 {"l16si %at,%as,%imm | %at!=%as ? IsaUseConst16",
296 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l16si %at,%at,0"},
297 {"l16ui %at,%as,%imm | %at!=%as ? IsaUseConst16",
298 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l16ui %at,%at,0"},
299 {"l32i %at,%as,%imm | %at!=%as ? IsaUseConst16",
300 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l32i %at,%at,0"},
301
302 #if 0 /* Xtensa Synchronization Option not yet available */
303 {"l32ai %at,%as,%imm ? IsaUseL32R",
304 "LITERAL0 %imm; l32r %at,%LITERAL0; add.n %at,%at,%as; l32ai %at,%at,0"},
305 #endif
306 #if 0 /* Xtensa Speculation Option not yet available */
307 {"l32is %at,%as,%imm ? IsaUseL32R",
308 "LITERAL0 %imm; l32r %at,%LITERAL0; add.n %at,%at,%as; l32is %at,%at,0"},
309 #endif
310
311 /* This is only PART of the loop instruction. In addition,
312 hardcoded into its use is a modification of the final operand in
313 the instruction in bytes 9 and 12. */
314 {"loop %as,%label | %as!=1 ? IsaUseLoops",
315 "loop %as,%LABEL0;"
316 "rsr.lend %as;" /* LEND */
317 "wsr.lbeg %as;" /* LBEG */
318 "addi %as, %as, 0;" /* lo8(%label-%LABEL1) */
319 "addmi %as, %as, 0;" /* mid8(%label-%LABEL1) */
320 "wsr.lend %as;"
321 "isync;"
322 "rsr.lcount %as;" /* LCOUNT */
323 "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */
324 "LABEL0"},
325 {"loopgtz %as,%label | %as!=1 ? IsaUseLoops",
326 "beqz %as,%label;"
327 "bltz %as,%label;"
328 "loopgtz %as,%LABEL0;"
329 "rsr.lend %as;" /* LEND */
330 "wsr.lbeg %as;" /* LBEG */
331 "addi %as, %as, 0;" /* lo8(%label-%LABEL1) */
332 "addmi %as, %as, 0;" /* mid8(%label-%LABEL1) */
333 "wsr.lend %as;"
334 "isync;"
335 "rsr.lcount %as;" /* LCOUNT */
336 "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */
337 "LABEL0"},
338 {"loopnez %as,%label | %as!=1 ? IsaUseLoops",
339 "beqz %as,%label;"
340 "loopnez %as,%LABEL0;"
341 "rsr.lend %as;" /* LEND */
342 "wsr.lbeg %as;" /* LBEG */
343 "addi %as, %as, 0;" /* lo8(%label-%LABEL1) */
344 "addmi %as, %as, 0;" /* mid8(%label-%LABEL1) */
345 "wsr.lend %as;"
346 "isync;"
347 "rsr.lcount %as;" /* LCOUNT */
348 "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */
349 "LABEL0"},
350
351 {"beqz %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%LABEL0;j %label;LABEL0"},
352 {"bnez %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%LABEL0;j %label;LABEL0"},
353 {"beqz %as,%label", "bnez %as,%LABEL0;j %label;LABEL0"},
354 {"bnez %as,%label", "beqz %as,%LABEL0;j %label;LABEL0"},
355 {"beqzt %as,%label ? IsaUsePredictedBranches", "bnez %as,%LABEL0;j %label;LABEL0"},
356 {"bnezt %as,%label ? IsaUsePredictedBranches", "beqz %as,%LABEL0;j %label;LABEL0"},
357
358 {"bgez %as,%label", "bltz %as,%LABEL0;j %label;LABEL0"},
359 {"bltz %as,%label", "bgez %as,%LABEL0;j %label;LABEL0"},
360 {"beqi %as,%imm,%label", "bnei %as,%imm,%LABEL0;j %label;LABEL0"},
361 {"bnei %as,%imm,%label", "beqi %as,%imm,%LABEL0;j %label;LABEL0"},
362 {"bgei %as,%imm,%label", "blti %as,%imm,%LABEL0;j %label;LABEL0"},
363 {"blti %as,%imm,%label", "bgei %as,%imm,%LABEL0;j %label;LABEL0"},
364 {"bgeui %as,%imm,%label", "bltui %as,%imm,%LABEL0;j %label;LABEL0"},
365 {"bltui %as,%imm,%label", "bgeui %as,%imm,%LABEL0;j %label;LABEL0"},
366 {"bbci %as,%imm,%label", "bbsi %as,%imm,%LABEL0;j %label;LABEL0"},
367 {"bbsi %as,%imm,%label", "bbci %as,%imm,%LABEL0;j %label;LABEL0"},
368 {"beq %as,%at,%label", "bne %as,%at,%LABEL0;j %label;LABEL0"},
369 {"bne %as,%at,%label", "beq %as,%at,%LABEL0;j %label;LABEL0"},
370 {"beqt %as,%at,%label ? IsaUsePredictedBranches", "bne %as,%at,%LABEL0;j %label;LABEL0"},
371 {"bnet %as,%at,%label ? IsaUsePredictedBranches", "beq %as,%at,%LABEL0;j %label;LABEL0"},
372 {"bge %as,%at,%label", "blt %as,%at,%LABEL0;j %label;LABEL0"},
373 {"blt %as,%at,%label", "bge %as,%at,%LABEL0;j %label;LABEL0"},
374 {"bgeu %as,%at,%label", "bltu %as,%at,%LABEL0;j %label;LABEL0"},
375 {"bltu %as,%at,%label", "bgeu %as,%at,%LABEL0;j %label;LABEL0"},
376 {"bany %as,%at,%label", "bnone %as,%at,%LABEL0;j %label;LABEL0"},
377
378 {"bt %bs,%label ? IsaUseBooleans", "bf %bs,%LABEL0;j %label;LABEL0"},
379 {"bf %bs,%label ? IsaUseBooleans", "bt %bs,%LABEL0;j %label;LABEL0"},
380
381 {"bnone %as,%at,%label", "bany %as,%at,%LABEL0;j %label;LABEL0"},
382 {"ball %as,%at,%label", "bnall %as,%at,%LABEL0;j %label;LABEL0"},
383 {"bnall %as,%at,%label", "ball %as,%at,%LABEL0;j %label;LABEL0"},
384 {"bbc %as,%at,%label", "bbs %as,%at,%LABEL0;j %label;LABEL0"},
385 {"bbs %as,%at,%label", "bbc %as,%at,%LABEL0;j %label;LABEL0"},
386
387 /* Expanding calls with literals. */
388 {"call0 %label,%ar0 ? IsaUseL32R",
389 "LITERAL0 %label; l32r a0,%LITERAL0; callx0 a0,%ar0"},
390 {"call4 %label,%ar4 ? IsaUseL32R",
391 "LITERAL0 %label; l32r a4,%LITERAL0; callx4 a4,%ar4"},
392 {"call8 %label,%ar8 ? IsaUseL32R",
393 "LITERAL0 %label; l32r a8,%LITERAL0; callx8 a8,%ar8"},
394 {"call12 %label,%ar12 ? IsaUseL32R",
395 "LITERAL0 %label; l32r a12,%LITERAL0; callx12 a12,%ar12"},
396
397 /* Expanding calls with const16. */
398 {"call0 %label,%ar0 ? IsaUseConst16",
399 "const16 a0,HI16U(%label); const16 a0,LOW16U(%label); callx0 a0,%ar0"},
400 {"call4 %label,%ar4 ? IsaUseConst16",
401 "const16 a4,HI16U(%label); const16 a4,LOW16U(%label); callx4 a4,%ar4"},
402 {"call8 %label,%ar8 ? IsaUseConst16",
403 "const16 a8,HI16U(%label); const16 a8,LOW16U(%label); callx8 a8,%ar8"},
404 {"call12 %label,%ar12 ? IsaUseConst16",
405 "const16 a12,HI16U(%label); const16 a12,LOW16U(%label); callx12 a12,%ar12"}
406 };
407
408 #define WIDEN_COUNT (sizeof (widen_spec_list) / sizeof (string_pattern_pair))
409
410
411 /* The simplify_spec_list specifies simplifying transformations that
412 will reduce the instruction width or otherwise simplify an
413 instruction. These are usually applied before relaxation in the
414 assembler. It is always legal to simplify. Even for "addi as, 0",
415 the "addi.n as, 0" will eventually be widened back to an "addi 0"
416 after the widening table is applied. Note: The usage of this table
417 has changed somewhat so that it is entirely specific to "narrowing"
418 instructions to use the density option. This table is not used at
419 all when the density option is not available. */
420
421 string_pattern_pair simplify_spec_list[] =
422 {
423 {"add %ar,%as,%at ? IsaUseDensityInstruction", "add.n %ar,%as,%at"},
424 {"addi.n %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"},
425 {"addi %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"},
426 {"addi %ar,%as,%imm ? IsaUseDensityInstruction", "addi.n %ar,%as,%imm"},
427 {"addmi %ar,%as,%imm ? IsaUseDensityInstruction", "addi.n %ar,%as,%imm"},
428 {"beqz %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%label"},
429 {"bnez %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%label"},
430 {"l32i %at,%as,%imm ? IsaUseDensityInstruction", "l32i.n %at,%as,%imm"},
431 {"movi %as,%imm ? IsaUseDensityInstruction", "movi.n %as,%imm"},
432 {"nop ? realnop ? IsaUseDensityInstruction", "nop.n"},
433 {"or %ar,%as,%at | %ar==%as | %as==%at ? IsaUseDensityInstruction", "nop.n"},
434 {"or %ar,%as,%at | %ar!=%as | %as==%at ? IsaUseDensityInstruction", "mov.n %ar,%as"},
435 {"ret %as ? IsaUseDensityInstruction", "ret.n %as"},
436 {"retw %as ? IsaUseDensityInstruction", "retw.n %as"},
437 {"s32i %at,%as,%imm ? IsaUseDensityInstruction", "s32i.n %at,%as,%imm"},
438 {"slli %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"}
439 };
440
441 #define SIMPLIFY_COUNT \
442 (sizeof (simplify_spec_list) / sizeof (string_pattern_pair))
443
444 \f
445 /* Transition generation helpers. */
446
447 static void append_transition
448 PARAMS ((TransitionTable *, xtensa_opcode, TransitionRule *,
449 transition_cmp_fn));
450 static void append_condition
451 PARAMS ((TransitionRule *, Precondition *));
452 static void append_value_condition
453 PARAMS ((TransitionRule *, CmpOp, unsigned, unsigned));
454 static void append_constant_value_condition
455 PARAMS ((TransitionRule *, CmpOp, unsigned, unsigned));
456 static void append_build_insn
457 PARAMS ((TransitionRule *, BuildInstr *));
458 static void append_op
459 PARAMS ((BuildInstr *, BuildOp *));
460 static void append_literal_op
461 PARAMS ((BuildInstr *, unsigned, unsigned));
462 static void append_label_op
463 PARAMS ((BuildInstr *, unsigned, unsigned));
464 static void append_constant_op
465 PARAMS ((BuildInstr *, unsigned, unsigned));
466 static void append_field_op
467 PARAMS ((BuildInstr *, unsigned, unsigned));
468 static void append_user_fn_field_op
469 PARAMS ((BuildInstr *, unsigned, OpType, unsigned));
470 static long operand_function_HI24S
471 PARAMS ((long));
472 static long operand_function_F32MINUS
473 PARAMS ((long));
474 static long operand_function_LOW8
475 PARAMS ((long));
476 static long operand_function_LOW16U
477 PARAMS ((long));
478 static long operand_function_HI16U
479 PARAMS ((long));
480
481 /* Externally visible functions. */
482
483 extern bfd_boolean xg_has_userdef_op_fn
484 PARAMS ((OpType));
485 extern long xg_apply_userdef_op_fn
486 PARAMS ((OpType, long));
487
488 /* Parsing helpers. */
489
490 static const char *enter_opname_n
491 PARAMS ((const char *, int));
492 static const char *enter_opname
493 PARAMS ((const char *));
494
495 /* Construction and destruction. */
496
497 static void init_opname_map
498 PARAMS ((opname_map *));
499 static void clear_opname_map
500 PARAMS ((opname_map *));
501 static void init_precond_list
502 PARAMS ((precond_list *));
503 static void clear_precond_list
504 PARAMS ((precond_list *));
505 static void init_insn_templ
506 PARAMS ((insn_templ *));
507 static void clear_insn_templ
508 PARAMS ((insn_templ *));
509 static void init_insn_pattern
510 PARAMS ((insn_pattern *));
511 static void clear_insn_pattern
512 PARAMS ((insn_pattern *));
513 static void init_insn_repl
514 PARAMS ((insn_repl *));
515 static void clear_insn_repl
516 PARAMS ((insn_repl *));
517 static void init_split_rec
518 PARAMS ((split_rec *));
519 static void clear_split_rec
520 PARAMS ((split_rec *));
521 static void clear_req_or_option_list
522 PARAMS ((ReqOrOption **));
523 static void clear_req_option_list
524 PARAMS ((ReqOption **));
525 static ReqOrOption *clone_req_or_option_list
526 PARAMS ((ReqOrOption *));
527 static ReqOption *clone_req_option_list
528 PARAMS ((ReqOption *));
529
530 /* Operand and insn_templ helpers. */
531
532 static bfd_boolean same_operand_name
533 PARAMS ((const opname_map_e *, const opname_map_e *));
534 static opname_map_e *get_opmatch
535 PARAMS ((opname_map *, const char *));
536 static bfd_boolean op_is_constant
537 PARAMS ((const opname_map_e *));
538 static unsigned op_get_constant
539 PARAMS ((const opname_map_e *));
540 static int insn_templ_operand_count
541 PARAMS ((const insn_templ *));
542
543 /* Parsing helpers. */
544
545 static const char *skip_white
546 PARAMS ((const char *));
547 static void trim_whitespace
548 PARAMS ((char *));
549 static void split_string
550 PARAMS ((split_rec *, const char *, char, bfd_boolean));
551
552 /* Language parsing. */
553
554 static bfd_boolean parse_insn_pattern
555 PARAMS ((const char *, insn_pattern *));
556 static bfd_boolean parse_insn_repl
557 PARAMS ((const char *, insn_repl *));
558 static bfd_boolean parse_insn_templ
559 PARAMS ((const char *, insn_templ *));
560 static bfd_boolean parse_special_fn
561 PARAMS ((const char *, const char **, const char **));
562 static bfd_boolean parse_precond
563 PARAMS ((const char *, precond_e *));
564 static bfd_boolean parse_constant
565 PARAMS ((const char *, unsigned *));
566 static bfd_boolean parse_id_constant
567 PARAMS ((const char *, const char *, unsigned *));
568 static bfd_boolean parse_option_cond
569 PARAMS ((const char *, ReqOption *));
570
571 /* Transition table building code. */
572
573 static bfd_boolean transition_applies
574 PARAMS ((insn_pattern *, const char *, const char *));
575 static TransitionRule *build_transition
576 PARAMS ((insn_pattern *, insn_repl *, const char *, const char *));
577 static TransitionTable *build_transition_table
578 PARAMS ((const string_pattern_pair *, int, transition_cmp_fn));
579
580 \f
581 void
582 append_transition (tt, opcode, t, cmp)
583 TransitionTable *tt;
584 xtensa_opcode opcode;
585 TransitionRule *t;
586 transition_cmp_fn cmp;
587 {
588 TransitionList *tl = (TransitionList *) xmalloc (sizeof (TransitionList));
589 TransitionList *prev;
590 TransitionList **t_p;
591 assert (tt != NULL);
592 assert (opcode < tt->num_opcodes);
593
594 prev = tt->table[opcode];
595 tl->rule = t;
596 tl->next = NULL;
597 if (prev == NULL)
598 {
599 tt->table[opcode] = tl;
600 return;
601 }
602
603 for (t_p = &tt->table[opcode]; (*t_p) != NULL; t_p = &(*t_p)->next)
604 {
605 if (cmp && cmp (t, (*t_p)->rule) < 0)
606 {
607 /* Insert it here. */
608 tl->next = *t_p;
609 *t_p = tl;
610 return;
611 }
612 }
613 (*t_p) = tl;
614 }
615
616
617 void
618 append_condition (tr, cond)
619 TransitionRule *tr;
620 Precondition *cond;
621 {
622 PreconditionList *pl =
623 (PreconditionList *) xmalloc (sizeof (PreconditionList));
624 PreconditionList *prev = tr->conditions;
625 PreconditionList *nxt;
626
627 pl->precond = cond;
628 pl->next = NULL;
629 if (prev == NULL)
630 {
631 tr->conditions = pl;
632 return;
633 }
634 nxt = prev->next;
635 while (nxt != NULL)
636 {
637 prev = nxt;
638 nxt = nxt->next;
639 }
640 prev->next = pl;
641 }
642
643
644 void
645 append_value_condition (tr, cmp, op1, op2)
646 TransitionRule *tr;
647 CmpOp cmp;
648 unsigned op1;
649 unsigned op2;
650 {
651 Precondition *cond = (Precondition *) xmalloc (sizeof (Precondition));
652
653 cond->cmp = cmp;
654 cond->op_num = op1;
655 cond->typ = OP_OPERAND;
656 cond->op_data = op2;
657 append_condition (tr, cond);
658 }
659
660
661 void
662 append_constant_value_condition (tr, cmp, op1, cnst)
663 TransitionRule *tr;
664 CmpOp cmp;
665 unsigned op1;
666 unsigned cnst;
667 {
668 Precondition *cond = (Precondition *) xmalloc (sizeof (Precondition));
669
670 cond->cmp = cmp;
671 cond->op_num = op1;
672 cond->typ = OP_CONSTANT;
673 cond->op_data = cnst;
674 append_condition (tr, cond);
675 }
676
677
678 void
679 append_build_insn (tr, bi)
680 TransitionRule *tr;
681 BuildInstr *bi;
682 {
683 BuildInstr *prev = tr->to_instr;
684 BuildInstr *nxt;
685
686 bi->next = NULL;
687 if (prev == NULL)
688 {
689 tr->to_instr = bi;
690 return;
691 }
692 nxt = prev->next;
693 while (nxt != 0)
694 {
695 prev = nxt;
696 nxt = prev->next;
697 }
698 prev->next = bi;
699 }
700
701
702 void
703 append_op (bi, b_op)
704 BuildInstr *bi;
705 BuildOp *b_op;
706 {
707 BuildOp *prev = bi->ops;
708 BuildOp *nxt;
709
710 if (prev == NULL)
711 {
712 bi->ops = b_op;
713 return;
714 }
715 nxt = prev->next;
716 while (nxt != NULL)
717 {
718 prev = nxt;
719 nxt = nxt->next;
720 }
721 prev->next = b_op;
722 }
723
724
725 void
726 append_literal_op (bi, op1, litnum)
727 BuildInstr *bi;
728 unsigned op1;
729 unsigned litnum;
730 {
731 BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
732
733 b_op->op_num = op1;
734 b_op->typ = OP_LITERAL;
735 b_op->op_data = litnum;
736 b_op->next = NULL;
737 append_op (bi, b_op);
738 }
739
740
741 void
742 append_label_op (bi, op1, labnum)
743 BuildInstr *bi;
744 unsigned op1;
745 unsigned labnum;
746 {
747 BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
748
749 b_op->op_num = op1;
750 b_op->typ = OP_LABEL;
751 b_op->op_data = labnum;
752 b_op->next = NULL;
753 append_op (bi, b_op);
754 }
755
756
757 void
758 append_constant_op (bi, op1, cnst)
759 BuildInstr *bi;
760 unsigned op1;
761 unsigned cnst;
762 {
763 BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
764
765 b_op->op_num = op1;
766 b_op->typ = OP_CONSTANT;
767 b_op->op_data = cnst;
768 b_op->next = NULL;
769 append_op (bi, b_op);
770 }
771
772
773 void
774 append_field_op (bi, op1, src_op)
775 BuildInstr *bi;
776 unsigned op1;
777 unsigned src_op;
778 {
779 BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
780
781 b_op->op_num = op1;
782 b_op->typ = OP_OPERAND;
783 b_op->op_data = src_op;
784 b_op->next = NULL;
785 append_op (bi, b_op);
786 }
787
788
789 /* These could be generated but are not currently. */
790
791 void
792 append_user_fn_field_op (bi, op1, typ, src_op)
793 BuildInstr *bi;
794 unsigned op1;
795 OpType typ;
796 unsigned src_op;
797 {
798 BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
799
800 b_op->op_num = op1;
801 b_op->typ = typ;
802 b_op->op_data = src_op;
803 b_op->next = NULL;
804 append_op (bi, b_op);
805 }
806
807
808 /* These operand functions are the semantics of user-defined
809 operand functions. */
810
811 long
812 operand_function_HI24S (a)
813 long a;
814 {
815 if (a & 0x80)
816 return (a & (~0xff)) + 0x100;
817 else
818 return (a & (~0xff));
819 }
820
821
822 long
823 operand_function_F32MINUS (a)
824 long a;
825 {
826 return (32 - a);
827 }
828
829
830 long
831 operand_function_LOW8 (a)
832 long a;
833 {
834 if (a & 0x80)
835 return (a & 0xff) | ~0xff;
836 else
837 return (a & 0xff);
838 }
839
840
841 long
842 operand_function_LOW16U (a)
843 long a;
844 {
845 return (a & 0xffff);
846 }
847
848
849 long
850 operand_function_HI16U (a)
851 long a;
852 {
853 unsigned long b = a & 0xffff0000;
854 return (long) (b >> 16);
855 }
856
857
858 bfd_boolean
859 xg_has_userdef_op_fn (op)
860 OpType op;
861 {
862 switch (op)
863 {
864 case OP_OPERAND_F32MINUS:
865 case OP_OPERAND_LOW8:
866 case OP_OPERAND_HI24S:
867 case OP_OPERAND_LOW16U:
868 case OP_OPERAND_HI16U:
869 return TRUE;
870 default:
871 break;
872 }
873 return FALSE;
874 }
875
876
877 long
878 xg_apply_userdef_op_fn (op, a)
879 OpType op;
880 long a;
881 {
882 switch (op)
883 {
884 case OP_OPERAND_F32MINUS:
885 return operand_function_F32MINUS (a);
886 case OP_OPERAND_LOW8:
887 return operand_function_LOW8 (a);
888 case OP_OPERAND_HI24S:
889 return operand_function_HI24S (a);
890 case OP_OPERAND_LOW16U:
891 return operand_function_LOW16U (a);
892 case OP_OPERAND_HI16U:
893 return operand_function_HI16U (a);
894 default:
895 break;
896 }
897 return FALSE;
898 }
899
900
901 /* Generate a transition table. */
902
903 const char *
904 enter_opname_n (name, len)
905 const char *name;
906 int len;
907 {
908 opname_e *op;
909
910 for (op = local_opnames; op != NULL; op = op->next)
911 {
912 if (strlen (op->opname) == (unsigned) len
913 && strncmp (op->opname, name, len) == 0)
914 return op->opname;
915 }
916 op = (opname_e *) xmalloc (sizeof (opname_e));
917 op->opname = (char *) xmalloc (len + 1);
918 strncpy (op->opname, name, len);
919 op->opname[len] = '\0';
920 return op->opname;
921 }
922
923
924 static const char *
925 enter_opname (name)
926 const char *name;
927 {
928 opname_e *op;
929
930 for (op = local_opnames; op != NULL; op = op->next)
931 {
932 if (strcmp (op->opname, name) == 0)
933 return op->opname;
934 }
935 op = (opname_e *) xmalloc (sizeof (opname_e));
936 op->opname = xstrdup (name);
937 return op->opname;
938 }
939
940
941 void
942 init_opname_map (m)
943 opname_map *m;
944 {
945 m->head = NULL;
946 m->tail = &m->head;
947 }
948
949
950 void
951 clear_opname_map (m)
952 opname_map *m;
953 {
954 opname_map_e *e;
955
956 while (m->head != NULL)
957 {
958 e = m->head;
959 m->head = e->next;
960 free (e);
961 }
962 m->tail = &m->head;
963 }
964
965
966 static bfd_boolean
967 same_operand_name (m1, m2)
968 const opname_map_e *m1;
969 const opname_map_e *m2;
970 {
971 if (m1->operand_name == NULL || m1->operand_name == NULL)
972 return FALSE;
973 return (m1->operand_name == m2->operand_name);
974 }
975
976
977 opname_map_e *
978 get_opmatch (map, operand_name)
979 opname_map *map;
980 const char *operand_name;
981 {
982 opname_map_e *m;
983
984 for (m = map->head; m != NULL; m = m->next)
985 {
986 if (strcmp (m->operand_name, operand_name) == 0)
987 return m;
988 }
989 return NULL;
990 }
991
992
993 bfd_boolean
994 op_is_constant (m1)
995 const opname_map_e *m1;
996 {
997 return (m1->operand_name == NULL);
998 }
999
1000
1001 static unsigned
1002 op_get_constant (m1)
1003 const opname_map_e *m1;
1004 {
1005 assert (m1->operand_name == NULL);
1006 return m1->constant_value;
1007 }
1008
1009
1010 void
1011 init_precond_list (l)
1012 precond_list *l;
1013 {
1014 l->head = NULL;
1015 l->tail = &l->head;
1016 }
1017
1018
1019 void
1020 clear_precond_list (l)
1021 precond_list *l;
1022 {
1023 precond_e *e;
1024
1025 while (l->head != NULL)
1026 {
1027 e = l->head;
1028 l->head = e->next;
1029 free (e);
1030 }
1031 l->tail = &l->head;
1032 }
1033
1034
1035 void
1036 init_insn_templ (t)
1037 insn_templ *t;
1038 {
1039 t->opcode_name = NULL;
1040 init_opname_map (&t->operand_map);
1041 }
1042
1043
1044 void
1045 clear_insn_templ (t)
1046 insn_templ *t;
1047 {
1048 clear_opname_map (&t->operand_map);
1049 }
1050
1051
1052 void
1053 init_insn_pattern (p)
1054 insn_pattern *p;
1055 {
1056 init_insn_templ (&p->t);
1057 init_precond_list (&p->preconds);
1058 p->options = NULL;
1059 }
1060
1061
1062 void
1063 clear_insn_pattern (p)
1064 insn_pattern *p;
1065 {
1066 clear_insn_templ (&p->t);
1067 clear_precond_list (&p->preconds);
1068 }
1069
1070
1071 void
1072 init_insn_repl (r)
1073 insn_repl *r;
1074 {
1075 r->head = NULL;
1076 r->tail = &r->head;
1077 }
1078
1079
1080 void
1081 clear_insn_repl (r)
1082 insn_repl *r;
1083 {
1084 insn_repl_e *e;
1085
1086 while (r->head != NULL)
1087 {
1088 e = r->head;
1089 r->head = e->next;
1090 clear_insn_templ (&e->t);
1091 }
1092 r->tail = &r->head;
1093 }
1094
1095
1096 static int
1097 insn_templ_operand_count (t)
1098 const insn_templ *t;
1099 {
1100 int i = 0;
1101 const opname_map_e *op;
1102
1103 for (op = t->operand_map.head; op != NULL; op = op->next, i++)
1104 ;
1105 return i;
1106 }
1107
1108
1109 /* Convert a string to a number. E.G.: parse_constant("10", &num) */
1110
1111 bfd_boolean
1112 parse_constant (in, val_p)
1113 const char *in;
1114 unsigned *val_p;
1115 {
1116 unsigned val = 0;
1117 const char *p;
1118
1119 if (in == NULL)
1120 return FALSE;
1121 p = in;
1122
1123 while (*p != '\0')
1124 {
1125 if (*p >= '0' && *p <= '9')
1126 val = val * 10 + (*p - '0');
1127 else
1128 return FALSE;
1129 ++p;
1130 }
1131 *val_p = val;
1132 return TRUE;
1133 }
1134
1135
1136 /* Match a pattern like "foo1" with
1137 parse_id_constant("foo1", "foo", &num).
1138 This may also be used to just match a number. */
1139
1140 bfd_boolean
1141 parse_id_constant (in, name, val_p)
1142 const char *in;
1143 const char *name;
1144 unsigned *val_p;
1145 {
1146 unsigned namelen = 0;
1147 const char *p;
1148
1149 if (in == NULL)
1150 return FALSE;
1151
1152 if (name != NULL)
1153 namelen = strlen (name);
1154
1155 if (name != NULL && strncmp (in, name, namelen) != 0)
1156 return FALSE;
1157
1158 p = &in[namelen];
1159 return parse_constant (p, val_p);
1160 }
1161
1162
1163 static bfd_boolean
1164 parse_special_fn (name, fn_name_p, arg_name_p)
1165 const char *name;
1166 const char **fn_name_p;
1167 const char **arg_name_p;
1168 {
1169 char *p_start;
1170 const char *p_end;
1171
1172 p_start = strchr (name, '(');
1173 if (p_start == NULL)
1174 return FALSE;
1175
1176 p_end = strchr (p_start, ')');
1177
1178 if (p_end == NULL)
1179 return FALSE;
1180
1181 if (p_end[1] != '\0')
1182 return FALSE;
1183
1184 *fn_name_p = enter_opname_n (name, p_start - name);
1185 *arg_name_p = enter_opname_n (p_start + 1, p_end - p_start - 1);
1186 return TRUE;
1187 }
1188
1189
1190 const char *
1191 skip_white (p)
1192 const char *p;
1193 {
1194 if (p == NULL)
1195 return p;
1196 while (*p == ' ')
1197 ++p;
1198 return p;
1199 }
1200
1201
1202 void
1203 trim_whitespace (in)
1204 char *in;
1205 {
1206 char *last_white = NULL;
1207 char *p = in;
1208
1209 while (p && *p != '\0')
1210 {
1211 while (*p == ' ')
1212 {
1213 if (last_white == NULL)
1214 last_white = p;
1215 p++;
1216 }
1217 if (*p != '\0')
1218 {
1219 last_white = NULL;
1220 p++;
1221 }
1222 }
1223 if (last_white)
1224 *last_white = '\0';
1225 }
1226
1227
1228 /* Split a string into component strings where "c" is the
1229 delimiter. Place the result in the split_rec. */
1230
1231 void
1232 split_string (rec, in, c, elide_whitespace)
1233 split_rec *rec;
1234 const char *in;
1235 char c;
1236 bfd_boolean elide_whitespace;
1237 {
1238 int cnt = 0;
1239 int i;
1240 const char *p = in;
1241
1242 while (p != NULL && *p != '\0')
1243 {
1244 cnt++;
1245 p = strchr (p, c);
1246 if (p)
1247 p++;
1248 }
1249 rec->count = cnt;
1250 rec->vec = NULL;
1251
1252 if (rec->count == 0)
1253 return;
1254
1255 rec->vec = (char **) xmalloc (sizeof (char *) * cnt);
1256 for (i = 0; i < cnt; i++)
1257 rec->vec[i] = 0;
1258
1259 p = in;
1260 for (i = 0; i < cnt; i++)
1261 {
1262 const char *q;
1263 int len;
1264
1265 q = p;
1266 if (elide_whitespace)
1267 q = skip_white (q);
1268
1269 p = strchr (q, c);
1270 if (p == NULL)
1271 rec->vec[i] = xstrdup (q);
1272 else
1273 {
1274 len = p - q;
1275 rec->vec[i] = (char *) xmalloc (sizeof (char) * (len + 1));
1276 strncpy (rec->vec[i], q, len);
1277 rec->vec[i][len] = '\0';
1278 p++;
1279 }
1280
1281 if (elide_whitespace)
1282 trim_whitespace (rec->vec[i]);
1283 }
1284 }
1285
1286
1287 void
1288 clear_split_rec (rec)
1289 split_rec *rec;
1290 {
1291 int i;
1292
1293 for (i = 0; i < rec->count; i++)
1294 free (rec->vec[i]);
1295
1296 if (rec->count > 0)
1297 free (rec->vec);
1298 }
1299
1300
1301 /* Initialize a split record. The split record must be initialized
1302 before split_string is called. */
1303
1304 void
1305 init_split_rec (rec)
1306 split_rec *rec;
1307 {
1308 rec->vec = NULL;
1309 rec->count = 0;
1310 }
1311
1312
1313 /* Parse an instruction template like "insn op1, op2, op3". */
1314
1315 bfd_boolean
1316 parse_insn_templ (s, t)
1317 const char *s;
1318 insn_templ *t;
1319 {
1320 const char *p = s;
1321 int insn_name_len;
1322 split_rec oprec;
1323 int i;
1324
1325 /* First find the first whitespace. */
1326
1327 init_split_rec (&oprec);
1328
1329 p = skip_white (p);
1330 insn_name_len = strcspn (s, " ");
1331 if (insn_name_len == 0)
1332 return FALSE;
1333
1334 init_insn_templ (t);
1335 t->opcode_name = enter_opname_n (p, insn_name_len);
1336
1337 p = p + insn_name_len;
1338
1339 /* Split by ',' and skip beginning and trailing whitespace. */
1340 split_string (&oprec, p, ',', TRUE);
1341
1342 for (i = 0; i < oprec.count; i++)
1343 {
1344 const char *opname = oprec.vec[i];
1345 opname_map_e *e = (opname_map_e *) xmalloc (sizeof (opname_map_e));
1346 e->next = NULL;
1347 e->operand_name = NULL;
1348 e->constant_value = 0;
1349 e->operand_num = i;
1350
1351 /* If it begins with a number, assume that it is a number. */
1352 if (opname && opname[0] >= '0' && opname[0] <= '9')
1353 {
1354 unsigned val;
1355
1356 if (parse_constant (opname, &val))
1357 e->constant_value = val;
1358 else
1359 {
1360 free (e);
1361 clear_split_rec (&oprec);
1362 clear_insn_templ (t);
1363 return FALSE;
1364 }
1365 }
1366 else
1367 e->operand_name = enter_opname (oprec.vec[i]);
1368
1369 *t->operand_map.tail = e;
1370 t->operand_map.tail = &e->next;
1371 }
1372 clear_split_rec (&oprec);
1373 return TRUE;
1374 }
1375
1376
1377 bfd_boolean
1378 parse_precond (s, precond)
1379 const char *s;
1380 precond_e *precond;
1381 {
1382 /* All preconditions are currently of the form:
1383 a == b or a != b or a == k (where k is a constant).
1384 Later we may use some special functions like DENSITY == 1
1385 to identify when density is available. */
1386
1387 const char *p = s;
1388 int len;
1389 precond->opname1 = NULL;
1390 precond->opval1 = 0;
1391 precond->cmpop = OP_EQUAL;
1392 precond->opname2 = NULL;
1393 precond->opval2 = 0;
1394 precond->next = NULL;
1395
1396 p = skip_white (p);
1397
1398 len = strcspn (p, " !=");
1399
1400 if (len == 0)
1401 return FALSE;
1402
1403 precond->opname1 = enter_opname_n (p, len);
1404 p = p + len;
1405 p = skip_white (p);
1406
1407 /* Check for "==" and "!=". */
1408 if (strncmp (p, "==", 2) == 0)
1409 precond->cmpop = OP_EQUAL;
1410 else if (strncmp (p, "!=", 2) == 0)
1411 precond->cmpop = OP_NOTEQUAL;
1412 else
1413 return FALSE;
1414
1415 p = p + 2;
1416 p = skip_white (p);
1417
1418 /* No trailing whitespace from earlier parsing. */
1419 if (p[0] >= '0' && p[0] <= '9')
1420 {
1421 unsigned val;
1422 if (parse_constant (p, &val))
1423 precond->opval2 = val;
1424 else
1425 return FALSE;
1426 }
1427 else
1428 precond->opname2 = enter_opname (p);
1429 return TRUE;
1430 }
1431
1432
1433 void
1434 clear_req_or_option_list (r_p)
1435 ReqOrOption **r_p;
1436 {
1437 if (*r_p == NULL)
1438 return;
1439
1440 free ((*r_p)->option_name);
1441 clear_req_or_option_list (&(*r_p)->next);
1442 *r_p = NULL;
1443 }
1444
1445
1446 void
1447 clear_req_option_list (r_p)
1448 ReqOption **r_p;
1449 {
1450 if (*r_p == NULL)
1451 return;
1452
1453 clear_req_or_option_list (&(*r_p)->or_option_terms);
1454 clear_req_option_list (&(*r_p)->next);
1455 *r_p = NULL;
1456 }
1457
1458
1459 ReqOrOption *
1460 clone_req_or_option_list (req_or_option)
1461 ReqOrOption *req_or_option;
1462 {
1463 ReqOrOption *new_req_or_option;
1464
1465 if (req_or_option == NULL)
1466 return NULL;
1467
1468 new_req_or_option = (ReqOrOption *) xmalloc (sizeof (ReqOrOption));
1469 new_req_or_option->option_name = xstrdup (req_or_option->option_name);
1470 new_req_or_option->is_true = req_or_option->is_true;
1471 new_req_or_option->next = NULL;
1472 new_req_or_option->next = clone_req_or_option_list (req_or_option->next);
1473 return new_req_or_option;
1474 }
1475
1476
1477 ReqOption *
1478 clone_req_option_list (req_option)
1479 ReqOption *req_option;
1480 {
1481 ReqOption *new_req_option;
1482
1483 if (req_option == NULL)
1484 return NULL;
1485
1486 new_req_option = (ReqOption *) xmalloc (sizeof (ReqOption));
1487 new_req_option->or_option_terms = NULL;
1488 new_req_option->next = NULL;
1489 new_req_option->or_option_terms =
1490 clone_req_or_option_list (req_option->or_option_terms);
1491 new_req_option->next = clone_req_option_list (req_option->next);
1492 return new_req_option;
1493 }
1494
1495
1496 bfd_boolean
1497 parse_option_cond (s, option)
1498 const char *s;
1499 ReqOption *option;
1500 {
1501 int i;
1502 split_rec option_term_rec;
1503
1504 /* All option or conditions are of the form:
1505 optionA + no-optionB + ...
1506 "Ands" are divided by "?". */
1507
1508 init_split_rec (&option_term_rec);
1509 split_string (&option_term_rec, s, '+', TRUE);
1510
1511 if (option_term_rec.count == 0)
1512 {
1513 clear_split_rec (&option_term_rec);
1514 return FALSE;
1515 }
1516
1517 for (i = 0; i < option_term_rec.count; i++)
1518 {
1519 char *option_name = option_term_rec.vec[i];
1520 bfd_boolean is_true = TRUE;
1521 ReqOrOption *req;
1522 ReqOrOption **r_p;
1523
1524 if (strncmp (option_name, "no-", 3) == 0)
1525 {
1526 option_name = xstrdup (&option_name[3]);
1527 is_true = FALSE;
1528 }
1529 else
1530 option_name = xstrdup (option_name);
1531
1532 req = (ReqOrOption *) xmalloc (sizeof (ReqOrOption));
1533 req->option_name = option_name;
1534 req->is_true = is_true;
1535 req->next = NULL;
1536
1537 /* Append to list. */
1538 for (r_p = &option->or_option_terms; (*r_p) != NULL;
1539 r_p = &(*r_p)->next)
1540 ;
1541 (*r_p) = req;
1542 }
1543 return TRUE;
1544 }
1545
1546
1547 /* Parse a string like:
1548 "insn op1, op2, op3, op4 | op1 != op2 | op2 == op3 | op4 == 1".
1549 I.E., instruction "insn" with 4 operands where operand 1 and 2 are not
1550 the same and operand 2 and 3 are the same and operand 4 is 1.
1551
1552 or:
1553
1554 "insn op1 | op1 == 1 / density + boolean / no-useroption".
1555 i.e. instruction "insn" with 1 operands where operand 1 is 1
1556 when "density" or "boolean" options are available and
1557 "useroption" is not available.
1558
1559 Because the current implementation of this parsing scheme uses
1560 split_string, it requires that '|' and '?' are only used as
1561 delimiters for predicates and required options. */
1562
1563 bfd_boolean
1564 parse_insn_pattern (in, insn)
1565 const char *in;
1566 insn_pattern *insn;
1567 {
1568 split_rec rec;
1569 split_rec optionrec;
1570 int i;
1571
1572 init_insn_pattern (insn);
1573
1574 init_split_rec (&optionrec);
1575 split_string (&optionrec, in, '?', TRUE);
1576 if (optionrec.count == 0)
1577 {
1578 clear_split_rec (&optionrec);
1579 return FALSE;
1580 }
1581
1582 init_split_rec (&rec);
1583
1584 split_string (&rec, optionrec.vec[0], '|', TRUE);
1585
1586 if (rec.count == 0)
1587 {
1588 clear_split_rec (&rec);
1589 clear_split_rec (&optionrec);
1590 return FALSE;
1591 }
1592
1593 if (!parse_insn_templ (rec.vec[0], &insn->t))
1594 {
1595 clear_split_rec (&rec);
1596 clear_split_rec (&optionrec);
1597 return FALSE;
1598 }
1599
1600 for (i = 1; i < rec.count; i++)
1601 {
1602 precond_e *cond = (precond_e *) xmalloc (sizeof (precond_e));
1603
1604 if (!parse_precond (rec.vec[i], cond))
1605 {
1606 clear_split_rec (&rec);
1607 clear_split_rec (&optionrec);
1608 clear_insn_pattern (insn);
1609 return FALSE;
1610 }
1611
1612 /* Append the condition. */
1613 *insn->preconds.tail = cond;
1614 insn->preconds.tail = &cond->next;
1615 }
1616
1617 for (i = 1; i < optionrec.count; i++)
1618 {
1619 /* Handle the option conditions. */
1620 ReqOption **r_p;
1621 ReqOption *req_option = (ReqOption *) xmalloc (sizeof (ReqOption));
1622 req_option->or_option_terms = NULL;
1623 req_option->next = NULL;
1624
1625 if (!parse_option_cond (optionrec.vec[i], req_option))
1626 {
1627 clear_split_rec (&rec);
1628 clear_split_rec (&optionrec);
1629 clear_insn_pattern (insn);
1630 clear_req_option_list (&req_option);
1631 return FALSE;
1632 }
1633
1634 /* Append the condition. */
1635 for (r_p = &insn->options; (*r_p) != NULL; r_p = &(*r_p)->next)
1636 ;
1637
1638 (*r_p) = req_option;
1639 }
1640
1641 clear_split_rec (&rec);
1642 clear_split_rec (&optionrec);
1643 return TRUE;
1644 }
1645
1646
1647 bfd_boolean
1648 parse_insn_repl (in, r_p)
1649 const char *in;
1650 insn_repl *r_p;
1651 {
1652 /* This is a list of instruction templates separated by ';'. */
1653 split_rec rec;
1654 int i;
1655
1656 split_string (&rec, in, ';', TRUE);
1657
1658 for (i = 0; i < rec.count; i++)
1659 {
1660 insn_repl_e *e = (insn_repl_e *) xmalloc (sizeof (insn_repl_e));
1661
1662 e->next = NULL;
1663
1664 if (!parse_insn_templ (rec.vec[i], &e->t))
1665 {
1666 free (e);
1667 clear_insn_repl (r_p);
1668 return FALSE;
1669 }
1670 *r_p->tail = e;
1671 r_p->tail = &e->next;
1672 }
1673 return TRUE;
1674 }
1675
1676
1677 bfd_boolean
1678 transition_applies (initial_insn, from_string, to_string)
1679 insn_pattern *initial_insn;
1680 const char *from_string ATTRIBUTE_UNUSED;
1681 const char *to_string ATTRIBUTE_UNUSED;
1682 {
1683 ReqOption *req_option;
1684
1685 for (req_option = initial_insn->options;
1686 req_option != NULL;
1687 req_option = req_option->next)
1688 {
1689 ReqOrOption *req_or_option = req_option->or_option_terms;
1690
1691 if (req_or_option == NULL
1692 || req_or_option->next != NULL)
1693 continue;
1694
1695 if (strncmp (req_or_option->option_name, "IsaUse", 6) == 0)
1696 {
1697 bfd_boolean option_available = FALSE;
1698 char *option_name = req_or_option->option_name + 6;
1699 if (!strcmp (option_name, "DensityInstruction"))
1700 option_available = (XCHAL_HAVE_DENSITY == 1);
1701 else if (!strcmp (option_name, "L32R"))
1702 option_available = (XCHAL_HAVE_L32R == 1);
1703 else if (!strcmp (option_name, "Const16"))
1704 option_available = (XCHAL_HAVE_CONST16 == 1);
1705 else if (!strcmp (option_name, "Loops"))
1706 option_available = (XCHAL_HAVE_LOOPS == 1);
1707 else if (!strcmp (option_name, "PredictedBranches"))
1708 option_available = (XCHAL_HAVE_PREDICTED_BRANCHES == 1);
1709 else if (!strcmp (option_name, "Booleans"))
1710 option_available = (XCHAL_HAVE_BOOLEANS == 1);
1711 else
1712 as_warn (_("invalid configuration option '%s' in transition rule '%s'"),
1713 req_or_option->option_name, from_string);
1714 if ((option_available ^ req_or_option->is_true) != 0)
1715 return FALSE;
1716 }
1717 else if (strcmp (req_or_option->option_name, "realnop") == 0)
1718 {
1719 bfd_boolean nop_available =
1720 (xtensa_opcode_lookup (xtensa_default_isa, "nop")
1721 != XTENSA_UNDEFINED);
1722 if ((nop_available ^ req_or_option->is_true) != 0)
1723 return FALSE;
1724 }
1725 }
1726 return TRUE;
1727 }
1728
1729
1730 TransitionRule *
1731 build_transition (initial_insn, replace_insns, from_string, to_string)
1732 insn_pattern *initial_insn;
1733 insn_repl *replace_insns;
1734 const char *from_string;
1735 const char *to_string;
1736 {
1737 TransitionRule *tr = NULL;
1738 xtensa_opcode opcode;
1739 xtensa_isa isa = xtensa_default_isa;
1740
1741 opname_map_e *op1;
1742 opname_map_e *op2;
1743
1744 precond_e *precond;
1745 insn_repl_e *r;
1746 unsigned label_count = 0;
1747 unsigned max_label_count = 0;
1748 bfd_boolean has_label = FALSE;
1749 unsigned literal_count = 0;
1750
1751 opcode = xtensa_opcode_lookup (isa, initial_insn->t.opcode_name);
1752 if (opcode == XTENSA_UNDEFINED)
1753 {
1754 /* It is OK to not be able to translate some of these opcodes. */
1755 #if 0
1756 as_warn (_("invalid opcode '%s' in transition rule '%s'"),
1757 initial_insn->t.opcode_name, from_string);
1758 #endif
1759 return NULL;
1760 }
1761
1762
1763 if (xtensa_opcode_num_operands (isa, opcode)
1764 != insn_templ_operand_count (&initial_insn->t))
1765 {
1766 /* This is also OK because there are opcodes that
1767 have different numbers of operands on different
1768 architecture variations. */
1769 #if 0
1770 as_fatal (_("opcode %s mismatched operand count %d != expected %d"),
1771 xtensa_opcode_name (isa, opcode),
1772 xtensa_num_operands (isa, opcode),
1773 insn_templ_operand_count (&initial_insn->t));
1774 #endif
1775 return NULL;
1776 }
1777
1778 tr = (TransitionRule *) xmalloc (sizeof (TransitionRule));
1779 tr->opcode = opcode;
1780 tr->conditions = NULL;
1781 tr->to_instr = NULL;
1782
1783 /* Build the conditions. First, equivalent operand condition.... */
1784 for (op1 = initial_insn->t.operand_map.head; op1 != NULL; op1 = op1->next)
1785 {
1786 for (op2 = op1->next; op2 != NULL; op2 = op2->next)
1787 {
1788 if (same_operand_name (op1, op2))
1789 {
1790 append_value_condition (tr, OP_EQUAL,
1791 op1->operand_num, op2->operand_num);
1792 }
1793 }
1794 }
1795
1796 /* Now the condition that an operand value must be a constant.... */
1797 for (op1 = initial_insn->t.operand_map.head; op1 != NULL; op1 = op1->next)
1798 {
1799 if (op_is_constant (op1))
1800 {
1801 append_constant_value_condition (tr,
1802 OP_EQUAL,
1803 op1->operand_num,
1804 op_get_constant (op1));
1805 }
1806 }
1807
1808
1809 /* Now add the explicit preconditions listed after the "|" in the spec.
1810 These are currently very limited, so we do a special case
1811 parse for them. We expect spaces, opname != opname. */
1812 for (precond = initial_insn->preconds.head;
1813 precond != NULL;
1814 precond = precond->next)
1815 {
1816 op1 = NULL;
1817 op2 = NULL;
1818
1819 if (precond->opname1)
1820 {
1821 op1 = get_opmatch (&initial_insn->t.operand_map, precond->opname1);
1822 if (op1 == NULL)
1823 {
1824 as_fatal (_("opcode '%s': no bound opname '%s' "
1825 "for precondition in '%s'"),
1826 xtensa_opcode_name (isa, opcode),
1827 precond->opname1, from_string);
1828 return NULL;
1829 }
1830 }
1831
1832 if (precond->opname2)
1833 {
1834 op2 = get_opmatch (&initial_insn->t.operand_map, precond->opname2);
1835 if (op2 == NULL)
1836 {
1837 as_fatal (_("opcode '%s': no bound opname '%s' "
1838 "for precondition in %s"),
1839 xtensa_opcode_name (isa, opcode),
1840 precond->opname2, from_string);
1841 return NULL;
1842 }
1843 }
1844
1845 if (op1 == NULL && op2 == NULL)
1846 {
1847 as_fatal (_("opcode '%s': precondition only contains "
1848 "constants in '%s'"),
1849 xtensa_opcode_name (isa, opcode), from_string);
1850 return NULL;
1851 }
1852 else if (op1 != NULL && op2 != NULL)
1853 append_value_condition (tr, precond->cmpop,
1854 op1->operand_num, op2->operand_num);
1855 else if (op2 == NULL)
1856 append_constant_value_condition (tr, precond->cmpop,
1857 op1->operand_num, precond->opval2);
1858 else
1859 append_constant_value_condition (tr, precond->cmpop,
1860 op2->operand_num, precond->opval1);
1861 }
1862
1863 tr->options = clone_req_option_list (initial_insn->options);
1864
1865 /* Generate the replacement instructions. Some of these
1866 "instructions" are actually labels and literals. The literals
1867 must be defined in order 0..n and a literal must be defined
1868 (e.g., "LITERAL0 %imm") before use (e.g., "%LITERAL0"). The
1869 labels must be defined in order, but they can be used before they
1870 are defined. Also there are a number of special operands (e.g.,
1871 HI24S). */
1872
1873 for (r = replace_insns->head; r != NULL; r = r->next)
1874 {
1875 BuildInstr *bi;
1876 const char *opcode_name;
1877 int operand_count;
1878 opname_map_e *op;
1879 unsigned idnum = 0;
1880 const char *fn_name;
1881 const char *operand_arg_name;
1882
1883 bi = (BuildInstr *) xmalloc (sizeof (BuildInstr));
1884 append_build_insn (tr, bi);
1885
1886 bi->id = 0;
1887 bi->opcode = XTENSA_UNDEFINED;
1888 bi->ops = NULL;
1889 bi->next = NULL;
1890
1891 opcode_name = r->t.opcode_name;
1892 operand_count = insn_templ_operand_count (&r->t);
1893
1894 if (parse_id_constant (opcode_name, "LITERAL", &idnum))
1895 {
1896 bi->typ = INSTR_LITERAL_DEF;
1897 bi->id = idnum;
1898 if (idnum != literal_count)
1899 as_fatal (_("generated literals must be numbered consecutively"));
1900 ++literal_count;
1901 if (operand_count != 1)
1902 as_fatal (_("expected one operand for generated literal"));
1903
1904 }
1905 else if (parse_id_constant (opcode_name, "LABEL", &idnum))
1906 {
1907 bi->typ = INSTR_LABEL_DEF;
1908 bi->id = idnum;
1909 if (idnum != label_count)
1910 as_fatal (_("generated labels must be numbered consecutively"));
1911 ++label_count;
1912 if (operand_count != 0)
1913 as_fatal (_("expected 0 operands for generated label"));
1914 }
1915 else
1916 {
1917 bi->typ = INSTR_INSTR;
1918 bi->opcode = xtensa_opcode_lookup (isa, r->t.opcode_name);
1919 if (bi->opcode == XTENSA_UNDEFINED)
1920 {
1921 as_warn (_("invalid opcode '%s' in transition rule '%s'"),
1922 r->t.opcode_name, to_string);
1923 return NULL;
1924 }
1925 /* Check for the right number of ops. */
1926 if (xtensa_opcode_num_operands (isa, bi->opcode)
1927 != (int) operand_count)
1928 as_fatal (_("opcode '%s': replacement does not have %d ops"),
1929 opcode_name,
1930 xtensa_opcode_num_operands (isa, bi->opcode));
1931 }
1932
1933 for (op = r->t.operand_map.head; op != NULL; op = op->next)
1934 {
1935 unsigned idnum;
1936
1937 if (op_is_constant (op))
1938 append_constant_op (bi, op->operand_num, op_get_constant (op));
1939 else if (parse_id_constant (op->operand_name, "%LITERAL", &idnum))
1940 {
1941 if (idnum >= literal_count)
1942 as_fatal (_("opcode %s: replacement "
1943 "literal %d >= literal_count(%d)"),
1944 opcode_name, idnum, literal_count);
1945 append_literal_op (bi, op->operand_num, idnum);
1946 }
1947 else if (parse_id_constant (op->operand_name, "%LABEL", &idnum))
1948 {
1949 has_label = TRUE;
1950 if (idnum > max_label_count)
1951 max_label_count = idnum;
1952 append_label_op (bi, op->operand_num, idnum);
1953 }
1954 else if (parse_id_constant (op->operand_name, "a", &idnum))
1955 append_constant_op (bi, op->operand_num, idnum);
1956 else if (op->operand_name[0] == '%')
1957 {
1958 opname_map_e *orig_op;
1959 orig_op = get_opmatch (&initial_insn->t.operand_map,
1960 op->operand_name);
1961 if (orig_op == NULL)
1962 {
1963 as_fatal (_("opcode %s: unidentified operand '%s' in '%s'"),
1964 opcode_name, op->operand_name, to_string);
1965
1966 append_constant_op (bi, op->operand_num, 0);
1967 }
1968 else
1969 append_field_op (bi, op->operand_num, orig_op->operand_num);
1970 }
1971 else if (parse_special_fn (op->operand_name,
1972 &fn_name, &operand_arg_name))
1973 {
1974 opname_map_e *orig_op;
1975 OpType typ = OP_CONSTANT;
1976
1977 if (strcmp (fn_name, "LOW8") == 0)
1978 typ = OP_OPERAND_LOW8;
1979 else if (strcmp (fn_name, "HI24S") == 0)
1980 typ = OP_OPERAND_HI24S;
1981 else if (strcmp (fn_name, "F32MINUS") == 0)
1982 typ = OP_OPERAND_F32MINUS;
1983 else if (strcmp (fn_name, "LOW16U") == 0)
1984 typ = OP_OPERAND_LOW16U;
1985 else if (strcmp (fn_name, "HI16U") == 0)
1986 typ = OP_OPERAND_HI16U;
1987 else
1988 as_fatal (_("unknown user-defined function %s"), fn_name);
1989
1990 orig_op = get_opmatch (&initial_insn->t.operand_map,
1991 operand_arg_name);
1992 if (orig_op == NULL)
1993 {
1994 as_fatal (_("opcode %s: unidentified operand '%s' in '%s'"),
1995 opcode_name, op->operand_name, to_string);
1996 append_constant_op (bi, op->operand_num, 0);
1997 }
1998 else
1999 append_user_fn_field_op (bi, op->operand_num,
2000 typ, orig_op->operand_num);
2001 }
2002 else
2003 {
2004 as_fatal (_("opcode %s: could not parse operand '%s' in '%s'"),
2005 opcode_name, op->operand_name, to_string);
2006 append_constant_op (bi, op->operand_num, 0);
2007 }
2008 }
2009 }
2010 if (has_label && max_label_count >= label_count)
2011 {
2012 as_fatal (_("opcode %s: replacement label %d >= label_count(%d)"),
2013 xtensa_opcode_name (isa, opcode),
2014 max_label_count, label_count);
2015 return NULL;
2016 }
2017
2018 return tr;
2019 }
2020
2021
2022 TransitionTable *
2023 build_transition_table (transitions, transition_count, cmp)
2024 const string_pattern_pair *transitions;
2025 int transition_count;
2026 transition_cmp_fn cmp;
2027 {
2028 TransitionTable *table = NULL;
2029 int num_opcodes = xtensa_isa_num_opcodes (xtensa_default_isa);
2030 int i, tnum;
2031
2032 if (table != NULL)
2033 return table;
2034
2035 /* Otherwise, build it now. */
2036 table = (TransitionTable *) xmalloc (sizeof (TransitionTable));
2037 table->num_opcodes = num_opcodes;
2038 table->table =
2039 (TransitionList **) xmalloc (sizeof (TransitionTable *) * num_opcodes);
2040
2041 for (i = 0; i < num_opcodes; i++)
2042 table->table[i] = NULL;
2043
2044 for (tnum = 0; tnum < transition_count; tnum++)
2045 {
2046 const char *from_string = transitions[tnum].pattern;
2047 const char *to_string = transitions[tnum].replacement;
2048
2049 insn_pattern initial_insn;
2050 insn_repl replace_insns;
2051 TransitionRule *tr;
2052
2053 init_insn_pattern (&initial_insn);
2054 if (!parse_insn_pattern (from_string, &initial_insn))
2055 {
2056 as_fatal (_("could not parse INSN_PATTERN '%s'"), from_string);
2057 clear_insn_pattern (&initial_insn);
2058 continue;
2059 }
2060
2061 init_insn_repl (&replace_insns);
2062 if (!parse_insn_repl (to_string, &replace_insns))
2063 {
2064 as_fatal (_("could not parse INSN_REPL '%s'"), to_string);
2065 clear_insn_pattern (&initial_insn);
2066 clear_insn_repl (&replace_insns);
2067 continue;
2068 }
2069
2070 if (transition_applies (&initial_insn, from_string, to_string))
2071 {
2072 tr = build_transition (&initial_insn, &replace_insns,
2073 from_string, to_string);
2074 if (tr)
2075 append_transition (table, tr->opcode, tr, cmp);
2076 else
2077 {
2078 #if TENSILICA_DEBUG
2079 as_warn (_("could not build transition for %s => %s"),
2080 from_string, to_string);
2081 #endif
2082 }
2083 }
2084
2085 clear_insn_repl (&replace_insns);
2086 clear_insn_pattern (&initial_insn);
2087 }
2088 return table;
2089 }
2090
2091 \f
2092 extern TransitionTable *
2093 xg_build_widen_table (cmp)
2094 transition_cmp_fn cmp;
2095 {
2096 static TransitionTable *table = NULL;
2097 if (table == NULL)
2098 table = build_transition_table (widen_spec_list, WIDEN_COUNT, cmp);
2099 return table;
2100 }
2101
2102
2103 extern TransitionTable *
2104 xg_build_simplify_table (cmp)
2105 transition_cmp_fn cmp;
2106 {
2107 static TransitionTable *table = NULL;
2108 if (table == NULL)
2109 table = build_transition_table (simplify_spec_list, SIMPLIFY_COUNT, cmp);
2110 return table;
2111 }
This page took 0.075333 seconds and 4 git commands to generate.