return true;
}
+/* If X is a likely-spilled register value, copy it to a pseudo
+ register and return that register. Return X otherwise. */
+
+static rtx
+avoid_likely_spilled_reg (rtx x)
+{
+ rtx new;
+
+ if (REG_P (x)
+ && HARD_REGISTER_P (x)
+ && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (REGNO (x))))
+ {
+ /* Make sure that we generate a REG rather than a CONCAT.
+ Moves into CONCATs can need nontrivial instructions,
+ and the whole point of this function is to avoid
+ using the hard register directly in such a situation. */
+ generating_concat_p = 0;
+ new = gen_reg_rtx (GET_MODE (x));
+ generating_concat_p = 1;
+ emit_move_insn (new, x);
+ return new;
+ }
+ return x;
+}
+
/* Generate all the code for a CALL_EXPR exp
and return an rtx for its value.
Store the value in TARGET (specified as an rtx) if convenient.
/* We have to copy a return value in a CLASS_LIKELY_SPILLED hard
reg to a plain register. */
- if (REG_P (valreg)
- && HARD_REGISTER_P (valreg)
- && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (REGNO (valreg)))
- && !(REG_P (target) && !HARD_REGISTER_P (target)))
- valreg = copy_to_reg (valreg);
+ if (!REG_P (target) || HARD_REGISTER_P (target))
+ valreg = avoid_likely_spilled_reg (valreg);
/* If TARGET is a MEM in the argument area, and we have
saved part of the argument area, then we can't store
sibcall_failure = 1;
}
else
- target = copy_to_reg (valreg);
+ target = copy_to_reg (avoid_likely_spilled_reg (valreg));
if (targetm.calls.promote_function_return(funtype))
{
bool
must_pass_in_stack_var_size (enum machine_mode mode ATTRIBUTE_UNUSED,
- tree type)
+ const_tree type)
{
if (!type)
return false;
/* ??? Should be able to merge these two by examining BLOCK_REG_PADDING. */
bool
-must_pass_in_stack_var_size_or_pad (enum machine_mode mode, tree type)
+must_pass_in_stack_var_size_or_pad (enum machine_mode mode, const_tree type)
{
if (!type)
return false;