aboutsummaryrefslogtreecommitdiff
path: root/gcc/reg-stack.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/reg-stack.c')
-rw-r--r--gcc/reg-stack.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index bace44e..1d9ea03 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -174,6 +174,7 @@
#include "reload.h"
#include "tree-pass.h"
#include "rtl-iter.h"
+#include "function-abi.h"
#ifdef STACK_REGS
@@ -1251,7 +1252,7 @@ swap_rtx_condition (rtx_insn *insn)
{
rtx pat = PATTERN (insn);
- /* We're looking for a single set to cc0 or an HImode temporary. */
+ /* We're looking for a single set to an HImode temporary. */
if (GET_CODE (pat) == SET
&& REG_P (SET_DEST (pat))
@@ -1298,7 +1299,7 @@ swap_rtx_condition (rtx_insn *insn)
|| ! dead_or_set_p (insn, dest))
return 0;
- /* Now we are prepared to handle this as a normal cc0 setter. */
+ /* Now we are prepared to handle this. */
insn = next_flags_user (insn);
if (insn == NULL_RTX)
return 0;
@@ -1586,9 +1587,7 @@ subst_stack_regs_pat (rtx_insn *insn, stack_ptr regstack, rtx pat)
break;
case REG:
- /* This is a `tstM2' case. */
- gcc_assert (*dest == cc0_rtx);
- src1 = src;
+ gcc_unreachable ();
/* Fall through. */
@@ -1596,8 +1595,7 @@ subst_stack_regs_pat (rtx_insn *insn, stack_ptr regstack, rtx pat)
case SQRT:
case ABS:
case NEG:
- /* These insns only operate on the top of the stack. DEST might
- be cc0_rtx if we're processing a tstM pattern. Also, it's
+ /* These insns only operate on the top of the stack. It's
possible that the tstM case results in a REG_DEAD note on the
source. */
@@ -2371,6 +2369,18 @@ subst_asm_stack_regs (rtx_insn *insn, stack_ptr regstack)
}
}
}
+
+/* Return true if a function call is allowed to alter some or all bits
+ of any stack reg. */
+static bool
+callee_clobbers_any_stack_reg (const function_abi & callee_abi)
+{
+ for (unsigned regno = FIRST_STACK_REG; regno <= LAST_STACK_REG; regno++)
+ if (callee_abi.clobbers_at_least_part_of_reg_p (regno))
+ return true;
+ return false;
+}
+
/* Substitute stack hard reg numbers for stack virtual registers in
INSN. Non-stack register numbers are not changed. REGSTACK is the
@@ -2385,7 +2395,10 @@ subst_stack_regs (rtx_insn *insn, stack_ptr regstack)
bool control_flow_insn_deleted = false;
int i;
- if (CALL_P (insn))
+ /* If the target of the call doesn't clobber any stack registers,
+ Don't clear the arguments. */
+ if (CALL_P (insn)
+ && callee_clobbers_any_stack_reg (insn_callee_abi (insn)))
{
int top = regstack->top;