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