expr.c (block_move_libcall_safe_for_call_parm): Clean up...
authorGeoffrey Keating <geoffk@apple.com>
Tue, 14 Oct 2003 15:01:44 +0000 (15:01 +0000)
committerGeoffrey Keating <geoffk@gcc.gnu.org>
Tue, 14 Oct 2003 15:01:44 +0000 (15:01 +0000)
* 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

gcc/ChangeLog
gcc/expr.c

index e5d1b3f6222fbbfb8cb9fcded3a420eb6e51c663..6ee700c449dcf9cf242f6cc0a9a57e89c4ddff98 100644 (file)
@@ -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.
 
index 532a227dd88b26573461aa0a48e29f97b4b850b4..927c158893968895aa415c51e7503b252550ac27 100644 (file)
@@ -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;