public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Eric Botcazou <ebotcazou@adacore.com>
To: gcc-patches@gcc.gnu.org
Subject: Re: Fix PR libffi/60073
Date: Mon, 17 Feb 2014 12:00:00 -0000	[thread overview]
Message-ID: <4610860.PLxQ7ligAu@polaris> (raw)
In-Reply-To: <8194381.ZP0W66Vpab@polaris>

[-- Attachment #1: Type: text/plain, Size: 1527 bytes --]

> This adds proper variadic support to the SPARC port of libffi, thus fixing a
> regression in the testsuite in 64-bit mode, and fixes a small inaccuracy in
> the documentation.

Follow-up patch attached.  It renames the existing FFI_V9 into FFI_COMPAT_V9 
and defines a new FFI_V9 value.  In order to avoid disturbing the V8 part, the 
new field is only added for V9, which means that more code is compiled only 
for SPARC64, hence some internal re-shuffling.

Tested on SPARC/Solaris and SPARC64/Solaris, both in a regular setup and in a 
mixed GCC 4.8/mainline setup, applied on the mainline.


2014-02-17  Eric Botcazou  <ebotcazou@adacore.com>

	PR libffi/60073
	* src/sparc/v8.S: Assemble only if !SPARC64.
	* src/sparc/v9.S: Remove obsolete comment.
	* src/sparc/ffitarget.h (enum ffi_abi): Add FFI_COMPAT_V9.
	(V8_ABI_P): New macro.
	(V9_ABI_P): Likewise.
	(FFI_EXTRA_CIF_FIELDS): Define only if SPARC64.
	* src/sparc/ffi.c (ffi_prep_args_v8): Compile only if !SPARC64.
	(ffi_prep_args_v9): Compile only if SPARC64.
	(ffi_prep_cif_machdep_core): Use V9_ABI_P predicate.
	(ffi_prep_cif_machdep): Guard access to nfixedargs field.
	(ffi_prep_cif_machdep_var): Likewise.
	(ffi_v9_layout_struct): Compile only if SPARC64.
	(ffi_call): Deal with FFI_V8PLUS and FFI_COMPAT_V9 and fix warnings.
	(ffi_prep_closure_loc): Use V9_ABI_P and V8_ABI_P predicates.
	(ffi_closure_sparc_inner_v8): Compile only if !SPARC64.
	(ffi_closure_sparc_inner_v9): Compile only if SPARC64.  Guard access
	to nfixedargs field.


-- 
Eric Botcazou

[-- Attachment #2: pr60073-2.diff --]
[-- Type: text/x-patch, Size: 17921 bytes --]

Index: src/sparc/v9.S
===================================================================
--- src/sparc/v9.S	(revision 207796)
+++ src/sparc/v9.S	(working copy)
@@ -1,6 +1,6 @@
 /* -----------------------------------------------------------------------
    v9.S - Copyright (c) 2000, 2003, 2004, 2008 Red Hat, Inc.
-   
+
    SPARC 64-bit Foreign Function Interface 
 
    Permission is hereby granted, free of charge, to any person obtaining
@@ -29,8 +29,6 @@
 #include <ffi.h>
 
 #ifdef SPARC64
-/* Only compile this in for 64bit builds, because otherwise the object file
-   will have inproper architecture due to used instructions.  */
 
 #define STACKFRAME 176		/* Minimum stack framesize for SPARC 64-bit */
 #define STACK_BIAS 2047
Index: src/sparc/ffitarget.h
===================================================================
--- src/sparc/ffitarget.h	(revision 207796)
+++ src/sparc/ffitarget.h	(working copy)
@@ -48,6 +48,8 @@ typedef enum ffi_abi {
   FFI_FIRST_ABI = 0,
   FFI_V8,
   FFI_V8PLUS,
+  /* See below for the COMPAT_V9 rationale.  */
+  FFI_COMPAT_V9,
   FFI_V9,
   FFI_LAST_ABI,
 #ifdef SPARC64
@@ -58,8 +60,19 @@ typedef enum ffi_abi {
 } ffi_abi;
 #endif
 
+#define V8_ABI_P(abi) ((abi) == FFI_V8 || (abi) == FFI_V8PLUS)
+#define V9_ABI_P(abi) ((abi) == FFI_COMPAT_V9 || (abi) == FFI_V9)
+
 #define FFI_TARGET_SPECIFIC_VARIADIC 1
+
+/* The support of variadic functions was broken in the original implementation
+   of the FFI_V9 ABI.  This has been fixed by adding one extra field to the
+   CIF structure (nfixedargs field), which means that the ABI of libffi itself
+   has changed.  In order to support applications using the original ABI, we
+   have renamed FFI_V9 into FFI_COMPAT_V9 and defined a new FFI_V9 value.  */
+#ifdef SPARC64
 #define FFI_EXTRA_CIF_FIELDS unsigned int nfixedargs
+#endif
 
 /* ---- Definitions for closures ----------------------------------------- */
 
Index: src/sparc/ffi.c
===================================================================
--- src/sparc/ffi.c	(revision 207796)
+++ src/sparc/ffi.c	(working copy)
@@ -1,7 +1,7 @@
 /* -----------------------------------------------------------------------
    ffi.c - Copyright (c) 2011 Anthony Green
            Copyright (c) 1996, 2003-2004, 2007-2008 Red Hat, Inc.
-   
+
    SPARC Foreign Function Interface 
 
    Permission is hereby granted, free of charge, to any person obtaining
@@ -34,93 +34,10 @@
 /* ffi_prep_args is called by the assembly routine once stack space
    has been allocated for the function's arguments */
 
-void ffi_prep_args_v8(char *stack, extended_cif *ecif)
-{
-  int i;
-  void **p_argv;
-  char *argp;
-  ffi_type **p_arg;
-
-  /* Skip 16 words for the window save area */
-  argp = stack + 16*sizeof(int);
-
-  /* This should only really be done when we are returning a structure,
-     however, it's faster just to do it all the time...
-
-  if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) */
-  *(int *) argp = (long)ecif->rvalue;
-
-  /* And 1 word for the  structure return value. */
-  argp += sizeof(int);
-
-#ifdef USING_PURIFY
-  /* Purify will probably complain in our assembly routine, unless we
-     zero out this memory. */
-
-  ((int*)argp)[0] = 0;
-  ((int*)argp)[1] = 0;
-  ((int*)argp)[2] = 0;
-  ((int*)argp)[3] = 0;
-  ((int*)argp)[4] = 0;
-  ((int*)argp)[5] = 0;
-#endif
-
-  p_argv = ecif->avalue;
-
-  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
-    {
-      size_t z;
-
-	  if ((*p_arg)->type == FFI_TYPE_STRUCT
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-	      || (*p_arg)->type == FFI_TYPE_LONGDOUBLE
-#endif
-	      )
-	    {
-	      *(unsigned int *) argp = (unsigned long)(* p_argv);
-	      z = sizeof(int);
-	    }
-	  else
-	    {
-	      z = (*p_arg)->size;
-	      if (z < sizeof(int))
-		{
-		  z = sizeof(int);
-		  switch ((*p_arg)->type)
-		    {
-		    case FFI_TYPE_SINT8:
-		      *(signed int *) argp = *(SINT8 *)(* p_argv);
-		      break;
-		      
-		    case FFI_TYPE_UINT8:
-		      *(unsigned int *) argp = *(UINT8 *)(* p_argv);
-		      break;
-		      
-		    case FFI_TYPE_SINT16:
-		      *(signed int *) argp = *(SINT16 *)(* p_argv);
-		      break;
-		      
-		    case FFI_TYPE_UINT16:
-		      *(unsigned int *) argp = *(UINT16 *)(* p_argv);
-		      break;
-
-		    default:
-		      FFI_ASSERT(0);
-		    }
-		}
-	      else
-		{
-		  memcpy(argp, *p_argv, z);
-		}
-	    }
-	  p_argv++;
-	  argp += z;
-    }
-  
-  return;
-}
+#ifdef SPARC64
 
-int ffi_prep_args_v9(char *stack, extended_cif *ecif)
+int
+ffi_prep_args_v9(char *stack, extended_cif *ecif)
 {
   int i, ret = 0;
   int tmp;
@@ -248,12 +165,105 @@ int ffi_prep_args_v9(char *stack, extend
   return ret;
 }
 
+#else
+
+void
+ffi_prep_args_v8(char *stack, extended_cif *ecif)
+{
+  int i;
+  void **p_argv;
+  char *argp;
+  ffi_type **p_arg;
+
+  /* Skip 16 words for the window save area */
+  argp = stack + 16*sizeof(int);
+
+  /* This should only really be done when we are returning a structure,
+     however, it's faster just to do it all the time...
+
+  if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) */
+  *(int *) argp = (long)ecif->rvalue;
+
+  /* And 1 word for the  structure return value. */
+  argp += sizeof(int);
+
+#ifdef USING_PURIFY
+  /* Purify will probably complain in our assembly routine, unless we
+     zero out this memory. */
+
+  ((int*)argp)[0] = 0;
+  ((int*)argp)[1] = 0;
+  ((int*)argp)[2] = 0;
+  ((int*)argp)[3] = 0;
+  ((int*)argp)[4] = 0;
+  ((int*)argp)[5] = 0;
+#endif
+
+  p_argv = ecif->avalue;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
+    {
+      size_t z;
+
+	  if ((*p_arg)->type == FFI_TYPE_STRUCT
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	      || (*p_arg)->type == FFI_TYPE_LONGDOUBLE
+#endif
+	      )
+	    {
+	      *(unsigned int *) argp = (unsigned long)(* p_argv);
+	      z = sizeof(int);
+	    }
+	  else
+	    {
+	      z = (*p_arg)->size;
+	      if (z < sizeof(int))
+		{
+		  z = sizeof(int);
+		  switch ((*p_arg)->type)
+		    {
+		    case FFI_TYPE_SINT8:
+		      *(signed int *) argp = *(SINT8 *)(* p_argv);
+		      break;
+		      
+		    case FFI_TYPE_UINT8:
+		      *(unsigned int *) argp = *(UINT8 *)(* p_argv);
+		      break;
+		      
+		    case FFI_TYPE_SINT16:
+		      *(signed int *) argp = *(SINT16 *)(* p_argv);
+		      break;
+		      
+		    case FFI_TYPE_UINT16:
+		      *(unsigned int *) argp = *(UINT16 *)(* p_argv);
+		      break;
+
+		    default:
+		      FFI_ASSERT(0);
+		    }
+		}
+	      else
+		{
+		  memcpy(argp, *p_argv, z);
+		}
+	    }
+	  p_argv++;
+	  argp += z;
+    }
+  
+  return;
+}
+
+#endif
+
 /* Perform machine dependent cif processing */
-static ffi_status ffi_prep_cif_machdep_core(ffi_cif *cif)
+
+static
+ffi_status ffi_prep_cif_machdep_core(ffi_cif *cif)
 {
   int wordsize;
 
-  if (cif->abi != FFI_V9)
+  if (!V9_ABI_P (cif->abi))
     {
       wordsize = 4;
 
@@ -303,7 +313,7 @@ static ffi_status ffi_prep_cif_machdep_c
       break;
 
     case FFI_TYPE_STRUCT:
-      if (cif->abi == FFI_V9 && cif->rtype->size > 32)
+      if (V9_ABI_P (cif->abi) && cif->rtype->size > 32)
 	cif->flags = FFI_TYPE_VOID;
       else
 	cif->flags = FFI_TYPE_STRUCT;
@@ -313,7 +323,7 @@ static ffi_status ffi_prep_cif_machdep_c
     case FFI_TYPE_UINT8:
     case FFI_TYPE_SINT16:
     case FFI_TYPE_UINT16:
-      if (cif->abi == FFI_V9)
+      if (V9_ABI_P (cif->abi))
 	cif->flags = FFI_TYPE_INT;
       else
 	cif->flags = cif->rtype->type;
@@ -321,7 +331,7 @@ static ffi_status ffi_prep_cif_machdep_c
 
     case FFI_TYPE_SINT64:
     case FFI_TYPE_UINT64:
-      if (cif->abi == FFI_V9)
+      if (V9_ABI_P (cif->abi))
 	cif->flags = FFI_TYPE_INT;
       else
 	cif->flags = FFI_TYPE_SINT64;
@@ -334,20 +344,31 @@ static ffi_status ffi_prep_cif_machdep_c
   return FFI_OK;
 }
 
-ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+ffi_status
+ffi_prep_cif_machdep(ffi_cif *cif)
 {
-  cif->nfixedargs = cif->nargs;
+#ifdef SPARC64
+  if (cif->abi != FFI_COMPAT_V9)
+    cif->nfixedargs = cif->nargs;
+#endif
   return ffi_prep_cif_machdep_core (cif);
 }
 
-ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned int nfixedargs,
-				    unsigned int ntotalargs)
+ffi_status
+ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned int nfixedargs,
+			 unsigned int ntotalargs)
 {
-  cif->nfixedargs = nfixedargs;
+#ifdef SPARC64
+  if (cif->abi != FFI_COMPAT_V9)
+    cif->nfixedargs = nfixedargs;
+#endif
   return ffi_prep_cif_machdep_core (cif);
 }
 
-int ffi_v9_layout_struct(ffi_type *arg, int off, char *ret, char *intg, char *flt)
+#ifdef SPARC64
+
+int
+ffi_v9_layout_struct(ffi_type *arg, int off, char *ret, char *intg, char *flt)
 {
   ffi_type **ptr = &arg->elements[0];
 
@@ -380,6 +401,7 @@ int ffi_v9_layout_struct(ffi_type *arg,
   return off;
 }
 
+#endif
 
 #ifdef SPARC64
 extern int ffi_call_v9(void *, extended_cif *, unsigned, 
@@ -389,33 +411,37 @@ extern int ffi_call_v8(void *, extended_
 		       unsigned, unsigned *, void (*fn)(void));
 #endif
 
-void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
+void
+ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
 {
   extended_cif ecif;
+#ifdef SPARC64
   void *rval = rvalue;
+#endif
 
   ecif.cif = cif;
   ecif.avalue = avalue;
-
-  /* If the return value is a struct and we don't have a return	*/
-  /* value address then we need to make one		        */
-
   ecif.rvalue = rvalue;
+
+  /* If the return value is a struct and we don't have a return value address,
+     then we need to make one.  */
   if (cif->rtype->type == FFI_TYPE_STRUCT)
     {
+      if (ecif.rvalue == NULL)
+	ecif.rvalue = alloca(cif->rtype->size);
+
+#ifdef SPARC64
       if (cif->rtype->size <= 32)
 	rval = alloca(64);
       else
-	{
-	  rval = NULL;
-	  if (rvalue == NULL)
-	    ecif.rvalue = alloca(cif->rtype->size);
-	}
+	rval = NULL;
+#endif
     }
 
   switch (cif->abi) 
     {
     case FFI_V8:
+    case FFI_V8PLUS:
 #ifdef SPARC64
       /* We don't yet support calling 32bit code from 64bit */
       FFI_ASSERT(0);
@@ -430,7 +456,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(v
 	  /* behind "call", so we alloc some executable space for it. */
 	  /* l7 is used, we need to make sure v8.S doesn't use %l7.   */
 	  unsigned int *call_struct = NULL;
-	  ffi_closure_alloc(32, &call_struct);
+	  ffi_closure_alloc(32, (void **)&call_struct);
 	  if (call_struct)
 	    {
 	      unsigned long f = (unsigned long)fn;
@@ -450,7 +476,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(v
 	      /* SPARC v8 requires 5 instructions for flush to be visible */
 	      asm volatile ("nop; nop; nop; nop; nop");
 	      ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
-			  cif->flags, rvalue, call_struct);
+			  cif->flags, rvalue, (void (*)(void)) call_struct);
 	      ffi_closure_free(call_struct);
 	    }
 	  else
@@ -466,12 +492,13 @@ void ffi_call(ffi_cif *cif, void (*fn)(v
 	}
 #endif
       break;
+    case FFI_COMPAT_V9:
     case FFI_V9:
 #ifdef SPARC64
-      ffi_call_v9(ffi_prep_args_v9, &ecif, cif->bytes,
-		  cif->flags, rval, fn);
+      ffi_call_v9(ffi_prep_args_v9, &ecif, cif->bytes, cif->flags, rval, fn);
       if (rvalue && rval && cif->rtype->type == FFI_TYPE_STRUCT)
-	ffi_v9_layout_struct(cif->rtype, 0, (char *)rvalue, (char *)rval, ((char *)rval)+32);
+	ffi_v9_layout_struct(cif->rtype, 0, (char *)rvalue, (char *)rval,
+			     ((char *)rval)+32);
 #else
       /* And vice versa */
       FFI_ASSERT(0);
@@ -502,7 +529,7 @@ ffi_prep_closure_loc (ffi_closure* closu
 #ifdef SPARC64
   /* Trampoline address is equal to the closure address.  We take advantage
      of that to reduce the trampoline size by 8 bytes. */
-  if (cif->abi != FFI_V9)
+  if (!V9_ABI_P (cif->abi))
     return FFI_BAD_ABI;
   fn = (unsigned long) ffi_closure_v9;
   tramp[0] = 0x83414000;	/* rd	%pc, %g1	*/
@@ -512,7 +539,7 @@ ffi_prep_closure_loc (ffi_closure* closu
   *((unsigned long *) &tramp[4]) = fn;
 #else
   unsigned long ctx = (unsigned long) codeloc;
-  if (cif->abi != FFI_V8)
+  if (!V8_ABI_P (cif->abi))
     return FFI_BAD_ABI;
   fn = (unsigned long) ffi_closure_v8;
   tramp[0] = 0x03000000 | fn >> 10;	/* sethi %hi(fn), %g1	*/
@@ -537,74 +564,11 @@ ffi_prep_closure_loc (ffi_closure* closu
   return FFI_OK;
 }
 
-int
-ffi_closure_sparc_inner_v8(ffi_closure *closure,
-  void *rvalue, unsigned long *gpr, unsigned long *scratch)
-{
-  ffi_cif *cif;
-  ffi_type **arg_types;
-  void **avalue;
-  int i, argn;
-
-  cif = closure->cif;
-  arg_types = cif->arg_types;
-  avalue = alloca(cif->nargs * sizeof(void *));
-
-  /* Copy the caller's structure return address so that the closure
-     returns the data directly to the caller.  */
-  if (cif->flags == FFI_TYPE_STRUCT
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE  
-      || cif->flags == FFI_TYPE_LONGDOUBLE
-#endif
-     )
-    rvalue = (void *) gpr[0];
-
-  /* Always skip the structure return address.  */
-  argn = 1;
-
-  /* Grab the addresses of the arguments from the stack frame.  */
-  for (i = 0; i < cif->nargs; i++)
-    {
-      if (arg_types[i]->type == FFI_TYPE_STRUCT
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-	  || arg_types[i]->type == FFI_TYPE_LONGDOUBLE
-#endif
-         )
-	{
-	  /* Straight copy of invisible reference.  */
-	  avalue[i] = (void *)gpr[argn++];
-	}
-      else if ((arg_types[i]->type == FFI_TYPE_DOUBLE
-	       || arg_types[i]->type == FFI_TYPE_SINT64
-	       || arg_types[i]->type == FFI_TYPE_UINT64)
-	       /* gpr is 8-byte aligned.  */
-	       && (argn % 2) != 0)
-	{
-	  /* Align on a 8-byte boundary.  */
-	  scratch[0] = gpr[argn];
-	  scratch[1] = gpr[argn+1];
-	  avalue[i] = scratch;
-	  scratch -= 2;
-	  argn += 2;
-	}
-      else
-	{
-	  /* Always right-justify.  */
-	  argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
-	  avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size;
-	}
-    }
-
-  /* Invoke the closure.  */
-  (closure->fun) (cif, rvalue, avalue, closure->user_data);
-
-  /* Tell ffi_closure_sparc how to perform return type promotions.  */
-  return cif->rtype->type;
-}
+#ifdef SPARC64
 
 int
-ffi_closure_sparc_inner_v9(ffi_closure *closure,
-  void *rvalue, unsigned long *gpr, double *fpr)
+ffi_closure_sparc_inner_v9(ffi_closure *closure, void *rvalue,
+			   unsigned long *gpr, double *fpr)
 {
   ffi_cif *cif;
   ffi_type **arg_types;
@@ -633,7 +597,8 @@ ffi_closure_sparc_inner_v9(ffi_closure *
     {
       /* If the function is variadic, FP arguments are passed in FP
 	 registers only if the corresponding parameter is named.  */
-      const int named = (i < cif->nfixedargs);
+      const int named
+	= (cif->abi == FFI_COMPAT_V9 ? 1 : i < cif->nfixedargs);
 
       if (arg_types[i]->type == FFI_TYPE_STRUCT)
 	{
@@ -653,7 +618,8 @@ ffi_closure_sparc_inner_v9(ffi_closure *
 				   ? (char *) &fpr[argn]
 				   : (char *) &gpr[argn]);
 	      avalue[i] = &gpr[argn];
-	      argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+	      argn
+	        += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
 	    }
 	}
       else
@@ -686,3 +652,72 @@ ffi_closure_sparc_inner_v9(ffi_closure *
   /* Tell ffi_closure_sparc how to perform return type promotions.  */
   return cif->rtype->type;
 }
+
+#else
+
+int
+ffi_closure_sparc_inner_v8(ffi_closure *closure, void *rvalue,
+			   unsigned long *gpr, unsigned long *scratch)
+{
+  ffi_cif *cif;
+  ffi_type **arg_types;
+  void **avalue;
+  int i, argn;
+
+  cif = closure->cif;
+  arg_types = cif->arg_types;
+  avalue = alloca(cif->nargs * sizeof(void *));
+
+  /* Copy the caller's structure return address so that the closure
+     returns the data directly to the caller.  */
+  if (cif->flags == FFI_TYPE_STRUCT
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE  
+      || cif->flags == FFI_TYPE_LONGDOUBLE
+#endif
+     )
+    rvalue = (void *) gpr[0];
+
+  /* Always skip the structure return address.  */
+  argn = 1;
+
+  /* Grab the addresses of the arguments from the stack frame.  */
+  for (i = 0; i < cif->nargs; i++)
+    {
+      if (arg_types[i]->type == FFI_TYPE_STRUCT
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	  || arg_types[i]->type == FFI_TYPE_LONGDOUBLE
+#endif
+         )
+	{
+	  /* Straight copy of invisible reference.  */
+	  avalue[i] = (void *)gpr[argn++];
+	}
+      else if ((arg_types[i]->type == FFI_TYPE_DOUBLE
+	       || arg_types[i]->type == FFI_TYPE_SINT64
+	       || arg_types[i]->type == FFI_TYPE_UINT64)
+	       /* gpr is 8-byte aligned.  */
+	       && (argn % 2) != 0)
+	{
+	  /* Align on a 8-byte boundary.  */
+	  scratch[0] = gpr[argn];
+	  scratch[1] = gpr[argn+1];
+	  avalue[i] = scratch;
+	  scratch -= 2;
+	  argn += 2;
+	}
+      else
+	{
+	  /* Always right-justify.  */
+	  argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+	  avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size;
+	}
+    }
+
+  /* Invoke the closure.  */
+  closure->fun (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell ffi_closure_sparc how to perform return type promotions.  */
+  return cif->rtype->type;
+}
+
+#endif
Index: src/sparc/v8.S
===================================================================
--- src/sparc/v8.S	(revision 207796)
+++ src/sparc/v8.S	(working copy)
@@ -1,6 +1,6 @@
 /* -----------------------------------------------------------------------
    v8.S - Copyright (c) 1996, 1997, 2003, 2004, 2008 Red Hat, Inc.
-   
+
    SPARC Foreign Function Interface 
 
    Permission is hereby granted, free of charge, to any person obtaining
@@ -28,6 +28,8 @@
 #include <fficonfig.h>
 #include <ffi.h>
 
+#ifndef SPARC64
+
 #define STACKFRAME 96		/* Minimum stack framesize for SPARC */
 #define ARGS (64+4)		/* Offset of register area in frame */
 
@@ -307,6 +309,7 @@ done2:
 	.byte	0x1f	! uleb128 0x1f
 	.align	WS
 .LLEFDE2:
+#endif
 
 #if defined __ELF__ && defined __linux__
 	.section	.note.GNU-stack,"",@progbits

  parent reply	other threads:[~2014-02-17 12:00 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-13 16:19 Eric Botcazou
2014-02-14  9:55 ` Alan Modra
2014-02-14 10:33   ` Eric Botcazou
2014-02-17 12:00 ` Eric Botcazou [this message]
  -- strict thread matches above, loose matches on Subject: below --
2014-02-13 16:19 Eric Botcazou

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4610860.PLxQ7ligAu@polaris \
    --to=ebotcazou@adacore.com \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).