This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Patch for -mcaller-super-interworking & stack arguments


Richard,

Sorry for not replying to this sooner, I've been pondering the situation
'cos I'm not 100% happy about any of this...

On Mon, 2004-08-09 at 08:03, Richard Sandiford wrote:
> -mcaller-super-interworking causes all indirect calls to use an
> _interwork_call_via_rN stub.  If the target address is an ARM function,
> this stub will push the (thumb) return address onto the stack and get
> the ARM function to return to _arm_return instead.
> 
> Unfortunately, pushing the return address onto the stack means that thumb
> functions can't pass stack arguments to ARM functions.  The suggested fix
> is to define alternative interworking functions that store the return
> address at [r7, #-4] instead.  This of course requires the caller to
> use a frame pointer and to provide appropriate scratch space there.
> 
> If the caller used a frame pointer anyway, I think the overhead of this
> approach should be very low.  We just need to bump up the size of the
> frame and fiddle with the elimination offsets.  The only source of
> extra insns should be from frame accesses that are on the borderline
> between being in-range and out-of-range.
> 

Agreed.

> On the other hand, if the function _didn't_ need a frame pointer for
> anything else, then there is definitely a big overhead.  The patch
> therefore only uses these new functions if there are some outgoing
> stack arguments.  (As per the comment in the patch, I don't think
> we can really refine the condition much more than that.)
> 

Yep, that's reasonable.

Another approach would be to use r11 (fp) to hold the 'frame pointer' in
the case where we didn't really need a frame (and continue to pretend
that the function was frameless).  It would mean a further function stub
in libgcc (unless you always made it work that way) but would mean that
we didn't loose a low register.  You'd end up with a prologue sequence
something like

	push	{r4-r7, lr}
	mov	r4, fp
	push	{r4}
	sub	sp, sp, #4
	mov	fp, sp

The interwork stub would be similar to the one in your proposed patch,
but use fp instead of r7.

To make this work you'd probably have to make r11 a fixed register for
-mthumb -mcaller-super-interworking, but that wouldn't hurt very much.

> This patch has been regression tested on arm-elf, test pattern:
> 
>     arm-sim{,-mthumb,-mthumb/-mcaller-super-interworking}
> 
> I admit this doesn't exercise thumb->ARM calls that much since the
> third pattern will link against the thumb multilibs.  Trying to test
> against a --disable-multilib build is useless because of all the extra
> linker warnings.
> 
> Even so, the thumb->ARM route does get some testing from compiler-generated
> trampolines and thunks, and the patch does fix gcc.dg/trampoline-1.c and
> g++.old-deja/g++.jason/thunk3.C.  There were no regressions.  OK to install?
> 
> Richard
> 
> 
> 	* config/arm/arm.h (CALLER_INTERWORKING_SLOT_SIZE): New macro.
> 	(FRAME_POINTER_REQUIRED): True if CALLER_INTERWORKING_SLOT_SIZE > 0.
> 	* config/arm/arm.c (arm_get_frame_offsets): Add
> 	CALLER_INTERWORKING_SLOT_SIZE bytes to the soft frame pointer offset.
> 	* config/arm/arm.md (*call_reg_thumb, *call_value_reg_thumb): Use
> 	_interwork_fp_call_via_rN if some arguments are passed on the stack.
> 	* config/arm/lib1funcs.asm (_arm_fp_return): New function.
> 	(interwork): Add _interwork_fp_call_via_rN() functions.

OK.  But can you give some thought to my suggestion.

R.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]