From 002ffd3caa684c3eb30f8f53206439b7aa34b370 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 30 Sep 2019 16:19:43 +0000 Subject: [PATCH] Add a target hook for getting an ABI from a function type 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-30 Richard Sandiford 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. From-SVN: r276308 --- gcc/ChangeLog | 13 +++++++++++++ gcc/config/aarch64/aarch64.c | 32 ++++++++++++++++++++++++++++++++ gcc/config/aarch64/aarch64.h | 1 + gcc/doc/tm.texi | 10 ++++++++++ gcc/doc/tm.texi.in | 5 +++++ gcc/function-abi.cc | 2 ++ gcc/target.def | 9 +++++++++ gcc/target.h | 3 +++ 8 files changed, 75 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 858f596..812dadb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,18 @@ 2019-09-30 Richard Sandiford + * 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. + +2019-09-30 Richard Sandiford + * Makefile.in (OBJS): Add function-abi.o. (GTFILES): Add function-abi.h. * function-abi.cc: New file. diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 29c070d..211459c 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -74,6 +74,7 @@ #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 @@ svpattern_token (enum aarch64_svpattern pattern) 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 regno, machine_mode mode) 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 @@ -21024,6 +21053,9 @@ aarch64_libgcc_floating_mode_supported_p #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 diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index 7bbeed4..5aff106 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -783,6 +783,7 @@ enum aarch64_abi_type enum arm_pcs { ARM_PCS_AAPCS64, /* Base standard AAPCS for 64 bit. */ + ARM_PCS_SIMD, /* For aarch64_vector_pcs functions. */ ARM_PCS_UNKNOWN }; diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index a86c210..0f79d38 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -1898,6 +1898,16 @@ must be defined. Modern ports should define @code{CALL_REALLY_USED_REGISTERS}. @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 diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 06dfcda..ed605c0 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -1709,6 +1709,11 @@ must be defined. Modern ports should define @code{CALL_REALLY_USED_REGISTERS}. @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 diff --git a/gcc/function-abi.cc b/gcc/function-abi.cc index e7c8581..c77989a 100644 --- a/gcc/function-abi.cc +++ b/gcc/function-abi.cc @@ -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; } diff --git a/gcc/target.def b/gcc/target.def index f9446fa..803c7a3 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -4943,6 +4943,15 @@ If this hook is not defined, then FUNCTION_VALUE_REGNO_P will be used.", 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, diff --git a/gcc/target.h b/gcc/target.h index a656930..9f80658 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -152,6 +152,9 @@ class _stmt_vec_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 *); -- 2.7.4