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