This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Invalid CALL_INSN_FUNCTION_USAGE for certain libcalls


The Blackfin stores arguments in registers R0, R1, R2, and subsequent ones on the stack. A function with two DImode args (e.g. __divdi3) takes its first arg in R0/R1, and the second is split between R2 and the stack. Unfortunately, for a library call, we emit a (use (reg:DI R2)) in the CALL_INSN_FUNCTION_USAGE, which means that R3 is considered live in places where it really is dead. That caused spill failures when the new multiplication patterns I added recently are used.

Fixed with the patch below, which transfers a bit of code from load_register_parameters to emit_library_call_value_1 to make it take partial regs into account.

Bootstrapped & regression tested on i686-linux, tested for a while in our local Blackfin tree. Committed as 122396.


Bernd -- This footer brought to you by insane German lawmakers. Analog Devices GmbH Wilhelm-Wagenfeld-Str. 6 80807 Muenchen Registergericht Muenchen HRB 40368 Geschaeftsfuehrer Thomas Wessel, Vincent Roche, Joseph E. McDonough
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 122395)
+++ ChangeLog	(working copy)
@@ -1,3 +1,8 @@
+2007-02-28  Bernd Schmidt  <bernd.schmidt@analog.com>
+
+	* calls.c (emit_library_call_value_1): Handle partial registers
+	correctly when building up CALL_INSN_FUNCTION_USAGE.
+	
 2007-02-27  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 
 	* pa/predicates.md (move_src_operand): Allow zero for mode.
Index: calls.c
===================================================================
--- calls.c	(revision 122395)
+++ calls.c	(working copy)
@@ -3774,7 +3774,18 @@ emit_library_call_value_1 (int retval, r
       if (reg != 0 && GET_CODE (reg) == PARALLEL)
 	use_group_regs (&call_fusage, reg);
       else if (reg != 0)
-	use_reg (&call_fusage, reg);
+        {
+	  int partial = argvec[count].partial;
+	  if (partial)
+	    {
+	      int nregs;
+              gcc_assert (partial % UNITS_PER_WORD == 0);
+	      nregs = partial / UNITS_PER_WORD;
+	      use_regs (&call_fusage, REGNO (reg), nregs);
+	    }
+	  else
+	    use_reg (&call_fusage, reg);
+	}
     }
 
   /* Pass the function the address in which to return a structure value.  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]