Automatic date update in version.in
[deliverable/binutils-gdb.git] / sim / igen / gen.c
index 927f16500adf780503a864153455eb6838ab6555..45ad181ac7a5461336e3750af2fcb2bf1150215b 100644 (file)
@@ -1,22 +1,23 @@
-/*  This file is part of the program psim.
+/* The IGEN simulator generator for GDB, the GNU Debugger.
 
-    Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
+   Copyright 2002-2019 Free Software Foundation, Inc.
 
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
+   Contributed by Andrew Cagney.
 
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-    */
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
 #include "misc.h"
 #include "gen.h"
 
 static insn_uint
-sub_val (insn_uint val,
-        insn_field_entry *field,
-        int first_pos,
-        int last_pos)
+sub_val (insn_uint val, int val_last_pos, int first_pos, int last_pos)
 {
-  return ((val >> (field->last - last_pos))
-         & (((insn_uint)1 << (last_pos - first_pos + 1)) - 1));
+  return ((val >> (val_last_pos - last_pos))
+         & (((insn_uint) 1 << (last_pos - first_pos + 1)) - 1));
 }
 
 static void
-update_depth (lf *file,
-             gen_entry *entry,
-             int depth,
-             void *data)
+update_depth (lf *file, gen_entry *entry, int depth, void *data)
 {
-  int *max_depth = (int*)data;
+  int *max_depth = (int *) data;
   if (*max_depth < depth)
     *max_depth = depth;
 }
@@ -55,26 +50,20 @@ int
 gen_entry_depth (gen_entry *table)
 {
   int depth = 0;
-  gen_entry_traverse_tree (NULL,
-                          table,
-                          1,
-                          NULL, /*start*/
-                          update_depth,
-                          NULL, /*end*/
-                          &depth); /* data */
+  gen_entry_traverse_tree (NULL, table, 1, NULL,       /*start */
+                          update_depth, NULL,  /*end */
+                          &depth);     /* data */
   return depth;
 }
 
 
 static void
-print_gen_entry_path (line_ref *line,
-                     gen_entry *table,
-                     error_func *print)
+print_gen_entry_path (line_ref *line, gen_entry *table, error_func *print)
 {
   if (table->parent == NULL)
     {
-      if (table->top->processor != NULL)
-       print (line, "%s", table->top->processor);
+      if (table->top->model != NULL)
+       print (line, "%s", table->top->model->name);
       else
        print (line, "");
     }
@@ -88,8 +77,7 @@ print_gen_entry_path (line_ref *line,
 static void
 print_gen_entry_insns (gen_entry *table,
                       error_func *print,
-                      char *first_message,
-                      char *next_message)
+                      char *first_message, char *next_message)
 {
   insn_list *i;
   char *message;
@@ -98,15 +86,87 @@ print_gen_entry_insns (gen_entry *table,
     {
       insn_entry *insn = i->insn;
       print_gen_entry_path (insn->line, table, print);
-      print (NULL, ": %s.%s %s\n",
-            insn->format_name,
-            insn->name,
-            message);
+      print (NULL, ": %s.%s %s\n", insn->format_name, insn->name, message);
       if (next_message != NULL)
        message = next_message;
     }
 }
 
+/* same as strcmp */
+static int
+insn_field_cmp (insn_word_entry *l, insn_word_entry *r)
+{
+  while (1)
+    {
+      int bit_nr;
+      if (l == NULL && r == NULL)
+       return 0;               /* all previous fields the same */
+      if (l == NULL)
+       return -1;              /* left shorter than right */
+      if (r == NULL)
+       return +1;              /* left longer than right */
+      for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++)
+       {
+         if (l->bit[bit_nr]->field->type != insn_field_string)
+           continue;
+         if (r->bit[bit_nr]->field->type != insn_field_string)
+           continue;
+         if (l->bit[bit_nr]->field->conditions == NULL)
+           continue;
+         if (r->bit[bit_nr]->field->conditions == NULL)
+           continue;
+         if (0)
+           printf ("%s%s%s VS %s%s%s\n",
+                   l->bit[bit_nr]->field->val_string,
+                   l->bit[bit_nr]->field->conditions->test ==
+                   insn_field_cond_eq ? "=" : "!",
+                   l->bit[bit_nr]->field->conditions->string,
+                   r->bit[bit_nr]->field->val_string,
+                   r->bit[bit_nr]->field->conditions->test ==
+                   insn_field_cond_eq ? "=" : "!",
+                   r->bit[bit_nr]->field->conditions->string);
+         if (l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq
+             && r->bit[bit_nr]->field->conditions->test ==
+             insn_field_cond_eq)
+           {
+             if (l->bit[bit_nr]->field->conditions->type ==
+                 insn_field_cond_field
+                 && r->bit[bit_nr]->field->conditions->type ==
+                 insn_field_cond_field)
+               /* somewhat arbitrary */
+               {
+                 int cmp = strcmp (l->bit[bit_nr]->field->conditions->string,
+                                   r->bit[bit_nr]->field->conditions->
+                                   string);
+                 if (cmp != 0)
+                   return cmp;
+                 else
+                   continue;
+               }
+             if (l->bit[bit_nr]->field->conditions->type ==
+                 insn_field_cond_field)
+               return +1;
+             if (r->bit[bit_nr]->field->conditions->type ==
+                 insn_field_cond_field)
+               return -1;
+             /* The case of both fields having constant values should have
+                already have been handled because such fields are converted
+                into normal constant fields, but we must not make this
+                an assert, as we wouldn't gracefully handle an (invalid)
+                duplicate insn description.  */
+             continue;
+           }
+         if (l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq)
+           return +1;          /* left = only */
+         if (r->bit[bit_nr]->field->conditions->test == insn_field_cond_eq)
+           return -1;          /* right = only */
+         /* FIXME: Need to some what arbitrarily order conditional lists */
+         continue;
+       }
+      l = l->next;
+      r = r->next;
+    }
+}
 
 /* same as strcmp */
 static int
@@ -116,14 +176,12 @@ insn_word_cmp (insn_word_entry *l, insn_word_entry *r)
     {
       int bit_nr;
       if (l == NULL && r == NULL)
-       return 0; /* all previous fields the same */
+       return 0;               /* all previous fields the same */
       if (l == NULL)
-       return -1; /* left shorter than right */
+       return -1;              /* left shorter than right */
       if (r == NULL)
-       return +1; /* left longer than right */
-      for (bit_nr = 0;
-          bit_nr < options.insn_bit_size;
-          bit_nr++)
+       return +1;              /* left longer than right */
+      for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++)
        {
          if (l->bit[bit_nr]->mask < r->bit[bit_nr]->mask)
            return -1;
@@ -139,31 +197,31 @@ insn_word_cmp (insn_word_entry *l, insn_word_entry *r)
     }
 }
 
+/* same as strcmp */
 static int
-opcode_bit_cmp (opcode_bits *l,
-               opcode_bits *r)
+opcode_bit_cmp (opcode_bits *l, opcode_bits *r)
 {
   if (l == NULL && r == NULL)
-    return 0; /* all previous bits the same */
+    return 0;                  /* all previous bits the same */
   if (l == NULL)
-    return -1; /* left shorter than right */
+    return -1;                 /* left shorter than right */
   if (r == NULL)
-    return +1; /* left longer than right */
+    return +1;                 /* left longer than right */
   /* most significant word */
   if (l->field->word_nr < r->field->word_nr)
-    return +1; /* left has more significant word */
+    return +1;                 /* left has more significant word */
   if (l->field->word_nr > r->field->word_nr)
-    return -1; /* right has more significant word */
+    return -1;                 /* right has more significant word */
   /* most significant bit? */
   if (l->first < r->first)
-    return +1; /* left as more significant bit */
+    return +1;                 /* left as more significant bit */
   if (l->first > r->first)
-    return -1; /* right as more significant bit */
+    return -1;                 /* right as more significant bit */
   /* nr bits? */
   if (l->last < r->last)
-    return +1; /* left as less bits */
+    return +1;                 /* left as less bits */
   if (l->last > r->last)
-    return -1; /* right as less bits */
+    return -1;                 /* right as less bits */
   /* value? */
   if (l->value < r->value)
     return -1;
@@ -172,15 +230,16 @@ opcode_bit_cmp (opcode_bits *l,
   return 0;
 }
 
+
+/* same as strcmp */
 static int
-opcode_bits_cmp (opcode_bits *l,
-                opcode_bits *r)
+opcode_bits_cmp (opcode_bits *l, opcode_bits *r)
 {
   while (1)
     {
       int cmp;
       if (l == NULL && r == NULL)
-       return 0; /* all previous bits the same */
+       return 0;               /* all previous bits the same */
       cmp = opcode_bit_cmp (l, r);
       if (cmp != 0)
        return cmp;
@@ -189,13 +248,12 @@ opcode_bits_cmp (opcode_bits *l,
     }
 }
 
+/* same as strcmp */
 static opcode_bits *
 new_opcode_bits (opcode_bits *old_bits,
                 int value,
                 int first,
-                int last,
-                insn_field_entry *field,
-                opcode_field *opcode)
+                int last, insn_field_entry *field, opcode_field *opcode)
 {
   opcode_bits *new_bits = ZALLOC (opcode_bits);
   new_bits->field = field;
@@ -203,7 +261,7 @@ new_opcode_bits (opcode_bits *old_bits,
   new_bits->first = first;
   new_bits->last = last;
   new_bits->opcode = opcode;
-  
+
   if (old_bits != NULL)
     {
       opcode_bits *new_list;
@@ -212,12 +270,11 @@ new_opcode_bits (opcode_bits *old_bits,
                                  old_bits->value,
                                  old_bits->first,
                                  old_bits->last,
-                                 old_bits->field,
-                                 old_bits->opcode);
+                                 old_bits->field, old_bits->opcode);
       while (*last != NULL)
        {
          int cmp = opcode_bit_cmp (new_bits, *last);
-         if (cmp < 0) /* new < new_list */
+         if (cmp < 0)          /* new < new_list */
            {
              break;
            }
@@ -237,80 +294,144 @@ new_opcode_bits (opcode_bits *old_bits,
     }
 }
 
+/* Same as strcmp().  */
+static int
+name_cmp (const char *l, const char *r)
+{
+  if (l == NULL && r == NULL)
+    return 0;
+  if (l != NULL && r == NULL)
+    return -1;
+  if (l == NULL && r != NULL)
+    return +1;
+  return strcmp (l, r);
+}
 
 
-
-typedef enum {
+typedef enum
+{
   merge_duplicate_insns,
   report_duplicate_insns,
-} duplicate_insn_actions;
+}
+duplicate_insn_actions;
 
 static insn_list *
 insn_list_insert (insn_list **cur_insn_ptr,
                  int *nr_insns,
-                 insn_entry *insn,
+                 insn_entry * insn,
                  opcode_bits *expanded_bits,
                  opcode_field *opcodes,
                  int nr_prefetched_words,
                  duplicate_insn_actions duplicate_action)
 {
   /* insert it according to the order of the fields & bits */
-  while ((*cur_insn_ptr) != NULL)
+  for (; (*cur_insn_ptr) != NULL; cur_insn_ptr = &(*cur_insn_ptr)->next)
     {
-      int word_cmp = insn_word_cmp (insn->words,
-                                   (*cur_insn_ptr)->insn->words);
-      if (word_cmp < 0)
+      int cmp;
+
+      /* key#1 sort according to the constant fields of each instruction */
+      cmp = insn_word_cmp (insn->words, (*cur_insn_ptr)->insn->words);
+      if (cmp < 0)
+       break;
+      else if (cmp > 0)
+       continue;
+
+      /* key#2 sort according to the expanded bits of each instruction */
+      cmp = opcode_bits_cmp (expanded_bits, (*cur_insn_ptr)->expanded_bits);
+      if (cmp < 0)
+       break;
+      else if (cmp > 0)
+       continue;
+
+      /* key#3 sort according to the non-constant fields of each instruction */
+      cmp = insn_field_cmp (insn->words, (*cur_insn_ptr)->insn->words);
+      if (cmp < 0)
+       break;
+      else if (cmp > 0)
+       continue;
+
+      if (duplicate_action == merge_duplicate_insns)
        {
-         /* found insertion point - new_insn < cur_insn->next */
-         break;
+         /* key#4: If we're going to merge duplicates, also sort
+            according to the format_name.  Two instructions with
+            identical decode patterns, but different names, are
+            considered different when merging.  Duplicates are only
+            important when creating a decode table (implied by
+            report_duplicate_insns) as such a table only has the
+            instruction's bit code as a way of differentiating
+            between instructions.  */
+         int cmp = name_cmp (insn->format_name,
+                             (*cur_insn_ptr)->insn->format_name);
+         if (cmp < 0)
+           break;
+         else if (cmp > 0)
+           continue;
        }
-      else if (word_cmp == 0)
+
+      if (duplicate_action == merge_duplicate_insns)
        {
-         /* words same, try for bit fields */
-         int bit_cmp = opcode_bits_cmp (expanded_bits,
-                                        (*cur_insn_ptr)->expanded_bits);
-         if (bit_cmp < 0)
+         /* key#5: If we're going to merge duplicates, also sort
+            according to the name.  See comment above for
+            format_name.  */
+         int cmp = name_cmp (insn->name, (*cur_insn_ptr)->insn->name);
+         if (cmp < 0)
+           break;
+         else if (cmp > 0)
+           continue;
+       }
+
+      /* duplicate keys, report problem */
+      switch (duplicate_action)
+       {
+       case report_duplicate_insns:
+         /* It would appear that we have two instructions with the
+            same constant field values across all words and bits.
+            This error can also occure when insn_field_cmp() is
+            failing to differentiate between two instructions that
+            differ only in their conditional fields. */
+         warning (insn->line,
+                  "Two instructions with identical constant fields\n");
+         error ((*cur_insn_ptr)->insn->line,
+                "Location of duplicate instruction\n");
+       case merge_duplicate_insns:
+         /* Add the opcode path to the instructions list */
+         if (options.trace.insn_insertion)
            {
-             /* found insertion point - new_insn < cur_insn->next */
-             break;
+             notify ((*cur_insn_ptr)->insn->line,
+                     "%s.%s: insert merge %s.%s\n",
+                     (*cur_insn_ptr)->insn->format_name,
+                     (*cur_insn_ptr)->insn->name,
+                     insn->format_name,
+                     insn->name);
            }
-         else if (bit_cmp == 0)
+         if (opcodes != NULL)
            {
-             switch (duplicate_action)
+             insn_opcodes **last = &(*cur_insn_ptr)->opcodes;
+             while (*last != NULL)
                {
-               case report_duplicate_insns:
-                 /* two instructions with the same constant field
-                    values across all words and bits */
-                 warning (insn->line,
-                          "Location of second (duplicated?) instruction");
-                 error ((*cur_insn_ptr)->insn->line,
-                        "Two instructions with identical constant fields\n");
-               case merge_duplicate_insns:
-                 /* Add the opcode path to the instructions list */
-                 if (opcodes != NULL)
-                   {
-                     insn_opcodes **last = &(*cur_insn_ptr)->opcodes;
-                     while (*last != NULL)
-                       {
-                         last = &(*last)->next;
-                       }
-                     (*last) = ZALLOC (insn_opcodes);
-                     (*last)->opcode = opcodes;
-                   }
-                 /* Use the larger nr_prefetched_words */
-                 if ((*cur_insn_ptr)->nr_prefetched_words < nr_prefetched_words)
-                   (*cur_insn_ptr)->nr_prefetched_words = nr_prefetched_words;
-                 return (*cur_insn_ptr);
+                 last = &(*last)->next;
                }
+             (*last) = ZALLOC (insn_opcodes);
+             (*last)->opcode = opcodes;
            }
+         /* Use the larger nr_prefetched_words */
+         if ((*cur_insn_ptr)->nr_prefetched_words < nr_prefetched_words)
+           (*cur_insn_ptr)->nr_prefetched_words = nr_prefetched_words;
+         return (*cur_insn_ptr);
        }
-      /* keep looking - new_insn > cur_insn->next */
-      cur_insn_ptr = &(*cur_insn_ptr)->next;
+
     }
-  
+
   /* create a new list entry and insert it */
   {
     insn_list *new_insn = ZALLOC (insn_list);
+    if (options.trace.insn_insertion)
+      {
+       notify (insn->line,
+               "%s.%s: insert new\n",
+               insn->format_name,
+               insn->name);
+      }
     new_insn->insn = insn;
     new_insn->expanded_bits = expanded_bits;
     new_insn->next = (*cur_insn_ptr);
@@ -322,7 +443,7 @@ insn_list_insert (insn_list **cur_insn_ptr,
       }
     (*cur_insn_ptr) = new_insn;
   }
-  
+
   *nr_insns += 1;
 
   return (*cur_insn_ptr);
@@ -333,27 +454,24 @@ extern void
 gen_entry_traverse_tree (lf *file,
                         gen_entry *table,
                         int depth,
-                        gen_entry_handler *start,
-                        gen_entry_handler *leaf,
-                        gen_entry_handler *end,
-                        void *data)
+                        gen_entry_handler * start,
+                        gen_entry_handler * leaf,
+                        gen_entry_handler * end, void *data)
 {
   gen_entry *entry;
-  
-  ASSERT (table != NULL);
+
+  ASSERT (table !=NULL);
   ASSERT (table->opcode != NULL);
   ASSERT (table->nr_entries > 0);
   ASSERT (table->entries != 0);
-  
+
   /* prefix */
   if (start != NULL && depth >= 0)
     {
       start (file, table, depth, data);
     }
   /* infix leaves */
-  for (entry = table->entries;
-       entry != NULL;
-       entry = entry->sibling)
+  for (entry = table->entries; entry != NULL; entry = entry->sibling)
     {
       if (entry->entries != NULL && depth != 0)
        {
@@ -380,28 +498,23 @@ gen_entry_traverse_tree (lf *file,
 /* create a list element containing a single gen_table entry */
 
 static gen_list *
-make_table (insn_table *isa,
-           decode_table *rules,
-           char *processor)
+make_table (insn_table *isa, decode_table *rules, model_entry *model)
 {
   insn_entry *insn;
   gen_list *entry = ZALLOC (gen_list);
   entry->table = ZALLOC (gen_entry);
   entry->table->top = entry;
-  entry->processor = processor;
+  entry->model = model;
   entry->isa = isa;
   for (insn = isa->insns; insn != NULL; insn = insn->next)
     {
-      if (processor == NULL
+      if (model == NULL
          || insn->processors == NULL
-         || filter_is_member (insn->processors, processor))
+         || filter_is_member (insn->processors, model->name))
        {
-         insn_list_insert (&entry->table->insns,
-                           &entry->table->nr_insns,
-                           insn,
-                           NULL, /* expanded_bits - none yet */
-                           NULL, /* opcodes - none yet */
-                           0, /* nr_prefetched_words - none yet */
+         insn_list_insert (&entry->table->insns, &entry->table->nr_insns, insn, NULL,  /* expanded_bits - none yet */
+                           NULL,       /* opcodes - none yet */
+                           0,  /* nr_prefetched_words - none yet */
                            report_duplicate_insns);
        }
     }
@@ -411,8 +524,7 @@ make_table (insn_table *isa,
 
 
 gen_table *
-make_gen_tables (insn_table *isa,
-                decode_table *rules)
+make_gen_tables (insn_table *isa, decode_table *rules)
 {
   gen_table *gen = ZALLOC (gen_table);
   gen->isa = isa;
@@ -420,18 +532,19 @@ make_gen_tables (insn_table *isa,
   if (options.gen.multi_sim)
     {
       gen_list **last = &gen->tables;
-      char *processor;
+      model_entry *model;
       filter *processors;
       if (options.model_filter != NULL)
        processors = options.model_filter;
       else
        processors = isa->model->processors;
-      for (processor = filter_next (processors, "");
-          processor != NULL;
-          processor = filter_next (processors, processor))
+      for (model = isa->model->models; model != NULL; model = model->next)
        {
-         *last = make_table (isa, rules, processor);
-         last = &(*last)->next;
+         if (filter_is_member (processors, model->name))
+           {
+             *last = make_table (isa, rules, model);
+             last = &(*last)->next;
+           }
        }
     }
   else
@@ -440,67 +553,30 @@ make_gen_tables (insn_table *isa,
     }
   return gen;
 }
-  
-  
-/****************************************************************/
-
-#if 0
-typedef enum {
-  field_is_not_constant = 0,
-  field_constant_int = 1,
-  field_constant_reserved = 2,
-  field_constant_string = 3
-} constant_field_types;
-
-static constant_field_types
-insn_field_is_constant (insn_field *field,
-                       decode_table *rule)
-{
-  switch (field->type)
-    {
-    case insn_field_int:
-      /* field is an integer */
-      return field_constant_int;
-    case insn_field_reserved:
-      /* field is `/' and treating that as a constant */
-      if (rule->with_zero_reserved)
-       return field_constant_reserved;
-      else
-       return field_is_not_constant;
-    case insn_field_wild:
-      return field_is_not_constant; /* never constant */
-    case insn_field_string:
-      /* field, though variable, is on the list of forced constants */
-      if (filter_is_member (rule->constant_field_names, field->val_string))
-       return field_constant_string;
-      else
-       return field_is_not_constant;
-    }
-  ERROR ("Internal error");
-  return field_is_not_constant;
-}
-#endif
 
 
 /****************************************************************/
 
-
 /* Is the bit, according to the decode rule, identical across all the
    instructions? */
 static int
-insns_bit_useless (insn_list *insns,
-                  decode_table *rule,
-                  int bit_nr)
+insns_bit_useless (insn_list *insns, decode_table *rule, int bit_nr)
 {
   insn_list *entry;
   int value = -1;
-  int is_useless = 1; /* cleared if something actually found */
+  int is_useless = 1;          /* cleared if something actually found */
+
+  /* check the instructions for some constant value in at least one of
+     the bit fields */
   for (entry = insns; entry != NULL; entry = entry->next)
     {
       insn_word_entry *word = entry->insn->word[rule->word_nr];
       insn_bit_entry *bit = word->bit[bit_nr];
       switch (bit->field->type)
        {
+       case insn_field_invalid:
+         ASSERT (0);
+         break;
        case insn_field_wild:
        case insn_field_reserved:
          /* neither useless or useful - ignore */
@@ -514,7 +590,9 @@ insns_bit_useless (insn_list *insns,
            case decode_find_constants:
            case decode_find_mixed:
              /* an integer is useful if its value isn't the same
-                 between all instructions? */
+                between all instructions.  The first time through the
+                value is saved, the second time through (if the
+                values differ) it is marked as useful. */
              if (value < 0)
                value = bit->value;
              else if (value != bit->value)
@@ -531,10 +609,22 @@ insns_bit_useless (insn_list *insns,
              break;
            case decode_find_constants:
            case decode_find_mixed:
-             /* a string field forced to constant */
              if (filter_is_member (rule->constant_field_names,
                                    bit->field->val_string))
+               /* a string field forced to constant? */
                is_useless = 0;
+             else if (bit->field->conditions != NULL
+                      && bit->field->conditions->test == insn_field_cond_eq
+                      && bit->field->conditions->type == insn_field_cond_value)
+               {
+                 int shift = bit->field->last - bit_nr;
+                 int bitvalue = (bit->field->conditions->value >> shift) & 1;
+
+                 if (value < 0)
+                   value = bitvalue;
+                 else if (value != bitvalue)
+                   is_useless = 0;
+               }
              else if (rule->search == decode_find_constants)
                /* the string field isn't constant */
                return 1;
@@ -542,6 +632,75 @@ insns_bit_useless (insn_list *insns,
            }
        }
     }
+
+  /* Given only one constant value has been found, check through all
+     the instructions to see if at least one conditional makes it
+     usefull */
+  if (value >= 0 && is_useless)
+    {
+      for (entry = insns; entry != NULL; entry = entry->next)
+       {
+         insn_word_entry *word = entry->insn->word[rule->word_nr];
+         insn_bit_entry *bit = word->bit[bit_nr];
+         switch (bit->field->type)
+           {
+           case insn_field_invalid:
+             ASSERT (0);
+             break;
+           case insn_field_wild:
+           case insn_field_reserved:
+           case insn_field_int:
+             /* already processed */
+             break;
+           case insn_field_string:
+             switch (rule->search)
+               {
+               case decode_find_strings:
+               case decode_find_constants:
+                 /* already processed */
+                 break;
+               case decode_find_mixed:
+                 /* string field with conditions.  If this condition
+                    eliminates the value then the compare is useful */
+                 if (bit->field->conditions != NULL)
+                   {
+                     insn_field_cond *condition;
+                     int shift = bit->field->last - bit_nr;
+                     for (condition = bit->field->conditions;
+                          condition != NULL; condition = condition->next)
+                       {
+                         switch (condition->type)
+                           {
+                           case insn_field_cond_value:
+                             switch (condition->test)
+                               {
+                               case insn_field_cond_ne:
+                                 if (((condition->value >> shift) & 1)
+                                     == (unsigned) value)
+                                   /* conditional field excludes the
+                                      current value */
+                                   is_useless = 0;
+                                 break;
+                               case insn_field_cond_eq:
+                                 if (((condition->value >> shift) & 1)
+                                     != (unsigned) value)
+                                   /* conditional field requires the
+                                      current value */
+                                   is_useless = 0;
+                                 break;
+                               }
+                             break;
+                           case insn_field_cond_field:
+                             /* are these handled separatly? */
+                             break;
+                           }
+                       }
+                   }
+               }
+           }
+       }
+    }
+
   return is_useless;
 }
 
@@ -551,8 +710,7 @@ insns_bit_useless (insn_list *insns,
 
 static opcode_field *
 gen_entry_find_opcode_field (insn_list *insns,
-                            decode_table *rule,
-                            int string_only)
+                            decode_table *rule, int string_only)
 {
   opcode_field curr_opcode;
   ASSERT (rule != NULL);
@@ -568,83 +726,18 @@ gen_entry_find_opcode_field (insn_list *insns,
   while (curr_opcode.first <= rule->last)
     {
       if (insns_bit_useless (insns, rule, curr_opcode.first))
-       curr_opcode.first ++;
+       curr_opcode.first++;
       else
        break;
     }
   while (curr_opcode.last >= rule->first)
     {
       if (insns_bit_useless (insns, rule, curr_opcode.last))
-       curr_opcode.last --;
+       curr_opcode.last--;
       else
        break;
     }
 
-
-#if 0
-  for (entry = insns; entry != NULL; entry = entry->next)
-    {
-      insn_word_entry *fields = entry->insn->word[rule->word_nr];
-      opcode_field new_opcode;
-      
-      ASSERT (fields != NULL);
-      
-      /* find a start point for the opcode field */
-      new_opcode.first = rule->first;
-      while (new_opcode.first <= rule->last
-            && (!string_only
-                || (insn_field_is_constant(fields->bit[new_opcode.first], rule)
-                    != field_constant_string))
-            && (string_only
-                || (insn_field_is_constant(fields->bit[new_opcode.first], rule)
-                    == field_is_not_constant)))
-       {
-         int new_first = fields->bit[new_opcode.first]->last + 1;
-         ASSERT (new_first > new_opcode.first);
-         new_opcode.first = new_first;
-       }
-      ASSERT(new_opcode.first > rule->last
-            || (string_only
-                && insn_field_is_constant(fields->bit[new_opcode.first],
-                                          rule) == field_constant_string)
-            || (!string_only
-                && insn_field_is_constant(fields->bit[new_opcode.first],
-                                          rule)));
-      
-      /* find the end point for the opcode field */
-      new_opcode.last = rule->last;
-      while (new_opcode.last >= rule->first
-            && (!string_only
-                || insn_field_is_constant(fields->bit[new_opcode.last],
-                                          rule) != field_constant_string)
-            && (string_only
-                || !insn_field_is_constant(fields->bit[new_opcode.last],
-                                           rule)))
-       {
-         int new_last = fields->bit[new_opcode.last]->first - 1;
-         ASSERT (new_last < new_opcode.last);
-         new_opcode.last = new_last;
-       }
-      ASSERT(new_opcode.last < rule->first
-            || (string_only
-                && insn_field_is_constant(fields->bit[new_opcode.last],
-                                          rule) == field_constant_string)
-            || (!string_only
-                && insn_field_is_constant(fields->bit[new_opcode.last],
-                                          rule)));
-      
-      /* now see if our current opcode needs expanding to include the
-        interesting fields within this instruction */
-      if (new_opcode.first <= rule->last
-         && curr_opcode.first > new_opcode.first)
-       curr_opcode.first = new_opcode.first;
-      if (new_opcode.last >= rule->first
-         && curr_opcode.last < new_opcode.last)
-       curr_opcode.last = new_opcode.last;
-      
-    }
-#endif
-
   /* did the final opcode field end up being empty? */
   if (curr_opcode.first > curr_opcode.last)
     {
@@ -656,21 +749,18 @@ gen_entry_find_opcode_field (insn_list *insns,
 
   /* Ensure that, for the non string only case, the opcode includes
      the range forced_first .. forced_last */
-  if (!string_only
-      && curr_opcode.first > rule->force_first)
+  if (!string_only && curr_opcode.first > rule->force_first)
     {
       curr_opcode.first = rule->force_first;
     }
-  if (!string_only
-      && curr_opcode.last < rule->force_last)
+  if (!string_only && curr_opcode.last < rule->force_last)
     {
       curr_opcode.last = rule->force_last;
     }
 
   /* For the string only case, force just the lower bound (so that the
      shift can be eliminated) */
-  if (string_only
-      && rule->force_last == options.insn_bit_size - 1)
+  if (string_only && rule->force_last == options.insn_bit_size - 1)
     {
       curr_opcode.last = options.insn_bit_size - 1;
     }
@@ -700,20 +790,19 @@ gen_entry_find_opcode_field (insn_list *insns,
 
 static void
 gen_entry_insert_insn (gen_entry *table,
-                      insn_entry *old_insn,
+                      insn_entry * old_insn,
                       int new_word_nr,
                       int new_nr_prefetched_words,
-                      int new_opcode_nr,
-                      opcode_bits *new_bits)
+                      int new_opcode_nr, opcode_bits *new_bits)
 {
   gen_entry **entry = &table->entries;
-  
+
   /* find the new table for this entry */
   while ((*entry) != NULL && (*entry)->opcode_nr < new_opcode_nr)
     {
       entry = &(*entry)->sibling;
     }
-  
+
   if ((*entry) == NULL || (*entry)->opcode_nr != new_opcode_nr)
     {
       /* insert the missing entry */
@@ -732,40 +821,43 @@ gen_entry_insert_insn (gen_entry *table,
     }
   /* ASSERT new_bits == cur_entry bits */
   ASSERT ((*entry) != NULL && (*entry)->opcode_nr == new_opcode_nr);
-  insn_list_insert (&(*entry)->insns,
-                   &(*entry)->nr_insns,
-                   old_insn,
-                   NULL, /* expanded_bits - only in final list */
-                   NULL, /* opcodes - only in final list */
-                   new_nr_prefetched_words, /* for this table */
+  insn_list_insert (&(*entry)->insns, &(*entry)->nr_insns, old_insn, NULL,     /* expanded_bits - only in final list */
+                   NULL,       /* opcodes - only in final list */
+                   new_nr_prefetched_words,    /* for this table */
                    report_duplicate_insns);
 }
 
 
 static void
 gen_entry_expand_opcode (gen_entry *table,
-                        insn_entry *instruction,
-                        int bit_nr,
-                        int opcode_nr,
-                        opcode_bits *bits)
+                        insn_entry * instruction,
+                        int bit_nr, int opcode_nr, opcode_bits *bits)
 {
   if (bit_nr > table->opcode->last)
     {
       /* Only include the hardwired bit information with an entry IF
          that entry (and hence its functions) are being duplicated.  */
+      if (options.trace.insn_expansion)
+       {
+         print_gen_entry_path (table->opcode_rule->line, table, notify);
+         notify (NULL, ": insert %d - %s.%s%s\n",
+                 opcode_nr,
+                 instruction->format_name,
+                 instruction->name,
+                 (table->opcode_rule->
+                  with_duplicates ? " (duplicated)" : ""));
+       }
       if (table->opcode_rule->with_duplicates)
        {
          gen_entry_insert_insn (table, instruction,
                                 table->opcode->word_nr,
-                                table->nr_prefetched_words,
-                                opcode_nr, bits);
+                                table->nr_prefetched_words, opcode_nr, bits);
        }
       else
        {
          gen_entry_insert_insn (table, instruction,
                                 table->opcode->word_nr,
-                                table->nr_prefetched_words,
-                                opcode_nr, NULL);
+                                table->nr_prefetched_words, opcode_nr, NULL);
        }
     }
   else
@@ -782,11 +874,10 @@ gen_entry_expand_opcode (gen_entry *table,
        case insn_field_int:
          {
            int val;
-           val = sub_val (field->val_int, field, first_pos, last_pos);
+           val = sub_val (field->val_int, field->last, first_pos, last_pos);
            gen_entry_expand_opcode (table, instruction,
                                     last_pos + 1,
-                                    ((opcode_nr << width) | val),
-                                    bits);
+                                    ((opcode_nr << width) | val), bits);
            break;
          }
        default:
@@ -794,48 +885,148 @@ gen_entry_expand_opcode (gen_entry *table,
            if (field->type == insn_field_reserved)
              gen_entry_expand_opcode (table, instruction,
                                       last_pos + 1,
-                                      ((opcode_nr << width)),
-                                      bits);
+                                      ((opcode_nr << width)), bits);
            else
              {
                int val;
-               int last_val = (table->opcode->is_boolean
-                               ? 2 : (1 << width));
+               int last_val = (table->opcode->is_boolean ? 2 : (1 << width));
                for (val = 0; val < last_val; val++)
                  {
-                   /* check to see if the value has been limited */
-                   insn_field_exclusion *exclusion;
-                   for (exclusion = field->exclusions;
-                        exclusion != NULL;
-                        exclusion = exclusion->next)
+                   /* check to see if the value has been precluded
+                      (by a conditional) in some way */
+                   int is_precluded;
+                   insn_field_cond *condition;
+                   for (condition = field->conditions, is_precluded = 0;
+                        condition != NULL && !is_precluded;
+                        condition = condition->next)
                      {
-                       int value = sub_val (exclusion->value, field,
-                                            first_pos, last_pos);
-                       if (value == val)
-                         break;
+                       switch (condition->type)
+                         {
+                         case insn_field_cond_value:
+                           {
+                             int value =
+                               sub_val (condition->value, field->last,
+                                        first_pos, last_pos);
+                             switch (condition->test)
+                               {
+                               case insn_field_cond_ne:
+                                 if (value == val)
+                                   is_precluded = 1;
+                                 break;
+                               case insn_field_cond_eq:
+                                 if (value != val)
+                                   is_precluded = 1;
+                                 break;
+                               }
+                             break;
+                           }
+                         case insn_field_cond_field:
+                           {
+                             int value = -1;
+                             opcode_bits *bit;
+                             gen_entry *t = NULL;
+                             /* Try to find a value for the
+                                conditional by looking back through
+                                the previously defined bits for one
+                                that covers the designated
+                                conditional field */
+                             for (bit = bits; bit != NULL; bit = bit->next)
+                               {
+                                 if (bit->field->word_nr ==
+                                     condition->field->word_nr
+                                     && bit->first <= condition->field->first
+                                     && bit->last >= condition->field->last)
+                                   {
+                                     /* the bit field fully specified
+                                        the conditional field's value */
+                                     value = sub_val (bit->value, bit->last,
+                                                      condition->field->
+                                                      first,
+                                                      condition->field->
+                                                      last);
+                                   }
+                               }
+                             /* Try to find a value by looking
+                                through this and previous tables */
+                             if (bit == NULL)
+                               {
+                                 for (t = table;
+                                      t->parent != NULL; t = t->parent)
+                                   {
+                                     if (t->parent->opcode->word_nr ==
+                                         condition->field->word_nr
+                                         && t->parent->opcode->first <=
+                                         condition->field->first
+                                         && t->parent->opcode->last >=
+                                         condition->field->last)
+                                       {
+                                         /* the table entry fully
+                                            specified the condition
+                                            field's value */
+                                         /* extract the field's value
+                                            from the opcode */
+                                         value =
+                                           sub_val (t->opcode_nr,
+                                                    t->parent->opcode->last,
+                                                    condition->field->first,
+                                                    condition->field->last);
+                                         /* this is a requirement of
+                                            a conditonal field
+                                            refering to another field */
+                                         ASSERT ((condition->field->first -
+                                                  condition->field->last) ==
+                                                 (first_pos - last_pos));
+                                         printf
+                                           ("value=%d, opcode_nr=%d, last=%d, [%d..%d]\n",
+                                            value, t->opcode_nr,
+                                            t->parent->opcode->last,
+                                            condition->field->first,
+                                            condition->field->last);
+                                       }
+                                   }
+                               }
+                             if (bit == NULL && t == NULL)
+                               error (instruction->line,
+                                      "Conditional `%s' of field `%s' isn't expanded",
+                                      condition->string, field->val_string);
+                             switch (condition->test)
+                               {
+                               case insn_field_cond_ne:
+                                 if (value == val)
+                                   is_precluded = 1;
+                                 break;
+                               case insn_field_cond_eq:
+                                 if (value != val)
+                                   is_precluded = 1;
+                                 break;
+                               }
+                             break;
+                           }
+                         }
                      }
-                   if (exclusion == NULL)
+                   if (!is_precluded)
                      {
                        /* Only add additional hardwired bit
-                           information if the entry is not going to
-                           later be combined */
+                          information if the entry is not going to
+                          later be combined */
                        if (table->opcode_rule->with_combine)
                          {
                            gen_entry_expand_opcode (table, instruction,
                                                     last_pos + 1,
-                                                    ((opcode_nr << width) | val),
-                                                    bits);
+                                                    ((opcode_nr << width) |
+                                                     val), bits);
                          }
                        else
                          {
-                           opcode_bits *new_bits = new_opcode_bits (bits, val,
-                                                                    first_pos, last_pos,
-                                                                    field,
-                                                                    table->opcode);
+                           opcode_bits *new_bits =
+                             new_opcode_bits (bits, val,
+                                              first_pos, last_pos,
+                                              field,
+                                              table->opcode);
                            gen_entry_expand_opcode (table, instruction,
                                                     last_pos + 1,
-                                                    ((opcode_nr << width) | val),
-                                                    new_bits);
+                                                    ((opcode_nr << width) |
+                                                     val), new_bits);
                          }
                      }
                  }
@@ -846,28 +1037,24 @@ gen_entry_expand_opcode (gen_entry *table,
 }
 
 static void
-gen_entry_insert_expanding (gen_entry *table,
-                           insn_entry *instruction)
+gen_entry_insert_expanding (gen_entry *table, insn_entry * instruction)
 {
   gen_entry_expand_opcode (table,
                           instruction,
-                          table->opcode->first,
-                          0,
-                          table->expanded_bits);
+                          table->opcode->first, 0, table->expanded_bits);
 }
 
 
 static int
-insns_match_format_names (insn_list *insns,
-                         filter *format_names)
+insns_match_format_names (insn_list *insns, filter *format_names)
 {
   if (format_names != NULL)
     {
       insn_list *i;
       for (i = insns; i != NULL; i = i->next)
        {
-         if ( i->insn->format_name != NULL
-              && !filter_is_member (format_names, i->insn->format_name))
+         if (i->insn->format_name != NULL
+             && !filter_is_member (format_names, i->insn->format_name))
            return 0;
        }
     }
@@ -875,8 +1062,7 @@ insns_match_format_names (insn_list *insns,
 }
 
 static int
-table_matches_path (gen_entry *table,
-                   decode_path_list *paths)
+table_matches_path (gen_entry *table, decode_path_list *paths)
 {
   if (paths == NULL)
     return 1;
@@ -902,8 +1088,7 @@ table_matches_path (gen_entry *table,
 
 
 static int
-insns_match_conditions (insn_list *insns,
-                       decode_cond *conditions)
+insns_match_conditions (insn_list *insns, decode_cond *conditions)
 {
   if (conditions != NULL)
     {
@@ -923,8 +1108,7 @@ insns_match_conditions (insn_list *insns,
                  if (!i->insn->word[cond->word_nr]->bit[bit_nr]->mask)
                    return 0;
                  if ((i->insn->word[cond->word_nr]->bit[bit_nr]->value
-                      == cond->value[bit_nr])
-                     == !cond->is_equal)
+                      == cond->value[bit_nr]) == !cond->is_equal)
                    return 0;
                }
            }
@@ -934,8 +1118,7 @@ insns_match_conditions (insn_list *insns,
 }
 
 static int
-insns_match_nr_words (insn_list *insns,
-                     int nr_words)
+insns_match_nr_words (insn_list *insns, int nr_words)
 {
   insn_list *i;
   for (i = insns; i != NULL; i = i->next)
@@ -947,8 +1130,7 @@ insns_match_nr_words (insn_list *insns,
 }
 
 static int
-insn_list_cmp (insn_list *l,
-              insn_list *r)
+insn_list_cmp (insn_list *l, insn_list *r)
 {
   while (1)
     {
@@ -960,7 +1142,7 @@ insn_list_cmp (insn_list *l,
       if (r == NULL)
        return 1;
       if (l->insn != r->insn)
-       return -1; /* somewhat arbitrary at present */
+       return -1;              /* somewhat arbitrary at present */
       /* skip this insn */
       insn = l->insn;
       while (l != NULL && l->insn == insn)
@@ -977,18 +1159,17 @@ gen_entry_expand_insns (gen_entry *table)
 {
   decode_table *opcode_rule;
 
-  ASSERT(table->nr_insns >= 1);
-  
+  ASSERT (table->nr_insns >= 1);
+
   /* determine a valid opcode */
   for (opcode_rule = table->opcode_rule;
-       opcode_rule != NULL;
-       opcode_rule = opcode_rule->next)
+       opcode_rule != NULL; opcode_rule = opcode_rule->next)
     {
       char *discard_reason;
-      if (table->top->processor != NULL
+      if (table->top->model != NULL
          && opcode_rule->model_names != NULL
          && !filter_is_member (opcode_rule->model_names,
-                               table->top->processor))
+                               table->top->model->name))
        {
          /* the rule isn't applicable to this processor */
          discard_reason = "wrong model";
@@ -996,17 +1177,19 @@ gen_entry_expand_insns (gen_entry *table)
       else if (table->nr_insns == 1 && opcode_rule->conditions == NULL)
        {
          /* for safety, require a pre-codition when attempting to
-             apply a rule to a single instruction */
+            apply a rule to a single instruction */
          discard_reason = "need pre-condition when nr-insn == 1";
        }
       else if (table->nr_insns == 1 && !opcode_rule->with_duplicates)
        {
          /* Little point in expanding a single instruction when we're
-             not duplicating the semantic functions that this table
-             calls */
+            not duplicating the semantic functions that this table
+            calls */
          discard_reason = "need duplication with nr-insns == 1";
        }
-      else if (!insns_match_format_names (table->insns, opcode_rule->format_names))
+      else
+       if (!insns_match_format_names
+           (table->insns, opcode_rule->format_names))
        {
          discard_reason = "wrong format name";
        }
@@ -1018,18 +1201,18 @@ gen_entry_expand_insns (gen_entry *table)
        {
          discard_reason = "path failed";
        }
-      else if (!insns_match_conditions (table->insns, opcode_rule->conditions))
+      else
+       if (!insns_match_conditions (table->insns, opcode_rule->conditions))
        {
          discard_reason = "condition failed";
        }
       else
        {
          discard_reason = "no opcode field";
-         table->opcode =
-           gen_entry_find_opcode_field (table->insns,
-                                        opcode_rule,
-                                        table->nr_insns == 1/*string-only*/
-                                        );
+         table->opcode = gen_entry_find_opcode_field (table->insns,
+                                                      opcode_rule,
+                                                      table->nr_insns == 1     /*string-only */
+           );
          if (table->opcode != NULL)
            {
              table->opcode_rule = opcode_rule;
@@ -1043,7 +1226,7 @@ gen_entry_expand_insns (gen_entry *table)
          notify (NULL, ": rule discarded - %s\n", discard_reason);
        }
     }
-  
+
   /* did we find anything */
   if (opcode_rule == NULL)
     {
@@ -1063,7 +1246,8 @@ gen_entry_expand_insns (gen_entry *table)
      this table to function */
   if (table->parent == NULL)
     table->nr_prefetched_words = table->opcode_rule->word_nr + 1;
-  else if (table->opcode_rule->word_nr + 1 > table->parent->nr_prefetched_words)
+  else if (table->opcode_rule->word_nr + 1 >
+          table->parent->nr_prefetched_words)
     table->nr_prefetched_words = table->opcode_rule->word_nr + 1;
   else
     table->nr_prefetched_words = table->parent->nr_prefetched_words;
@@ -1071,19 +1255,11 @@ gen_entry_expand_insns (gen_entry *table)
   /* back link what we found to its parent */
   if (table->parent != NULL)
     {
-      ASSERT(table->parent->opcode != NULL);
+      ASSERT (table->parent->opcode != NULL);
       table->opcode->parent = table->parent->opcode;
     }
 
-  /* expand the raw instructions according to the opcode */
-  {
-    insn_list *entry;
-    for (entry = table->insns; entry != NULL; entry = entry->next)
-      {
-       gen_entry_insert_expanding (table, entry->insn);
-      }
-  }
-
+  /* report the rule being used to expand the instructions */
   if (options.trace.rule_selection)
     {
       print_gen_entry_path (table->opcode_rule->line, table, notify);
@@ -1094,10 +1270,24 @@ gen_entry_expand_insns (gen_entry *table)
              i2target (options.hi_bit_nr, table->opcode->last),
              i2target (options.hi_bit_nr, table->opcode_rule->first),
              i2target (options.hi_bit_nr, table->opcode_rule->last),
-             table->opcode->nr_opcodes,
-             table->nr_entries);
+             table->opcode->nr_opcodes, table->nr_entries);
     }
 
+  /* expand the raw instructions according to the opcode */
+  {
+    insn_list *entry;
+    for (entry = table->insns; entry != NULL; entry = entry->next)
+      {
+       if (options.trace.insn_expansion)
+         {
+           print_gen_entry_path (table->opcode_rule->line, table, notify);
+           notify (NULL, ": expand - %s.%s\n",
+                   entry->insn->format_name, entry->insn->name);
+         }
+       gen_entry_insert_expanding (table, entry->insn);
+      }
+  }
+
   /* dump the results */
   if (options.trace.entries)
     {
@@ -1107,14 +1297,13 @@ gen_entry_expand_insns (gen_entry *table)
          insn_list *l;
          print_gen_entry_path (table->opcode_rule->line, entry, notify);
          notify (NULL, ": %d - entries %d -",
-                 entry->opcode_nr,
-                 entry->nr_insns);
+                 entry->opcode_nr, entry->nr_insns);
          for (l = entry->insns; l != NULL; l = l->next)
            notify (NULL, " %s.%s", l->insn->format_name, l->insn->name);
          notify (NULL, "\n");
        }
     }
-       
+
   /* perform a combine pass if needed */
   if (table->opcode_rule->with_combine)
     {
@@ -1148,9 +1337,9 @@ gen_entry_expand_insns (gen_entry *table)
                  insn_list *l;
                  gen_entry *duplicate;
                  nr_unique++;
-                 print_gen_entry_path (table->opcode_rule->line, entry, notify);
-                 for (duplicate = entry->combined_next;
-                      duplicate != NULL;
+                 print_gen_entry_path (table->opcode_rule->line, entry,
+                                       notify);
+                 for (duplicate = entry->combined_next; duplicate != NULL;
                       duplicate = duplicate->combined_next)
                    {
                      notify (NULL, "+%d", duplicate->opcode_nr);
@@ -1159,42 +1348,42 @@ gen_entry_expand_insns (gen_entry *table)
                  for (l = entry->insns; l != NULL; l = l->next)
                    {
                      notify (NULL, " %s.%s",
-                             l->insn->format_name,
-                             l->insn->name);
+                             l->insn->format_name, l->insn->name);
                    }
                  notify (NULL, "\n");
                }
            }
          print_gen_entry_path (table->opcode_rule->line, table, notify);
-         notify (NULL, ": combine - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d, unique %d\n",
-                 table->opcode->word_nr,
-                 i2target (options.hi_bit_nr, table->opcode->first),
+         notify (NULL,
+                 ": combine - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d, unique %d\n",
+                 table->opcode->word_nr, i2target (options.hi_bit_nr,
+                                                   table->opcode->first),
                  i2target (options.hi_bit_nr, table->opcode->last),
                  i2target (options.hi_bit_nr, table->opcode_rule->first),
                  i2target (options.hi_bit_nr, table->opcode_rule->last),
-                 table->opcode->nr_opcodes,
-                 table->nr_entries,
-                 nr_unique);
+                 table->opcode->nr_opcodes, table->nr_entries, nr_unique);
        }
     }
-       
+
   /* Check that the rule did more than re-arange the order of the
      instructions */
   {
-      gen_entry *entry;
-      for (entry = table->entries; entry != NULL; entry = entry->sibling)
-       {
-         if (entry->combined_parent == NULL)
-           {
-             if (insn_list_cmp (table->insns, entry->insns) == 0)
-               {
-                 print_gen_entry_path (table->opcode_rule->line, table, warning);
-                 warning (NULL, ": Applying rule just copied all instructions\n");
-                 print_gen_entry_insns (entry, warning, "Copied", NULL);
-                 error (NULL, "");
-               }
-           }
-       }    
+    gen_entry *entry;
+    for (entry = table->entries; entry != NULL; entry = entry->sibling)
+      {
+       if (entry->combined_parent == NULL)
+         {
+           if (insn_list_cmp (table->insns, entry->insns) == 0)
+             {
+               print_gen_entry_path (table->opcode_rule->line, table,
+                                     warning);
+               warning (NULL,
+                        ": Applying rule just copied all instructions\n");
+               print_gen_entry_insns (entry, warning, "Copied", NULL);
+               error (NULL, "");
+             }
+         }
+      }
   }
 
   /* if some form of expanded table, fill in the missing dots */
@@ -1214,10 +1403,7 @@ gen_entry_expand_insns (gen_entry *table)
              if ((*entry) == NULL || (*entry)->opcode_nr != opcode_nr)
                {
                  /* missing - insert it under our feet at *entry */
-                 gen_entry_insert_insn (table,
-                                        table->top->isa->illegal_insn,
-                                        table->opcode->word_nr,
-                                        0, /* nr_prefetched_words == 0 for invalid */
+                 gen_entry_insert_insn (table, table->top->isa->illegal_insn, table->opcode->word_nr, 0,       /* nr_prefetched_words == 0 for invalid */
                                         opcode_nr, NULL);
                  ASSERT ((*entry) != NULL);
                  ASSERT ((*entry)->opcode_nr == opcode_nr);
@@ -1229,7 +1415,7 @@ gen_entry_expand_insns (gen_entry *table)
              opcode_nr++;
            }
          /* oops, will have pointed the first illegal insn back to
-             its self.  Fix this */
+            its self.  Fix this */
          if (illegals != NULL)
            illegals->combined_parent = NULL;
        }
@@ -1244,7 +1430,7 @@ gen_entry_expand_insns (gen_entry *table)
      expand entries that haven't been combined. */
   {
     gen_entry *entry;
-    for (entry = table->entries; entry != NULL; entry =  entry->sibling)
+    for (entry = table->entries; entry != NULL; entry = entry->sibling)
       {
        if (entry->combined_parent == NULL)
          {
@@ -1270,12 +1456,9 @@ gen_tables_expand_insns (gen_table *gen)
    worked. */
 
 static void
-make_gen_semantics_list (lf *file,
-                        gen_entry *entry,
-                        int depth,
-                        void *data)
+make_gen_semantics_list (lf *file, gen_entry *entry, int depth, void *data)
 {
-  gen_table *gen = (gen_table*) data;
+  gen_table *gen = (gen_table *) data;
   insn_list *insn;
   /* Not interested in an entrie that have been combined into some
      other entry at the same level */
@@ -1305,14 +1488,12 @@ gen_tables_expand_semantics (gen_table *gen)
   gen_list *entry;
   for (entry = gen->tables; entry != NULL; entry = entry->next)
     {
-      gen_entry_traverse_tree (NULL,
-                              entry->table,
-                              1, /* depth */
-                              NULL, /* start-handler */
-                              make_gen_semantics_list, /* leaf-handler */
-                              NULL, /* end-handler */
-                              gen); /* data */
-  }
+      gen_entry_traverse_tree (NULL, entry->table, 1,  /* depth */
+                              NULL,    /* start-handler */
+                              make_gen_semantics_list, /* leaf-handler */
+                              NULL,    /* end-handler */
+                              gen);    /* data */
+    }
 }
 
 
@@ -1323,34 +1504,30 @@ gen_tables_expand_semantics (gen_table *gen)
 static void
 dump_opcode_field (lf *file,
                   char *prefix,
-                  opcode_field *field,
-                  char *suffix,
-                  int levels)
+                  opcode_field *field, char *suffix, int levels)
 {
   lf_printf (file, "%s(opcode_field *) 0x%lx", prefix, (long) field);
-  if (levels && field != NULL) {
-    lf_indent (file, +1);
-    lf_printf (file, "\n(first %d)", field->first);
-    lf_printf (file, "\n(last %d)", field->last);
-    lf_printf (file, "\n(nr_opcodes %d)", field->nr_opcodes);
-    lf_printf (file, "\n(is_boolean %d)", field->is_boolean);
-    lf_printf (file, "\n(boolean_constant %d)", field->boolean_constant);
-    dump_opcode_field(file, "\n(parent ", field->parent, ")", levels - 1);
-    lf_indent (file, -1);
-  }
+  if (levels && field != NULL)
+    {
+      lf_indent (file, +1);
+      lf_printf (file, "\n(first %d)", field->first);
+      lf_printf (file, "\n(last %d)", field->last);
+      lf_printf (file, "\n(nr_opcodes %d)", field->nr_opcodes);
+      lf_printf (file, "\n(is_boolean %d)", field->is_boolean);
+      lf_printf (file, "\n(boolean_constant %d)", field->boolean_constant);
+      dump_opcode_field (file, "\n(parent ", field->parent, ")", levels - 1);
+      lf_indent (file, -1);
+    }
   lf_printf (file, "%s", suffix);
 }
 
 
 static void
 dump_opcode_bits (lf *file,
-                 char *prefix,
-                 opcode_bits *bits,
-                 char *suffix,
-                 int levels)
+                 char *prefix, opcode_bits *bits, char *suffix, int levels)
 {
   lf_printf (file, "%s(opcode_bits *) 0x%lx", prefix, (long) bits);
-  
+
   if (levels && bits != NULL)
     {
       lf_indent (file, +1);
@@ -1366,28 +1543,25 @@ dump_opcode_bits (lf *file,
 
 
 static void
-dump_insn_list (lf *file,
-               char *prefix,
-               insn_list *entry,
-               char *suffix)
+dump_insn_list (lf *file, char *prefix, insn_list *entry, char *suffix)
 {
   lf_printf (file, "%s(insn_list *) 0x%lx", prefix, (long) entry);
 
-  if (entry != NULL) {
-    lf_indent (file, +1);
-    dump_insn_entry (file, "\n(insn ", entry->insn, ")");
-    lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
-    lf_indent (file, -1);
-  }
+  if (entry != NULL)
+    {
+      lf_indent (file, +1);
+      dump_insn_entry (file, "\n(insn ", entry->insn, ")");
+      lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
+      lf_indent (file, -1);
+    }
   lf_printf (file, "%s", suffix);
 }
 
 
 static void
 dump_insn_word_entry_list_entries (lf *file,
-                              char *prefix,
-                              insn_list *entry,
-                              char *suffix)
+                                  char *prefix,
+                                  insn_list *entry, char *suffix)
 {
   lf_printf (file, "%s", prefix);
   while (entry != NULL)
@@ -1401,39 +1575,37 @@ dump_insn_word_entry_list_entries (lf *file,
 
 static void
 dump_gen_entry (lf *file,
-               char *prefix,
-               gen_entry *table,
-               char *suffix,
-               int levels)
+               char *prefix, gen_entry *table, char *suffix, int levels)
 {
 
   lf_printf (file, "%s(gen_entry *) 0x%lx", prefix, (long) table);
 
-  if (levels && table != NULL) {
-
-    lf_indent (file, +1);
-    lf_printf (file, "\n(opcode_nr %d)", table->opcode_nr);
-    lf_printf (file, "\n(word_nr %d)", table->word_nr);
-    dump_opcode_bits (file, "\n(expanded_bits ", table->expanded_bits, ")", -1);
-    lf_printf (file, "\n(nr_insns %d)", table->nr_insns);
-    dump_insn_word_entry_list_entries (file, "\n(insns ", table->insns, ")");
-    dump_decode_rule (file, "\n(opcode_rule ", table->opcode_rule, ")");
-    dump_opcode_field (file, "\n(opcode ", table->opcode, ")", 0);
-    lf_printf (file, "\n(nr_entries %d)", table->nr_entries);
-    dump_gen_entry (file, "\n(entries ", table->entries, ")", table->nr_entries);
-    dump_gen_entry (file, "\n(sibling ", table->sibling, ")", levels - 1);
-    dump_gen_entry (file, "\n(parent ", table->parent, ")", 0);
-    lf_indent (file, -1);
-  }
+  if (levels && table !=NULL)
+    {
+
+      lf_indent (file, +1);
+      lf_printf (file, "\n(opcode_nr %d)", table->opcode_nr);
+      lf_printf (file, "\n(word_nr %d)", table->word_nr);
+      dump_opcode_bits (file, "\n(expanded_bits ", table->expanded_bits, ")",
+                       -1);
+      lf_printf (file, "\n(nr_insns %d)", table->nr_insns);
+      dump_insn_word_entry_list_entries (file, "\n(insns ", table->insns,
+                                        ")");
+      dump_decode_rule (file, "\n(opcode_rule ", table->opcode_rule, ")");
+      dump_opcode_field (file, "\n(opcode ", table->opcode, ")", 0);
+      lf_printf (file, "\n(nr_entries %d)", table->nr_entries);
+      dump_gen_entry (file, "\n(entries ", table->entries, ")",
+                     table->nr_entries);
+      dump_gen_entry (file, "\n(sibling ", table->sibling, ")", levels - 1);
+      dump_gen_entry (file, "\n(parent ", table->parent, ")", 0);
+      lf_indent (file, -1);
+    }
   lf_printf (file, "%s", suffix);
 }
 
 static void
 dump_gen_list (lf *file,
-              char *prefix,
-              gen_list *entry,
-              char *suffix,
-              int levels)
+              char *prefix, gen_list *entry, char *suffix, int levels)
 {
   while (entry != NULL)
     {
@@ -1447,10 +1619,7 @@ dump_gen_list (lf *file,
 
 static void
 dump_gen_table (lf *file,
-               char *prefix,
-               gen_table *gen,
-               char *suffix,
-               int levels)
+               char *prefix, gen_table *gen, char *suffix, int levels)
 {
   lf_printf (file, "%s(gen_table *) 0x%lx", prefix, (long) gen);
   lf_printf (file, "\n(isa (insn_table *) 0x%lx)", (long) gen->isa);
@@ -1463,8 +1632,7 @@ dump_gen_table (lf *file,
 igen_options options;
 
 int
-main (int argc,
-      char **argv)
+main (int argc, char **argv)
 {
   decode_table *decode_rules;
   insn_table *instructions;
@@ -1472,16 +1640,17 @@ main (int argc,
   lf *l;
 
   if (argc != 7)
-    error (NULL, "Usage: insn <filter-in> <hi-bit-nr> <insn-bit-size> <widths> <decode-table> <insn-table>\n");
+    error (NULL,
+          "Usage: insn <filter-in> <hi-bit-nr> <insn-bit-size> <widths> <decode-table> <insn-table>\n");
 
   INIT_OPTIONS (options);
 
   filter_parse (&options.flags_filter, argv[1]);
 
-  options.hi_bit_nr = a2i(argv[2]);
-  options.insn_bit_size = a2i(argv[3]);
-  options.insn_specifying_widths = a2i(argv[4]);
-  ASSERT(options.hi_bit_nr < options.insn_bit_size);
+  options.hi_bit_nr = a2i (argv[2]);
+  options.insn_bit_size = a2i (argv[3]);
+  options.insn_specifying_widths = a2i (argv[4]);
+  ASSERT (options.hi_bit_nr < options.insn_bit_size);
 
   instructions = load_insn_table (argv[6], NULL);
   decode_rules = load_decode_table (argv[5]);
This page took 0.04485 seconds and 4 git commands to generate.