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