Index: gcc/target-insns.def
===================================================================
--- gcc/target-insns.def	2015-07-28 20:56:29.721512028 +0100
+++ gcc/target-insns.def	2015-07-28 20:56:29.713512127 +0100
@@ -34,6 +34,7 @@ DEF_TARGET_INSN (allocate_stack, (rtx x0
 DEF_TARGET_INSN (builtin_longjmp, (rtx x0))
 DEF_TARGET_INSN (builtin_setjmp_receiver, (rtx x0))
 DEF_TARGET_INSN (builtin_setjmp_setup, (rtx x0))
+DEF_TARGET_INSN (can_extend, (rtx x0, rtx x1))
 DEF_TARGET_INSN (canonicalize_funcptr_for_compare, (rtx x0, rtx x1))
 DEF_TARGET_INSN (casesi, (rtx x0, rtx x1, rtx x2, rtx x3, rtx x4))
 DEF_TARGET_INSN (check_stack, (rtx x0))
@@ -58,6 +59,7 @@ DEF_TARGET_INSN (prefetch, (rtx x0, rtx
 DEF_TARGET_INSN (probe_stack, (rtx x0))
 DEF_TARGET_INSN (probe_stack_address, (rtx x0))
 DEF_TARGET_INSN (prologue, (void))
+DEF_TARGET_INSN (ptr_extend, (rtx x0, rtx x1))
 DEF_TARGET_INSN (restore_stack_block, (rtx x0, rtx x1))
 DEF_TARGET_INSN (restore_stack_function, (rtx x0, rtx x1))
 DEF_TARGET_INSN (restore_stack_nonlocal, (rtx x0, rtx x1))
Index: gcc/optabs.c
===================================================================
--- gcc/optabs.c	2015-07-28 20:56:29.721512028 +0100
+++ gcc/optabs.c	2015-07-28 20:56:29.709512177 +0100
@@ -4851,10 +4851,8 @@ can_extend_p (machine_mode to_mode, mach
 	      int unsignedp)
 {
   convert_optab tab;
-#ifdef HAVE_ptr_extend
-  if (unsignedp < 0)
-    return CODE_FOR_ptr_extend;
-#endif
+  if (unsignedp < 0 && targetm.have_ptr_extend ())
+    return targetm.code_for_ptr_extend;
 
   tab = unsignedp ? zext_optab : sext_optab;
   return convert_optab_handler (tab, to_mode, from_mode);
Index: gcc/simplify-rtx.c
===================================================================
--- gcc/simplify-rtx.c	2015-07-28 20:56:29.721512028 +0100
+++ gcc/simplify-rtx.c	2015-07-28 20:56:29.713512127 +0100
@@ -1431,7 +1431,7 @@ simplify_unary_operation_1 (enum rtx_cod
 	    }
 	}
 
-#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
+#if defined(POINTERS_EXTEND_UNSIGNED)
       /* As we do not know which address space the pointer is referring to,
 	 we can do this only if the target does not support different pointer
 	 or address modes depending on the address space.  */
@@ -1442,7 +1442,8 @@ simplify_unary_operation_1 (enum rtx_cod
 	      || (GET_CODE (op) == SUBREG
 		  && REG_P (SUBREG_REG (op))
 		  && REG_POINTER (SUBREG_REG (op))
-		  && GET_MODE (SUBREG_REG (op)) == Pmode)))
+		  && GET_MODE (SUBREG_REG (op)) == Pmode))
+	  && !targetm.have_ptr_extend ())
 	return convert_memory_address (Pmode, op);
 #endif
       break;
@@ -1552,7 +1553,7 @@ simplify_unary_operation_1 (enum rtx_cod
 				     GET_MODE (SUBREG_REG (op)));
 	}
 
-#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
+#if defined(POINTERS_EXTEND_UNSIGNED)
       /* As we do not know which address space the pointer is referring to,
 	 we can do this only if the target does not support different pointer
 	 or address modes depending on the address space.  */
@@ -1563,7 +1564,8 @@ simplify_unary_operation_1 (enum rtx_cod
 	      || (GET_CODE (op) == SUBREG
 		  && REG_P (SUBREG_REG (op))
 		  && REG_POINTER (SUBREG_REG (op))
-		  && GET_MODE (SUBREG_REG (op)) == Pmode)))
+		  && GET_MODE (SUBREG_REG (op)) == Pmode))
+	  && !targetm.have_ptr_extend ())
 	return convert_memory_address (Pmode, op);
 #endif
       break;
Index: gcc/emit-rtl.c
===================================================================
--- gcc/emit-rtl.c	2015-07-28 20:56:29.721512028 +0100
+++ gcc/emit-rtl.c	2015-07-28 20:56:29.713512127 +0100
@@ -1159,9 +1159,10 @@ set_reg_attrs_from_value (rtx reg, rtx x
 	 || GET_CODE (x) == TRUNCATE
 	 || (GET_CODE (x) == SUBREG && subreg_lowpart_p (x)))
     {
-#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
-      if ((GET_CODE (x) == SIGN_EXTEND && POINTERS_EXTEND_UNSIGNED)
-	  || (GET_CODE (x) != SIGN_EXTEND && ! POINTERS_EXTEND_UNSIGNED))
+#if defined(POINTERS_EXTEND_UNSIGNED)
+      if (((GET_CODE (x) == SIGN_EXTEND && POINTERS_EXTEND_UNSIGNED)
+	   || (GET_CODE (x) != SIGN_EXTEND && ! POINTERS_EXTEND_UNSIGNED))
+	  && !targetm.have_ptr_extend ())
 	can_be_reg_pointer = false;
 #endif
       x = XEXP (x, 0);
Index: gcc/rtlanal.c
===================================================================
--- gcc/rtlanal.c	2015-07-28 20:56:29.721512028 +0100
+++ gcc/rtlanal.c	2015-07-28 20:56:29.713512127 +0100
@@ -4278,7 +4278,7 @@ nonzero_bits1 (const_rtx x, machine_mode
   switch (code)
     {
     case REG:
-#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
+#if defined(POINTERS_EXTEND_UNSIGNED)
       /* If pointers extend unsigned and this is a pointer in Pmode, say that
 	 all the bits above ptr_mode are known to be zero.  */
       /* As we do not know which address space the pointer is referring to,
@@ -4286,7 +4286,8 @@ nonzero_bits1 (const_rtx x, machine_mode
 	 or address modes depending on the address space.  */
       if (target_default_pointer_address_modes_p ()
 	  && POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
-	  && REG_POINTER (x))
+	  && REG_POINTER (x)
+	  && !targetm.have_ptr_extend ())
 	nonzero &= GET_MODE_MASK (ptr_mode);
 #endif
 
@@ -4785,7 +4786,7 @@ num_sign_bit_copies1 (const_rtx x, machi
     {
     case REG:
 
-#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
+#if defined(POINTERS_EXTEND_UNSIGNED)
       /* If pointers extend signed and this is a pointer in Pmode, say that
 	 all the bits above ptr_mode are known to be sign bit copies.  */
       /* As we do not know which address space the pointer is referring to,
@@ -4793,7 +4794,8 @@ num_sign_bit_copies1 (const_rtx x, machi
 	 or address modes depending on the address space.  */
       if (target_default_pointer_address_modes_p ()
 	  && ! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
-	  && mode == Pmode && REG_POINTER (x))
+	  && mode == Pmode && REG_POINTER (x)
+	  && !targetm.have_ptr_extend ())
 	return GET_MODE_PRECISION (Pmode) - GET_MODE_PRECISION (ptr_mode) + 1;
 #endif
 
