This patch adds a target hook that allows targets to return the ABI associated with a particular function type. Generally, when multiple ABIs are in use, it must be possible to tell from a function type and its attributes which ABI it is using.
2019-09-11 Richard Sandiford <richard.sandif...@arm.com> gcc/ * target.def (fntype_abi): New target hook. * doc/tm.texi.in (TARGET_FNTYPE_ABI): Likewise. * doc/tm.texi: Regenerate. * target.h (predefined_function_abi): Declare. * function-abi.cc (fntype_abi): Call targetm.calls.fntype_abi, if defined. * config/aarch64/aarch64.h (ARM_PCS_SIMD): New arm_pcs value. * config/aarch64/aarch64.c: Include function-abi.h. (aarch64_simd_abi, aarch64_fntype_abi): New functions. (TARGET_FNTYPE_ABI): Define. Index: gcc/target.def =================================================================== --- gcc/target.def 2019-09-09 17:51:55.848574716 +0100 +++ gcc/target.def 2019-09-11 19:47:20.406290945 +0100 @@ -4892,6 +4892,15 @@ If this hook is not defined, then FUNCTI bool, (const unsigned int regno), default_function_value_regno_p) +DEFHOOK +(fntype_abi, + "Return the ABI used by a function with type @var{type}; see the\n\ +definition of @code{predefined_function_abi} for details of the ABI\n\ +descriptor. Targets only need to define this hook if they support\n\ +interoperability between several ABIs in the same translation unit.", + const predefined_function_abi &, (const_tree type), + NULL) + /* ??? Documenting this hook requires a GFDL license grant. */ DEFHOOK_UNDOC (internal_arg_pointer, Index: gcc/doc/tm.texi.in =================================================================== --- gcc/doc/tm.texi.in 2019-09-10 19:57:04.713041281 +0100 +++ gcc/doc/tm.texi.in 2019-09-11 19:47:20.402290974 +0100 @@ -1709,6 +1709,11 @@ must be defined. Modern ports should de @cindex call-used register @cindex call-clobbered register @cindex call-saved register +@hook TARGET_FNTYPE_ABI + +@cindex call-used register +@cindex call-clobbered register +@cindex call-saved register @hook TARGET_HARD_REGNO_CALL_PART_CLOBBERED @hook TARGET_REMOVE_EXTRA_CALL_PRESERVED_REGS Index: gcc/doc/tm.texi =================================================================== --- gcc/doc/tm.texi 2019-09-10 19:57:04.713041281 +0100 +++ gcc/doc/tm.texi 2019-09-11 19:47:20.402290974 +0100 @@ -1898,6 +1898,16 @@ must be defined. Modern ports should de @cindex call-used register @cindex call-clobbered register @cindex call-saved register +@deftypefn {Target Hook} {const predefined_function_abi &} TARGET_FNTYPE_ABI (const_tree @var{type}) +Return the ABI used by a function with type @var{type}; see the +definition of @code{predefined_function_abi} for details of the ABI +descriptor. Targets only need to define this hook if they support +interoperability between several ABIs in the same translation unit. +@end deftypefn + +@cindex call-used register +@cindex call-clobbered register +@cindex call-saved register @deftypefn {Target Hook} bool TARGET_HARD_REGNO_CALL_PART_CLOBBERED (rtx_insn *@var{insn}, unsigned int @var{regno}, machine_mode @var{mode}) This hook should return true if @var{regno} is partly call-saved and partly call-clobbered, and if a value of mode @var{mode} would be partly Index: gcc/target.h =================================================================== --- gcc/target.h 2019-08-20 09:52:11.022820825 +0100 +++ gcc/target.h 2019-09-11 19:47:20.406290945 +0100 @@ -152,6 +152,9 @@ struct noce_if_info; /* This is defined in calls.h. */ class function_arg_info; +/* This is defined in function-abi.h. */ +class predefined_function_abi; + /* These are defined in tree-vect-stmts.c. */ extern tree stmt_vectype (class _stmt_vec_info *); extern bool stmt_in_inner_loop_p (class _stmt_vec_info *); Index: gcc/function-abi.cc =================================================================== --- gcc/function-abi.cc 2019-09-11 19:47:07.490381964 +0100 +++ gcc/function-abi.cc 2019-09-11 19:47:20.402290974 +0100 @@ -132,6 +132,8 @@ const predefined_function_abi & fntype_abi (const_tree type) { gcc_assert (FUNC_OR_METHOD_TYPE_P (type)); + if (targetm.calls.fntype_abi) + return targetm.calls.fntype_abi (type); return default_function_abi; } Index: gcc/config/aarch64/aarch64.h =================================================================== --- gcc/config/aarch64/aarch64.h 2019-09-05 08:49:31.193737018 +0100 +++ gcc/config/aarch64/aarch64.h 2019-09-11 19:47:20.398291002 +0100 @@ -783,6 +783,7 @@ #define TARGET_ILP32 (aarch64_abi & AARC enum arm_pcs { ARM_PCS_AAPCS64, /* Base standard AAPCS for 64 bit. */ + ARM_PCS_SIMD, /* For aarch64_vector_pcs functions. */ ARM_PCS_UNKNOWN }; Index: gcc/config/aarch64/aarch64.c =================================================================== --- gcc/config/aarch64/aarch64.c 2019-09-11 19:47:00.322432478 +0100 +++ gcc/config/aarch64/aarch64.c 2019-09-11 19:47:20.398291002 +0100 @@ -74,6 +74,7 @@ #define INCLUDE_STRING #include "rtx-vector-builder.h" #include "intl.h" #include "expmed.h" +#include "function-abi.h" /* This file should be included last. */ #include "target-def.h" @@ -1365,6 +1366,24 @@ #define CASE(UPPER, LOWER, VALUE) case A gcc_unreachable (); } +/* Return the descriptor of the SIMD ABI. */ + +static const predefined_function_abi & +aarch64_simd_abi (void) +{ + predefined_function_abi &simd_abi = function_abis[ARM_PCS_SIMD]; + if (!simd_abi.initialized_p ()) + { + HARD_REG_SET full_reg_clobbers + = default_function_abi.full_reg_clobbers (); + for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + if (FP_SIMD_SAVED_REGNUM_P (regno)) + CLEAR_HARD_REG_BIT (full_reg_clobbers, regno); + simd_abi.initialize (ARM_PCS_SIMD, full_reg_clobbers); + } + return simd_abi; +} + /* Generate code to enable conditional branches in functions over 1 MiB. */ const char * aarch64_gen_far_branch (rtx * operands, int pos_label, const char * dest, @@ -1810,6 +1829,16 @@ aarch64_hard_regno_mode_ok (unsigned reg return false; } +/* Implement TARGET_FNTYPE_ABI. */ + +static const predefined_function_abi & +aarch64_fntype_abi (const_tree fntype) +{ + if (lookup_attribute ("aarch64_vector_pcs", TYPE_ATTRIBUTES (fntype))) + return aarch64_simd_abi (); + return default_function_abi; +} + /* Return true if this is a definition of a vectorized simd function. */ static bool @@ -20826,6 +20855,9 @@ #define TARGET_COMP_TYPE_ATTRIBUTES aarc #undef TARGET_GET_MULTILIB_ABI_NAME #define TARGET_GET_MULTILIB_ABI_NAME aarch64_get_multilib_abi_name +#undef TARGET_FNTYPE_ABI +#define TARGET_FNTYPE_ABI aarch64_fntype_abi + #if CHECKING_P #undef TARGET_RUN_TARGET_SELFTESTS #define TARGET_RUN_TARGET_SELFTESTS selftest::aarch64_run_selftests