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]

Fix PR target/13557


This is a deviation from the psABI on SPARC64.  The compiler passes the 
structure

struct sf {
   float f;
};

in %f1, while the ABI mandates %f0.  The structure is sent with SFmode to the 
FUNCTION_ARG macro, which fools it into thinking that it sees a bare float.


Fixed by reordering the cases in the FUNCTION_ARG macro.  The patch was 
bootstrapped/regtested on sparc64-sun-solaris2.9 (except Ada and libgcj) and 
compat-regtested against the Sun ONE Studio 8 compiler.  It fixes:

FAIL: gcc.dg/compat/struct-by-value-5 c_compat_x_tst.o-c_compat_y_alt.o 
execute
FAIL: gcc.dg/compat/struct-by-value-5 c_compat_x_alt.o-c_compat_y_tst.o 
execute

in the latter testsuite.  Applied to mainline and 3.4 branch (the 3.4 branch 
already contains ABI fixes which makes it incompatible with 3.3.x).


2004-01-20  Eric Botcazou  <ebotcazou@libertysurf.fr>

	PR target/13557
	* config/sparc/sparc.c (function_arg): Reorder the cases.


-- 
Eric Botcazou
Index: config/sparc/sparc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sparc.c,v
retrieving revision 1.271
diff -u -p -r1.271 sparc.c
--- config/sparc/sparc.c	10 Dec 2003 15:25:41 -0000	1.271
+++ config/sparc/sparc.c	12 Jan 2004 14:29:25 -0000
@@ -5353,12 +5355,33 @@ function_arg (const struct sparc_args *c
       reg = gen_rtx_REG (mode, regno);
       return reg;
     }
+    
+  if (type && TREE_CODE (type) == RECORD_TYPE)
+    {
+      /* Structures up to 16 bytes in size are passed in arg slots on the
+	 stack and are promoted to registers where possible.  */
+
+      if (int_size_in_bytes (type) > 16)
+	abort (); /* shouldn't get here */
+
+      return function_arg_record_value (type, mode, slotno, named, regbase);
+    }
+  else if (type && TREE_CODE (type) == UNION_TYPE)
+    {
+      enum machine_mode mode;
+      int bytes = int_size_in_bytes (type);
+
+      if (bytes > 16)
+	abort ();
 
+      mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 0);
+      reg = gen_rtx_REG (mode, regno);
+    }
   /* v9 fp args in reg slots beyond the int reg slots get passed in regs
      but also have the slot allocated for them.
      If no prototype is in scope fp values in register slots get passed
      in two places, either fp regs and int regs or fp regs and memory.  */
-  if ((GET_MODE_CLASS (mode) == MODE_FLOAT
+  else if ((GET_MODE_CLASS (mode) == MODE_FLOAT
        || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
       && SPARC_FP_REG_P (regno))
     {
@@ -5422,27 +5445,6 @@ function_arg (const struct sparc_args *c
 	      return gen_rtx_PARALLEL (mode, gen_rtvec (2, v0, v1));
 	    }
 	}
-    }
-  else if (type && TREE_CODE (type) == RECORD_TYPE)
-    {
-      /* Structures up to 16 bytes in size are passed in arg slots on the
-	 stack and are promoted to registers where possible.  */
-
-      if (int_size_in_bytes (type) > 16)
-	abort (); /* shouldn't get here */
-
-      return function_arg_record_value (type, mode, slotno, named, regbase);
-    }
-  else if (type && TREE_CODE (type) == UNION_TYPE)
-    {
-      enum machine_mode mode;
-      int bytes = int_size_in_bytes (type);
-
-      if (bytes > 16)
-	abort ();
-
-      mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 0);
-      reg = gen_rtx_REG (mode, regno);
     }
   else
     {

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