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]

Fix x86-64 epilogues wrt very large stack frames


Hi,
Zdenek is working on testsuite for dealing with 64bit data sizes.  One
problem he caught is that things get truncated in epilogue sequences.
I've bootstrapped/regtested the patch on x86-64-linux and
i386-pc-gnu-linux and will commit it.

Honza

2003-11-30  Jan Hubicka  <jh@suse.cz>
	* i386.c (ix86_emit_restore_regs_using_mov):  Deal with large offsets.
	(pro_epilogue_adjust_stack):  Update comment.
Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.490.2.56
diff -c -3 -p -r1.490.2.56 config/i386/i386.c
*** i386.c	24 Nov 2003 00:26:01 -0000	1.490.2.56
--- i386.c	29 Nov 2003 19:48:42 -0000
*************** static int ix86_split_to_parts PARAMS ((
*** 812,818 ****
  static int ix86_nsaved_regs PARAMS ((void));
  static void ix86_emit_save_regs PARAMS ((void));
  static void ix86_emit_save_regs_using_mov PARAMS ((rtx, HOST_WIDE_INT));
! static void ix86_emit_restore_regs_using_mov PARAMS ((rtx, int, int));
  static void ix86_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
  static void ix86_set_move_mem_attrs_1 PARAMS ((rtx, rtx, rtx, rtx, rtx));
  static void ix86_sched_reorder_ppro PARAMS ((rtx *, rtx *));
--- 812,818 ----
  static int ix86_nsaved_regs PARAMS ((void));
  static void ix86_emit_save_regs PARAMS ((void));
  static void ix86_emit_save_regs_using_mov PARAMS ((rtx, HOST_WIDE_INT));
! static void ix86_emit_restore_regs_using_mov PARAMS ((rtx, HOST_WIDE_INT, int));
  static void ix86_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
  static void ix86_set_move_mem_attrs_1 PARAMS ((rtx, rtx, rtx, rtx, rtx));
  static void ix86_sched_reorder_ppro PARAMS ((rtx *, rtx *));
*************** pro_epilogue_adjust_stack (rtx dest, rtx
*** 5095,5101 ****
        /* r11 is used by indirect sibcall return as well, set before the
  	 epilogue and used after the epilogue.  ATM indirect sibcall
  	 shouldn't be used together with huge frame sizes in one
! 	 function because of the frame_size check in sibcall.c.  */
        if (style == 0)
  	abort ();
        r11 = gen_rtx_REG (DImode, FIRST_REX_INT_REG + 3 /* R11 */);
--- 5095,5104 ----
        /* r11 is used by indirect sibcall return as well, set before the
  	 epilogue and used after the epilogue.  ATM indirect sibcall
  	 shouldn't be used together with huge frame sizes in one
! 	 function because of the frame_size check in sibcall.c. 
! 
! 	 Similar assumption is also made by ix86_emit_restore_regs_using_mov.
! 	 */
        if (style == 0)
  	abort ();
        r11 = gen_rtx_REG (DImode, FIRST_REX_INT_REG + 3 /* R11 */);
*************** ix86_expand_prologue (void)
*** 5242,5257 ****
  static void
  ix86_emit_restore_regs_using_mov (pointer, offset, maybe_eh_return)
       rtx pointer;
!      int offset;
       int maybe_eh_return;
  {
    int regno;
  
    for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
      if (ix86_save_reg (regno, maybe_eh_return))
        {
  	emit_move_insn (gen_rtx_REG (Pmode, regno),
! 			adjust_address (gen_rtx_MEM (Pmode, pointer),
  					Pmode, offset));
  	offset += UNITS_PER_WORD;
        }
--- 5245,5273 ----
  static void
  ix86_emit_restore_regs_using_mov (pointer, offset, maybe_eh_return)
       rtx pointer;
!      HOST_WIDE_INT offset;
       int maybe_eh_return;
  {
    int regno;
+   rtx base_address = gen_rtx_MEM (Pmode, pointer);
  
    for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
      if (ix86_save_reg (regno, maybe_eh_return))
        {
+ 	/* Ensure that adjust_address won't be forced to produce pointer
+ 	   out of range allowed by x86-64 instruction set.  */
+ 	if (TARGET_64BIT && offset != (int)offset)
+ 	  {
+ 	    rtx r11;
+ 
+ 	    r11 = gen_rtx_REG (DImode, FIRST_REX_INT_REG + 3 /* R11 */);
+ 	    emit_move_insn (r11, GEN_INT (offset));
+ 	    emit_insn (gen_adddi3 (r11, r11, pointer));
+ 	    base_address = gen_rtx_MEM (Pmode, r11);
+ 	    offset = 0;
+ 	  }
  	emit_move_insn (gen_rtx_REG (Pmode, regno),
! 			adjust_address (base_address,
  					Pmode, offset));
  	offset += UNITS_PER_WORD;
        }


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