This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: commutative asm operands


On Sat, Aug 03, 2002 at 11:19:18PM +0200, Roman Zippel wrote:
> Hi,
> 
> Alan Modra wrote:
> > I was forwarded a testcase today containing some horrible asm
> > 
> > asm ("addc %0, %2, %3\n\t"
> >      "adde %1, %4, %5"
> >      : "=r" (lo), "=r" (hi)
> >      : "%r" (__lo), "0" (lo), "%r" (__hi), "1" (hi))
> 
> I have a patch to fix this problem, but I have to update and test it again.

Hey, so have I!  I'd better post it..

	* recog.c (constrain_operands): Handle commutative operands.

Bootstrapped, regtested powerpc-linux.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

Index: recog.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/recog.c,v
retrieving revision 1.162
diff -u -p -r1.162 recog.c
--- recog.c	23 Jul 2002 20:50:59 -0000	1.162
+++ recog.c	3 Aug 2002 13:08:02 -0000
@@ -2332,10 +2332,12 @@ constrain_operands (strict)
      int strict;
 {
   const char *constraints[MAX_RECOG_OPERANDS];
+  const char *last_constraints[MAX_RECOG_OPERANDS];
   int matching_operands[MAX_RECOG_OPERANDS];
   int earlyclobber[MAX_RECOG_OPERANDS];
   int c;
-
+  int commutative;
+  bool swapped;
   struct funny_match funny_match[MAX_RECOG_OPERANDS];
   int funny_match_index;
 
@@ -2349,6 +2351,8 @@ constrain_operands (strict)
       matching_operands[c] = -1;
     }
 
+  swapped = false;
+  commutative = 0;
   do
     {
       int opno;
@@ -2390,7 +2394,12 @@ constrain_operands (strict)
 	  while (*p && (c = *p++) != ',')
 	    switch (c)
 	      {
-	      case '?':  case '!': case '*':  case '%':
+	      case '%':
+		if (! lose && ! swapped)
+		  commutative = opno + 1;
+		break;
+
+	      case '?':  case '!': case '*':
 	      case '=':  case '+':
 		break;
 
@@ -2605,11 +2614,12 @@ constrain_operands (strict)
 		}
 	      }
 
+	  last_constraints[opno] = constraints[opno];
 	  constraints[opno] = p;
 	  /* If this operand did not win somehow,
 	     this alternative loses.  */
-	  if (! win)
-	    lose = 1;
+	  if (! win && ! lose)
+	    lose = opno + 1;
 	}
       /* This alternative won; the operands are ok.
 	 Change whichever operands this alternative says to change.  */
@@ -2638,7 +2648,7 @@ constrain_operands (strict)
 						 recog_data.operand[eopno]))
 		      && ! safe_from_earlyclobber (recog_data.operand[opno],
 						   recog_data.operand[eopno]))
-		    lose = 1;
+		    lose = opno + 1;
 
 	  if (! lose)
 	    {
@@ -2652,7 +2662,28 @@ constrain_operands (strict)
 	    }
 	}
 
-      which_alternative++;
+      if (! swapped
+	  && commutative
+	  && (lose == commutative || lose == commutative + 1))
+	{
+	  for (opno = 0; opno < recog_data.n_operands; opno++)
+	    constraints[opno] = last_constraints[opno];
+	  constraints[commutative - 1] = last_constraints[commutative];
+	  constraints[commutative] = last_constraints[commutative - 1];
+	  swapped = true;
+	}
+      else
+	{
+	  if (swapped)
+	    {
+	      const char *tmp = constraints[commutative - 1];
+	      constraints[commutative - 1] = constraints[commutative];
+	      constraints[commutative] = tmp;
+	      swapped = false;
+	    }
+	  commutative = 0;
+	  which_alternative++;
+	}
     }
   while (which_alternative < recog_data.n_alternatives);
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]