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.11  christos    Copyright 2002-2024 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 
     28   1.1  christos #include "igen.h"
     29   1.1  christos #include "ld-insn.h"
     30   1.1  christos #include "ld-decode.h"
     31   1.1  christos #include "gen.h"
     32   1.1  christos 
     33   1.1  christos static insn_uint
     34   1.1  christos sub_val (insn_uint val, int val_last_pos, int first_pos, int last_pos)
     35   1.1  christos {
     36   1.1  christos   return ((val >> (val_last_pos - last_pos))
     37   1.1  christos 	  & (((insn_uint) 1 << (last_pos - first_pos + 1)) - 1));
     38   1.1  christos }
     39   1.1  christos 
     40   1.1  christos static void
     41  1.10  christos update_depth (lf *file, const gen_entry *entry, int depth, void *data)
     42   1.1  christos {
     43   1.1  christos   int *max_depth = (int *) data;
     44   1.1  christos   if (*max_depth < depth)
     45   1.1  christos     *max_depth = depth;
     46   1.1  christos }
     47   1.1  christos 
     48   1.1  christos 
     49   1.1  christos int
     50  1.10  christos gen_entry_depth (const gen_entry *table)
     51   1.1  christos {
     52   1.1  christos   int depth = 0;
     53   1.1  christos   gen_entry_traverse_tree (NULL, table, 1, NULL,	/*start */
     54   1.1  christos 			   update_depth, NULL,	/*end */
     55   1.1  christos 			   &depth);	/* data */
     56   1.1  christos   return depth;
     57   1.1  christos }
     58   1.1  christos 
     59   1.1  christos 
     60   1.1  christos static void
     61  1.10  christos print_gen_entry_path (const line_ref *line,
     62  1.10  christos 		      const gen_entry *table,
     63  1.10  christos 		      error_func *print)
     64   1.1  christos {
     65   1.1  christos   if (table->parent == NULL)
     66   1.1  christos     {
     67   1.1  christos       if (table->top->model != NULL)
     68   1.1  christos 	print (line, "%s", table->top->model->name);
     69   1.1  christos       else
     70  1.11  christos 	{
     71  1.11  christos 	  /* We don't want to output things, but we want the side-effects they
     72  1.11  christos 	     might have (e.g. checking line != NULL).  */
     73  1.11  christos 	  print (line, "%s", "");
     74  1.11  christos 	}
     75   1.1  christos     }
     76   1.1  christos   else
     77   1.1  christos     {
     78   1.1  christos       print_gen_entry_path (line, table->parent, print);
     79   1.1  christos       print (NULL, ".%d", table->opcode_nr);
     80   1.1  christos     }
     81   1.1  christos }
     82   1.1  christos 
     83   1.1  christos static void
     84  1.10  christos print_gen_entry_insns (const gen_entry *table,
     85   1.1  christos 		       error_func *print,
     86  1.10  christos 		       const char *first_message,
     87  1.10  christos 		       const char *next_message)
     88   1.1  christos {
     89   1.1  christos   insn_list *i;
     90  1.10  christos   const char *message;
     91   1.1  christos   message = first_message;
     92   1.1  christos   for (i = table->insns; i != NULL; i = i->next)
     93   1.1  christos     {
     94   1.1  christos       insn_entry *insn = i->insn;
     95   1.1  christos       print_gen_entry_path (insn->line, table, print);
     96   1.1  christos       print (NULL, ": %s.%s %s\n", insn->format_name, insn->name, message);
     97   1.1  christos       if (next_message != NULL)
     98   1.1  christos 	message = next_message;
     99   1.1  christos     }
    100   1.1  christos }
    101   1.1  christos 
    102   1.1  christos /* same as strcmp */
    103   1.1  christos static int
    104  1.10  christos insn_field_cmp (const insn_word_entry *l, const insn_word_entry *r)
    105   1.1  christos {
    106   1.1  christos   while (1)
    107   1.1  christos     {
    108   1.1  christos       int bit_nr;
    109   1.1  christos       if (l == NULL && r == NULL)
    110   1.1  christos 	return 0;		/* all previous fields the same */
    111   1.1  christos       if (l == NULL)
    112   1.1  christos 	return -1;		/* left shorter than right */
    113   1.1  christos       if (r == NULL)
    114   1.1  christos 	return +1;		/* left longer than right */
    115   1.1  christos       for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++)
    116   1.1  christos 	{
    117   1.1  christos 	  if (l->bit[bit_nr]->field->type != insn_field_string)
    118   1.1  christos 	    continue;
    119   1.1  christos 	  if (r->bit[bit_nr]->field->type != insn_field_string)
    120   1.1  christos 	    continue;
    121   1.1  christos 	  if (l->bit[bit_nr]->field->conditions == NULL)
    122   1.1  christos 	    continue;
    123   1.1  christos 	  if (r->bit[bit_nr]->field->conditions == NULL)
    124   1.1  christos 	    continue;
    125   1.1  christos 	  if (0)
    126   1.1  christos 	    printf ("%s%s%s VS %s%s%s\n",
    127   1.1  christos 		    l->bit[bit_nr]->field->val_string,
    128   1.1  christos 		    l->bit[bit_nr]->field->conditions->test ==
    129   1.1  christos 		    insn_field_cond_eq ? "=" : "!",
    130   1.1  christos 		    l->bit[bit_nr]->field->conditions->string,
    131   1.1  christos 		    r->bit[bit_nr]->field->val_string,
    132   1.1  christos 		    r->bit[bit_nr]->field->conditions->test ==
    133   1.1  christos 		    insn_field_cond_eq ? "=" : "!",
    134   1.1  christos 		    r->bit[bit_nr]->field->conditions->string);
    135   1.1  christos 	  if (l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq
    136   1.1  christos 	      && r->bit[bit_nr]->field->conditions->test ==
    137   1.1  christos 	      insn_field_cond_eq)
    138   1.1  christos 	    {
    139   1.1  christos 	      if (l->bit[bit_nr]->field->conditions->type ==
    140   1.1  christos 		  insn_field_cond_field
    141   1.1  christos 		  && r->bit[bit_nr]->field->conditions->type ==
    142   1.1  christos 		  insn_field_cond_field)
    143   1.1  christos 		/* somewhat arbitrary */
    144   1.1  christos 		{
    145   1.1  christos 		  int cmp = strcmp (l->bit[bit_nr]->field->conditions->string,
    146   1.1  christos 				    r->bit[bit_nr]->field->conditions->
    147   1.1  christos 				    string);
    148   1.1  christos 		  if (cmp != 0)
    149   1.1  christos 		    return cmp;
    150   1.1  christos 		  else
    151   1.1  christos 		    continue;
    152   1.1  christos 		}
    153   1.1  christos 	      if (l->bit[bit_nr]->field->conditions->type ==
    154   1.1  christos 		  insn_field_cond_field)
    155   1.1  christos 		return +1;
    156   1.1  christos 	      if (r->bit[bit_nr]->field->conditions->type ==
    157   1.1  christos 		  insn_field_cond_field)
    158   1.1  christos 		return -1;
    159   1.1  christos 	      /* The case of both fields having constant values should have
    160   1.1  christos 	         already have been handled because such fields are converted
    161   1.1  christos 	         into normal constant fields, but we must not make this
    162   1.1  christos 		 an assert, as we wouldn't gracefully handle an (invalid)
    163   1.1  christos 		 duplicate insn description.  */
    164   1.1  christos 	      continue;
    165   1.1  christos 	    }
    166   1.1  christos 	  if (l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq)
    167   1.1  christos 	    return +1;		/* left = only */
    168   1.1  christos 	  if (r->bit[bit_nr]->field->conditions->test == insn_field_cond_eq)
    169   1.1  christos 	    return -1;		/* right = only */
    170   1.1  christos 	  /* FIXME: Need to some what arbitrarily order conditional lists */
    171   1.1  christos 	  continue;
    172   1.1  christos 	}
    173   1.1  christos       l = l->next;
    174   1.1  christos       r = r->next;
    175   1.1  christos     }
    176   1.1  christos }
    177   1.1  christos 
    178   1.1  christos /* same as strcmp */
    179   1.1  christos static int
    180  1.10  christos insn_word_cmp (const insn_word_entry *l, const insn_word_entry *r)
    181   1.1  christos {
    182   1.1  christos   while (1)
    183   1.1  christos     {
    184   1.1  christos       int bit_nr;
    185   1.1  christos       if (l == NULL && r == NULL)
    186   1.1  christos 	return 0;		/* all previous fields the same */
    187   1.1  christos       if (l == NULL)
    188   1.1  christos 	return -1;		/* left shorter than right */
    189   1.1  christos       if (r == NULL)
    190   1.1  christos 	return +1;		/* left longer than right */
    191   1.1  christos       for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++)
    192   1.1  christos 	{
    193   1.1  christos 	  if (l->bit[bit_nr]->mask < r->bit[bit_nr]->mask)
    194   1.1  christos 	    return -1;
    195   1.1  christos 	  if (l->bit[bit_nr]->mask > r->bit[bit_nr]->mask)
    196   1.1  christos 	    return 1;
    197   1.1  christos 	  if (l->bit[bit_nr]->value < r->bit[bit_nr]->value)
    198   1.1  christos 	    return -1;
    199   1.1  christos 	  if (l->bit[bit_nr]->value > r->bit[bit_nr]->value)
    200   1.1  christos 	    return 1;
    201   1.1  christos 	}
    202   1.1  christos       l = l->next;
    203   1.1  christos       r = r->next;
    204   1.1  christos     }
    205   1.1  christos }
    206   1.1  christos 
    207   1.1  christos /* same as strcmp */
    208   1.1  christos static int
    209  1.10  christos opcode_bit_cmp (const opcode_bits *l, const opcode_bits *r)
    210   1.1  christos {
    211   1.1  christos   if (l == NULL && r == NULL)
    212   1.1  christos     return 0;			/* all previous bits the same */
    213   1.1  christos   if (l == NULL)
    214   1.1  christos     return -1;			/* left shorter than right */
    215   1.1  christos   if (r == NULL)
    216   1.1  christos     return +1;			/* left longer than right */
    217   1.1  christos   /* most significant word */
    218   1.1  christos   if (l->field->word_nr < r->field->word_nr)
    219   1.1  christos     return +1;			/* left has more significant word */
    220   1.1  christos   if (l->field->word_nr > r->field->word_nr)
    221   1.1  christos     return -1;			/* right has more significant word */
    222   1.1  christos   /* most significant bit? */
    223   1.1  christos   if (l->first < r->first)
    224   1.1  christos     return +1;			/* left as more significant bit */
    225   1.1  christos   if (l->first > r->first)
    226   1.1  christos     return -1;			/* right as more significant bit */
    227   1.1  christos   /* nr bits? */
    228   1.1  christos   if (l->last < r->last)
    229   1.1  christos     return +1;			/* left as less bits */
    230   1.1  christos   if (l->last > r->last)
    231   1.1  christos     return -1;			/* right as less bits */
    232   1.1  christos   /* value? */
    233   1.1  christos   if (l->value < r->value)
    234   1.1  christos     return -1;
    235   1.1  christos   if (l->value > r->value)
    236   1.1  christos     return 1;
    237   1.1  christos   return 0;
    238   1.1  christos }
    239   1.1  christos 
    240   1.1  christos 
    241   1.1  christos /* same as strcmp */
    242   1.1  christos static int
    243  1.10  christos opcode_bits_cmp (const opcode_bits *l, const opcode_bits *r)
    244   1.1  christos {
    245   1.1  christos   while (1)
    246   1.1  christos     {
    247   1.1  christos       int cmp;
    248   1.1  christos       if (l == NULL && r == NULL)
    249   1.1  christos 	return 0;		/* all previous bits the same */
    250   1.1  christos       cmp = opcode_bit_cmp (l, r);
    251   1.1  christos       if (cmp != 0)
    252   1.1  christos 	return cmp;
    253   1.1  christos       l = l->next;
    254   1.1  christos       r = r->next;
    255   1.1  christos     }
    256   1.1  christos }
    257   1.1  christos 
    258   1.1  christos /* same as strcmp */
    259   1.1  christos static opcode_bits *
    260   1.1  christos new_opcode_bits (opcode_bits *old_bits,
    261   1.1  christos 		 int value,
    262   1.1  christos 		 int first,
    263   1.1  christos 		 int last, insn_field_entry *field, opcode_field *opcode)
    264   1.1  christos {
    265   1.1  christos   opcode_bits *new_bits = ZALLOC (opcode_bits);
    266   1.1  christos   new_bits->field = field;
    267   1.1  christos   new_bits->value = value;
    268   1.1  christos   new_bits->first = first;
    269   1.1  christos   new_bits->last = last;
    270   1.1  christos   new_bits->opcode = opcode;
    271   1.1  christos 
    272   1.1  christos   if (old_bits != NULL)
    273   1.1  christos     {
    274   1.1  christos       opcode_bits *new_list;
    275   1.1  christos       opcode_bits **last = &new_list;
    276   1.1  christos       new_list = new_opcode_bits (old_bits->next,
    277   1.1  christos 				  old_bits->value,
    278   1.1  christos 				  old_bits->first,
    279   1.1  christos 				  old_bits->last,
    280   1.1  christos 				  old_bits->field, old_bits->opcode);
    281   1.1  christos       while (*last != NULL)
    282   1.1  christos 	{
    283   1.1  christos 	  int cmp = opcode_bit_cmp (new_bits, *last);
    284   1.1  christos 	  if (cmp < 0)		/* new < new_list */
    285   1.1  christos 	    {
    286   1.1  christos 	      break;
    287   1.1  christos 	    }
    288   1.1  christos 	  if (cmp == 0)
    289   1.1  christos 	    {
    290   1.1  christos 	      ERROR ("Duplicated insn bits in list");
    291   1.1  christos 	    }
    292   1.1  christos 	  last = &(*last)->next;
    293   1.1  christos 	}
    294   1.1  christos       new_bits->next = *last;
    295   1.1  christos       *last = new_bits;
    296   1.1  christos       return new_list;
    297   1.1  christos     }
    298   1.1  christos   else
    299   1.1  christos     {
    300   1.1  christos       return new_bits;
    301   1.1  christos     }
    302   1.1  christos }
    303   1.1  christos 
    304   1.1  christos /* Same as strcmp().  */
    305   1.1  christos static int
    306   1.1  christos name_cmp (const char *l, const char *r)
    307   1.1  christos {
    308   1.1  christos   if (l == NULL && r == NULL)
    309   1.1  christos     return 0;
    310   1.1  christos   if (l != NULL && r == NULL)
    311   1.1  christos     return -1;
    312   1.1  christos   if (l == NULL && r != NULL)
    313   1.1  christos     return +1;
    314   1.1  christos   return strcmp (l, r);
    315   1.1  christos }
    316   1.1  christos 
    317   1.1  christos 
    318   1.1  christos typedef enum
    319   1.1  christos {
    320   1.1  christos   merge_duplicate_insns,
    321   1.1  christos   report_duplicate_insns,
    322   1.1  christos }
    323   1.1  christos duplicate_insn_actions;
    324   1.1  christos 
    325   1.1  christos static insn_list *
    326   1.1  christos insn_list_insert (insn_list **cur_insn_ptr,
    327   1.1  christos 		  int *nr_insns,
    328   1.1  christos 		  insn_entry * insn,
    329   1.1  christos 		  opcode_bits *expanded_bits,
    330   1.1  christos 		  opcode_field *opcodes,
    331   1.1  christos 		  int nr_prefetched_words,
    332   1.1  christos 		  duplicate_insn_actions duplicate_action)
    333   1.1  christos {
    334   1.1  christos   /* insert it according to the order of the fields & bits */
    335   1.1  christos   for (; (*cur_insn_ptr) != NULL; cur_insn_ptr = &(*cur_insn_ptr)->next)
    336   1.1  christos     {
    337   1.1  christos       int cmp;
    338   1.1  christos 
    339   1.1  christos       /* key#1 sort according to the constant fields of each instruction */
    340   1.1  christos       cmp = insn_word_cmp (insn->words, (*cur_insn_ptr)->insn->words);
    341   1.1  christos       if (cmp < 0)
    342   1.1  christos 	break;
    343   1.1  christos       else if (cmp > 0)
    344   1.1  christos 	continue;
    345   1.1  christos 
    346   1.1  christos       /* key#2 sort according to the expanded bits of each instruction */
    347   1.1  christos       cmp = opcode_bits_cmp (expanded_bits, (*cur_insn_ptr)->expanded_bits);
    348   1.1  christos       if (cmp < 0)
    349   1.1  christos 	break;
    350   1.1  christos       else if (cmp > 0)
    351   1.1  christos 	continue;
    352   1.1  christos 
    353   1.1  christos       /* key#3 sort according to the non-constant fields of each instruction */
    354   1.1  christos       cmp = insn_field_cmp (insn->words, (*cur_insn_ptr)->insn->words);
    355   1.1  christos       if (cmp < 0)
    356   1.1  christos 	break;
    357   1.1  christos       else if (cmp > 0)
    358   1.1  christos 	continue;
    359   1.1  christos 
    360   1.1  christos       if (duplicate_action == merge_duplicate_insns)
    361   1.1  christos 	{
    362   1.1  christos 	  /* key#4: If we're going to merge duplicates, also sort
    363   1.1  christos 	     according to the format_name.  Two instructions with
    364   1.1  christos 	     identical decode patterns, but different names, are
    365   1.1  christos 	     considered different when merging.  Duplicates are only
    366   1.1  christos 	     important when creating a decode table (implied by
    367   1.1  christos 	     report_duplicate_insns) as such a table only has the
    368   1.1  christos 	     instruction's bit code as a way of differentiating
    369   1.1  christos 	     between instructions.  */
    370   1.1  christos 	  int cmp = name_cmp (insn->format_name,
    371   1.1  christos 			      (*cur_insn_ptr)->insn->format_name);
    372   1.1  christos 	  if (cmp < 0)
    373   1.1  christos 	    break;
    374   1.1  christos 	  else if (cmp > 0)
    375   1.1  christos 	    continue;
    376   1.1  christos 	}
    377   1.1  christos 
    378   1.1  christos       if (duplicate_action == merge_duplicate_insns)
    379   1.1  christos 	{
    380   1.1  christos 	  /* key#5: If we're going to merge duplicates, also sort
    381   1.1  christos 	     according to the name.  See comment above for
    382   1.1  christos 	     format_name.  */
    383   1.1  christos 	  int cmp = name_cmp (insn->name, (*cur_insn_ptr)->insn->name);
    384   1.1  christos 	  if (cmp < 0)
    385   1.1  christos 	    break;
    386   1.1  christos 	  else if (cmp > 0)
    387   1.1  christos 	    continue;
    388   1.1  christos 	}
    389   1.1  christos 
    390   1.1  christos       /* duplicate keys, report problem */
    391   1.1  christos       switch (duplicate_action)
    392   1.1  christos 	{
    393   1.1  christos 	case report_duplicate_insns:
    394   1.1  christos 	  /* It would appear that we have two instructions with the
    395   1.1  christos 	     same constant field values across all words and bits.
    396   1.1  christos 	     This error can also occure when insn_field_cmp() is
    397   1.1  christos 	     failing to differentiate between two instructions that
    398   1.1  christos 	     differ only in their conditional fields. */
    399   1.1  christos 	  warning (insn->line,
    400   1.1  christos 		   "Two instructions with identical constant fields\n");
    401   1.1  christos 	  error ((*cur_insn_ptr)->insn->line,
    402   1.1  christos 		 "Location of duplicate instruction\n");
    403   1.1  christos 	case merge_duplicate_insns:
    404   1.1  christos 	  /* Add the opcode path to the instructions list */
    405   1.1  christos 	  if (options.trace.insn_insertion)
    406   1.1  christos 	    {
    407   1.1  christos 	      notify ((*cur_insn_ptr)->insn->line,
    408   1.1  christos 		      "%s.%s: insert merge %s.%s\n",
    409   1.1  christos 		      (*cur_insn_ptr)->insn->format_name,
    410   1.1  christos 		      (*cur_insn_ptr)->insn->name,
    411   1.1  christos 		      insn->format_name,
    412   1.1  christos 		      insn->name);
    413   1.1  christos 	    }
    414   1.1  christos 	  if (opcodes != NULL)
    415   1.1  christos 	    {
    416   1.1  christos 	      insn_opcodes **last = &(*cur_insn_ptr)->opcodes;
    417   1.1  christos 	      while (*last != NULL)
    418   1.1  christos 		{
    419   1.1  christos 		  last = &(*last)->next;
    420   1.1  christos 		}
    421   1.1  christos 	      (*last) = ZALLOC (insn_opcodes);
    422   1.1  christos 	      (*last)->opcode = opcodes;
    423   1.1  christos 	    }
    424   1.1  christos 	  /* Use the larger nr_prefetched_words */
    425   1.1  christos 	  if ((*cur_insn_ptr)->nr_prefetched_words < nr_prefetched_words)
    426   1.1  christos 	    (*cur_insn_ptr)->nr_prefetched_words = nr_prefetched_words;
    427   1.1  christos 	  return (*cur_insn_ptr);
    428   1.1  christos 	}
    429   1.1  christos 
    430   1.1  christos     }
    431   1.1  christos 
    432   1.1  christos   /* create a new list entry and insert it */
    433   1.1  christos   {
    434   1.1  christos     insn_list *new_insn = ZALLOC (insn_list);
    435   1.1  christos     if (options.trace.insn_insertion)
    436   1.1  christos       {
    437   1.1  christos 	notify (insn->line,
    438   1.1  christos 		"%s.%s: insert new\n",
    439   1.1  christos 		insn->format_name,
    440   1.1  christos 		insn->name);
    441   1.1  christos       }
    442   1.1  christos     new_insn->insn = insn;
    443   1.1  christos     new_insn->expanded_bits = expanded_bits;
    444   1.1  christos     new_insn->next = (*cur_insn_ptr);
    445   1.1  christos     new_insn->nr_prefetched_words = nr_prefetched_words;
    446   1.1  christos     if (opcodes != NULL)
    447   1.1  christos       {
    448   1.1  christos 	new_insn->opcodes = ZALLOC (insn_opcodes);
    449   1.1  christos 	new_insn->opcodes->opcode = opcodes;
    450   1.1  christos       }
    451   1.1  christos     (*cur_insn_ptr) = new_insn;
    452   1.1  christos   }
    453   1.1  christos 
    454   1.1  christos   *nr_insns += 1;
    455   1.1  christos 
    456   1.1  christos   return (*cur_insn_ptr);
    457   1.1  christos }
    458   1.1  christos 
    459   1.1  christos 
    460   1.1  christos extern void
    461   1.1  christos gen_entry_traverse_tree (lf *file,
    462  1.10  christos 			 const gen_entry *table,
    463   1.1  christos 			 int depth,
    464   1.1  christos 			 gen_entry_handler * start,
    465   1.1  christos 			 gen_entry_handler * leaf,
    466   1.1  christos 			 gen_entry_handler * end, void *data)
    467   1.1  christos {
    468   1.1  christos   gen_entry *entry;
    469   1.1  christos 
    470   1.1  christos   ASSERT (table !=NULL);
    471   1.1  christos   ASSERT (table->opcode != NULL);
    472   1.1  christos   ASSERT (table->nr_entries > 0);
    473   1.1  christos   ASSERT (table->entries != 0);
    474   1.1  christos 
    475   1.1  christos   /* prefix */
    476   1.1  christos   if (start != NULL && depth >= 0)
    477   1.1  christos     {
    478   1.1  christos       start (file, table, depth, data);
    479   1.1  christos     }
    480   1.1  christos   /* infix leaves */
    481   1.1  christos   for (entry = table->entries; entry != NULL; entry = entry->sibling)
    482   1.1  christos     {
    483   1.1  christos       if (entry->entries != NULL && depth != 0)
    484   1.1  christos 	{
    485   1.1  christos 	  gen_entry_traverse_tree (file, entry, depth + 1,
    486   1.1  christos 				   start, leaf, end, data);
    487   1.1  christos 	}
    488   1.1  christos       else if (depth >= 0)
    489   1.1  christos 	{
    490   1.1  christos 	  if (leaf != NULL)
    491   1.1  christos 	    {
    492   1.1  christos 	      leaf (file, entry, depth, data);
    493   1.1  christos 	    }
    494   1.1  christos 	}
    495   1.1  christos     }
    496   1.1  christos   /* postfix */
    497   1.1  christos   if (end != NULL && depth >= 0)
    498   1.1  christos     {
    499   1.1  christos       end (file, table, depth, data);
    500   1.1  christos     }
    501   1.1  christos }
    502   1.1  christos 
    503   1.1  christos 
    504   1.1  christos 
    505   1.1  christos /* create a list element containing a single gen_table entry */
    506   1.1  christos 
    507   1.1  christos static gen_list *
    508  1.10  christos make_table (const insn_table *isa,
    509  1.10  christos 	    const decode_table *rules,
    510  1.10  christos 	    const model_entry *model)
    511   1.1  christos {
    512   1.1  christos   insn_entry *insn;
    513   1.1  christos   gen_list *entry = ZALLOC (gen_list);
    514   1.1  christos   entry->table = ZALLOC (gen_entry);
    515   1.1  christos   entry->table->top = entry;
    516   1.1  christos   entry->model = model;
    517   1.1  christos   entry->isa = isa;
    518   1.1  christos   for (insn = isa->insns; insn != NULL; insn = insn->next)
    519   1.1  christos     {
    520   1.1  christos       if (model == NULL
    521   1.1  christos 	  || insn->processors == NULL
    522   1.1  christos 	  || filter_is_member (insn->processors, model->name))
    523   1.1  christos 	{
    524   1.1  christos 	  insn_list_insert (&entry->table->insns, &entry->table->nr_insns, insn, NULL,	/* expanded_bits - none yet */
    525   1.1  christos 			    NULL,	/* opcodes - none yet */
    526   1.1  christos 			    0,	/* nr_prefetched_words - none yet */
    527   1.1  christos 			    report_duplicate_insns);
    528   1.1  christos 	}
    529   1.1  christos     }
    530   1.1  christos   entry->table->opcode_rule = rules;
    531   1.1  christos   return entry;
    532   1.1  christos }
    533   1.1  christos 
    534   1.1  christos 
    535   1.1  christos gen_table *
    536  1.10  christos make_gen_tables (const insn_table *isa, const decode_table *rules)
    537   1.1  christos {
    538   1.1  christos   gen_table *gen = ZALLOC (gen_table);
    539   1.1  christos   gen->isa = isa;
    540   1.1  christos   gen->rules = rules;
    541   1.1  christos   if (options.gen.multi_sim)
    542   1.1  christos     {
    543   1.1  christos       gen_list **last = &gen->tables;
    544   1.1  christos       model_entry *model;
    545   1.1  christos       filter *processors;
    546   1.1  christos       if (options.model_filter != NULL)
    547   1.1  christos 	processors = options.model_filter;
    548   1.1  christos       else
    549   1.1  christos 	processors = isa->model->processors;
    550   1.1  christos       for (model = isa->model->models; model != NULL; model = model->next)
    551   1.1  christos 	{
    552   1.1  christos 	  if (filter_is_member (processors, model->name))
    553   1.1  christos 	    {
    554   1.1  christos 	      *last = make_table (isa, rules, model);
    555   1.1  christos 	      last = &(*last)->next;
    556   1.1  christos 	    }
    557   1.1  christos 	}
    558   1.1  christos     }
    559   1.1  christos   else
    560   1.1  christos     {
    561   1.1  christos       gen->tables = make_table (isa, rules, NULL);
    562   1.1  christos     }
    563   1.1  christos   return gen;
    564   1.1  christos }
    565   1.1  christos 
    566   1.1  christos 
    567   1.1  christos /****************************************************************/
    568   1.1  christos 
    569   1.1  christos /* Is the bit, according to the decode rule, identical across all the
    570   1.1  christos    instructions? */
    571   1.1  christos static int
    572  1.10  christos insns_bit_useless (const insn_list *insns, const decode_table *rule, int bit_nr)
    573   1.1  christos {
    574  1.10  christos   const insn_list *entry;
    575   1.1  christos   int value = -1;
    576   1.1  christos   int is_useless = 1;		/* cleared if something actually found */
    577   1.1  christos 
    578   1.1  christos   /* check the instructions for some constant value in at least one of
    579   1.1  christos      the bit fields */
    580   1.1  christos   for (entry = insns; entry != NULL; entry = entry->next)
    581   1.1  christos     {
    582   1.1  christos       insn_word_entry *word = entry->insn->word[rule->word_nr];
    583   1.1  christos       insn_bit_entry *bit = word->bit[bit_nr];
    584   1.1  christos       switch (bit->field->type)
    585   1.1  christos 	{
    586   1.1  christos 	case insn_field_invalid:
    587   1.1  christos 	  ASSERT (0);
    588   1.1  christos 	  break;
    589   1.1  christos 	case insn_field_wild:
    590   1.1  christos 	case insn_field_reserved:
    591   1.1  christos 	  /* neither useless or useful - ignore */
    592   1.1  christos 	  break;
    593   1.1  christos 	case insn_field_int:
    594   1.1  christos 	  switch (rule->search)
    595   1.1  christos 	    {
    596   1.1  christos 	    case decode_find_strings:
    597   1.1  christos 	      /* an integer isn't a string */
    598   1.1  christos 	      return 1;
    599   1.1  christos 	    case decode_find_constants:
    600   1.1  christos 	    case decode_find_mixed:
    601   1.1  christos 	      /* an integer is useful if its value isn't the same
    602   1.1  christos 	         between all instructions.  The first time through the
    603   1.1  christos 	         value is saved, the second time through (if the
    604   1.1  christos 	         values differ) it is marked as useful. */
    605   1.1  christos 	      if (value < 0)
    606   1.1  christos 		value = bit->value;
    607   1.1  christos 	      else if (value != bit->value)
    608   1.1  christos 		is_useless = 0;
    609   1.1  christos 	      break;
    610   1.1  christos 	    }
    611   1.1  christos 	  break;
    612   1.1  christos 	case insn_field_string:
    613   1.1  christos 	  switch (rule->search)
    614   1.1  christos 	    {
    615   1.1  christos 	    case decode_find_strings:
    616   1.1  christos 	      /* at least one string, keep checking */
    617   1.1  christos 	      is_useless = 0;
    618   1.1  christos 	      break;
    619   1.1  christos 	    case decode_find_constants:
    620   1.1  christos 	    case decode_find_mixed:
    621   1.1  christos 	      if (filter_is_member (rule->constant_field_names,
    622   1.1  christos 				    bit->field->val_string))
    623   1.1  christos 		/* a string field forced to constant? */
    624   1.1  christos 		is_useless = 0;
    625   1.1  christos 	      else if (bit->field->conditions != NULL
    626   1.1  christos 		       && bit->field->conditions->test == insn_field_cond_eq
    627   1.1  christos 		       && bit->field->conditions->type == insn_field_cond_value)
    628   1.1  christos 		{
    629   1.1  christos 		  int shift = bit->field->last - bit_nr;
    630   1.1  christos 		  int bitvalue = (bit->field->conditions->value >> shift) & 1;
    631   1.1  christos 
    632   1.1  christos 		  if (value < 0)
    633   1.1  christos 		    value = bitvalue;
    634   1.1  christos 		  else if (value != bitvalue)
    635   1.1  christos 		    is_useless = 0;
    636   1.1  christos 		}
    637   1.1  christos 	      else if (rule->search == decode_find_constants)
    638   1.1  christos 		/* the string field isn't constant */
    639   1.1  christos 		return 1;
    640   1.1  christos 	      break;
    641   1.1  christos 	    }
    642   1.1  christos 	}
    643   1.1  christos     }
    644   1.1  christos 
    645   1.1  christos   /* Given only one constant value has been found, check through all
    646   1.1  christos      the instructions to see if at least one conditional makes it
    647   1.1  christos      usefull */
    648   1.1  christos   if (value >= 0 && is_useless)
    649   1.1  christos     {
    650   1.1  christos       for (entry = insns; entry != NULL; entry = entry->next)
    651   1.1  christos 	{
    652   1.1  christos 	  insn_word_entry *word = entry->insn->word[rule->word_nr];
    653   1.1  christos 	  insn_bit_entry *bit = word->bit[bit_nr];
    654   1.1  christos 	  switch (bit->field->type)
    655   1.1  christos 	    {
    656   1.1  christos 	    case insn_field_invalid:
    657   1.1  christos 	      ASSERT (0);
    658   1.1  christos 	      break;
    659   1.1  christos 	    case insn_field_wild:
    660   1.1  christos 	    case insn_field_reserved:
    661   1.1  christos 	    case insn_field_int:
    662   1.1  christos 	      /* already processed */
    663   1.1  christos 	      break;
    664   1.1  christos 	    case insn_field_string:
    665   1.1  christos 	      switch (rule->search)
    666   1.1  christos 		{
    667   1.1  christos 		case decode_find_strings:
    668   1.1  christos 		case decode_find_constants:
    669   1.1  christos 		  /* already processed */
    670   1.1  christos 		  break;
    671   1.1  christos 		case decode_find_mixed:
    672   1.1  christos 		  /* string field with conditions.  If this condition
    673   1.1  christos 		     eliminates the value then the compare is useful */
    674   1.1  christos 		  if (bit->field->conditions != NULL)
    675   1.1  christos 		    {
    676   1.1  christos 		      insn_field_cond *condition;
    677   1.1  christos 		      int shift = bit->field->last - bit_nr;
    678   1.1  christos 		      for (condition = bit->field->conditions;
    679   1.1  christos 			   condition != NULL; condition = condition->next)
    680   1.1  christos 			{
    681   1.1  christos 			  switch (condition->type)
    682   1.1  christos 			    {
    683   1.1  christos 			    case insn_field_cond_value:
    684   1.1  christos 			      switch (condition->test)
    685   1.1  christos 				{
    686   1.1  christos 				case insn_field_cond_ne:
    687   1.1  christos 				  if (((condition->value >> shift) & 1)
    688   1.1  christos 				      == (unsigned) value)
    689   1.1  christos 				    /* conditional field excludes the
    690   1.1  christos 				       current value */
    691   1.1  christos 				    is_useless = 0;
    692   1.1  christos 				  break;
    693   1.1  christos 				case insn_field_cond_eq:
    694   1.1  christos 				  if (((condition->value >> shift) & 1)
    695   1.1  christos 				      != (unsigned) value)
    696   1.1  christos 				    /* conditional field requires the
    697   1.1  christos 				       current value */
    698   1.1  christos 				    is_useless = 0;
    699   1.1  christos 				  break;
    700   1.1  christos 				}
    701   1.1  christos 			      break;
    702   1.1  christos 			    case insn_field_cond_field:
    703   1.1  christos 			      /* are these handled separatly? */
    704   1.1  christos 			      break;
    705   1.1  christos 			    }
    706   1.1  christos 			}
    707   1.1  christos 		    }
    708   1.1  christos 		}
    709   1.1  christos 	    }
    710   1.1  christos 	}
    711   1.1  christos     }
    712   1.1  christos 
    713   1.1  christos   return is_useless;
    714   1.1  christos }
    715   1.1  christos 
    716   1.1  christos 
    717   1.1  christos /* go through a gen-table's list of instruction formats looking for a
    718   1.1  christos    range of bits that meet the decode table RULEs requirements */
    719   1.1  christos 
    720   1.1  christos static opcode_field *
    721   1.1  christos gen_entry_find_opcode_field (insn_list *insns,
    722  1.10  christos 			     const decode_table *rule, int string_only)
    723   1.1  christos {
    724   1.1  christos   opcode_field curr_opcode;
    725   1.1  christos   ASSERT (rule != NULL);
    726   1.1  christos 
    727   1.1  christos   memset (&curr_opcode, 0, sizeof (curr_opcode));
    728   1.1  christos   curr_opcode.word_nr = rule->word_nr;
    729   1.1  christos   curr_opcode.first = rule->first;
    730   1.1  christos   curr_opcode.last = rule->last;
    731   1.1  christos 
    732   1.1  christos   /* Try to reduce the size of first..last in accordance with the
    733   1.1  christos      decode rules */
    734   1.1  christos 
    735   1.1  christos   while (curr_opcode.first <= rule->last)
    736   1.1  christos     {
    737   1.1  christos       if (insns_bit_useless (insns, rule, curr_opcode.first))
    738   1.1  christos 	curr_opcode.first++;
    739   1.1  christos       else
    740   1.1  christos 	break;
    741   1.1  christos     }
    742   1.1  christos   while (curr_opcode.last >= rule->first)
    743   1.1  christos     {
    744   1.1  christos       if (insns_bit_useless (insns, rule, curr_opcode.last))
    745   1.1  christos 	curr_opcode.last--;
    746   1.1  christos       else
    747   1.1  christos 	break;
    748   1.1  christos     }
    749   1.1  christos 
    750   1.1  christos   /* did the final opcode field end up being empty? */
    751   1.1  christos   if (curr_opcode.first > curr_opcode.last)
    752   1.1  christos     {
    753   1.1  christos       return NULL;
    754   1.1  christos     }
    755   1.1  christos   ASSERT (curr_opcode.last >= rule->first);
    756   1.1  christos   ASSERT (curr_opcode.first <= rule->last);
    757   1.1  christos   ASSERT (curr_opcode.first <= curr_opcode.last);
    758   1.1  christos 
    759   1.1  christos   /* Ensure that, for the non string only case, the opcode includes
    760   1.1  christos      the range forced_first .. forced_last */
    761   1.1  christos   if (!string_only && curr_opcode.first > rule->force_first)
    762   1.1  christos     {
    763   1.1  christos       curr_opcode.first = rule->force_first;
    764   1.1  christos     }
    765   1.1  christos   if (!string_only && curr_opcode.last < rule->force_last)
    766   1.1  christos     {
    767   1.1  christos       curr_opcode.last = rule->force_last;
    768   1.1  christos     }
    769   1.1  christos 
    770   1.1  christos   /* For the string only case, force just the lower bound (so that the
    771   1.1  christos      shift can be eliminated) */
    772   1.1  christos   if (string_only && rule->force_last == options.insn_bit_size - 1)
    773   1.1  christos     {
    774   1.1  christos       curr_opcode.last = options.insn_bit_size - 1;
    775   1.1  christos     }
    776   1.1  christos 
    777   1.1  christos   /* handle any special cases */
    778   1.1  christos   switch (rule->type)
    779   1.1  christos     {
    780   1.1  christos     case normal_decode_rule:
    781   1.1  christos       /* let the above apply */
    782   1.1  christos       curr_opcode.nr_opcodes =
    783   1.1  christos 	(1 << (curr_opcode.last - curr_opcode.first + 1));
    784   1.1  christos       break;
    785   1.1  christos     case boolean_rule:
    786   1.1  christos       curr_opcode.is_boolean = 1;
    787   1.1  christos       curr_opcode.boolean_constant = rule->constant;
    788   1.1  christos       curr_opcode.nr_opcodes = 2;
    789   1.1  christos       break;
    790   1.1  christos     }
    791   1.1  christos 
    792   1.1  christos   {
    793   1.1  christos     opcode_field *new_field = ZALLOC (opcode_field);
    794   1.1  christos     memcpy (new_field, &curr_opcode, sizeof (opcode_field));
    795   1.1  christos     return new_field;
    796   1.1  christos   }
    797   1.1  christos }
    798   1.1  christos 
    799   1.1  christos 
    800   1.1  christos static void
    801   1.1  christos gen_entry_insert_insn (gen_entry *table,
    802   1.1  christos 		       insn_entry * old_insn,
    803   1.1  christos 		       int new_word_nr,
    804   1.1  christos 		       int new_nr_prefetched_words,
    805   1.1  christos 		       int new_opcode_nr, opcode_bits *new_bits)
    806   1.1  christos {
    807   1.1  christos   gen_entry **entry = &table->entries;
    808   1.1  christos 
    809   1.1  christos   /* find the new table for this entry */
    810   1.1  christos   while ((*entry) != NULL && (*entry)->opcode_nr < new_opcode_nr)
    811   1.1  christos     {
    812   1.1  christos       entry = &(*entry)->sibling;
    813   1.1  christos     }
    814   1.1  christos 
    815   1.1  christos   if ((*entry) == NULL || (*entry)->opcode_nr != new_opcode_nr)
    816   1.1  christos     {
    817   1.1  christos       /* insert the missing entry */
    818   1.1  christos       gen_entry *new_entry = ZALLOC (gen_entry);
    819   1.1  christos       new_entry->sibling = (*entry);
    820   1.1  christos       (*entry) = new_entry;
    821   1.1  christos       table->nr_entries++;
    822   1.1  christos       /* fill it in */
    823   1.1  christos       new_entry->top = table->top;
    824   1.1  christos       new_entry->opcode_nr = new_opcode_nr;
    825   1.1  christos       new_entry->word_nr = new_word_nr;
    826   1.1  christos       new_entry->expanded_bits = new_bits;
    827   1.1  christos       new_entry->opcode_rule = table->opcode_rule->next;
    828   1.1  christos       new_entry->parent = table;
    829   1.1  christos       new_entry->nr_prefetched_words = new_nr_prefetched_words;
    830   1.1  christos     }
    831   1.1  christos   /* ASSERT new_bits == cur_entry bits */
    832   1.1  christos   ASSERT ((*entry) != NULL && (*entry)->opcode_nr == new_opcode_nr);
    833   1.1  christos   insn_list_insert (&(*entry)->insns, &(*entry)->nr_insns, old_insn, NULL,	/* expanded_bits - only in final list */
    834   1.1  christos 		    NULL,	/* opcodes - only in final list */
    835   1.1  christos 		    new_nr_prefetched_words,	/* for this table */
    836   1.1  christos 		    report_duplicate_insns);
    837   1.1  christos }
    838   1.1  christos 
    839   1.1  christos 
    840   1.1  christos static void
    841   1.1  christos gen_entry_expand_opcode (gen_entry *table,
    842   1.1  christos 			 insn_entry * instruction,
    843   1.1  christos 			 int bit_nr, int opcode_nr, opcode_bits *bits)
    844   1.1  christos {
    845   1.1  christos   if (bit_nr > table->opcode->last)
    846   1.1  christos     {
    847   1.1  christos       /* Only include the hardwired bit information with an entry IF
    848   1.1  christos          that entry (and hence its functions) are being duplicated.  */
    849   1.1  christos       if (options.trace.insn_expansion)
    850   1.1  christos 	{
    851   1.1  christos 	  print_gen_entry_path (table->opcode_rule->line, table, notify);
    852   1.1  christos 	  notify (NULL, ": insert %d - %s.%s%s\n",
    853   1.1  christos 		  opcode_nr,
    854   1.1  christos 		  instruction->format_name,
    855   1.1  christos 		  instruction->name,
    856   1.1  christos 		  (table->opcode_rule->
    857   1.1  christos 		   with_duplicates ? " (duplicated)" : ""));
    858   1.1  christos 	}
    859   1.1  christos       if (table->opcode_rule->with_duplicates)
    860   1.1  christos 	{
    861   1.1  christos 	  gen_entry_insert_insn (table, instruction,
    862   1.1  christos 				 table->opcode->word_nr,
    863   1.1  christos 				 table->nr_prefetched_words, opcode_nr, bits);
    864   1.1  christos 	}
    865   1.1  christos       else
    866   1.1  christos 	{
    867   1.1  christos 	  gen_entry_insert_insn (table, instruction,
    868   1.1  christos 				 table->opcode->word_nr,
    869   1.1  christos 				 table->nr_prefetched_words, opcode_nr, NULL);
    870   1.1  christos 	}
    871   1.1  christos     }
    872   1.1  christos   else
    873   1.1  christos     {
    874   1.1  christos       insn_word_entry *word = instruction->word[table->opcode->word_nr];
    875   1.1  christos       insn_field_entry *field = word->bit[bit_nr]->field;
    876   1.1  christos       int last_pos = ((field->last < table->opcode->last)
    877   1.1  christos 		      ? field->last : table->opcode->last);
    878   1.1  christos       int first_pos = ((field->first > table->opcode->first)
    879   1.1  christos 		       ? field->first : table->opcode->first);
    880   1.1  christos       int width = last_pos - first_pos + 1;
    881   1.1  christos       switch (field->type)
    882   1.1  christos 	{
    883   1.1  christos 	case insn_field_int:
    884   1.1  christos 	  {
    885   1.1  christos 	    int val;
    886   1.1  christos 	    val = sub_val (field->val_int, field->last, first_pos, last_pos);
    887   1.1  christos 	    gen_entry_expand_opcode (table, instruction,
    888   1.1  christos 				     last_pos + 1,
    889   1.1  christos 				     ((opcode_nr << width) | val), bits);
    890   1.1  christos 	    break;
    891   1.1  christos 	  }
    892   1.1  christos 	default:
    893   1.1  christos 	  {
    894   1.1  christos 	    if (field->type == insn_field_reserved)
    895   1.1  christos 	      gen_entry_expand_opcode (table, instruction,
    896   1.1  christos 				       last_pos + 1,
    897   1.1  christos 				       ((opcode_nr << width)), bits);
    898   1.1  christos 	    else
    899   1.1  christos 	      {
    900   1.1  christos 		int val;
    901   1.1  christos 		int last_val = (table->opcode->is_boolean ? 2 : (1 << width));
    902   1.1  christos 		for (val = 0; val < last_val; val++)
    903   1.1  christos 		  {
    904   1.1  christos 		    /* check to see if the value has been precluded
    905   1.1  christos 		       (by a conditional) in some way */
    906   1.1  christos 		    int is_precluded;
    907   1.1  christos 		    insn_field_cond *condition;
    908   1.1  christos 		    for (condition = field->conditions, is_precluded = 0;
    909   1.1  christos 			 condition != NULL && !is_precluded;
    910   1.1  christos 			 condition = condition->next)
    911   1.1  christos 		      {
    912   1.1  christos 			switch (condition->type)
    913   1.1  christos 			  {
    914   1.1  christos 			  case insn_field_cond_value:
    915   1.1  christos 			    {
    916   1.1  christos 			      int value =
    917   1.1  christos 				sub_val (condition->value, field->last,
    918   1.1  christos 					 first_pos, last_pos);
    919   1.1  christos 			      switch (condition->test)
    920   1.1  christos 				{
    921   1.1  christos 				case insn_field_cond_ne:
    922   1.1  christos 				  if (value == val)
    923   1.1  christos 				    is_precluded = 1;
    924   1.1  christos 				  break;
    925   1.1  christos 				case insn_field_cond_eq:
    926   1.1  christos 				  if (value != val)
    927   1.1  christos 				    is_precluded = 1;
    928   1.1  christos 				  break;
    929   1.1  christos 				}
    930   1.1  christos 			      break;
    931   1.1  christos 			    }
    932   1.1  christos 			  case insn_field_cond_field:
    933   1.1  christos 			    {
    934   1.1  christos 			      int value = -1;
    935   1.1  christos 			      opcode_bits *bit;
    936   1.1  christos 			      gen_entry *t = NULL;
    937   1.1  christos 			      /* Try to find a value for the
    938   1.1  christos 			         conditional by looking back through
    939   1.1  christos 			         the previously defined bits for one
    940   1.1  christos 			         that covers the designated
    941   1.1  christos 			         conditional field */
    942   1.1  christos 			      for (bit = bits; bit != NULL; bit = bit->next)
    943   1.1  christos 				{
    944   1.1  christos 				  if (bit->field->word_nr ==
    945   1.1  christos 				      condition->field->word_nr
    946   1.1  christos 				      && bit->first <= condition->field->first
    947   1.1  christos 				      && bit->last >= condition->field->last)
    948   1.1  christos 				    {
    949   1.1  christos 				      /* the bit field fully specified
    950   1.1  christos 				         the conditional field's value */
    951   1.1  christos 				      value = sub_val (bit->value, bit->last,
    952   1.1  christos 						       condition->field->
    953   1.1  christos 						       first,
    954   1.1  christos 						       condition->field->
    955   1.1  christos 						       last);
    956   1.1  christos 				    }
    957   1.1  christos 				}
    958   1.1  christos 			      /* Try to find a value by looking
    959   1.1  christos 			         through this and previous tables */
    960   1.1  christos 			      if (bit == NULL)
    961   1.1  christos 				{
    962   1.1  christos 				  for (t = table;
    963   1.1  christos 				       t->parent != NULL; t = t->parent)
    964   1.1  christos 				    {
    965   1.1  christos 				      if (t->parent->opcode->word_nr ==
    966   1.1  christos 					  condition->field->word_nr
    967   1.1  christos 					  && t->parent->opcode->first <=
    968   1.1  christos 					  condition->field->first
    969   1.1  christos 					  && t->parent->opcode->last >=
    970   1.1  christos 					  condition->field->last)
    971   1.1  christos 					{
    972   1.1  christos 					  /* the table entry fully
    973   1.1  christos 					     specified the condition
    974   1.1  christos 					     field's value */
    975   1.1  christos 					  /* extract the field's value
    976   1.1  christos 					     from the opcode */
    977   1.1  christos 					  value =
    978   1.1  christos 					    sub_val (t->opcode_nr,
    979   1.1  christos 						     t->parent->opcode->last,
    980   1.1  christos 						     condition->field->first,
    981   1.1  christos 						     condition->field->last);
    982   1.1  christos 					  /* this is a requirement of
    983   1.1  christos 					     a conditonal field
    984   1.1  christos 					     refering to another field */
    985   1.1  christos 					  ASSERT ((condition->field->first -
    986   1.1  christos 						   condition->field->last) ==
    987   1.1  christos 						  (first_pos - last_pos));
    988   1.1  christos 					  printf
    989   1.1  christos 					    ("value=%d, opcode_nr=%d, last=%d, [%d..%d]\n",
    990   1.1  christos 					     value, t->opcode_nr,
    991   1.1  christos 					     t->parent->opcode->last,
    992   1.1  christos 					     condition->field->first,
    993   1.1  christos 					     condition->field->last);
    994   1.1  christos 					}
    995   1.1  christos 				    }
    996   1.1  christos 				}
    997   1.1  christos 			      if (bit == NULL && t == NULL)
    998   1.1  christos 				error (instruction->line,
    999  1.10  christos 				       "Conditional `%s' of field `%s' isn't expanded\n",
   1000   1.1  christos 				       condition->string, field->val_string);
   1001   1.1  christos 			      switch (condition->test)
   1002   1.1  christos 				{
   1003   1.1  christos 				case insn_field_cond_ne:
   1004   1.1  christos 				  if (value == val)
   1005   1.1  christos 				    is_precluded = 1;
   1006   1.1  christos 				  break;
   1007   1.1  christos 				case insn_field_cond_eq:
   1008   1.1  christos 				  if (value != val)
   1009   1.1  christos 				    is_precluded = 1;
   1010   1.1  christos 				  break;
   1011   1.1  christos 				}
   1012   1.1  christos 			      break;
   1013   1.1  christos 			    }
   1014   1.1  christos 			  }
   1015   1.1  christos 		      }
   1016   1.1  christos 		    if (!is_precluded)
   1017   1.1  christos 		      {
   1018   1.1  christos 			/* Only add additional hardwired bit
   1019   1.1  christos 			   information if the entry is not going to
   1020   1.1  christos 			   later be combined */
   1021   1.1  christos 			if (table->opcode_rule->with_combine)
   1022   1.1  christos 			  {
   1023   1.1  christos 			    gen_entry_expand_opcode (table, instruction,
   1024   1.1  christos 						     last_pos + 1,
   1025   1.1  christos 						     ((opcode_nr << width) |
   1026   1.1  christos 						      val), bits);
   1027   1.1  christos 			  }
   1028   1.1  christos 			else
   1029   1.1  christos 			  {
   1030   1.1  christos 			    opcode_bits *new_bits =
   1031   1.1  christos 			      new_opcode_bits (bits, val,
   1032   1.1  christos 					       first_pos, last_pos,
   1033   1.1  christos 					       field,
   1034   1.1  christos 					       table->opcode);
   1035   1.1  christos 			    gen_entry_expand_opcode (table, instruction,
   1036   1.1  christos 						     last_pos + 1,
   1037   1.1  christos 						     ((opcode_nr << width) |
   1038   1.1  christos 						      val), new_bits);
   1039   1.1  christos 			  }
   1040   1.1  christos 		      }
   1041   1.1  christos 		  }
   1042   1.1  christos 	      }
   1043   1.1  christos 	  }
   1044   1.1  christos 	}
   1045   1.1  christos     }
   1046   1.1  christos }
   1047   1.1  christos 
   1048   1.1  christos static void
   1049   1.1  christos gen_entry_insert_expanding (gen_entry *table, insn_entry * instruction)
   1050   1.1  christos {
   1051   1.1  christos   gen_entry_expand_opcode (table,
   1052   1.1  christos 			   instruction,
   1053   1.1  christos 			   table->opcode->first, 0, table->expanded_bits);
   1054   1.1  christos }
   1055   1.1  christos 
   1056   1.1  christos 
   1057   1.1  christos static int
   1058   1.1  christos insns_match_format_names (insn_list *insns, filter *format_names)
   1059   1.1  christos {
   1060   1.1  christos   if (format_names != NULL)
   1061   1.1  christos     {
   1062   1.1  christos       insn_list *i;
   1063   1.1  christos       for (i = insns; i != NULL; i = i->next)
   1064   1.1  christos 	{
   1065   1.1  christos 	  if (i->insn->format_name != NULL
   1066   1.1  christos 	      && !filter_is_member (format_names, i->insn->format_name))
   1067   1.1  christos 	    return 0;
   1068   1.1  christos 	}
   1069   1.1  christos     }
   1070   1.1  christos   return 1;
   1071   1.1  christos }
   1072   1.1  christos 
   1073   1.1  christos static int
   1074   1.1  christos table_matches_path (gen_entry *table, decode_path_list *paths)
   1075   1.1  christos {
   1076   1.1  christos   if (paths == NULL)
   1077   1.1  christos     return 1;
   1078   1.1  christos   while (paths != NULL)
   1079   1.1  christos     {
   1080   1.1  christos       gen_entry *entry = table;
   1081   1.1  christos       decode_path *path = paths->path;
   1082   1.1  christos       while (1)
   1083   1.1  christos 	{
   1084   1.1  christos 	  if (entry == NULL && path == NULL)
   1085   1.1  christos 	    return 1;
   1086   1.1  christos 	  if (entry == NULL || path == NULL)
   1087   1.1  christos 	    break;
   1088   1.1  christos 	  if (entry->opcode_nr != path->opcode_nr)
   1089   1.1  christos 	    break;
   1090   1.1  christos 	  entry = entry->parent;
   1091   1.1  christos 	  path = path->parent;
   1092   1.1  christos 	}
   1093   1.1  christos       paths = paths->next;
   1094   1.1  christos     }
   1095   1.1  christos   return 0;
   1096   1.1  christos }
   1097   1.1  christos 
   1098   1.1  christos 
   1099   1.1  christos static int
   1100   1.1  christos insns_match_conditions (insn_list *insns, decode_cond *conditions)
   1101   1.1  christos {
   1102   1.1  christos   if (conditions != NULL)
   1103   1.1  christos     {
   1104   1.1  christos       insn_list *i;
   1105   1.1  christos       for (i = insns; i != NULL; i = i->next)
   1106   1.1  christos 	{
   1107   1.1  christos 	  decode_cond *cond;
   1108   1.1  christos 	  for (cond = conditions; cond != NULL; cond = cond->next)
   1109   1.1  christos 	    {
   1110   1.1  christos 	      int bit_nr;
   1111   1.1  christos 	      if (i->insn->nr_words <= cond->word_nr)
   1112   1.1  christos 		return 0;
   1113   1.1  christos 	      for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++)
   1114   1.1  christos 		{
   1115   1.1  christos 		  if (!cond->mask[bit_nr])
   1116   1.1  christos 		    continue;
   1117   1.1  christos 		  if (!i->insn->word[cond->word_nr]->bit[bit_nr]->mask)
   1118   1.1  christos 		    return 0;
   1119   1.1  christos 		  if ((i->insn->word[cond->word_nr]->bit[bit_nr]->value
   1120   1.1  christos 		       == cond->value[bit_nr]) == !cond->is_equal)
   1121   1.1  christos 		    return 0;
   1122   1.1  christos 		}
   1123   1.1  christos 	    }
   1124   1.1  christos 	}
   1125   1.1  christos     }
   1126   1.1  christos   return 1;
   1127   1.1  christos }
   1128   1.1  christos 
   1129   1.1  christos static int
   1130  1.10  christos insns_match_nr_words (const insn_list *insns, int nr_words)
   1131   1.1  christos {
   1132  1.10  christos   const insn_list *i;
   1133   1.1  christos   for (i = insns; i != NULL; i = i->next)
   1134   1.1  christos     {
   1135   1.1  christos       if (i->insn->nr_words < nr_words)
   1136   1.1  christos 	return 0;
   1137   1.1  christos     }
   1138   1.1  christos   return 1;
   1139   1.1  christos }
   1140   1.1  christos 
   1141   1.1  christos static int
   1142  1.10  christos insn_list_cmp (const insn_list *l, const insn_list *r)
   1143   1.1  christos {
   1144   1.1  christos   while (1)
   1145   1.1  christos     {
   1146  1.10  christos       const insn_entry *insn;
   1147   1.1  christos       if (l == NULL && r == NULL)
   1148   1.1  christos 	return 0;
   1149   1.1  christos       if (l == NULL)
   1150   1.1  christos 	return -1;
   1151   1.1  christos       if (r == NULL)
   1152   1.1  christos 	return 1;
   1153   1.1  christos       if (l->insn != r->insn)
   1154   1.1  christos 	return -1;		/* somewhat arbitrary at present */
   1155   1.1  christos       /* skip this insn */
   1156   1.1  christos       insn = l->insn;
   1157   1.1  christos       while (l != NULL && l->insn == insn)
   1158   1.1  christos 	l = l->next;
   1159   1.1  christos       while (r != NULL && r->insn == insn)
   1160   1.1  christos 	r = r->next;
   1161   1.1  christos     }
   1162   1.1  christos }
   1163   1.1  christos 
   1164   1.1  christos 
   1165   1.1  christos 
   1166   1.1  christos static void
   1167   1.1  christos gen_entry_expand_insns (gen_entry *table)
   1168   1.1  christos {
   1169  1.10  christos   const decode_table *opcode_rule;
   1170   1.1  christos 
   1171   1.1  christos   ASSERT (table->nr_insns >= 1);
   1172   1.1  christos 
   1173   1.1  christos   /* determine a valid opcode */
   1174   1.1  christos   for (opcode_rule = table->opcode_rule;
   1175   1.1  christos        opcode_rule != NULL; opcode_rule = opcode_rule->next)
   1176   1.1  christos     {
   1177   1.1  christos       char *discard_reason;
   1178   1.1  christos       if (table->top->model != NULL
   1179   1.1  christos 	  && opcode_rule->model_names != NULL
   1180   1.1  christos 	  && !filter_is_member (opcode_rule->model_names,
   1181   1.1  christos 				table->top->model->name))
   1182   1.1  christos 	{
   1183   1.1  christos 	  /* the rule isn't applicable to this processor */
   1184   1.1  christos 	  discard_reason = "wrong model";
   1185   1.1  christos 	}
   1186   1.1  christos       else if (table->nr_insns == 1 && opcode_rule->conditions == NULL)
   1187   1.1  christos 	{
   1188   1.1  christos 	  /* for safety, require a pre-codition when attempting to
   1189   1.1  christos 	     apply a rule to a single instruction */
   1190   1.1  christos 	  discard_reason = "need pre-condition when nr-insn == 1";
   1191   1.1  christos 	}
   1192   1.1  christos       else if (table->nr_insns == 1 && !opcode_rule->with_duplicates)
   1193   1.1  christos 	{
   1194   1.1  christos 	  /* Little point in expanding a single instruction when we're
   1195   1.1  christos 	     not duplicating the semantic functions that this table
   1196   1.1  christos 	     calls */
   1197   1.1  christos 	  discard_reason = "need duplication with nr-insns == 1";
   1198   1.1  christos 	}
   1199   1.1  christos       else
   1200   1.1  christos 	if (!insns_match_format_names
   1201   1.1  christos 	    (table->insns, opcode_rule->format_names))
   1202   1.1  christos 	{
   1203   1.1  christos 	  discard_reason = "wrong format name";
   1204   1.1  christos 	}
   1205   1.1  christos       else if (!insns_match_nr_words (table->insns, opcode_rule->word_nr + 1))
   1206   1.1  christos 	{
   1207   1.1  christos 	  discard_reason = "wrong nr words";
   1208   1.1  christos 	}
   1209   1.1  christos       else if (!table_matches_path (table, opcode_rule->paths))
   1210   1.1  christos 	{
   1211   1.1  christos 	  discard_reason = "path failed";
   1212   1.1  christos 	}
   1213   1.1  christos       else
   1214   1.1  christos 	if (!insns_match_conditions (table->insns, opcode_rule->conditions))
   1215   1.1  christos 	{
   1216   1.1  christos 	  discard_reason = "condition failed";
   1217   1.1  christos 	}
   1218   1.1  christos       else
   1219   1.1  christos 	{
   1220   1.1  christos 	  discard_reason = "no opcode field";
   1221   1.1  christos 	  table->opcode = gen_entry_find_opcode_field (table->insns,
   1222   1.1  christos 						       opcode_rule,
   1223   1.1  christos 						       table->nr_insns == 1	/*string-only */
   1224   1.1  christos 	    );
   1225   1.1  christos 	  if (table->opcode != NULL)
   1226   1.1  christos 	    {
   1227   1.1  christos 	      table->opcode_rule = opcode_rule;
   1228   1.1  christos 	      break;
   1229   1.1  christos 	    }
   1230   1.1  christos 	}
   1231   1.1  christos 
   1232   1.1  christos       if (options.trace.rule_rejection)
   1233   1.1  christos 	{
   1234   1.1  christos 	  print_gen_entry_path (opcode_rule->line, table, notify);
   1235   1.1  christos 	  notify (NULL, ": rule discarded - %s\n", discard_reason);
   1236   1.1  christos 	}
   1237   1.1  christos     }
   1238   1.1  christos 
   1239   1.1  christos   /* did we find anything */
   1240   1.1  christos   if (opcode_rule == NULL)
   1241   1.1  christos     {
   1242   1.1  christos       /* the decode table failed, this set of instructions haven't
   1243   1.1  christos          been uniquely identified */
   1244   1.1  christos       if (table->nr_insns > 1)
   1245   1.1  christos 	{
   1246   1.1  christos 	  print_gen_entry_insns (table, warning,
   1247   1.1  christos 				 "was not uniquely decoded",
   1248   1.1  christos 				 "decodes to the same entry");
   1249  1.11  christos 	  error (NULL, "unrecoverable\n");
   1250   1.1  christos 	}
   1251   1.1  christos       return;
   1252   1.1  christos     }
   1253   1.1  christos 
   1254   1.1  christos   /* Determine the number of words that must have been prefetched for
   1255   1.1  christos      this table to function */
   1256   1.1  christos   if (table->parent == NULL)
   1257   1.1  christos     table->nr_prefetched_words = table->opcode_rule->word_nr + 1;
   1258   1.1  christos   else if (table->opcode_rule->word_nr + 1 >
   1259   1.1  christos 	   table->parent->nr_prefetched_words)
   1260   1.1  christos     table->nr_prefetched_words = table->opcode_rule->word_nr + 1;
   1261   1.1  christos   else
   1262   1.1  christos     table->nr_prefetched_words = table->parent->nr_prefetched_words;
   1263   1.1  christos 
   1264   1.1  christos   /* back link what we found to its parent */
   1265   1.1  christos   if (table->parent != NULL)
   1266   1.1  christos     {
   1267   1.1  christos       ASSERT (table->parent->opcode != NULL);
   1268   1.1  christos       table->opcode->parent = table->parent->opcode;
   1269   1.1  christos     }
   1270   1.1  christos 
   1271   1.1  christos   /* report the rule being used to expand the instructions */
   1272   1.1  christos   if (options.trace.rule_selection)
   1273   1.1  christos     {
   1274   1.1  christos       print_gen_entry_path (table->opcode_rule->line, table, notify);
   1275   1.1  christos       notify (NULL,
   1276   1.1  christos 	      ": decode - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d\n",
   1277   1.1  christos 	      table->opcode->word_nr,
   1278   1.1  christos 	      i2target (options.hi_bit_nr, table->opcode->first),
   1279   1.1  christos 	      i2target (options.hi_bit_nr, table->opcode->last),
   1280   1.1  christos 	      i2target (options.hi_bit_nr, table->opcode_rule->first),
   1281   1.1  christos 	      i2target (options.hi_bit_nr, table->opcode_rule->last),
   1282   1.1  christos 	      table->opcode->nr_opcodes, table->nr_entries);
   1283   1.1  christos     }
   1284   1.1  christos 
   1285   1.1  christos   /* expand the raw instructions according to the opcode */
   1286   1.1  christos   {
   1287   1.1  christos     insn_list *entry;
   1288   1.1  christos     for (entry = table->insns; entry != NULL; entry = entry->next)
   1289   1.1  christos       {
   1290   1.1  christos 	if (options.trace.insn_expansion)
   1291   1.1  christos 	  {
   1292   1.1  christos 	    print_gen_entry_path (table->opcode_rule->line, table, notify);
   1293   1.1  christos 	    notify (NULL, ": expand - %s.%s\n",
   1294   1.1  christos 		    entry->insn->format_name, entry->insn->name);
   1295   1.1  christos 	  }
   1296   1.1  christos 	gen_entry_insert_expanding (table, entry->insn);
   1297   1.1  christos       }
   1298   1.1  christos   }
   1299   1.1  christos 
   1300   1.1  christos   /* dump the results */
   1301   1.1  christos   if (options.trace.entries)
   1302   1.1  christos     {
   1303   1.1  christos       gen_entry *entry;
   1304   1.1  christos       for (entry = table->entries; entry != NULL; entry = entry->sibling)
   1305   1.1  christos 	{
   1306   1.1  christos 	  insn_list *l;
   1307   1.1  christos 	  print_gen_entry_path (table->opcode_rule->line, entry, notify);
   1308   1.1  christos 	  notify (NULL, ": %d - entries %d -",
   1309   1.1  christos 		  entry->opcode_nr, entry->nr_insns);
   1310   1.1  christos 	  for (l = entry->insns; l != NULL; l = l->next)
   1311   1.1  christos 	    notify (NULL, " %s.%s", l->insn->format_name, l->insn->name);
   1312   1.1  christos 	  notify (NULL, "\n");
   1313   1.1  christos 	}
   1314   1.1  christos     }
   1315   1.1  christos 
   1316   1.1  christos   /* perform a combine pass if needed */
   1317   1.1  christos   if (table->opcode_rule->with_combine)
   1318   1.1  christos     {
   1319   1.1  christos       gen_entry *entry;
   1320   1.1  christos       for (entry = table->entries; entry != NULL; entry = entry->sibling)
   1321   1.1  christos 	{
   1322   1.1  christos 	  if (entry->combined_parent == NULL)
   1323   1.1  christos 	    {
   1324   1.1  christos 	      gen_entry **last = &entry->combined_next;
   1325   1.1  christos 	      gen_entry *alt;
   1326   1.1  christos 	      for (alt = entry->sibling; alt != NULL; alt = alt->sibling)
   1327   1.1  christos 		{
   1328   1.1  christos 		  if (alt->combined_parent == NULL
   1329   1.1  christos 		      && insn_list_cmp (entry->insns, alt->insns) == 0)
   1330   1.1  christos 		    {
   1331   1.1  christos 		      alt->combined_parent = entry;
   1332   1.1  christos 		      *last = alt;
   1333   1.1  christos 		      last = &alt->combined_next;
   1334   1.1  christos 		    }
   1335   1.1  christos 		}
   1336   1.1  christos 	    }
   1337   1.1  christos 	}
   1338   1.1  christos       if (options.trace.combine)
   1339   1.1  christos 	{
   1340   1.1  christos 	  int nr_unique = 0;
   1341   1.1  christos 	  gen_entry *entry;
   1342   1.1  christos 	  for (entry = table->entries; entry != NULL; entry = entry->sibling)
   1343   1.1  christos 	    {
   1344   1.1  christos 	      if (entry->combined_parent == NULL)
   1345   1.1  christos 		{
   1346   1.1  christos 		  insn_list *l;
   1347   1.1  christos 		  gen_entry *duplicate;
   1348   1.1  christos 		  nr_unique++;
   1349   1.1  christos 		  print_gen_entry_path (table->opcode_rule->line, entry,
   1350   1.1  christos 					notify);
   1351   1.1  christos 		  for (duplicate = entry->combined_next; duplicate != NULL;
   1352   1.1  christos 		       duplicate = duplicate->combined_next)
   1353   1.1  christos 		    {
   1354   1.1  christos 		      notify (NULL, "+%d", duplicate->opcode_nr);
   1355   1.1  christos 		    }
   1356   1.1  christos 		  notify (NULL, ": entries %d -", entry->nr_insns);
   1357   1.1  christos 		  for (l = entry->insns; l != NULL; l = l->next)
   1358   1.1  christos 		    {
   1359   1.1  christos 		      notify (NULL, " %s.%s",
   1360   1.1  christos 			      l->insn->format_name, l->insn->name);
   1361   1.1  christos 		    }
   1362   1.1  christos 		  notify (NULL, "\n");
   1363   1.1  christos 		}
   1364   1.1  christos 	    }
   1365   1.1  christos 	  print_gen_entry_path (table->opcode_rule->line, table, notify);
   1366   1.1  christos 	  notify (NULL,
   1367   1.1  christos 		  ": combine - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d, unique %d\n",
   1368   1.1  christos 		  table->opcode->word_nr, i2target (options.hi_bit_nr,
   1369   1.1  christos 						    table->opcode->first),
   1370   1.1  christos 		  i2target (options.hi_bit_nr, table->opcode->last),
   1371   1.1  christos 		  i2target (options.hi_bit_nr, table->opcode_rule->first),
   1372   1.1  christos 		  i2target (options.hi_bit_nr, table->opcode_rule->last),
   1373   1.1  christos 		  table->opcode->nr_opcodes, table->nr_entries, nr_unique);
   1374   1.1  christos 	}
   1375   1.1  christos     }
   1376   1.1  christos 
   1377   1.1  christos   /* Check that the rule did more than re-arange the order of the
   1378   1.1  christos      instructions */
   1379   1.1  christos   {
   1380   1.1  christos     gen_entry *entry;
   1381   1.1  christos     for (entry = table->entries; entry != NULL; entry = entry->sibling)
   1382   1.1  christos       {
   1383   1.1  christos 	if (entry->combined_parent == NULL)
   1384   1.1  christos 	  {
   1385   1.1  christos 	    if (insn_list_cmp (table->insns, entry->insns) == 0)
   1386   1.1  christos 	      {
   1387   1.1  christos 		print_gen_entry_path (table->opcode_rule->line, table,
   1388   1.1  christos 				      warning);
   1389   1.1  christos 		warning (NULL,
   1390   1.1  christos 			 ": Applying rule just copied all instructions\n");
   1391   1.1  christos 		print_gen_entry_insns (entry, warning, "Copied", NULL);
   1392  1.11  christos 		error (NULL, "unrecoverable\n");
   1393   1.1  christos 	      }
   1394   1.1  christos 	  }
   1395   1.1  christos       }
   1396   1.1  christos   }
   1397   1.1  christos 
   1398   1.1  christos   /* if some form of expanded table, fill in the missing dots */
   1399   1.1  christos   switch (table->opcode_rule->gen)
   1400   1.1  christos     {
   1401   1.1  christos     case padded_switch_gen:
   1402   1.1  christos     case array_gen:
   1403   1.1  christos     case goto_switch_gen:
   1404   1.1  christos       if (!table->opcode->is_boolean)
   1405   1.1  christos 	{
   1406   1.1  christos 	  gen_entry **entry = &table->entries;
   1407   1.1  christos 	  gen_entry *illegals = NULL;
   1408   1.1  christos 	  gen_entry **last_illegal = &illegals;
   1409   1.1  christos 	  int opcode_nr = 0;
   1410   1.1  christos 	  while (opcode_nr < table->opcode->nr_opcodes)
   1411   1.1  christos 	    {
   1412   1.1  christos 	      if ((*entry) == NULL || (*entry)->opcode_nr != opcode_nr)
   1413   1.1  christos 		{
   1414   1.1  christos 		  /* missing - insert it under our feet at *entry */
   1415   1.1  christos 		  gen_entry_insert_insn (table, table->top->isa->illegal_insn, table->opcode->word_nr, 0,	/* nr_prefetched_words == 0 for invalid */
   1416   1.1  christos 					 opcode_nr, NULL);
   1417   1.1  christos 		  ASSERT ((*entry) != NULL);
   1418   1.1  christos 		  ASSERT ((*entry)->opcode_nr == opcode_nr);
   1419   1.1  christos 		  (*last_illegal) = *entry;
   1420   1.1  christos 		  (*last_illegal)->combined_parent = illegals;
   1421   1.1  christos 		  last_illegal = &(*last_illegal)->combined_next;
   1422   1.1  christos 		}
   1423   1.1  christos 	      entry = &(*entry)->sibling;
   1424   1.1  christos 	      opcode_nr++;
   1425   1.1  christos 	    }
   1426   1.1  christos 	  /* oops, will have pointed the first illegal insn back to
   1427   1.1  christos 	     its self.  Fix this */
   1428   1.1  christos 	  if (illegals != NULL)
   1429   1.1  christos 	    illegals->combined_parent = NULL;
   1430   1.1  christos 	}
   1431   1.1  christos       break;
   1432   1.1  christos     case switch_gen:
   1433   1.1  christos     case invalid_gen:
   1434   1.1  christos       /* ignore */
   1435   1.1  christos       break;
   1436   1.1  christos     }
   1437   1.1  christos 
   1438   1.1  christos   /* and do the same for the newly created sub entries but *only*
   1439   1.1  christos      expand entries that haven't been combined. */
   1440   1.1  christos   {
   1441   1.1  christos     gen_entry *entry;
   1442   1.1  christos     for (entry = table->entries; entry != NULL; entry = entry->sibling)
   1443   1.1  christos       {
   1444   1.1  christos 	if (entry->combined_parent == NULL)
   1445   1.1  christos 	  {
   1446   1.1  christos 	    gen_entry_expand_insns (entry);
   1447   1.1  christos 	  }
   1448   1.1  christos       }
   1449   1.1  christos   }
   1450   1.1  christos }
   1451   1.1  christos 
   1452   1.1  christos void
   1453   1.1  christos gen_tables_expand_insns (gen_table *gen)
   1454   1.1  christos {
   1455   1.1  christos   gen_list *entry;
   1456   1.1  christos   for (entry = gen->tables; entry != NULL; entry = entry->next)
   1457   1.1  christos     {
   1458   1.1  christos       gen_entry_expand_insns (entry->table);
   1459   1.1  christos     }
   1460   1.1  christos }
   1461   1.1  christos 
   1462   1.1  christos 
   1463   1.1  christos /* create a list of all the semantic functions that need to be
   1464   1.1  christos    generated.  Eliminate any duplicates. Verify that the decode stage
   1465   1.1  christos    worked. */
   1466   1.1  christos 
   1467   1.1  christos static void
   1468  1.10  christos make_gen_semantics_list (lf *file, const gen_entry *entry, int depth, void *data)
   1469   1.1  christos {
   1470   1.1  christos   gen_table *gen = (gen_table *) data;
   1471   1.1  christos   insn_list *insn;
   1472   1.1  christos   /* Not interested in an entrie that have been combined into some
   1473   1.1  christos      other entry at the same level */
   1474   1.1  christos   if (entry->combined_parent != NULL)
   1475   1.1  christos     return;
   1476   1.1  christos 
   1477   1.1  christos   /* a leaf should contain exactly one instruction. If not the decode
   1478   1.1  christos      stage failed. */
   1479   1.1  christos   ASSERT (entry->nr_insns == 1);
   1480   1.1  christos 
   1481   1.1  christos   /* Enter this instruction into the list of semantic functions. */
   1482   1.1  christos   insn = insn_list_insert (&gen->semantics, &gen->nr_semantics,
   1483   1.1  christos 			   entry->insns->insn,
   1484   1.1  christos 			   entry->expanded_bits,
   1485   1.1  christos 			   entry->parent->opcode,
   1486   1.1  christos 			   entry->insns->nr_prefetched_words,
   1487   1.1  christos 			   merge_duplicate_insns);
   1488   1.1  christos   /* point the table entry at the real semantic function */
   1489   1.1  christos   ASSERT (insn != NULL);
   1490   1.1  christos   entry->insns->semantic = insn;
   1491   1.1  christos }
   1492   1.1  christos 
   1493   1.1  christos 
   1494   1.1  christos void
   1495   1.1  christos gen_tables_expand_semantics (gen_table *gen)
   1496   1.1  christos {
   1497   1.1  christos   gen_list *entry;
   1498   1.1  christos   for (entry = gen->tables; entry != NULL; entry = entry->next)
   1499   1.1  christos     {
   1500   1.1  christos       gen_entry_traverse_tree (NULL, entry->table, 1,	/* depth */
   1501   1.1  christos 			       NULL,	/* start-handler */
   1502   1.1  christos 			       make_gen_semantics_list,	/* leaf-handler */
   1503   1.1  christos 			       NULL,	/* end-handler */
   1504   1.1  christos 			       gen);	/* data */
   1505   1.1  christos     }
   1506   1.1  christos }
   1507   1.1  christos 
   1508   1.1  christos 
   1509   1.1  christos 
   1510   1.1  christos #ifdef MAIN
   1511   1.1  christos 
   1512   1.1  christos 
   1513   1.1  christos static void
   1514   1.1  christos dump_opcode_field (lf *file,
   1515   1.1  christos 		   char *prefix,
   1516   1.1  christos 		   opcode_field *field, char *suffix, int levels)
   1517   1.1  christos {
   1518  1.10  christos   lf_printf (file, "%s(opcode_field *) %p", prefix, field);
   1519   1.1  christos   if (levels && field != NULL)
   1520   1.1  christos     {
   1521   1.1  christos       lf_indent (file, +1);
   1522   1.1  christos       lf_printf (file, "\n(first %d)", field->first);
   1523   1.1  christos       lf_printf (file, "\n(last %d)", field->last);
   1524   1.1  christos       lf_printf (file, "\n(nr_opcodes %d)", field->nr_opcodes);
   1525   1.1  christos       lf_printf (file, "\n(is_boolean %d)", field->is_boolean);
   1526   1.1  christos       lf_printf (file, "\n(boolean_constant %d)", field->boolean_constant);
   1527   1.1  christos       dump_opcode_field (file, "\n(parent ", field->parent, ")", levels - 1);
   1528   1.1  christos       lf_indent (file, -1);
   1529   1.1  christos     }
   1530   1.1  christos   lf_printf (file, "%s", suffix);
   1531   1.1  christos }
   1532   1.1  christos 
   1533   1.1  christos 
   1534   1.1  christos static void
   1535   1.1  christos dump_opcode_bits (lf *file,
   1536   1.1  christos 		  char *prefix, opcode_bits *bits, char *suffix, int levels)
   1537   1.1  christos {
   1538  1.10  christos   lf_printf (file, "%s(opcode_bits *) %p", prefix, bits);
   1539   1.1  christos 
   1540   1.1  christos   if (levels && bits != NULL)
   1541   1.1  christos     {
   1542   1.1  christos       lf_indent (file, +1);
   1543   1.1  christos       lf_printf (file, "\n(value %d)", bits->value);
   1544   1.1  christos       dump_opcode_field (file, "\n(opcode ", bits->opcode, ")", 0);
   1545   1.1  christos       dump_insn_field (file, "\n(field ", bits->field, ")");
   1546   1.1  christos       dump_opcode_bits (file, "\n(next ", bits->next, ")", levels - 1);
   1547   1.1  christos       lf_indent (file, -1);
   1548   1.1  christos     }
   1549   1.1  christos   lf_printf (file, "%s", suffix);
   1550   1.1  christos }
   1551   1.1  christos 
   1552   1.1  christos 
   1553   1.1  christos 
   1554   1.1  christos static void
   1555   1.1  christos dump_insn_list (lf *file, char *prefix, insn_list *entry, char *suffix)
   1556   1.1  christos {
   1557  1.10  christos   lf_printf (file, "%s(insn_list *) %p", prefix, entry);
   1558   1.1  christos 
   1559   1.1  christos   if (entry != NULL)
   1560   1.1  christos     {
   1561   1.1  christos       lf_indent (file, +1);
   1562   1.1  christos       dump_insn_entry (file, "\n(insn ", entry->insn, ")");
   1563  1.10  christos       lf_printf (file, "\n(next %p)", entry->next);
   1564   1.1  christos       lf_indent (file, -1);
   1565   1.1  christos     }
   1566   1.1  christos   lf_printf (file, "%s", suffix);
   1567   1.1  christos }
   1568   1.1  christos 
   1569   1.1  christos 
   1570   1.1  christos static void
   1571   1.1  christos dump_insn_word_entry_list_entries (lf *file,
   1572   1.1  christos 				   char *prefix,
   1573   1.1  christos 				   insn_list *entry, char *suffix)
   1574   1.1  christos {
   1575   1.1  christos   lf_printf (file, "%s", prefix);
   1576   1.1  christos   while (entry != NULL)
   1577   1.1  christos     {
   1578   1.1  christos       dump_insn_list (file, "\n(", entry, ")");
   1579   1.1  christos       entry = entry->next;
   1580   1.1  christos     }
   1581   1.1  christos   lf_printf (file, "%s", suffix);
   1582   1.1  christos }
   1583   1.1  christos 
   1584   1.1  christos 
   1585   1.1  christos static void
   1586   1.1  christos dump_gen_entry (lf *file,
   1587   1.1  christos 		char *prefix, gen_entry *table, char *suffix, int levels)
   1588   1.1  christos {
   1589   1.1  christos 
   1590  1.10  christos   lf_printf (file, "%s(gen_entry *) %p", prefix, table);
   1591   1.1  christos 
   1592   1.1  christos   if (levels && table !=NULL)
   1593   1.1  christos     {
   1594   1.1  christos 
   1595   1.1  christos       lf_indent (file, +1);
   1596   1.1  christos       lf_printf (file, "\n(opcode_nr %d)", table->opcode_nr);
   1597   1.1  christos       lf_printf (file, "\n(word_nr %d)", table->word_nr);
   1598   1.1  christos       dump_opcode_bits (file, "\n(expanded_bits ", table->expanded_bits, ")",
   1599   1.1  christos 			-1);
   1600   1.1  christos       lf_printf (file, "\n(nr_insns %d)", table->nr_insns);
   1601   1.1  christos       dump_insn_word_entry_list_entries (file, "\n(insns ", table->insns,
   1602   1.1  christos 					 ")");
   1603   1.1  christos       dump_decode_rule (file, "\n(opcode_rule ", table->opcode_rule, ")");
   1604   1.1  christos       dump_opcode_field (file, "\n(opcode ", table->opcode, ")", 0);
   1605   1.1  christos       lf_printf (file, "\n(nr_entries %d)", table->nr_entries);
   1606   1.1  christos       dump_gen_entry (file, "\n(entries ", table->entries, ")",
   1607   1.1  christos 		      table->nr_entries);
   1608   1.1  christos       dump_gen_entry (file, "\n(sibling ", table->sibling, ")", levels - 1);
   1609   1.1  christos       dump_gen_entry (file, "\n(parent ", table->parent, ")", 0);
   1610   1.1  christos       lf_indent (file, -1);
   1611   1.1  christos     }
   1612   1.1  christos   lf_printf (file, "%s", suffix);
   1613   1.1  christos }
   1614   1.1  christos 
   1615   1.1  christos static void
   1616   1.1  christos dump_gen_list (lf *file,
   1617   1.1  christos 	       char *prefix, gen_list *entry, char *suffix, int levels)
   1618   1.1  christos {
   1619   1.1  christos   while (entry != NULL)
   1620   1.1  christos     {
   1621  1.10  christos       lf_printf (file, "%s(gen_list *) %p", prefix, entry);
   1622   1.1  christos       dump_gen_entry (file, "\n(", entry->table, ")", levels);
   1623  1.10  christos       lf_printf (file, "\n(next (gen_list *) %p)", entry->next);
   1624   1.1  christos       lf_printf (file, "%s", suffix);
   1625   1.1  christos     }
   1626   1.1  christos }
   1627   1.1  christos 
   1628   1.1  christos 
   1629   1.1  christos static void
   1630   1.1  christos dump_gen_table (lf *file,
   1631   1.1  christos 		char *prefix, gen_table *gen, char *suffix, int levels)
   1632   1.1  christos {
   1633  1.10  christos   lf_printf (file, "%s(gen_table *) %p", prefix, gen);
   1634  1.10  christos   lf_printf (file, "\n(isa (insn_table *) %p)", gen->isa);
   1635  1.10  christos   lf_printf (file, "\n(rules (decode_table *) %p)", gen->rules);
   1636   1.1  christos   dump_gen_list (file, "\n(", gen->tables, ")", levels);
   1637   1.1  christos   lf_printf (file, "%s", suffix);
   1638   1.1  christos }
   1639   1.1  christos 
   1640   1.1  christos 
   1641   1.1  christos igen_options options;
   1642   1.1  christos 
   1643   1.1  christos int
   1644   1.1  christos main (int argc, char **argv)
   1645   1.1  christos {
   1646   1.1  christos   decode_table *decode_rules;
   1647   1.1  christos   insn_table *instructions;
   1648   1.1  christos   gen_table *gen;
   1649   1.1  christos   lf *l;
   1650   1.1  christos 
   1651   1.1  christos   if (argc != 7)
   1652   1.1  christos     error (NULL,
   1653   1.1  christos 	   "Usage: insn <filter-in> <hi-bit-nr> <insn-bit-size> <widths> <decode-table> <insn-table>\n");
   1654   1.1  christos 
   1655  1.10  christos   INIT_OPTIONS ();
   1656   1.1  christos 
   1657   1.1  christos   filter_parse (&options.flags_filter, argv[1]);
   1658   1.1  christos 
   1659   1.1  christos   options.hi_bit_nr = a2i (argv[2]);
   1660   1.1  christos   options.insn_bit_size = a2i (argv[3]);
   1661   1.1  christos   options.insn_specifying_widths = a2i (argv[4]);
   1662   1.1  christos   ASSERT (options.hi_bit_nr < options.insn_bit_size);
   1663   1.1  christos 
   1664   1.1  christos   instructions = load_insn_table (argv[6], NULL);
   1665   1.1  christos   decode_rules = load_decode_table (argv[5]);
   1666   1.1  christos   gen = make_gen_tables (instructions, decode_rules);
   1667   1.1  christos 
   1668   1.1  christos   gen_tables_expand_insns (gen);
   1669   1.1  christos 
   1670   1.1  christos   l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn");
   1671   1.1  christos 
   1672   1.1  christos   dump_gen_table (l, "(", gen, ")\n", -1);
   1673   1.1  christos   return 0;
   1674   1.1  christos }
   1675   1.1  christos 
   1676   1.1  christos #endif
   1677