diff options
author | John David Anglin <dave@hiauly1.hia.nrc.ca> | 2002-11-27 02:29:12 +0000 |
---|---|---|
committer | John David Anglin <danglin@gcc.gnu.org> | 2002-11-27 02:29:12 +0000 |
commit | 084a11066f6825b040acb692ad1f17981a17f1f6 (patch) | |
tree | fc534194a61afad57285d25be308fb71db734c93 /gcc/function.c | |
parent | a16f235752abdce78d8e5f608762a207f4973f13 (diff) | |
download | gcc-084a11066f6825b040acb692ad1f17981a17f1f6.zip gcc-084a11066f6825b040acb692ad1f17981a17f1f6.tar.gz gcc-084a11066f6825b040acb692ad1f17981a17f1f6.tar.bz2 |
expr.c (gen_group_rtx, [...]): New functions.
* expr.c (gen_group_rtx, emit_group_move): New functions.
* expr.h (gen_group_rtx, emit_group_move): Prototype.
* function.c (expand_function_start): Use gen_group_rtx to create a
PARALLEL rtx to hold the return value when the real return rtx is a
PARALLEL.
(expand_function_end): Use emit_group_move to move the return value
from a PARALLEL to the real return registers.
* rtl.h (REG_FUNCTION_VALUE_P): Allow function values to be returned
in PARALLELs.
From-SVN: r59554
Diffstat (limited to 'gcc/function.c')
-rw-r--r-- | gcc/function.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/gcc/function.c b/gcc/function.c index 0c066ed..6e6d6d7 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -6559,18 +6559,17 @@ expand_function_start (subr, parms_have_cleanups) subr, 1); /* Structures that are returned in registers are not aggregate_value_p, - so we may see a PARALLEL. Don't play pseudo games with this. */ - if (! REG_P (hard_reg)) - SET_DECL_RTL (DECL_RESULT (subr), hard_reg); + so we may see a PARALLEL or a REG. */ + if (REG_P (hard_reg)) + SET_DECL_RTL (DECL_RESULT (subr), gen_reg_rtx (GET_MODE (hard_reg))); + else if (GET_CODE (hard_reg) == PARALLEL) + SET_DECL_RTL (DECL_RESULT (subr), gen_group_rtx (hard_reg)); else - { - /* Create the pseudo. */ - SET_DECL_RTL (DECL_RESULT (subr), gen_reg_rtx (GET_MODE (hard_reg))); + abort (); - /* Needed because we may need to move this to memory - in case it's a named return value whose address is taken. */ - DECL_REGISTER (DECL_RESULT (subr)) = 1; - } + /* Set DECL_REGISTER flag so that expand_function_end will copy the + result to the real return register(s). */ + DECL_REGISTER (DECL_RESULT (subr)) = 1; } /* Initialize rtx for parameters and local variables. @@ -6998,8 +6997,16 @@ expand_function_end (filename, line, end_bindings) convert_move (real_decl_rtl, decl_rtl, unsignedp); } else if (GET_CODE (real_decl_rtl) == PARALLEL) - emit_group_load (real_decl_rtl, decl_rtl, - int_size_in_bytes (TREE_TYPE (decl_result))); + { + /* If expand_function_start has created a PARALLEL for decl_rtl, + move the result to the real return registers. Otherwise, do + a group load from decl_rtl for a named return. */ + if (GET_CODE (decl_rtl) == PARALLEL) + emit_group_move (real_decl_rtl, decl_rtl); + else + emit_group_load (real_decl_rtl, decl_rtl, + int_size_in_bytes (TREE_TYPE (decl_result))); + } else emit_move_insn (real_decl_rtl, decl_rtl); } |