aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeoffrey Keating <geoffk@apple.com>2003-10-14 15:01:44 +0000
committerGeoffrey Keating <geoffk@gcc.gnu.org>2003-10-14 15:01:44 +0000
commita357a6d4ed376ad1fbb4b5370b4db281bd270ea8 (patch)
tree1ed8dbebc0fa59182ac860b5b54dad5c224de313
parentd9b46dfb99308239e5fff12faf47ff0516f59f1a (diff)
downloadgcc-a357a6d4ed376ad1fbb4b5370b4db281bd270ea8.zip
gcc-a357a6d4ed376ad1fbb4b5370b4db281bd270ea8.tar.gz
gcc-a357a6d4ed376ad1fbb4b5370b4db281bd270ea8.tar.bz2
expr.c (block_move_libcall_safe_for_call_parm): Clean up...
* expr.c (block_move_libcall_safe_for_call_parm): Clean up, and add case for machines where outgoing register parameters get stack space. From-SVN: r72474
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/expr.c78
2 files changed, 38 insertions, 44 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e5d1b3f..6ee700c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,9 @@
2003-10-14 Geoffrey Keating <geoffk@apple.com>
+ * expr.c (block_move_libcall_safe_for_call_parm): Clean up,
+ and add case for machines where outgoing register parameters
+ get stack space.
+
* config/darwin.c (machopic_indirect_data_reference): Use a scratch
register when generating indirect address.
diff --git a/gcc/expr.c b/gcc/expr.c
index 532a227..927c158 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -1394,56 +1394,46 @@ emit_block_move (rtx x, rtx y, rtx size, enum block_op_methods method)
static bool
block_move_libcall_safe_for_call_parm (void)
{
+ /* If arguments are pushed on the stack, then they're safe. */
if (PUSH_ARGS)
return true;
- else
- {
- /* Check to see whether memcpy takes all register arguments. */
- static enum {
- takes_regs_uninit, takes_regs_no, takes_regs_yes
- } takes_regs = takes_regs_uninit;
-
- switch (takes_regs)
- {
- case takes_regs_uninit:
- {
- CUMULATIVE_ARGS args_so_far;
- tree fn, arg;
-
- fn = emit_block_move_libcall_fn (false);
- INIT_CUMULATIVE_ARGS (args_so_far, TREE_TYPE (fn), NULL_RTX, 0);
- arg = TYPE_ARG_TYPES (TREE_TYPE (fn));
- for ( ; arg != void_list_node ; arg = TREE_CHAIN (arg))
- {
- enum machine_mode mode = TYPE_MODE (TREE_VALUE (arg));
- rtx tmp = FUNCTION_ARG (args_so_far, mode, NULL_TREE, 1);
- if (!tmp || !REG_P (tmp))
- goto fail_takes_regs;
-#ifdef FUNCTION_ARG_PARTIAL_NREGS
- if (FUNCTION_ARG_PARTIAL_NREGS (args_so_far, mode,
- NULL_TREE, 1))
- goto fail_takes_regs;
+ /* If registers go on the stack anyway, any argument is sure to clobber
+ an outgoing argument. */
+#if defined (REG_PARM_STACK_SPACE) && defined (OUTGOING_REG_PARM_STACK_SPACE)
+ {
+ tree fn = emit_block_move_libcall_fn (false);
+ (void) fn;
+ if (REG_PARM_STACK_SPACE (fn) != 0)
+ return false;
+ }
#endif
- FUNCTION_ARG_ADVANCE (args_so_far, mode, NULL_TREE, 1);
- }
- }
- takes_regs = takes_regs_yes;
- /* FALLTHRU */
-
- case takes_regs_yes:
- return true;
- fail_takes_regs:
- takes_regs = takes_regs_no;
- /* FALLTHRU */
- case takes_regs_no:
+ /* If any argument goes in memory, then it might clobber an outgoing
+ argument. */
+ {
+ CUMULATIVE_ARGS args_so_far;
+ tree fn, arg;
+
+ fn = emit_block_move_libcall_fn (false);
+ INIT_CUMULATIVE_ARGS (args_so_far, TREE_TYPE (fn), NULL_RTX, 0);
+
+ arg = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ for ( ; arg != void_list_node ; arg = TREE_CHAIN (arg))
+ {
+ enum machine_mode mode = TYPE_MODE (TREE_VALUE (arg));
+ rtx tmp = FUNCTION_ARG (args_so_far, mode, NULL_TREE, 1);
+ if (!tmp || !REG_P (tmp))
return false;
-
- default:
- abort ();
- }
- }
+#ifdef FUNCTION_ARG_PARTIAL_NREGS
+ if (FUNCTION_ARG_PARTIAL_NREGS (args_so_far, mode,
+ NULL_TREE, 1))
+ return false;
+#endif
+ FUNCTION_ARG_ADVANCE (args_so_far, mode, NULL_TREE, 1);
+ }
+ }
+ return true;
}
/* A subroutine of emit_block_move. Expand a movstr pattern;