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 complex floating-point types passing (SPARC64)


Hi,

While working on the previous patch for complex integral types, I noticed two 
nits in function_arg_partial_nregs:
- a complex float argument will be wrongly split if passed as the 6th unnamed 
parameter of a function,
- the code contains a condition that looks weird to me, to say the least.

I managed to devise a testcase for the first issue but not for the second 
one, so I fixed the former and added a ??? comment for the latter.

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


2003-11-01  Eric Botcazou  <ebotcazou@libertysurf.fr>

	* config/sparc/sparc.c (function_arg_partial_nregs) [TARGET_ARCH64]:
	Return 0 for all complex modes whose size is lesser or equal to a
	word.  Add a ??? comment for the condition used with 16-byte
	aligned modes.


2003-11-01  Eric Botcazou  <ebotcazou@libertysurf.fr>

	* gcc.dg/sparc-complex-1.c: New test.


-- 
Eric Botcazou
Index: config/sparc/sparc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sparc.c,v
retrieving revision 1.267
diff -u -p -r1.267 sparc.c
--- config/sparc/sparc.c	29 Oct 2003 15:36:12 -0000	1.267
+++ config/sparc/sparc.c	31 Oct 2003 12:59:28 -0000
@@ -5429,14 +5429,19 @@ function_arg_partial_nregs (const struct
 	      && slotno == SPARC_INT_ARG_MAX - 1)
 	    return 1;
 	}
-      else if ((GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
-		&& GET_MODE_SIZE (mode) > UNITS_PER_WORD)
+      else if (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
 	       || (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
 		   && ! (TARGET_FPU && named)))
 	{
+	  /* The complex types are passed as packed types.  */
+	  if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
+	    return 0;
+
 	  if (GET_MODE_ALIGNMENT (mode) == 128)
 	    {
 	      slotno += slotno & 1;
+
+	      /* ??? The mode needs 3 slots?  */
 	      if (slotno == SPARC_INT_ARG_MAX - 2)
 		return 1;
 	    }
/* { dg-do run { target sparc64-*-* sparcv9-*-* } } */
/* { dg-options "-O" } */

/* Verify that the 6th complex floating-point argument is
   correctly passed as unnamed argument. */

extern void abort(void);   

void foo(long arg1, long arg2, long arg3, long arg4, long arg5, ...)
{
  __builtin_va_list ap;
  _Complex float cf;

  __builtin_va_start(ap, arg5);
  cf = __builtin_va_arg(ap, _Complex float);
  __builtin_va_end(ap);

  if (__imag__ cf != 2.0f)
    abort();
}

int bar(long arg1, long arg2, long arg3, long arg4, long arg5, _Complex float arg6)
{
  foo(arg1, arg2, arg3, arg4, arg5, arg6);
  return 0;
}

int main(void)
{
  return bar(0, 0, 0, 0, 0, 2.0fi);
}

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