This is the mail archive of the gcc-patches@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: [3.0] fix c/4299


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.


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