OSDN Git Service

(notice_cc_update): Set CC_FCOMI is this is a float compare.
[pf3gnuchains/gcc-fork.git] / gcc / genrecog.c
index 2480ea9..b07c70f 100644 (file)
@@ -1,5 +1,5 @@
 /* Generate code from machine description to recognize rtl as insns.
-   Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc.
+   Copyright (C) 1987, 88, 92, 93, 94, 1995 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -15,7 +15,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 
 /* This program is used to produce insn-recog.c, which contains
@@ -119,7 +120,7 @@ static int next_number;
 static int next_insn_code;
 
 /* Similar, but counts all expressions in the MD file; used for
-   error messages. */
+   error messages.  */
 
 static int next_index;
 
@@ -158,7 +159,7 @@ static struct pred_table
      {"push_operand", {MEM}},
      {"memory_operand", {SUBREG, MEM}},
      {"indirect_operand", {SUBREG, MEM}},
-     {"comparison_operation", {EQ, NE, LE, LT, GE, LT, LEU, LTU, GEU, GTU}},
+     {"comparison_operator", {EQ, NE, LE, LT, GE, GT, LEU, LTU, GEU, GTU}},
      {"mode_independent_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
                                   LABEL_REF, SUBREG, REG, MEM}}};
 
@@ -372,36 +373,46 @@ add_to_sequence (pattern, last, position)
 
         Finally, if we know that the predicate does not allow CONST_INT, we
         know that the only way the predicate can match is if the modes match
-        (here we use the kluge of relying on the fact that "address_operand"
+        (here we use the kludge of relying on the fact that "address_operand"
         accepts CONST_INT; otherwise, it would have to be a special case),
         so we can test the mode (but we need not).  This fact should
         considerably simplify the generated code.  */
 
       if (new->tests)
-       for (i = 0; i < NUM_KNOWN_PREDS; i++)
-         if (! strcmp (preds[i].name, new->tests))
-           {
-             int j;
-             int allows_const_int = 0;
+       {
+         for (i = 0; i < NUM_KNOWN_PREDS; i++)
+           if (! strcmp (preds[i].name, new->tests))
+             {
+               int j;
+               int allows_const_int = 0;
 
-             new->pred = i;
+               new->pred = i;
 
-             if (preds[i].codes[1] == 0 && new->code == UNKNOWN)
-               {
-                 new->code = preds[i].codes[0];
-                 if (! strcmp ("const_int_operand", new->tests))
-                   new->tests = 0, new->pred = -1;
-               }
+               if (preds[i].codes[1] == 0 && new->code == UNKNOWN)
+                 {
+                   new->code = preds[i].codes[0];
+                   if (! strcmp ("const_int_operand", new->tests))
+                     new->tests = 0, new->pred = -1;
+                 }
 
-             for (j = 0; j < NUM_RTX_CODE && preds[i].codes[j] != 0; j++)
-               if (preds[i].codes[j] == CONST_INT)
-                 allows_const_int = 1;
+               for (j = 0; j < NUM_RTX_CODE && preds[i].codes[j] != 0; j++)
+                 if (preds[i].codes[j] == CONST_INT)
+                   allows_const_int = 1;
 
-             if (! allows_const_int)
-               new->enforce_mode = new->ignore_mode= 1;
+               if (! allows_const_int)
+                 new->enforce_mode = new->ignore_mode= 1;
 
-             break;
-           }
+               break;
+             }
+
+#ifdef PREDICATE_CODES
+         /* If the port has a list of the predicates it uses but omits
+            one, warn.  */
+         if (i == NUM_KNOWN_PREDS)
+           fprintf (stderr, "Warning: `%s' not in PREDICATE_CODES\n",
+                    new->tests);
+#endif
+       }
 
       if (code == MATCH_OPERATOR || code == MATCH_PARALLEL)
        {
@@ -487,7 +498,7 @@ add_to_sequence (pattern, last, position)
       if (GET_CODE (XEXP (pattern, 0)) == CC0)
        break;
 
-      /* ... fall through ... */
+      /* ... fall through ...  */
       
     case COMPARE:
       /* Enforce the mode on the first operand to avoid ambiguous insns.  */
@@ -561,7 +572,7 @@ not_both_true (d1, d2, toplevel)
   struct decision *p1, *p2;
 
   /* If they are both to test modes and the modes are different, they aren't
-     both true.  Similarly for codes, integer elements, and vector lengths. */
+     both true.  Similarly for codes, integer elements, and vector lengths.  */
 
   if ((d1->enforce_mode && d2->enforce_mode
        && d1->mode != VOIDmode && d2->mode != VOIDmode && d1->mode != d2->mode)
@@ -945,7 +956,7 @@ break_out_subroutines (head, type, initial)
      int initial;
 {
   int size = 0;
-  struct decision *node, *sub;
+  struct decision *sub;
 
   for (sub = head.first; sub; sub = sub->next)
     size += 1 + break_out_subroutines (sub->success, type, 0);
@@ -1128,7 +1139,7 @@ write_tree_1 (tree, prevpos, afterward, type)
             seen any of the codes that are valid for the predicate, we
             can write a series of "case" statement, one for each possible
             code.  Since we are already in a switch, these redundant tests
-            are very cheap and will reduce the number of predicate called. */
+            are very cheap and will reduce the number of predicate called.  */
 
          if (p->pred >= 0)
            {
@@ -1298,7 +1309,7 @@ write_tree_1 (tree, prevpos, afterward, type)
        }
 
       /* Now that most mode and code tests have been done, we can write out
-        a label for an inner node, if we haven't already. */
+        a label for an inner node, if we haven't already.  */
       if (p->label_needed)
        printf ("%sL%d:\n", indents[indent - 2], p->number);
 
@@ -1332,13 +1343,22 @@ write_tree_1 (tree, prevpos, afterward, type)
          if (p->test_elt_one_int)
            printf ("XINT (x%d, 1) == %d && ", depth, p->elt_one_int);
          if (p->test_elt_zero_wide)
-           printf (
+           {
+             /* Set offset to 1 iff the number might get propagated to
+                unsigned long by ANSI C rules, else 0.
+                Prospective hosts are required to have at least 32 bit
+                ints, and integer constants in machine descriptions
+                must fit in 32 bit, thus it suffices to check only
+                for 1 << 31 .  */
+             HOST_WIDE_INT offset = p->elt_zero_wide == -2147483647 - 1;
+             printf (
 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
-                   "XWINT (x%d, 0) == %d && ",
+                      "XWINT (x%d, 0) == %d%s && ",
 #else
-                   "XWINT (x%d, 0) == %ld && ",
+                      "XWINT (x%d, 0) == %ld%s && ",
 #endif
-                   depth, p->elt_zero_wide);
+                      depth, p->elt_zero_wide + offset, offset ? "-1" : "");
+           }
          if (p->veclen)
            printf ("XVECLEN (x%d, 0) == %d && ", depth, p->veclen);
          if (p->dupno >= 0)