diff options
author | Geoffrey Keating <geoffk@apple.com> | 2003-10-14 15:01:44 +0000 |
---|---|---|
committer | Geoffrey Keating <geoffk@gcc.gnu.org> | 2003-10-14 15:01:44 +0000 |
commit | a357a6d4ed376ad1fbb4b5370b4db281bd270ea8 (patch) | |
tree | 1ed8dbebc0fa59182ac860b5b54dad5c224de313 | |
parent | d9b46dfb99308239e5fff12faf47ff0516f59f1a (diff) | |
download | gcc-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/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/expr.c | 78 |
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. @@ -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; |