This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / sim / igen / ld-insn.c
1 /*  This file is part of the program psim.
2
3     Copyright (C) 1994-1998, 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 #include "igen.h"
27 #include "ld-insn.h"
28
29 static insn_word_entry *
30 parse_insn_word (line_ref *line,
31                  char *string,
32                  int word_nr)
33 {
34   char *chp;
35   insn_word_entry *word = ZALLOC (insn_word_entry);
36
37   /* create a leading sentinal */
38   word->first = ZALLOC (insn_field_entry);
39   word->first->first = -1;
40   word->first->last = -1;
41   word->first->width = 0;
42
43   /* and a trailing sentinal */
44   word->last = ZALLOC (insn_field_entry);
45   word->last->first = options.insn_bit_size;
46   word->last->last = options.insn_bit_size;
47   word->last->width = 0;
48
49   /* link them together */
50   word->first->next = word->last;
51   word->last->prev = word->first;
52
53   /* now work through the formats */
54   chp = skip_spaces (string);
55
56   while (*chp != '\0') {
57     char *start_pos;
58     int strlen_pos;
59     char *start_val;
60     int strlen_val;
61     insn_field_entry *new_field;
62
63     /* create / link in the new field */
64     new_field = ZALLOC (insn_field_entry);
65     new_field->next = word->last;
66     new_field->prev = word->last->prev;
67     new_field->next->prev = new_field;
68     new_field->prev->next = new_field;
69     new_field->word_nr = word_nr;
70
71     /* break out the first field (if present) */
72     start_pos = chp;
73     chp = skip_to_separator (chp, ".,!");
74     strlen_pos = back_spaces (start_pos, chp) - start_pos;
75
76     /* break out the second field (if present) */
77     if (*chp != '.')
78       {
79         /* assume what was specified was the value (and not the start
80            position).  Assume the value length implicitly specifies
81            the number of bits */
82         start_val = start_pos;
83         strlen_val = strlen_pos;
84         start_pos = "";
85         strlen_pos = 0;
86       }
87     else
88       {
89         chp++; /* skip `.' */
90         chp = skip_spaces (chp);
91         start_val = chp;
92         if (*chp == '/' || *chp == '*')
93           {
94             do
95               {
96                 chp++;
97               }
98             while (*chp == '/' || *chp == '*');
99           }
100         else if (isalpha(*start_val))
101           {
102             do
103               {
104                 chp++;
105               }
106             while (isalnum(*chp) || *chp == '_');
107           }
108         else if (isdigit(*start_val))
109           {
110             do {
111               chp++;
112             }
113             while (isalnum(*chp));
114           }
115         strlen_val = chp - start_val;
116         chp = skip_spaces (chp);
117       }
118     if (strlen_val == 0)
119       error (line, "Empty value field\n");
120     
121     /* break out any conditional fields - { "!" <value> } */
122     while (*chp == '!')
123       {
124         char *start;
125         int len;
126         insn_field_exclusion *new_exclusion = ZALLOC (insn_field_exclusion);
127         insn_field_exclusion **last;
128         
129         /* what type of conditional field */
130         chp++; 
131         chp = skip_spaces (chp);
132         /* the value */
133         start = chp;
134         chp = skip_digits (chp);
135         len = chp - start;
136         if (len == 0)
137           error (line, "Missing or invalid conditional value\n");
138         /* fill in the entry */
139         new_exclusion->string = NZALLOC (char, len + 1);
140         strncpy (new_exclusion->string, start, len);
141         new_exclusion->value = a2i (new_exclusion->string);
142         /* insert it */
143         last = &new_field->exclusions;
144         while (*last != NULL)
145           last = &(*last)->next;
146         *last = new_exclusion;
147         chp = skip_spaces (chp);
148       }
149
150     /* NOW verify that the field ws finished */
151     if (*chp == ',')
152       {
153         chp = skip_spaces (chp + 1);
154         if (*chp == '\0')
155           error (line, "empty field\n");
156       }
157     else if (*chp != '\0')
158       {
159         error (line, "Missing field separator");
160       }
161
162     /* copy the value */
163     new_field->val_string = NZALLOC (char, strlen_val+1);
164     strncpy (new_field->val_string, start_val, strlen_val);
165     if (isdigit (new_field->val_string[0]))
166       {
167         if (strlen_pos == 0)
168           {
169             /* when the length/pos field is omited, an integer field
170                is always binary */
171             unsigned64 val = 0;
172             int i;
173             for (i = 0; i < strlen_val; i++)
174               {
175                 if (new_field->val_string[i] != '0'
176                     && new_field->val_string[i] != '1')
177                   error (line, "invalid binary field %s\n",
178                          new_field->val_string);
179                 val = (val << 1) + (new_field->val_string[i] == '1');
180               }
181             new_field->val_int = val;
182             new_field->type = insn_field_int;
183           }
184         else
185           {
186             new_field->val_int = a2i (new_field->val_string);
187             new_field->type = insn_field_int;
188           }
189       }
190     else if (new_field->val_string[0] == '/')
191       {
192         new_field->type = insn_field_reserved;
193       }
194     else if (new_field->val_string[0] == '*')
195       {
196         new_field->type = insn_field_wild;
197       }
198     else
199       {
200         new_field->type = insn_field_string;
201         if (filter_is_member (word->field_names, new_field->val_string))
202           error (line, "Field name %s is duplicated\n", new_field->val_string);
203         filter_parse (&word->field_names, new_field->val_string);
204       }
205     if (new_field->type != insn_field_string
206         && new_field->exclusions != NULL)
207       error (line, "Exclusions only apply to name fields\n");
208
209     /* the copy the position */
210     new_field->pos_string = NZALLOC (char, strlen_pos + 1);
211     strncpy (new_field->pos_string, start_pos, strlen_pos);
212     if (strlen_pos == 0)
213       {
214         new_field->first = new_field->prev->last + 1;
215         if (new_field->first == 0 /* first field */
216             && *chp == '\0' /* no further fields */
217             && new_field->type == insn_field_string)
218           {
219             /* A single string without any position, assume that it
220                represents the entire instruction word */
221             new_field->width = options.insn_bit_size;
222           }
223         else
224           {
225             /* No explicit width/position, assume value implicitly
226                supplies the width */
227             new_field->width = strlen_val;
228           }
229         new_field->last = new_field->first + new_field->width - 1;
230         if (new_field->last >= options.insn_bit_size)
231           error (line, "Bit position %d exceed instruction bit size (%d)\n",
232                  new_field->last, options.insn_bit_size);
233       }
234     else if (options.insn_specifying_widths)
235       {
236         new_field->first = new_field->prev->last + 1;
237         new_field->width = a2i(new_field->pos_string);
238         new_field->last = new_field->first + new_field->width - 1;
239         if (new_field->last >= options.insn_bit_size)
240           error (line, "Bit position %d exceed instruction bit size (%d)\n",
241                  new_field->last, options.insn_bit_size);
242       }
243     else
244       {
245         new_field->first = target_a2i(options.hi_bit_nr,
246                                       new_field->pos_string);
247         new_field->last = new_field->next->first - 1; /* guess */
248         new_field->width = new_field->last - new_field->first + 1; /* guess */
249         new_field->prev->last = new_field->first - 1; /*fix*/
250         new_field->prev->width = new_field->first - new_field->prev->first; /*fix*/
251       }
252   }
253
254   /* fiddle first/last so that the sentinals disapear */
255   ASSERT(word->first->last < 0);
256   ASSERT(word->last->first >= options.insn_bit_size);
257   word->first = word->first->next;
258   word->last = word->last->prev;
259
260   /* check that the last field goes all the way to the last bit */
261   if (word->last->last != options.insn_bit_size - 1)
262     {
263       if (options.warn.width)
264         options.warning (line, "Instruction format is not %d bits wide\n",
265                          options.insn_bit_size);
266       word->last->last = options.insn_bit_size - 1;
267     }
268
269   /* now go over this again, pointing each bit position at a field
270      record */
271   {
272     insn_field_entry *field;
273     for (field = word->first;
274          field->last < options.insn_bit_size;
275          field = field->next)
276       {
277         int i;
278         for (i = field->first; i <= field->last; i++)
279           {
280             word->bit[i] = ZALLOC (insn_bit_entry);
281             word->bit[i]->field = field;
282             switch (field->type)
283               {
284               case insn_field_int:
285                 word->bit[i]->mask = 1;
286                 word->bit[i]->value = ((field->val_int
287                                         & ((insn_uint)1 << (field->last - i)))
288                                        != 0);
289               case insn_field_reserved:
290               case insn_field_wild:
291               case insn_field_string:
292                 break;
293               }
294           }
295       }
296   }
297
298   return word;
299 }
300
301
302 static void
303 parse_insn_words (insn_entry *insn,
304                   char *formats)
305 {
306   insn_word_entry **last_word = &insn->words;
307   char *chp;
308
309   /* now work through the formats */
310   insn->nr_words = 0;
311   chp = formats;
312
313   while (1)
314     {
315       char *start_pos;
316       char *end_pos;
317       int strlen_pos;
318       char *format;
319       insn_word_entry *new_word;
320
321       /* skip leading spaces */
322       chp = skip_spaces (chp);
323
324       /* break out the format */
325       start_pos = chp;
326       chp = skip_to_separator (chp, "+");
327       end_pos = back_spaces (start_pos, chp);
328       strlen_pos = end_pos - start_pos;
329
330       /* check that something was there */
331       if (strlen_pos == 0)
332         error (insn->line, "missing or empty instruction format\n");
333
334       /* parse the field */
335       format = NZALLOC (char, strlen_pos + 1);
336       strncpy (format, start_pos, strlen_pos);
337       new_word = parse_insn_word (insn->line, format, insn->nr_words);
338       insn->nr_words++;
339       if (filter_is_common (insn->field_names, new_word->field_names))
340         error (insn->line, "Field name duplicated between two words\n");
341       filter_add (&insn->field_names, new_word->field_names);
342
343       /* insert it */
344       *last_word = new_word;
345       last_word = &new_word->next;
346
347       /* last format? */
348       if (*chp == '\0')
349         break;
350       ASSERT (*chp == '+');
351       chp++;
352     }
353
354   /* now create a quick access array of the same structure */
355   {
356     int i;
357     insn_word_entry *word;
358     insn->word = NZALLOC (insn_word_entry *, insn->nr_words + 1);
359     for (i = 0, word = insn->words;
360          i < insn->nr_words;
361          i++, word = word->next)
362       insn->word[i] = word;
363   }
364 }
365
366 typedef enum {
367   unknown_record = 0,
368   insn_record, /* default */
369   code_record,
370   cache_record,
371   compute_record,
372   scratch_record,
373   option_record,
374   string_function_record,
375   function_record,
376   internal_record,
377   define_record,
378   include_record,
379   model_processor_record,
380   model_macro_record,
381   model_data_record,
382   model_static_record,
383   model_function_record,
384   model_internal_record,
385 } insn_record_type;
386
387 static const name_map insn_type_map[] = {
388   { "option", option_record },
389   { "cache", cache_record },
390   { "compute", compute_record },
391   { "scratch", scratch_record },
392   { "define", define_record },
393   { "include", include_record },
394   { "%s", string_function_record },
395   { "function", function_record },
396   { "internal", internal_record },
397   { "model", model_processor_record },
398   { "model-macro", model_macro_record },
399   { "model-data", model_data_record },
400   { "model-static", model_static_record },
401   { "model-internal", model_internal_record },
402   { "model-function", model_function_record },
403   { NULL, insn_record },
404 };
405
406
407 static int
408 record_is_old (table_entry *entry)
409 {
410   if (entry->nr_fields > record_type_field
411       && strlen (entry->field[record_type_field]) == 0)
412     return 1;
413   return 0;
414 }
415
416 static insn_record_type
417 record_type (table_entry *entry)
418 {
419   switch (entry->type)
420     {
421     case table_code_entry:
422       return code_record;
423
424     case table_colon_entry:
425       if (record_is_old (entry))
426         {
427           /* old-format? */
428           if (entry->nr_fields > old_record_type_field)
429             {
430               int i = name2i (entry->field[old_record_type_field],
431                               insn_type_map);
432               return i;
433             }
434           else
435             {
436               return unknown_record;
437             }
438         }
439       else if (entry->nr_fields > record_type_field
440                && entry->field[0][0] == '\0')
441         {
442           /* new-format? */
443           int i = name2i (entry->field[record_type_field],
444                           insn_type_map);
445           return i;
446         }
447       else
448         return insn_record; /* default */
449     }
450   return unknown_record;
451 }
452
453 static int
454 record_prefix_is (table_entry *entry,
455                   char ch,
456                   int nr_fields)
457 {
458   if (entry->type != table_colon_entry)
459     return 0;
460   if (entry->nr_fields < nr_fields)
461     return 0;
462   if (entry->field[0][0] != ch && ch != '\0')
463     return 0;
464   return 1;
465 }
466
467 static table_entry *
468 parse_model_data_record (insn_table *isa,
469                          table *file,
470                          table_entry *record,
471                          int nr_fields,
472                          model_data **list)
473 {
474   table_entry *model_record = record;
475   table_entry *code_record = NULL;
476   model_data *new_data;
477   if (record->nr_fields < nr_fields)
478     error (record->line, "Incorrect number of fields\n");
479   record = table_read (file);
480   if (record->type == table_code_entry)
481     {
482       code_record = record;
483       record = table_read (file);
484     }
485   /* create the new data record */
486   new_data = ZALLOC (model_data);
487   new_data->line = model_record->line;
488   filter_parse (&new_data->flags,
489                 model_record->field[record_filter_flags_field]);
490   new_data->entry = model_record;
491   new_data->code = code_record;
492   /* append it if not filtered out */
493   if (!is_filtered_out (options.flags_filter,
494                         model_record->field[record_filter_flags_field])
495       && !is_filtered_out (options.model_filter,
496                            model_record->field[record_filter_models_field]))
497     {
498       while (*list != NULL)
499         list = &(*list)->next;
500       *list = new_data;
501     }
502   return record;
503 }
504
505
506 typedef enum {
507   insn_bit_size_option = 1,
508   insn_specifying_widths_option,
509   hi_bit_nr_option,
510   flags_filter_option,
511   model_filter_option,
512   multi_sim_option,
513   format_names_option,
514   gen_delayed_branch,
515   unknown_option,
516 } option_names;
517
518 static const name_map option_map[] = {
519   { "insn-bit-size", insn_bit_size_option },
520   { "insn-specifying-widths", insn_specifying_widths_option },
521   { "hi-bit-nr", hi_bit_nr_option },
522   { "flags-filter", flags_filter_option },
523   { "model-filter", model_filter_option },
524   { "multi-sim", multi_sim_option },
525   { "format-names", format_names_option },
526   { "gen-delayed-branch", gen_delayed_branch },
527   { NULL, unknown_option },
528 };
529
530 static table_entry *
531 parse_include_record (table *file,
532                       table_entry *record)
533 {
534   /* parse the include record */
535   if (record->nr_fields < nr_include_fields)
536     error (record->line, "Incorrect nr fields for include record\n");
537   /* process it */
538   if (!is_filtered_out (options.flags_filter,
539                         record->field[record_filter_flags_field])
540       && !is_filtered_out (options.model_filter,
541                            record->field[record_filter_models_field]))
542     {
543       table_push (file, record->line, options.include,
544                   record->field[include_filename_field]);
545     }  
546   /* nb: can't read next record until after the file has been pushed */
547   record = table_read (file);
548   return record;
549 }
550
551
552 static table_entry *
553 parse_option_record (table *file,
554                      table_entry *record)
555 {
556   table_entry *option_record;
557   /* parse the option record */
558   option_record = record;
559   if (record->nr_fields < nr_option_fields)
560     error (record->line, "Incorrect nr of fields for option record\n");
561   record = table_read (file);
562   /* process it */
563   if (!is_filtered_out (options.flags_filter,
564                         option_record->field[record_filter_flags_field])
565       && !is_filtered_out (options.model_filter,
566                            option_record->field[record_filter_models_field]))
567     {
568       char *name = option_record->field[option_name_field];
569       option_names option = name2i (name, option_map);
570       char *value = option_record->field[option_value_field];
571       switch (option)
572         {
573         case insn_bit_size_option:
574           {
575             options.insn_bit_size = a2i (value);
576             if (options.insn_bit_size < 0
577                 || options.insn_bit_size > max_insn_bit_size)
578               error (option_record->line, "Instruction bit size out of range\n");
579             if (options.hi_bit_nr != options.insn_bit_size - 1
580                 && options.hi_bit_nr != 0)
581               error (option_record->line, "insn-bit-size / hi-bit-nr conflict\n");
582             break;
583           }
584         case insn_specifying_widths_option:
585           {
586             options.insn_specifying_widths = a2i (value);
587             break;
588           }
589         case hi_bit_nr_option:
590           {
591             options.hi_bit_nr = a2i (value);
592             if (options.hi_bit_nr != 0
593                 && options.hi_bit_nr != options.insn_bit_size - 1)
594               error (option_record->line, "hi-bit-nr / insn-bit-size conflict\n");
595             break;
596           }
597         case flags_filter_option:
598           {
599             filter_parse (&options.flags_filter, value);
600             break;
601           }
602         case model_filter_option:
603           {
604             filter_parse (&options.model_filter, value);
605             break;
606           }
607         case multi_sim_option:
608           {
609             options.gen.multi_sim = a2i (value);
610             break;
611           }
612         case format_names_option:
613           {
614             filter_parse (&options.format_name_filter, value);
615             break;
616           }
617         case gen_delayed_branch:
618           {
619             options.gen.delayed_branch = a2i (value);
620             break;
621           }
622         case unknown_option:
623           {
624             error (option_record->line, "Unknown option - %s\n", name);
625             break;
626           }
627         }
628     }  
629   return record;
630 }
631
632
633 static table_entry *
634 parse_function_record (table *file,
635                        table_entry *record,
636                        function_entry **list,
637                        function_entry **list_entry,
638                        int is_internal)
639 {
640   function_entry *new_function;
641   new_function = ZALLOC (function_entry);
642   new_function->line = record->line;
643   new_function->is_internal = is_internal;
644   /* parse the function header */
645   if (record_is_old (record))
646     {
647       if (record->nr_fields < nr_old_function_fields)
648         error (record->line, "Missing fields from (old) function record\n");
649       new_function->type = record->field[old_function_typedef_field];
650       new_function->type = record->field[old_function_typedef_field];
651       if (record->nr_fields > old_function_param_field)
652         new_function->param = record->field[old_function_param_field];
653       new_function->name = record->field[old_function_name_field];
654     }
655   else
656     {
657       if (record->nr_fields < nr_function_fields)
658         error (record->line, "Missing fields from function record\n");
659       filter_parse (&new_function->flags,
660                     record->field[record_filter_flags_field]);
661       filter_parse (&new_function->models,
662                     record->field[record_filter_models_field]);
663       new_function->type = record->field[function_typedef_field];
664       new_function->param = record->field[function_param_field];
665       new_function->name = record->field[function_name_field];
666     }
667   record = table_read (file);
668   /* parse any function-model records */
669   while (record != NULL
670          && record_prefix_is (record, '*', nr_function_model_fields))
671     {
672       filter_parse (&new_function->models,
673                     record->field[function_model_name_field] + 1 /*skip `*'*/);
674       record = table_read (file);
675     }
676   /* parse the function body */
677   if (record->type == table_code_entry)
678     {
679       new_function->code = record;
680       record = table_read (file);
681     }
682   /* insert it */
683   if (!filter_is_subset (options.flags_filter, new_function->flags))
684     {
685       if (options.warn.discard)
686         notify (new_function->line, "Discarding function entry - filter flags\n");
687     }
688   else if (!filter_is_subset (options.model_filter, new_function->models))
689     {
690       if (options.warn.discard)
691         notify (new_function->line, "Discarding function entry - filter models\n");
692     }
693   else
694     {
695       while (*list != NULL)
696         list = &(*list)->next;
697       *list = new_function;
698       if (list_entry != NULL)
699         *list_entry = new_function;
700     }
701   /* done */
702   return record;
703 }
704
705 static void
706 parse_insn_model_record (table *file,
707                          table_entry *record,
708                          insn_entry *insn,
709                          model_table *model)
710 {
711   insn_model_entry **last_insn_model;
712   insn_model_entry *new_insn_model = ZALLOC (insn_model_entry);
713   /* parse it */
714   new_insn_model->line = record->line;
715   if (record->nr_fields > insn_model_unit_data_field)
716     new_insn_model->unit_data = record->field[insn_model_unit_data_field];
717   new_insn_model->insn = insn;
718   /* parse the model names, verify that all were defined */
719   new_insn_model->names = NULL;
720   filter_parse (&new_insn_model->names,
721                 record->field[insn_model_name_field] + 1 /*skip `*'*/);
722   if (new_insn_model->names == NULL)
723     {
724       /* No processor names - a generic model entry, enter it into all
725          the non-empty fields */
726       int index;
727       for (index = 0; index < model->nr_models; index++)
728         if (insn->model[index] == 0)
729           {
730             insn->model[index] = new_insn_model;
731           }
732       /* also add the complete processor set to this processor's set */
733       filter_add (&insn->processors, model->processors);
734     }
735   else
736     {
737       /* Find the corresponding master model record for each name so
738          that they can be linked in. */
739       int index;
740       char *name = "";
741       while (1)
742         {
743           name = filter_next (new_insn_model->names, name);
744           if (name == NULL) break;
745           index = filter_is_member (model->processors, name) - 1;
746           if (index < 0)
747             {
748               error (new_insn_model->line,
749                      "machine model `%s' undefined\n", name);
750             }
751           /* store it in the corresponding model array entry */
752           if (insn->model[index] != NULL
753               && insn->model[index]->names != NULL)
754             {
755               warning (new_insn_model->line,
756                        "machine model `%s' previously defined\n", name);
757               error (insn->model[index]->line, "earlier definition\n");
758             }
759           insn->model[index] = new_insn_model;
760           /* also add the name to the instructions processor set as an
761              alternative lookup mechanism */
762           filter_parse (&insn->processors, name);
763         }
764     }
765 #if 0
766   /* for some reason record the max length of any
767      function unit field */
768   int len = strlen (insn_model_ptr->field[insn_model_fields]);
769   if (model->max_model_fields_len < len)
770     model->max_model_fields_len = len;
771 #endif
772   /* link it in */
773   last_insn_model = &insn->models;
774   while ((*last_insn_model) != NULL)
775     last_insn_model = &(*last_insn_model)->next;
776   *last_insn_model = new_insn_model;
777 }
778
779
780 static void
781 parse_insn_mnemonic_record (table *file,
782                             table_entry *record,
783                             insn_entry *insn)
784 {
785   insn_mnemonic_entry **last_insn_mnemonic;
786   insn_mnemonic_entry *new_insn_mnemonic = ZALLOC (insn_mnemonic_entry);
787   /* parse it */
788   new_insn_mnemonic->line = record->line;
789   ASSERT (record->nr_fields > insn_mnemonic_format_field);
790   new_insn_mnemonic->format = record->field[insn_mnemonic_format_field];
791   ASSERT (new_insn_mnemonic->format[0] == '"');
792   if (new_insn_mnemonic->format[strlen (new_insn_mnemonic->format) - 1] != '"')
793     error (new_insn_mnemonic->line, "Missing closing double quote in mnemonic field\n");
794   if (record->nr_fields > insn_mnemonic_condition_field)
795     new_insn_mnemonic->condition = record->field[insn_mnemonic_condition_field];
796   new_insn_mnemonic->insn = insn;
797   /* insert it */
798   last_insn_mnemonic = &insn->mnemonics;
799   while ((*last_insn_mnemonic) != NULL)
800     last_insn_mnemonic = &(*last_insn_mnemonic)->next;
801   insn->nr_mnemonics++;
802   *last_insn_mnemonic = new_insn_mnemonic;
803 }
804
805
806 insn_table *
807 load_insn_table (char *file_name,
808                  cache_entry *cache)
809 {
810   table *file = table_open (file_name);
811   table_entry *record = table_read (file);
812
813   insn_table *isa = ZALLOC (insn_table);
814   model_table *model = ZALLOC (model_table);
815   
816   isa->model = model;
817   isa->caches = cache;
818
819   while (record != NULL)
820     {
821
822       switch (record_type (record))
823         {
824
825         case include_record:
826           {
827             record = parse_include_record (file, record);
828             break;
829           }
830
831         case option_record:
832           {
833             if (isa->insns != NULL)
834               error (record->line, "Option after first instruction\n");
835             record = parse_option_record (file, record);
836             break;
837           }
838         
839         case string_function_record:
840           {
841             function_entry *function = NULL;
842             record = parse_function_record (file, record,
843                                             &isa->functions,
844                                             &function,
845                                             0/*is-internal*/);
846             /* convert a string function record into an internal function */
847             if (function != NULL)
848               {
849                 char *name = NZALLOC (char,
850                                       (strlen ("str_")
851                                        + strlen (function->name)
852                                        + 1));
853                 strcat (name, "str_");
854                 strcat (name, function->name);
855                 function->name = name;
856                 function->type = "const char *";
857               }
858             break;
859           }
860         
861         case function_record: /* function record */
862           {
863             record = parse_function_record (file, record,
864                                             &isa->functions,
865                                             NULL,
866                                             0/*is-internal*/);
867             break;
868           }
869
870         case internal_record:
871           {
872             /* only insert it into the function list if it is unknown */
873             function_entry *function = NULL;
874             record = parse_function_record (file, record,
875                                             &isa->functions,
876                                             &function,
877                                             1/*is-internal*/);
878             /* check what was inserted to see if a pseudo-instruction
879                entry also needs to be created */
880             if (function != NULL)
881               {
882                 insn_entry **insn = NULL;
883                 if (strcmp (function->name, "illegal") == 0)
884                   {
885                     /* illegal function save it away */
886                     if (isa->illegal_insn != NULL)
887                       {
888                         warning (function->line,
889                                  "Multiple illegal instruction definitions\n");
890                         error (isa->illegal_insn->line,
891                                "Location of first illegal instruction\n");
892                       }
893                     else
894                       insn = &isa->illegal_insn;
895                   }
896                 if (insn != NULL)
897                   {
898                     *insn = ZALLOC (insn_entry);
899                     (*insn)->line = function->line;
900                     (*insn)->name = function->name;
901                     (*insn)->code = function->code;
902                   }
903               }
904             break;
905           }
906           
907         case scratch_record: /* cache macro records */
908         case cache_record:
909         case compute_record:
910           {
911             cache_entry *new_cache;
912             /* parse the cache record */
913             if (record->nr_fields < nr_cache_fields)
914               error (record->line,
915                      "Incorrect nr of fields for scratch/cache/compute record\n");
916             /* create it */
917             new_cache = ZALLOC (cache_entry);
918             new_cache->line = record->line;
919             filter_parse (&new_cache->flags,
920                           record->field[record_filter_flags_field]);
921             filter_parse (&new_cache->models,
922                           record->field[record_filter_models_field]);
923             new_cache->type = record->field[cache_typedef_field];
924             new_cache->name = record->field[cache_name_field];
925             filter_parse (&new_cache->original_fields,
926                           record->field[cache_original_fields_field]);
927             new_cache->expression = record->field[cache_expression_field];
928             /* insert it but only if not filtered out */
929             if (!filter_is_subset (options.flags_filter, new_cache->flags))
930               {
931                 notify (new_cache->line, "Discarding cache entry %s - filter flags\n",
932                         new_cache->name);
933               }
934             else if (is_filtered_out (options.model_filter,
935                                       record->field[record_filter_models_field]))
936               {
937                 notify (new_cache->line, "Discarding cache entry %s - filter models\n",
938                         new_cache->name);
939               }
940             else
941               {
942                 cache_entry **last;
943                 last = &isa->caches;
944                 while (*last != NULL)
945                   last = &(*last)->next;
946                 *last = new_cache;
947               }
948             /* advance things */
949             record = table_read (file);
950             break;
951           }
952         
953         /* model records */
954         case model_processor_record:
955           {
956             model_entry *new_model;
957             /* parse the model */
958             if (record->nr_fields < nr_model_processor_fields)
959               error (record->line, "Incorrect nr of fields for model record\n");
960             if (isa->insns != NULL)
961               error (record->line, "Model appears after first instruction\n");
962             new_model = ZALLOC (model_entry);
963             filter_parse (&new_model->flags,
964                           record->field[record_filter_flags_field]);
965             new_model->line = record->line;
966             new_model->name = record->field[model_name_field];
967             new_model->full_name = record->field[model_full_name_field];
968             new_model->unit_data = record->field[model_unit_data_field];
969             /* only insert it if not filtered out */
970             if (!filter_is_subset (options.flags_filter, new_model->flags))
971               {
972                 notify (new_model->line, "Discarding processor model %s - filter flags\n",
973                         new_model->name);
974               }
975             else if (is_filtered_out (options.model_filter,
976                                       record->field[record_filter_models_field]))
977               {
978                 notify (new_model->line, "Discarding processor model %s - filter models\n",
979                         new_model->name);
980               }
981             else if (filter_is_member (model->processors, new_model->name))
982               {
983                 error (new_model->line, "Duplicate processor model %s\n",
984                        new_model->name);
985               }
986             else
987               {
988                 model_entry **last;
989                 last = &model->models;
990                 while (*last != NULL)
991                   last = &(*last)->next;
992                 *last = new_model;
993                 /* count it */
994                 model->nr_models ++;
995                 filter_parse (&model->processors, new_model->name);
996               }
997             /* advance things */
998             record = table_read (file);
999           }
1000           break;
1001           
1002         case model_macro_record:
1003           record = parse_model_data_record (isa, file, record,
1004                                             nr_model_macro_fields,
1005                                             &model->macros);
1006           break;
1007           
1008         case model_data_record:
1009           record = parse_model_data_record (isa, file, record,
1010                                             nr_model_data_fields,
1011                                             &model->data);
1012           break;
1013           
1014         case model_static_record:
1015           record = parse_function_record (file, record,
1016                                           &model->statics,
1017                                           NULL,
1018                                           0/*is internal*/);
1019           break;
1020           
1021         case model_internal_record:
1022           record = parse_function_record (file, record,
1023                                           &model->internals,
1024                                           NULL,
1025                                           1/*is internal*/);
1026           break;
1027           
1028         case model_function_record:
1029           record = parse_function_record (file, record,
1030                                           &model->functions,
1031                                           NULL,
1032                                           0/*is internal*/);
1033           break;
1034           
1035         case insn_record: /* instruction records */
1036           {
1037             insn_entry *new_insn;
1038             char *format;
1039             /* parse the instruction */
1040             if (record->nr_fields < nr_insn_fields)
1041               error (record->line, "Incorrect nr of fields for insn record\n");
1042             new_insn = ZALLOC (insn_entry);
1043             new_insn->line = record->line;
1044             filter_parse (&new_insn->flags,
1045                           record->field[record_filter_flags_field]);
1046             /* save the format field.  Can't parse it until after the
1047                filter-out checks.  Could be filtered out because the
1048                format is invalid */
1049             format = record->field[insn_word_field];
1050             new_insn->format_name = record->field[insn_format_name_field];
1051             if (options.format_name_filter != NULL
1052                 && !filter_is_member (options.format_name_filter,
1053                                       new_insn->format_name))
1054               error (new_insn->line, "Unreconized instruction format name `%s'\n",
1055                      new_insn->format_name);
1056             filter_parse (&new_insn->options,
1057                           record->field[insn_options_field]);
1058             new_insn->name = record->field[insn_name_field];
1059             record = table_read (file);
1060             /* Parse any model/assember records */
1061             new_insn->nr_models = model->nr_models;
1062             new_insn->model = NZALLOC (insn_model_entry*, model->nr_models + 1);
1063             while (record != NULL)
1064               {
1065                 if (record_prefix_is (record, '*', nr_insn_model_fields))
1066                   parse_insn_model_record (file, record, new_insn, model);
1067                 else if (record_prefix_is (record, '"', nr_insn_mnemonic_fields))
1068                   parse_insn_mnemonic_record (file, record, new_insn);
1069                 else
1070                   break;
1071                 /* advance */
1072                 record = table_read (file);
1073               }
1074             /* Parse the code record */
1075             if (record != NULL && record->type == table_code_entry)
1076               {
1077                 new_insn->code = record;
1078                 record = table_read (file);
1079               }
1080             /* insert it */
1081             if (!filter_is_subset (options.flags_filter, new_insn->flags))
1082               {
1083                 if (options.warn.discard)
1084                   notify (new_insn->line,
1085                           "Discarding instruction %s (flags-filter)\n",
1086                           new_insn->name);
1087               }
1088             else if (new_insn->processors != NULL
1089                      && options.model_filter != NULL
1090                      && !filter_is_common (options.model_filter,
1091                                            new_insn->processors))
1092               {
1093                 /* only discard an instruction based in the processor
1094                    model when both the instruction and the options are
1095                    nonempty */
1096                 if (options.warn.discard)
1097                   notify (new_insn->line,
1098                           "Discarding instruction %s (processor-model)\n",
1099                           new_insn->name);
1100               }
1101             else
1102               {
1103                 insn_entry **last;
1104                 /* finish the parsing */
1105                 parse_insn_words (new_insn, format);
1106                 /* append it */
1107                 last = &isa->insns;
1108                 while (*last)
1109                   last = &(*last)->next;
1110                 *last = new_insn;
1111                 /* update global isa counters */
1112                 isa->nr_insns ++;
1113                 if (isa->max_nr_words < new_insn->nr_words)
1114                   isa->max_nr_words = new_insn->nr_words;
1115                 filter_add (&isa->flags, new_insn->flags);
1116                 filter_add (&isa->options, new_insn->options);
1117               }
1118             break;
1119           }
1120       
1121         case unknown_record:
1122         case define_record:
1123         case code_record:
1124           error (record->line, "Unknown or unexpected entry\n");
1125
1126
1127         }
1128     }
1129   return isa;
1130 }
1131
1132
1133 void
1134 print_insn_words (lf *file,
1135                   insn_entry *insn)
1136 {
1137   insn_word_entry *word = insn->words;
1138   if (word != NULL)
1139     {
1140       while (1)
1141         {
1142           insn_field_entry *field = word->first;
1143           while (1)
1144             {
1145               if (options.insn_specifying_widths)
1146                 lf_printf (file, "%d.", field->width);
1147               else
1148                 lf_printf (file, "%d.", i2target (options.hi_bit_nr, field->first));
1149               switch (field->type)
1150                 {
1151                 case insn_field_int:
1152                   lf_printf (file, "0x%lx", (long) field->val_int);
1153                   break;
1154                 case insn_field_reserved:
1155                   lf_printf (file, "/");
1156                   break;
1157                 case insn_field_wild:
1158                   lf_printf (file, "*");
1159                   break;
1160                 case insn_field_string:
1161                   lf_printf (file, "%s", field->val_string);
1162                   break;
1163                 }
1164               if (field == word->last)
1165                 break;
1166               field = field->next;
1167               lf_printf (file, ",");
1168             }
1169           word = word->next;
1170           if (word == NULL)
1171             break;
1172           lf_printf (file, "+");
1173         }
1174     }
1175 }
1176
1177
1178 \f
1179 void
1180 function_entry_traverse (lf *file,
1181                          function_entry *functions,
1182                          function_entry_handler *handler,
1183                          void *data)
1184 {
1185   function_entry *function;
1186   for (function = functions; function != NULL; function = function->next)
1187     {
1188       handler (file, function, data);
1189     }
1190 }
1191
1192 void
1193 insn_table_traverse_insn (lf *file,
1194                           insn_table *isa,
1195                           insn_entry_handler *handler,
1196                           void *data)
1197 {
1198   insn_entry *insn;
1199   for (insn = isa->insns; insn != NULL; insn = insn->next)
1200     {
1201       handler (file, isa, insn, data);
1202     }
1203 }
1204
1205 \f
1206 static void
1207 dump_function_entry (lf *file,
1208                      char *prefix,
1209                      function_entry *entry,
1210                      char *suffix)
1211 {
1212   lf_printf (file, "%s(function_entry *) 0x%lx", prefix, (long) entry);
1213   if (entry != NULL)
1214     {
1215       dump_line_ref (file, "\n(line ", entry->line, ")");
1216       dump_filter (file, "\n(flags ", entry->flags, ")");
1217       lf_printf (file, "\n(type \"%s\")", entry->type);
1218       lf_printf (file, "\n(name \"%s\")", entry->name);
1219       lf_printf (file, "\n(param \"%s\")", entry->param);
1220       dump_table_entry (file, "\n(code ", entry->code, ")");
1221       lf_printf (file, "\n(is_internal %d)", entry->is_internal);
1222       lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1223     }
1224   lf_printf (file, "%s", suffix);
1225 }
1226
1227 static void
1228 dump_function_entries (lf *file,
1229                        char *prefix,
1230                        function_entry *entry,
1231                        char *suffix)
1232 {
1233   lf_printf (file, "%s", prefix);
1234   lf_indent (file, +1);
1235   while (entry != NULL)
1236     {
1237       dump_function_entry (file, "\n(", entry, ")");
1238       entry = entry->next;
1239     }
1240   lf_indent (file, -1);
1241   lf_printf (file, "%s", suffix);
1242 }
1243
1244 static char *
1245 cache_entry_type_to_str (cache_entry_type type)
1246 {
1247   switch (type)
1248     {
1249     case scratch_value: return "scratch";
1250     case cache_value: return "cache";
1251     case compute_value: return "compute";
1252     }
1253   ERROR ("Bad switch");
1254   return 0;
1255 }
1256
1257 static void
1258 dump_cache_entry (lf *file,
1259                   char *prefix,
1260                   cache_entry *entry,
1261                   char *suffix)
1262 {
1263   lf_printf (file, "%s(cache_entry *) 0x%lx", prefix, (long) entry);
1264   if (entry != NULL)
1265     {
1266       dump_line_ref (file, "\n(line ", entry->line, ")");
1267       dump_filter (file, "\n(flags ", entry->flags, ")");
1268       lf_printf (file, "\n(entry_type \"%s\")", cache_entry_type_to_str (entry->entry_type));
1269       lf_printf (file, "\n(name \"%s\")", entry->name);
1270       dump_filter (file, "\n(original_fields ", entry->original_fields, ")");
1271       lf_printf (file, "\n(type \"%s\")", entry->type);
1272       lf_printf (file, "\n(expression \"%s\")", entry->expression);
1273       lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1274     }
1275   lf_printf (file, "%s", suffix);
1276 }
1277
1278 void
1279 dump_cache_entries (lf *file,
1280                     char *prefix,
1281                     cache_entry *entry,
1282                     char *suffix)
1283 {
1284   lf_printf (file, "%s", prefix);
1285   lf_indent (file, +1);
1286   while (entry != NULL)
1287     {
1288       dump_cache_entry (file, "\n(", entry, ")");
1289       entry = entry->next;
1290     }
1291   lf_indent (file, -1);
1292   lf_printf (file, "%s", suffix);
1293 }
1294
1295 static void
1296 dump_model_data (lf *file,
1297                  char *prefix,
1298                  model_data *entry,
1299                  char *suffix)
1300 {
1301   lf_printf (file, "%s(model_data *) 0x%lx", prefix, (long) entry);
1302   if (entry != NULL)
1303     {
1304       lf_indent (file, +1);
1305       dump_line_ref (file, "\n(line ", entry->line, ")");
1306       dump_filter (file, "\n(flags ", entry->flags, ")");
1307       dump_table_entry (file, "\n(entry ", entry->entry, ")");
1308       dump_table_entry (file, "\n(code ", entry->code, ")");
1309       lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1310       lf_indent (file, -1);
1311     }
1312   lf_printf (file, "%s", prefix);
1313 }
1314
1315 static void
1316 dump_model_datas (lf *file,
1317                   char *prefix,
1318                   model_data *entry,
1319                   char *suffix)
1320 {
1321   lf_printf (file, "%s", prefix);
1322   lf_indent (file, +1);
1323   while (entry != NULL)
1324     {
1325       dump_model_data (file, "\n(", entry, ")");
1326       entry = entry->next;
1327     }
1328   lf_indent (file, -1);
1329   lf_printf (file, "%s", suffix);
1330 }
1331
1332 static void
1333 dump_model_entry (lf *file,
1334                   char *prefix,
1335                   model_entry *entry,
1336                   char *suffix)
1337 {
1338   lf_printf (file, "%s(model_entry *) 0x%lx", prefix, (long) entry);
1339   if (entry != NULL)
1340     {
1341       lf_indent (file, +1);
1342       dump_line_ref (file, "\n(line ", entry->line, ")");
1343       dump_filter (file, "\n(flags ", entry->flags, ")");
1344       lf_printf (file, "\n(name \"%s\")", entry->name);
1345       lf_printf (file, "\n(full_name \"%s\")", entry->full_name);
1346       lf_printf (file, "\n(unit_data \"%s\")", entry->unit_data);
1347       lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1348       lf_indent (file, -1);
1349     }
1350   lf_printf (file, "%s", prefix);
1351 }
1352
1353 static void
1354 dump_model_entries (lf *file,
1355                     char *prefix,
1356                     model_entry *entry,
1357                     char *suffix)
1358 {
1359   lf_printf (file, "%s", prefix);
1360   lf_indent (file, +1);
1361   while (entry != NULL)
1362     {
1363       dump_model_entry (file, "\n(", entry, ")");
1364       entry = entry->next;
1365     }
1366   lf_indent (file, -1);
1367   lf_printf (file, "%s", suffix);
1368 }
1369
1370
1371 static void
1372 dump_model_table (lf *file,
1373                   char *prefix,
1374                   model_table *entry,
1375                   char *suffix)
1376 {
1377   lf_printf (file, "%s(model_table *) 0x%lx", prefix, (long) entry);
1378   if (entry != NULL)
1379     {
1380       lf_indent (file, +1);
1381       dump_filter (file, "\n(processors ", entry->processors, ")");
1382       lf_printf (file, "\n(nr_models %d)", entry->nr_models);
1383       dump_model_entries (file, "\n(models ", entry->models, ")");
1384       dump_model_datas (file, "\n(macros ", entry->macros, ")");
1385       dump_model_datas (file, "\n(data ", entry->data, ")");
1386       dump_function_entries (file, "\n(statics ", entry->statics, ")");
1387       dump_function_entries (file, "\n(internals ", entry->functions, ")");
1388       dump_function_entries (file, "\n(functions ", entry->functions, ")");
1389       lf_indent (file, -1);
1390     }
1391   lf_printf (file, "%s", suffix);
1392 }
1393
1394
1395 static char *
1396 insn_field_type_to_str (insn_field_type type)
1397 {
1398   switch (type)
1399     {
1400     case insn_field_int: return "int";
1401     case insn_field_reserved: return "reserved";
1402     case insn_field_wild: return "wild";
1403     case insn_field_string: return "string";
1404     }
1405   ERROR ("bad switch");
1406   return 0;
1407 }
1408
1409 void
1410 dump_insn_field (lf *file,
1411                  char *prefix,
1412                  insn_field_entry *field,
1413                  char *suffix)
1414 {
1415   char *sep = " ";
1416   lf_printf (file, "%s(insn_field_entry *) 0x%lx", prefix, (long) field);
1417   if (field != NULL)
1418     {
1419       lf_indent (file, +1);
1420       lf_printf (file, "%s(first %d)", sep, field->first);
1421       lf_printf (file, "%s(last %d)", sep, field->last);
1422       lf_printf (file, "%s(width %d)", sep, field->width);
1423       lf_printf (file, "%s(type %s)", sep, insn_field_type_to_str (field->type));
1424       switch (field->type)
1425         {
1426         case insn_field_int:
1427           lf_printf (file, "%s(val 0x%lx)", sep, (long) field->val_int);
1428           break;
1429         case insn_field_reserved:
1430           /* nothing output */
1431           break;
1432         case insn_field_wild:
1433           /* nothing output */
1434           break;
1435         case insn_field_string:
1436           lf_printf (file, "%s(val \"%s\")", sep, field->val_string);
1437           break;
1438         }
1439       lf_printf (file, "%s(next 0x%lx)", sep, (long) field->next);
1440       lf_printf (file, "%s(prev 0x%lx)", sep, (long) field->prev);
1441       lf_indent (file, -1);
1442     }
1443   lf_printf (file, "%s", suffix);
1444 }
1445
1446 void
1447 dump_insn_word_entry (lf *file,
1448                       char *prefix,
1449                       insn_word_entry *word,
1450                       char *suffix)
1451 {
1452   lf_printf (file, "%s(insn_word_entry *) 0x%lx", prefix, (long) word);
1453   if (word != NULL)
1454     {
1455       int i;
1456       insn_field_entry *field;
1457       lf_indent (file, +1);
1458       lf_printf (file, "\n(first 0x%lx)", (long) word->first);
1459       lf_printf (file, "\n(last 0x%lx)", (long) word->last);
1460       lf_printf (file, "\n(bit");
1461       for (i = 0; i < options.insn_bit_size; i++)
1462         lf_printf (file, "\n ((value %d) (mask %d) (field 0x%lx))",
1463                    word->bit[i]->value, word->bit[i]->mask, (long) word->bit[i]->field);
1464       lf_printf (file, ")");
1465       for (field = word->first; field != NULL; field = field->next)
1466         dump_insn_field (file, "\n(", field, ")");
1467       dump_filter (file, "\n(field_names ", word->field_names, ")");
1468       lf_printf (file, "\n(next 0x%lx)", (long) word->next);
1469       lf_indent (file, -1);
1470     }
1471   lf_printf (file, "%s", suffix);
1472 }
1473
1474 static void
1475 dump_insn_word_entries (lf *file,
1476                         char *prefix,
1477                         insn_word_entry *word,
1478                         char *suffix)
1479 {
1480   lf_printf (file, "%s", prefix);
1481   while (word != NULL)
1482     {
1483       dump_insn_word_entry (file, "\n(", word, ")");
1484       word = word->next;
1485     }
1486   lf_printf (file, "%s", suffix);
1487 }
1488
1489 static void
1490 dump_insn_model_entry (lf *file,
1491                        char *prefix,
1492                        insn_model_entry *model,
1493                        char *suffix)
1494 {
1495   lf_printf (file, "%s(insn_model_entry *) 0x%lx", prefix, (long) model);
1496   if (model != NULL)
1497     {
1498       lf_indent (file, +1);
1499       dump_line_ref (file, "\n(line ", model->line, ")");
1500       dump_filter (file, "\n(names ", model->names, ")");
1501       lf_printf (file, "\n(full_name \"%s\")", model->full_name);
1502       lf_printf (file, "\n(unit_data \"%s\")", model->unit_data);
1503       lf_printf (file, "\n(insn (insn_entry *) 0x%lx)", (long) model->insn);
1504       lf_printf (file, "\n(next (insn_model_entry *) 0x%lx)",
1505                  (long) model->next);
1506       lf_indent (file, -1);
1507     }
1508   lf_printf (file, "%s", suffix);
1509 }
1510
1511 static void
1512 dump_insn_model_entries (lf *file,
1513                          char *prefix,
1514                          insn_model_entry *model,
1515                          char *suffix)
1516 {
1517   lf_printf (file, "%s", prefix);
1518   while (model != NULL)
1519     {
1520       dump_insn_model_entry (file, "\n", model, "");
1521       model = model->next;
1522     }
1523   lf_printf (file, "%s", suffix);
1524 }
1525
1526
1527 static void
1528 dump_insn_mnemonic_entry (lf *file,
1529                           char *prefix,
1530                           insn_mnemonic_entry *mnemonic,
1531                           char *suffix)
1532 {
1533   lf_printf (file, "%s(insn_mnemonic_entry *) 0x%lx", prefix, (long) mnemonic);
1534   if (mnemonic != NULL)
1535     {
1536       lf_indent (file, +1);
1537       dump_line_ref (file, "\n(line ", mnemonic->line, ")");
1538       lf_printf (file, "\n(format \"%s\")", mnemonic->format);
1539       lf_printf (file, "\n(condition \"%s\")", mnemonic->condition);
1540       lf_printf (file, "\n(insn (insn_entry *) 0x%lx)",
1541                  (long) mnemonic->insn);
1542       lf_printf (file, "\n(next (insn_mnemonic_entry *) 0x%lx)",
1543                  (long) mnemonic->next);
1544       lf_indent (file, -1);
1545     }
1546   lf_printf (file, "%s", suffix);
1547 }
1548
1549 static void
1550 dump_insn_mnemonic_entries (lf *file,
1551                             char *prefix,
1552                             insn_mnemonic_entry *mnemonic,
1553                             char *suffix)
1554 {
1555   lf_printf (file, "%s", prefix);
1556   while (mnemonic != NULL)
1557     {
1558       dump_insn_mnemonic_entry (file, "\n", mnemonic, "");
1559       mnemonic = mnemonic->next;
1560     }
1561   lf_printf (file, "%s", suffix);
1562 }
1563
1564 void
1565 dump_insn_entry (lf *file,
1566                  char *prefix,
1567                  insn_entry *entry,
1568                  char *suffix)
1569 {
1570   lf_printf (file, "%s(insn_entry *) 0x%lx", prefix, (long) entry);
1571   if (entry != NULL)
1572     {
1573       int i;
1574       lf_indent (file, +1);
1575       dump_line_ref (file, "\n(line ", entry->line, ")");
1576       dump_filter (file, "\n(flags ", entry->flags, ")");
1577       lf_printf (file, "\n(nr_words %d)", entry->nr_words);
1578       dump_insn_word_entries (file, "\n(words ", entry->words, ")");
1579       lf_printf (file, "\n(word");
1580       for (i = 0; i < entry->nr_models; i++)
1581         lf_printf (file, " 0x%lx", (long) entry->word[i]);
1582       lf_printf (file, ")");
1583       dump_filter (file, "\n(field_names ", entry->field_names, ")");
1584       lf_printf (file, "\n(format_name \"%s\")", entry->format_name);
1585       dump_filter (file, "\n(options ", entry->options, ")");
1586       lf_printf (file, "\n(name \"%s\")", entry->name);
1587       lf_printf (file, "\n(nr_models %d)", entry->nr_models);
1588       dump_insn_model_entries (file, "\n(models ", entry->models, ")");
1589       lf_printf (file, "\n(model");
1590       for (i = 0; i < entry->nr_models; i++)
1591         lf_printf (file, " 0x%lx", (long) entry->model[i]);
1592       lf_printf (file, ")");
1593       dump_filter (file, "\n(processors ", entry->processors, ")");
1594       dump_insn_mnemonic_entries (file, "\n(mnemonics ", entry->mnemonics, ")");
1595       dump_table_entry (file, "\n(code ", entry->code, ")");
1596       lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1597       lf_indent (file, -1);
1598   }
1599   lf_printf (file, "%s", suffix);
1600 }
1601
1602 static void
1603 dump_insn_entries (lf *file,
1604                    char *prefix,
1605                    insn_entry *entry,
1606                    char *suffix)
1607 {
1608   lf_printf (file, "%s", prefix);
1609   lf_indent (file, +1);
1610   while (entry != NULL)
1611     {
1612       dump_insn_entry (file, "\n(", entry, ")");
1613       entry = entry->next;
1614     }
1615   lf_indent (file, -1);
1616   lf_printf (file, "%s", suffix);
1617 }
1618
1619
1620
1621 void
1622 dump_insn_table (lf *file,
1623                  char *prefix,
1624                  insn_table *isa,
1625                  char *suffix)
1626 {
1627   lf_printf (file, "%s(insn_table *) 0x%lx", prefix, (long) isa);
1628   if (isa != NULL)
1629     {
1630       lf_indent (file, +1);
1631       dump_cache_entries (file, "\n(caches ", isa->caches, ")");
1632       lf_printf (file, "\n(nr_insns %d)", isa->nr_insns);
1633       lf_printf (file, "\n(max_nr_words %d)", isa->max_nr_words);
1634       dump_insn_entries (file, "\n(insns ", isa->insns, ")");
1635       dump_function_entries (file, "\n(functions ", isa->functions, ")");
1636       dump_insn_entry (file, "\n(illegal_insn ", isa->illegal_insn, ")");
1637       dump_model_table (file, "\n(model ", isa->model, ")");
1638       dump_filter (file, "\n(flags ", isa->flags, ")");
1639       dump_filter (file, "\n(options ", isa->options, ")");
1640       lf_indent (file, -1);
1641     }
1642   lf_printf (file, "%s", suffix);
1643 }
1644
1645 #ifdef MAIN
1646
1647 igen_options options;
1648
1649 int
1650 main (int argc, char **argv)
1651 {
1652   insn_table *isa;
1653   lf *l;
1654
1655   INIT_OPTIONS (options);
1656
1657   if (argc == 3)
1658     filter_parse (&options.flags_filter, argv[2]);
1659   else if (argc != 2)
1660     error (NULL, "Usage: insn <insn-table> [ <filter-in> ]\n");
1661
1662   isa = load_insn_table (argv[1], NULL);
1663   l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn");
1664   dump_insn_table (l, "(isa ", isa, ")\n");
1665
1666   return 0;
1667 }
1668
1669 #endif