de8861906651ed26dcfcfcfd280f3cd5bdcfd221
[platform/upstream/binutils.git] / sim / igen / gen.c
1 /*  This file is part of the program psim.
2
3     Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14  
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  
19     */
20
21
22 #include "misc.h"
23 #include "lf.h"
24 #include "table.h"
25 #include "filter.h"
26
27 #include "igen.h"
28 #include "ld-insn.h"
29 #include "ld-decode.h"
30 #include "gen.h"
31
32 static insn_uint
33 sub_val (insn_uint val,
34          int val_last_pos,
35          int first_pos,
36          int last_pos)
37 {
38   return ((val >> (val_last_pos - last_pos))
39           & (((insn_uint)1 << (last_pos - first_pos + 1)) - 1));
40 }
41
42 static void
43 update_depth (lf *file,
44               gen_entry *entry,
45               int depth,
46               void *data)
47 {
48   int *max_depth = (int*)data;
49   if (*max_depth < depth)
50     *max_depth = depth;
51 }
52
53
54 int
55 gen_entry_depth (gen_entry *table)
56 {
57   int depth = 0;
58   gen_entry_traverse_tree (NULL,
59                            table,
60                            1,
61                            NULL, /*start*/
62                            update_depth,
63                            NULL, /*end*/
64                            &depth); /* data */
65   return depth;
66 }
67
68
69 static void
70 print_gen_entry_path (line_ref *line,
71                       gen_entry *table,
72                       error_func *print)
73 {
74   if (table->parent == NULL)
75     {
76       if (table->top->model != NULL)
77         print (line, "%s", table->top->model->name);
78       else
79         print (line, "");
80     }
81   else
82     {
83       print_gen_entry_path (line, table->parent, print);
84       print (NULL, ".%d", table->opcode_nr);
85     }
86 }
87
88 static void
89 print_gen_entry_insns (gen_entry *table,
90                        error_func *print,
91                        char *first_message,
92                        char *next_message)
93 {
94   insn_list *i;
95   char *message;
96   message = first_message;
97   for (i = table->insns; i != NULL; i = i->next)
98     {
99       insn_entry *insn = i->insn;
100       print_gen_entry_path (insn->line, table, print);
101       print (NULL, ": %s.%s %s\n",
102              insn->format_name,
103              insn->name,
104              message);
105       if (next_message != NULL)
106         message = next_message;
107     }
108 }
109
110 /* same as strcmp */
111 static int
112 insn_field_cmp (insn_word_entry *l, insn_word_entry *r)
113 {
114   while (1)
115     {
116       int bit_nr;
117       if (l == NULL && r == NULL)
118         return 0; /* all previous fields the same */
119       if (l == NULL)
120         return -1; /* left shorter than right */
121       if (r == NULL)
122         return +1; /* left longer than right */
123       for (bit_nr = 0;
124            bit_nr < options.insn_bit_size;
125            bit_nr++)
126         {
127           if (l->bit[bit_nr]->field->type != insn_field_string)
128             continue;
129           if (r->bit[bit_nr]->field->type != insn_field_string)
130             continue;
131           if (l->bit[bit_nr]->field->conditions == NULL)
132             continue;
133           if (r->bit[bit_nr]->field->conditions == NULL)
134             continue;
135           if (0)
136             printf ("%s%s%s VS %s%s%s\n",
137                     l->bit[bit_nr]->field->val_string,
138                     l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq ? "=" : "!",
139                     l->bit[bit_nr]->field->conditions->string,  
140                     r->bit[bit_nr]->field->val_string,
141                     r->bit[bit_nr]->field->conditions->test == insn_field_cond_eq ? "=" : "!",
142                     r->bit[bit_nr]->field->conditions->string);
143           if (l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq
144               && r->bit[bit_nr]->field->conditions->test == insn_field_cond_eq)
145             {
146               if (l->bit[bit_nr]->field->conditions->type == insn_field_cond_field
147                   && r->bit[bit_nr]->field->conditions->type == insn_field_cond_field)
148                 /* somewhat arbitrary */
149                 {
150                   int cmp = strcmp (l->bit[bit_nr]->field->conditions->string,
151                                     r->bit[bit_nr]->field->conditions->string);
152                   if (cmp != 0)
153                     return cmp;
154                   else
155                     continue;
156                 }
157               if (l->bit[bit_nr]->field->conditions->type == insn_field_cond_field)
158                 return +1;
159               if (r->bit[bit_nr]->field->conditions->type == insn_field_cond_field)
160                 return -1;
161               /* The case of both fields having constant values should have
162                  already have been handled because such fields are converted
163                  into normal constant fields. */
164               continue;
165             }
166           if (l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq)
167             return +1; /* left = only */
168           if (r->bit[bit_nr]->field->conditions->test == insn_field_cond_eq)
169             return -1; /* right = only */
170           /* FIXME: Need to some what arbitrarily order conditional lists */
171           continue;
172         }
173       l = l->next;
174       r = r->next;
175     }
176 }
177
178 /* same as strcmp */
179 static int
180 insn_word_cmp (insn_word_entry *l, insn_word_entry *r)
181 {
182   while (1)
183     {
184       int bit_nr;
185       if (l == NULL && r == NULL)
186         return 0; /* all previous fields the same */
187       if (l == NULL)
188         return -1; /* left shorter than right */
189       if (r == NULL)
190         return +1; /* left longer than right */
191       for (bit_nr = 0;
192            bit_nr < options.insn_bit_size;
193            bit_nr++)
194         {
195           if (l->bit[bit_nr]->mask < r->bit[bit_nr]->mask)
196             return -1;
197           if (l->bit[bit_nr]->mask > r->bit[bit_nr]->mask)
198             return 1;
199           if (l->bit[bit_nr]->value < r->bit[bit_nr]->value)
200             return -1;
201           if (l->bit[bit_nr]->value > r->bit[bit_nr]->value)
202             return 1;
203         }
204       l = l->next;
205       r = r->next;
206     }
207 }
208
209 /* same as strcmp */
210 static int
211 opcode_bit_cmp (opcode_bits *l,
212                 opcode_bits *r)
213 {
214   if (l == NULL && r == NULL)
215     return 0; /* all previous bits the same */
216   if (l == NULL)
217     return -1; /* left shorter than right */
218   if (r == NULL)
219     return +1; /* left longer than right */
220   /* most significant word */
221   if (l->field->word_nr < r->field->word_nr)
222     return +1; /* left has more significant word */
223   if (l->field->word_nr > r->field->word_nr)
224     return -1; /* right has more significant word */
225   /* most significant bit? */
226   if (l->first < r->first)
227     return +1; /* left as more significant bit */
228   if (l->first > r->first)
229     return -1; /* right as more significant bit */
230   /* nr bits? */
231   if (l->last < r->last)
232     return +1; /* left as less bits */
233   if (l->last > r->last)
234     return -1; /* right as less bits */
235   /* value? */
236   if (l->value < r->value)
237     return -1;
238   if (l->value > r->value)
239     return 1;
240   return 0;
241 }
242
243
244 /* same as strcmp */
245 static int
246 opcode_bits_cmp (opcode_bits *l,
247                  opcode_bits *r)
248 {
249   while (1)
250     {
251       int cmp;
252       if (l == NULL && r == NULL)
253         return 0; /* all previous bits the same */
254       cmp = opcode_bit_cmp (l, r);
255       if (cmp != 0)
256         return cmp;
257       l = l->next;
258       r = r->next;
259     }
260 }
261
262 /* same as strcmp */
263 static opcode_bits *
264 new_opcode_bits (opcode_bits *old_bits,
265                  int value,
266                  int first,
267                  int last,
268                  insn_field_entry *field,
269                  opcode_field *opcode)
270 {
271   opcode_bits *new_bits = ZALLOC (opcode_bits);
272   new_bits->field = field;
273   new_bits->value = value;
274   new_bits->first = first;
275   new_bits->last = last;
276   new_bits->opcode = opcode;
277   
278   if (old_bits != NULL)
279     {
280       opcode_bits *new_list;
281       opcode_bits **last = &new_list;
282       new_list = new_opcode_bits (old_bits->next,
283                                   old_bits->value,
284                                   old_bits->first,
285                                   old_bits->last,
286                                   old_bits->field,
287                                   old_bits->opcode);
288       while (*last != NULL)
289         {
290           int cmp = opcode_bit_cmp (new_bits, *last);
291           if (cmp < 0) /* new < new_list */
292             {
293               break;
294             }
295           if (cmp == 0)
296             {
297               ERROR ("Duplicated insn bits in list");
298             }
299           last = &(*last)->next;
300         }
301       new_bits->next = *last;
302       *last = new_bits;
303       return new_list;
304     }
305   else
306     {
307       return new_bits;
308     }
309 }
310
311
312
313
314 typedef enum {
315   merge_duplicate_insns,
316   report_duplicate_insns,
317 } duplicate_insn_actions;
318
319 static insn_list *
320 insn_list_insert (insn_list **cur_insn_ptr,
321                   int *nr_insns,
322                   insn_entry *insn,
323                   opcode_bits *expanded_bits,
324                   opcode_field *opcodes,
325                   int nr_prefetched_words,
326                   duplicate_insn_actions duplicate_action)
327 {
328   /* insert it according to the order of the fields & bits */
329   for (; (*cur_insn_ptr) != NULL; cur_insn_ptr = &(*cur_insn_ptr)->next)
330     {
331       int cmp;
332
333       /* key#1 sort according to the constant fields of each instruction */
334       cmp = insn_word_cmp (insn->words, (*cur_insn_ptr)->insn->words);
335       if (cmp < 0)
336         break;
337       else if (cmp > 0)
338         continue;
339
340       /* key#2 sort according to the expanded bits of each instruction */
341       cmp = opcode_bits_cmp (expanded_bits, (*cur_insn_ptr)->expanded_bits);
342       if (cmp < 0)
343         break;
344       else if (cmp > 0)
345         continue;
346
347       /* key#3 sort according to the non-constant fields of each instruction */
348       cmp = insn_field_cmp (insn->words, (*cur_insn_ptr)->insn->words);
349       if (cmp < 0)
350         break;
351       else if (cmp > 0)
352         continue;
353
354       /* duplicate keys, report problem */
355       switch (duplicate_action)
356         {
357         case report_duplicate_insns:
358           /* It would appear that we have two instructions with the
359              same constant field values across all words and bits.
360              This error can also occure when insn_field_cmp() is
361              failing to differentiate between two instructions that
362              differ only in their conditional fields. */
363           warning (insn->line,
364                    "Two instructions with identical constant fields\n");
365           error ((*cur_insn_ptr)->insn->line,
366                  "Location of duplicate instruction\n");
367         case merge_duplicate_insns:
368           /* Add the opcode path to the instructions list */
369           if (opcodes != NULL)
370             {
371               insn_opcodes **last = &(*cur_insn_ptr)->opcodes;
372               while (*last != NULL)
373                 {
374                   last = &(*last)->next;
375                 }
376               (*last) = ZALLOC (insn_opcodes);
377               (*last)->opcode = opcodes;
378             }
379           /* Use the larger nr_prefetched_words */
380           if ((*cur_insn_ptr)->nr_prefetched_words < nr_prefetched_words)
381             (*cur_insn_ptr)->nr_prefetched_words = nr_prefetched_words;
382           return (*cur_insn_ptr);
383         }
384
385     }
386   
387   /* create a new list entry and insert it */
388   {
389     insn_list *new_insn = ZALLOC (insn_list);
390     new_insn->insn = insn;
391     new_insn->expanded_bits = expanded_bits;
392     new_insn->next = (*cur_insn_ptr);
393     new_insn->nr_prefetched_words = nr_prefetched_words;
394     if (opcodes != NULL)
395       {
396         new_insn->opcodes = ZALLOC (insn_opcodes);
397         new_insn->opcodes->opcode = opcodes;
398       }
399     (*cur_insn_ptr) = new_insn;
400   }
401   
402   *nr_insns += 1;
403
404   return (*cur_insn_ptr);
405 }
406
407
408 extern void
409 gen_entry_traverse_tree (lf *file,
410                          gen_entry *table,
411                          int depth,
412                          gen_entry_handler *start,
413                          gen_entry_handler *leaf,
414                          gen_entry_handler *end,
415                          void *data)
416 {
417   gen_entry *entry;
418   
419   ASSERT (table != NULL);
420   ASSERT (table->opcode != NULL);
421   ASSERT (table->nr_entries > 0);
422   ASSERT (table->entries != 0);
423   
424   /* prefix */
425   if (start != NULL && depth >= 0)
426     {
427       start (file, table, depth, data);
428     }
429   /* infix leaves */
430   for (entry = table->entries;
431        entry != NULL;
432        entry = entry->sibling)
433     {
434       if (entry->entries != NULL && depth != 0)
435         {
436           gen_entry_traverse_tree (file, entry, depth + 1,
437                                    start, leaf, end, data);
438         }
439       else if (depth >= 0)
440         {
441           if (leaf != NULL)
442             {
443               leaf (file, entry, depth, data);
444             }
445         }
446     }
447   /* postfix */
448   if (end != NULL && depth >= 0)
449     {
450       end (file, table, depth, data);
451     }
452 }
453
454
455
456 /* create a list element containing a single gen_table entry */
457
458 static gen_list *
459 make_table (insn_table *isa,
460             decode_table *rules,
461             model_entry *model)
462 {
463   insn_entry *insn;
464   gen_list *entry = ZALLOC (gen_list);
465   entry->table = ZALLOC (gen_entry);
466   entry->table->top = entry;
467   entry->model = model;
468   entry->isa = isa;
469   for (insn = isa->insns; insn != NULL; insn = insn->next)
470     {
471       if (model == NULL
472           || insn->processors == NULL
473           || filter_is_member (insn->processors, model->name))
474         {
475           insn_list_insert (&entry->table->insns,
476                             &entry->table->nr_insns,
477                             insn,
478                             NULL, /* expanded_bits - none yet */
479                             NULL, /* opcodes - none yet */
480                             0, /* nr_prefetched_words - none yet */
481                             report_duplicate_insns);
482         }
483     }
484   entry->table->opcode_rule = rules;
485   return entry;
486 }
487
488
489 gen_table *
490 make_gen_tables (insn_table *isa,
491                  decode_table *rules)
492 {
493   gen_table *gen = ZALLOC (gen_table);
494   gen->isa = isa;
495   gen->rules = rules;
496   if (options.gen.multi_sim)
497     {
498       gen_list **last = &gen->tables;
499       model_entry *model;
500       filter *processors;
501       if (options.model_filter != NULL)
502         processors = options.model_filter;
503       else
504         processors = isa->model->processors;
505       for (model = isa->model->models;
506            model != NULL;
507            model = model->next)
508         {
509           if (filter_is_member (processors, model->name))
510             {
511               *last = make_table (isa, rules, model);
512               last = &(*last)->next;
513             }
514         }
515     }
516   else
517     {
518       gen->tables = make_table (isa, rules, NULL);
519     }
520   return gen;
521 }
522   
523   
524 /****************************************************************/
525
526 #if 0
527 typedef enum {
528   field_is_not_constant = 0,
529   field_constant_int = 1,
530   field_constant_reserved = 2,
531   field_constant_string = 3
532 } constant_field_types;
533
534 static constant_field_types
535 insn_field_is_constant (insn_field *field,
536                         decode_table *rule)
537 {
538   switch (field->type)
539     {
540     case insn_field_int:
541       /* field is an integer */
542       return field_constant_int;
543     case insn_field_reserved:
544       /* field is `/' and treating that as a constant */
545       if (rule->with_zero_reserved)
546         return field_constant_reserved;
547       else
548         return field_is_not_constant;
549     case insn_field_wild:
550       return field_is_not_constant; /* never constant */
551     case insn_field_string:
552       /* field, though variable, is on the list of forced constants */
553       if (filter_is_member (rule->constant_field_names, field->val_string))
554         return field_constant_string;
555       else
556         return field_is_not_constant;
557     }
558   ERROR ("Internal error");
559   return field_is_not_constant;
560 }
561 #endif
562
563
564 /****************************************************************/
565
566
567 /* Is the bit, according to the decode rule, identical across all the
568    instructions? */
569 static int
570 insns_bit_useless (insn_list *insns,
571                    decode_table *rule,
572                    int bit_nr)
573 {
574   insn_list *entry;
575   int value = -1;
576   int is_useless = 1; /* cleared if something actually found */
577
578   /* check the instructions for some constant value in at least one of
579      the bit fields */
580   for (entry = insns; entry != NULL; entry = entry->next)
581     {
582       insn_word_entry *word = entry->insn->word[rule->word_nr];
583       insn_bit_entry *bit = word->bit[bit_nr];
584       switch (bit->field->type)
585         {
586         case insn_field_invalid:
587           ASSERT (0);
588           break;
589         case insn_field_wild:
590         case insn_field_reserved:
591           /* neither useless or useful - ignore */
592           break;
593         case insn_field_int:
594           switch (rule->search)
595             {
596             case decode_find_strings:
597               /* an integer isn't a string */
598               return 1;
599             case decode_find_constants:
600             case decode_find_mixed:
601               /* an integer is useful if its value isn't the same
602                  between all instructions.  The first time through the
603                  value is saved, the second time through (if the
604                  values differ) it is marked as useful. */
605               if (value < 0)
606                 value = bit->value;
607               else if (value != bit->value)
608                 is_useless = 0;
609               break;
610             }
611           break;
612         case insn_field_string:
613           switch (rule->search)
614             {
615             case decode_find_strings:
616               /* at least one string, keep checking */
617               is_useless = 0;
618               break;
619             case decode_find_constants:
620             case decode_find_mixed:
621               if (filter_is_member (rule->constant_field_names,
622                                     bit->field->val_string))
623                 /* a string field forced to constant? */
624                 is_useless = 0;
625               else if (rule->search == decode_find_constants)
626                 /* the string field isn't constant */
627                 return 1;
628               break;
629             }
630         }
631     }
632
633   /* Given only one constant value has been found, check through all
634      the instructions to see if at least one conditional makes it
635      usefull */
636   if (value >= 0 && is_useless)
637     {
638       for (entry = insns; entry != NULL; entry = entry->next)
639         {
640           insn_word_entry *word = entry->insn->word[rule->word_nr];
641           insn_bit_entry *bit = word->bit[bit_nr];
642           switch (bit->field->type)
643             {
644             case insn_field_invalid:
645               ASSERT (0);
646               break;
647             case insn_field_wild:
648             case insn_field_reserved:
649             case insn_field_int:
650               /* already processed */
651               break;
652             case insn_field_string:
653               switch (rule->search)
654                 {
655                 case decode_find_strings:
656                 case decode_find_constants:
657                   /* already processed */
658                   break;
659                 case decode_find_mixed:
660                   /* string field with conditions.  If this condition
661                      eliminates the value then the compare is useful */
662                   if (bit->field->conditions != NULL)
663                     {
664                       insn_field_cond *condition;
665                       int shift = bit->field->last - bit_nr;
666                       for (condition = bit->field->conditions;
667                            condition != NULL;
668                            condition = condition->next)
669                         {
670                           switch (condition->type)
671                             {
672                             case insn_field_cond_value:
673                               switch (condition->test)
674                                 {
675                                 case insn_field_cond_ne:
676                                   if (((condition->value >> shift) & 1)
677                                       == (unsigned) value)
678                                     /* conditional field excludes the
679                                        current value */
680                                     is_useless = 0;
681                                   break;
682                                 case insn_field_cond_eq:
683                                   if (((condition->value >> shift) & 1)
684                                       != (unsigned) value)
685                                     /* conditional field requires the
686                                        current value */
687                                     is_useless = 0;
688                                   break;
689                                 }
690                               break;
691                             case insn_field_cond_field:
692                               /* are these handled separatly? */
693                               break;
694                             }
695                         }
696                     }
697                 }
698             }
699         }
700     }
701
702   return is_useless;
703 }
704
705
706 /* go through a gen-table's list of instruction formats looking for a
707    range of bits that meet the decode table RULEs requirements */
708
709 static opcode_field *
710 gen_entry_find_opcode_field (insn_list *insns,
711                              decode_table *rule,
712                              int string_only)
713 {
714   opcode_field curr_opcode;
715   ASSERT (rule != NULL);
716
717   memset (&curr_opcode, 0, sizeof (curr_opcode));
718   curr_opcode.word_nr = rule->word_nr;
719   curr_opcode.first = rule->first;
720   curr_opcode.last = rule->last;
721
722   /* Try to reduce the size of first..last in accordance with the
723      decode rules */
724
725   while (curr_opcode.first <= rule->last)
726     {
727       if (insns_bit_useless (insns, rule, curr_opcode.first))
728         curr_opcode.first ++;
729       else
730         break;
731     }
732   while (curr_opcode.last >= rule->first)
733     {
734       if (insns_bit_useless (insns, rule, curr_opcode.last))
735         curr_opcode.last --;
736       else
737         break;
738     }
739
740
741 #if 0
742   for (entry = insns; entry != NULL; entry = entry->next)
743     {
744       insn_word_entry *fields = entry->insn->word[rule->word_nr];
745       opcode_field new_opcode;
746       
747       ASSERT (fields != NULL);
748       
749       /* find a start point for the opcode field */
750       new_opcode.first = rule->first;
751       while (new_opcode.first <= rule->last
752              && (!string_only
753                  || (insn_field_is_constant(fields->bit[new_opcode.first], rule)
754                      != field_constant_string))
755              && (string_only
756                  || (insn_field_is_constant(fields->bit[new_opcode.first], rule)
757                      == field_is_not_constant)))
758         {
759           int new_first = fields->bit[new_opcode.first]->last + 1;
760           ASSERT (new_first > new_opcode.first);
761           new_opcode.first = new_first;
762         }
763       ASSERT(new_opcode.first > rule->last
764              || (string_only
765                  && insn_field_is_constant(fields->bit[new_opcode.first],
766                                            rule) == field_constant_string)
767              || (!string_only
768                  && insn_field_is_constant(fields->bit[new_opcode.first],
769                                            rule)));
770       
771       /* find the end point for the opcode field */
772       new_opcode.last = rule->last;
773       while (new_opcode.last >= rule->first
774              && (!string_only
775                  || insn_field_is_constant(fields->bit[new_opcode.last],
776                                            rule) != field_constant_string)
777              && (string_only
778                  || !insn_field_is_constant(fields->bit[new_opcode.last],
779                                             rule)))
780         {
781           int new_last = fields->bit[new_opcode.last]->first - 1;
782           ASSERT (new_last < new_opcode.last);
783           new_opcode.last = new_last;
784         }
785       ASSERT(new_opcode.last < rule->first
786              || (string_only
787                  && insn_field_is_constant(fields->bit[new_opcode.last],
788                                            rule) == field_constant_string)
789              || (!string_only
790                  && insn_field_is_constant(fields->bit[new_opcode.last],
791                                            rule)));
792       
793       /* now see if our current opcode needs expanding to include the
794          interesting fields within this instruction */
795       if (new_opcode.first <= rule->last
796           && curr_opcode.first > new_opcode.first)
797         curr_opcode.first = new_opcode.first;
798       if (new_opcode.last >= rule->first
799           && curr_opcode.last < new_opcode.last)
800         curr_opcode.last = new_opcode.last;
801       
802     }
803 #endif
804
805   /* did the final opcode field end up being empty? */
806   if (curr_opcode.first > curr_opcode.last)
807     {
808       return NULL;
809     }
810   ASSERT (curr_opcode.last >= rule->first);
811   ASSERT (curr_opcode.first <= rule->last);
812   ASSERT (curr_opcode.first <= curr_opcode.last);
813
814   /* Ensure that, for the non string only case, the opcode includes
815      the range forced_first .. forced_last */
816   if (!string_only
817       && curr_opcode.first > rule->force_first)
818     {
819       curr_opcode.first = rule->force_first;
820     }
821   if (!string_only
822       && curr_opcode.last < rule->force_last)
823     {
824       curr_opcode.last = rule->force_last;
825     }
826
827   /* For the string only case, force just the lower bound (so that the
828      shift can be eliminated) */
829   if (string_only
830       && rule->force_last == options.insn_bit_size - 1)
831     {
832       curr_opcode.last = options.insn_bit_size - 1;
833     }
834
835   /* handle any special cases */
836   switch (rule->type)
837     {
838     case normal_decode_rule:
839       /* let the above apply */
840       curr_opcode.nr_opcodes =
841         (1 << (curr_opcode.last - curr_opcode.first + 1));
842       break;
843     case boolean_rule:
844       curr_opcode.is_boolean = 1;
845       curr_opcode.boolean_constant = rule->constant;
846       curr_opcode.nr_opcodes = 2;
847       break;
848     }
849
850   {
851     opcode_field *new_field = ZALLOC (opcode_field);
852     memcpy (new_field, &curr_opcode, sizeof (opcode_field));
853     return new_field;
854   }
855 }
856
857
858 static void
859 gen_entry_insert_insn (gen_entry *table,
860                        insn_entry *old_insn,
861                        int new_word_nr,
862                        int new_nr_prefetched_words,
863                        int new_opcode_nr,
864                        opcode_bits *new_bits)
865 {
866   gen_entry **entry = &table->entries;
867   
868   /* find the new table for this entry */
869   while ((*entry) != NULL && (*entry)->opcode_nr < new_opcode_nr)
870     {
871       entry = &(*entry)->sibling;
872     }
873   
874   if ((*entry) == NULL || (*entry)->opcode_nr != new_opcode_nr)
875     {
876       /* insert the missing entry */
877       gen_entry *new_entry = ZALLOC (gen_entry);
878       new_entry->sibling = (*entry);
879       (*entry) = new_entry;
880       table->nr_entries++;
881       /* fill it in */
882       new_entry->top = table->top;
883       new_entry->opcode_nr = new_opcode_nr;
884       new_entry->word_nr = new_word_nr;
885       new_entry->expanded_bits = new_bits;
886       new_entry->opcode_rule = table->opcode_rule->next;
887       new_entry->parent = table;
888       new_entry->nr_prefetched_words = new_nr_prefetched_words;
889     }
890   /* ASSERT new_bits == cur_entry bits */
891   ASSERT ((*entry) != NULL && (*entry)->opcode_nr == new_opcode_nr);
892   insn_list_insert (&(*entry)->insns,
893                     &(*entry)->nr_insns,
894                     old_insn,
895                     NULL, /* expanded_bits - only in final list */
896                     NULL, /* opcodes - only in final list */
897                     new_nr_prefetched_words, /* for this table */
898                     report_duplicate_insns);
899 }
900
901
902 static void
903 gen_entry_expand_opcode (gen_entry *table,
904                          insn_entry *instruction,
905                          int bit_nr,
906                          int opcode_nr,
907                          opcode_bits *bits)
908 {
909   if (bit_nr > table->opcode->last)
910     {
911       /* Only include the hardwired bit information with an entry IF
912          that entry (and hence its functions) are being duplicated.  */
913       if (options.trace.insn_expansion)
914         {
915           print_gen_entry_path (table->opcode_rule->line, table, notify);
916           notify (NULL, ": insert %d - %s.%s%s\n",
917                   opcode_nr,
918                   instruction->format_name,
919                   instruction->name,
920                   (table->opcode_rule->with_duplicates ? " (duplicated)" : ""));
921         }
922       if (table->opcode_rule->with_duplicates)
923         {
924           gen_entry_insert_insn (table, instruction,
925                                  table->opcode->word_nr,
926                                  table->nr_prefetched_words,
927                                  opcode_nr, bits);
928         }
929       else
930         {
931           gen_entry_insert_insn (table, instruction,
932                                  table->opcode->word_nr,
933                                  table->nr_prefetched_words,
934                                  opcode_nr, NULL);
935         }
936     }
937   else
938     {
939       insn_word_entry *word = instruction->word[table->opcode->word_nr];
940       insn_field_entry *field = word->bit[bit_nr]->field;
941       int last_pos = ((field->last < table->opcode->last)
942                       ? field->last
943                       : table->opcode->last);
944       int first_pos = ((field->first > table->opcode->first)
945                        ? field->first
946                        : table->opcode->first);
947       int width = last_pos - first_pos + 1;
948       switch (field->type)
949         {
950         case insn_field_int:
951           {
952             int val;
953             val = sub_val (field->val_int, field->last,
954                            first_pos, last_pos);
955             gen_entry_expand_opcode (table, instruction,
956                                      last_pos + 1,
957                                      ((opcode_nr << width) | val),
958                                      bits);
959             break;
960           }
961         default:
962           {
963             if (field->type == insn_field_reserved)
964               gen_entry_expand_opcode (table, instruction,
965                                        last_pos + 1,
966                                        ((opcode_nr << width)),
967                                        bits);
968             else
969               {
970                 int val;
971                 int last_val = (table->opcode->is_boolean
972                                 ? 2
973                                 : (1 << width));
974                 for (val = 0; val < last_val; val++)
975                   {
976                     /* check to see if the value has been precluded
977                        (by a conditional) in some way */
978                     int is_precluded;
979                     insn_field_cond *condition;
980                     for (condition = field->conditions, is_precluded = 0;
981                          condition != NULL && !is_precluded;
982                          condition = condition->next)
983                       {
984                         switch (condition->type)
985                           {
986                           case insn_field_cond_value:
987                             {
988                               int value = sub_val (condition->value, field->last,
989                                                    first_pos, last_pos);
990                               switch (condition->test)
991                                 {
992                                 case insn_field_cond_ne:
993                                   if (value == val)
994                                     is_precluded = 1;
995                                   break;
996                                 case insn_field_cond_eq:
997                                   if (value != val)
998                                     is_precluded = 1;
999                                   break;
1000                                 }
1001                               break;
1002                             }
1003                           case insn_field_cond_field:
1004                             {
1005                               int value;
1006                               opcode_bits *bit;
1007                               gen_entry *t;
1008                               /* Try to find a value for the
1009                                  conditional by looking back through
1010                                  the previously defined bits for one
1011                                  that covers the designated
1012                                  conditional field */
1013                               for (bit = bits;
1014                                    bit != NULL;
1015                                    bit = bit->next)
1016                                 {
1017                                   if (bit->field->word_nr == condition->field->word_nr
1018                                       && bit->first <= condition->field->first
1019                                       && bit->last >= condition->field->last)
1020                                     {
1021                                       /* the bit field fully specified
1022                                          the conditional field's value */
1023                                       value = sub_val (bit->value, bit->last,
1024                                                        condition->field->first,
1025                                                        condition->field->last);
1026                                     }
1027                                 }
1028                               /* Try to find a value by looking
1029                                  through this and previous tables */
1030                               if (bit == NULL)
1031                                 {
1032                                   for (t = table;
1033                                        t->parent != NULL;
1034                                        t = t->parent)
1035                                     {
1036                                       if (t->parent->opcode->word_nr == condition->field->word_nr
1037                                           && t->parent->opcode->first <= condition->field->first
1038                                           && t->parent->opcode->last >= condition->field->last)
1039                                         {
1040                                           /* the table entry fully
1041                                              specified the condition
1042                                              field's value */
1043                                           /* extract the field's value
1044                                              from the opcode */
1045                                           value = sub_val (t->opcode_nr, t->parent->opcode->last,
1046                                                            condition->field->first, condition->field->last);
1047                                           /* this is a requirement of
1048                                              a conditonal field
1049                                              refering to another field */
1050                                           ASSERT ((condition->field->first - condition->field->last)
1051                                                   == (first_pos - last_pos));
1052 printf ("value=%d, opcode_nr=%d, last=%d, [%d..%d]\n",
1053         value, t->opcode_nr, t->parent->opcode->last, condition->field->first, condition->field->last);
1054                                         }
1055                                     }
1056                                 }
1057                               if (bit == NULL && t == NULL)
1058                                 error (instruction->line,
1059                                        "Conditional `%s' of field `%s' isn't expanded",
1060                                        condition->string, field->val_string);
1061                               switch (condition->test)
1062                                 {
1063                                 case insn_field_cond_ne:
1064                                   if (value == val)
1065                                     is_precluded = 1;
1066                                   break;
1067                                 case insn_field_cond_eq:
1068                                   if (value != val)
1069                                     is_precluded = 1;
1070                                   break;
1071                                 }
1072                               break;
1073                             }
1074                           }
1075                       }
1076                     if (!is_precluded)
1077                       {
1078                         /* Only add additional hardwired bit
1079                            information if the entry is not going to
1080                            later be combined */
1081                         if (table->opcode_rule->with_combine)
1082                           {
1083                             gen_entry_expand_opcode (table, instruction,
1084                                                      last_pos + 1,
1085                                                      ((opcode_nr << width) | val),
1086                                                      bits);
1087                           }
1088                         else
1089                           {
1090                             opcode_bits *new_bits = new_opcode_bits (bits, val,
1091                                                                      first_pos, last_pos,
1092                                                                      field,
1093                                                                      table->opcode);
1094                             gen_entry_expand_opcode (table, instruction,
1095                                                      last_pos + 1,
1096                                                      ((opcode_nr << width) | val),
1097                                                      new_bits);
1098                           }
1099                       }
1100                   }
1101               }
1102           }
1103         }
1104     }
1105 }
1106
1107 static void
1108 gen_entry_insert_expanding (gen_entry *table,
1109                             insn_entry *instruction)
1110 {
1111   gen_entry_expand_opcode (table,
1112                            instruction,
1113                            table->opcode->first,
1114                            0,
1115                            table->expanded_bits);
1116 }
1117
1118
1119 static int
1120 insns_match_format_names (insn_list *insns,
1121                           filter *format_names)
1122 {
1123   if (format_names != NULL)
1124     {
1125       insn_list *i;
1126       for (i = insns; i != NULL; i = i->next)
1127         {
1128           if ( i->insn->format_name != NULL
1129                && !filter_is_member (format_names, i->insn->format_name))
1130             return 0;
1131         }
1132     }
1133   return 1;
1134 }
1135
1136 static int
1137 table_matches_path (gen_entry *table,
1138                     decode_path_list *paths)
1139 {
1140   if (paths == NULL)
1141     return 1;
1142   while (paths != NULL)
1143     {
1144       gen_entry *entry = table;
1145       decode_path *path = paths->path;
1146       while (1)
1147         {
1148           if (entry == NULL && path == NULL)
1149             return 1;
1150           if (entry == NULL || path == NULL)
1151             break;
1152           if (entry->opcode_nr != path->opcode_nr)
1153             break;
1154           entry = entry->parent;
1155           path = path->parent;
1156         }
1157       paths = paths->next;
1158     }
1159   return 0;
1160 }
1161
1162
1163 static int
1164 insns_match_conditions (insn_list *insns,
1165                         decode_cond *conditions)
1166 {
1167   if (conditions != NULL)
1168     {
1169       insn_list *i;
1170       for (i = insns; i != NULL; i = i->next)
1171         {
1172           decode_cond *cond;
1173           for (cond = conditions; cond != NULL; cond = cond->next)
1174             {
1175               int bit_nr;
1176               if (i->insn->nr_words <= cond->word_nr)
1177                 return 0;
1178               for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++)
1179                 {
1180                   if (!cond->mask[bit_nr])
1181                     continue;
1182                   if (!i->insn->word[cond->word_nr]->bit[bit_nr]->mask)
1183                     return 0;
1184                   if ((i->insn->word[cond->word_nr]->bit[bit_nr]->value
1185                        == cond->value[bit_nr])
1186                       == !cond->is_equal)
1187                     return 0;
1188                 }
1189             }
1190         }
1191     }
1192   return 1;
1193 }
1194
1195 static int
1196 insns_match_nr_words (insn_list *insns,
1197                       int nr_words)
1198 {
1199   insn_list *i;
1200   for (i = insns; i != NULL; i = i->next)
1201     {
1202       if (i->insn->nr_words < nr_words)
1203         return 0;
1204     }
1205   return 1;
1206 }
1207
1208 static int
1209 insn_list_cmp (insn_list *l,
1210                insn_list *r)
1211 {
1212   while (1)
1213     {
1214       insn_entry *insn;
1215       if (l == NULL && r == NULL)
1216         return 0;
1217       if (l == NULL)
1218         return -1;
1219       if (r == NULL)
1220         return 1;
1221       if (l->insn != r->insn)
1222         return -1; /* somewhat arbitrary at present */
1223       /* skip this insn */
1224       insn = l->insn;
1225       while (l != NULL && l->insn == insn)
1226         l = l->next;
1227       while (r != NULL && r->insn == insn)
1228         r = r->next;
1229     }
1230 }
1231
1232
1233
1234 static void
1235 gen_entry_expand_insns (gen_entry *table)
1236 {
1237   decode_table *opcode_rule;
1238
1239   ASSERT(table->nr_insns >= 1);
1240   
1241   /* determine a valid opcode */
1242   for (opcode_rule = table->opcode_rule;
1243        opcode_rule != NULL;
1244        opcode_rule = opcode_rule->next)
1245     {
1246       char *discard_reason;
1247       if (table->top->model != NULL
1248           && opcode_rule->model_names != NULL
1249           && !filter_is_member (opcode_rule->model_names,
1250                                 table->top->model->name))
1251         {
1252           /* the rule isn't applicable to this processor */
1253           discard_reason = "wrong model";
1254         }
1255       else if (table->nr_insns == 1 && opcode_rule->conditions == NULL)
1256         {
1257           /* for safety, require a pre-codition when attempting to
1258              apply a rule to a single instruction */
1259           discard_reason = "need pre-condition when nr-insn == 1";
1260         }
1261       else if (table->nr_insns == 1 && !opcode_rule->with_duplicates)
1262         {
1263           /* Little point in expanding a single instruction when we're
1264              not duplicating the semantic functions that this table
1265              calls */
1266           discard_reason = "need duplication with nr-insns == 1";
1267         }
1268       else if (!insns_match_format_names (table->insns, opcode_rule->format_names))
1269         {
1270           discard_reason = "wrong format name";
1271         }
1272       else if (!insns_match_nr_words (table->insns, opcode_rule->word_nr + 1))
1273         {
1274           discard_reason = "wrong nr words";
1275         }
1276       else if (!table_matches_path (table, opcode_rule->paths))
1277         {
1278           discard_reason = "path failed";
1279         }
1280       else if (!insns_match_conditions (table->insns, opcode_rule->conditions))
1281         {
1282           discard_reason = "condition failed";
1283         }
1284       else
1285         {
1286           discard_reason = "no opcode field";
1287           table->opcode =
1288             gen_entry_find_opcode_field (table->insns,
1289                                          opcode_rule,
1290                                          table->nr_insns == 1/*string-only*/
1291                                          );
1292           if (table->opcode != NULL)
1293             {
1294               table->opcode_rule = opcode_rule;
1295               break;
1296             }
1297         }
1298
1299       if (options.trace.rule_rejection)
1300         {
1301           print_gen_entry_path (opcode_rule->line, table, notify);
1302           notify (NULL, ": rule discarded - %s\n", discard_reason);
1303         }
1304     }
1305   
1306   /* did we find anything */
1307   if (opcode_rule == NULL)
1308     {
1309       /* the decode table failed, this set of instructions haven't
1310          been uniquely identified */
1311       if (table->nr_insns > 1)
1312         {
1313           print_gen_entry_insns (table, warning,
1314                                  "was not uniquely decoded",
1315                                  "decodes to the same entry");
1316           error (NULL, "");
1317         }
1318       return;
1319     }
1320
1321   /* Determine the number of words that must have been prefetched for
1322      this table to function */
1323   if (table->parent == NULL)
1324     table->nr_prefetched_words = table->opcode_rule->word_nr + 1;
1325   else if (table->opcode_rule->word_nr + 1 > table->parent->nr_prefetched_words)
1326     table->nr_prefetched_words = table->opcode_rule->word_nr + 1;
1327   else
1328     table->nr_prefetched_words = table->parent->nr_prefetched_words;
1329
1330   /* back link what we found to its parent */
1331   if (table->parent != NULL)
1332     {
1333       ASSERT(table->parent->opcode != NULL);
1334       table->opcode->parent = table->parent->opcode;
1335     }
1336
1337   /* report the rule being used to expand the instructions */
1338   if (options.trace.rule_selection)
1339     {
1340       print_gen_entry_path (table->opcode_rule->line, table, notify);
1341       notify (NULL,
1342               ": decode - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d\n",
1343               table->opcode->word_nr,
1344               i2target (options.hi_bit_nr, table->opcode->first),
1345               i2target (options.hi_bit_nr, table->opcode->last),
1346               i2target (options.hi_bit_nr, table->opcode_rule->first),
1347               i2target (options.hi_bit_nr, table->opcode_rule->last),
1348               table->opcode->nr_opcodes,
1349               table->nr_entries);
1350     }
1351
1352   /* expand the raw instructions according to the opcode */
1353   {
1354     insn_list *entry;
1355     for (entry = table->insns; entry != NULL; entry = entry->next)
1356       {
1357         if (options.trace.insn_expansion)
1358           {
1359             print_gen_entry_path (table->opcode_rule->line, table, notify);
1360             notify (NULL, ": expand - %s.%s\n",
1361                     entry->insn->format_name,
1362                     entry->insn->name);
1363           }
1364         gen_entry_insert_expanding (table, entry->insn);
1365       }
1366   }
1367
1368   /* dump the results */
1369   if (options.trace.entries)
1370     {
1371       gen_entry *entry;
1372       for (entry = table->entries; entry != NULL; entry = entry->sibling)
1373         {
1374           insn_list *l;
1375           print_gen_entry_path (table->opcode_rule->line, entry, notify);
1376           notify (NULL, ": %d - entries %d -",
1377                   entry->opcode_nr,
1378                   entry->nr_insns);
1379           for (l = entry->insns; l != NULL; l = l->next)
1380             notify (NULL, " %s.%s", l->insn->format_name, l->insn->name);
1381           notify (NULL, "\n");
1382         }
1383     }
1384         
1385   /* perform a combine pass if needed */
1386   if (table->opcode_rule->with_combine)
1387     {
1388       gen_entry *entry;
1389       for (entry = table->entries; entry != NULL; entry = entry->sibling)
1390         {
1391           if (entry->combined_parent == NULL)
1392             {
1393               gen_entry **last = &entry->combined_next;
1394               gen_entry *alt;
1395               for (alt = entry->sibling; alt != NULL; alt = alt->sibling)
1396                 {
1397                   if (alt->combined_parent == NULL
1398                       && insn_list_cmp (entry->insns, alt->insns) == 0)
1399                     {
1400                       alt->combined_parent = entry;
1401                       *last = alt;
1402                       last = &alt->combined_next;
1403                     }
1404                 }
1405             }
1406         }
1407       if (options.trace.combine)
1408         {
1409           int nr_unique = 0;
1410           gen_entry *entry;
1411           for (entry = table->entries; entry != NULL; entry = entry->sibling)
1412             {
1413               if (entry->combined_parent == NULL)
1414                 {
1415                   insn_list *l;
1416                   gen_entry *duplicate;
1417                   nr_unique++;
1418                   print_gen_entry_path (table->opcode_rule->line, entry, notify);
1419                   for (duplicate = entry->combined_next;
1420                        duplicate != NULL;
1421                        duplicate = duplicate->combined_next)
1422                     {
1423                       notify (NULL, "+%d", duplicate->opcode_nr);
1424                     }
1425                   notify (NULL, ": entries %d -", entry->nr_insns);
1426                   for (l = entry->insns; l != NULL; l = l->next)
1427                     {
1428                       notify (NULL, " %s.%s",
1429                               l->insn->format_name,
1430                               l->insn->name);
1431                     }
1432                   notify (NULL, "\n");
1433                 }
1434             }
1435           print_gen_entry_path (table->opcode_rule->line, table, notify);
1436           notify (NULL, ": combine - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d, unique %d\n",
1437                   table->opcode->word_nr,
1438                   i2target (options.hi_bit_nr, table->opcode->first),
1439                   i2target (options.hi_bit_nr, table->opcode->last),
1440                   i2target (options.hi_bit_nr, table->opcode_rule->first),
1441                   i2target (options.hi_bit_nr, table->opcode_rule->last),
1442                   table->opcode->nr_opcodes,
1443                   table->nr_entries,
1444                   nr_unique);
1445         }
1446     }
1447         
1448   /* Check that the rule did more than re-arange the order of the
1449      instructions */
1450   {
1451       gen_entry *entry;
1452       for (entry = table->entries; entry != NULL; entry = entry->sibling)
1453         {
1454           if (entry->combined_parent == NULL)
1455             {
1456               if (insn_list_cmp (table->insns, entry->insns) == 0)
1457                 {
1458                   print_gen_entry_path (table->opcode_rule->line, table, warning);
1459                   warning (NULL, ": Applying rule just copied all instructions\n");
1460                   print_gen_entry_insns (entry, warning, "Copied", NULL);
1461                   error (NULL, "");
1462                 }
1463             }
1464         }    
1465   }
1466
1467   /* if some form of expanded table, fill in the missing dots */
1468   switch (table->opcode_rule->gen)
1469     {
1470     case padded_switch_gen:
1471     case array_gen:
1472     case goto_switch_gen:
1473       if (!table->opcode->is_boolean)
1474         {
1475           gen_entry **entry = &table->entries;
1476           gen_entry *illegals = NULL;
1477           gen_entry **last_illegal = &illegals;
1478           int opcode_nr = 0;
1479           while (opcode_nr < table->opcode->nr_opcodes)
1480             {
1481               if ((*entry) == NULL || (*entry)->opcode_nr != opcode_nr)
1482                 {
1483                   /* missing - insert it under our feet at *entry */
1484                   gen_entry_insert_insn (table,
1485                                          table->top->isa->illegal_insn,
1486                                          table->opcode->word_nr,
1487                                          0, /* nr_prefetched_words == 0 for invalid */
1488                                          opcode_nr, NULL);
1489                   ASSERT ((*entry) != NULL);
1490                   ASSERT ((*entry)->opcode_nr == opcode_nr);
1491                   (*last_illegal) = *entry;
1492                   (*last_illegal)->combined_parent = illegals;
1493                   last_illegal = &(*last_illegal)->combined_next;
1494                 }
1495               entry = &(*entry)->sibling;
1496               opcode_nr++;
1497             }
1498           /* oops, will have pointed the first illegal insn back to
1499              its self.  Fix this */
1500           if (illegals != NULL)
1501             illegals->combined_parent = NULL;
1502         }
1503       break;
1504     case switch_gen:
1505     case invalid_gen:
1506       /* ignore */
1507       break;
1508     }
1509
1510   /* and do the same for the newly created sub entries but *only*
1511      expand entries that haven't been combined. */
1512   {
1513     gen_entry *entry;
1514     for (entry = table->entries; entry != NULL; entry =  entry->sibling)
1515       {
1516         if (entry->combined_parent == NULL)
1517           {
1518             gen_entry_expand_insns (entry);
1519           }
1520       }
1521   }
1522 }
1523
1524 void
1525 gen_tables_expand_insns (gen_table *gen)
1526 {
1527   gen_list *entry;
1528   for (entry = gen->tables; entry != NULL; entry = entry->next)
1529     {
1530       gen_entry_expand_insns (entry->table);
1531     }
1532 }
1533
1534
1535 /* create a list of all the semantic functions that need to be
1536    generated.  Eliminate any duplicates. Verify that the decode stage
1537    worked. */
1538
1539 static void
1540 make_gen_semantics_list (lf *file,
1541                          gen_entry *entry,
1542                          int depth,
1543                          void *data)
1544 {
1545   gen_table *gen = (gen_table*) data;
1546   insn_list *insn;
1547   /* Not interested in an entrie that have been combined into some
1548      other entry at the same level */
1549   if (entry->combined_parent != NULL)
1550     return;
1551
1552   /* a leaf should contain exactly one instruction. If not the decode
1553      stage failed. */
1554   ASSERT (entry->nr_insns == 1);
1555
1556   /* Enter this instruction into the list of semantic functions. */
1557   insn = insn_list_insert (&gen->semantics, &gen->nr_semantics,
1558                            entry->insns->insn,
1559                            entry->expanded_bits,
1560                            entry->parent->opcode,
1561                            entry->insns->nr_prefetched_words,
1562                            merge_duplicate_insns);
1563   /* point the table entry at the real semantic function */
1564   ASSERT (insn != NULL);
1565   entry->insns->semantic = insn;
1566 }
1567
1568
1569 void
1570 gen_tables_expand_semantics (gen_table *gen)
1571 {
1572   gen_list *entry;
1573   for (entry = gen->tables; entry != NULL; entry = entry->next)
1574     {
1575       gen_entry_traverse_tree (NULL,
1576                                entry->table,
1577                                1, /* depth */
1578                                NULL, /* start-handler */
1579                                make_gen_semantics_list, /* leaf-handler */
1580                                NULL, /* end-handler */
1581                                gen); /* data */
1582   }
1583 }
1584
1585
1586
1587 #ifdef MAIN
1588
1589
1590 static void
1591 dump_opcode_field (lf *file,
1592                    char *prefix,
1593                    opcode_field *field,
1594                    char *suffix,
1595                    int levels)
1596 {
1597   lf_printf (file, "%s(opcode_field *) 0x%lx", prefix, (long) field);
1598   if (levels && field != NULL) {
1599     lf_indent (file, +1);
1600     lf_printf (file, "\n(first %d)", field->first);
1601     lf_printf (file, "\n(last %d)", field->last);
1602     lf_printf (file, "\n(nr_opcodes %d)", field->nr_opcodes);
1603     lf_printf (file, "\n(is_boolean %d)", field->is_boolean);
1604     lf_printf (file, "\n(boolean_constant %d)", field->boolean_constant);
1605     dump_opcode_field(file, "\n(parent ", field->parent, ")", levels - 1);
1606     lf_indent (file, -1);
1607   }
1608   lf_printf (file, "%s", suffix);
1609 }
1610
1611
1612 static void
1613 dump_opcode_bits (lf *file,
1614                   char *prefix,
1615                   opcode_bits *bits,
1616                   char *suffix,
1617                   int levels)
1618 {
1619   lf_printf (file, "%s(opcode_bits *) 0x%lx", prefix, (long) bits);
1620   
1621   if (levels && bits != NULL)
1622     {
1623       lf_indent (file, +1);
1624       lf_printf (file, "\n(value %d)", bits->value);
1625       dump_opcode_field (file, "\n(opcode ", bits->opcode, ")", 0);
1626       dump_insn_field (file, "\n(field ", bits->field, ")");
1627       dump_opcode_bits (file, "\n(next ", bits->next, ")", levels - 1);
1628       lf_indent (file, -1);
1629     }
1630   lf_printf (file, "%s", suffix);
1631 }
1632
1633
1634
1635 static void
1636 dump_insn_list (lf *file,
1637                 char *prefix,
1638                 insn_list *entry,
1639                 char *suffix)
1640 {
1641   lf_printf (file, "%s(insn_list *) 0x%lx", prefix, (long) entry);
1642
1643   if (entry != NULL) {
1644     lf_indent (file, +1);
1645     dump_insn_entry (file, "\n(insn ", entry->insn, ")");
1646     lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1647     lf_indent (file, -1);
1648   }
1649   lf_printf (file, "%s", suffix);
1650 }
1651
1652
1653 static void
1654 dump_insn_word_entry_list_entries (lf *file,
1655                                char *prefix,
1656                                insn_list *entry,
1657                                char *suffix)
1658 {
1659   lf_printf (file, "%s", prefix);
1660   while (entry != NULL)
1661     {
1662       dump_insn_list (file, "\n(", entry, ")");
1663       entry = entry->next;
1664     }
1665   lf_printf (file, "%s", suffix);
1666 }
1667
1668
1669 static void
1670 dump_gen_entry (lf *file,
1671                 char *prefix,
1672                 gen_entry *table,
1673                 char *suffix,
1674                 int levels)
1675 {
1676
1677   lf_printf (file, "%s(gen_entry *) 0x%lx", prefix, (long) table);
1678
1679   if (levels && table != NULL) {
1680
1681     lf_indent (file, +1);
1682     lf_printf (file, "\n(opcode_nr %d)", table->opcode_nr);
1683     lf_printf (file, "\n(word_nr %d)", table->word_nr);
1684     dump_opcode_bits (file, "\n(expanded_bits ", table->expanded_bits, ")", -1);
1685     lf_printf (file, "\n(nr_insns %d)", table->nr_insns);
1686     dump_insn_word_entry_list_entries (file, "\n(insns ", table->insns, ")");
1687     dump_decode_rule (file, "\n(opcode_rule ", table->opcode_rule, ")");
1688     dump_opcode_field (file, "\n(opcode ", table->opcode, ")", 0);
1689     lf_printf (file, "\n(nr_entries %d)", table->nr_entries);
1690     dump_gen_entry (file, "\n(entries ", table->entries, ")", table->nr_entries);
1691     dump_gen_entry (file, "\n(sibling ", table->sibling, ")", levels - 1);
1692     dump_gen_entry (file, "\n(parent ", table->parent, ")", 0);
1693     lf_indent (file, -1);
1694   }
1695   lf_printf (file, "%s", suffix);
1696 }
1697
1698 static void
1699 dump_gen_list (lf *file,
1700                char *prefix,
1701                gen_list *entry,
1702                char *suffix,
1703                int levels)
1704 {
1705   while (entry != NULL)
1706     {
1707       lf_printf (file, "%s(gen_list *) 0x%lx", prefix, (long) entry);
1708       dump_gen_entry (file, "\n(", entry->table, ")", levels);
1709       lf_printf (file, "\n(next (gen_list *) 0x%lx)", (long) entry->next);
1710       lf_printf (file, "%s", suffix);
1711     }
1712 }
1713
1714
1715 static void
1716 dump_gen_table (lf *file,
1717                 char *prefix,
1718                 gen_table *gen,
1719                 char *suffix,
1720                 int levels)
1721 {
1722   lf_printf (file, "%s(gen_table *) 0x%lx", prefix, (long) gen);
1723   lf_printf (file, "\n(isa (insn_table *) 0x%lx)", (long) gen->isa);
1724   lf_printf (file, "\n(rules (decode_table *) 0x%lx)", (long) gen->rules);
1725   dump_gen_list (file, "\n(", gen->tables, ")", levels);
1726   lf_printf (file, "%s", suffix);
1727 }
1728
1729
1730 igen_options options;
1731
1732 int
1733 main (int argc,
1734       char **argv)
1735 {
1736   decode_table *decode_rules;
1737   insn_table *instructions;
1738   gen_table *gen;
1739   lf *l;
1740
1741   if (argc != 7)
1742     error (NULL, "Usage: insn <filter-in> <hi-bit-nr> <insn-bit-size> <widths> <decode-table> <insn-table>\n");
1743
1744   INIT_OPTIONS (options);
1745
1746   filter_parse (&options.flags_filter, argv[1]);
1747
1748   options.hi_bit_nr = a2i(argv[2]);
1749   options.insn_bit_size = a2i(argv[3]);
1750   options.insn_specifying_widths = a2i(argv[4]);
1751   ASSERT(options.hi_bit_nr < options.insn_bit_size);
1752
1753   instructions = load_insn_table (argv[6], NULL);
1754   decode_rules = load_decode_table (argv[5]);
1755   gen = make_gen_tables (instructions, decode_rules);
1756
1757   gen_tables_expand_insns (gen);
1758
1759   l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn");
1760
1761   dump_gen_table (l, "(", gen, ")\n", -1);
1762   return 0;
1763 }
1764
1765 #endif