summaryrefslogtreecommitdiff
path: root/gcc/genrecog.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2001-01-14 20:35:06 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2001-01-14 20:35:06 +0000
commit35b0bfe2639704daf3b82bf70883f6e0b8a1bac8 (patch)
tree0ae5b9e038cb8db433e6b4a957bbe6bce29b9d84 /gcc/genrecog.c
parent2162064c90d9a75786ffec295b579f68a434ce69 (diff)
downloadgcc-35b0bfe2639704daf3b82bf70883f6e0b8a1bac8.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@39016 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/genrecog.c')
-rw-r--r--gcc/genrecog.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/gcc/genrecog.c b/gcc/genrecog.c
index 80d680a4292..cbca47b8e2d 100644
--- a/gcc/genrecog.c
+++ b/gcc/genrecog.c
@@ -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;