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
 

Reply via email to