Patch for -mcaller-super-interworking & stack arguments
Richard Earnshaw
rearnsha@gcc.gnu.org
Tue Oct 12 16:07:00 GMT 2004
On Wed, 2004-09-01 at 15:14, Richard Sandiford wrote:
> Richard Earnshaw <rearnsha@gcc.gnu.org> writes:
> > 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.
>
> OK, here's a patch to do that. In most other respects, it's the same
> as the patch I posted before.
>
> The main difficulty with using r11 is that we need to make it fixed
> while at the same time:
>
> (a) making sure it is treated as call-saved rather than call-clobbered and
> (b) making sure that every CALL_INSN is treated as using r11.
>
> (a) is easy enough to do with CALL_REALLY_USED_REGISTERS, but I believe
> the standard way to achieve (b) is to either:
>
> (1) add (use r11) to the call patterns or
> (2) add (use r11) to CALL_INSN_FUNCTION_USAGE.
>
> (1) would mean adding new patterns or complicating the existing ones.
> (2) would mean changing the call expanders so that they do something like:
>
> insn = emit_call_insn (gen_... (...));
> if (...)
> use_reg (&CALL_INSN_FUNCTION_USAGE (insn), gen_rtx_REG (Pmode, 11));
> DONE;
>
> Both seemed too invasive for what is (I suspect) such a little-used feature.
>
> The patch therefore just makes r11 global, which achieves (a) and (b) above,
> and also has the benefit of warning if the user tries to use r11 as a true
> global register.
>
> In his review, Nick asked me to add a testcase to the testsuite.
> This is a bit difficult because something like:
>
> /* { dg-options "-mthumb -mcaller-super-interworking" } */
>
> will cause lots of linker warnings if run on a non-thumb multilib.
> For example, testglue (which arm-sim still uses) will not have been
> compiled for thumb.
>
> I think the only reliable way of testing -mcaller-super-interworking is
> to add it to the --target_board list. If you do that, then like I said
> in my original posting, you'll get a failure in gcc.dg/trampoline-1.c
> that is fixed by this patch.
>
> Tested on arm-elf with {,-mthumb,-mthumb/-mcaller-super-interworking}.
> OK to install?
>
> Richard
>
>
> * config/arm/arm.h (CONDITIONAL_REGISTER_USAGE): Make r11 fixed and
> global for -mcaller-super-interworking.
> (CALLER_INTERWORKING_SLOT_SIZE): New macro.
> * config/arm/arm.c (thumb_compute_save_reg_mask): Save r11 if
> CALLER_INTERWORKING_SLOT_SIZE is nonzero and the function does
> not need a frame pointer.
> (arm_get_frame_offsets): Add CALLER_INTERWORKING_SLOT_SIZE bytes to
> the soft frame pointer offset.
> (thumb_expand_prologue): Set up r11 for -mcaller-super-interworking.
> * config/arm/arm.md (*call_reg_thumb, *call_value_reg_thumb): Use
> _interwork_{r7,r11}_call_via_rN if some arguments are passed on
> the stack. Use frame_pointer_needed to choose between them.
> * config/arm/lib1funcs.asm (_arm_return_{r7,r11}): New functions.
> (interwork_with_frame): New macro.
> (interwork): Add _interwork_{r7,r11}_call_via_rN().
Having thought about this for a while, I now think this is probably the
best solution. However, can you make the following change before
committing?
> *************** #define STACK_GROWS_DOWNWARD 1
> *** 1517,1522 ****
> --- 1523,1542 ----
> goes at a more negative offset in the frame. */
> #define FRAME_GROWS_DOWNWARD 1
>
> + /* The amount of scratch space needed by _interwork_{r7,r11}_call_via_rN().
> + When present, it is one word in size, and sits at the top of the frame,
> + between the soft frame pointer and either r7 or r11.
> +
> + We only need _interwork_rM_call_via_rN() for -mcaller-super-interworking,
> + and only then if some outgoing arguments are passed on the stack. It would
> + be tempting to also check whether the stack arguments are passed by indirect
> + calls, but there seems to be no reason in principle why a post-reload pass
> + couldn't convert a direct call into an indirect one. */
> + #define CALLER_INTERWORKING_SLOT_SIZE \
> + (!TARGET_CALLER_INTERWORKING ? 0 \
> + : current_function_outgoing_args_size == 0 ? 0 \
> + : UNITS_PER_WORD)
> +
> /* Offset within stack frame to start allocating local variables at.
> If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
> first local allocated. Otherwise, it is the offset to the BEGINNING
This would be clearer if expressed as
((TARGET_CALLER_INTERWORKING
&& current_funciton_outgoing_args_size != 0)
? UNITS_PER_WORD : 0)
R.
More information about the Gcc-patches
mailing list