summaryrefslogtreecommitdiffstats
path: root/gcc/reg-stack.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>1999-11-05 00:35:10 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>1999-11-05 00:35:10 +0000
commit631ef7ce153511a5edc1162394039f199393b55e (patch)
tree3bf8e0ad4395b139c88e9c1ff7b7933ea4b1d9db /gcc/reg-stack.c
parente1f2ec6ee8253c8f0c9160cee0abb7e9f95e681a (diff)
downloadppe42-gcc-631ef7ce153511a5edc1162394039f199393b55e.tar.gz
ppe42-gcc-631ef7ce153511a5edc1162394039f199393b55e.zip
* function.c (diddle_return_value): New.
(expand_function_end): Use it. * stmt.c (expand_null_return): Likewise. (expand_value_return): Likewise. * reg-stack.c (subst_stack_regs_pat): Handle clobbers at top-level. * reload1.c (reload): Don't remove return value clobbers. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@30401 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/reg-stack.c')
-rw-r--r--gcc/reg-stack.c49
1 files changed, 35 insertions, 14 deletions
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index e20e92e8595..4efaea1c73f 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -1394,27 +1394,48 @@ subst_stack_regs_pat (insn, regstack, pat)
{
rtx note;
- /* The fix_truncdi_1 pattern wants to be able to allocate it's
- own scratch register. It does this by clobbering an fp reg
- so that it is assured of an empty reg-stack register.
- If the register is live, kill it now. Remove the DEAD/UNUSED
- note so we don't try to kill it later too. */
-
dest = get_true_reg (&XEXP (pat, 0));
if (STACK_REG_P (*dest))
{
note = find_reg_note (insn, REG_DEAD, *dest);
- if (note)
- emit_pop_insn (insn, regstack, *dest, EMIT_BEFORE);
- else
+
+ if (pat != PATTERN (insn))
{
- note = find_reg_note (insn, REG_UNUSED, *dest);
- if (!note)
- abort ();
+ /* The fix_truncdi_1 pattern wants to be able to allocate
+ it's own scratch register. It does this by clobbering
+ an fp reg so that it is assured of an empty reg-stack
+ register. If the register is live, kill it now.
+ Remove the DEAD/UNUSED note so we don't try to kill it
+ later too. */
+
+ if (note)
+ emit_pop_insn (insn, regstack, *dest, EMIT_BEFORE);
+ else
+ {
+ note = find_reg_note (insn, REG_UNUSED, *dest);
+ if (!note)
+ abort ();
+ }
+ remove_note (insn, note);
+ replace_reg (dest, LAST_STACK_REG);
}
+ else
+ {
+ /* A top-level clobber with no REG_DEAD, and no hard-regnum
+ indicates an uninitialized value. Because reload removed
+ all other clobbers, this must be due to a function
+ returning without a value. Load up a NaN. */
- remove_note (insn, note);
- replace_reg (dest, LAST_STACK_REG);
+ if (! note
+ && get_hard_regnum (regstack, *dest) == -1)
+ {
+ pat = gen_rtx_SET (VOIDmode,
+ FP_MODE_REG (REGNO (*dest), SFmode),
+ nan);
+ PATTERN (insn) = pat;
+ move_for_stack_reg (insn, regstack, pat);
+ }
+ }
}
break;
}
OpenPOWER on IntegriCloud