From 21a3b98301b762310a6b261f5ea13bef38ec14a0 Mon Sep 17 00:00:00 2001
From: Jeffrey A Law <law@cygnus.com>
Date: Tue, 9 Mar 1999 16:40:30 +0000
Subject: [PATCH] calls.c (load_register_parameters): New function.

        * calls.c (load_register_parameters): New function.
        (expand_call): Use it.

From-SVN: r25658
---
 gcc/ChangeLog |   3 +
 gcc/calls.c   | 157 +++++++++++++++++++++++++++-----------------------
 2 files changed, 88 insertions(+), 72 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e9d1c4f26a2e..6bd6b96ef185 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -25,6 +25,9 @@ Tue Mar  9 09:33:16 1999  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
 Tue Mar  9 02:08:17 1999  Jeffrey A Law  (law@cygnus.com)
 
+	* calls.c (load_register_parameters): New function.
+	(expand_call): Use it.
+
 	* calls.c (expand_call): Slightly reorganize code.
 
 	* calls.c (compute_argument_addresses): New function.
diff --git a/gcc/calls.c b/gcc/calls.c
index e45c3c23360d..185b0e123755 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -155,7 +155,9 @@ static void initialize_argument_information	PROTO ((int,
 static void compute_argument_addresses		PROTO ((struct arg_data *,
 							rtx, int));
 static rtx rtx_for_function_call		PROTO ((tree, tree));
-							
+static void load_register_parameters		PROTO ((struct arg_data *,
+							int, rtx *));
+
 #if defined(ACCUMULATE_OUTGOING_ARGS) && defined(REG_PARM_STACK_SPACE)
 static rtx save_fixed_argument_area	PROTO ((int, rtx, int *, int *));
 static void restore_fixed_argument_area	PROTO ((rtx, rtx, int, int));
@@ -1416,6 +1418,86 @@ rtx_for_function_call (fndecl, exp)
   return funexp;
 }
 
+/* Do the register loads required for any wholly-register parms or any
+   parms which are passed both on the stack and in a register.  Their
+   expressions were already evaluated. 
+
+   Mark all register-parms as living through the call, putting these USE
+   insns in the CALL_INSN_FUNCTION_USAGE field.  */
+
+static void
+load_register_parameters (args, num_actuals, call_fusage)
+     struct arg_data *args;
+     int num_actuals;
+     rtx *call_fusage;
+{
+  int i, j;
+
+#ifdef LOAD_ARGS_REVERSED
+  for (i = num_actuals - 1; i >= 0; i--)
+#else
+  for (i = 0; i < num_actuals; i++)
+#endif
+    {
+      rtx reg = args[i].reg;
+      int partial = args[i].partial;
+      int nregs;
+
+      if (reg)
+	{
+	  /* Set to non-negative if must move a word at a time, even if just
+	     one word (e.g, partial == 1 && mode == DFmode).  Set to -1 if
+	     we just use a normal move insn.  This value can be zero if the
+	     argument is a zero size structure with no fields.  */
+	  nregs = (partial ? partial
+		   : (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode
+		      ? ((int_size_in_bytes (TREE_TYPE (args[i].tree_value))
+			  + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
+		      : -1));
+
+	  /* Handle calls that pass values in multiple non-contiguous
+	     locations.  The Irix 6 ABI has examples of this.  */
+
+	  if (GET_CODE (reg) == PARALLEL)
+	    {
+	      emit_group_load (reg, args[i].value,
+			       int_size_in_bytes (TREE_TYPE (args[i].tree_value)),
+			       (TYPE_ALIGN (TREE_TYPE (args[i].tree_value))
+				/ BITS_PER_UNIT));
+	    }
+
+	  /* If simple case, just do move.  If normal partial, store_one_arg
+	     has already loaded the register for us.  In all other cases,
+	     load the register(s) from memory.  */
+
+	  else if (nregs == -1)
+	    emit_move_insn (reg, args[i].value);
+
+	  /* If we have pre-computed the values to put in the registers in
+	     the case of non-aligned structures, copy them in now.  */
+
+	  else if (args[i].n_aligned_regs != 0)
+	    for (j = 0; j < args[i].n_aligned_regs; j++)
+	      emit_move_insn (gen_rtx_REG (word_mode, REGNO (reg) + j),
+			      args[i].aligned_regs[j]);
+
+	  else if (partial == 0 || args[i].pass_on_stack)
+	    move_block_to_reg (REGNO (reg),
+			       validize_mem (args[i].value), nregs,
+			       args[i].mode);
+
+	  /* Handle calls that pass values in multiple non-contiguous
+	     locations.  The Irix 6 ABI has examples of this.  */
+	  if (GET_CODE (reg) == PARALLEL)
+	    use_group_regs (call_fusage, reg);
+	  else if (nregs == -1)
+	    use_reg (call_fusage, reg);
+	  else
+	    use_regs (call_fusage, REGNO (reg), nregs == 0 ? 1 : nregs);
+	}
+    }
+}
+
 /* Generate all the code for a function call
    and return an rtx for its value.
    Store the value in TARGET (specified as an rtx) if convenient.
@@ -1530,7 +1612,7 @@ expand_call (exp, target, ignore)
   int old_inhibit_defer_pop = inhibit_defer_pop;
   rtx call_fusage = 0;
   register tree p;
-  register int i, j;
+  register int i;
 
   /* The value of the function call can be put in a hard register.  But
      if -fcheck-memory-usage, code which invokes functions (and thus
@@ -2182,76 +2264,7 @@ expand_call (exp, target, ignore)
 
   funexp = prepare_call_address (funexp, fndecl, &call_fusage, reg_parm_seen);
 
-  /* Now do the register loads required for any wholly-register parms or any
-     parms which are passed both on the stack and in a register.  Their
-     expressions were already evaluated. 
-
-     Mark all register-parms as living through the call, putting these USE
-     insns in the CALL_INSN_FUNCTION_USAGE field.  */
-
-#ifdef LOAD_ARGS_REVERSED
-  for (i = num_actuals - 1; i >= 0; i--)
-#else
-  for (i = 0; i < num_actuals; i++)
-#endif
-    {
-      rtx reg = args[i].reg;
-      int partial = args[i].partial;
-      int nregs;
-
-      if (reg)
-	{
-	  /* Set to non-negative if must move a word at a time, even if just
-	     one word (e.g, partial == 1 && mode == DFmode).  Set to -1 if
-	     we just use a normal move insn.  This value can be zero if the
-	     argument is a zero size structure with no fields.  */
-	  nregs = (partial ? partial
-		   : (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode
-		      ? ((int_size_in_bytes (TREE_TYPE (args[i].tree_value))
-			  + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
-		      : -1));
-
-	  /* Handle calls that pass values in multiple non-contiguous
-	     locations.  The Irix 6 ABI has examples of this.  */
-
-	  if (GET_CODE (reg) == PARALLEL)
-	    {
-	      emit_group_load (reg, args[i].value,
-			       int_size_in_bytes (TREE_TYPE (args[i].tree_value)),
-			       (TYPE_ALIGN (TREE_TYPE (args[i].tree_value))
-				/ BITS_PER_UNIT));
-	    }
-
-	  /* If simple case, just do move.  If normal partial, store_one_arg
-	     has already loaded the register for us.  In all other cases,
-	     load the register(s) from memory.  */
-
-	  else if (nregs == -1)
-	    emit_move_insn (reg, args[i].value);
-
-	  /* If we have pre-computed the values to put in the registers in
-	     the case of non-aligned structures, copy them in now.  */
-
-	  else if (args[i].n_aligned_regs != 0)
-	    for (j = 0; j < args[i].n_aligned_regs; j++)
-	      emit_move_insn (gen_rtx_REG (word_mode, REGNO (reg) + j),
-			      args[i].aligned_regs[j]);
-
-	  else if (partial == 0 || args[i].pass_on_stack)
-	    move_block_to_reg (REGNO (reg),
-			       validize_mem (args[i].value), nregs,
-			       args[i].mode);
-
-	  /* Handle calls that pass values in multiple non-contiguous
-	     locations.  The Irix 6 ABI has examples of this.  */
-	  if (GET_CODE (reg) == PARALLEL)
-	    use_group_regs (&call_fusage, reg);
-	  else if (nregs == -1)
-	    use_reg (&call_fusage, reg);
-	  else
-	    use_regs (&call_fusage, REGNO (reg), nregs == 0 ? 1 : nregs);
-	}
-    }
+  load_register_parameters (args, num_actuals, &call_fusage);
 
   /* Perform postincrements before actually calling the function.  */
   emit_queue ();
-- 
GitLab