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