aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorYvan Roux <yvan.roux@linaro.org>2015-01-14 12:53:04 +0000
committerYvan Roux <yvan.roux@linaro.org>2015-01-14 12:53:04 +0000
commit0cb00b340e45d1d2ec415b5afc846fc3c507e1cd (patch)
treee685581a2e6164fddd985b7b5c42e38b08b83152 /gcc
parent4be2790b9f6f36666362135f7a71d65e43ea459f (diff)
2015-01-14 Yvan Roux <yvan.roux@linaro.org>
Fix Linaro PR #902 Partial Backport from trunk r211798. 2014-06-18 Radovan Obradovic <robradovic@mips.com> Tom de Vries <tom@codesourcery.com> * config/arm/arm.c (arm_emit_call_insn): Add IP and CC clobbers to CALL_INSN_FUNCTION_USAGE. Backport from trunk r209800. 2014-04-25 Tom de Vries <tom@codesourcery.com> * expr.c (clobber_reg_mode): New function. * expr.h (clobber_reg): New function. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/linaro/gcc-4_9-branch@219597 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog.linaro17
-rw-r--r--gcc/config/arm/arm.c9
-rw-r--r--gcc/expr.c12
-rw-r--r--gcc/expr.h8
4 files changed, 46 insertions, 0 deletions
diff --git a/gcc/ChangeLog.linaro b/gcc/ChangeLog.linaro
index 0657fd421ab..8795ac9a4d7 100644
--- a/gcc/ChangeLog.linaro
+++ b/gcc/ChangeLog.linaro
@@ -1,5 +1,22 @@
2015-01-14 Yvan Roux <yvan.roux@linaro.org>
+ Fix Linaro PR #902
+
+ Partial Backport from trunk r211798.
+ 2014-06-18 Radovan Obradovic <robradovic@mips.com>
+ Tom de Vries <tom@codesourcery.com>
+
+ * config/arm/arm.c (arm_emit_call_insn): Add IP and CC clobbers to
+ CALL_INSN_FUNCTION_USAGE.
+
+ Backport from trunk r209800.
+ 2014-04-25 Tom de Vries <tom@codesourcery.com>
+
+ * expr.c (clobber_reg_mode): New function.
+ * expr.h (clobber_reg): New function.
+
+2015-01-14 Yvan Roux <yvan.roux@linaro.org>
+
Backport from trunk r211783.
2014-06-18 Charles Baylis <charles.baylis@linaro.org>
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 145fb272584..1ef6b0f5d9f 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -17727,6 +17727,15 @@ arm_emit_call_insn (rtx pat, rtx addr)
require_pic_register ();
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), cfun->machine->pic_reg);
}
+
+ if (TARGET_AAPCS_BASED)
+ {
+ /* For AAPCS, IP and CC can be clobbered by veneers inserted by the
+ linker. */
+ rtx *fusage = &CALL_INSN_FUNCTION_USAGE (insn);
+ clobber_reg (fusage, gen_rtx_REG (word_mode, IP_REGNUM));
+ clobber_reg (fusage, gen_rtx_REG (word_mode, CC_REGNUM));
+ }
}
/* Output a 'call' insn. */
diff --git a/gcc/expr.c b/gcc/expr.c
index 75ce5c2ef36..06ae2844f52 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -2343,6 +2343,18 @@ use_reg_mode (rtx *call_fusage, rtx reg, enum machine_mode mode)
= gen_rtx_EXPR_LIST (mode, gen_rtx_USE (VOIDmode, reg), *call_fusage);
}
+/* Add a CLOBBER expression for REG to the (possibly empty) list pointed
+ to by CALL_FUSAGE. REG must denote a hard register. */
+
+void
+clobber_reg_mode (rtx *call_fusage, rtx reg, enum machine_mode mode)
+{
+ gcc_assert (REG_P (reg) && REGNO (reg) < FIRST_PSEUDO_REGISTER);
+
+ *call_fusage
+ = gen_rtx_EXPR_LIST (mode, gen_rtx_CLOBBER (VOIDmode, reg), *call_fusage);
+}
+
/* Add USE expressions to *CALL_FUSAGE for each of NREGS consecutive regs,
starting at REGNO. All of these registers must be hard registers. */
diff --git a/gcc/expr.h b/gcc/expr.h
index 524da6731a9..1823febac26 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -346,6 +346,7 @@ extern void copy_blkmode_from_reg (rtx, rtx, tree);
/* Mark REG as holding a parameter for the next CALL_INSN.
Mode is TYPE_MODE of the non-promoted parameter, or VOIDmode. */
extern void use_reg_mode (rtx *, rtx, enum machine_mode);
+extern void clobber_reg_mode (rtx *, rtx, enum machine_mode);
extern rtx copy_blkmode_to_reg (enum machine_mode, tree);
@@ -356,6 +357,13 @@ use_reg (rtx *fusage, rtx reg)
use_reg_mode (fusage, reg, VOIDmode);
}
+/* Mark REG as clobbered by the call with FUSAGE as CALL_INSN_FUNCTION_USAGE. */
+static inline void
+clobber_reg (rtx *fusage, rtx reg)
+{
+ clobber_reg_mode (fusage, reg, VOIDmode);
+}
+
/* Mark NREGS consecutive regs, starting at REGNO, as holding parameters
for the next CALL_INSN. */
extern void use_regs (rtx *, int, int);