summaryrefslogtreecommitdiff
path: root/gcc/genrecog.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2000-12-10 19:50:53 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2000-12-10 19:50:53 +0000
commit386d0079beacbfdcc6c6ddd8e8cbe4eaa24c14e2 (patch)
treedc7494e7a1d7e13ddb26f9159fe982343c92b8f5 /gcc/genrecog.c
parentdaa0d24b2a13c428a2431543035229a4c19d668c (diff)
downloadgcc-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.c89
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,