]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR libffi/60073 (64-bit libffi.call/cls_double_va.c FAILs after recent modification)
authorEric Botcazou <ebotcazou@adacore.com>
Mon, 17 Feb 2014 12:00:04 +0000 (12:00 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 17 Feb 2014 12:00:04 +0000 (12:00 +0000)
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.

From-SVN: r207822

libffi/ChangeLog
libffi/src/sparc/ffi.c
libffi/src/sparc/ffitarget.h
libffi/src/sparc/v8.S
libffi/src/sparc/v9.S

index f4fe5178cfeee9ecdfe4af901bdd6a740381b468..80e94ed77ca1467a81f113ecea0c66da7101271b 100644 (file)
@@ -1,3 +1,24 @@
+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.
+
 2014-02-13  Eric Botcazou  <ebotcazou@adacore.com>
 
        PR libffi/60073
index a4ee84ec51471f1caa6244a580ee2f3dc4916fe0..77e3822065734de20f9fcd62ec9cf372ead614c8 100644 (file)
@@ -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
 /* 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, extended_cif *ecif)
   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_core(ffi_cif *cif)
       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_core(ffi_cif *cif)
     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_core(ffi_cif *cif)
 
     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_core(ffi_cif *cif)
   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, int off, char *ret, char *intg, char *fl
   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_cif *, unsigned,
                       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)(void), void *rvalue, void **avalue)
          /* 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)(void), void *rvalue, void **avalue)
              /* 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)(void), void *rvalue, void **avalue)
        }
 #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* closure,
 #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* closure,
   *((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* closure,
   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 *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 *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 *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 a1f5e494820f16584f7e6c390cdd10a950d3aa37..6489ac05fd4eef6008c9f57b8945a44b79b67e1c 100644 (file)
@@ -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 2c4eb60a0fb95b942b91ea451451cd5664cb2627..7ec6e1c119432ff06799406f1ff1bf4638b57dea 100644 (file)
@@ -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
index bf31a2b5110c518429614951a3054c1818af419a..2c97673e351ae5ddaeb517f54706c754c30f33e5 100644 (file)
@@ -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