49a93b20e053adb28def6f1eb4eb18bf6eb9bc43
[external/binutils.git] / gas / config / xtensa-relax.c
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 \f
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 \f
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 \f
508 void
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
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
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
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
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
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
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
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
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
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
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
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
744 operand_function_F32MINUS (a)
745      long a;
746 {
747   return (32 - a);
748 }
749
750
751 long
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
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
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 *
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 *
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
839 init_opname_map (m)
840      opname_map *m;
841 {
842   m->head = NULL;
843   m->tail = &m->head;
844 }
845
846
847 void
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
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 *
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
891 op_is_constant (m1)
892      const opname_map_e *m1;
893 {
894   return (m1->operand_name == NULL);
895 }
896
897
898 static unsigned
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
908 init_precond_list (l)
909      precond_list *l;
910 {
911   l->head = NULL;
912   l->tail = &l->head;
913 }
914
915
916 void
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
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
942 clear_insn_templ (t)
943      insn_templ *t;
944 {
945   clear_opname_map (&t->operand_map);
946 }
947
948
949 void
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
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
968 init_insn_repl (r)
969      insn_repl *r;
970 {
971   r->head = NULL;
972   r->tail = &r->head;
973 }
974
975
976 void
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
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
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
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
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 *
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
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
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
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
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
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
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
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
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 *
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 *
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 \f
1748 extern TransitionTable *
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 *
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 }