This is the mail archive of the
mailing list for the GCC project.
Re: [PATCH] pdp11: Fix bad code for no frame pointer case
On Nov 19, 2010, at 12:33 PM, Richard Henderson wrote:
> On 11/18/2010 06:04 PM, Paul Koning wrote:
>> -#define FIRST_PARM_OFFSET(FNDECL) 4
>> +#define FIRST_PARM_OFFSET(FNDECL) ((frame_pointer_needed) ? 4 : 2)
> This is a sign of broken register elimination. This macro is used very early
> in the rtl optimization path -- virtual register instantiation. At that point,
> the final value of frame_pointer_needed has not been set.
> The position of ARG_POINTER_REGNUM needs to be completely above the local stack
> frame in order to properly address the arguments. So either you need to position
> FRAME_POINTER_REGNUM at the top of the frame, or you need to create a "soft"
> ARG_POINTER_REGNUM that is always eliminated to either the FRAME_POINTER_REGNUM
> or to STACK_POINTER_REGNUM.
> Quite often, ports also create a "soft" FRAME_POINTER_REGNUM, which is always
> eliminated to HARD_FRAME_POINTER_REGNUM. The soft frame pointer will always
> point to the area for the local variables, whereas the hard frame pointer is
> somewhere else, generally within the area for the saved registers.
> For instance, for i386:
> void f(int a, int b)
> int x;
> int y[a];
> g(a, x, y);
> --------------- arg_pointer
> return addr
> save ebp
> --------------- hard_frame_pointer
> save ebx
> save esi
> save edi
> --------------- frame_pointer
> x (local variable area)
> y[a] (alloca area)
> &x (outgoing arguments)
> --------------- stack_pointer
> Before register allocation, the fixed positions that we have are
> arg_pointer, frame_pointer, and stack_pointer (for outgoing arguments).
> During register allocation, the ELIMINABLE_REGS, TARGET_CAN_ELIMINATE
> and INITIAL_ELIMINATION_OFFSET macros determine which eliminations are
> possible, and what offsets to apply when doing so.
> The pieces of information needed in order to compute these offsets are
> (1) whether frame pointer is required (frame_pointer_needed),
> (2) the size of the register save area (some cpu.c function),
> (3) the size of the local stack frame (get_frame_size ()),
> (4) the size of the outgoing arguments (ctrl->outgoing_args_size).
> Exactly how you apply these depends on exactly how you lay out the
> entire local stack frame.
That's helpful. I noticed that this "fix" helps some cases and breaks others, depending on whether a frame pointer appears or not. I'll dig into i386 and those other macros to make this right.