* ld-insn.c (print_insn_words): For fields, print conditionals.
[external/binutils.git] / sim / igen / ld-insn.c
1 /* The IGEN simulator generator for GDB, the GNU Debugger.
2
3    Copyright 2002, 2007, 2008, 2009, 2010, 2011 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   /* link it in */
878   last_insn_model = &insn->models;
879   while ((*last_insn_model) != NULL)
880     last_insn_model = &(*last_insn_model)->next;
881   *last_insn_model = new_insn_model;
882 }
883
884
885 static void
886 parse_insn_mnemonic_record (table *file,
887                             table_entry *record, insn_entry * insn)
888 {
889   insn_mnemonic_entry **last_insn_mnemonic;
890   insn_mnemonic_entry *new_insn_mnemonic = ZALLOC (insn_mnemonic_entry);
891   /* parse it */
892   new_insn_mnemonic->line = record->line;
893   ASSERT (record->nr_fields > insn_mnemonic_format_field);
894   new_insn_mnemonic->format = record->field[insn_mnemonic_format_field];
895   ASSERT (new_insn_mnemonic->format[0] == '"');
896   if (new_insn_mnemonic->format[strlen (new_insn_mnemonic->format) - 1] !=
897       '"')
898     error (new_insn_mnemonic->line,
899            "Missing closing double quote in mnemonic field\n");
900   if (record->nr_fields > insn_mnemonic_condition_field)
901     new_insn_mnemonic->condition =
902       record->field[insn_mnemonic_condition_field];
903   new_insn_mnemonic->insn = insn;
904   /* insert it */
905   last_insn_mnemonic = &insn->mnemonics;
906   while ((*last_insn_mnemonic) != NULL)
907     last_insn_mnemonic = &(*last_insn_mnemonic)->next;
908   insn->nr_mnemonics++;
909   *last_insn_mnemonic = new_insn_mnemonic;
910 }
911
912
913 static table_entry *
914 parse_macro_record (table *file, table_entry *record)
915 {
916 #if 1
917   error (record->line, "Macros are not implemented");
918 #else
919   /* parse the define record */
920   if (record->nr_fields < nr_define_fields)
921     error (record->line, "Incorrect nr fields for define record\n");
922   /* process it */
923   if (!is_filtered_out (options.flags_filter,
924                         record->field[record_filter_flags_field])
925       && !is_filtered_out (options.model_filter,
926                            record->field[record_filter_models_field]))
927     {
928       table_define (file,
929                     record->line,
930                     record->field[macro_name_field],
931                     record->field[macro_args_field],
932                     record->field[macro_expr_field]);
933     }
934   record = table_read (file);
935 #endif
936   return record;
937 }
938
939
940 insn_table *
941 load_insn_table (char *file_name, cache_entry *cache)
942 {
943   table *file = table_open (file_name);
944   table_entry *record = table_read (file);
945
946   insn_table *isa = ZALLOC (insn_table);
947   model_table *model = ZALLOC (model_table);
948
949   isa->model = model;
950   isa->caches = cache;
951
952   while (record != NULL)
953     {
954
955       switch (record_type (record))
956         {
957
958         case include_record:
959           {
960             record = parse_include_record (file, record);
961             break;
962           }
963
964         case option_record:
965           {
966             if (isa->insns != NULL)
967               error (record->line, "Option after first instruction\n");
968             record = parse_option_record (file, record);
969             break;
970           }
971
972         case string_function_record:
973           {
974             function_entry *function = NULL;
975             record = parse_function_record (file, record,
976                                             &isa->functions,
977                                             &function, 0 /*is-internal */ ,
978                                             model);
979             /* convert a string function record into an internal function */
980             if (function != NULL)
981               {
982                 char *name = NZALLOC (char,
983                                       (strlen ("str_")
984                                        + strlen (function->name) + 1));
985                 strcat (name, "str_");
986                 strcat (name, function->name);
987                 function->name = name;
988                 function->type = "const char *";
989               }
990             break;
991           }
992
993         case function_record:   /* function record */
994           {
995             record = parse_function_record (file, record,
996                                             &isa->functions,
997                                             NULL, 0 /*is-internal */ ,
998                                             model);
999             break;
1000           }
1001
1002         case internal_record:
1003           {
1004             /* only insert it into the function list if it is unknown */
1005             function_entry *function = NULL;
1006             record = parse_function_record (file, record,
1007                                             &isa->functions,
1008                                             &function, 1 /*is-internal */ ,
1009                                             model);
1010             /* check what was inserted to see if a pseudo-instruction
1011                entry also needs to be created */
1012             if (function != NULL)
1013               {
1014                 insn_entry **insn = NULL;
1015                 if (strcmp (function->name, "illegal") == 0)
1016                   {
1017                     /* illegal function save it away */
1018                     if (isa->illegal_insn != NULL)
1019                       {
1020                         warning (function->line,
1021                                  "Multiple illegal instruction definitions\n");
1022                         error (isa->illegal_insn->line,
1023                                "Location of first illegal instruction\n");
1024                       }
1025                     else
1026                       insn = &isa->illegal_insn;
1027                   }
1028                 if (insn != NULL)
1029                   {
1030                     *insn = ZALLOC (insn_entry);
1031                     (*insn)->line = function->line;
1032                     (*insn)->name = function->name;
1033                     (*insn)->code = function->code;
1034                   }
1035               }
1036             break;
1037           }
1038
1039         case scratch_record:    /* cache macro records */
1040         case cache_record:
1041         case compute_record:
1042           {
1043             cache_entry *new_cache;
1044             /* parse the cache record */
1045             if (record->nr_fields < nr_cache_fields)
1046               error (record->line,
1047                      "Incorrect nr of fields for scratch/cache/compute record\n");
1048             /* create it */
1049             new_cache = ZALLOC (cache_entry);
1050             new_cache->line = record->line;
1051             filter_parse (&new_cache->flags,
1052                           record->field[record_filter_flags_field]);
1053             filter_parse (&new_cache->models,
1054                           record->field[record_filter_models_field]);
1055             new_cache->type = record->field[cache_typedef_field];
1056             new_cache->name = record->field[cache_name_field];
1057             filter_parse (&new_cache->original_fields,
1058                           record->field[cache_original_fields_field]);
1059             new_cache->expression = record->field[cache_expression_field];
1060             /* insert it but only if not filtered out */
1061             if (!filter_is_subset (options.flags_filter, new_cache->flags))
1062               {
1063                 notify (new_cache->line,
1064                         "Discarding cache entry %s - filter flags\n",
1065                         new_cache->name);
1066               }
1067             else if (is_filtered_out (options.model_filter,
1068                                       record->
1069                                       field[record_filter_models_field]))
1070               {
1071                 notify (new_cache->line,
1072                         "Discarding cache entry %s - filter models\n",
1073                         new_cache->name);
1074               }
1075             else
1076               {
1077                 cache_entry **last;
1078                 last = &isa->caches;
1079                 while (*last != NULL)
1080                   last = &(*last)->next;
1081                 *last = new_cache;
1082               }
1083             /* advance things */
1084             record = table_read (file);
1085             break;
1086           }
1087
1088           /* model records */
1089         case model_processor_record:
1090           {
1091             model_entry *new_model;
1092             /* parse the model */
1093             if (record->nr_fields < nr_model_processor_fields)
1094               error (record->line,
1095                      "Incorrect nr of fields for model record\n");
1096             if (isa->insns != NULL)
1097               error (record->line, "Model appears after first instruction\n");
1098             new_model = ZALLOC (model_entry);
1099             filter_parse (&new_model->flags,
1100                           record->field[record_filter_flags_field]);
1101             new_model->line = record->line;
1102             new_model->name = record->field[model_name_field];
1103             new_model->full_name = record->field[model_full_name_field];
1104             new_model->unit_data = record->field[model_unit_data_field];
1105             /* only insert it if not filtered out */
1106             if (!filter_is_subset (options.flags_filter, new_model->flags))
1107               {
1108                 notify (new_model->line,
1109                         "Discarding processor model %s - filter flags\n",
1110                         new_model->name);
1111               }
1112             else if (is_filtered_out (options.model_filter,
1113                                       record->
1114                                       field[record_filter_models_field]))
1115               {
1116                 notify (new_model->line,
1117                         "Discarding processor model %s - filter models\n",
1118                         new_model->name);
1119               }
1120             else if (filter_is_member (model->processors, new_model->name))
1121               {
1122                 error (new_model->line, "Duplicate processor model %s\n",
1123                        new_model->name);
1124               }
1125             else
1126               {
1127                 model_entry **last;
1128                 last = &model->models;
1129                 while (*last != NULL)
1130                   last = &(*last)->next;
1131                 *last = new_model;
1132                 /* count it */
1133                 model->nr_models++;
1134                 filter_parse (&model->processors, new_model->name);
1135               }
1136             /* advance things */
1137             record = table_read (file);
1138           }
1139           break;
1140
1141         case model_macro_record:
1142           record = parse_model_data_record (isa, file, record,
1143                                             nr_model_macro_fields,
1144                                             &model->macros);
1145           break;
1146
1147         case model_data_record:
1148           record = parse_model_data_record (isa, file, record,
1149                                             nr_model_data_fields,
1150                                             &model->data);
1151           break;
1152
1153         case model_static_record:
1154           record = parse_function_record (file, record,
1155                                           &model->statics,
1156                                           NULL, 0 /*is internal */ ,
1157                                           model);
1158           break;
1159
1160         case model_internal_record:
1161           record = parse_function_record (file, record,
1162                                           &model->internals,
1163                                           NULL, 1 /*is internal */ ,
1164                                           model);
1165           break;
1166
1167         case model_function_record:
1168           record = parse_function_record (file, record,
1169                                           &model->functions,
1170                                           NULL, 0 /*is internal */ ,
1171                                           model);
1172           break;
1173
1174         case insn_record:       /* instruction records */
1175           {
1176             insn_entry *new_insn;
1177             char *format;
1178             /* parse the instruction */
1179             if (record->nr_fields < nr_insn_fields)
1180               error (record->line,
1181                      "Incorrect nr of fields for insn record\n");
1182             new_insn = ZALLOC (insn_entry);
1183             new_insn->line = record->line;
1184             filter_parse (&new_insn->flags,
1185                           record->field[record_filter_flags_field]);
1186             /* save the format field.  Can't parse it until after the
1187                filter-out checks.  Could be filtered out because the
1188                format is invalid */
1189             format = record->field[insn_word_field];
1190             new_insn->format_name = record->field[insn_format_name_field];
1191             if (options.format_name_filter != NULL
1192                 && !filter_is_member (options.format_name_filter,
1193                                       new_insn->format_name))
1194               error (new_insn->line,
1195                      "Unreconized instruction format name `%s'\n",
1196                      new_insn->format_name);
1197             filter_parse (&new_insn->options,
1198                           record->field[insn_options_field]);
1199             new_insn->name = record->field[insn_name_field];
1200             record = table_read (file);
1201             /* Parse any model/assember records */
1202             new_insn->nr_models = model->nr_models;
1203             new_insn->model =
1204               NZALLOC (insn_model_entry *, model->nr_models + 1);
1205             while (record != NULL)
1206               {
1207                 if (record_prefix_is (record, '*', nr_insn_model_fields))
1208                   parse_insn_model_record (file, record, new_insn, model);
1209                 else
1210                   if (record_prefix_is (record, '"', nr_insn_mnemonic_fields))
1211                   parse_insn_mnemonic_record (file, record, new_insn);
1212                 else
1213                   break;
1214                 /* advance */
1215                 record = table_read (file);
1216               }
1217             /* Parse the code record */
1218             if (record != NULL && record->type == table_code_entry)
1219               {
1220                 new_insn->code = record;
1221                 record = table_read (file);
1222               }
1223             else if (options.warn.unimplemented)
1224               notify (new_insn->line, "unimplemented\n");
1225             /* insert it */
1226             if (!filter_is_subset (options.flags_filter, new_insn->flags))
1227               {
1228                 if (options.warn.discard)
1229                   notify (new_insn->line,
1230                           "Discarding instruction %s (flags-filter)\n",
1231                           new_insn->name);
1232               }
1233             else if (new_insn->processors != NULL
1234                      && options.model_filter != NULL
1235                      && !filter_is_common (options.model_filter,
1236                                            new_insn->processors))
1237               {
1238                 /* only discard an instruction based in the processor
1239                    model when both the instruction and the options are
1240                    nonempty */
1241                 if (options.warn.discard)
1242                   notify (new_insn->line,
1243                           "Discarding instruction %s (processor-model)\n",
1244                           new_insn->name);
1245               }
1246             else
1247               {
1248                 insn_entry **last;
1249                 /* finish the parsing */
1250                 parse_insn_words (new_insn, format);
1251                 /* append it */
1252                 last = &isa->insns;
1253                 while (*last)
1254                   last = &(*last)->next;
1255                 *last = new_insn;
1256                 /* update global isa counters */
1257                 isa->nr_insns++;
1258                 if (isa->max_nr_words < new_insn->nr_words)
1259                   isa->max_nr_words = new_insn->nr_words;
1260                 filter_add (&isa->flags, new_insn->flags);
1261                 filter_add (&isa->options, new_insn->options);
1262               }
1263             break;
1264           }
1265
1266         case define_record:
1267           record = parse_macro_record (file, record);
1268           break;
1269
1270         case unknown_record:
1271         case code_record:
1272           error (record->line, "Unknown or unexpected entry\n");
1273
1274
1275         }
1276     }
1277   return isa;
1278 }
1279
1280
1281 void
1282 print_insn_words (lf *file, insn_entry * insn)
1283 {
1284   insn_word_entry *word = insn->words;
1285   if (word != NULL)
1286     {
1287       while (1)
1288         {
1289           insn_field_entry *field = word->first;
1290           while (1)
1291             {
1292               insn_field_cond *cond;
1293
1294               if (options.insn_specifying_widths)
1295                 lf_printf (file, "%d.", field->width);
1296               else
1297                 lf_printf (file, "%d.",
1298                            i2target (options.hi_bit_nr, field->first));
1299               switch (field->type)
1300                 {
1301                 case insn_field_invalid:
1302                   ASSERT (0);
1303                   break;
1304                 case insn_field_int:
1305                   lf_printf (file, "0x%lx", (long) field->val_int);
1306                   break;
1307                 case insn_field_reserved:
1308                   lf_printf (file, "/");
1309                   break;
1310                 case insn_field_wild:
1311                   lf_printf (file, "*");
1312                   break;
1313                 case insn_field_string:
1314                   lf_printf (file, "%s", field->val_string);
1315
1316                   if (field->conditions == NULL)
1317                     break;
1318
1319                   if (field->conditions->test == insn_field_cond_eq)
1320                     {
1321                       if (field->conditions->type == insn_field_cond_value)
1322                         lf_printf (file, "=%ld",
1323                                    (long) field->conditions->value);
1324                       else
1325                         lf_printf (file, "=%s", field->conditions->string);
1326
1327                       /* There can be only one equality condition.  */
1328                       ASSERT (field->conditions->next == NULL);
1329                       break;
1330                     }
1331
1332                   for (cond = field->conditions;
1333                        cond != NULL;
1334                        cond = cond->next)
1335                     {
1336                       ASSERT (cond->test == insn_field_cond_ne);
1337
1338                       if (cond->type == insn_field_cond_value)
1339                         lf_printf (file, "!%ld", (long) cond->value);
1340                       else
1341                         lf_printf (file, "!%s", cond->string);
1342                     }
1343                   break;
1344                 }
1345               if (field == word->last)
1346                 break;
1347               field = field->next;
1348               lf_printf (file, ",");
1349             }
1350           word = word->next;
1351           if (word == NULL)
1352             break;
1353           lf_printf (file, "+");
1354         }
1355     }
1356 }
1357 \f
1358
1359
1360 void
1361 function_entry_traverse (lf *file,
1362                          function_entry * functions,
1363                          function_entry_handler * handler, void *data)
1364 {
1365   function_entry *function;
1366   for (function = functions; function != NULL; function = function->next)
1367     {
1368       handler (file, function, data);
1369     }
1370 }
1371
1372 void
1373 insn_table_traverse_insn (lf *file,
1374                           insn_table *isa,
1375                           insn_entry_handler * handler, void *data)
1376 {
1377   insn_entry *insn;
1378   for (insn = isa->insns; insn != NULL; insn = insn->next)
1379     {
1380       handler (file, isa, insn, data);
1381     }
1382 }
1383 \f
1384
1385 static void
1386 dump_function_entry (lf *file,
1387                      char *prefix, function_entry * entry, char *suffix)
1388 {
1389   lf_printf (file, "%s(function_entry *) 0x%lx", prefix, (long) entry);
1390   if (entry != NULL)
1391     {
1392       dump_line_ref (file, "\n(line ", entry->line, ")");
1393       dump_filter (file, "\n(flags ", entry->flags, ")");
1394       lf_printf (file, "\n(type \"%s\")", entry->type);
1395       lf_printf (file, "\n(name \"%s\")", entry->name);
1396       lf_printf (file, "\n(param \"%s\")", entry->param);
1397       dump_table_entry (file, "\n(code ", entry->code, ")");
1398       lf_printf (file, "\n(is_internal %d)", entry->is_internal);
1399       lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1400     }
1401   lf_printf (file, "%s", suffix);
1402 }
1403
1404 static void
1405 dump_function_entries (lf *file,
1406                        char *prefix, function_entry * entry, char *suffix)
1407 {
1408   lf_printf (file, "%s", prefix);
1409   lf_indent (file, +1);
1410   while (entry != NULL)
1411     {
1412       dump_function_entry (file, "\n(", entry, ")");
1413       entry = entry->next;
1414     }
1415   lf_indent (file, -1);
1416   lf_printf (file, "%s", suffix);
1417 }
1418
1419 static char *
1420 cache_entry_type_to_str (cache_entry_type type)
1421 {
1422   switch (type)
1423     {
1424     case scratch_value:
1425       return "scratch";
1426     case cache_value:
1427       return "cache";
1428     case compute_value:
1429       return "compute";
1430     }
1431   ERROR ("Bad switch");
1432   return 0;
1433 }
1434
1435 static void
1436 dump_cache_entry (lf *file, char *prefix, cache_entry *entry, char *suffix)
1437 {
1438   lf_printf (file, "%s(cache_entry *) 0x%lx", prefix, (long) entry);
1439   if (entry != NULL)
1440     {
1441       dump_line_ref (file, "\n(line ", entry->line, ")");
1442       dump_filter (file, "\n(flags ", entry->flags, ")");
1443       lf_printf (file, "\n(entry_type \"%s\")",
1444                  cache_entry_type_to_str (entry->entry_type));
1445       lf_printf (file, "\n(name \"%s\")", entry->name);
1446       dump_filter (file, "\n(original_fields ", entry->original_fields, ")");
1447       lf_printf (file, "\n(type \"%s\")", entry->type);
1448       lf_printf (file, "\n(expression \"%s\")", entry->expression);
1449       lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1450     }
1451   lf_printf (file, "%s", suffix);
1452 }
1453
1454 void
1455 dump_cache_entries (lf *file, char *prefix, cache_entry *entry, char *suffix)
1456 {
1457   lf_printf (file, "%s", prefix);
1458   lf_indent (file, +1);
1459   while (entry != NULL)
1460     {
1461       dump_cache_entry (file, "\n(", entry, ")");
1462       entry = entry->next;
1463     }
1464   lf_indent (file, -1);
1465   lf_printf (file, "%s", suffix);
1466 }
1467
1468 static void
1469 dump_model_data (lf *file, char *prefix, model_data *entry, char *suffix)
1470 {
1471   lf_printf (file, "%s(model_data *) 0x%lx", prefix, (long) entry);
1472   if (entry != NULL)
1473     {
1474       lf_indent (file, +1);
1475       dump_line_ref (file, "\n(line ", entry->line, ")");
1476       dump_filter (file, "\n(flags ", entry->flags, ")");
1477       dump_table_entry (file, "\n(entry ", entry->entry, ")");
1478       dump_table_entry (file, "\n(code ", entry->code, ")");
1479       lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1480       lf_indent (file, -1);
1481     }
1482   lf_printf (file, "%s", prefix);
1483 }
1484
1485 static void
1486 dump_model_datas (lf *file, char *prefix, model_data *entry, char *suffix)
1487 {
1488   lf_printf (file, "%s", prefix);
1489   lf_indent (file, +1);
1490   while (entry != NULL)
1491     {
1492       dump_model_data (file, "\n(", entry, ")");
1493       entry = entry->next;
1494     }
1495   lf_indent (file, -1);
1496   lf_printf (file, "%s", suffix);
1497 }
1498
1499 static void
1500 dump_model_entry (lf *file, char *prefix, model_entry *entry, char *suffix)
1501 {
1502   lf_printf (file, "%s(model_entry *) 0x%lx", prefix, (long) entry);
1503   if (entry != NULL)
1504     {
1505       lf_indent (file, +1);
1506       dump_line_ref (file, "\n(line ", entry->line, ")");
1507       dump_filter (file, "\n(flags ", entry->flags, ")");
1508       lf_printf (file, "\n(name \"%s\")", entry->name);
1509       lf_printf (file, "\n(full_name \"%s\")", entry->full_name);
1510       lf_printf (file, "\n(unit_data \"%s\")", entry->unit_data);
1511       lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1512       lf_indent (file, -1);
1513     }
1514   lf_printf (file, "%s", prefix);
1515 }
1516
1517 static void
1518 dump_model_entries (lf *file, char *prefix, model_entry *entry, char *suffix)
1519 {
1520   lf_printf (file, "%s", prefix);
1521   lf_indent (file, +1);
1522   while (entry != NULL)
1523     {
1524       dump_model_entry (file, "\n(", entry, ")");
1525       entry = entry->next;
1526     }
1527   lf_indent (file, -1);
1528   lf_printf (file, "%s", suffix);
1529 }
1530
1531
1532 static void
1533 dump_model_table (lf *file, char *prefix, model_table *entry, char *suffix)
1534 {
1535   lf_printf (file, "%s(model_table *) 0x%lx", prefix, (long) entry);
1536   if (entry != NULL)
1537     {
1538       lf_indent (file, +1);
1539       dump_filter (file, "\n(processors ", entry->processors, ")");
1540       lf_printf (file, "\n(nr_models %d)", entry->nr_models);
1541       dump_model_entries (file, "\n(models ", entry->models, ")");
1542       dump_model_datas (file, "\n(macros ", entry->macros, ")");
1543       dump_model_datas (file, "\n(data ", entry->data, ")");
1544       dump_function_entries (file, "\n(statics ", entry->statics, ")");
1545       dump_function_entries (file, "\n(internals ", entry->functions, ")");
1546       dump_function_entries (file, "\n(functions ", entry->functions, ")");
1547       lf_indent (file, -1);
1548     }
1549   lf_printf (file, "%s", suffix);
1550 }
1551
1552
1553 static char *
1554 insn_field_type_to_str (insn_field_type type)
1555 {
1556   switch (type)
1557     {
1558     case insn_field_invalid:
1559       ASSERT (0);
1560       return "(invalid)";
1561     case insn_field_int:
1562       return "int";
1563     case insn_field_reserved:
1564       return "reserved";
1565     case insn_field_wild:
1566       return "wild";
1567     case insn_field_string:
1568       return "string";
1569     }
1570   ERROR ("bad switch");
1571   return 0;
1572 }
1573
1574 void
1575 dump_insn_field (lf *file,
1576                  char *prefix, insn_field_entry *field, char *suffix)
1577 {
1578   char *sep = " ";
1579   lf_printf (file, "%s(insn_field_entry *) 0x%lx", prefix, (long) field);
1580   if (field != NULL)
1581     {
1582       lf_indent (file, +1);
1583       lf_printf (file, "%s(first %d)", sep, field->first);
1584       lf_printf (file, "%s(last %d)", sep, field->last);
1585       lf_printf (file, "%s(width %d)", sep, field->width);
1586       lf_printf (file, "%s(type %s)", sep,
1587                  insn_field_type_to_str (field->type));
1588       switch (field->type)
1589         {
1590         case insn_field_invalid:
1591           ASSERT (0);
1592           break;
1593         case insn_field_int:
1594           lf_printf (file, "%s(val 0x%lx)", sep, (long) field->val_int);
1595           break;
1596         case insn_field_reserved:
1597           /* nothing output */
1598           break;
1599         case insn_field_wild:
1600           /* nothing output */
1601           break;
1602         case insn_field_string:
1603           lf_printf (file, "%s(val \"%s\")", sep, field->val_string);
1604           break;
1605         }
1606       lf_printf (file, "%s(next 0x%lx)", sep, (long) field->next);
1607       lf_printf (file, "%s(prev 0x%lx)", sep, (long) field->prev);
1608       lf_indent (file, -1);
1609     }
1610   lf_printf (file, "%s", suffix);
1611 }
1612
1613 void
1614 dump_insn_word_entry (lf *file,
1615                       char *prefix, insn_word_entry *word, char *suffix)
1616 {
1617   lf_printf (file, "%s(insn_word_entry *) 0x%lx", prefix, (long) word);
1618   if (word != NULL)
1619     {
1620       int i;
1621       insn_field_entry *field;
1622       lf_indent (file, +1);
1623       lf_printf (file, "\n(first 0x%lx)", (long) word->first);
1624       lf_printf (file, "\n(last 0x%lx)", (long) word->last);
1625       lf_printf (file, "\n(bit");
1626       for (i = 0; i < options.insn_bit_size; i++)
1627         lf_printf (file, "\n ((value %d) (mask %d) (field 0x%lx))",
1628                    word->bit[i]->value, word->bit[i]->mask,
1629                    (long) word->bit[i]->field);
1630       lf_printf (file, ")");
1631       for (field = word->first; field != NULL; field = field->next)
1632         dump_insn_field (file, "\n(", field, ")");
1633       dump_filter (file, "\n(field_names ", word->field_names, ")");
1634       lf_printf (file, "\n(next 0x%lx)", (long) word->next);
1635       lf_indent (file, -1);
1636     }
1637   lf_printf (file, "%s", suffix);
1638 }
1639
1640 static void
1641 dump_insn_word_entries (lf *file,
1642                         char *prefix, insn_word_entry *word, char *suffix)
1643 {
1644   lf_printf (file, "%s", prefix);
1645   while (word != NULL)
1646     {
1647       dump_insn_word_entry (file, "\n(", word, ")");
1648       word = word->next;
1649     }
1650   lf_printf (file, "%s", suffix);
1651 }
1652
1653 static void
1654 dump_insn_model_entry (lf *file,
1655                        char *prefix, insn_model_entry *model, char *suffix)
1656 {
1657   lf_printf (file, "%s(insn_model_entry *) 0x%lx", prefix, (long) model);
1658   if (model != NULL)
1659     {
1660       lf_indent (file, +1);
1661       dump_line_ref (file, "\n(line ", model->line, ")");
1662       dump_filter (file, "\n(names ", model->names, ")");
1663       lf_printf (file, "\n(full_name \"%s\")", model->full_name);
1664       lf_printf (file, "\n(unit_data \"%s\")", model->unit_data);
1665       lf_printf (file, "\n(insn (insn_entry *) 0x%lx)", (long) model->insn);
1666       lf_printf (file, "\n(next (insn_model_entry *) 0x%lx)",
1667                  (long) model->next);
1668       lf_indent (file, -1);
1669     }
1670   lf_printf (file, "%s", suffix);
1671 }
1672
1673 static void
1674 dump_insn_model_entries (lf *file,
1675                          char *prefix, insn_model_entry *model, char *suffix)
1676 {
1677   lf_printf (file, "%s", prefix);
1678   while (model != NULL)
1679     {
1680       dump_insn_model_entry (file, "\n", model, "");
1681       model = model->next;
1682     }
1683   lf_printf (file, "%s", suffix);
1684 }
1685
1686
1687 static void
1688 dump_insn_mnemonic_entry (lf *file,
1689                           char *prefix,
1690                           insn_mnemonic_entry *mnemonic, char *suffix)
1691 {
1692   lf_printf (file, "%s(insn_mnemonic_entry *) 0x%lx", prefix,
1693              (long) mnemonic);
1694   if (mnemonic != NULL)
1695     {
1696       lf_indent (file, +1);
1697       dump_line_ref (file, "\n(line ", mnemonic->line, ")");
1698       lf_printf (file, "\n(format \"%s\")", mnemonic->format);
1699       lf_printf (file, "\n(condition \"%s\")", mnemonic->condition);
1700       lf_printf (file, "\n(insn (insn_entry *) 0x%lx)",
1701                  (long) mnemonic->insn);
1702       lf_printf (file, "\n(next (insn_mnemonic_entry *) 0x%lx)",
1703                  (long) mnemonic->next);
1704       lf_indent (file, -1);
1705     }
1706   lf_printf (file, "%s", suffix);
1707 }
1708
1709 static void
1710 dump_insn_mnemonic_entries (lf *file,
1711                             char *prefix,
1712                             insn_mnemonic_entry *mnemonic, char *suffix)
1713 {
1714   lf_printf (file, "%s", prefix);
1715   while (mnemonic != NULL)
1716     {
1717       dump_insn_mnemonic_entry (file, "\n", mnemonic, "");
1718       mnemonic = mnemonic->next;
1719     }
1720   lf_printf (file, "%s", suffix);
1721 }
1722
1723 void
1724 dump_insn_entry (lf *file, char *prefix, insn_entry * entry, char *suffix)
1725 {
1726   lf_printf (file, "%s(insn_entry *) 0x%lx", prefix, (long) entry);
1727   if (entry != NULL)
1728     {
1729       int i;
1730       lf_indent (file, +1);
1731       dump_line_ref (file, "\n(line ", entry->line, ")");
1732       dump_filter (file, "\n(flags ", entry->flags, ")");
1733       lf_printf (file, "\n(nr_words %d)", entry->nr_words);
1734       dump_insn_word_entries (file, "\n(words ", entry->words, ")");
1735       lf_printf (file, "\n(word");
1736       for (i = 0; i < entry->nr_models; i++)
1737         lf_printf (file, " 0x%lx", (long) entry->word[i]);
1738       lf_printf (file, ")");
1739       dump_filter (file, "\n(field_names ", entry->field_names, ")");
1740       lf_printf (file, "\n(format_name \"%s\")", entry->format_name);
1741       dump_filter (file, "\n(options ", entry->options, ")");
1742       lf_printf (file, "\n(name \"%s\")", entry->name);
1743       lf_printf (file, "\n(nr_models %d)", entry->nr_models);
1744       dump_insn_model_entries (file, "\n(models ", entry->models, ")");
1745       lf_printf (file, "\n(model");
1746       for (i = 0; i < entry->nr_models; i++)
1747         lf_printf (file, " 0x%lx", (long) entry->model[i]);
1748       lf_printf (file, ")");
1749       dump_filter (file, "\n(processors ", entry->processors, ")");
1750       dump_insn_mnemonic_entries (file, "\n(mnemonics ", entry->mnemonics,
1751                                   ")");
1752       dump_table_entry (file, "\n(code ", entry->code, ")");
1753       lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1754       lf_indent (file, -1);
1755     }
1756   lf_printf (file, "%s", suffix);
1757 }
1758
1759 static void
1760 dump_insn_entries (lf *file, char *prefix, insn_entry * entry, char *suffix)
1761 {
1762   lf_printf (file, "%s", prefix);
1763   lf_indent (file, +1);
1764   while (entry != NULL)
1765     {
1766       dump_insn_entry (file, "\n(", entry, ")");
1767       entry = entry->next;
1768     }
1769   lf_indent (file, -1);
1770   lf_printf (file, "%s", suffix);
1771 }
1772
1773
1774
1775 void
1776 dump_insn_table (lf *file, char *prefix, insn_table *isa, char *suffix)
1777 {
1778   lf_printf (file, "%s(insn_table *) 0x%lx", prefix, (long) isa);
1779   if (isa != NULL)
1780     {
1781       lf_indent (file, +1);
1782       dump_cache_entries (file, "\n(caches ", isa->caches, ")");
1783       lf_printf (file, "\n(nr_insns %d)", isa->nr_insns);
1784       lf_printf (file, "\n(max_nr_words %d)", isa->max_nr_words);
1785       dump_insn_entries (file, "\n(insns ", isa->insns, ")");
1786       dump_function_entries (file, "\n(functions ", isa->functions, ")");
1787       dump_insn_entry (file, "\n(illegal_insn ", isa->illegal_insn, ")");
1788       dump_model_table (file, "\n(model ", isa->model, ")");
1789       dump_filter (file, "\n(flags ", isa->flags, ")");
1790       dump_filter (file, "\n(options ", isa->options, ")");
1791       lf_indent (file, -1);
1792     }
1793   lf_printf (file, "%s", suffix);
1794 }
1795
1796 #ifdef MAIN
1797
1798 igen_options options;
1799
1800 int
1801 main (int argc, char **argv)
1802 {
1803   insn_table *isa;
1804   lf *l;
1805
1806   INIT_OPTIONS (options);
1807
1808   if (argc == 3)
1809     filter_parse (&options.flags_filter, argv[2]);
1810   else if (argc != 2)
1811     error (NULL, "Usage: insn <insn-table> [ <filter-in> ]\n");
1812
1813   isa = load_insn_table (argv[1], NULL);
1814   l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn");
1815   dump_insn_table (l, "(isa ", isa, ")\n");
1816
1817   return 0;
1818 }
1819
1820 #endif