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]

more alpha relocation work


The main goal here is to allow the two insns that reload the $gp
after calls to be non-sequential, and thus avoid a pipeline stall.
This requires that the remaining symbolic references be modified
to show that they use the $gp.


r~


	* config/alpha/alpha.c (local_symbol_p): Split out from ...
	(local_symbolic_operand): ... here.
	(small_symbolic_operand): Check mode.
	(global_symbolic_operand): New.
	(input_operand): Reject symbolics if explicit relocs.
	(call_operand): Tidy.
	(alpha_legitimize_address): Use movdi_er_high_g.
	(alpha_expand_mov): Likewise.
	* config/alpha/alpha-protos.h: Update.
	* config/alpha/alpha.h (PREDICATE_CODES): Update.
	* config/alpha/alpha.md (UNSPEC_LITERAL, UNSPEC_LITUSE): New.
	(UNSPEC_LDGP2, UNSPECV_PLDGP2): New.
	(UNSPECV_LDGP2): Remove.
	(all call patterns): Use 's' not 'i' for symbolic constraint.
	(call_osf call_value_osf): Use call_operand.
	(all osf call patterns): Use $gp.  New peepholes for explicit relocs.
	(movdi_er_nofix, movdi_er_fix): Remove symbolic alternative.
	(prologue_ldgp_1_er): Remove.
	(ldgp_er_1, ldgp_er_2, prologue_ldgp_er_2): New.
	(builtin_setjmp_receiver_er patterns): Use them.
	(exception_receiver_er): Likewise.

Index: config/alpha/alpha-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha-protos.h,v
retrieving revision 1.25
diff -c -p -d -r1.25 alpha-protos.h
*** alpha-protos.h	2001/09/11 08:52:36	1.25
--- alpha-protos.h	2001/09/19 18:33:59
*************** along with GNU CC; see the file COPYING.
*** 18,23 ****
--- 18,25 ----
  the Free Software Foundation, 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.  */
  
+ extern int alpha_next_sequence_number;
+ 
  extern void literal_section PARAMS ((void));
  extern void override_options PARAMS ((void));
  extern int zap_mask PARAMS ((HOST_WIDE_INT));
*************** extern int some_ni_operand PARAMS ((rtx,
*** 55,60 ****
--- 57,64 ----
  extern int input_operand PARAMS ((rtx, enum machine_mode));
  extern int current_file_function_operand PARAMS ((rtx, enum machine_mode));
  extern int local_symbolic_operand PARAMS ((rtx, enum machine_mode));
+ extern int small_symbolic_operand PARAMS ((rtx, enum machine_mode));
+ extern int global_symbolic_operand PARAMS ((rtx, enum machine_mode));
  extern int call_operand PARAMS ((rtx, enum machine_mode));
  extern int symbolic_operand PARAMS ((rtx, enum machine_mode));
  extern int alpha_comparison_operator PARAMS ((rtx, enum machine_mode));
Index: config/alpha/alpha.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.c,v
retrieving revision 1.193
diff -c -p -d -r1.193 alpha.c
*** alpha.c	2001/09/13 14:37:25	1.193
--- alpha.c	2001/09/19 18:34:04
*************** int alpha_this_literal_sequence_number;
*** 114,119 ****
--- 114,121 ----
  int alpha_this_gpdisp_sequence_number;
  
  /* Declarations of static functions.  */
+ static bool local_symbol_p
+   PARAMS ((rtx));
  static void alpha_set_memflags_1
    PARAMS ((rtx, int, int, int));
  static rtx alpha_emit_set_const_1
*************** input_operand (op, mode)
*** 795,800 ****
--- 797,805 ----
      case LABEL_REF:
      case SYMBOL_REF:
      case CONST:
+       if (TARGET_EXPLICIT_RELOCS)
+ 	return 0;
+ 
        /* This handles both the Windows/NT and OSF cases.  */
        return mode == ptr_mode || mode == DImode;
  
*************** current_file_function_operand (op, mode)
*** 840,855 ****
  	      || op == XEXP (DECL_RTL (current_function_decl), 0)));
  }
  
! /* Return true if OP is a SYMBOL_REF or CONST referencing a variable
!    known to be defined in this file.  */
  
  int
  local_symbolic_operand (op, mode)
       rtx op;
       enum machine_mode mode;
  {
-   const char *str;
- 
    if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
      return 0;
  
--- 845,876 ----
  	      || op == XEXP (DECL_RTL (current_function_decl), 0)));
  }
  
! /* Return true if OP is a LABEL_REF, or SYMBOL_REF or CONST referencing
!    a variable known to be defined in this file.  */
! 
! static bool
! local_symbol_p (op)
!      rtx op;
! {
!   const char *str = XSTR (op, 0);
! 
!   /* ??? SYMBOL_REF_FLAG is set for local function symbols, but we
!      run into problems with the rtl inliner in that the symbol was
!      once external, but is local after inlining, which results in
!      unrecognizable insns.  */
  
+   return (CONSTANT_POOL_ADDRESS_P (op)
+ 	  /* If @, then ENCODE_SECTION_INFO sez it's local.  */
+ 	  || str[0] == '@'
+ 	  /* If *$, then ASM_GENERATE_INTERNAL_LABEL sez it's local.  */
+ 	  || (str[0] == '*' && str[1] == '$'));
+ }
+ 
  int
  local_symbolic_operand (op, mode)
       rtx op;
       enum machine_mode mode;
  {
    if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
      return 0;
  
*************** local_symbolic_operand (op, mode)
*** 864,881 ****
    if (GET_CODE (op) != SYMBOL_REF)
      return 0;
  
!   str = XSTR (op, 0);
! 
!   /* ??? SYMBOL_REF_FLAG is set for local function symbols, but we
!      run into problems with the rtl inliner in that the symbol was
!      once external, but is local after inlining, which results in
!      unrecognizable insns.  */
! 
!   return (CONSTANT_POOL_ADDRESS_P (op)
! 	  /* If @, then ENCODE_SECTION_INFO sez it's local.  */
! 	  || str[0] == '@'
! 	  /* If *$, then ASM_GENERATE_INTERNAL_LABEL sez it's local.  */
! 	  || (str[0] == '*' && str[1] == '$'));
  }
  
  /* Return true if OP is a SYMBOL_REF or CONST referencing a variable
--- 885,891 ----
    if (GET_CODE (op) != SYMBOL_REF)
      return 0;
  
!   return local_symbol_p (op);
  }
  
  /* Return true if OP is a SYMBOL_REF or CONST referencing a variable
*************** small_symbolic_operand (op, mode)
*** 891,896 ****
--- 901,909 ----
    if (! TARGET_SMALL_DATA)
      return 0;
  
+   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
+     return 0;
+ 
    if (GET_CODE (op) == CONST
        && GET_CODE (XEXP (op, 0)) == PLUS
        && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
*************** small_symbolic_operand (op, mode)
*** 900,906 ****
      return 0;
  
    if (CONSTANT_POOL_ADDRESS_P (op))
!     return GET_MODE_SIZE (get_pool_mode (op)) <= g_switch_value;
    else
      {
        str = XSTR (op, 0);
--- 913,919 ----
      return 0;
  
    if (CONSTANT_POOL_ADDRESS_P (op))
!     return GET_MODE_SIZE (get_pool_mode (op)) <= (unsigned) g_switch_value;
    else
      {
        str = XSTR (op, 0);
*************** small_symbolic_operand (op, mode)
*** 908,913 ****
--- 921,948 ----
      }
  }
  
+ /* Return true if OP is a SYMBOL_REF or CONST referencing a variable
+    not known (or known not) to be defined in this file.  */
+ 
+ int
+ global_symbolic_operand (op, mode)
+      rtx op;
+      enum machine_mode mode;
+ {
+   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
+     return 0;
+ 
+   if (GET_CODE (op) == CONST
+       && GET_CODE (XEXP (op, 0)) == PLUS
+       && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
+     op = XEXP (XEXP (op, 0), 0);
+ 
+   if (GET_CODE (op) != SYMBOL_REF)
+     return 0;
+ 
+   return ! local_symbol_p (op);
+ }
+ 
  /* Return 1 if OP is a valid operand for the MEM of a CALL insn.  */
  
  int
*************** call_operand (op, mode)
*** 918,927 ****
    if (mode != Pmode)
      return 0;
  
-   if (TARGET_ABI_UNICOSMK)
-     return GET_CODE (op) == REG;
-   if (GET_CODE (op) == SYMBOL_REF)
-     return 1;
    if (GET_CODE (op) == REG)
      {
        if (TARGET_ABI_OSF)
--- 953,958 ----
*************** call_operand (op, mode)
*** 929,934 ****
--- 960,969 ----
        else
  	return 1;
      }
+   if (TARGET_ABI_UNICOSMK)
+     return 0;
+   if (GET_CODE (op) == SYMBOL_REF)
+     return 1;
  
    return 0;
  }
*************** alpha_legitimize_address (x, oldx, mode)
*** 1593,1618 ****
      }
  
    /* If this is a local symbol, split the address into HIGH/LO_SUM parts.  */
!   if (TARGET_EXPLICIT_RELOCS && local_symbolic_operand (x, Pmode))
      {
        rtx scratch;
  
!       if (small_symbolic_operand (x, Pmode))
! 	scratch = pic_offset_table_rtx;
        else
  	{
- 	  rtx insn, tmp;
- 
  	  scratch = gen_reg_rtx (Pmode);
! 
! 	  tmp = gen_rtx_HIGH (Pmode, x);
! 	  tmp = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmp);
!           insn = emit_insn (gen_rtx_SET (VOIDmode, scratch, tmp));
! 	  REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, tmp,
! 						REG_NOTES (insn));
  	}
- 
-       return gen_rtx_LO_SUM (Pmode, scratch, x);
      }
  
    return NULL;
--- 1628,1663 ----
      }
  
    /* If this is a local symbol, split the address into HIGH/LO_SUM parts.  */
!   if (TARGET_EXPLICIT_RELOCS && symbolic_operand (x, Pmode))
      {
        rtx scratch;
+       if (local_symbolic_operand (x, Pmode))
+ 	{
+ 	  if (small_symbolic_operand (x, Pmode))
+ 	    scratch = pic_offset_table_rtx;
+ 	  else
+ 	    {
+ 	      rtx insn, tmp;
  
! 	      scratch = gen_reg_rtx (Pmode);
! 
! 	      tmp = gen_rtx_HIGH (Pmode, x);
! 	      tmp = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmp);
!               insn = emit_insn (gen_rtx_SET (VOIDmode, scratch, tmp));
! 	      REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, tmp,
! 						    REG_NOTES (insn));
! 	    }
! 
! 	  return gen_rtx_LO_SUM (Pmode, scratch, x);
! 	}
        else
  	{
  	  scratch = gen_reg_rtx (Pmode);
! 	  emit_insn (gen_movdi_er_high_g (scratch, pic_offset_table_rtx,
! 					  x, const0_rtx));
! 	  /* ??? FIXME: Tag the use of scratch with a lituse.  */
! 	  return scratch;
  	}
      }
  
    return NULL;
*************** alpha_expand_mov (mode, operands)
*** 2172,2198 ****
        && ! reg_or_0_operand (operands[1], mode))
      operands[1] = force_reg (mode, operands[1]);
  
!   if (TARGET_EXPLICIT_RELOCS && local_symbolic_operand (operands[1], mode))
      {
!       rtx scratch;
! 
!       if (small_symbolic_operand (operands[1], Pmode))
! 	scratch = pic_offset_table_rtx;
!       else
  	{
! 	  rtx insn, tmp;
  
! 	  scratch = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
  
! 	  tmp = gen_rtx_HIGH (Pmode, operands[1]);
! 	  tmp = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmp);
!           insn = emit_insn (gen_rtx_SET (VOIDmode, scratch, tmp));
! 	  REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, tmp,
! 						REG_NOTES (insn));
! 	}
  
!       operands[1] = gen_rtx_LO_SUM (Pmode, scratch, operands[1]);
!       return false;
      }
  
    /* Early out for non-constants and valid constants.  */
--- 2217,2252 ----
        && ! reg_or_0_operand (operands[1], mode))
      operands[1] = force_reg (mode, operands[1]);
  
!   if (TARGET_EXPLICIT_RELOCS && symbolic_operand (operands[1], mode))
      {
!       if (local_symbolic_operand (operands[1], mode))
  	{
! 	  rtx scratch;
  
! 	  if (small_symbolic_operand (operands[1], Pmode))
! 	    scratch = pic_offset_table_rtx;
! 	  else
! 	    {
! 	      rtx insn, tmp;
  
! 	      scratch = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
  
! 	      tmp = gen_rtx_HIGH (Pmode, operands[1]);
! 	      tmp = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmp);
!               insn = emit_insn (gen_rtx_SET (VOIDmode, scratch, tmp));
! 	      REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, tmp,
! 						    REG_NOTES (insn));
! 	    }
! 
!           operands[1] = gen_rtx_LO_SUM (Pmode, scratch, operands[1]);
! 	  return false;
! 	}
!       else
! 	{
! 	  emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx,
! 					  operands[1], const0_rtx));
! 	  return true;
! 	}
      }
  
    /* Early out for non-constants and valid constants.  */
Index: config/alpha/alpha.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.h,v
retrieving revision 1.134
diff -c -p -d -r1.134 alpha.h
*** alpha.h	2001/09/13 08:42:20	1.134
--- alpha.h	2001/09/19 18:34:07
*************** do {									\
*** 2189,2194 ****
--- 2189,2196 ----
    {"fp0_operand", {CONST_DOUBLE}},					\
    {"current_file_function_operand", {SYMBOL_REF}},			\
    {"local_symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}},		\
+   {"small_symbolic_operand", {SYMBOL_REF, CONST}},			\
+   {"global_symbolic_operand", {SYMBOL_REF, CONST}},			\
    {"call_operand", {REG, SYMBOL_REF}},					\
    {"input_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE,		\
  		     SYMBOL_REF, CONST, LABEL_REF}},			\
Index: config/alpha/alpha.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.md,v
retrieving revision 1.152
diff -c -p -d -r1.152 alpha.md
*** alpha.md	2001/09/14 16:25:26	1.152
--- alpha.md	2001/09/19 18:34:12
***************
*** 35,40 ****
--- 35,43 ----
     (UNSPEC_UMK_LALM	7)
     (UNSPEC_UMK_LAL	8)
     (UNSPEC_UMK_LOAD_CIW	9)
+    (UNSPEC_LDGP2	10)
+    (UNSPEC_LITERAL	11)
+    (UNSPEC_LITUSE	12)
    ])
  
  ;; UNSPEC_VOLATILE:
***************
*** 49,57 ****
     (UNSPECV_REALIGN	6)
     (UNSPECV_EHR		7)	; exception_receiver
     (UNSPECV_MCOUNT	8)
!    (UNSPECV_LDGP1	9)
!    (UNSPECV_LDGP2	10)
!    (UNSPECV_FORCE_MOV	11)
    ])
  
  ;; Where necessary, the suffixes _le and _be are used to distinguish between
--- 52,60 ----
     (UNSPECV_REALIGN	6)
     (UNSPECV_EHR		7)	; exception_receiver
     (UNSPECV_MCOUNT	8)
!    (UNSPECV_FORCE_MOV	9)
!    (UNSPECV_LDGP1	10)
!    (UNSPECV_PLDGP2	11)	; prologue ldgp
    ])
  
  ;; Where necessary, the suffixes _le and _be are used to distinguish between
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 638,644 ****
    ""
    "")
  
! (define_insn "*adddi_er_high"
    [(set (match_operand:DI 0 "register_operand" "=r")
  	(plus:DI (match_operand:DI 1 "register_operand" "r")
  		 (high:DI (match_operand:DI 2 "local_symbolic_operand" ""))))]
--- 641,647 ----
    ""
    "")
  
! (define_insn "*adddi_er_high_l"
    [(set (match_operand:DI 0 "register_operand" "=r")
  	(plus:DI (match_operand:DI 1 "register_operand" "r")
  		 (high:DI (match_operand:DI 2 "local_symbolic_operand" ""))))]
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 4502,4509 ****
  })
  
  (define_expand "sibcall"
!   [(call (mem:DI (match_operand 0 "" ""))
! 		 (match_operand 1 "" ""))]
    "TARGET_ABI_OSF"
  {
    if (GET_CODE (operands[0]) != MEM)
--- 4505,4513 ----
  })
  
  (define_expand "sibcall"
!   [(parallel [(call (mem:DI (match_operand 0 "" ""))
! 			    (match_operand 1 "" ""))
! 	      (use (reg:DI 29))])]
    "TARGET_ABI_OSF"
  {
    if (GET_CODE (operands[0]) != MEM)
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 4514,4520 ****
  (define_expand "call_osf"
    [(parallel [(call (mem:DI (match_operand 0 "" ""))
  		    (match_operand 1 "" ""))
! 	      (clobber (reg:DI 27))
  	      (clobber (reg:DI 26))])]
    ""
  {
--- 4518,4524 ----
  (define_expand "call_osf"
    [(parallel [(call (mem:DI (match_operand 0 "" ""))
  		    (match_operand 1 "" ""))
! 	      (use (reg:DI 29))
  	      (clobber (reg:DI 26))])]
    ""
  {
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 4522,4534 ****
      abort ();
  
    operands[0] = XEXP (operands[0], 0);
! 
!   if (GET_CODE (operands[0]) != SYMBOL_REF
!       && ! (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 27))
      {
!       rtx tem = gen_rtx_REG (DImode, 27);
!       emit_move_insn (tem, operands[0]);
!       operands[0] = tem;
      }
  })
  
--- 4526,4536 ----
      abort ();
  
    operands[0] = XEXP (operands[0], 0);
!   if (! call_operand (operands[0], Pmode))
      {
!       rtx pv = gen_rtx_REG (Pmode, 27);
!       emit_move_insn (pv, operands[0]);
!       operands[0] = pv;
      }
  })
  
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 4634,4642 ****
  })
  
  (define_expand "sibcall_value"
!   [(set (match_operand 0 "" "")
! 	(call (mem:DI (match_operand 1 "" ""))
! 	      (match_operand 2 "" "")))]
    "TARGET_ABI_OSF"
  {
    if (GET_CODE (operands[1]) != MEM)
--- 4636,4645 ----
  })
  
  (define_expand "sibcall_value"
!   [(parallel [(set (match_operand 0 "" "")
! 		   (call (mem:DI (match_operand 1 "" ""))
! 		         (match_operand 2 "" "")))
! 	      (use (reg:DI 29))])]
    "TARGET_ABI_OSF"
  {
    if (GET_CODE (operands[1]) != MEM)
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 4648,4654 ****
    [(parallel [(set (match_operand 0 "" "")
  		   (call (mem:DI (match_operand 1 "" ""))
  			 (match_operand 2 "" "")))
! 	      (clobber (reg:DI 27))
  	      (clobber (reg:DI 26))])]
    ""
  {
--- 4651,4657 ----
    [(parallel [(set (match_operand 0 "" "")
  		   (call (mem:DI (match_operand 1 "" ""))
  			 (match_operand 2 "" "")))
! 	      (use (reg:DI 29))
  	      (clobber (reg:DI 26))])]
    ""
  {
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 4656,4668 ****
      abort ();
  
    operands[1] = XEXP (operands[1], 0);
! 
!   if (GET_CODE (operands[1]) != SYMBOL_REF
!       && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27))
      {
!       rtx tem = gen_rtx_REG (DImode, 27);
!       emit_move_insn (tem, operands[1]);
!       operands[1] = tem;
      }
  })
  
--- 4659,4669 ----
      abort ();
  
    operands[1] = XEXP (operands[1], 0);
!   if (! call_operand (operands[1], Pmode))
      {
!       rtx pv = gen_rtx_REG (Pmode, 27);
!       emit_move_insn (pv, operands[1]);
!       operands[1] = pv;
      }
  })
  
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 4735,4773 ****
    emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
  })
  
- (define_insn "*call_osf_1_er_noreturn"
-   [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,i"))
- 	 (match_operand 1 "" ""))
-    (clobber (reg:DI 27))
-    (clobber (reg:DI 26))]
-   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
-    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
-   "@
-    jsr $26,($27),0
-    bsr $26,$%0..ng
-    ldq $27,%0($29)\t\t!literal!%#\;jsr $26,($27),%0\t\t!lituse_jsr!%#"
-   [(set_attr "type" "jsr")
-    (set_attr "length" "*,*,8")])
- 
  (define_insn "*call_osf_1_er"
!   [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,i"))
  	 (match_operand 1 "" ""))
!    (clobber (reg:DI 27))
     (clobber (reg:DI 26))]
    "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
    "@
!    jsr $26,($27),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
     bsr $26,$%0..ng
!    ldq $27,%0($29)\t\t!literal!%#\;jsr $26,($27),%0\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
    [(set_attr "type" "jsr")
     (set_attr "length" "12,*,16")])
  
  (define_insn "*call_osf_1_noreturn"
!   [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,i"))
  	 (match_operand 1 "" ""))
!    (clobber (reg:DI 27))
     (clobber (reg:DI 26))]
!   "TARGET_ABI_OSF && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
    "@
     jsr $26,($27),0
     bsr $26,$%0..ng
--- 4736,4833 ----
    emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
  })
  
  (define_insn "*call_osf_1_er"
!   [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
  	 (match_operand 1 "" ""))
!    (use (reg:DI 29))
     (clobber (reg:DI 26))]
    "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
    "@
!    jsr $26,(%0),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
     bsr $26,$%0..ng
!    ldq $27,%0($29)\t\t!literal!%#\;jsr $26,($27),0\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
    [(set_attr "type" "jsr")
     (set_attr "length" "12,*,16")])
  
+ ;; We must use peep2 instead of a split because we need accurate life
+ ;; information for $gp.  Consider the case of { bar(); while (1); }.
+ (define_peephole2
+   [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand" ""))
+ 		    (match_operand 1 "" ""))
+ 	      (use (reg:DI 29))
+ 	      (clobber (reg:DI 26))])]
+   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
+    && ! current_file_function_operand (operands[0], Pmode)
+    && peep2_regno_dead_p (1, 29)"
+   [(parallel [(call (mem:DI (match_dup 2))
+ 		    (match_dup 1))
+ 	      (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
+ 	      (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+ 	      (use (match_dup 0))])]
+ {
+   if (CONSTANT_P (operands[0]))
+     {
+       operands[2] = gen_rtx_REG (Pmode, 27);
+       emit_move_insn (operands[2], operands[0]);
+     }
+   else
+     {
+       operands[2] = operands[0];
+       operands[0] = const0_rtx;
+     }
+ })
+ 
+ (define_peephole2
+   [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand" ""))
+ 		    (match_operand 1 "" ""))
+ 	      (use (reg:DI 29))
+ 	      (clobber (reg:DI 26))])]
+   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
+    && ! current_file_function_operand (operands[0], Pmode)
+    && ! peep2_regno_dead_p (1, 29)"
+   [(parallel [(call (mem:DI (match_dup 2))
+ 		    (match_dup 1))
+ 	      (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
+ 	      (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+ 	      (use (match_dup 0))])
+    (set (reg:DI 29)
+ 	(unspec_volatile:DI [(reg:DI 26) (match_dup 3)] UNSPECV_LDGP1))
+    (set (reg:DI 29)
+ 	(unspec:DI [(reg:DI 29) (match_dup 3)] UNSPEC_LDGP2))]
+ {
+   if (CONSTANT_P (operands[0]))
+     {
+       operands[2] = gen_rtx_REG (Pmode, 27);
+       emit_move_insn (operands[2], operands[0]);
+     }
+   else
+     {
+       operands[2] = operands[0];
+       operands[0] = const0_rtx;
+     }
+   operands[3] = GEN_INT (alpha_next_sequence_number++);
+ })
+ 
+ ;; We add a blockage unspec_volatile to prevent insns from moving down
+ ;; from above the call to in between the call and the ldah gpdisp.
+ 
+ (define_insn "*call_osf_2_er"
+   [(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
+ 	 (match_operand 1 "" ""))
+    (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
+    (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+    (use (match_operand 2 "" ""))]
+   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+   "jsr $26,(%0),%2"
+   [(set_attr "type" "jsr")])
+ 
  (define_insn "*call_osf_1_noreturn"
!   [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
  	 (match_operand 1 "" ""))
!    (use (reg:DI 29))
     (clobber (reg:DI 26))]
!   "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
!    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
    "@
     jsr $26,($27),0
     bsr $26,$%0..ng
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 4776,4786 ****
     (set_attr "length" "*,*,8")])
  
  (define_insn "*call_osf_1"
!   [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,i"))
  	 (match_operand 1 "" ""))
!    (clobber (reg:DI 27))
     (clobber (reg:DI 26))]
!   "TARGET_ABI_OSF"
    "@
     jsr $26,($27),0\;ldgp $29,0($26)
     bsr $26,$%0..ng
--- 4836,4846 ----
     (set_attr "length" "*,*,8")])
  
  (define_insn "*call_osf_1"
!   [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
  	 (match_operand 1 "" ""))
!    (use (reg:DI 29))
     (clobber (reg:DI 26))]
!   "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
    "@
     jsr $26,($27),0\;ldgp $29,0($26)
     bsr $26,$%0..ng
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 4790,4802 ****
  
  (define_insn "*sibcall_osf_1"
    [(call (mem:DI (match_operand:DI 0 "current_file_function_operand" "R"))
! 	 (match_operand 1 "" ""))]
    "TARGET_ABI_OSF"
    "br $31,$%0..ng"
    [(set_attr "type" "jsr")])
  
  (define_insn "*call_nt_1"
!   [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
  	 (match_operand 1 "" ""))
     (clobber (reg:DI 26))]
    "TARGET_ABI_WINDOWS_NT"
--- 4850,4863 ----
  
  (define_insn "*sibcall_osf_1"
    [(call (mem:DI (match_operand:DI 0 "current_file_function_operand" "R"))
! 	 (match_operand 1 "" ""))
!    (use (reg:DI 29))]
    "TARGET_ABI_OSF"
    "br $31,$%0..ng"
    [(set_attr "type" "jsr")])
  
  (define_insn "*call_nt_1"
!   [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,s"))
  	 (match_operand 1 "" ""))
     (clobber (reg:DI 26))]
    "TARGET_ABI_WINDOWS_NT"
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 4808,4814 ****
     (set_attr "length" "*,*,12")])
  
  (define_insn "*call_vms_1"
!   [(call (mem:DI (match_operand:DI 0 "call_operand" "r,i"))
  	 (match_operand 1 "" ""))
     (use (match_operand:DI 2 "nonimmediate_operand" "r,m"))
     (use (reg:DI 25))
--- 4869,4875 ----
     (set_attr "length" "*,*,12")])
  
  (define_insn "*call_vms_1"
!   [(call (mem:DI (match_operand:DI 0 "call_operand" "r,s"))
  	 (match_operand 1 "" ""))
     (use (match_operand:DI 2 "nonimmediate_operand" "r,m"))
     (use (reg:DI 25))
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 5302,5308 ****
  }
    [(set_attr "type" "iadd")])
  
! (define_insn "*movdi_er_low"
    [(set (match_operand:DI 0 "register_operand" "=r")
  	(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
  		   (match_operand:DI 2 "local_symbolic_operand" "")))]
--- 5363,5369 ----
  }
    [(set_attr "type" "iadd")])
  
! (define_insn "*movdi_er_low_l"
    [(set (match_operand:DI 0 "register_operand" "=r")
  	(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
  		   (match_operand:DI 2 "local_symbolic_operand" "")))]
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 5314,5338 ****
      return "lda %0,%2(%1)\t\t!gprellow";
  })
  
  (define_insn "*movdi_er_nofix"
!   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q")
! 	(match_operand:DI 1 "input_operand" "rJ,K,L,T,s,m,rJ,*fJ,Q,*f"))]
    "TARGET_EXPLICIT_RELOCS && ! TARGET_FIX
     && (register_operand (operands[0], DImode)
!        || reg_or_0_operand (operands[1], DImode))
!    && ! local_symbolic_operand (operands[1], DImode)"
    "@
     mov %r1,%0
     lda %0,%1($31)
     ldah %0,%h1($31)
     ldah %0,%H1
-    ldq %0,%1($29)\t\t!literal
     ldq%A1 %0,%1
     stq%A0 %r1,%0
     fmov %R1,%0
     ldt %0,%1
     stt %R1,%0"
!   [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
  
  ;; The 'U' constraint matches symbolic operands on Unicos/Mk. Those should
  ;; have been split up by the rules above but we shouldn't reject the
--- 5375,5407 ----
      return "lda %0,%2(%1)\t\t!gprellow";
  })
  
+ (define_insn "movdi_er_high_g"
+   [(set (match_operand:DI 0 "register_operand" "=r")
+ 	(unspec:DI [(match_operand:DI 1 "register_operand" "r")
+ 		    (match_operand:DI 2 "global_symbolic_operand" "")
+ 		    (match_operand 3 "const_int_operand" "")]
+ 		   UNSPEC_LITERAL))]
+   "TARGET_EXPLICIT_RELOCS"
+   "ldq %0,%2(%1)\t\t!literal"
+   [(set_attr "type" "ldsym")])
+ 
  (define_insn "*movdi_er_nofix"
!   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q")
! 	(match_operand:DI 1 "input_operand" "rJ,K,L,T,m,rJ,*fJ,Q,*f"))]
    "TARGET_EXPLICIT_RELOCS && ! TARGET_FIX
     && (register_operand (operands[0], DImode)
!        || reg_or_0_operand (operands[1], DImode))"
    "@
     mov %r1,%0
     lda %0,%1($31)
     ldah %0,%h1($31)
     ldah %0,%H1
     ldq%A1 %0,%1
     stq%A0 %r1,%0
     fmov %R1,%0
     ldt %0,%1
     stt %R1,%0"
!   [(set_attr "type" "ilog,iadd,iadd,iadd,ild,ist,fcpys,fld,fst")])
  
  ;; The 'U' constraint matches symbolic operands on Unicos/Mk. Those should
  ;; have been split up by the rules above but we shouldn't reject the
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 5359,5376 ****
     (set_attr "length" "*,*,*,16,*,*,*,*,*,*")])
  
  (define_insn "*movdi_er_fix"
!   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q,r,*f")
! 	(match_operand:DI 1 "input_operand" "rJ,K,L,T,s,m,rJ,*fJ,Q,*f,*f,r"))]
    "TARGET_EXPLICIT_RELOCS && TARGET_FIX
     && (register_operand (operands[0], DImode)
!        || reg_or_0_operand (operands[1], DImode))
!    && ! local_symbolic_operand (operands[1], DImode)"
    "@
     mov %r1,%0
     lda %0,%1($31)
     ldah %0,%h1($31)
     ldah %0,%H1
-    ldq %0,%1($29)\t\t!literal
     ldq%A1 %0,%1
     stq%A0 %r1,%0
     fmov %R1,%0
--- 5428,5443 ----
     (set_attr "length" "*,*,*,16,*,*,*,*,*,*")])
  
  (define_insn "*movdi_er_fix"
!   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q,r,*f")
! 	(match_operand:DI 1 "input_operand" "rJ,K,L,T,m,rJ,*fJ,Q,*f,*f,r"))]
    "TARGET_EXPLICIT_RELOCS && TARGET_FIX
     && (register_operand (operands[0], DImode)
!        || reg_or_0_operand (operands[1], DImode))"
    "@
     mov %r1,%0
     lda %0,%1($31)
     ldah %0,%h1($31)
     ldah %0,%H1
     ldq%A1 %0,%1
     stq%A0 %r1,%0
     fmov %R1,%0
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 5378,5384 ****
     stt %R1,%0
     ftoit %1,%0
     itoft %1,%0"
!   [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
  
  (define_insn "*movdi_fix"
    [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q,r,*f")
--- 5445,5451 ----
     stt %R1,%0
     ftoit %1,%0
     itoft %1,%0"
!   [(set_attr "type" "ilog,iadd,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")])
  
  (define_insn "*movdi_fix"
    [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q,r,*f")
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 6260,6282 ****
  ;; with them.
  
  (define_expand "prologue_ldgp"
!   [(unspec_volatile [(const_int 0)] UNSPECV_LDGP1)
!    (unspec_volatile [(const_int 0)] UNSPECV_LDGP2)]
    ""
!   "")
  
! (define_insn "*prologue_ldgp_1_er"
!   [(unspec_volatile [(const_int 0)] UNSPECV_LDGP1)]
!   "TARGET_EXPLICIT_RELOCS"
!   "ldah $29,0($27)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*\n$%~..ng:")
  
  (define_insn "*prologue_ldgp_1"
!   [(unspec_volatile [(const_int 0)] UNSPECV_LDGP1)]
    ""
!   "ldgp $29,0($27)\n$%~..ng:")
  
  (define_insn "*prologue_ldgp_2"
!   [(unspec_volatile [(const_int 0)] UNSPECV_LDGP2)]
    ""
    "")
  
--- 6327,6382 ----
  ;; with them.
  
  (define_expand "prologue_ldgp"
!   [(set (match_dup 0)
! 	(unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
!    (set (match_dup 0)
! 	(unspec_volatile:DI [(match_dup 0) (match_dup 2)] UNSPECV_PLDGP2))]
    ""
! {
!   operands[0] = pic_offset_table_rtx;
!   operands[1] = gen_rtx_REG (Pmode, 27);
!   operands[2] = (TARGET_EXPLICIT_RELOCS
! 		 ? GEN_INT (alpha_next_sequence_number++)
! 		 : const0_rtx);
! })
  
! (define_insn "*ldgp_er_1"
!   [(set (match_operand:DI 0 "register_operand" "=r")
! 	(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
! 			     (match_operand 2 "const_int_operand" "")]
! 			    UNSPECV_LDGP1))]
!   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
!   "ldah %0,0(%1)\t\t!gpdisp!%2")
! 
! (define_insn "*ldgp_er_2"
!   [(set (match_operand:DI 0 "register_operand" "=r")
! 	(unspec:DI [(match_operand:DI 1 "register_operand" "r")
! 		    (match_operand 2 "const_int_operand" "")]
! 		   UNSPEC_LDGP2))]
!   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
!   "lda %0,0(%1)\t\t!gpdisp!%2")
  
+ (define_insn "*prologue_ldgp_er_2"
+   [(set (match_operand:DI 0 "register_operand" "=r")
+ 	(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
+ 			     (match_operand 2 "const_int_operand" "")]
+ 		   	    UNSPECV_PLDGP2))]
+   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+   "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:")
+ 
  (define_insn "*prologue_ldgp_1"
!   [(set (match_operand:DI 0 "register_operand" "=r")
! 	(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
! 			     (match_operand 2 "const_int_operand" "")]
! 			    UNSPECV_LDGP1))]
    ""
!   "ldgp %0,0(%1)\n$%~..ng:")
  
  (define_insn "*prologue_ldgp_2"
!   [(set (match_operand:DI 0 "register_operand" "=r")
! 	(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
! 			     (match_operand 2 "const_int_operand" "")]
! 		   	    UNSPECV_PLDGP2))]
    ""
    "")
  
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 6359,6409 ****
    "jmp $31,(%0),0"
    [(set_attr "type" "ibr")])
  
! (define_insn "*builtin_setjmp_receiver_sub_label_er"
    [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
    "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && TARGET_AS_CAN_SUBTRACT_LABELS"
!   "\n$LSJ%=:\;ldah $29,0($27)\t\t!gpdisp!%*\;lda $29,$LSJ%=-%l0($29)\t\t!gpdisp!%*"
!   [(set_attr "length" "8")
!    (set_attr "type" "multi")])
  
! (define_insn "*builtin_setjmp_receiver_sub_label"
    [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
!   "TARGET_ABI_OSF && TARGET_AS_CAN_SUBTRACT_LABELS"
!   "\n$LSJ%=:\;ldgp $29,$LSJ%=-%l0($27)"
!   [(set_attr "length" "8")
!    (set_attr "type" "multi")])
  
! (define_insn "*builtin_setjmp_receiver_er"
    [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
!   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
!   "br $29,$LSJ%=\n$LSJ%=:\;ldah $29,0($29)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
    [(set_attr "length" "12")
     (set_attr "type" "multi")])
  
! (define_insn "builtin_setjmp_receiver"
    [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
    "TARGET_ABI_OSF"
!   "br $29,$LSJ%=\n$LSJ%=:\;ldgp $29,0($29)"
!   [(set_attr "length" "12")
!    (set_attr "type" "multi")])
  
  (define_expand "exception_receiver"
    [(unspec_volatile [(match_dup 0)] UNSPECV_EHR)]
    "TARGET_ABI_OSF"
  {
    if (TARGET_LD_BUGGY_LDGP)
      operands[0] = alpha_gp_save_rtx ();
    else
      operands[0] = const0_rtx;
  })
  
- (define_insn "*exception_receiver_1_er"
-   [(unspec_volatile [(const_int 0)] UNSPECV_EHR)]
-   "TARGET_EXPLICIT_RELOCS && ! TARGET_LD_BUGGY_LDGP"
-   "ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
-   [(set_attr "length" "8")
-    (set_attr "type" "multi")])
- 
  (define_insn "*exception_receiver_1"
    [(unspec_volatile [(const_int 0)] UNSPECV_EHR)]
    "! TARGET_LD_BUGGY_LDGP"
--- 6459,6540 ----
    "jmp $31,(%0),0"
    [(set_attr "type" "ibr")])
  
! (define_insn "*builtin_setjmp_receiver_er_sl_1"
    [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
    "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && TARGET_AS_CAN_SUBTRACT_LABELS"
!   "lda $27,$LSJ%=-%l0($27)\n$LSJ%=:")
!   
! (define_insn "*builtin_setjmp_receiver_er_1"
!   [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
!   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
!   "br $27,$LSJ%=\n$LSJ%=:"
!   [(set_attr "type" "ibr")])
  
! (define_split
    [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
!   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
!    && prev_nonnote_insn (insn) == operands[0]"
!   [(const_int 0)]
!   "DONE;")
  
! (define_insn "*builtin_setjmp_receiver_1"
    [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
!   "TARGET_ABI_OSF"
!   "br $27,$LSJ%=\n$LSJ%=:\;ldgp $29,0($27)"
    [(set_attr "length" "12")
     (set_attr "type" "multi")])
  
! (define_expand "builtin_setjmp_receiver_er"
!   [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)
!    (set (match_dup 1)
! 	(unspec_volatile:DI [(match_dup 2) (match_dup 3)] UNSPECV_LDGP1))
!    (set (match_dup 1)
! 	(unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LDGP2))]
!   ""
! {
!   operands[1] = pic_offset_table_rtx;
!   operands[2] = gen_rtx_REG (Pmode, 27);
!   operands[3] = GEN_INT (alpha_next_sequence_number++);
! })
! 
! (define_expand "builtin_setjmp_receiver"
    [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
    "TARGET_ABI_OSF"
! {
!   if (TARGET_EXPLICIT_RELOCS)
!     {
!       emit_insn (gen_builtin_setjmp_receiver_er (operands[0]));
!       DONE;
!     }
! })
  
+ (define_expand "exception_receiver_er"
+   [(set (match_dup 0)
+ 	(unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
+    (set (match_dup 0)
+ 	(unspec:DI [(match_dup 0) (match_dup 2)] UNSPEC_LDGP2))]
+   ""
+ {
+   operands[0] = pic_offset_table_rtx;
+   operands[1] = gen_rtx_REG (Pmode, 26);
+   operands[2] = GEN_INT (alpha_next_sequence_number++);
+ })
+ 
  (define_expand "exception_receiver"
    [(unspec_volatile [(match_dup 0)] UNSPECV_EHR)]
    "TARGET_ABI_OSF"
  {
    if (TARGET_LD_BUGGY_LDGP)
      operands[0] = alpha_gp_save_rtx ();
+   else if (TARGET_EXPLICIT_RELOCS)
+     {
+       emit_insn (gen_exception_receiver_er ());
+       DONE;
+     }
    else
      operands[0] = const0_rtx;
  })
  
  (define_insn "*exception_receiver_1"
    [(unspec_volatile [(const_int 0)] UNSPECV_EHR)]
    "! TARGET_LD_BUGGY_LDGP"
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 6411,6426 ****
    [(set_attr "length" "8")
     (set_attr "type" "multi")])
  
- ;; ??? We don't represent the usage of $29 properly in address loads
- ;; and function calls.  This leads to the following move being deleted
- ;; as dead code unless it is represented as a volatile unspec.
- 
  (define_insn "*exception_receiver_2"
    [(unspec_volatile [(match_operand:DI 0 "nonimmediate_operand" "r,m")]
  		    UNSPECV_EHR)]
    "TARGET_LD_BUGGY_LDGP"
    "@
!    mov %0,$29
     ldq $29,%0"
    [(set_attr "type" "ilog,ild")])
  
--- 6542,6553 ----
    [(set_attr "length" "8")
     (set_attr "type" "multi")])
  
  (define_insn "*exception_receiver_2"
    [(unspec_volatile [(match_operand:DI 0 "nonimmediate_operand" "r,m")]
  		    UNSPECV_EHR)]
    "TARGET_LD_BUGGY_LDGP"
    "@
!    bis $31,%0,$29
     ldq $29,%0"
    [(set_attr "type" "ilog,ild")])
  
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 6555,6591 ****
  ;; The call patterns are at the end of the file because their
  ;; wildcard operand0 interferes with nice recognition.
  
! (define_insn "*call_value_umk"
    [(set (match_operand 0 "" "")
! 	(call (mem:DI (match_operand:DI 1 "call_operand" "r"))
  	      (match_operand 2 "" "")))
!    (use (reg:DI 25))
     (clobber (reg:DI 26))]
!   "TARGET_ABI_UNICOSMK"
!   "jsr $26,(%1)"
    [(set_attr "type" "jsr")])
  
! (define_insn "*call_value_osf_1_er"
    [(set (match_operand 0 "" "")
! 	(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,i"))
  	      (match_operand 2 "" "")))
!    (clobber (reg:DI 27))
     (clobber (reg:DI 26))]
!   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
    "@
!    jsr $26,($27),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
     bsr $26,$%1..ng
!    ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),%1\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
    [(set_attr "type" "jsr")
!    (set_attr "length" "12,*,16")])
  
  (define_insn "*call_value_osf_1"
    [(set (match_operand 0 "" "")
! 	(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,i"))
  	      (match_operand 2 "" "")))
!    (clobber (reg:DI 27))
     (clobber (reg:DI 26))]
!   "TARGET_ABI_OSF"
    "@
     jsr $26,($27),0\;ldgp $29,0($26)
     bsr $26,$%1..ng
--- 6682,6800 ----
  ;; The call patterns are at the end of the file because their
  ;; wildcard operand0 interferes with nice recognition.
  
! (define_insn "*call_value_osf_1_er"
    [(set (match_operand 0 "" "")
! 	(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
  	      (match_operand 2 "" "")))
!    (use (reg:DI 29))
     (clobber (reg:DI 26))]
!   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
!   "@
!    jsr $26,(%1),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
!    bsr $26,$%1..ng
!    ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),0\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
!   [(set_attr "type" "jsr")
!    (set_attr "length" "12,*,16")])
! 
! ;; We must use peep2 instead of a split because we need accurate life
! ;; information for $gp.  Consider the case of { bar(); while (1); }.
! (define_peephole2
!   [(parallel [(set (match_operand 0 "" "")
! 		   (call (mem:DI (match_operand:DI 1 "call_operand" ""))
! 		         (match_operand 2 "" "")))
! 	      (use (reg:DI 29))
! 	      (clobber (reg:DI 26))])]
!   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF  && reload_completed
!    && ! current_file_function_operand (operands[0], Pmode)
!    && peep2_regno_dead_p (1, 29)"
!   [(parallel [(set (match_dup 0)
! 		   (call (mem:DI (match_dup 3))
! 			 (match_dup 2)))
! 	      (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
! 	      (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
! 	      (use (match_dup 1))])]
! {
!   if (CONSTANT_P (operands[1]))
!     {
!       operands[3] = gen_rtx_REG (Pmode, 27);
!       emit_move_insn (operands[3], operands[1]);
!     }
!   else
!     {
!       operands[3] = operands[1];
!       operands[1] = const0_rtx;
!     }
! })
! 
! (define_peephole2
!   [(parallel [(set (match_operand 0 "" "")
! 		   (call (mem:DI (match_operand:DI 1 "call_operand" ""))
! 		         (match_operand 2 "" "")))
! 	      (use (reg:DI 29))
! 	      (clobber (reg:DI 26))])]
!   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF  && reload_completed
!    && ! current_file_function_operand (operands[0], Pmode)
!    && ! peep2_regno_dead_p (1, 29)"
!   [(parallel [(set (match_dup 0)
! 		   (call (mem:DI (match_dup 3))
! 			 (match_dup 2)))
! 	      (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
! 	      (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
! 	      (use (match_dup 1))])
!    (set (reg:DI 29)
! 	(unspec_volatile:DI [(reg:DI 26) (match_dup 4)] UNSPECV_LDGP1))
!    (set (reg:DI 29)
! 	(unspec:DI [(reg:DI 29) (match_dup 4)] UNSPEC_LDGP2))]
! {
!   if (CONSTANT_P (operands[1]))
!     {
!       operands[3] = gen_rtx_REG (Pmode, 27);
!       emit_move_insn (operands[3], operands[1]);
!     }
!   else
!     {
!       operands[3] = operands[1];
!       operands[1] = const0_rtx;
!     }
!   operands[4] = GEN_INT (alpha_next_sequence_number++);
! })
! 
! ;; We add a blockage unspec_volatile to prevent insns from moving down
! ;; from above the call to in between the call and the ldah gpdisp.
! (define_insn "*call_value_osf_2_er"
!   [(set (match_operand 0 "" "")
! 	(call (mem:DI (match_operand:DI 1 "register_operand" "c"))
! 	      (match_operand 2 "" "")))
!    (set (reg:DI 26)
! 	(plus:DI (pc) (const_int 4)))
!    (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
!    (use (match_operand 3 "" ""))]
!   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
!   "jsr $26,(%1),%3"
    [(set_attr "type" "jsr")])
  
! (define_insn "*call_value_osf_1_noreturn"
    [(set (match_operand 0 "" "")
! 	(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
  	      (match_operand 2 "" "")))
!    (use (reg:DI 29))
     (clobber (reg:DI 26))]
!   "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
!    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
    "@
!    jsr $26,($27),0
     bsr $26,$%1..ng
!    jsr $26,%1"
    [(set_attr "type" "jsr")
!    (set_attr "length" "*,*,8")])
  
  (define_insn "*call_value_osf_1"
    [(set (match_operand 0 "" "")
! 	(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
  	      (match_operand 2 "" "")))
!    (use (reg:DI 29))
     (clobber (reg:DI 26))]
!   "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
    "@
     jsr $26,($27),0\;ldgp $29,0($26)
     bsr $26,$%1..ng
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 6596,6609 ****
  (define_insn "*sibcall_value_osf_1"
    [(set (match_operand 0 "" "")
  	(call (mem:DI (match_operand:DI 1 "current_file_function_operand" "R"))
! 	      (match_operand 2 "" "")))]
    "TARGET_ABI_OSF"
    "br $31,$%1..ng"
    [(set_attr "type" "jsr")])
  
  (define_insn "*call_value_nt_1"
    [(set (match_operand 0 "" "")
! 	(call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
  	      (match_operand 2 "" "")))
     (clobber (reg:DI 26))]
    "TARGET_ABI_WINDOWS_NT"
--- 6805,6819 ----
  (define_insn "*sibcall_value_osf_1"
    [(set (match_operand 0 "" "")
  	(call (mem:DI (match_operand:DI 1 "current_file_function_operand" "R"))
! 	      (match_operand 2 "" "")))
!    (use (reg:DI 29))]
    "TARGET_ABI_OSF"
    "br $31,$%1..ng"
    [(set_attr "type" "jsr")])
  
  (define_insn "*call_value_nt_1"
    [(set (match_operand 0 "" "")
! 	(call (mem:DI (match_operand:DI 1 "call_operand" "r,R,s"))
  	      (match_operand 2 "" "")))
     (clobber (reg:DI 26))]
    "TARGET_ABI_WINDOWS_NT"
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 6616,6622 ****
  
  (define_insn "*call_value_vms_1"
    [(set (match_operand 0 "" "")
! 	(call (mem:DI (match_operand:DI 1 "call_operand" "r,i"))
  	      (match_operand 2 "" "")))
     (use (match_operand:DI 3 "nonimmediate_operand" "r,m"))
     (use (reg:DI 25))
--- 6826,6832 ----
  
  (define_insn "*call_value_vms_1"
    [(set (match_operand 0 "" "")
! 	(call (mem:DI (match_operand:DI 1 "call_operand" "r,s"))
  	      (match_operand 2 "" "")))
     (use (match_operand:DI 3 "nonimmediate_operand" "r,m"))
     (use (reg:DI 25))
*************** fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi
*** 6628,6630 ****
--- 6838,6851 ----
     ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)"
    [(set_attr "type" "jsr")
     (set_attr "length" "12,16")])
+ 
+ (define_insn "*call_value_umk"
+   [(set (match_operand 0 "" "")
+ 	(call (mem:DI (match_operand:DI 1 "call_operand" "r"))
+ 	      (match_operand 2 "" "")))
+    (use (reg:DI 25))
+    (clobber (reg:DI 26))]
+   "TARGET_ABI_UNICOSMK"
+   "jsr $26,(%1)"
+   [(set_attr "type" "jsr")])
+ 


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