diff options
Diffstat (limited to 'gcc/reg-stack.c')
-rw-r--r-- | gcc/reg-stack.c | 29 |
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; |