diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-11-05 00:35:10 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-11-05 00:35:10 +0000 |
commit | 631ef7ce153511a5edc1162394039f199393b55e (patch) | |
tree | 3bf8e0ad4395b139c88e9c1ff7b7933ea4b1d9db /gcc/reg-stack.c | |
parent | e1f2ec6ee8253c8f0c9160cee0abb7e9f95e681a (diff) | |
download | ppe42-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.c | 49 |
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; } |