diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-12-10 19:50:53 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-12-10 19:50:53 +0000 |
commit | 386d0079beacbfdcc6c6ddd8e8cbe4eaa24c14e2 (patch) | |
tree | dc7494e7a1d7e13ddb26f9159fe982343c92b8f5 /gcc/genrecog.c | |
parent | daa0d24b2a13c428a2431543035229a4c19d668c (diff) | |
download | gcc-386d0079beacbfdcc6c6ddd8e8cbe4eaa24c14e2.tar.gz |
* genrecog.c (find_operand): Handle 'V' format code.
(find_matching_operand): New.
(validate_pattern): Accept '=' for an in-out operand if there
is another operand with a matching constraint.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@38175 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/genrecog.c')
-rw-r--r-- | gcc/genrecog.c | 89 |
1 files changed, 79 insertions, 10 deletions
diff --git a/gcc/genrecog.c b/gcc/genrecog.c index 7213ce7aed9..795d5214bfb 100644 --- a/gcc/genrecog.c +++ b/gcc/genrecog.c @@ -230,6 +230,8 @@ static struct decision_test *new_decision_test PARAMS ((enum decision_type, struct decision_test ***)); static rtx find_operand PARAMS ((rtx, int)); +static rtx find_matching_operand + PARAMS ((rtx, int)); static void validate_pattern PARAMS ((rtx, rtx, rtx, int)); static struct decision *add_to_sequence @@ -379,6 +381,11 @@ find_operand (pattern, n) return r; break; + case 'V': + if (! XVEC (pattern, i)) + break; + /* FALLTHRU */ + case 'E': for (j = 0; j < XVECLEN (pattern, i); j++) if ((r = find_operand (XVECEXP (pattern, i, j), n)) != NULL_RTX) @@ -396,6 +403,60 @@ find_operand (pattern, n) return NULL; } +/* Search for and return operand M, such that it has a matching + constraint for operand N. */ + +static rtx +find_matching_operand (pattern, n) + rtx pattern; + int n; +{ + const char *fmt; + RTX_CODE code; + int i, j, len; + rtx r; + + code = GET_CODE (pattern); + if (code == MATCH_OPERAND + && (XSTR (pattern, 2)[0] == '0' + n + || (XSTR (pattern, 2)[0] == '%' + && XSTR (pattern, 2)[1] == '0' + n))) + return pattern; + + fmt = GET_RTX_FORMAT (code); + len = GET_RTX_LENGTH (code); + for (i = 0; i < len; i++) + { + switch (fmt[i]) + { + case 'e': case 'u': + if ((r = find_matching_operand (XEXP (pattern, i), n))) + return r; + break; + + case 'V': + if (! XVEC (pattern, i)) + break; + /* FALLTHRU */ + + case 'E': + for (j = 0; j < XVECLEN (pattern, i); j++) + if ((r = find_matching_operand (XVECEXP (pattern, i, j), n))) + return r; + break; + + case 'i': case 'w': case '0': case 's': + break; + + default: + abort (); + } + } + + return NULL; +} + + /* Check for various errors in patterns. SET is nonnull for a destination, and is the complete set pattern. SET_CODE is '=' for normal sets, and '+' within a context that requires in-out constraints. */ @@ -484,19 +545,27 @@ validate_pattern (pattern, insn, set, set_code) } /* A MATCH_OPERAND that is a SET should have an output reload. */ - if (set && code == MATCH_OPERAND) + if (set && code == MATCH_OPERAND + && XSTR (pattern, 2)[0] != '\0') { - if (set_code == '+' - && XSTR (pattern, 2)[0] != '\0' - && XSTR (pattern, 2)[0] != '+') + if (set_code == '+') { - message_with_line (pattern_lineno, - "operand %d missing in-out reload", - XINT (pattern, 0)); - error_count++; + if (XSTR (pattern, 2)[0] == '+') + ; + /* If we've only got an output reload for this operand, + we'd better have a matching input operand. */ + else if (XSTR (pattern, 2)[0] == '=' + && find_matching_operand (insn, XINT (pattern, 0))) + ; + else + { + message_with_line (pattern_lineno, + "operand %d missing in-out reload", + XINT (pattern, 0)); + error_count++; + } } - else if (XSTR (pattern, 2)[0] != '\0' - && XSTR (pattern, 2)[0] != '=' + else if (XSTR (pattern, 2)[0] != '=' && XSTR (pattern, 2)[0] != '+') { message_with_line (pattern_lineno, |