Add Xtensa port
[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 mutiple 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   return;
536 }
537
538
539 void
540 append_condition (tr, cond)
541      TransitionRule *tr;
542      Precondition *cond;
543 {
544   PreconditionList *pl =
545     (PreconditionList *) xmalloc (sizeof (PreconditionList));
546   PreconditionList *prev = tr->conditions;
547   PreconditionList *nxt;
548
549   pl->precond = cond;
550   pl->next = NULL;
551   if (prev == NULL)
552     {
553       tr->conditions = pl;
554       return;
555     }
556   nxt = prev->next;
557   while (nxt != NULL)
558     {
559       prev = nxt;
560       nxt = nxt->next;
561     }
562   prev->next = pl;
563 }
564
565
566 void
567 append_value_condition (tr, cmp, op1, op2)
568      TransitionRule *tr;
569      CmpOp cmp;
570      unsigned op1;
571      unsigned op2;
572 {
573   Precondition *cond = (Precondition *) xmalloc (sizeof (Precondition));
574
575   cond->cmp = cmp;
576   cond->op_num = op1;
577   cond->typ = OP_OPERAND;
578   cond->op_data = op2;
579   append_condition (tr, cond);
580 }
581
582
583 void
584 append_constant_value_condition (tr, cmp, op1, cnst)
585      TransitionRule *tr;
586      CmpOp cmp;
587      unsigned op1;
588      unsigned cnst;
589 {
590   Precondition *cond = (Precondition *) xmalloc (sizeof (Precondition));
591
592   cond->cmp = cmp;
593   cond->op_num = op1;
594   cond->typ = OP_CONSTANT;
595   cond->op_data = cnst;
596   append_condition (tr, cond);
597 }
598
599
600 void
601 append_build_insn (tr, bi)
602      TransitionRule *tr;
603      BuildInstr *bi;
604 {
605   BuildInstr *prev = tr->to_instr;
606   BuildInstr *nxt;
607
608   bi->next = NULL;
609   if (prev == NULL)
610     {
611       tr->to_instr = bi;
612       return;
613     }
614   nxt = prev->next;
615   while (nxt != 0)
616     {
617       prev = nxt;
618       nxt = prev->next;
619     }
620   prev->next = bi;
621 }
622
623
624 void
625 append_op (bi, b_op)
626      BuildInstr *bi;
627      BuildOp *b_op;
628 {
629   BuildOp *prev = bi->ops;
630   BuildOp *nxt;
631
632   if (prev == NULL)
633     {
634       bi->ops = b_op;
635       return;
636     }
637   nxt = prev->next;
638   while (nxt != NULL)
639     {
640       prev = nxt;
641       nxt = nxt->next;
642     }
643   prev->next = b_op;
644 }
645
646
647 void
648 append_literal_op (bi, op1, litnum)
649      BuildInstr *bi;
650      unsigned op1;
651      unsigned litnum;
652 {
653   BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
654
655   b_op->op_num = op1;
656   b_op->typ = OP_LITERAL;
657   b_op->op_data = litnum;
658   b_op->next = NULL;
659   append_op (bi, b_op);
660 }
661
662
663 void
664 append_label_op (bi, op1, labnum)
665      BuildInstr *bi;
666      unsigned op1;
667      unsigned labnum;
668 {
669   BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
670
671   b_op->op_num = op1;
672   b_op->typ = OP_LABEL;
673   b_op->op_data = labnum;
674   b_op->next = NULL;
675   append_op (bi, b_op);
676 }
677
678
679 void
680 append_constant_op (bi, op1, cnst)
681      BuildInstr *bi;
682      unsigned op1;
683      unsigned cnst;
684 {
685   BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
686
687   b_op->op_num = op1;
688   b_op->typ = OP_CONSTANT;
689   b_op->op_data = cnst;
690   b_op->next = NULL;
691   append_op (bi, b_op);
692 }
693
694
695 void
696 append_field_op (bi, op1, src_op)
697      BuildInstr *bi;
698      unsigned op1;
699      unsigned src_op;
700 {
701   BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
702
703   b_op->op_num = op1;
704   b_op->typ = OP_OPERAND;
705   b_op->op_data = src_op;
706   b_op->next = NULL;
707   append_op (bi, b_op);
708 }
709
710
711 /* These could be generated but are not currently.  */
712
713 void
714 append_user_fn_field_op (bi, op1, typ, src_op)
715      BuildInstr *bi;
716      unsigned op1;
717      OpType typ;
718      unsigned src_op;
719 {
720   BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp));
721
722   b_op->op_num = op1;
723   b_op->typ = typ;
724   b_op->op_data = src_op;
725   b_op->next = NULL;
726   append_op (bi, b_op);
727 }
728
729
730 /* These operand functions are the semantics of user-defined
731    operand functions.  */
732
733 long
734 operand_function_HI24S (a)
735      long a;
736 {
737   if (a & 0x80)
738     return (a & (~0xff)) + 0x100;
739   else
740     return (a & (~0xff));
741 }
742
743
744 long
745 operand_function_F32MINUS (a)
746      long a;
747 {
748   return (32 - a);
749 }
750
751
752 long
753 operand_function_LOW8 (a)
754      long a;
755 {
756   if (a & 0x80)
757     return (a & 0xff) | ~0xff;
758   else
759     return (a & 0xff);
760 }
761
762
763 bfd_boolean
764 xg_has_userdef_op_fn (op)
765      OpType op;
766 {
767   switch (op)
768     {
769     case OP_OPERAND_F32MINUS:
770     case OP_OPERAND_LOW8:
771     case OP_OPERAND_HI24S:
772       return TRUE;
773     default:
774       break;
775     }
776   return FALSE;
777 }
778
779
780 long
781 xg_apply_userdef_op_fn (op, a)
782      OpType op;
783      long a;
784 {
785   switch (op)
786     {
787     case OP_OPERAND_F32MINUS:
788       return operand_function_F32MINUS (a);
789     case OP_OPERAND_LOW8:
790       return operand_function_LOW8 (a);
791     case OP_OPERAND_HI24S:
792       return operand_function_HI24S (a);
793     default:
794       break;
795     }
796   return FALSE;
797 }
798
799
800 /* Generate a transition table.  */
801
802 const char *
803 enter_opname_n (name, len)
804      const char *name;
805      size_t len;
806 {
807   opname_e *op;
808
809   for (op = local_opnames; op != NULL; op = op->next)
810     {
811       if (strlen (op->opname) == len && strncmp (op->opname, name, len) == 0)
812         return op->opname;
813     }
814   op = (opname_e *) xmalloc (sizeof (opname_e));
815   op->opname = (char *) xmalloc (len + 1);
816   strncpy (op->opname, name, len);
817   op->opname[len] = '\0';
818   return op->opname;
819 }
820
821
822 static const char *
823 enter_opname (name)
824      const char *name;
825 {
826   opname_e *op;
827
828   for (op = local_opnames; op != NULL; op = op->next)
829     {
830       if (strcmp (op->opname, name) == 0)
831         return op->opname;
832     }
833   op = (opname_e *) xmalloc (sizeof (opname_e));
834   op->opname = strdup (name);
835   return op->opname;
836 }
837
838
839 void
840 init_opname_map (m)
841      opname_map *m;
842 {
843   m->head = NULL;
844   m->tail = &m->head;
845 }
846
847
848 void
849 clear_opname_map (m)
850      opname_map *m;
851 {
852   opname_map_e *e;
853
854   while (m->head != NULL)
855     {
856       e = m->head;
857       m->head = e->next;
858       free (e);
859     }
860   m->tail = &m->head;
861 }
862
863
864 static bfd_boolean
865 same_operand_name (m1, m2)
866      const opname_map_e *m1;
867      const opname_map_e *m2;
868 {
869   if (m1->operand_name == NULL || m1->operand_name == NULL)
870     return FALSE;
871   return (m1->operand_name == m2->operand_name);
872 }
873
874
875 opname_map_e *
876 get_opmatch (map, operand_name)
877      opname_map *map;
878      const char *operand_name;
879 {
880   opname_map_e *m;
881
882   for (m = map->head; m != NULL; m = m->next)
883     {
884       if (strcmp (m->operand_name, operand_name) == 0)
885         return m;
886     }
887   return NULL;
888 }
889
890
891 bfd_boolean
892 op_is_constant (m1)
893      const opname_map_e *m1;
894 {
895   return (m1->operand_name == NULL);
896 }
897
898
899 static unsigned
900 op_get_constant (m1)
901      const opname_map_e *m1;
902 {
903   assert (m1->operand_name == NULL);
904   return m1->constant_value;
905 }
906
907
908 void
909 init_precond_list (l)
910      precond_list *l;
911 {
912   l->head = NULL;
913   l->tail = &l->head;
914 }
915
916
917 void
918 clear_precond_list (l)
919      precond_list *l;
920 {
921   precond_e *e;
922
923   while (l->head != NULL)
924     {
925       e = l->head;
926       l->head = e->next;
927       free (e);
928     }
929   l->tail = &l->head;
930 }
931
932
933 void
934 init_insn_templ (t)
935      insn_templ *t;
936 {
937   t->opcode_name = NULL;
938   init_opname_map (&t->operand_map);
939 }
940
941
942 void
943 clear_insn_templ (t)
944      insn_templ *t;
945 {
946   clear_opname_map (&t->operand_map);
947 }
948
949
950 void
951 init_insn_pattern (p)
952      insn_pattern *p;
953 {
954   init_insn_templ (&p->t);
955   init_precond_list (&p->preconds);
956 }
957
958
959 void
960 clear_insn_pattern (p)
961      insn_pattern *p;
962 {
963   clear_insn_templ (&p->t);
964   clear_precond_list (&p->preconds);
965 }
966
967
968 void
969 init_insn_repl (r)
970      insn_repl *r;
971 {
972   r->head = NULL;
973   r->tail = &r->head;
974 }
975
976
977 void
978 clear_insn_repl (r)
979      insn_repl *r;
980 {
981   insn_repl_e *e;
982
983   while (r->head != NULL)
984     {
985       e = r->head;
986       r->head = e->next;
987       clear_insn_templ (&e->t);
988     }
989   r->tail = &r->head;
990 }
991
992
993 static size_t
994 insn_templ_operand_count (t)
995      const insn_templ *t;
996 {
997   size_t i = 0;
998   const opname_map_e *op;
999
1000   for (op = t->operand_map.head; op != NULL; op = op->next, ++i)
1001     ;
1002   return i;
1003 }
1004
1005
1006 /* Convert a string to a number.  E.G.: parse_constant("10", &num) */
1007
1008 bfd_boolean
1009 parse_constant (in, val_p)
1010      const char *in;
1011      unsigned *val_p;
1012 {
1013   unsigned val = 0;
1014   const char *p;
1015
1016   if (in == NULL)
1017     return FALSE;
1018   p = in;
1019
1020   while (*p != '\0')
1021     {
1022       if (*p >= '0' && *p <= '9')
1023         val = val * 10 + (*p - '0');
1024       else
1025         return FALSE;
1026       ++p;
1027     }
1028   *val_p = val;
1029   return TRUE;
1030 }
1031
1032
1033 /* Match a pattern like "foo1" with
1034    parse_id_constant("foo1", "foo", &num).
1035    This may also be used to just match a number.  */
1036
1037 bfd_boolean
1038 parse_id_constant (in, name, val_p)
1039      const char *in;
1040      const char *name;
1041      unsigned *val_p;
1042 {
1043   unsigned namelen = 0;
1044   const char *p;
1045
1046   if (in == NULL)
1047     return FALSE;
1048
1049   if (name != NULL)
1050     namelen = strlen (name);
1051
1052   if (name != NULL && strncmp (in, name, namelen) != 0)
1053     return FALSE;
1054
1055   p = &in[namelen];
1056   return parse_constant (p, val_p);
1057 }
1058
1059
1060 static bfd_boolean
1061 parse_special_fn (name, fn_name_p, arg_name_p)
1062      const char *name;
1063      const char **fn_name_p;
1064      const char **arg_name_p;
1065 {
1066   char *p_start;
1067   const char *p_end;
1068
1069   p_start = strchr (name, '(');
1070   if (p_start == NULL)
1071     return FALSE;
1072
1073   p_end = strchr (p_start, ')');
1074
1075   if (p_end == NULL)
1076     return FALSE;
1077
1078   if (p_end[1] != '\0')
1079     return FALSE;
1080
1081   *fn_name_p = enter_opname_n (name, p_start - name);
1082   *arg_name_p = enter_opname_n (p_start + 1, p_end - p_start - 1);
1083   return TRUE;
1084 }
1085
1086
1087 const char *
1088 skip_white (p)
1089      const char *p;
1090 {
1091   if (p == NULL)
1092     return p;
1093   while (*p == ' ')
1094     ++p;
1095   return p;
1096 }
1097
1098
1099 void
1100 trim_whitespace (in)
1101      char *in;
1102 {
1103   char *last_white = NULL;
1104   char *p = in;
1105
1106   while (p && *p != '\0')
1107     {
1108       while (*p == ' ')
1109         {
1110           if (last_white == NULL)
1111             last_white = p;
1112           p++;
1113         }
1114       if (*p != '\0')
1115         {
1116           last_white = NULL;
1117           p++;
1118         }
1119     }
1120   if (last_white)
1121     *last_white = '\0';
1122 }
1123
1124
1125 /* Split a string into component strings where "c" is the
1126    delimiter.  Place the result in the split_rec.  */
1127
1128 void
1129 split_string (rec, in, c, elide_whitespace)
1130      split_rec *rec;
1131      const char *in;
1132      char c;
1133      bfd_boolean elide_whitespace;
1134 {
1135   size_t cnt = 0;
1136   size_t i;
1137   const char *p = in;
1138
1139   while (p != NULL && *p != '\0')
1140     {
1141       cnt++;
1142       p = strchr (p, c);
1143       if (p)
1144         p++;
1145     }
1146   rec->count = cnt;
1147   rec->vec = NULL;
1148
1149   if (rec->count == 0)
1150     return;
1151
1152   rec->vec = (char **) xmalloc (sizeof (char *) * cnt);
1153   for (i = 0; i < cnt; i++)
1154     rec->vec[i] = 0;
1155
1156   p = in;
1157   for (i = 0; i < cnt; i++)
1158     {
1159       const char *q;
1160       size_t len;
1161
1162       q = p;
1163       if (elide_whitespace)
1164         q = skip_white (q);
1165
1166       p = strchr (q, c);
1167       if (p == NULL)
1168         rec->vec[i] = strdup (q);
1169       else
1170         {
1171           len = p - q;
1172           rec->vec[i] = (char *) xmalloc (sizeof (char) * (len + 1));
1173           strncpy (rec->vec[i], q, len);
1174           rec->vec[i][len] = '\0';
1175           p++;
1176         }
1177
1178       if (elide_whitespace)
1179         trim_whitespace (rec->vec[i]);
1180     }
1181 }
1182
1183
1184 void
1185 clear_split_rec (rec)
1186      split_rec *rec;
1187 {
1188   size_t i;
1189
1190   for (i = 0; i < rec->count; ++i)
1191     free (rec->vec[i]);
1192
1193   if (rec->count > 0)
1194     free (rec->vec);
1195 }
1196
1197
1198 void
1199 init_split_rec (rec)
1200      split_rec *rec;
1201 {
1202   rec->vec = NULL;
1203   rec->count = 0;
1204 }
1205
1206
1207 /* Parse an instruction template like "insn op1, op2, op3".  */
1208
1209 bfd_boolean
1210 parse_insn_templ (s, t)
1211      const char *s;
1212      insn_templ *t;
1213 {
1214   const char *p = s;
1215   /* First find the first whitespace.  */
1216   size_t insn_name_len;
1217   split_rec oprec;
1218   size_t i;
1219
1220   init_split_rec (&oprec);
1221
1222   p = skip_white (p);
1223   insn_name_len = strcspn (s, " ");
1224   if (insn_name_len == 0)
1225     return FALSE;
1226
1227   init_insn_templ (t);
1228   t->opcode_name = enter_opname_n (p, insn_name_len);
1229
1230   p = p + insn_name_len;
1231
1232   /* Split by ',' and skip beginning and trailing whitespace.  */
1233   split_string (&oprec, p, ',', TRUE);
1234
1235   for (i = 0; i < oprec.count; i++)
1236     {
1237       const char *opname = oprec.vec[i];
1238       opname_map_e *e = (opname_map_e *) xmalloc (sizeof (opname_map_e));
1239       e->next = NULL;
1240       e->operand_name = NULL;
1241       e->constant_value = 0;
1242       e->operand_num = i;
1243
1244       /* If it begins with a number, assume that it is a number.  */
1245       if (opname && opname[0] >= '0' && opname[0] <= '9')
1246         {
1247           unsigned val;
1248
1249           if (parse_constant (opname, &val))
1250             e->constant_value = val;
1251           else
1252             {
1253               free (e);
1254               clear_split_rec (&oprec);
1255               clear_insn_templ (t);
1256               return FALSE;
1257             }
1258         }
1259       else
1260         e->operand_name = enter_opname (oprec.vec[i]);
1261
1262       *t->operand_map.tail = e;
1263       t->operand_map.tail = &e->next;
1264     }
1265   clear_split_rec (&oprec);
1266   return TRUE;
1267 }
1268
1269
1270 bfd_boolean
1271 parse_precond (s, precond)
1272      const char *s;
1273      precond_e *precond;
1274 {
1275   /* All preconditions are currently of the form:
1276      a == b or a != b or a == k (where k is a constant).
1277      Later we may use some special functions like DENSITY == 1
1278      to identify when density is available.  */
1279
1280   const char *p = s;
1281   size_t len;
1282   precond->opname1 = NULL;
1283   precond->opval1 = 0;
1284   precond->cmpop = OP_EQUAL;
1285   precond->opname2 = NULL;
1286   precond->opval2 = 0;
1287   precond->next = NULL;
1288
1289   p = skip_white (p);
1290
1291   len = strcspn (p, " !=");
1292
1293   if (len == 0)
1294     return FALSE;
1295
1296   precond->opname1 = enter_opname_n (p, len);
1297   p = p + len;
1298   p = skip_white (p);
1299
1300   /* Check for "==" and "!=".  */
1301   if (strncmp (p, "==", 2) == 0)
1302     precond->cmpop = OP_EQUAL;
1303   else if (strncmp (p, "!=", 2) == 0)
1304     precond->cmpop = OP_NOTEQUAL;
1305   else
1306     return FALSE;
1307
1308   p = p + 2;
1309   p = skip_white (p);
1310
1311   /* No trailing whitespace from earlier parsing.  */
1312   if (p[0] >= '0' && p[0] <= '9')
1313     {
1314       unsigned val;
1315       if (parse_constant (p, &val))
1316         precond->opval2 = val;
1317       else
1318         return FALSE;
1319     }
1320   else
1321     precond->opname2 = enter_opname (p);
1322   return TRUE;
1323 }
1324
1325
1326 /* Parse a string like:
1327    "insn op1, op2, op3, op4 | op1 != op2 | op2 == op3 | op4 == 1".
1328    I.E., instruction "insn" with 4 operands where operand 1 and 2 are not
1329    the same and operand 2 and 3 are the same and operand 4 is 1.  */
1330
1331 bfd_boolean
1332 parse_insn_pattern (in, insn)
1333      const char *in;
1334      insn_pattern *insn;
1335 {
1336
1337   split_rec rec;
1338   size_t i;
1339
1340   init_split_rec (&rec);
1341   init_insn_pattern (insn);
1342
1343   split_string (&rec, in, '|', TRUE);
1344
1345   if (rec.count == 0)
1346     {
1347       clear_split_rec (&rec);
1348       return FALSE;
1349     }
1350
1351   if (!parse_insn_templ (rec.vec[0], &insn->t))
1352     {
1353       clear_split_rec (&rec);
1354       return FALSE;
1355     }
1356
1357   for (i = 1; i < rec.count; i++)
1358     {
1359       precond_e *cond = (precond_e *) xmalloc (sizeof (precond_e));
1360
1361       if (!parse_precond (rec.vec[i], cond))
1362         {
1363           clear_split_rec (&rec);
1364           clear_insn_pattern (insn);
1365           return FALSE;
1366         }
1367
1368       /* Append the condition.  */
1369       *insn->preconds.tail = cond;
1370       insn->preconds.tail = &cond->next;
1371     }
1372
1373   clear_split_rec (&rec);
1374   return TRUE;
1375 }
1376
1377
1378 bfd_boolean
1379 parse_insn_repl (in, r_p)
1380      const char *in;
1381      insn_repl *r_p;
1382 {
1383   /* This is a list of instruction templates separated by ';'.  */
1384   split_rec rec;
1385   size_t i;
1386
1387   split_string (&rec, in, ';', TRUE);
1388
1389   for (i = 0; i < rec.count; i++)
1390     {
1391       insn_repl_e *e = (insn_repl_e *) xmalloc (sizeof (insn_repl_e));
1392
1393       e->next = NULL;
1394
1395       if (!parse_insn_templ (rec.vec[i], &e->t))
1396         {
1397           free (e);
1398           clear_insn_repl (r_p);
1399           return FALSE;
1400         }
1401       *r_p->tail = e;
1402       r_p->tail = &e->next;
1403     }
1404   return TRUE;
1405 }
1406
1407
1408 TransitionRule *
1409 build_transition (initial_insn, replace_insns, from_string, to_string)
1410      insn_pattern *initial_insn;
1411      insn_repl *replace_insns;
1412      const char *from_string;
1413      const char *to_string;
1414 {
1415   TransitionRule *tr = NULL;
1416   xtensa_opcode opcode;
1417   xtensa_isa isa = xtensa_default_isa;
1418
1419   opname_map_e *op1;
1420   opname_map_e *op2;
1421
1422   precond_e *precond;
1423   insn_repl_e *r;
1424   unsigned label_count = 0;
1425   unsigned max_label_count = 0;
1426   bfd_boolean has_label = FALSE;
1427   unsigned literal_count = 0;
1428
1429   opcode = xtensa_opcode_lookup (isa, initial_insn->t.opcode_name);
1430   if (opcode == XTENSA_UNDEFINED)
1431     {
1432       /* It is OK to not be able to translate some of these opcodes.  */
1433 #if 0
1434       as_warn (_("Invalid opcode '%s' in transition rule '%s'\n"),
1435                initial_insn->t.opcode_name, to_string);
1436 #endif
1437       return NULL;
1438     }
1439
1440
1441   if (xtensa_num_operands (isa, opcode)
1442       != (int) insn_templ_operand_count (&initial_insn->t))
1443     {
1444       /* This is also OK because there are opcodes that
1445          have different numbers of operands on different
1446          architecture variations.  */
1447 #if 0
1448       as_fatal (_("opcode %s mismatched operand count %d != expected %d"),
1449                 xtensa_opcode_name (isa, opcode),
1450                 xtensa_num_operands (isa, opcode),
1451                 insn_templ_operand_count (&initial_insn->t));
1452 #endif
1453       return NULL;
1454     }
1455
1456   tr = (TransitionRule *) xmalloc (sizeof (TransitionRule));
1457   tr->opcode = opcode;
1458   tr->conditions = NULL;
1459   tr->to_instr = NULL;
1460
1461   /* Build the conditions. First, equivalent operand condition....  */
1462   for (op1 = initial_insn->t.operand_map.head; op1 != NULL; op1 = op1->next)
1463     {
1464       for (op2 = op1->next; op2 != NULL; op2 = op2->next)
1465         {
1466           if (same_operand_name (op1, op2))
1467             {
1468               append_value_condition (tr, OP_EQUAL,
1469                                       op1->operand_num, op2->operand_num);
1470             }
1471         }
1472     }
1473
1474   /* Now the condition that an operand value must be a constant....  */
1475   for (op1 = initial_insn->t.operand_map.head; op1 != NULL; op1 = op1->next)
1476     {
1477       if (op_is_constant (op1))
1478         {
1479           append_constant_value_condition (tr,
1480                                            OP_EQUAL,
1481                                            op1->operand_num,
1482                                            op_get_constant (op1));
1483         }
1484     }
1485
1486
1487   /* Now add the explicit preconditions listed after the "|" in the spec.
1488      These are currently very limited, so we do a special case
1489      parse for them.  We expect spaces, opname != opname.  */
1490   for (precond = initial_insn->preconds.head;
1491        precond != NULL;
1492        precond = precond->next)
1493     {
1494       op1 = NULL;
1495       op2 = NULL;
1496
1497       if (precond->opname1)
1498         {
1499           op1 = get_opmatch (&initial_insn->t.operand_map, precond->opname1);
1500           if (op1 == NULL)
1501             {
1502               as_fatal (_("opcode '%s': no bound opname '%s' "
1503                           "for precondition in '%s'"),
1504                         xtensa_opcode_name (isa, opcode),
1505                         precond->opname1, from_string);
1506               return NULL;
1507             }
1508         }
1509
1510       if (precond->opname2)
1511         {
1512           op2 = get_opmatch (&initial_insn->t.operand_map, precond->opname2);
1513           if (op2 == NULL)
1514             {
1515               as_fatal (_("opcode '%s': no bound opname '%s' "
1516                           "for precondition in %s"),
1517                        xtensa_opcode_name (isa, opcode),
1518                        precond->opname2, from_string);
1519               return NULL;
1520             }
1521         }
1522
1523       if (op1 == NULL && op2 == NULL)
1524         {
1525           as_fatal (_("opcode '%s': precondition only contains "
1526                       "constants in '%s'"),
1527                     xtensa_opcode_name (isa, opcode), from_string);
1528           return NULL;
1529         }
1530       else if (op1 != NULL && op2 != NULL)
1531         append_value_condition (tr, precond->cmpop,
1532                                 op1->operand_num, op2->operand_num);
1533       else if (op2 == NULL)
1534         append_constant_value_condition (tr, precond->cmpop,
1535                                          op1->operand_num, precond->opval1);
1536       else
1537         append_constant_value_condition (tr, precond->cmpop,
1538                                          op2->operand_num, precond->opval2);
1539     }
1540
1541   /* Generate the replacement instructions.  Some of these
1542      "instructions" are actually labels and literals.  The literals
1543      must be defined in order 0..n and a literal must be defined
1544      (e.g., "LITERAL0 %imm") before use (e.g., "%LITERAL0").  The
1545      labels must be defined in order, but they can be used before they
1546      are defined.  Also there are a number of special operands (e.g.,
1547      HI24S).  */
1548
1549   for (r = replace_insns->head; r != NULL; r = r->next)
1550     {
1551       BuildInstr *bi;
1552       const char *opcode_name;
1553       size_t operand_count;
1554       opname_map_e *op;
1555       unsigned idnum = 0;
1556       const char *fn_name;
1557       const char *operand_arg_name;
1558
1559       bi = (BuildInstr *) xmalloc (sizeof (BuildInstr));
1560       append_build_insn (tr, bi);
1561
1562       bi->id = 0;
1563       bi->opcode = XTENSA_UNDEFINED;
1564       bi->ops = NULL;
1565       bi->next = NULL;
1566
1567       opcode_name = r->t.opcode_name;
1568       operand_count = insn_templ_operand_count (&r->t);
1569
1570       if (parse_id_constant (opcode_name, "LITERAL", &idnum))
1571         {
1572           bi->typ = INSTR_LITERAL_DEF;
1573           bi->id = idnum;
1574           if (idnum != literal_count)
1575             as_fatal (_("generated literals must be numbered consecutively"));
1576           ++literal_count;
1577           if (operand_count != 1)
1578             as_fatal (_("expected one operand for generated literal"));
1579
1580         }
1581       else if (parse_id_constant (opcode_name, "LABEL", &idnum))
1582         {
1583           bi->typ = INSTR_LABEL_DEF;
1584           bi->id = idnum;
1585           if (idnum != label_count)
1586             as_fatal (_("generated labels must be numbered consecutively"));
1587           ++label_count;
1588           if (operand_count != 0)
1589             as_fatal (_("expected 0 operands for generated label"));
1590         }
1591       else
1592         {
1593           bi->typ = INSTR_INSTR;
1594           bi->opcode = xtensa_opcode_lookup (isa, r->t.opcode_name);
1595           if (bi->opcode == XTENSA_UNDEFINED)
1596             return NULL;
1597           /* Check for the right number of ops.  */
1598           if (xtensa_num_operands (isa, bi->opcode) 
1599               != (int) operand_count)
1600             as_fatal (_("opcode '%s': replacement does not have %d ops"),
1601                       opcode_name, xtensa_num_operands (isa, bi->opcode));
1602         }
1603
1604       for (op = r->t.operand_map.head; op != NULL; op = op->next)
1605         {
1606           unsigned idnum;
1607
1608           if (op_is_constant (op))
1609             append_constant_op (bi, op->operand_num, op_get_constant (op));
1610           else if (parse_id_constant (op->operand_name, "%LITERAL", &idnum))
1611             {
1612               if (idnum >= literal_count)
1613                 as_fatal (_("opcode %s: replacement "
1614                             "literal %d >= literal_count(%d)"),
1615                           opcode_name, idnum, literal_count);
1616               append_literal_op (bi, op->operand_num, idnum);
1617             }
1618           else if (parse_id_constant (op->operand_name, "%LABEL", &idnum))
1619             {
1620               has_label = TRUE;
1621               if (idnum > max_label_count)
1622                 max_label_count = idnum;
1623               append_label_op (bi, op->operand_num, idnum);
1624             }
1625           else if (parse_id_constant (op->operand_name, "a", &idnum))
1626             append_constant_op (bi, op->operand_num, idnum);
1627           else if (op->operand_name[0] == '%')
1628             {
1629               opname_map_e *orig_op;
1630               orig_op = get_opmatch (&initial_insn->t.operand_map,
1631                                      op->operand_name);
1632               if (orig_op == NULL)
1633                 {
1634                   as_fatal (_("opcode %s: unidentified operand '%s' in '%s'"),
1635                             opcode_name, op->operand_name, to_string);
1636
1637                   append_constant_op (bi, op->operand_num, 0);
1638                 }
1639               else
1640                 append_field_op (bi, op->operand_num, orig_op->operand_num);
1641             }
1642           else if (parse_special_fn (op->operand_name,
1643                                      &fn_name, &operand_arg_name))
1644             {
1645               opname_map_e *orig_op;
1646               OpType typ = OP_CONSTANT;
1647
1648               if (strcmp (fn_name, "LOW8") == 0)
1649                 typ = OP_OPERAND_LOW8;
1650               else if (strcmp (fn_name, "HI24S") == 0)
1651                 typ = OP_OPERAND_HI24S;
1652               else if (strcmp (fn_name, "F32MINUS") == 0)
1653                 typ = OP_OPERAND_F32MINUS;
1654               else
1655                 as_fatal (_("unknown user defined function %s"), fn_name);
1656
1657               orig_op = get_opmatch (&initial_insn->t.operand_map,
1658                                      operand_arg_name);
1659               if (orig_op == NULL)
1660                 {
1661                   as_fatal (_("opcode %s: unidentified operand '%s' in '%s'"),
1662                             opcode_name, op->operand_name, to_string);
1663                   append_constant_op (bi, op->operand_num, 0);
1664                 }
1665               else
1666                 append_user_fn_field_op (bi, op->operand_num,
1667                                          typ, orig_op->operand_num);
1668             }
1669           else
1670             {
1671               as_fatal (_("opcode %s: could not parse operand '%s' in '%s'"),
1672                         opcode_name, op->operand_name, to_string);
1673               append_constant_op (bi, op->operand_num, 0);
1674             }
1675         }
1676     }
1677   if (has_label && max_label_count >= label_count)
1678     {
1679       as_fatal (_("opcode %s: replacement label %d >= label_count(%d)"),
1680                 xtensa_opcode_name (isa, opcode),
1681                 max_label_count, label_count);
1682       return NULL;
1683     }
1684
1685   return tr;
1686 }
1687
1688
1689 TransitionTable *
1690 build_transition_table (transitions, transition_count)
1691      const string_pattern_pair *transitions;
1692      size_t transition_count;
1693 {
1694   TransitionTable *table = NULL;
1695   int num_opcodes = xtensa_num_opcodes (xtensa_default_isa);
1696   int i;
1697   size_t tnum;
1698
1699   if (table != NULL)
1700     return table;
1701
1702   /* Otherwise, build it now.  */
1703   table = (TransitionTable *) xmalloc (sizeof (TransitionTable));
1704   table->num_opcodes = num_opcodes;
1705   table->table =
1706     (TransitionList **) xmalloc (sizeof (TransitionTable *) * num_opcodes);
1707
1708   for (i = 0; i < num_opcodes; i++)
1709     table->table[i] = NULL;
1710
1711   for (tnum = 0; tnum < transition_count; tnum++)
1712     {
1713       const char *from_string = transitions[tnum].pattern;
1714       const char *to_string = transitions[tnum].replacement;
1715
1716       insn_pattern initial_insn;
1717       insn_repl replace_insns;
1718       TransitionRule *tr;
1719
1720       init_insn_pattern (&initial_insn);
1721       if (!parse_insn_pattern (from_string, &initial_insn))
1722         {
1723           as_fatal (_("could not parse INSN_PATTERN '%s'"), from_string);
1724           clear_insn_pattern (&initial_insn);
1725           continue;
1726         }
1727
1728       init_insn_repl (&replace_insns);
1729       if (!parse_insn_repl (to_string, &replace_insns))
1730         {
1731           as_fatal (_("could not parse INSN_REPL '%s'"), to_string);
1732           clear_insn_pattern (&initial_insn);
1733           clear_insn_repl (&replace_insns);
1734           continue;
1735         }
1736
1737       tr = build_transition (&initial_insn, &replace_insns,
1738                              from_string, to_string);
1739       if (tr)
1740         append_transition (table, tr->opcode, tr);
1741
1742       clear_insn_repl (&replace_insns);
1743       clear_insn_pattern (&initial_insn);
1744     }
1745   return table;
1746 }
1747
1748 \f
1749 extern TransitionTable *
1750 xg_build_widen_table ()
1751 {
1752   static TransitionTable *table = NULL;
1753   if (table == NULL)
1754     table = build_transition_table (widen_spec_list, WIDEN_COUNT);
1755   return table;
1756 }
1757
1758
1759 extern TransitionTable *
1760 xg_build_simplify_table ()
1761 {
1762   static TransitionTable *table = NULL;
1763   if (table == NULL)
1764     table = build_transition_table (simplify_spec_list, SIMPLIFY_COUNT);
1765   return table;
1766 }