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