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