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]

[MIPS 6/50] Rewrite compute_frame_size


Another of the more crufty parts of the port is compute_frame_size.
I'd always found this one of the hardest functions to follow.

One of the problems is that it works out lots of stuff from the bottom
of the frame, rather than keeping a running count.  This function rewrites
it into a form that IMO is clearer.  This new form allows all register
save areas to be padded downward; we need this for MIPS16e SAVE and
RESTORE instructions, and don't care either way otherwise.  If anything,
downward padding is better, because the address of the $31 save slot is
then more predictable, although still not fully predictable.

I reluctantly kept the "MIPS 3 linker" comment.  I'm not quite sure what
"doesn't like" means -- wrong code, wrong debug info, error? -- but I'm
also unsure if other tools also rely on this.  (The o32 IRIX linker might.)

Also, the frame diagram was too o32-centric and missed out stuff used
for other ABIs.  The comments next to the mips_frame_info fields were
sometimes a little terse.

Finally, there was some lingering code to handle rtl profiling,
where a libcall could be added after STARTING_FRAME_OFFSET had
been calculated.  Jim said when he committed this patch
(for PR target/16325) that it could be reverted once we do the
profiling at the tree level.  That happy day has arrived.

Richard


gcc/
	* config/mips/mips.h (STARTING_FRAME_OFFSET): Remove rtl
	profiling code.
	* config/mips/mips.c (mips_frame_info): Give num_gp and num_fp type
	"unsigned int" rather than "int" and put them with the other
	register-related fields.  Put expanded comments above fields
	rather than to their right.
	(mips16e_mask_registers): Replace the GP_REG_SIZE_PTR argument
	with a NUM_REGS_PTR argument.
	(mips16e_save_restore_pattern_p): Update accordingly.
	(compute_frame_size): Clarify frame diagram.  Rewrite.

Index: gcc/config/mips/mips.h
===================================================================
*** gcc/config/mips/mips.h	2007-10-18 20:20:14.000000000 +0100
--- gcc/config/mips/mips.h	2007-10-18 20:20:15.000000000 +0100
*************** #define CANNOT_CHANGE_MODE_CLASS(FROM, T
*** 1885,1905 ****
  #define STACK_GROWS_DOWNWARD
  
  /* The offset of the first local variable from the beginning of the frame.
!    See compute_frame_size for details about the frame layout.
! 
!    ??? If flag_profile_values is true, and we are generating 32-bit code, then
!    we assume that we will need 16 bytes of argument space.  This is because
!    the value profiling code may emit calls to cmpdi2 in leaf functions.
!    Without this hack, the local variables will start at sp+8 and the gp save
!    area will be at sp+16, and thus they will overlap.  compute_frame_size is
!    OK because it uses STARTING_FRAME_OFFSET to compute cprestore_size, which
!    will end up as 24 instead of 8.  This won't be needed if profiling code is
!    inserted before virtual register instantiation.  */
  
  #define STARTING_FRAME_OFFSET						\
!   ((flag_profile_values && ! TARGET_64BIT				\
!     ? MAX (REG_PARM_STACK_SPACE(NULL), current_function_outgoing_args_size) \
!     : current_function_outgoing_args_size)				\
     + (TARGET_CALL_CLOBBERED_GP ? MIPS_STACK_ALIGN (UNITS_PER_WORD) : 0))
  
  #define RETURN_ADDR_RTX mips_return_addr
--- 1885,1894 ----
  #define STACK_GROWS_DOWNWARD
  
  /* The offset of the first local variable from the beginning of the frame.
!    See compute_frame_size for details about the frame layout.  */
  
  #define STARTING_FRAME_OFFSET						\
!   (current_function_outgoing_args_size					\
     + (TARGET_CALL_CLOBBERED_GP ? MIPS_STACK_ALIGN (UNITS_PER_WORD) : 0))
  
  #define RETURN_ADDR_RTX mips_return_addr
Index: gcc/config/mips/mips.c
===================================================================
*** gcc/config/mips/mips.c	2007-10-18 20:20:14.000000000 +0100
--- gcc/config/mips/mips.c	2007-10-18 20:20:26.000000000 +0100
*************** static const char *const mips_fp_conditi
*** 239,259 ****
  
  struct mips_frame_info GTY(())
  {
!   HOST_WIDE_INT total_size;	/* # bytes that the entire frame takes up */
!   HOST_WIDE_INT var_size;	/* # bytes that variables take up */
!   HOST_WIDE_INT args_size;	/* # bytes that outgoing arguments take up */
!   HOST_WIDE_INT cprestore_size;	/* # bytes that the .cprestore slot takes up */
!   HOST_WIDE_INT gp_reg_size;	/* # bytes needed to store gp regs */
!   HOST_WIDE_INT fp_reg_size;	/* # bytes needed to store fp regs */
!   unsigned int mask;		/* mask of saved gp registers */
!   unsigned int fmask;		/* mask of saved fp registers */
!   HOST_WIDE_INT gp_save_offset;	/* offset from vfp to store gp registers */
!   HOST_WIDE_INT fp_save_offset;	/* offset from vfp to store fp registers */
!   HOST_WIDE_INT gp_sp_offset;	/* offset from new sp to store gp registers */
!   HOST_WIDE_INT fp_sp_offset;	/* offset from new sp to store fp registers */
!   bool initialized;		/* true if frame size already calculated */
!   int num_gp;			/* number of gp registers saved */
!   int num_fp;			/* number of fp registers saved */
  };
  
  struct machine_function GTY(()) {
--- 239,282 ----
  
  struct mips_frame_info GTY(())
  {
!   /* The size of the frame in bytes.  */
!   HOST_WIDE_INT total_size;
! 
!   /* The number of bytes allocated to variables.  */
!   HOST_WIDE_INT var_size;
! 
!   /* The number of bytes allocated to outgoing function arguments.  */
!   HOST_WIDE_INT args_size;
! 
!   /* The number of bytes allocated to the .cprestore slot, or 0 if there
!      is no such slot.  */
!   HOST_WIDE_INT cprestore_size;
! 
!   /* The size in bytes of the GPR and FPR save areas.  */
!   HOST_WIDE_INT gp_reg_size;
!   HOST_WIDE_INT fp_reg_size;
! 
!   /* Bit X is set if the function saves or restores GPR X.  */
!   unsigned int mask;
! 
!   /* Likewise FPR X.  */
!   unsigned int fmask;
! 
!   /* The number of GPRs and FPRs saved.  */
!   unsigned int num_gp;
!   unsigned int num_fp;
! 
!   /* The offset of the topmost GPR and FPR save slots from the top of
!      the frame, or zero if no such slots are needed.  */
!   HOST_WIDE_INT gp_save_offset;
!   HOST_WIDE_INT fp_save_offset;
! 
!   /* Likewise, but giving offsets from the bottom of the frame.  */
!   HOST_WIDE_INT gp_sp_offset;
!   HOST_WIDE_INT fp_sp_offset;
! 
!   /* True if this structure has been initialized after reload.  */
!   bool initialized;
  };
  
  struct machine_function GTY(()) {
*************** mips16e_find_first_register (unsigned in
*** 7249,7262 ****
    return i;
  }
  
! /* *MASK_PTR is a mask of general purpose registers and *GP_REG_SIZE_PTR
!    is the number of bytes that they occupy.  If *MASK_PTR contains REGS[X]
!    for some X in [0, SIZE), adjust *MASK_PTR and *GP_REG_SIZE_PTR so that
!    the same is true for all indexes (X, SIZE).  */
  
  static void
  mips16e_mask_registers (unsigned int *mask_ptr, const unsigned char *regs,
! 			unsigned int size, HOST_WIDE_INT *gp_reg_size_ptr)
  {
    unsigned int i;
  
--- 7272,7285 ----
    return i;
  }
  
! /* *MASK_PTR is a mask of general-purpose registers and *NUM_REGS_PTR
!    is the number of set bits.  If *MASK_PTR contains REGS[X] for some X
!    in [0, SIZE), adjust *MASK_PTR and *NUM_REGS_PTR so that the same
!    is true for all indexes (X, SIZE).  */
  
  static void
  mips16e_mask_registers (unsigned int *mask_ptr, const unsigned char *regs,
! 			unsigned int size, unsigned int *num_regs_ptr)
  {
    unsigned int i;
  
*************** mips16e_mask_registers (unsigned int *ma
*** 7264,7270 ****
    for (i++; i < size; i++)
      if (!BITSET_P (*mask_ptr, regs[i]))
        {
! 	*gp_reg_size_ptr += GET_MODE_SIZE (gpr_mode);
  	*mask_ptr |= 1 << regs[i];
        }
  }
--- 7287,7293 ----
    for (i++; i < size; i++)
      if (!BITSET_P (*mask_ptr, regs[i]))
        {
! 	*num_regs_ptr += 1;
  	*mask_ptr |= 1 << regs[i];
        }
  }
*************** mips16e_build_save_restore (bool restore
*** 7507,7514 ****
  mips16e_save_restore_pattern_p (rtx pattern, HOST_WIDE_INT adjust,
  				struct mips16e_save_restore_info *info)
  {
!   unsigned int i, nargs, mask;
!   HOST_WIDE_INT top_offset, save_offset, offset, extra;
    rtx set, reg, mem, base;
    int n;
  
--- 7530,7537 ----
  mips16e_save_restore_pattern_p (rtx pattern, HOST_WIDE_INT adjust,
  				struct mips16e_save_restore_info *info)
  {
!   unsigned int i, nargs, mask, extra;
!   HOST_WIDE_INT top_offset, save_offset, offset;
    rtx set, reg, mem, base;
    int n;
  
*************** mips_save_reg_p (unsigned int regno)
*** 7816,8018 ****
  
     MIPS stack frames look like:
  
!              Before call		        After call
!    high +-----------------------+	+-----------------------+
!    mem. |			|       |      			|
! 	|  caller's temps.    	|       |  caller's temps.    	|
! 	|       		|       |       	        |
!         +-----------------------+	+-----------------------+
!  	|       		|	|		        |
!         |  arguments on stack.  |	|  arguments on stack.  |
! 	|       		|	|			|
!         +-----------------------+	+-----------------------+
!  	|  4 words to save     	|	|  4 words to save	|
! 	|  arguments passed	|	|  arguments passed	|
! 	|  in registers, even	|	|  in registers, even	|
!         |  if not passed.       |       |  if not passed.	|
!     SP->+-----------------------+  VFP->+-----------------------+
! 	        (VFP = SP+fp_sp_offset) |		        |\
! 					|  fp register save     | | fp_reg_size
! 					|			|/
! 		       SP+gp_sp_offset->+-----------------------+
! 				       /|		        |\
! 				      | |  gp register save     | | gp_reg_size
! 		       gp_reg_rounded | |       		|/
! 				      |	+-----------------------+
! 				       \|  alignment padding    |
! 					+-----------------------+
! 					|		        |\
! 					|  local variables	| | var_size
! 					|			|/
! 					+-----------------------+
! 					|			|
! 					|  alloca allocations   |
! 					|			|
! 					+-----------------------+
! 				       /|			|
! 		       cprestore_size | |  GP save for V.4 abi	|
! 				       \|			|
! 					+-----------------------+
! 					|			|\
! 					|  arguments on stack   | |
! 					|		        | |
! 					+-----------------------+ |
! 					|  4 words to save      | | args_size
! 					|  arguments passed     | |
! 					|  in registers, even   | |
! 					|  if not passed.       | |
!    low					|  (TARGET_OLDABI only) |/
!    memory			    SP->+-----------------------+
! 
! */
  
  HOST_WIDE_INT
  compute_frame_size (HOST_WIDE_INT size)
  {
!   unsigned int regno;
!   HOST_WIDE_INT total_size;	/* # bytes that the entire frame takes up */
!   HOST_WIDE_INT var_size;	/* # bytes that variables take up */
!   HOST_WIDE_INT args_size;	/* # bytes that outgoing arguments take up */
!   HOST_WIDE_INT cprestore_size; /* # bytes that the cprestore slot takes up */
!   HOST_WIDE_INT gp_reg_rounded;	/* # bytes needed to store gp after rounding */
!   HOST_WIDE_INT gp_reg_size;	/* # bytes needed to store gp regs */
!   HOST_WIDE_INT fp_reg_size;	/* # bytes needed to store fp regs */
!   unsigned int mask;		/* mask of saved gp registers */
!   unsigned int fmask;		/* mask of saved fp registers */
  
!   cfun->machine->global_pointer = mips_global_pointer ();
  
!   gp_reg_size = 0;
!   fp_reg_size = 0;
!   mask = 0;
!   fmask	= 0;
!   var_size = MIPS_STACK_ALIGN (size);
!   args_size = current_function_outgoing_args_size;
!   cprestore_size = MIPS_STACK_ALIGN (STARTING_FRAME_OFFSET) - args_size;
! 
!   /* The space set aside by STARTING_FRAME_OFFSET isn't needed in leaf
!      functions.  If the function has local variables, we're committed
!      to allocating it anyway.  Otherwise reclaim it here.  */
!   if (var_size == 0 && current_function_is_leaf)
!     cprestore_size = args_size = 0;
! 
!   /* The MIPS 3.0 linker does not like functions that dynamically
!      allocate the stack and have 0 for STACK_DYNAMIC_OFFSET, since it
!      looks like we are trying to create a second frame pointer to the
!      function, so allocate some stack space to make it happy.  */
  
!   if (args_size == 0 && current_function_calls_alloca)
!     args_size = 4 * UNITS_PER_WORD;
  
!   total_size = var_size + args_size + cprestore_size;
  
!   /* Calculate space needed for gp registers.  */
    for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
      if (mips_save_reg_p (regno))
        {
! 	gp_reg_size += GET_MODE_SIZE (gpr_mode);
! 	mask |= 1 << (regno - GP_REG_FIRST);
        }
  
!   /* We need to restore these for the handler.  */
    if (current_function_calls_eh_return)
!     {
!       unsigned int i;
!       for (i = 0; ; ++i)
! 	{
! 	  regno = EH_RETURN_DATA_REGNO (i);
! 	  if (regno == INVALID_REGNUM)
! 	    break;
! 	  gp_reg_size += GET_MODE_SIZE (gpr_mode);
! 	  mask |= 1 << (regno - GP_REG_FIRST);
! 	}
!     }
  
    /* The MIPS16e SAVE and RESTORE instructions have two ranges of registers:
       $a3-$a0 and $s2-$s8.  If we save one register in the range, we must
       save all later registers too.  */
    if (GENERATE_MIPS16E_SAVE_RESTORE)
      {
!       mips16e_mask_registers (&mask, mips16e_s2_s8_regs,
!  			      ARRAY_SIZE (mips16e_s2_s8_regs), &gp_reg_size);
!       mips16e_mask_registers (&mask, mips16e_a0_a3_regs,
!  			      ARRAY_SIZE (mips16e_a0_a3_regs), &gp_reg_size);
      }
  
!   /* This loop must iterate over the same space as its companion in
!      mips_for_each_saved_reg.  */
    if (TARGET_HARD_FLOAT)
!     for (regno = (FP_REG_LAST - MAX_FPRS_PER_FMT + 1);
! 	 regno >= FP_REG_FIRST;
! 	 regno -= MAX_FPRS_PER_FMT)
        if (mips_save_reg_p (regno))
  	{
! 	  fp_reg_size += MAX_FPRS_PER_FMT * UNITS_PER_FPREG;
! 	  fmask |= ((1 << MAX_FPRS_PER_FMT) - 1) << (regno - FP_REG_FIRST);
  	}
  
!   gp_reg_rounded = MIPS_STACK_ALIGN (gp_reg_size);
!   total_size += gp_reg_rounded + MIPS_STACK_ALIGN (fp_reg_size);
! 
!   /* Add in the space required for saving incoming register arguments.  */
!   total_size += current_function_pretend_args_size;
!   total_size += MIPS_STACK_ALIGN (cfun->machine->varargs_size);
! 
!   /* Save other computed information.  */
!   cfun->machine->frame.total_size = total_size;
!   cfun->machine->frame.var_size = var_size;
!   cfun->machine->frame.args_size = args_size;
!   cfun->machine->frame.cprestore_size = cprestore_size;
!   cfun->machine->frame.gp_reg_size = gp_reg_size;
!   cfun->machine->frame.fp_reg_size = fp_reg_size;
!   cfun->machine->frame.mask = mask;
!   cfun->machine->frame.fmask = fmask;
!   cfun->machine->frame.initialized = reload_completed;
!   cfun->machine->frame.num_gp = gp_reg_size / UNITS_PER_WORD;
!   cfun->machine->frame.num_fp = (fp_reg_size
! 				 / (MAX_FPRS_PER_FMT * UNITS_PER_FPREG));
! 
!   if (mask)
!     {
!       HOST_WIDE_INT offset;
! 
!       if (GENERATE_MIPS16E_SAVE_RESTORE)
! 	/* MIPS16e SAVE and RESTORE instructions require the GP save area
! 	   to be aligned at the high end with any padding at the low end.
! 	   It is only safe to use this calculation for o32, where we never
! 	   have pretend arguments, and where any varargs will be saved in
! 	   the caller-allocated area rather than at the top of the frame.  */
! 	offset = (total_size - GET_MODE_SIZE (gpr_mode));
!       else
! 	offset = (args_size + cprestore_size + var_size
! 		  + gp_reg_size - GET_MODE_SIZE (gpr_mode));
!       cfun->machine->frame.gp_sp_offset = offset;
!       cfun->machine->frame.gp_save_offset = offset - total_size;
!     }
!   else
      {
!       cfun->machine->frame.gp_sp_offset = 0;
!       cfun->machine->frame.gp_save_offset = 0;
      }
  
!   if (fmask)
!     {
!       HOST_WIDE_INT offset;
  
!       offset = (args_size + cprestore_size + var_size
! 		+ gp_reg_rounded + fp_reg_size
! 		- MAX_FPRS_PER_FMT * UNITS_PER_FPREG);
!       cfun->machine->frame.fp_sp_offset = offset;
!       cfun->machine->frame.fp_save_offset = offset - total_size;
!     }
!   else
!     {
!       cfun->machine->frame.fp_sp_offset = 0;
!       cfun->machine->frame.fp_save_offset = 0;
!     }
  
!   /* Ok, we're done.  */
!   return total_size;
  }
  
  /* Return the style of GP load sequence that is being used for the
--- 7839,8009 ----
  
     MIPS stack frames look like:
  
! 	+-------------------------------+
! 	|                               |
! 	|  incoming stack arguments     |
! 	|                               |
! 	+-------------------------------+
! 	|                               |
! 	|  caller-allocated save area   |
!       A |  for register arguments       |
! 	|                               |
! 	+-------------------------------+ <-- incoming stack pointer
! 	|                               |
! 	|  callee-allocated save area   |
!       B |  for arguments that are       |
! 	|  split between registers and  |
! 	|  the stack                    |
! 	|                               |
! 	+-------------------------------+ <-- arg_pointer_rtx
! 	|                               |
!       C |  callee-allocated save area   |
! 	|  for register varargs         |
! 	|                               |
! 	+-------------------------------+ <-- frame_pointer_rtx + fp_sp_offset
! 	|                               |       + UNITS_PER_HWFPVALUE
! 	|  FPR save area                |
! 	|                               |
! 	+-------------------------------+ <-- frame_pointer_rtx + gp_sp_offset
! 	|                               |       + UNITS_PER_WORD
! 	|  GPR save area                |
! 	|                               |
! 	+-------------------------------+
! 	|                               | \
! 	|  local variables              |  | var_size
! 	|                               | /
! 	+-------------------------------+
! 	|                               | \
! 	|  $gp save area                |  | cprestore_size
! 	|                               | /
!       P +-------------------------------+ <-- hard_frame_pointer_rtx for
! 	|                               |       MIPS16 code
! 	|  outgoing stack arguments     |
! 	|                               |
! 	+-------------------------------+
! 	|                               |
! 	|  caller-allocated save area   |
! 	|  for register arguments       |
! 	|                               |
! 	+-------------------------------+ <-- stack_pointer_rtx
! 					      frame_pointer_rtx
! 					      hard_frame_pointer_rtx for
! 						non-MIPS16 code.
! 
!    At least two of A, B and C will be empty.
! 
!    Dynamic stack allocations such as alloca insert data at point P.
!    They decrease stack_pointer_rtx but leave frame_pointer_rtx and
!    hard_frame_pointer_rtx unchanged.  */
  
  HOST_WIDE_INT
  compute_frame_size (HOST_WIDE_INT size)
  {
!   struct mips_frame_info *frame;
!   HOST_WIDE_INT offset;
!   unsigned int regno, i;
  
!   frame = &cfun->machine->frame;
!   memset (frame, 0, sizeof (*frame));
  
!   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.  */
!   if (size == 0 && current_function_is_leaf)
!     {
!       /* The MIPS 3.0 linker does not like functions that dynamically
! 	 allocate the stack and have 0 for STACK_DYNAMIC_OFFSET, since it
! 	 looks like we are trying to create a second frame pointer to the
! 	 function, so allocate some stack space to make it happy.  */
!       if (current_function_calls_alloca)
! 	frame->args_size = REG_PARM_STACK_SPACE (cfun->decl);
!       else
! 	frame->args_size = 0;
!       frame->cprestore_size = 0;
!     }
!   else
!     {
!       frame->args_size = current_function_outgoing_args_size;
!       frame->cprestore_size = STARTING_FRAME_OFFSET - frame->args_size;
!     }
!   offset = frame->args_size + frame->cprestore_size;
  
!   /* Move above the local variables.  */
!   frame->var_size = MIPS_STACK_ALIGN (size);
!   offset += frame->var_size;
  
!   /* Find out which GPRs we need to save.  */
    for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
      if (mips_save_reg_p (regno))
        {
! 	frame->num_gp++;
! 	frame->mask |= 1 << (regno - GP_REG_FIRST);
        }
  
!   /* If this function calls eh_return, we must also save and restore the
!      EH data registers.  */
    if (current_function_calls_eh_return)
!     for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; i++)
!       {
! 	frame->num_gp++;
! 	frame->mask |= 1 << (EH_RETURN_DATA_REGNO (i) - GP_REG_FIRST);
!       }
  
    /* The MIPS16e SAVE and RESTORE instructions have two ranges of registers:
       $a3-$a0 and $s2-$s8.  If we save one register in the range, we must
       save all later registers too.  */
    if (GENERATE_MIPS16E_SAVE_RESTORE)
      {
!       mips16e_mask_registers (&frame->mask, mips16e_s2_s8_regs,
!  			      ARRAY_SIZE (mips16e_s2_s8_regs), &frame->num_gp);
!       mips16e_mask_registers (&frame->mask, mips16e_a0_a3_regs,
!  			      ARRAY_SIZE (mips16e_a0_a3_regs), &frame->num_gp);
      }
  
!   /* Move above the GPR save area.  */
!   if (frame->num_gp > 0)
!     {
!       frame->gp_reg_size = frame->num_gp * UNITS_PER_WORD;
!       offset += MIPS_STACK_ALIGN (frame->gp_reg_size);
!       frame->gp_sp_offset = offset - UNITS_PER_WORD;
!     }
! 
!   /* Find out which FPRs we need to save.  This loop must iterate over
!      the same space as its companion in mips_for_each_saved_reg.  */
    if (TARGET_HARD_FLOAT)
!     for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno += MAX_FPRS_PER_FMT)
        if (mips_save_reg_p (regno))
  	{
! 	  frame->num_fp += MAX_FPRS_PER_FMT;
! 	  frame->fmask |= ~(~0 << MAX_FPRS_PER_FMT) << (regno - FP_REG_FIRST);
  	}
  
!   /* Move above the FPR save area.  */
!   if (frame->num_fp > 0)
      {
!       frame->fp_reg_size = frame->num_fp * UNITS_PER_FPREG;
!       offset += MIPS_STACK_ALIGN (frame->fp_reg_size);
!       frame->fp_sp_offset = offset - UNITS_PER_HWFPVALUE;
      }
  
!   /* Move above the callee-allocated varargs save area.  */
!   offset += MIPS_STACK_ALIGN (cfun->machine->varargs_size);
  
!   /* Move above the callee-allocated area for pretend stack arguments.  */
!   offset += current_function_pretend_args_size;
!   frame->total_size = offset;
! 
!   /* Work out the offsets of the save areas from the top of the frame.  */
!   if (frame->gp_sp_offset > 0)
!     frame->gp_save_offset = frame->gp_sp_offset - offset;
!   if (frame->fp_sp_offset > 0)
!     frame->fp_save_offset = frame->fp_sp_offset - offset;
  
!   frame->initialized = reload_completed;
!   return frame->total_size;
  }
  
  /* Return the style of GP load sequence that is being used for the


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