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