This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: bug in internal PUSH expanding (splitting)
- To: law at cygnus dot com
- Subject: Re: bug in internal PUSH expanding (splitting)
- From: Denis Chertykov <denisc at overta dot ru>
- Date: Thu, 16 Dec 1999 00:08:35 +0300
- Cc: gcc at gcc dot gnu dot org
- References: <1067.945250148@upchuck>
Jeffrey A Law <law@cygnus.com> writes:
> I think something else is wrong.
>
> I would think you should be referencing the virtual outgoing
> argument pointer,
> not the stack pointer here. That will be turned into SP +
> STACK_POINTER_OFFSET.
May be you right. May be no.
My main question: What gcc mean push is ?
1. *(--sp) = arg;
2. *((--sp) + STACK_POINTER_OFFSET) = arg,
In first case you right.
In second no.
gcc don't use virtual_outgoing_args_rtx because on any level above
than emit_move_insn_1 gcc don't check a `movdi' pattern.
> If you look at the c4x port, which has similar characteristics to your port
> you'll see something like this in the .rtl dump:
c4x port have all movXX patterns.
(really movqi and movhi but QImode = 32 bit and HImode = 64 bit)
My port don't have a movdi pattern and gcc try to expand push command
for DImode himself (emit_move_insn_1).
My new example:
void boo (int, ...);
struct {long int lo,hi;} di_struct;
foo ()
{
boo (1,0x1234567890LL /* number in DImode. Wrong code */);
boo (1, di_struct /* here gcc generates right code.
Here gcc uses another method
(sp-=sizeof (di_struct),
memcpy (sp + STACK_POINTER_OFFSET, di_struct, ...))
*/ );
}
IMHO: Solution is in emit_move_insn_1.
old_sp = sp;
sp-=sizeof (arg);
*old_sp-- = arg[n]; /* MSB of arg */
*old_sp-- = arg[3];
*old_sp-- = arg[2];
*old_sp-- = arg[1];
*old_sp-- = arg[0]; /* LSB of arg */
Today's gcc-2.95.2:
sp-=sizeof (arg);
*sp = arg;
With my patch:
sp-=sizeof (arg);
*(sp + STACK_POINTER_OFFSET) = arg;
???
Denis.
PS: Is my bad English a problem for understanding my message ?