genrecog.c (find_operand): Handle 'V' format code.
authorRichard Henderson <rth@gcc.gnu.org>
Sun, 10 Dec 2000 19:50:53 +0000 (11:50 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Sun, 10 Dec 2000 19:50:53 +0000 (11:50 -0800)
        * 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.

From-SVN: r38175

gcc/ChangeLog
gcc/genrecog.c

index e524a35..25f1de5 100644 (file)
@@ -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>
 
 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>
 
 
 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>
 
index 7213ce7..795d521 100644 (file)
@@ -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,