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