PATCH: PR target/45213: "suffix or operands invalid for `push'" triggered by optimisations on x86_64

Uros Bizjak ubizjak@gmail.com
Sat Aug 7 21:24:00 GMT 2010


On Sat, 2010-08-07 at 14:09 -0700, H.J. Lu wrote:

> >>>> SF is 4 bytes, the same as SI. pushq takes 32bit signed extended immediate.
> >>>> It is safe for pushq since the upper 4 bytes, which are all 1s, are unused.
> >>>> For everything else, we use 32bit unsigned int.  We don't want
> >>>>
> >>>> movl  $0xffffffffbf800000, (%rsp)
> >>>>
> >>>> How does this patch look?
> >>>
> >>> Based on your patch, I think this is what we want:
> >>>
> >>> Index: i386.c
> >>> ===================================================================
> >>> --- i386.c      (revision 162975)
> >>> +++ i386.c      (working copy)
> >>> @@ -12921,7 +12921,11 @@
> >>>
> >>>       if (ASSEMBLER_DIALECT == ASM_ATT)
> >>>        putc ('$', file);
> >>> -      fprintf (file, "0x%08lx", (long unsigned int) l);
> >>> +      /* For 64bit ABI sign extend 32bit immediate to 8 bytes.  */
> >>> +      if (code == 'q')
> >>> +       fprintf (file, "0x%08llx", (unsigned long long) (int) l);
> >>> +      else
> >>> +       fprintf (file, "0x%08x", (unsigned int) l);
> >>>     }
> >>>
> >>
> >> That has nothing to do with 64bit ABI. It is due to how pushq works
> >> in hardware. We do wants to generate a 4byte immediate, not 8byte.
> >
> > OK will say "Sign extend 32bit signed immediate to 8 bytes.
> >
> > 0xff.ff.ff.ff.80.00.00.00
> >
> > So, 8 bytes.
> 
> Only pushq sign extends to 8 bytes and we don't care about
> the upper 4 bytes here.  Everything else is 4 byte.

You have to feed pushq with 8 bytes, and we do care for upper 4 bytes
since they should all be 0xff to correctly sign-extend the 32bit
immediate.

pushq mnemonic _REQUIRES_ 8 bytes, the top 4 must be explicitly set in
the asm source. Just try to assemble "pushq 0xfeffffff80000000".

Uros.





More information about the Gcc-patches mailing list