IA64 HP-UX ILP32 patch for __builtin_return_address (PR 11535)

Steve Ellcey sje@cup.hp.com
Thu Jul 31 18:18:00 GMT 2003


Combined with my earlier patch
(http://gcc.gnu.org/ml/gcc-patches/2003-07/msg02962.html) this fixes PR
11535.  The problem here is that on IA64 branch registers can only be
moved from/to general registers.  They cannot be loaded or stored
directly from memory and they cannot be accessed in a subreg mode, they
have to be moved as entire 8 byte quantities.  I tested this on ToT and
am currently testing on the 3.3 branch.  I would like to check in this
and the earlier patch on both.

Steve Ellcey
sje@cup.hp.com


2003-07-31  Steve Ellcey  <sje@cup.hp.com>

	* config/ia64/ia64.h (GENERAL_REGNO_P): Do not consider 
	RETURN_ADDRESS_POINTER_REGNUM to be a general register.
	(BR_REGNO_P): Recognize RETURN_ADDRESS_POINTER_REGNUM as
	a branch register.
	* config/ia64/ia64.c (hard_br_register_operand): New routine.
	(ia64_move_ok): Branch registers can only be moved to/from
	general registers.

*** gcc.orig/gcc/gcc/config/ia64/ia64.h	Thu Jul 31 09:49:30 2003
--- gcc/gcc/gcc/config/ia64/ia64.h	Thu Jul 31 09:52:04 2003
*************** while (0)
*** 462,472 ****
  #define GR_REGNO_P(REGNO) ((unsigned HOST_WIDE_INT) (REGNO) <= 127)
  #define FR_REGNO_P(REGNO) ((REGNO) >= 128 && (REGNO) <= 255)
  #define PR_REGNO_P(REGNO) ((REGNO) >= 256 && (REGNO) <= 319)
! #define BR_REGNO_P(REGNO) ((REGNO) >= 320 && (REGNO) <= 327)
  #define GENERAL_REGNO_P(REGNO) \
    (GR_REGNO_P (REGNO)							\
!    || (REGNO) == FRAME_POINTER_REGNUM					\
!    || (REGNO) == RETURN_ADDRESS_POINTER_REGNUM)
  
  #define GR_REG(REGNO) ((REGNO) + 0)
  #define FR_REG(REGNO) ((REGNO) + 128)
--- 462,473 ----
  #define GR_REGNO_P(REGNO) ((unsigned HOST_WIDE_INT) (REGNO) <= 127)
  #define FR_REGNO_P(REGNO) ((REGNO) >= 128 && (REGNO) <= 255)
  #define PR_REGNO_P(REGNO) ((REGNO) >= 256 && (REGNO) <= 319)
! #define BR_REGNO_P(REGNO) (((REGNO) >= 320 && (REGNO) <= 327)		\
!    || ((REGNO) == RETURN_ADDRESS_POINTER_REGNUM))
! 	
  #define GENERAL_REGNO_P(REGNO) \
    (GR_REGNO_P (REGNO)							\
!    || (REGNO) == FRAME_POINTER_REGNUM)
  
  #define GR_REG(REGNO) ((REGNO) + 0)
  #define FR_REG(REGNO) ((REGNO) + 128)
*** gcc.orig/gcc/gcc/config/ia64/ia64.c	Thu Jul 31 09:49:33 2003
--- gcc/gcc/gcc/config/ia64/ia64.c	Thu Jul 31 09:55:05 2003
*************** static void do_restore PARAMS ((rtx (*)(
*** 180,185 ****
--- 180,186 ----
  static rtx gen_movdi_x PARAMS ((rtx, rtx, rtx));
  static rtx gen_fr_spill_x PARAMS ((rtx, rtx, rtx));
  static rtx gen_fr_restore_x PARAMS ((rtx, rtx, rtx));
+ static int hard_br_register_operand PARAMS ((rtx, enum machine_mode));
  
  static enum machine_mode hfa_element_mode PARAMS ((tree, int));
  static bool ia64_function_ok_for_sibcall PARAMS ((tree, tree));
*************** gr_register_operand (op, mode)
*** 584,589 ****
--- 585,611 ----
    return 1;
  }
  
+ 
+ /* Return 1 if OP is a register operand that is a BR reg.  */
+ 
+ static int
+ hard_br_register_operand (op, mode)
+      rtx op;
+      enum machine_mode mode;
+ {
+   if (! register_operand (op, mode))
+     return 0;
+   if (GET_CODE (op) == SUBREG)
+     op = SUBREG_REG (op);
+   if (GET_CODE (op) == REG)
+     {
+       unsigned int regno = REGNO (op);
+       if (regno < FIRST_PSEUDO_REGISTER)
+ 	return BR_REGNO_P (regno);
+     }
+   return 0;
+ }
+ 
  /* Return 1 if OP is a register operand that is (or could be) an FR reg.  */
  
  int
*************** int
*** 1046,1051 ****
--- 1068,1080 ----
  ia64_move_ok (dst, src)
       rtx dst, src;
  {
+   /* Branch registers can only be moved to/from general registers and
+      only in DImode.  */
+   if (hard_br_register_operand (dst, VOIDmode))
+     return gr_register_operand (src, DImode);
+   if (hard_br_register_operand (src, VOIDmode))
+     return gr_register_operand (dst, DImode);
+ 
    /* If we're under init_recog_no_volatile, we'll not be able to use
       memory_operand.  So check the code directly and don't worry about
       the validity of the underlying address, which should have been



More information about the Gcc-patches mailing list