diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-01-14 20:35:06 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-01-14 20:35:06 +0000 |
commit | 35b0bfe2639704daf3b82bf70883f6e0b8a1bac8 (patch) | |
tree | 0ae5b9e038cb8db433e6b4a957bbe6bce29b9d84 /gcc/genrecog.c | |
parent | 2162064c90d9a75786ffec295b579f68a434ce69 (diff) | |
download | gcc-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.c | 27 |
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; |