Remove i386_elf_emit_arch_note
[deliverable/binutils-gdb.git] / sim / igen / gen.c
index 0ff15d487938e1afb3a9f91505c395b621b907cd..cdf1549fb3844427849515768610b644349082da 100644 (file)
@@ -1,6 +1,6 @@
 /* The IGEN simulator generator for GDB, the GNU Debugger.
 
-   Copyright 2002 Free Software Foundation, Inc.
+   Copyright 2002-2015 Free Software Foundation, Inc.
 
    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
-   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,
@@ -17,9 +17,7 @@
    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"
@@ -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
-                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)
@@ -296,7 +296,7 @@ new_opcode_bits (opcode_bits *old_bits,
 
 /* Same as strcmp().  */
 static int
-format_name_cmp (const char *l, const char *r)
+name_cmp (const char *l, const char *r)
 {
   if (l == NULL && r == NULL)
     return 0;
@@ -350,19 +350,35 @@ insn_list_insert (insn_list **cur_insn_ptr,
       else if (cmp > 0)
        continue;
 
-      /* key#4 sort according to the format-name.  If two apparently
-         identical instructions have unique format-names, then the
-         instructions are different.  This is because the
-         format-name's use is overloaded, it not only indicates the
-         format name but also provides a unique semantic name for the
-         function.  */
-      cmp =
-       format_name_cmp (insn->format_name,
-                        (*cur_insn_ptr)->insn->format_name);
-      if (cmp < 0)
-       break;
-      else if (cmp > 0)
-       continue;
+      if (duplicate_action == merge_duplicate_insns)
+       {
+         /* 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;
+       }
+
+      if (duplicate_action == merge_duplicate_insns)
+       {
+         /* 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)
@@ -379,6 +395,15 @@ insn_list_insert (insn_list **cur_insn_ptr,
                 "Location of duplicate instruction\n");
        case merge_duplicate_insns:
          /* Add the opcode path to the instructions list */
+         if (options.trace.insn_insertion)
+           {
+             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);
+           }
          if (opcodes != NULL)
            {
              insn_opcodes **last = &(*cur_insn_ptr)->opcodes;
@@ -400,6 +425,13 @@ insn_list_insert (insn_list **cur_insn_ptr,
   /* 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);
@@ -525,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
@@ -623,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;
+             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;
@@ -736,75 +738,6 @@ gen_entry_find_opcode_field (insn_list *insns,
        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)
     {
This page took 0.025891 seconds and 4 git commands to generate.