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]

[PATCH] s390: virtual register return_address_pointer


Hello,

the included patch introduces a return_address_pointer as a virtual
register eliminable with stack pointer or hard frame pointer. Except from
simplifying EH_RETURN_HANDLER_RTX and RETURN_ADDR_RTX there
cannot be seen big advantages in doing so. The patch is actually intended to
ease bigger changes in the stack frame layout of the s390 backend.
Separating this patch makes (hopefully) the following patch much less complex
and easier to debug.

Bootstrapped and regtested on s390 and s390x.

OK?

-Andreas-

2004-07-19  Andreas Krebbel  <krebbel1@de.ibm.com>

	* config/s390/s390-protos.h (s390_return_address_offset): Prototype
	added.
	* config/s390/s390.c (regclass_map initializer): Register 35 added to
	ADDR_REGS.
	(load_multiple_operation, store_multiple_operation, 
	s390_decompose_address): Added checks for return_address_pointer_rtx.
	(s390_return_addr_rtx): Use return_address_pointer_rtx for count == 0.
	(s390_return_address_offset): New function.
	* config/s390/s390.h (FIRST_PSEUDO_REGISTER): Increased to 36.
	(FRAME_REGNO_P): Added check for register 35.
	(FIXED_REGISTERS, CALL_USED_REGISTERS, CALL_REALLY_USED_REGISTERS,
	REG_ALLOC_ORDER): Appended entry for register 35.
	(REG_CLASS_CONTENTS): Adjusted class masks for register 35.
	(EH_RETURN_HANDLER_RTX): Use return_address_pointer_rtx.
	(RETURN_ADDRESS_POINTER_REGNUM): New macro.
	(ELIMINABLE_REGS, INITIAL_ELIMINATION_OFFSET): Return address pointer
	is eliminable using stack pointer or hard frame pointer.
	(REGISTER_NAMES): Added name for register 35.


Index: config/s390/s390-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390-protos.h,v
retrieving revision 1.52
diff -p -c -r1.52 s390-protos.h
*** config/s390/s390-protos.h	14 Jul 2004 06:24:22 -0000	1.52
--- config/s390/s390-protos.h	16 Jul 2004 13:53:55 -0000
*************** Software Foundation, 59 Temple Place - S
*** 24,29 ****
--- 24,30 ----
  extern void optimization_options (int, int);
  extern void override_options (void);
  extern HOST_WIDE_INT s390_arg_frame_offset (void);
+ extern HOST_WIDE_INT s390_return_address_offset (void);
  extern void s390_emit_prologue (void);
  extern void s390_emit_epilogue (bool);
  extern void s390_function_profiler (FILE *, int);
Index: config/s390/s390.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.c,v
retrieving revision 1.161
diff -p -c -r1.161 s390.c
*** config/s390/s390.c	16 Jul 2004 12:51:20 -0000	1.161
--- config/s390/s390.c	16 Jul 2004 13:53:56 -0000
*************** const enum reg_class regclass_map[FIRST_
*** 1038,1044 ****
    FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
    FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
    FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
!   ADDR_REGS,    NO_REGS,   ADDR_REGS
  };
  
  /* Return attribute type of insn.  */
--- 1038,1044 ----
    FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
    FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
    FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
!   ADDR_REGS,    NO_REGS,   ADDR_REGS, ADDR_REGS
  };
  
  /* Return attribute type of insn.  */
*************** load_multiple_operation (rtx op, enum ma
*** 1613,1619 ****
    else
      return 0;
  
!   if (src_addr == frame_pointer_rtx || src_addr == arg_pointer_rtx)
      return 0;
  
    for (i = 1; i < count; i++)
--- 1613,1621 ----
    else
      return 0;
  
!   if (src_addr == frame_pointer_rtx 
!       || src_addr == arg_pointer_rtx
!       || src_addr == return_address_pointer_rtx)
      return 0;
  
    for (i = 1; i < count; i++)
*************** store_multiple_operation (rtx op, enum m
*** 1676,1682 ****
    else
      return 0;
  
!   if (dest_addr == frame_pointer_rtx || dest_addr == arg_pointer_rtx)
      return 0;
  
    for (i = 1; i < count; i++)
--- 1678,1686 ----
    else
      return 0;
  
!   if (dest_addr == frame_pointer_rtx 
!       || dest_addr == arg_pointer_rtx
!       || dest_addr == return_address_pointer_rtx)
      return 0;
  
    for (i = 1; i < count; i++)
*************** s390_decompose_address (register rtx add
*** 2266,2272 ****
  	 Thus we don't check the displacement for validity here.  If after
  	 elimination the displacement turns out to be invalid after all,
  	 this is fixed up by reload in any case.  */
!       if (base != arg_pointer_rtx && indx != arg_pointer_rtx)
  	if (!DISP_IN_RANGE (offset))
  	  return FALSE;
      }
--- 2270,2279 ----
  	 Thus we don't check the displacement for validity here.  If after
  	 elimination the displacement turns out to be invalid after all,
  	 this is fixed up by reload in any case.  */
!       if (base != arg_pointer_rtx 
! 	  && indx != arg_pointer_rtx 
! 	  && base != return_address_pointer_rtx 
! 	  && indx != return_address_pointer_rtx)
  	if (!DISP_IN_RANGE (offset))
  	  return FALSE;
      }
*************** s390_reorg (void)
*** 5499,5505 ****
     frame pointer of that frame.  */
  
  rtx
! s390_return_addr_rtx (int count, rtx frame)
  {
    rtx addr;
  
--- 5506,5512 ----
     frame pointer of that frame.  */
  
  rtx
! s390_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
  {
    rtx addr;
  
*************** s390_return_addr_rtx (int count, rtx fra
*** 5512,5521 ****
       value of RETURN_REGNUM is actually saved.  */
  
    if (count == 0)
!     cfun->machine->save_return_addr_p = true;
! 
!   /* To retrieve the return address we read the stack slot where the
!      corresponding RETURN_REGNUM value was saved.  */
  
    addr = plus_constant (frame, RETURN_REGNUM * UNITS_PER_WORD);
    addr = memory_address (Pmode, addr);
--- 5519,5528 ----
       value of RETURN_REGNUM is actually saved.  */
  
    if (count == 0)
!     {
!       cfun->machine->save_return_addr_p = true;
!       return gen_rtx_MEM (Pmode, return_address_pointer_rtx);
!     }
  
    addr = plus_constant (frame, RETURN_REGNUM * UNITS_PER_WORD);
    addr = memory_address (Pmode, addr);
*************** s390_arg_frame_offset (void)
*** 5642,5647 ****
--- 5649,5663 ----
    return cfun->machine->frame_size + STACK_POINTER_OFFSET;
  }
  
+ /* Return offset between return address pointer (location of r14
+    on the stack) and frame pointer initially after prologue.  */
+ 
+ HOST_WIDE_INT
+ s390_return_address_offset (void)
+ {
+   return cfun->machine->frame_size + RETURN_REGNUM * UNITS_PER_WORD;
+ }
+ 
  /* Emit insn to save fpr REGNUM at offset OFFSET relative
     to register BASE.  Return generated insn.  */
  
Index: config/s390/s390.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.h,v
retrieving revision 1.111
diff -p -c -r1.111 s390.h
*** config/s390/s390.h	16 Jul 2004 12:51:21 -0000	1.111
--- config/s390/s390.h	16 Jul 2004 13:53:57 -0000
*************** if (INTEGRAL_MODE_P (MODE) &&	        	 
*** 284,297 ****
     Reg 33: Condition code
     Reg 34: Frame pointer  */
  
! #define FIRST_PSEUDO_REGISTER 35
  
  /* Standard register usage.  */
  #define GENERAL_REGNO_P(N)	((int)(N) >= 0 && (N) < 16)
  #define ADDR_REGNO_P(N)		((N) >= 1 && (N) < 16)
  #define FP_REGNO_P(N)		((N) >= 16 && (N) < (TARGET_IEEE_FLOAT? 32 : 20))
  #define CC_REGNO_P(N)		((N) == 33)
! #define FRAME_REGNO_P(N)	((N) == 32 || (N) == 34)
  
  #define GENERAL_REG_P(X)	(REG_P (X) && GENERAL_REGNO_P (REGNO (X)))
  #define ADDR_REG_P(X)		(REG_P (X) && ADDR_REGNO_P (REGNO (X)))
--- 284,297 ----
     Reg 33: Condition code
     Reg 34: Frame pointer  */
  
! #define FIRST_PSEUDO_REGISTER 36
  
  /* Standard register usage.  */
  #define GENERAL_REGNO_P(N)	((int)(N) >= 0 && (N) < 16)
  #define ADDR_REGNO_P(N)		((N) >= 1 && (N) < 16)
  #define FP_REGNO_P(N)		((N) >= 16 && (N) < (TARGET_IEEE_FLOAT? 32 : 20))
  #define CC_REGNO_P(N)		((N) == 33)
! #define FRAME_REGNO_P(N)	((N) == 32 || (N) == 34 || (N) == 35)
  
  #define GENERAL_REG_P(X)	(REG_P (X) && GENERAL_REGNO_P (REGNO (X)))
  #define ADDR_REG_P(X)		(REG_P (X) && ADDR_REGNO_P (REGNO (X)))
*************** if (INTEGRAL_MODE_P (MODE) &&	        	 
*** 327,333 ****
    0, 0, 0, 0, 					\
    0, 0, 0, 0, 					\
    0, 0, 0, 0, 					\
!   1, 1, 1 }
  
  #define CALL_USED_REGISTERS			\
  { 1, 1, 1, 1, 					\
--- 327,333 ----
    0, 0, 0, 0, 					\
    0, 0, 0, 0, 					\
    0, 0, 0, 0, 					\
!   1, 1, 1, 1 }
  
  #define CALL_USED_REGISTERS			\
  { 1, 1, 1, 1, 					\
*************** if (INTEGRAL_MODE_P (MODE) &&	        	 
*** 338,344 ****
    1, 1, 1, 1, 					\
    1, 1, 1, 1, 					\
    1, 1, 1, 1, 					\
!   1, 1, 1 }
  
  #define CALL_REALLY_USED_REGISTERS		\
  { 1, 1, 1, 1, 					\
--- 338,344 ----
    1, 1, 1, 1, 					\
    1, 1, 1, 1, 					\
    1, 1, 1, 1, 					\
!   1, 1, 1, 1 }
  
  #define CALL_REALLY_USED_REGISTERS		\
  { 1, 1, 1, 1, 					\
*************** if (INTEGRAL_MODE_P (MODE) &&	        	 
*** 349,355 ****
    1, 1, 1, 1, 					\
    1, 1, 1, 1, 					\
    1, 1, 1, 1, 					\
!   1, 1, 1 }
  
  #define CONDITIONAL_REGISTER_USAGE s390_conditional_register_usage ()
  
--- 349,355 ----
    1, 1, 1, 1, 					\
    1, 1, 1, 1, 					\
    1, 1, 1, 1, 					\
!   1, 1, 1, 1 }
  
  #define CONDITIONAL_REGISTER_USAGE s390_conditional_register_usage ()
  
*************** if (INTEGRAL_MODE_P (MODE) &&	        	 
*** 358,364 ****
  {  1, 2, 3, 4, 5, 0, 13, 12, 11, 10, 9, 8, 7, 6, 14,            \
     16, 17, 18, 19, 20, 21, 22, 23,                              \
     24, 25, 26, 27, 28, 29, 30, 31,                              \
!    15, 32, 33, 34 }
  
  
  /* Fitting values into registers.  */
--- 358,364 ----
  {  1, 2, 3, 4, 5, 0, 13, 12, 11, 10, 9, 8, 7, 6, 14,            \
     16, 17, 18, 19, 20, 21, 22, 23,                              \
     24, 25, 26, 27, 28, 29, 30, 31,                              \
!    15, 32, 33, 34, 35 }
  
  
  /* Fitting values into registers.  */
*************** enum reg_class
*** 449,460 ****
  #define REG_CLASS_CONTENTS \
  {				       			\
    { 0x00000000, 0x00000000 },	/* NO_REGS */		\
!   { 0x0000fffe, 0x00000005 },	/* ADDR_REGS */		\
!   { 0x0000ffff, 0x00000005 },	/* GENERAL_REGS */	\
    { 0xffff0000, 0x00000000 },	/* FP_REGS */		\
!   { 0xfffffffe, 0x00000005 },	/* ADDR_FP_REGS */	\
!   { 0xffffffff, 0x00000005 },	/* GENERAL_FP_REGS */	\
!   { 0xffffffff, 0x00000007 },	/* ALL_REGS */		\
  }
  
  /* Register -> class mapping.  */
--- 449,460 ----
  #define REG_CLASS_CONTENTS \
  {				       			\
    { 0x00000000, 0x00000000 },	/* NO_REGS */		\
!   { 0x0000fffe, 0x0000000d },	/* ADDR_REGS */		\
!   { 0x0000ffff, 0x0000000d },	/* GENERAL_REGS */	\
    { 0xffff0000, 0x00000000 },	/* FP_REGS */		\
!   { 0xfffffffe, 0x0000000d },	/* ADDR_FP_REGS */	\
!   { 0xffffffff, 0x0000000d },	/* GENERAL_FP_REGS */	\
!   { 0xffffffff, 0x0000000f },	/* ALL_REGS */		\
  }
  
  /* Register -> class mapping.  */
*************** extern int current_function_outgoing_arg
*** 579,588 ****
  
  /* Describe how we implement __builtin_eh_return.  */
  #define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 6 : INVALID_REGNUM)
! #define EH_RETURN_HANDLER_RTX \
!   gen_rtx_MEM (Pmode, plus_constant (arg_pointer_rtx, \
!                -STACK_POINTER_OFFSET + UNITS_PER_WORD*RETURN_REGNUM))
! 
  /* Select a format to encode pointers in exception handling data.  */
  #define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL)			    \
    (flag_pic								    \
--- 579,586 ----
  
  /* Describe how we implement __builtin_eh_return.  */
  #define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 6 : INVALID_REGNUM)
! #define EH_RETURN_HANDLER_RTX gen_rtx_MEM (Pmode, return_address_pointer_rtx)
!        
  /* Select a format to encode pointers in exception handling data.  */
  #define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL)			    \
    (flag_pic								    \
*************** extern int current_function_outgoing_arg
*** 596,601 ****
--- 594,600 ----
  #define FRAME_POINTER_REGNUM 34
  #define HARD_FRAME_POINTER_REGNUM 11
  #define ARG_POINTER_REGNUM 32
+ #define RETURN_ADDRESS_POINTER_REGNUM 35
  
  /* The static chain must be call-clobbered, but not used for
     function argument passing.  As register 1 is clobbered by
*************** extern int current_function_outgoing_arg
*** 614,624 ****
  
  #define INITIAL_FRAME_POINTER_OFFSET(DEPTH) (DEPTH) = 0
  
! #define ELIMINABLE_REGS				        \
! {{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},	        \
!  { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM},    \
!  { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM},	        \
!  { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
  
  #define CAN_ELIMINATE(FROM, TO) (1)
  
--- 613,625 ----
  
  #define INITIAL_FRAME_POINTER_OFFSET(DEPTH) (DEPTH) = 0
  
! #define ELIMINABLE_REGS				             \
! {{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},	             \
!  { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM},         \
!  { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM},	             \
!  { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM},           \
!  { RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM},     \
!  { RETURN_ADDRESS_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
  
  #define CAN_ELIMINATE(FROM, TO) (1)
  
*************** extern int current_function_outgoing_arg
*** 633,638 ****
--- 634,643 ----
    { (OFFSET) = s390_arg_frame_offset (); }     				  \
    else if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM)  \
    { (OFFSET) = s390_arg_frame_offset (); }     				  \
+   else if ((FROM) == RETURN_ADDRESS_POINTER_REGNUM                        \
+             && ((TO) == STACK_POINTER_REGNUM                              \
+                 || (TO) == HARD_FRAME_POINTER_REGNUM))                    \
+   { (OFFSET) = s390_return_address_offset (); }     			  \
    else									  \
      abort();								  \
  }
*************** extern int flag_pic;
*** 921,927 ****
    "%r8",  "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",	\
    "%f0",  "%f2",  "%f4",  "%f6",  "%f1",  "%f3",  "%f5",  "%f7",	\
    "%f8",  "%f10", "%f12", "%f14", "%f9", "%f11", "%f13", "%f15",	\
!   "%ap",  "%cc",  "%fp"							\
  }
  
  /* Emit a dtp-relative reference to a TLS variable.  */
--- 926,932 ----
    "%r8",  "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",	\
    "%f0",  "%f2",  "%f4",  "%f6",  "%f1",  "%f3",  "%f5",  "%f7",	\
    "%f8",  "%f10", "%f12", "%f14", "%f9", "%f11", "%f13", "%f15",	\
!   "%ap",  "%cc",  "%fp"	, "%rp"						\
  }
  
  /* Emit a dtp-relative reference to a TLS variable.  */


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