This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: function arguments offset computation with -fomit-frame-pointer
- From: Bernardo Innocenti <bernie at develer dot com>
- To: Hans-Peter Nilsson <hp at bitrange dot com>,Jim Wilson <wilson at tuliptree dot org>
- Cc: <gcc at gcc dot gnu dot org>,Peter Barada <pbarada at mail dot wm dot sps dot mot dot com>
- Date: Wed, 9 Jul 2003 09:47:20 +0200
- Subject: Re: function arguments offset computation with -fomit-frame-pointer
- Organization: Develer
- References: <Pine.BSF.4.44.0307080400550.22413-100000@dair.pair.com>
On Wednesday 09 July 2003 06:48, Hans-Peter Nilsson wrote:
> > > I also have a more m68k-specific question: the code path for
> > > creating room for the frame when no frame pointer always adds 4
> > > bytes to the required frame size. Is that done to get the same
> > > offset that link/unlink would have done? Why is that necessary?
> >
> > Probably nobody knows anymore, it has been there for well over a
> > decard, but link/unlink space for the return address is the obvious
> > guess. Maybe the problem is that INITIAL_FRAME_POINTER_OFFSET isn't
> > checking frame_pointer_needed, and thus we always need to add the 4
> > bytes to make INITIAL_FRAME_POINTER_OFFSET work? If so, then fixing
> > that macro would let you get rid of the extra 4 bytes in the
> > prologue code.
>
> Having faced that problem myself for two other ports, I thought
> I should mention that I agree with your guess, but I don't think
> the solution was that simple (though I've forgotten the details;
> maybe it was only complicated on targets that don't have to save
> the return address for leaf-functions).
>
> Anyway IIRC the correct solution is to use ELIMINATE_REGS rather
> than INITIAL_FRAME_POINTER_OFFSET. (Hmm, that'd indicate the
> problem being related to eliminating the argument pointer in
> favor of the stack pointer and missing an offset between fp and
> ap or something.)
Actually, there must be something _very_ bad going on here. Frame
handling for the ColdFire is a little more complicated because there
are no pre-decrement and post-increment addressing modes in movem.
The size of saved registers has to be added to the stack pointer within
the same instruction that increments it to create the frame (either link
or lea/add/move).
I've double-checked the way I compute the frame size in the prolog,
epologue and and in initial_frame_pointer_offset(). I added debug
statements to print the computed sizes in the generated assembly.
Everything appears to be fine for several cases I examined, so I was
quite confident about it.
However, there must be still a bug somewhere because a Linux kernel
compiled with -fomit-frame-pointer crashes with bus errors in a place
I cannot reach with the debugger. I don't have strong evidence on this,
but I believe one function gets its parameters from the wrong sp offset.
Here's how I compute the frame size for the compiler:
int
initial_frame_pointer_offset()
{
int depth;
int regno;
int fp_size = /* TARGET_CFV4E ? 8 : */ 12;
int offset = -4;
int interrupt_handler = m68k_interrupt_function_p (current_function_decl);
int fsize = (get_frame_size() + 3) & -4;
for (regno = 16; regno < FIRST_PSEUDO_REGISTER; regno++)
if (m68k_save_reg (regno, interrupt_handler))
offset += fp_size;
for (regno = 0; regno < 16; regno++)
if (m68k_save_reg (regno, interrupt_handler))
offset += 4;
if (flag_pic && current_function_uses_pic_offset_table)
offset += 4;
depth = (offset + fsize
+ ((fsize && frame_pointer_needed) ? 4 : 0));
return depth;
}
--
// Bernardo Innocenti - Develer S.r.l., R&D dept.
\X/ http://www.develer.com/
Please don't send Word attachments - http://www.gnu.org/philosophy/no-word-attachments.html