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]

[PATCH] Fix ABI for complex integral types (SPARC64)


Hi,

As I discovered some time ago thanks to Janis' compat testcases, the ABI for 
complex integral types on SPARC64 is... interesting. For example, with two 
parameters:

   void foo(_Complex int arg1, _Complex int arg2);

arg1 is packed into %o0 and arg2 is packed into %o2.

So we end up with holes in the parameters array, which would not be that 
serious if the va_arg handling code didn't expect consecutive slots. The 
complex floating-point types are not affected.

The patch fills in the holes by packing arg1 into %o0 and arg2 into %o1 for 
the example. I manually verified that this is actually the case and that the 
ABI for complex floating types is not modified.

Bootstrapped/regtested on sparc64-sun-solaris2.9 and sparc-sun-solaris2.8 
(mainline, except Ada).

It fixes

FAIL: gcc.dg/compat/scalar-by-value-3 c_compat_x_tst.o-c_compat_y_tst.o 
execute 
FAIL: gcc.dg/compat/scalar-return-3 c_compat_x_tst.o-c_compat_y_tst.o execute 

on sparc64-sun-solaris2.9, which were the last two remaining compat failures 
on sparc*-sun-solaris2* (except of course the compat-vector tests since the 
SPARC backend has no vector ABI).


2003-10-29  Eric Botcazou  <ebotcazou@libertysurf.fr>

        * config/sparc/sparc.c (function_arg_partial_nregs) [TARGET_ARCH64]:
	Never return 1 for complex integral modes whose size is lesser or
	equal to a word.
	(function_arg_pass_by_reference) [TARGET_ARCH64]: Mention CTImode
	in the comment.
	(function_arg_advance) [TARGET_ARCH64]: Don't special-case complex
	modes.
	(sparc_va_arg) [TARGET_ARCH64]: Handle any modes whose is greater
	than 16 bytes by reference.

-- 
Eric Botcazou
Index: config/sparc/sparc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sparc.c,v
retrieving revision 1.266
diff -c -p -r1.266 sparc.c
*** config/sparc/sparc.c	18 Oct 2003 07:39:56 -0000	1.266
--- config/sparc/sparc.c	28 Oct 2003 13:49:46 -0000
*************** function_arg_partial_nregs (const struct
*** 5429,5435 ****
  	      && slotno == SPARC_INT_ARG_MAX - 1)
  	    return 1;
  	}
!       else if (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
  	       || (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
  		   && ! (TARGET_FPU && named)))
  	{
--- 5429,5436 ----
  	      && slotno == SPARC_INT_ARG_MAX - 1)
  	    return 1;
  	}
!       else if ((GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
! 		&& GET_MODE_SIZE (mode) > UNITS_PER_WORD)
  	       || (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
  		   && ! (TARGET_FPU && named)))
  	{
*************** function_arg_pass_by_reference (const st
*** 5476,5482 ****
    else
      {
        return ((type && TREE_CODE (type) == ARRAY_TYPE)
! 	      /* Consider complex values as aggregates, so care for TCmode.  */
  	      || GET_MODE_SIZE (mode) > 16
  	      || (type
  		  && AGGREGATE_TYPE_P (type)
--- 5477,5484 ----
    else
      {
        return ((type && TREE_CODE (type) == ARRAY_TYPE)
! 	      /* Consider complex values as aggregates, so care
! 		 for CTImode and TCmode.  */
  	      || GET_MODE_SIZE (mode) > 16
  	      || (type
  		  && AGGREGATE_TYPE_P (type)
*************** function_arg_advance (struct sparc_args 
*** 5521,5534 ****
  	  else /* passed by reference */
  	    ++cum->words;
  	}
-       else if (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
- 	{
- 	  cum->words += 2;
- 	}
-       else if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
- 	{
- 	  cum->words += GET_MODE_SIZE (mode) / UNITS_PER_WORD;
- 	}
        else
  	{
  	  cum->words += (mode != BLKmode
--- 5523,5528 ----
*************** sparc_va_arg (tree valist, tree type)
*** 5661,5677 ****
        if (TYPE_ALIGN (type) >= 2 * (unsigned) BITS_PER_WORD)
  	align = 2 * UNITS_PER_WORD;
  
!       if (AGGREGATE_TYPE_P (type))
  	{
! 	  if ((unsigned HOST_WIDE_INT) size > 16)
! 	    {
! 	      indirect = 1;
! 	      size = rsize = UNITS_PER_WORD;
! 	      align = 0;
! 	    }
! 	  /* SPARC v9 ABI states that structures up to 8 bytes in size are
! 	     given one 8 byte slot.  */
! 	  else if (size == 0)
  	    size = rsize = UNITS_PER_WORD;
  	  else
  	    size = rsize;
--- 5655,5673 ----
        if (TYPE_ALIGN (type) >= 2 * (unsigned) BITS_PER_WORD)
  	align = 2 * UNITS_PER_WORD;
  
!       /* Consider complex values as aggregates, so care
! 	 for CTImode and TCmode.  */
!       if ((unsigned HOST_WIDE_INT) size > 16)
! 	{
! 	  indirect = 1;
! 	  size = rsize = UNITS_PER_WORD;
! 	  align = 0;
! 	}
!       else if (AGGREGATE_TYPE_P (type))
  	{
! 	  /* SPARC-V9 ABI states that structures up to 16 bytes in size
! 	     are given whole integer slots as needed.  */
! 	  if (size == 0)
  	    size = rsize = UNITS_PER_WORD;
  	  else
  	    size = rsize;

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