This is the mail archive of the libffi-discuss@sources.redhat.com mailing list for the libffi project.


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

[PATCH] Support for sparc-*-linux* and sparc64-*-linux*


Hi!

Following patch adds support for 32bit and 64bit SPARC Linux targets.
It does not yet support cross calls from 32bit libffi to 64bit code and vice
versa, but I guess there would be many other problems with it anyway
(e.g. address space issues).
ffitest succeeds on both platforms.
The 64bit code (new in this patch) might work on Solaris as well,
but I could not test it.
I wonder also why FFI_TYPE_UNION type is missing. If it ever gets added,
then FFI_V9 structure/union returning code will have to be changed slightly
(any union part of structure/union is passed only in integer registers,
while for other types it depends on the type of the variable (integer values
in integer registers, floating values for floating registers)).
Another thing which I've changed here (and am going to submit an automake
patch as well) is that libtool --mode=link $(CCLD)
will not work on sparc64 with multilibing, because the linking depends on
the multilib flags in CCLD and when it is not surrounded by double quotes,
libtool throws that away and thus the build fails.

2000-04-14  Jakub Jelinek  <jakub@redhat.com>

        * include/ffi.h.in (SPARC64): Define for 64bit SPARC builds.
	Set SPARC FFI_DEFAULT_ABI based on SPARC64 define.
	* src/sparc/ffi.c (ffi_prep_args_v8): Renamed from ffi_prep_args.
	Replace all void * sizeofs with sizeof(int).
	Only compare type with FFI_TYPE_LONGDOUBLE if LONGDOUBLE is
	different than DOUBLE.
	Remove FFI_TYPE_SINT32 and FFI_TYPE_UINT32 cases (handled elsewhere).
	(ffi_prep_args_v9): New function.
	(ffi_prep_cif_machdep): Handle V9 ABI and long long on V8.
	(ffi_V9_return_struct): New function.
	(ffi_call): Handle FFI_V9 ABI from 64bit code and FFI_V8 ABI from
	32bit code (not yet cross-arch calls).
	* src/sparc/v8.S: Add struct return delay nop.
	Handle long long.
	* src/sparc/v9.S: New file.
	* src/prep_cif.c (ffi_prep_cif): Return structure pointer
	is used on sparc64 only for structures larger than 32 bytes.
	Pass by reference for structures is done for structure arguments
	larger than 16 bytes.
	* src/ffitest.c (main): Use 64bit rint on sparc64.
	Run long long tests on sparc.
	* src/types.c (FFI_TYPE_POINTER): Pointer is 64bit on alpha and
	sparc64.
	(FFI_TYPE_LONGDOUBLE): long double is 128 bit aligned to 128 bits
	on sparc64.
	* configure.in (sparc-*-linux*): New supported target.
	(sparc64-*-linux*): Likewise.
	* configure: Rebuilt.
	* Makefile.am: Add v9.S to SPARC files.
	* Makefile.in: Likewise.
	(LINK): Surround $(CCLD) into double quotes, so that multilib
	compiles work correctly.

--- libffi/include/ffi.h.in.jj	Fri Feb 25 20:13:44 2000
+++ libffi/include/ffi.h.in	Fri Apr 14 10:29:54 2000
@@ -160,6 +160,12 @@ extern "C" {
 #define SIZEOF_ARG SIZEOF_VOID_P
 #endif
 
+#ifdef SPARC
+#if defined(__arch64__) || defined(__sparcv9)
+#define SPARC64
+#endif
+#endif
+
 #ifndef LIBFFI_ASM
 
 /* ---- Generic type definitions ----------------------------------------- */
@@ -176,9 +182,13 @@ typedef enum ffi_abi {
   /* ---- Sparc -------------------- */
 #ifdef SPARC
   FFI_V8,
-  FFI_DEFAULT_ABI = FFI_V8,
   FFI_V8PLUS,
   FFI_V9,
+#ifdef SPARC64
+  FFI_DEFAULT_ABI = FFI_V9,
+#else
+  FFI_DEFAULT_ABI = FFI_V8,
+#endif
 #endif
 
   /* ---- Intel x86 ---------------- */
--- libffi/src/sparc/ffi.c.jj	Sun Aug  8 15:27:19 1999
+++ libffi/src/sparc/ffi.c	Fri Apr 14 10:27:31 2000
@@ -33,7 +33,7 @@
 /* ffi_prep_args is called by the assembly routine once stack space
    has been allocated for the function's arguments */
 
-void ffi_prep_args(char *stack, extended_cif *ecif)
+void ffi_prep_args_v8(char *stack, extended_cif *ecif)
 {
   int i;
   int tmp;
@@ -45,16 +45,16 @@ void ffi_prep_args(char *stack, extended
   tmp = 0;
 
   /* Skip 16 words for the window save area */
-  argp = stack + 16*sizeof(void*);
+  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 ) */
-  *(void **) argp = ecif->rvalue;
+  *(int *) argp = (long)ecif->rvalue;
 
   /* And 1 word for the  structure return value. */
-  argp += sizeof(void*);
+  argp += sizeof(int);
 
 #ifdef USING_PURIFY
   /* Purify will probably complain in our assembly routine, unless we
@@ -81,10 +81,13 @@ void ffi_prep_args(char *stack, extended
 	{
 	  avn--;
 	  if ((*p_arg)->type == FFI_TYPE_STRUCT
-	      || (*p_arg)->type == FFI_TYPE_LONGDOUBLE)
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	      || (*p_arg)->type == FFI_TYPE_LONGDOUBLE
+#endif
+	      )
 	    {
-	      *(unsigned int *) argp = (unsigned int)(* p_argv);
-	      z = sizeof(void*);
+	      *(unsigned int *) argp = (unsigned long)(* p_argv);
+	      z = sizeof(int);
 	    }
 	  else
 	    {
@@ -109,15 +112,7 @@ void ffi_prep_args(char *stack, extended
 		    case FFI_TYPE_UINT16:
 		      *(unsigned int *) argp = *(UINT16 *)(* p_argv);
 		      break;
-		      
-		    case FFI_TYPE_SINT32:
-		      *(signed int *) argp = *(SINT32 *)(* p_argv);
-		      break;
-		      
-		    case FFI_TYPE_UINT32:
-		      *(unsigned int *) argp = *(UINT32 *)(* p_argv);
-		      break;
-		      
+
 		    default:
 		      FFI_ASSERT(0);
 		    }
@@ -135,82 +130,295 @@ void ffi_prep_args(char *stack, extended
   return;
 }
 
+int ffi_prep_args_v9(char *stack, extended_cif *ecif)
+{
+  int i, ret = 0;
+  int tmp;
+  void **p_argv;
+  char *argp;
+  ffi_type **p_arg;
+
+  tmp = 0;
+
+  /* Skip 16 words for the window save area */
+  argp = stack + 16*sizeof(long long);
+
+#ifdef USING_PURIFY
+  /* Purify will probably complain in our assembly routine, unless we
+     zero out this memory. */
+
+  ((long long*)argp)[0] = 0;
+  ((long long*)argp)[1] = 0;
+  ((long long*)argp)[2] = 0;
+  ((long long*)argp)[3] = 0;
+  ((long long*)argp)[4] = 0;
+  ((long long*)argp)[5] = 0;
+#endif
+
+  p_argv = ecif->avalue;
+
+  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT &&
+      ecif->cif->rtype->size > 32)
+    {
+      *(unsigned long long *) argp = (unsigned long)ecif->rvalue;
+      tmp = 1;
+    }
+
+  for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs;
+       i++, p_arg++)
+    {
+      size_t z;
+
+      z = (*p_arg)->size;
+      switch ((*p_arg)->type)
+	{
+	case FFI_TYPE_STRUCT:
+	  if (z > 16)
+	    {
+	      /* For structures larger than 16 bytes we pass reference.  */
+	      *(unsigned long long *) argp = (unsigned long)* p_argv;
+	      argp += sizeof(long long);
+	      tmp++;
+	      p_argv++;
+	      continue;
+	    }
+	  /* FALLTHROUGH */
+	case FFI_TYPE_FLOAT:
+	case FFI_TYPE_DOUBLE:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	case FFI_TYPE_LONGDOUBLE:
+#endif
+	  ret = 1; /* We should promote into FP regs as well as integer.  */
+	  break;
+	}
+      if (z < sizeof(long long))
+	{
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	      *(signed long long *) argp = *(SINT8 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_UINT8:
+	      *(unsigned long long *) argp = *(UINT8 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_SINT16:
+	      *(signed long long *) argp = *(SINT16 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_UINT16:
+	      *(unsigned long long *) argp = *(UINT16 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_SINT32:
+	      *(signed long long *) argp = *(SINT32 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_UINT32:
+	      *(unsigned long long *) argp = *(UINT32 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_FLOAT:
+	      *(float *) (argp + 4) = *(FLOAT32 *)(* p_argv); /* Right justify */
+	      break;
+
+	    case FFI_TYPE_STRUCT:
+	      memcpy(argp, *p_argv, z);
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	  z = sizeof(long long);
+	  tmp++;
+	}
+      else if (z == sizeof(long long))
+	{
+	  memcpy(argp, *p_argv, z);
+	  z = sizeof(long long);
+	  tmp++;
+	}
+      else
+	{
+	  if ((tmp & 1) && (*p_arg)->alignment > 8)
+	    {
+	      tmp++;
+	      argp += sizeof(long long);
+	    }
+	  memcpy(argp, *p_argv, z);
+	  z = 2 * sizeof(long long);
+	  tmp += 2;
+	}
+      p_argv++;
+      argp += z;
+    }
+
+  return ret;
+}
+
 /* Perform machine dependent cif processing */
 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
 {
-  /* If we are returning a struct, this will already have been added.
-     Otherwise we need to add it because it's always got to be there! */
+  int wordsize;
+
+  if (cif->abi != FFI_V9)
+    {
+      wordsize = 4;
+
+      /* If we are returning a struct, this will already have been added.
+	 Otherwise we need to add it because it's always got to be there! */
 
-  if (cif->rtype->type != FFI_TYPE_STRUCT)
-    cif->bytes += sizeof(void*);
+      if (cif->rtype->type != FFI_TYPE_STRUCT)
+	cif->bytes += wordsize;
 
-  /* sparc call frames require that space is allocated for 6 args,
-     even if they aren't used. Make that space if necessary. */
+      /* sparc call frames require that space is allocated for 6 args,
+	 even if they aren't used. Make that space if necessary. */
   
-  if (cif->bytes < 4*6+4)
-    cif->bytes = 4*6+4;
+      if (cif->bytes < 4*6+4)
+	cif->bytes = 4*6+4;
+    }
+  else
+    {
+      wordsize = 8;
+
+      /* sparc call frames require that space is allocated for 6 args,
+	 even if they aren't used. Make that space if necessary. */
+  
+      if (cif->bytes < 8*6)
+	cif->bytes = 8*6;
+    }
 
   /* Adjust cif->bytes. to include 16 words for the window save area,
      and maybe the struct/union return pointer area, */
 
-  cif->bytes += 64;
+  cif->bytes += 16 * wordsize;
 
-  /* The stack must be double word aligned, so round bytes up
+  /* The stack must be 2 word aligned, so round bytes up
      appropriately. */
 
-  cif->bytes = ALIGN(cif->bytes, 2*sizeof(void*));
+  cif->bytes = ALIGN(cif->bytes, 2 * wordsize);
 
   /* Set the return type flag */
   switch (cif->rtype->type)
     {
     case FFI_TYPE_VOID:
-    case FFI_TYPE_STRUCT:
-      cif->flags = cif->rtype->type;
-      break;
-
     case FFI_TYPE_FLOAT:
-      cif->flags = FFI_TYPE_FLOAT;
+    case FFI_TYPE_DOUBLE:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+    case FFI_TYPE_LONGDOUBLE:
+#endif
+      cif->flags = cif->rtype->type;
       break;
 
-    case FFI_TYPE_DOUBLE:
-      cif->flags = FFI_TYPE_DOUBLE;
+    case FFI_TYPE_STRUCT:
+      if (cif->abi == FFI_V9 && cif->rtype->size > 32)
+	cif->flags = FFI_TYPE_VOID;
+      else
+	cif->flags = FFI_TYPE_STRUCT;
       break;
 
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_UINT64:
+      if (cif->abi != FFI_V9)
+	{
+	  cif->flags = FFI_TYPE_SINT64;
+	  break;
+	}
+      /* FALLTHROUGH */
     default:
       cif->flags = FFI_TYPE_INT;
       break;
     }
-
   return FFI_OK;
 }
 
+int ffi_V9_return_struct(ffi_type *arg, int off, char *ret, char *intg, char *flt)
+{
+  ffi_type **ptr = &arg->elements[0];
+
+  while (*ptr != NULL)
+    {
+      if (off & ((*ptr)->alignment - 1))
+	off = ALIGN(off, (*ptr)->alignment);
+
+      switch ((*ptr)->type)
+	{
+	case FFI_TYPE_STRUCT:
+	  off = ffi_V9_return_struct(*ptr, off, ret, intg, flt);
+	  break;
+	case FFI_TYPE_FLOAT:
+	case FFI_TYPE_DOUBLE:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	case FFI_TYPE_LONGDOUBLE:
+#endif
+	  memcpy(ret + off, flt + off, (*ptr)->size);
+	  off += (*ptr)->size;
+	  break;
+	default:
+	  memcpy(ret + off, intg + off, (*ptr)->size);
+	  off += (*ptr)->size;
+	  break;
+	}
+      ptr++;
+    }
+  return off;
+}
+
 extern int ffi_call_V8(void *, extended_cif *, unsigned, 
 		       unsigned, unsigned *, void (*fn)());
+extern int ffi_call_V9(void *, extended_cif *, unsigned, 
+		       unsigned, unsigned *, void (*fn)());
 
 void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
 {
   extended_cif ecif;
+  void *rval = rvalue;
 
   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		        */
-  
-  if ((rvalue == NULL) && 
-      (cif->rtype->type == FFI_TYPE_STRUCT))
-    ecif.rvalue = alloca(cif->rtype->size);
-  else
-    ecif.rvalue = rvalue;
-    
+
+  ecif.rvalue = rvalue;
+  if (cif->rtype->type == FFI_TYPE_STRUCT)
+    {
+      if (cif->rtype->size <= 32)
+	rval = alloca(64);
+      else
+	{
+	  rval = NULL;
+	  if (rvalue == NULL)
+	    ecif.rvalue = alloca(cif->rtype->size);
+	}
+    }
+
   switch (cif->abi) 
     {
     case FFI_V8:
-      ffi_call_V8(ffi_prep_args, &ecif, cif->bytes, 
+#ifdef SPARC64
+      /* We don't yet support calling 32bit code from 64bit */
+      FFI_ASSERT(0);
+#else
+      ffi_call_V8(ffi_prep_args_v8, &ecif, cif->bytes, 
 		  cif->flags, rvalue, fn);
+#endif
+      break;
+    case FFI_V9:
+#ifdef SPARC64
+      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_return_struct(cif->rtype, 0, (char *)rvalue, (char *)rval, ((char *)rval)+32);
+#else
+      /* And vice versa */
+      FFI_ASSERT(0);
+#endif
       break;
     default:
       FFI_ASSERT(0);
       break;
     }
+
 }
--- libffi/src/sparc/v8.S.jj	Sun Aug  8 15:27:19 1999
+++ libffi/src/sparc/v8.S	Thu Apr 13 15:15:16 2000
@@ -56,6 +56,7 @@ _ffi_call_V8:
 	ld	[%l0+ARGS+20], %o5
 	call	%i5
 	mov	%l0, %sp	! (delay) switch to frame
+	nop			! STRUCT returning functions skip 12 instead of 8 bytes
 
 	! If the return value pointer is NULL, assume no return value.
 	tst	%i4
@@ -70,6 +71,9 @@ _ffi_call_V8:
 	be,a	done
 	st	%f0, [%i4+0]	! (delay)
 
+	cmp	%i3, FFI_TYPE_SINT64
+	be	longlong
+
 	cmp	%i3, FFI_TYPE_DOUBLE
 	bne	done
 	nop
@@ -77,6 +81,12 @@ _ffi_call_V8:
 	st	%f1, [%i4+4]
 	
 done:
+	ret
+	restore
+
+longlong:
+	st	%o0, [%i4+0]
+	st	%o1, [%i4+4]
 	ret
 	restore
 
--- libffi/src/sparc/v9.S.jj	Thu Apr 13 14:58:15 2000
+++ libffi/src/sparc/v9.S	Fri Apr 14 09:26:45 2000
@@ -0,0 +1,127 @@
+/* -----------------------------------------------------------------------
+   v9.S - Copyright (c) 2000 Cygnus Solutions
+   
+   Sparc 64bit Foreign Function Interface 
+
+   $Id:$
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#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 128		/* Minimum stack framesize for SPARC */
+#define STACK_BIAS 2047
+#define ARGS (128)		/* Offset of register area in frame */
+
+.text
+        .align 8
+.globl ffi_call_V9
+.globl _ffi_call_V9
+
+ffi_call_V9:
+_ffi_call_V9:
+	save	%sp, -STACKFRAME, %sp
+	
+	sub	%sp, %i2, %sp	! alloca() space in stack for frame to set up
+	add	%sp, STACKFRAME+STACK_BIAS, %l0	! %l0 has start of 
+						! frame to set up
+
+	mov	%l0, %o0	! call routine to set up frame
+	call	%i0
+	 mov	%i1, %o1	! (delay)
+	brz,pt	%o0, 1f
+	 ldx	[%l0+ARGS], %o0	! call foreign function
+
+	ldd	[%l0+ARGS], %f0
+	ldd	[%l0+ARGS+8], %f2
+	ldd	[%l0+ARGS+16], %f4
+	ldd	[%l0+ARGS+24], %f6
+	ldd	[%l0+ARGS+32], %f8
+	ldd	[%l0+ARGS+40], %f10
+	ldd	[%l0+ARGS+48], %f12
+	ldd	[%l0+ARGS+56], %f14
+	ldd	[%l0+ARGS+64], %f16
+	ldd	[%l0+ARGS+72], %f18
+	ldd	[%l0+ARGS+80], %f20
+	ldd	[%l0+ARGS+88], %f22
+	ldd	[%l0+ARGS+96], %f24
+	ldd	[%l0+ARGS+104], %f26
+	ldd	[%l0+ARGS+112], %f28
+	ldd	[%l0+ARGS+120], %f30
+
+1:	ldx	[%l0+ARGS+8], %o1
+	ldx	[%l0+ARGS+16], %o2
+	ldx	[%l0+ARGS+24], %o3
+	ldx	[%l0+ARGS+32], %o4
+	ldx	[%l0+ARGS+40], %o5
+	call	%i5
+	 sub	%l0, STACK_BIAS, %sp	! (delay) switch to frame
+
+	! If the return value pointer is NULL, assume no return value.
+	brz,pn	%i4, done
+	 nop
+
+	cmp	%i3, FFI_TYPE_INT
+	be,a,pt	%icc, done
+	 stx	%o0, [%i4]	! (delay)
+
+	cmp	%i3, FFI_TYPE_FLOAT
+	be,a,pn	%icc, done
+	 st	%f0, [%i4+0]	! (delay)
+
+	cmp	%i3, FFI_TYPE_DOUBLE
+	be,a,pn	%icc, done
+	 std	%f0, [%i4+0]	! (delay)
+
+	cmp	%i3, FFI_TYPE_STRUCT
+	be,pn	%icc, dostruct
+
+	 cmp	%i3, FFI_TYPE_LONGDOUBLE
+	bne,pt	%icc, done
+	 nop
+	std	%f0, [%i4+0]
+	std	%f2, [%i4+8]
+
+done:	ret
+	 restore
+
+dostruct:
+	/* This will not work correctly for unions. */
+	stx	%o0, [%i4+0]
+	stx	%o1, [%i4+8]
+	stx	%o2, [%i4+16]
+	stx	%o3, [%i4+24]
+	std	%f0, [%i4+32]
+	std	%f2, [%i4+40]
+	std	%f4, [%i4+48]
+	std	%f6, [%i4+56]
+	ret
+	 restore
+
+.ffi_call_V9_end:
+        .size    ffi_call_V9,.ffi_call_V9_end-ffi_call_V9
+
+#endif
--- libffi/src/prep_cif.c.jj	Sun Aug  8 15:27:19 1999
+++ libffi/src/prep_cif.c	Fri Apr 14 10:22:57 2000
@@ -107,7 +107,11 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@par
 
 #ifndef M68K
   /* Make space for the return structure pointer */
-  if (cif->rtype->type == FFI_TYPE_STRUCT)
+  if (cif->rtype->type == FFI_TYPE_STRUCT
+#ifdef SPARC
+      && (cif->abi != FFI_V9 || cif->rtype->size > 32)
+#endif
+      )
     bytes = STACK_ARG_SIZE(sizeof(void*));
 #endif
 
@@ -121,8 +125,10 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@par
 	return FFI_BAD_TYPEDEF;
 
 #ifdef SPARC
-      if ((*ptr)->type == FFI_TYPE_STRUCT
-	  || (*ptr)->type == FFI_TYPE_LONGDOUBLE)
+      if (((*ptr)->type == FFI_TYPE_STRUCT
+	   && ((*ptr)->size > 16 || cif->abi != FFI_V9))
+	  || ((*ptr)->type == FFI_TYPE_LONGDOUBLE
+	      && cif->abi != FFI_V9))
 	bytes += sizeof(void*);
       else
 #endif
@@ -140,4 +146,3 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@par
   /* Perform machine dependent cif processing */
   return ffi_prep_cif_machdep(cif);
 }
-
--- libffi/src/ffitest.c.jj	Fri Feb 25 20:13:44 2000
+++ libffi/src/ffitest.c	Fri Apr 14 10:23:34 2000
@@ -224,7 +224,7 @@ int main(/*@unused@*/ int argc, /*@unuse
   signed int si1;
   signed int si2;
 
-#if defined(ALPHA) || defined(IA64) || (defined(MIPS) && (_MIPS_SIM == _ABIN32))
+#if defined(ALPHA) || defined(IA64) || defined(SPARC64) || (defined(MIPS) && (_MIPS_SIM == _ABIN32))
   long long rint;
 #else
   int rint;
@@ -295,7 +295,7 @@ int main(/*@unused@*/ int argc, /*@unuse
 
   /* return value tests */
   {
-#if defined(MIPS) || defined(SPARC) /* || defined(ARM) */
+#if defined(MIPS) /* || defined(ARM) */
     puts ("long long tests not run. This is a known bug on this architecture.");
 #else
     args[0] = &ffi_type_sint64;
--- libffi/src/types.c.jj	Sun Aug  8 15:27:19 1999
+++ libffi/src/types.c	Fri Apr 14 09:24:37 2000
@@ -42,9 +42,17 @@ FFI_INTEGRAL_TYPEDEF(uint16, 2, 2, FFI_T
 FFI_INTEGRAL_TYPEDEF(sint16, 2, 2, FFI_TYPE_SINT16);
 FFI_INTEGRAL_TYPEDEF(uint32, 4, 4, FFI_TYPE_UINT32);
 FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32);
-FFI_INTEGRAL_TYPEDEF(pointer, 4, 4, FFI_TYPE_POINTER);
 FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT);
 
+#if defined ALPHA || defined SPARC64
+
+FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER);
+
+#else
+
+FFI_INTEGRAL_TYPEDEF(pointer, 4, 4, FFI_TYPE_POINTER);
+
+#endif
 
 #ifdef X86
 
@@ -87,7 +95,16 @@ FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, 
 #elif defined SPARC
 
 FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);
+
+#ifdef SPARC64
+
+FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE);
+
+#else
+
 FFI_INTEGRAL_TYPEDEF(longdouble, 16, 8, FFI_TYPE_LONGDOUBLE);
+
+#endif
 
 #else
 
--- libffi/configure.in.jj	Tue Apr  4 20:22:01 2000
+++ libffi/configure.in	Fri Apr 14 09:09:46 2000
@@ -50,6 +50,8 @@ i*86-*-solaris*) TARGET=X86; TARGETDIR=x
 i*86-*-beos*) TARGET=X86; TARGETDIR=x86;;
 sparc-sun-4*) TARGET=SPARC; TARGETDIR=sparc;;
 sparc-sun-*) TARGET=SPARC; TARGETDIR=sparc;;
+sparc-*-linux*) TARGET=SPARC; TARGETDIR=sparc;;
+sparc64-*-linux*) TARGET=SPARC; TARGETDIR=sparc;;
 alpha*-*-linux* | alpha*-*-osf*) TARGET=ALPHA; TARGETDIR=alpha;;
 ia64*-*-*) TARGET=IA64; TARGETDIR=ia64;;
 m68k-*-linux*) TARGET=M68K; TARGETDIR=m68k;;
--- libffi/configure.jj	Tue Apr  4 20:22:01 2000
+++ libffi/configure	Fri Apr 14 09:10:08 2000
@@ -1630,6 +1630,8 @@ i*86-*-solaris*) TARGET=X86; TARGETDIR=x
 i*86-*-beos*) TARGET=X86; TARGETDIR=x86;;
 sparc-sun-4*) TARGET=SPARC; TARGETDIR=sparc;;
 sparc-sun-*) TARGET=SPARC; TARGETDIR=sparc;;
+sparc-*-linux*) TARGET=SPARC; TARGETDIR=sparc;;
+sparc64-*-linux*) TARGET=SPARC; TARGETDIR=sparc;;
 alpha*-*-linux* | alpha*-*-osf*) TARGET=ALPHA; TARGETDIR=alpha;;
 ia64*-*-*) TARGET=IA64; TARGETDIR=ia64;;
 m68k-*-linux*) TARGET=M68K; TARGETDIR=m68k;;
--- libffi/Makefile.am.jj	Fri Mar  3 02:19:22 2000
+++ libffi/Makefile.am	Fri Apr 14 09:14:10 2000
@@ -4,7 +4,7 @@ AUTOMAKE_OPTIONS = cygnus
 
 EXTRA_DIST = LICENSE ChangeLog.v1 src/mips/ffi.c src/mips/n32.S \
 		src/mips/n32.s src/mips/o32.S src/mips/o32.s \
-		src/sparc/ffi.c src/sparc/v8.S \
+		src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S \
 		src/x86/ffi.c src/x86/sysv.S \
 		src/alpha/ffi.c src/alpha/osf.S \
 		src/m68k/ffi.c src/m68k/sysv.S \
@@ -40,7 +40,7 @@ ffitest_LDADD = libffi.la
 TARGET_SRC_MIPS_GCC = src/mips/ffi.c src/mips/o32.S src/mips/n32.S
 TARGET_SRC_MIPS_SGI = src/mips/ffi.c src/mips/o32.s src/mips/n32.s
 TARGET_SRC_X86 = src/x86/ffi.c src/x86/sysv.S
-TARGET_SRC_SPARC = src/sparc/ffi.c src/sparc/v8.S
+TARGET_SRC_SPARC = src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S
 TARGET_SRC_ALPHA = src/alpha/ffi.c src/alpha/osf.S
 TARGET_SRC_IA64 = src/ia64/ffi.c src/ia64/unix.S
 TARGET_SRC_M68K = src/m68k/ffi.c src/m68k/sysv.S
--- libffi/Makefile.in.jj	Tue Mar 21 02:03:02 2000
+++ libffi/Makefile.in	Fri Apr 14 09:13:55 2000
@@ -84,7 +84,7 @@ AUTOMAKE_OPTIONS = cygnus
 
 EXTRA_DIST = LICENSE ChangeLog.v1 src/mips/ffi.c src/mips/n32.S \
 		src/mips/n32.s src/mips/o32.S src/mips/o32.s \
-		src/sparc/ffi.c src/sparc/v8.S \
+		src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S \
 		src/x86/ffi.c src/x86/sysv.S \
 		src/alpha/ffi.c src/alpha/osf.S \
 		src/m68k/ffi.c src/m68k/sysv.S \
@@ -115,7 +115,7 @@ ffitest_LDADD = libffi.la
 TARGET_SRC_MIPS_GCC = src/mips/ffi.c src/mips/o32.S src/mips/n32.S
 TARGET_SRC_MIPS_SGI = src/mips/ffi.c src/mips/o32.s src/mips/n32.s
 TARGET_SRC_X86 = src/x86/ffi.c src/x86/sysv.S
-TARGET_SRC_SPARC = src/sparc/ffi.c src/sparc/v8.S
+TARGET_SRC_SPARC = src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S 
 TARGET_SRC_ALPHA = src/alpha/ffi.c src/alpha/osf.S
 TARGET_SRC_IA64 = src/ia64/ffi.c src/ia64/unix.S
 TARGET_SRC_M68K = src/m68k/ffi.c src/m68k/sysv.S
@@ -164,7 +164,7 @@ libffi_la_LIBADD = 
 @POWERPC_TRUE@am_libffi_la_OBJECTS =  debug.lo prep_cif.lo types.lo \
 @POWERPC_TRUE@raw_api.lo java_raw_api.lo ffi.lo sysv.lo
 @SPARC_TRUE@am_libffi_la_OBJECTS =  debug.lo prep_cif.lo types.lo \
-@SPARC_TRUE@raw_api.lo java_raw_api.lo ffi.lo v8.lo
+@SPARC_TRUE@raw_api.lo java_raw_api.lo ffi.lo v8.lo v9.lo
 @X86_TRUE@am_libffi_la_OBJECTS =  debug.lo prep_cif.lo types.lo \
 @X86_TRUE@raw_api.lo java_raw_api.lo ffi.lo sysv.lo
 libffi_la_OBJECTS =  $(am_libffi_la_OBJECTS)
@@ -179,7 +179,7 @@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM
 LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 CFLAGS = @CFLAGS@
 CCLD = $(CC)
-LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+LINK = $(LIBTOOL) --mode=link "$(CCLD)" $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
 DIST_SOURCES =  $(libffi_la_SOURCES) $(ffitest_SOURCES)
 DIST_COMMON =  README ./stamp-h.in ChangeLog Makefile.am Makefile.in \
 acconfig.h aclocal.m4 config.guess config.sub configure configure.in \
@@ -299,6 +299,7 @@ sysv.lo: src/arm/sysv.S
 o32.lo: src/mips/o32.S
 n32.lo: src/mips/n32.S
 v8.lo: src/sparc/v8.S
+v9.lo: src/sparc/v9.S
 
 libffi.la: $(libffi_la_OBJECTS) $(libffi_la_DEPENDENCIES)
 	$(LINK) -rpath $(toolexeclibdir) $(libffi_la_LDFLAGS) $(libffi_la_OBJECTS) $(libffi_la_LIBADD) $(LIBS)

	Jakub

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