This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [3.0] fix c/4299
- From: Franz Sirl <Franz dot Sirl-kernel at lauterbach dot com>
- To: Richard Henderson <rth at redhat dot com>,gcc-patches at gcc dot gnu dot org,mark at codesourcery dot com
- Date: Thu, 13 Dec 2001 23:55:54 +0100
- Subject: Re: [3.0] fix c/4299
- References: <20011205221421.B9033@redhat.com>
On Thursday 06 December 2001 07:14, Richard Henderson wrote:
> The problem here is that we process the output operands,
> decide that X is ok as a register, then process the input
> operands. In the process we call mark_addressable, which
> modifies the DECL_RTL in place, which modifies the output
> operand we validated earlier and which is no longer valid.
>
> So we wind up with an asm with operands that don't match
> the constraints, which results in a abort because we can't
> validate a change to the insn.
>
> The solution I've chosen is to make two passes over the
> operands. In the first pass we do nothing but call
> mark_addressable. In the second pass we do all the regular
> data movement and validation we were doing before.
>
> Bootstrapped and tested on i686-linux.
>
> This patch will need some massaging before it will apply
> to mainline.
>
>
> r~
>
>
> * stmt.c (parse_input_constraint): Break out from ...
> (expand_asm_operands): ... here. Loop over the operands twice,
> the first time only calling mark_addressable.
>
> * gcc.c-torture/compile/20011205-1.c: New test.
Richard, I think your patch broke glibc compilation for powerpc-linux-gnu.
This code:
typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__)));
void
__setfpucw (fpu_control_t set)
{
fpu_control_t cw;
(
{
union
{
double d;
fpu_control_t cw[2];
} tmp __attribute__ ((__aligned__(8)));
__asm__ ("mffs 0; stfd%U0 0,%0" : "=m" (tmp.d) : : "fr0");
(cw)=tmp.cw[1];
tmp.cw[1];
}
);
cw &= 0xffffff00;
cw |= set & ~0xffffff00;
{
union
{
double d;
fpu_control_t cw[2];
} tmp __attribute__ ((__aligned__(8)));
tmp.cw[0] = 0xFFF80000;
tmp.cw[1] = cw;
__asm__ ("lfd%U0 0,%0; mtfsf 255,0" : : "m" (tmp.d) : "fr0");
};
}
yields:
test.c: In function `__setfpucw':
test.c:15: output number 0 not directly addressable
test.c:15: inconsistent operand constraints in an `asm'
if compiled with current gcc-3.0.3pre. Strangely enough it seems to work if I
add a *& no-op like
_asm__ ("mffs 0; stfd%U0 0,%0" : "=m" (*&tmp.d) : : "fr0");
Franz.