Subject: Testers wanted
To: None <port-sparc@netbsd.org>
From: None <eeh@netbsd.org>
List: port-sparc
Date: 04/22/2002 16:43:08
I am in the process of backporting a C++ compiler fix from
gcc-current to our in-tree gcc and need some help testing.
Since gcc has a single back-end for both 32-bit and 64-bit
sparc, any changes could break either port.

I'm looking for volunteers to test the accompanying patch
on 32-bit sparc.  I suppose the best way would be to run
the gcc testsuite with the current compiler first, check
for breakage, then do the same with this fix and see if
anything has changed.

To run the testsuite you need to:

1) Get a gcc source tree

2) Get deja-gnu from:

ftp://gcc.gnu.org/pub/gcc/infrastructure/dejagnu-20010126.tar.gz

3) Build and install that version of dejagnu

4) Configure gcc (preferably with a separate build directory)

5) do a `make check' in the top-level gcc build directory


Building a new compiler is more complicated.  You need to
apply the patch, then build src/gnu/lib, and src/gnu/usr.bin,
possibly includes, src/lib, src/usr.bin/make, src/share/mk, etc.

Eduardo


Index: gnu/dist/toolchain/gcc/config/sparc/sparc.c
===================================================================
RCS file: /cvsroot/gnusrc/gnu/dist/toolchain/gcc/config/sparc/sparc.c,v
retrieving revision 1.5
diff -u -r1.5 sparc.c
--- gnu/dist/toolchain/gcc/config/sparc/sparc.c	2002/03/28 08:14:56	1.5
+++ gnu/dist/toolchain/gcc/config/sparc/sparc.c	2002/04/22 16:27:14
@@ -3651,20 +3651,23 @@
 {
   rtx ret;
   int slotno, named, regbase;
-  int nregs, intoffset;
+  unsigned int nregs;
+  int intoffset;
 };
 
 static void function_arg_record_value_3
-	PROTO((int, struct function_arg_record_value_parms *));
+	PROTO((HOST_WIDE_INT, struct function_arg_record_value_parms *));
 static void function_arg_record_value_2
-	PROTO((tree, int, struct function_arg_record_value_parms *));
+	PROTO((tree, HOST_WIDE_INT, struct function_arg_record_value_parms *));
+static void function_arg_record_value_1
+	PROTO((tree, HOST_WIDE_INT, struct function_arg_record_value_parms *));
 static rtx function_arg_record_value
 	PROTO((tree, enum machine_mode, int, int, int));
 
 static void
 function_arg_record_value_1 (type, startbitpos, parms)
      tree type;
-     int startbitpos;
+     HOST_WIDE_INT startbitpos;
      struct function_arg_record_value_parms *parms;
 {
   tree field;
@@ -3692,16 +3695,18 @@
     {
       if (TREE_CODE (field) == FIELD_DECL)
 	{
-	  int bitpos = startbitpos;
+	  HOST_WIDE_INT bitpos = startbitpos;
 	  if (DECL_FIELD_BITPOS (field))
 	    bitpos += TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field));
+
 	  /* ??? FIXME: else assume zero offset.  */
 
 	  if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
-	    {
-	      function_arg_record_value_1 (TREE_TYPE (field), bitpos, parms);
-	    }
-	  else if (TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
+	    function_arg_record_value_1 (TREE_TYPE (field), bitpos, parms);
+	  else if ((TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
+		    || (TREE_CODE (TREE_TYPE (field)) == COMPLEX_TYPE
+			&& (TREE_CODE (TREE_TYPE (TREE_TYPE (field)))
+			    == REAL_TYPE)))
 	           && TARGET_FPU
 	           && ! packed_p
 	           && parms->named)
@@ -3724,6 +3729,8 @@
 	      /* There's no need to check this_slotno < SPARC_FP_ARG MAX.
 		 If it wasn't true we wouldn't be here.  */
 	      parms->nregs += 1;
+	      if (TREE_CODE (TREE_TYPE (field)) == COMPLEX_TYPE)
+		parms->nregs += 1;
 	    }
 	  else
 	    {
@@ -3738,11 +3745,13 @@
 
 static void 
 function_arg_record_value_3 (bitpos, parms)
-     int bitpos;
+     HOST_WIDE_INT bitpos;
      struct function_arg_record_value_parms *parms;
 {
   enum machine_mode mode;
-  int regno, this_slotno, intslots, intoffset;
+  unsigned int regno;
+  unsigned int startbit, endbit;
+  int this_slotno, intslots, intoffset;
   rtx reg;
 
   if (parms->intoffset == -1)
@@ -3750,7 +3759,9 @@
   intoffset = parms->intoffset;
   parms->intoffset = -1;
 
-  intslots = (bitpos - intoffset + BITS_PER_WORD - 1) / BITS_PER_WORD;
+  startbit = intoffset & -BITS_PER_WORD;
+  endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
+  intslots = (endbit - startbit) / BITS_PER_WORD;
   this_slotno = parms->slotno + intoffset / BITS_PER_WORD;
 
   intslots = MIN (intslots, SPARC_INT_ARG_MAX - this_slotno);
@@ -3797,7 +3808,7 @@
 static void
 function_arg_record_value_2 (type, startbitpos, parms)
      tree type;
-     int startbitpos;
+     HOST_WIDE_INT startbitpos;
      struct function_arg_record_value_parms *parms;
 {
   tree field;
@@ -3816,7 +3827,7 @@
     {
       if (TREE_CODE (field) == FIELD_DECL)
 	{
-	  int bitpos = startbitpos;
+	  HOST_WIDE_INT bitpos = startbitpos;
 	  if (DECL_FIELD_BITPOS (field))
 	    bitpos += TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field));
 	  /* ??? FIXME: else assume zero offset.  */
@@ -3825,24 +3836,45 @@
 	    {
 	      function_arg_record_value_2 (TREE_TYPE (field), bitpos, parms);
 	    }
-	  else if (TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
+	  else if ((TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
+		    || (TREE_CODE (TREE_TYPE (field)) == COMPLEX_TYPE
+			&& (TREE_CODE (TREE_TYPE (TREE_TYPE (field)))
+			    == REAL_TYPE)))
 	           && TARGET_FPU
 	           && ! packed_p
 	           && parms->named)
 	    {
 	      int this_slotno = parms->slotno + bitpos / BITS_PER_WORD;
+	      int regno;
+	      enum machine_mode mode = DECL_MODE (field);
 	      rtx reg;
 
 	      function_arg_record_value_3 (bitpos, parms);
-
-	      reg = gen_rtx_REG (DECL_MODE (field),
-			         (SPARC_FP_ARG_FIRST + this_slotno * 2
-			          + (DECL_MODE (field) == SFmode
-				     && (bitpos & 32) != 0)));
+	      regno = SPARC_FP_ARG_FIRST + this_slotno * 2
+		      + ((mode == SFmode || mode == SCmode)
+			 && (bitpos & 32) != 0);
+	      switch (mode)
+		{
+		case SCmode: mode = SFmode; break;
+		case DCmode: mode = DFmode; break;
+		case TCmode: mode = TFmode; break;
+		default: break;
+		}
+	      reg = gen_rtx_REG (mode, regno);
 	      XVECEXP (parms->ret, 0, parms->nregs)
 		= gen_rtx_EXPR_LIST (VOIDmode, reg,
 			   GEN_INT (bitpos / BITS_PER_UNIT));
 	      parms->nregs += 1;
+	      if (TREE_CODE (TREE_TYPE (field)) == COMPLEX_TYPE)
+		{
+		  regno += GET_MODE_SIZE (mode) / 4;
+	  	  reg = gen_rtx_REG (mode, regno);
+		  XVECEXP (parms->ret, 0, parms->nregs)
+		    = gen_rtx_EXPR_LIST (VOIDmode, reg,
+			GEN_INT ((bitpos + GET_MODE_BITSIZE (mode))
+				 / BITS_PER_UNIT));
+		  parms->nregs += 1;
+		}
 	    }
 	  else
 	    {
@@ -3864,7 +3896,7 @@
 {
   HOST_WIDE_INT typesize = int_size_in_bytes (type);
   struct function_arg_record_value_parms parms;
-  int nregs;
+  unsigned int nregs;
 
   parms.ret = NULL_RTX;
   parms.slotno = slotno;