Yoriko Komatsuzaki <yor...@sm.sony.co.jp> writes: > Could you tell me why it doesn't work well around FRAME_GROWS_DOWNWARD > on mips ?
I have a WIP patch for this but was holding back mostly because of stage3/4 and that I was trying to make FRAME_GROWS_DOWNWARD the default and I was running into performance issues. The patch below enables FRAME_GROWS_DOWNWARD with -mframe-grows-downward (mostly for testing) and with -fstack-protector. Adam Index: config/mips/mips.opt =================================================================== --- config/mips/mips.opt (revision 142249) +++ config/mips/mips.opt (working copy) @@ -283,3 +283,6 @@ Perform VR4130-specific alignment optimi mxgot Target Report Var(TARGET_XGOT) Lift restrictions on GOT size + +mframe-grows-downward +Target Var(flag_frame_grows_downward) Init(1) Index: config/mips/mips.c =================================================================== --- config/mips/mips.c (revision 142249) +++ config/mips/mips.c (working copy) @@ -274,10 +274,10 @@ struct mips_frame_info GTY(()) { HOST_WIDE_INT gp_sp_offset; HOST_WIDE_INT fp_sp_offset; - /* The offset of arg_pointer_rtx from frame_pointer_rtx. */ + /* The offset of arg_pointer_rtx from the bottom of the frame. */ HOST_WIDE_INT arg_pointer_offset; - /* The offset of hard_frame_pointer_rtx from frame_pointer_rtx. */ + /* The offset of hard_frame_pointer_rtx from the bottom of the frame. */ HOST_WIDE_INT hard_frame_pointer_offset; }; @@ -8593,10 +8593,9 @@ mips_compute_frame_info (void) cfun->machine->global_pointer = mips_global_pointer (); - /* The first STARTING_FRAME_OFFSET bytes contain the outgoing argument - area and the $gp save slot. This area isn't needed in leaf functions, - but if the target-independent frame size is nonzero, we're committed - to allocating it anyway. */ + /* The first bytes contain the outgoing argument area and the $gp save slot. + This area isn't needed in leaf functions, but if the target-independent + frame size is nonzero, we're committed to allocating it anyway. */ if (size == 0 && current_function_is_leaf) { /* The MIPS 3.0 linker does not like functions that dynamically @@ -8612,7 +8611,7 @@ mips_compute_frame_info (void) else { frame->args_size = crtl->outgoing_args_size; - frame->cprestore_size = STARTING_FRAME_OFFSET - frame->args_size; + frame->cprestore_size = MIPS_GP_SAVE_AREA_SIZE; } offset = frame->args_size + frame->cprestore_size; @@ -8746,12 +8745,16 @@ mips_initial_elimination_offset (int fro mips_compute_frame_info (); - /* Set OFFSET to the offset from the soft frame pointer, which is also - the offset from the end-of-prologue stack pointer. */ + /* Set OFFSET to the offset from the end-of-prologue stack pointer. */ switch (from) { case FRAME_POINTER_REGNUM: - offset = 0; + if (FRAME_GROWS_DOWNWARD) + offset = (cfun->machine->frame.args_size + + cfun->machine->frame.cprestore_size + + cfun->machine->frame.var_size); + else + offset = 0; break; case ARG_POINTER_REGNUM: Index: config/mips/mips.h =================================================================== --- config/mips/mips.h (revision 142249) +++ config/mips/mips.h (working copy) @@ -2035,14 +2035,20 @@ enum reg_class /* Stack layout; function entry, exit and calling. */ +#define FRAME_GROWS_DOWNWARD (flag_frame_grows_downward || flag_stack_protect) + #define STACK_GROWS_DOWNWARD -/* The offset of the first local variable from the beginning of the frame. - See mips_compute_frame_info for details about the frame layout. */ +#define MIPS_GP_SAVE_AREA_SIZE \ + (TARGET_CALL_CLOBBERED_GP ? MIPS_STACK_ALIGN (UNITS_PER_WORD) : 0) + +/* The offset of the first local variable from the frame pointer. See + mips_compute_frame_info for details about the frame layout. */ -#define STARTING_FRAME_OFFSET \ - (crtl->outgoing_args_size \ - + (TARGET_CALL_CLOBBERED_GP ? MIPS_STACK_ALIGN (UNITS_PER_WORD) : 0)) +#define STARTING_FRAME_OFFSET \ + (FRAME_GROWS_DOWNWARD \ + ? 0 \ + : crtl->outgoing_args_size + MIPS_GP_SAVE_AREA_SIZE) #define RETURN_ADDR_RTX mips_return_addr