aboutsummaryrefslogtreecommitdiff
path: root/gcc/function.c
diff options
context:
space:
mode:
authorJohn David Anglin <dave@hiauly1.hia.nrc.ca>2002-11-27 02:29:12 +0000
committerJohn David Anglin <danglin@gcc.gnu.org>2002-11-27 02:29:12 +0000
commit084a11066f6825b040acb692ad1f17981a17f1f6 (patch)
treefc534194a61afad57285d25be308fb71db734c93 /gcc/function.c
parenta16f235752abdce78d8e5f608762a207f4973f13 (diff)
downloadgcc-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.c31
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);
}