Correct handling of constant fields.
[deliverable/binutils-gdb.git] / sim / igen / gen.c
index 76bf00d04084ced84206c848eb03c4462049db5e..9b7671172079353c5757164f35f1efeda80f8a4d 100644 (file)
@@ -1,6 +1,6 @@
 /* The IGEN simulator generator for GDB, the GNU Debugger.
 
 /* The IGEN simulator generator for GDB, the GNU Debugger.
 
-   Copyright 2002 Free Software Foundation, Inc.
+   Copyright 2002, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 
    Contributed by Andrew Cagney.
 
 
    Contributed by Andrew Cagney.
 
@@ -8,7 +8,7 @@
 
    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
 
    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
+   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,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -17,9 +17,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    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.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
 #include "misc.h"
 
 
 #include "misc.h"
@@ -153,7 +151,9 @@ insn_field_cmp (insn_word_entry *l, insn_word_entry *r)
                return -1;
              /* The case of both fields having constant values should have
                 already have been handled because such fields are converted
                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. */
+                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)
              continue;
            }
          if (l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq)
@@ -557,48 +557,6 @@ make_gen_tables (insn_table *isa, decode_table *rules)
 
 /****************************************************************/
 
 
 /****************************************************************/
 
-#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
 /* Is the bit, according to the decode rule, identical across all the
    instructions? */
 static int
@@ -655,6 +613,18 @@ insns_bit_useless (insn_list *insns, decode_table *rule, int bit_nr)
                                    bit->field->val_string))
                /* a string field forced to constant? */
                is_useless = 0;
                                    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;
              else if (rule->search == decode_find_constants)
                /* the string field isn't constant */
                return 1;
@@ -768,75 +738,6 @@ gen_entry_find_opcode_field (insn_list *insns,
        break;
     }
 
        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)
     {
   /* did the final opcode field end up being empty? */
   if (curr_opcode.first > curr_opcode.last)
     {
This page took 0.025247 seconds and 4 git commands to generate.