aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorSteve Ellcey <sellcey@marvell.com>2019-01-11 15:53:02 +0000
committerSteve Ellcey <sje@gcc.gnu.org>2019-01-11 15:53:02 +0000
commitb3650d40fab1ed168be0109372ec49fcff95a18b (patch)
tree67291192b8cc5e5873f3b1e1d0896cd30b753ad0 /gcc/config
parent17a73b3c47f58155350af2e1ca359e915ffedcae (diff)
downloadgcc-b3650d40fab1ed168be0109372ec49fcff95a18b.zip
gcc-b3650d40fab1ed168be0109372ec49fcff95a18b.tar.gz
gcc-b3650d40fab1ed168be0109372ec49fcff95a18b.tar.bz2
aarch64.c (aarch64_simd_call_p): New function.
2019-01-11 Steve Ellcey <sellcey@marvell.com> * config/aarch64/aarch64.c (aarch64_simd_call_p): New function. (aarch64_remove_extra_call_preserved_regs): New function. (TARGET_REMOVE_EXTRA_CALL_PRESERVED_REGS): New macro. * doc/tm.texi.in (TARGET_REMOVE_EXTRA_CALL_PRESERVED_REGS): New hook. * doc/tm.texi: Regenerate. * final.c (get_call_reg_set_usage): Call new hook. * target.def (remove_extra_call_preserved_regs): New hook. * targhooks.c (default_remove_extra_call_preserved_regs): New function. * targhooks.h (default_remove_extra_call_preserved_regs): New function. From-SVN: r267846
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/aarch64/aarch64.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 1c300af..588fc80 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -1655,6 +1655,45 @@ aarch64_reg_save_mode (tree fndecl, unsigned regno)
: (aarch64_simd_decl_p (fndecl) ? E_TFmode : E_DFmode);
}
+/* Return true if the instruction is a call to a SIMD function, false
+ if it is not a SIMD function or if we do not know anything about
+ the function. */
+
+static bool
+aarch64_simd_call_p (rtx_insn *insn)
+{
+ rtx symbol;
+ rtx call;
+ tree fndecl;
+
+ gcc_assert (CALL_P (insn));
+ call = get_call_rtx_from (insn);
+ symbol = XEXP (XEXP (call, 0), 0);
+ if (GET_CODE (symbol) != SYMBOL_REF)
+ return false;
+ fndecl = SYMBOL_REF_DECL (symbol);
+ if (!fndecl)
+ return false;
+
+ return aarch64_simd_decl_p (fndecl);
+}
+
+/* Implement TARGET_REMOVE_EXTRA_CALL_PRESERVED_REGS. If INSN calls
+ a function that uses the SIMD ABI, take advantage of the extra
+ call-preserved registers that the ABI provides. */
+
+void
+aarch64_remove_extra_call_preserved_regs (rtx_insn *insn,
+ HARD_REG_SET *return_set)
+{
+ if (aarch64_simd_call_p (insn))
+ {
+ for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ if (FP_SIMD_SAVED_REGNUM_P (regno))
+ CLEAR_HARD_REG_BIT (*return_set, regno);
+ }
+}
+
/* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED. The callee only saves
the lower 64 bits of a 128-bit register. Tell the compiler the callee
clobbers the top 64 bits when restoring the bottom 64 bits. */
@@ -18825,6 +18864,10 @@ aarch64_libgcc_floating_mode_supported_p
#define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
aarch64_hard_regno_call_part_clobbered
+#undef TARGET_REMOVE_EXTRA_CALL_PRESERVED_REGS
+#define TARGET_REMOVE_EXTRA_CALL_PRESERVED_REGS \
+ aarch64_remove_extra_call_preserved_regs
+
#undef TARGET_CONSTANT_ALIGNMENT
#define TARGET_CONSTANT_ALIGNMENT aarch64_constant_alignment