This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[m68k] Fix __builtin_return_address
- From: Paul Brook <paul at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 24 Dec 2005 01:31:39 +0000
- Subject: [m68k] Fix __builtin_return_address
The default definition of RETURN_ADDR_RTX assumes the frame pointer points to
a (frame backlink, return address) pair. This is not true for m68k when
-fomit-frame-pointer is used.
The attached patch fixes this by using a similar definiton to the one in
i386.c. We know the return address will always be immediately before the
functions arguments.
In the process I tripped over the FIXME in m68k_initial_elimination_offset.
The "obscure reason" is that the old values don't take FIRST_PARM_OFFSET into
account. The old values worked mostly by chance because we never eliminate
arg->sp when frame_pointer_needed, and never eliminate arg->fp
when !frame_pointer_needed.
This fixes gcc.c-torture/execute/pr17377.c
Tested with cross to m68k-elf/-m5200
Ok?
Paul
2005-12-23 Paul Brook <paul@codesourcery.com>
* config/m68k/m68k.h (RETURN_ADDR_RTX): Define.
* config/m68k/m68k.c (m68k_initial_elimination_offset): Remove FIXME.
Include offset due to FIRST_PARM_OFFSET.
Index: gcc/config/m68k/m68k.c
===================================================================
--- gcc/config/m68k/m68k.c (revision 108911)
+++ gcc/config/m68k/m68k.c (working copy)
@@ -434,11 +434,13 @@
HOST_WIDE_INT
m68k_initial_elimination_offset (int from, int to)
{
- /* FIXME: The correct offset to compute here would appear to be
- (frame_pointer_needed ? -UNITS_PER_WORD * 2 : -UNITS_PER_WORD);
- but for some obscure reason, this must be 0 to get correct code. */
+ int argptr_offset;
+ /* The arg pointer points 8 bytes before the start of the arguments,
+ as defined by FIRST_PARM_OFFSET. This makes it coincident with the
+ frame pointer in most frames. */
+ argptr_offset = frame_pointer_needed ? 0 : UNITS_PER_WORD;
if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
- return 0;
+ return argptr_offset;
m68k_compute_frame_layout ();
@@ -446,8 +448,7 @@
switch (from)
{
case ARG_POINTER_REGNUM:
- return (current_frame.offset + current_frame.size
- + (frame_pointer_needed ? -UNITS_PER_WORD * 2 : -UNITS_PER_WORD));
+ return current_frame.offset + current_frame.size - argptr_offset;
case FRAME_POINTER_REGNUM:
return current_frame.offset + current_frame.size;
default:
Index: gcc/config/m68k/m68k.h
===================================================================
--- gcc/config/m68k/m68k.h (revision 108911)
+++ gcc/config/m68k/m68k.h (working copy)
@@ -890,6 +890,12 @@
#define INCOMING_RETURN_ADDR_RTX \
gen_rtx_MEM (VOIDmode, gen_rtx_REG (VOIDmode, STACK_POINTER_REGNUM))
+/* After the prologue, RA is at 4(AP) in the current frame. */
+#define RETURN_ADDR_RTX(COUNT, FRAME) \
+ ((COUNT) == 0 \
+ ? gen_rtx_MEM (Pmode, plus_constant (arg_pointer_rtx, UNITS_PER_WORD)) \
+ : gen_rtx_MEM (Pmode, plus_constant (FRAME, UNITS_PER_WORD)))
+
/* We must not use the DBX register numbers for the DWARF 2 CFA column
numbers because that maps to numbers beyond FIRST_PSEUDO_REGISTER.
Instead use the identity mapping. */