[m68k] Fix and improve ColdFire function prologue/epilogue generation (respin)

Bernardo Innocenti bernie@develer.com
Mon Sep 8 19:53:00 GMT 2003


Richard Henderson wrote:

> On Thu, Sep 04, 2003 at 11:38:15AM +0200, Bernardo Innocenti wrote:
> 
>>Actually, it works fine with and without -fomit-frame-pointer.
>>The reason is probably that GCC never invokes that function to
>>eliminate the ARG_POINTER_REGNUM from HARD_FRAME_POINTER_REGNUM.
> 
> Indeed.  I read that the wrong wat around.  It never will
> invoke with that, so there's no point checking for it.

It appears not to be so (read below).


>>I think the correct value should be:
>>
>> if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
>>   return (frame_pointer_needed ? -UNITS_PER_WORD * 2 : -UNITS_PER_WORD);
> 
> Yes.

Grrr... GCC produces bad code if I set it that way! It only seems
to work fine with 0. Is it possible that something else is already
producing the wanted offset before or after the elimination?

This means that the elimination _IS_ being used and _MUST_ be 0.

Also, I noticed that, on m68k, HARD_FRAME_POINTER_REGNUM gets defined
to the same value of FRAME_POINTER_REGNUM, therefore I've eliminated
the elimination pair ;-)

m68k seems to be plagued by a i386 cut & paste syndrome :-)


>>>m68k.h:#define FIRST_PARM_OFFSET(FNDECL) 8
>>>
>>>That says that the offset from ARG_POINTER_REGNUM to the first
>>>actual argument is 8.  Which, when you have a frame pointer, is
>>>exactly right for m68k -- four bytes for saved frame pointer,
>>>and four bytes for saved return address.
>>
>>What does GCC use that for? Its value gets assigned to the static
>>variable `in_arg_offset' at function entry time and seems to be
>>only used in instantiate_new_reg().
> 
> For instantiating virtual_incoming_args_rtx.

Then, there must be some piece of black magic that makes the
case with no frame pointer work all over the Linux kernel. I can't
figure out what it is.


Another odd thing about EH problems. The m68k backend defines this
macro:

 /* Describe how we implement __builtin_eh_return.  */
 #define EH_RETURN_DATA_REGNO(N) \
   ((N) < 2 ? (N) : INVALID_REGNUM)


But docs I've read explicitly say that it must _NOT_ use scratch
registers:

** EH_RETURN_DATA_REGNO(N) **

The new implementation of the EH uses two registers to pass
information back to catch.  The macro EH_RETURN_DATA_REGNO maps
the values to hard registers.  These registers require stack slots, so
they cannot be scratch registers that are not saved across function
calls.  The macro EH_RETURN_DATA_REGNO will need to be defined and
return appropriate register numbers for the values 0 and 1.  Below is
an example:

#define EH_RETURN_DATA_REGNO(N) \
	((N) == 0 ? GPR_R7 : (N) == 1 ? GPR_R8 : INVALID_REGNUM)


Shall I post a patch to use D2/D3 instead? It would look like this,
but I can't test it propeely because EH doesn't work on ColdFire
targets:

 /* Describe how we implement __builtin_eh_return.  */
 #define EH_RETURN_DATA_REGNO(N) \
   ((N) < 2 ? ((N) + 2) : INVALID_REGNUM)

Anyone wants to try it?

-- 
  // 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





More information about the Gcc-patches mailing list