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