genrecog.c (DT_veclen_ge): New.
authorRichard Henderson <rth@redhat.com>
Sun, 14 Jan 2001 20:35:06 +0000 (12:35 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Sun, 14 Jan 2001 20:35:06 +0000 (12:35 -0800)
        * genrecog.c (DT_veclen_ge): New.
        (add_to_sequence) [MATCH_PARALLEL]: Generate one.
        (maybe_both_true_2): Simplify DT_veclen vs DT_veclen_ge.
        (nodes_identical_1): Handle DT_veclen_ge.
        (write_cond, debug_decision_2): Likewise.

From-SVN: r39016

gcc/ChangeLog
gcc/genrecog.c

index 70fe869..5769bb8 100644 (file)
@@ -1,3 +1,11 @@
+2001-01-14  Richard Henderson  <rth@redhat.com>
+
+       * genrecog.c (DT_veclen_ge): New.
+       (add_to_sequence) [MATCH_PARALLEL]: Generate one.
+       (maybe_both_true_2): Simplify DT_veclen vs DT_veclen_ge.
+       (nodes_identical_1): Handle DT_veclen_ge.
+       (write_cond, debug_decision_2): Likewise.
+
 2001-01-14  Richard Earnshaw  <rearnsha@arm.com>
 
        * arm.md (ldmsi_postinc, ldmsi, stmsi_postinc, smsi): Delete.  Replace
index 80d680a..cbca47b 100644 (file)
@@ -87,7 +87,7 @@ struct decision_test
   enum decision_type {
     DT_mode, DT_code, DT_veclen,
     DT_elt_zero_int, DT_elt_one_int, DT_elt_zero_wide,
-    DT_dup, DT_pred, DT_c_test, 
+    DT_veclen_ge, DT_dup, DT_pred, DT_c_test, 
     DT_accept_op, DT_accept_insn
   } type;
 
@@ -802,10 +802,19 @@ add_to_sequence (pattern, last, position, insn_type, top)
       /* Else nothing special.  */
       break;
 
+    case MATCH_PARALLEL:
+      /* The explicit patterns within a match_parallel enforce a minimum
+        length on the vector.  The match_parallel predicate may allow
+        for more elements.  We do need to check for this minimum here
+        or the code generated to match the internals may reference data
+        beyond the end of the vector.  */
+      test = new_decision_test (DT_veclen_ge, &place);
+      test->u.veclen = XVECLEN (pattern, 2);
+      /* FALLTHRU */
+
     case MATCH_OPERAND:
     case MATCH_SCRATCH:
     case MATCH_OPERATOR:
-    case MATCH_PARALLEL:
     case MATCH_INSN:
       {
        const char *pred_name;
@@ -1122,6 +1131,12 @@ maybe_both_true_2 (d1, d2)
        }
     }
 
+  /* Tests vs veclen may be known when strict equality is involved.  */
+  if (d1->type == DT_veclen && d2->type == DT_veclen_ge)
+    return d1->u.veclen >= d2->u.veclen;
+  if (d1->type == DT_veclen_ge && d2->type == DT_veclen)
+    return d2->u.veclen >= d1->u.veclen;
+
   return -1;
 }
 
@@ -1252,6 +1267,7 @@ nodes_identical_1 (d1, d2)
       return strcmp (d1->u.c_test, d2->u.c_test) == 0;
 
     case DT_veclen:
+    case DT_veclen_ge:
       return d1->u.veclen == d2->u.veclen;
 
     case DT_dup:
@@ -1952,6 +1968,10 @@ write_cond (p, depth, subroutine_type)
       printf (HOST_WIDE_INT_PRINT_DEC, p->u.intval);
       break;
 
+    case DT_veclen_ge:
+      printf ("XVECLEN (x%d, 0) >= %d", depth, p->u.veclen);
+      break;
+
     case DT_dup:
       printf ("rtx_equal_p (x%d, operands[%d])", depth, p->u.dup);
       break;
@@ -2715,6 +2735,9 @@ debug_decision_2 (test)
       fprintf (stderr, "elt0_w=");
       fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, test->u.intval);
       break;
+    case DT_veclen_ge:
+      fprintf (stderr, "veclen>=%d", test->u.veclen);
+      break;
     case DT_dup:
       fprintf (stderr, "dup=%d", test->u.dup);
       break;