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