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