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