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