On Fri, Mar 18, 2011 at 3:42 PM, Jakub Jelinek <ja...@redhat.com> wrote:
> On Fri, Mar 18, 2011 at 03:32:45PM -0700, H.J. Lu wrote:
>> On Fri, Mar 18, 2011 at 3:18 PM, Richard Henderson <r...@redhat.com> wrote:
>> > On 03/18/2011 02:56 PM, H.J. Lu wrote:
>> >> X86 backend uses Pmode for hardware pointer size. Changes
>> >> it to 32bit for x32, which is really 64bit process, breaks many
>> >> assumptions of x86 backend. push/pop/call is just the tip of
>> >> the iceberg.
>> >
>> > Please enumerate "many assumptions".  I can't think of any off
>> > the top of my head.
>> >
>>
>> I don't have a complete list.  gen_push is one of them:
>>
>> static rtx
>> gen_push (rtx arg)
>> {
>>   struct machine_function *m = cfun->machine;
>>
>>   if (m->fs.cfa_reg == stack_pointer_rtx)
>>     m->fs.cfa_offset += UNITS_PER_WORD;
>>   m->fs.sp_offset += UNITS_PER_WORD;
>>
>>   return gen_rtx_SET (VOIDmode,
>>                       gen_rtx_MEM (Pmode,
>>                                    gen_rtx_PRE_DEC (Pmode,
>>                                                     stack_pointer_rtx)),
>>                       arg);
>> }
>>
>> You can only push/pup 64bit in hardware 64bit mode.
>
> That's still push/pop/call.  And you can certainly use a Pmode (== SImode)
> stack_pointer_rtx to describe it too, push/pop reference %rsp just
> implicitly.  For the MEM you would just use DImode for x32 in that case,
> or for <= 32 bit pushes you could describe it as a SImode MEM with
> PRE_MODIFY inside of it.
>

Operations on stack and frame pointers, like push/pop, require stack
and frame pointers in DImode.  Even if I use word_mode in gen_push
and gen_pop, I got

[hjl@gnu-6 pmode-1]$ cat x.i
extern void abort (void) __attribute__ ((__nothrow__)) __attribute__
((__noreturn__));
typedef int DItype __attribute__ ((mode (DI)));
typedef unsigned int UDItype __attribute__ ((mode (DI)));
void
foo (DItype a, DItype b)
{
  const DItype w = (UDItype) a + (UDItype) b;
  if (w < a)
    abort ();
}
[hjl@gnu-6 pmode-1]$ make
/export/build/gnu/gcc-x32/build-x86_64-linux/gcc/xgcc
-B/export/build/gnu/gcc-x32/build-x86_64-linux/gcc/ -S -o x.s -mx32
x.i
x.i: In function \u2018foo\u2019:
x.i:10:1: error: unrecognizable insn:
(insn/f 22 5 23 2 (set (mem:SI (pre_dec:DI (reg/f:SI 7 sp)) [0 S4 A8])
        (reg/f:SI 6 bp)) x.i:6 -1
     (nil))
x.i:10:1: internal compiler error: in insn_default_length, at
config/i386/i386.md:600
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
make: *** [x.s] Error 1
[hjl@gnu-6 pmode-1]$


-- 
H.J.

Reply via email to