Bootstrapped & regression-tested on x86_64-linux-gnu and aarch64-linux-gnu. Also tested via config-list.mk. Committed as preapproved.
Thanks, Richard gcc/ * target-insns.def (can_extend, ptr_extend): New targetm instruction patterns. * optabs.c (can_extend_p): Use them instead of HAVE_*/gen_* interface. * simplify-rtx.c (simplify_unary_operation_1): Likewise. * emit-rtl.c (set_reg_attrs_from_value): Likewise. * rtlanal.c (nonzero_bits1): Likewise. (num_sign_bit_copies1): Likewise. 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