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