diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 32 | ||||
-rw-r--r-- | gcc/genrecog.c | 89 |
2 files changed, 100 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e524a35..25f1de51 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,15 @@ 2000-12-10 Richard Henderson <rth@redhat.com> + * 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. + + * config/i386/i386.md (andqi_ext_0_cc): Use matching constraint + for op1 to op0. + +2000-12-10 Richard Henderson <rth@redhat.com> + * genrecog.c (validate_pattern) [STRICT_LOW_PART]: Fix thinko. 2000-12-09 Richard Henderson <rth@redhat.com> @@ -30,16 +40,16 @@ 2000-12-09 Neil Booth <neilb@earthling.net> - * cppfiles.c (NEVER_REREAD, DO_NOT_REREAD): Move from cpphash.h. - * cpphash.h (NEVER_REREAD, DO_NOT_REREAD, ABSOLUTE_PATH): Delete. - * cpplex.c (parse_identifier): Improve diagnostic. - (_cpp_lex_token): Return unconditionally at the end of a directive. - * cpplib.c (read_flag): Verify legality of each flag. - (end_directive): Resotre pfile->skipping before skip_rest_of_line. - (do_line): Use the new read_flag. - * cppmacro.c (struct cpp_macro, parse_arg, replace_args, - check_macro_redefinition, parse_params): Rename var_args to - variadic. + * cppfiles.c (NEVER_REREAD, DO_NOT_REREAD): Move from cpphash.h. + * cpphash.h (NEVER_REREAD, DO_NOT_REREAD, ABSOLUTE_PATH): Delete. + * cpplex.c (parse_identifier): Improve diagnostic. + (_cpp_lex_token): Return unconditionally at the end of a directive. + * cpplib.c (read_flag): Verify legality of each flag. + (end_directive): Resotre pfile->skipping before skip_rest_of_line. + (do_line): Use the new read_flag. + * cppmacro.c (struct cpp_macro, parse_arg, replace_args, + check_macro_redefinition, parse_params): Rename var_args to + variadic. 2000-12-09 Joseph S. Myers <jsm28@cam.ac.uk> @@ -130,7 +140,7 @@ 2000-12-08 Brad Lucier <lucier@math.purdue.edu> - * tradcpp.c (do_include): Make pointer differences 64-bit clean. + * tradcpp.c (do_include): Make pointer differences 64-bit clean. Fri Dec 8 08:23:29 2000 J"orn Rennecke <amylaar@redhat.com> diff --git a/gcc/genrecog.c b/gcc/genrecog.c index 7213ce7..795d521 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, |