This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: commutative asm operands
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: Roman Zippel <zippel at linux-m68k dot org>
- Cc: gcc at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Sun, 4 Aug 2002 12:15:53 +0930
- Subject: Re: commutative asm operands
- References: <20020731141425.GD12579@bubble.sa.bigpond.net.au> <3D4C48D6.2020702@linux-m68k.org>
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);