diff options
author | Richard Henderson <rth@cygnus.com> | 2000-10-06 18:45:21 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2000-10-06 18:45:21 -0700 |
commit | 3e4eac3fe9f4b590e6c95356c3fcb7b08630acf2 (patch) | |
tree | 9d13e5f3092be6335d2cfa6ba7da64b6af514668 /gcc/function.c | |
parent | 15f18aaca64d6d5b27f29cc0072f46b5f04dbbe2 (diff) | |
download | gcc-3e4eac3fe9f4b590e6c95356c3fcb7b08630acf2.zip gcc-3e4eac3fe9f4b590e6c95356c3fcb7b08630acf2.tar.gz gcc-3e4eac3fe9f4b590e6c95356c3fcb7b08630acf2.tar.bz2 |
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
Diffstat (limited to 'gcc/function.c')
-rw-r--r-- | gcc/function.c | 76 |
1 files changed, 48 insertions, 28 deletions
diff --git a/gcc/function.c b/gcc/function.c index 85a18bf..11ceea7 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -6444,8 +6444,7 @@ diddle_return_value (doit, arg) /* If this is a BLKmode structure being returned in registers, then use the mode computed in expand_return. */ if (GET_MODE (outgoing) == BLKmode) - PUT_MODE (outgoing, - GET_MODE (DECL_RTL (DECL_RESULT (current_function_decl)))); + PUT_MODE (outgoing, GET_MODE (current_function_return_rtx)); 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); } - /* If scalar return value was computed in a pseudo-reg, - copy that to the hard return register. */ - if (DECL_RTL (DECL_RESULT (current_function_decl)) != 0 - && GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) == REG - && (REGNO (DECL_RTL (DECL_RESULT (current_function_decl))) - >= FIRST_PSEUDO_REGISTER)) + /* If scalar return value was computed in a pseudo-reg, or was a named + return value that got dumped to the stack, copy that to the hard + return register. */ + if (DECL_RTL (DECL_RESULT (current_function_decl)) != 0) { - 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 - real_decl_result - = FUNCTION_OUTGOING_VALUE (TREE_TYPE (DECL_RESULT (current_function_decl)), - current_function_decl); + real_decl_rtl = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl_result), + current_function_decl); #else - real_decl_result - = FUNCTION_VALUE (TREE_TYPE (DECL_RESULT (current_function_decl)), - current_function_decl); + real_decl_rtl = FUNCTION_VALUE (TREE_TYPE (decl_result), + current_function_decl); #endif - REG_FUNCTION_VALUE_P (real_decl_result) = 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 - holds the hard register containing the return value, not a temporary - pseudo. */ - current_function_return_rtx = real_decl_result; + 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. Note that if + decl_rtl is memory, then its mode may have been changed, + 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 |