function.c (diddle_return_value): Examine current_function_return_rtx instead of the DECL_RESULT.
* function.c (diddle_return_value): Examine current_function_return_rtx instead of the DECL_RESULT. (expand_function_end): Handle reloading DECL_RESULT from memory into a hard register. Query promote_mode for sign of mismatched modes. From-SVN: r36769
This commit is contained in:
parent
15f18aaca6
commit
3e4eac3fe9
@ -1,3 +1,11 @@
|
|||||||
|
2000-10-06 Richard Henderson <rth@cygnus.com>
|
||||||
|
|
||||||
|
* function.c (diddle_return_value): Examine
|
||||||
|
current_function_return_rtx instead of the DECL_RESULT.
|
||||||
|
(expand_function_end): Handle reloading DECL_RESULT from memory
|
||||||
|
into a hard register. Query promote_mode for sign of mismatched
|
||||||
|
modes.
|
||||||
|
|
||||||
2000-10-06 Vladimir Makarov <vmakarov@touchme.toronto.redhat.com>
|
2000-10-06 Vladimir Makarov <vmakarov@touchme.toronto.redhat.com>
|
||||||
|
|
||||||
* haifa-sched.c (schedule_insns): Fix typo in freeing
|
* haifa-sched.c (schedule_insns): Fix typo in freeing
|
||||||
|
@ -6444,8 +6444,7 @@ diddle_return_value (doit, arg)
|
|||||||
/* If this is a BLKmode structure being returned in registers, then use
|
/* If this is a BLKmode structure being returned in registers, then use
|
||||||
the mode computed in expand_return. */
|
the mode computed in expand_return. */
|
||||||
if (GET_MODE (outgoing) == BLKmode)
|
if (GET_MODE (outgoing) == BLKmode)
|
||||||
PUT_MODE (outgoing,
|
PUT_MODE (outgoing, GET_MODE (current_function_return_rtx));
|
||||||
GET_MODE (DECL_RTL (DECL_RESULT (current_function_decl))));
|
|
||||||
REG_FUNCTION_VALUE_P (outgoing) = 1;
|
REG_FUNCTION_VALUE_P (outgoing) = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6730,37 +6729,58 @@ expand_function_end (filename, line, end_bindings)
|
|||||||
emit_stack_restore (SAVE_FUNCTION, tem, NULL_RTX);
|
emit_stack_restore (SAVE_FUNCTION, tem, NULL_RTX);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If scalar return value was computed in a pseudo-reg,
|
/* If scalar return value was computed in a pseudo-reg, or was a named
|
||||||
copy that to the hard return register. */
|
return value that got dumped to the stack, copy that to the hard
|
||||||
if (DECL_RTL (DECL_RESULT (current_function_decl)) != 0
|
return register. */
|
||||||
&& GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) == REG
|
if (DECL_RTL (DECL_RESULT (current_function_decl)) != 0)
|
||||||
&& (REGNO (DECL_RTL (DECL_RESULT (current_function_decl)))
|
|
||||||
>= FIRST_PSEUDO_REGISTER))
|
|
||||||
{
|
{
|
||||||
rtx real_decl_result;
|
tree decl_result = DECL_RESULT (current_function_decl);
|
||||||
|
rtx decl_rtl = DECL_RTL (decl_result);
|
||||||
|
|
||||||
|
if (REG_P (decl_rtl)
|
||||||
|
? REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER
|
||||||
|
: DECL_REGISTER (decl_result))
|
||||||
|
{
|
||||||
|
rtx real_decl_rtl;
|
||||||
|
|
||||||
#ifdef FUNCTION_OUTGOING_VALUE
|
#ifdef FUNCTION_OUTGOING_VALUE
|
||||||
real_decl_result
|
real_decl_rtl = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl_result),
|
||||||
= FUNCTION_OUTGOING_VALUE (TREE_TYPE (DECL_RESULT (current_function_decl)),
|
current_function_decl);
|
||||||
current_function_decl);
|
|
||||||
#else
|
#else
|
||||||
real_decl_result
|
real_decl_rtl = FUNCTION_VALUE (TREE_TYPE (decl_result),
|
||||||
= FUNCTION_VALUE (TREE_TYPE (DECL_RESULT (current_function_decl)),
|
current_function_decl);
|
||||||
current_function_decl);
|
|
||||||
#endif
|
#endif
|
||||||
REG_FUNCTION_VALUE_P (real_decl_result) = 1;
|
REG_FUNCTION_VALUE_P (real_decl_rtl) = 1;
|
||||||
/* If this is a BLKmode structure being returned in registers, then use
|
|
||||||
the mode computed in expand_return. */
|
|
||||||
if (GET_MODE (real_decl_result) == BLKmode)
|
|
||||||
PUT_MODE (real_decl_result,
|
|
||||||
GET_MODE (DECL_RTL (DECL_RESULT (current_function_decl))));
|
|
||||||
emit_move_insn (real_decl_result,
|
|
||||||
DECL_RTL (DECL_RESULT (current_function_decl)));
|
|
||||||
|
|
||||||
/* The delay slot scheduler assumes that current_function_return_rtx
|
/* If this is a BLKmode structure being returned in registers,
|
||||||
holds the hard register containing the return value, not a temporary
|
then use the mode computed in expand_return. Note that if
|
||||||
pseudo. */
|
decl_rtl is memory, then its mode may have been changed,
|
||||||
current_function_return_rtx = real_decl_result;
|
but that current_function_return_rtx has not. */
|
||||||
|
if (GET_MODE (real_decl_rtl) == BLKmode)
|
||||||
|
PUT_MODE (real_decl_rtl, GET_MODE (current_function_return_rtx));
|
||||||
|
|
||||||
|
/* If a named return value dumped decl_return to memory, then
|
||||||
|
we may need to re-do the PROMOTE_MODE signed/unsigned
|
||||||
|
extension. */
|
||||||
|
if (GET_MODE (real_decl_rtl) != GET_MODE (decl_rtl))
|
||||||
|
{
|
||||||
|
int unsignedp = TREE_UNSIGNED (TREE_TYPE (decl_result));
|
||||||
|
|
||||||
|
#ifdef PROMOTE_FUNCTION_RETURN
|
||||||
|
promote_mode (TREE_TYPE (decl_result), GET_MODE (decl_rtl),
|
||||||
|
&unsignedp, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
convert_move (real_decl_rtl, decl_rtl, unsignedp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
emit_move_insn (real_decl_rtl, decl_rtl);
|
||||||
|
|
||||||
|
/* The delay slot scheduler assumes that current_function_return_rtx
|
||||||
|
holds the hard register containing the return value, not a
|
||||||
|
temporary pseudo. */
|
||||||
|
current_function_return_rtx = real_decl_rtl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If returning a structure, arrange to return the address of the value
|
/* If returning a structure, arrange to return the address of the value
|
||||||
|
Loading…
Reference in New Issue
Block a user