Commit 3e4eac3f by Richard Henderson Committed by Richard Henderson

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
parent 15f18aac
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) ...@@ -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) ...@@ -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 this is a BLKmode structure being returned in registers,
if (GET_MODE (real_decl_result) == BLKmode) then use the mode computed in expand_return. Note that if
PUT_MODE (real_decl_result, decl_rtl is memory, then its mode may have been changed,
GET_MODE (DECL_RTL (DECL_RESULT (current_function_decl)))); but that current_function_return_rtx has not. */
emit_move_insn (real_decl_result, if (GET_MODE (real_decl_rtl) == BLKmode)
DECL_RTL (DECL_RESULT (current_function_decl))); PUT_MODE (real_decl_rtl, GET_MODE (current_function_return_rtx));
/* The delay slot scheduler assumes that current_function_return_rtx /* If a named return value dumped decl_return to memory, then
holds the hard register containing the return value, not a temporary we may need to re-do the PROMOTE_MODE signed/unsigned
pseudo. */ extension. */
current_function_return_rtx = real_decl_result; 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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment