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: PATCH: PR target/45213: "suffix or operands invalid for `push'" triggered by optimisations on x86_64


On Sat, Aug 7, 2010 at 2:23 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
> 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".
>

This is probably too much details. pushq puts 8byte, which is sign extended
from 32bit immediate operand, on stack. pushq takes INT_MIN to INT_MAX.
You can express them in either 8byte hex or 4byte signed decimal. They
are equivalent as long as 8byte hex is within INT_MIN and INT_MAX.

Since SF is 4byte and the size of each argument gets rounded up to eightbytes,
it is OK to use pushq to put SF on stack when passing function parameter.
The upper 4bytes of "pushq" target are unused by callee.

-- 
H.J.


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