m68k fixes
authorAnthony Green <green@moxielogic.com>
Mon, 23 Jan 2012 17:41:06 +0000 (12:41 -0500)
committerAnthony Green <green@moxielogic.com>
Mon, 23 Jan 2012 17:41:06 +0000 (12:41 -0500)
.pc/applied-patches
.pc/m68k-patches/.timestamp [new file with mode: 0644]
.pc/m68k-patches/src/m68k/ffi.c [new file with mode: 0644]
.pc/m68k-patches/src/m68k/sysv.S [new file with mode: 0644]
.pc/m68k-patches/testsuite/libffi.call/return_sc.c [new file with mode: 0644]
ChangeLog
patches/m68k-patches [new file with mode: 0644]
patches/series
src/m68k/ffi.c
src/m68k/sysv.S
testsuite/libffi.call/return_sc.c

index 840dbde..d8f6964 100644 (file)
@@ -36,3 +36,4 @@ interix-patch
 remove-debug-code
 powerpc-ffi-softfloat
 variadic
+m68k-patches
diff --git a/.pc/m68k-patches/.timestamp b/.pc/m68k-patches/.timestamp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/.pc/m68k-patches/src/m68k/ffi.c b/.pc/m68k-patches/src/m68k/ffi.c
new file mode 100644 (file)
index 0000000..0d4df1e
--- /dev/null
@@ -0,0 +1,288 @@
+/* -----------------------------------------------------------------------
+   ffi.c
+   
+   m68k Foreign Function Interface 
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#ifdef __rtems__
+void rtems_cache_flush_multiple_data_lines( const void *, size_t );
+#else
+#include <sys/syscall.h>
+#include <asm/cachectl.h>
+#endif
+
+void ffi_call_SYSV (extended_cif *,
+                   unsigned, unsigned,
+                   void *, void (*fn) ());
+void *ffi_prep_args (void *stack, extended_cif *ecif);
+void ffi_closure_SYSV (ffi_closure *);
+void ffi_closure_struct_SYSV (ffi_closure *);
+unsigned int ffi_closure_SYSV_inner (ffi_closure *closure,
+                                    void *resp, void *args);
+
+/* ffi_prep_args is called by the assembly routine once stack space has
+   been allocated for the function's arguments.  */
+
+void *
+ffi_prep_args (void *stack, extended_cif *ecif)
+{
+  unsigned int i;
+  void **p_argv;
+  char *argp;
+  ffi_type **p_arg;
+  void *struct_value_ptr;
+
+  argp = stack;
+
+  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT
+      && !ecif->cif->flags)
+    struct_value_ptr = ecif->rvalue;
+  else
+    struct_value_ptr = NULL;
+
+  p_argv = ecif->avalue;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+       i != 0;
+       i--, p_arg++)
+    {
+      size_t z;
+
+      z = (*p_arg)->size;
+      if (z < sizeof (int))
+       {
+         switch ((*p_arg)->type)
+           {
+           case FFI_TYPE_SINT8:
+             *(signed int *) argp = (signed int) *(SINT8 *) *p_argv;
+             break;
+
+           case FFI_TYPE_UINT8:
+             *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv;
+             break;
+
+           case FFI_TYPE_SINT16:
+             *(signed int *) argp = (signed int) *(SINT16 *) *p_argv;
+             break;
+
+           case FFI_TYPE_UINT16:
+             *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv;
+             break;
+
+           case FFI_TYPE_STRUCT:
+             memcpy (argp + sizeof (int) - z, *p_argv, z);
+             break;
+
+           default:
+             FFI_ASSERT (0);
+           }
+         z = sizeof (int);
+       }
+      else
+       {
+         memcpy (argp, *p_argv, z);
+
+         /* Align if necessary.  */
+         if ((sizeof(int) - 1) & z)
+           z = ALIGN(z, sizeof(int));
+       }
+
+      p_argv++;
+      argp += z;
+    }
+
+  return struct_value_ptr;
+}
+
+#define CIF_FLAGS_INT          1
+#define CIF_FLAGS_DINT         2
+#define CIF_FLAGS_FLOAT                4
+#define CIF_FLAGS_DOUBLE       8
+#define CIF_FLAGS_LDOUBLE      16
+#define CIF_FLAGS_POINTER      32
+#define CIF_FLAGS_STRUCT1      64
+#define CIF_FLAGS_STRUCT2      128
+
+/* Perform machine dependent cif processing */
+ffi_status
+ffi_prep_cif_machdep (ffi_cif *cif)
+{
+  /* Set the return type flag */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_VOID:
+      cif->flags = 0;
+      break;
+
+    case FFI_TYPE_STRUCT:
+      switch (cif->rtype->size)
+       {
+       case 1:
+         cif->flags = CIF_FLAGS_STRUCT1;
+         break;
+       case 2:
+         cif->flags = CIF_FLAGS_STRUCT2;
+         break;
+       case 4:
+         cif->flags = CIF_FLAGS_INT;
+         break;
+       case 8:
+         cif->flags = CIF_FLAGS_DINT;
+         break;
+       default:
+         cif->flags = 0;
+         break;
+       }
+      break;
+
+    case FFI_TYPE_FLOAT:
+      cif->flags = CIF_FLAGS_FLOAT;
+      break;
+
+    case FFI_TYPE_DOUBLE:
+      cif->flags = CIF_FLAGS_DOUBLE;
+      break;
+
+#if (FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE)
+    case FFI_TYPE_LONGDOUBLE:
+      cif->flags = CIF_FLAGS_LDOUBLE;
+      break;
+#endif
+
+    case FFI_TYPE_POINTER:
+      cif->flags = CIF_FLAGS_POINTER;
+      break;
+
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_UINT64:
+      cif->flags = CIF_FLAGS_DINT;
+      break;
+
+    default:
+      cif->flags = CIF_FLAGS_INT;
+      break;
+    }
+
+  return FFI_OK;
+}
+
+void
+ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue)
+{
+  extended_cif ecif;
+
+  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
+      && cif->rtype->size > 8)
+    ecif.rvalue = alloca (cif->rtype->size);
+  else
+    ecif.rvalue = rvalue;
+
+  switch (cif->abi)
+    {
+    case FFI_SYSV:
+      ffi_call_SYSV (&ecif, cif->bytes, cif->flags,
+                    ecif.rvalue, fn);
+      break;
+
+    default:
+      FFI_ASSERT (0);
+      break;
+    }
+}
+
+static void
+ffi_prep_incoming_args_SYSV (char *stack, void **avalue, ffi_cif *cif)
+{
+  unsigned int i;
+  void **p_argv;
+  char *argp;
+  ffi_type **p_arg;
+
+  argp = stack;
+  p_argv = avalue;
+
+  for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
+    {
+      size_t z;
+
+      z = (*p_arg)->size;
+      if (z <= 4)
+       {
+         *p_argv = (void *) (argp + 4 - z);
+
+         z = 4;
+       }
+      else
+       {
+         *p_argv = (void *) argp;
+
+         /* Align if necessary */
+         if ((sizeof(int) - 1) & z)
+           z = ALIGN(z, sizeof(int));
+       }
+
+      p_argv++;
+      argp += z;
+    }
+}
+
+unsigned int
+ffi_closure_SYSV_inner (ffi_closure *closure, void *resp, void *args)
+{
+  ffi_cif *cif;
+  void **arg_area;
+
+  cif = closure->cif;
+  arg_area = (void**) alloca (cif->nargs * sizeof (void *));
+
+  ffi_prep_incoming_args_SYSV(args, arg_area, cif);
+
+  (closure->fun) (cif, resp, arg_area, closure->user_data);
+
+  return cif->flags;
+}
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure* closure,
+                     ffi_cif* cif,
+                     void (*fun)(ffi_cif*,void*,void**,void*),
+                     void *user_data,
+                     void *codeloc)
+{
+  FFI_ASSERT (cif->abi == FFI_SYSV);
+
+  *(unsigned short *)closure->tramp = 0x207c;
+  *(void **)(closure->tramp + 2) = codeloc;
+  *(unsigned short *)(closure->tramp + 6) = 0x4ef9;
+  if (cif->rtype->type == FFI_TYPE_STRUCT
+      && !cif->flags)
+    *(void **)(closure->tramp + 8) = ffi_closure_struct_SYSV;
+  else
+    *(void **)(closure->tramp + 8) = ffi_closure_SYSV;
+
+#ifdef __rtems__
+  rtems_cache_flush_multiple_data_lines( codeloc, FFI_TRAMPOLINE_SIZE );
+#else
+  syscall(SYS_cacheflush, codeloc, FLUSH_SCOPE_LINE,
+         FLUSH_CACHE_BOTH, FFI_TRAMPOLINE_SIZE);
+#endif
+
+  closure->cif  = cif;
+  closure->user_data = user_data;
+  closure->fun  = fun;
+
+  return FFI_OK;
+}
+
diff --git a/.pc/m68k-patches/src/m68k/sysv.S b/.pc/m68k-patches/src/m68k/sysv.S
new file mode 100644 (file)
index 0000000..c782f51
--- /dev/null
@@ -0,0 +1,270 @@
+/* -----------------------------------------------------------------------
+       
+   sysv.S - Copyright (c) 1998 Andreas Schwab
+           Copyright (c) 2008 Red Hat, Inc. 
+   
+   m68k Foreign Function Interface 
+
+   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 THE AUTHORS OR COPYRIGHT
+   HOLDERS 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 <fficonfig.h>
+#include <ffi.h>
+
+#ifdef HAVE_AS_CFI_PSEUDO_OP
+#define CFI_STARTPROC()                .cfi_startproc
+#define CFI_OFFSET(reg,off)    .cfi_offset     reg,off
+#define CFI_DEF_CFA(reg,off)   .cfi_def_cfa    reg,off
+#define CFI_ENDPROC()          .cfi_endproc
+#else
+#define CFI_STARTPROC()
+#define CFI_OFFSET(reg,off)
+#define CFI_DEF_CFA(reg,off)
+#define CFI_ENDPROC()
+#endif
+
+       .text
+
+       .globl  ffi_call_SYSV
+       .type   ffi_call_SYSV,@function
+       .align  4
+
+ffi_call_SYSV:
+       CFI_STARTPROC()
+       link    %fp,#0
+       CFI_OFFSET(14,-8)
+       CFI_DEF_CFA(14,8)
+       move.l  %d2,-(%sp)
+       CFI_OFFSET(2,-12)
+
+       | Make room for all of the new args.
+       sub.l   12(%fp),%sp
+
+       | Call ffi_prep_args
+       move.l  8(%fp),-(%sp)
+       pea     4(%sp)
+#if !defined __PIC__
+       jsr     ffi_prep_args
+#else
+       bsr.l   ffi_prep_args@PLTPC
+#endif
+       addq.l  #8,%sp  
+
+       | Pass pointer to struct value, if any
+       move.l  %a0,%a1
+
+       | Call the function
+       move.l  24(%fp),%a0
+       jsr     (%a0)
+
+       | Remove the space we pushed for the args
+       add.l   12(%fp),%sp
+
+       | Load the pointer to storage for the return value
+       move.l  20(%fp),%a1
+
+       | Load the return type code 
+       move.l  16(%fp),%d2
+
+       | If the return value pointer is NULL, assume no return value.
+       | NOTE: On the mc68000, tst on an address register is not supported.
+#if defined(__mc68000__) && !defined(__mcoldfire__)
+       cmp.w   #0, %a1
+#else
+       tst.l   %a1
+#endif
+       jbeq    noretval
+
+       btst    #0,%d2
+       jbeq    retlongint
+       move.l  %d0,(%a1)
+       jbra    epilogue
+
+retlongint:
+       btst    #1,%d2
+       jbeq    retfloat
+       move.l  %d0,(%a1)
+       move.l  %d1,4(%a1)
+       jbra    epilogue
+
+retfloat:
+       btst    #2,%d2
+       jbeq    retdouble
+#if defined(__MC68881__)
+       fmove.s %fp0,(%a1)
+#else
+       move.l  %d0,(%a1)
+#endif
+       jbra    epilogue
+
+retdouble:
+       btst    #3,%d2
+       jbeq    retlongdouble
+#if defined(__MC68881__)
+       fmove.d %fp0,(%a1)
+#else
+       move.l  %d0,(%a1)+
+       move.l  %d1,(%a1)
+#endif
+       jbra    epilogue
+
+retlongdouble:
+       btst    #4,%d2
+       jbeq    retpointer
+#if defined(__MC68881__)
+       fmove.x %fp0,(%a1)
+#else
+       move.l  %d0,(%a1)+
+       move.l  %d1,(%a1)+
+       move.l  %d2,(%a1)
+#endif
+       jbra    epilogue
+
+retpointer:
+       btst    #5,%d2
+       jbeq    retstruct1
+       move.l  %a0,(%a1)
+       jbra    epilogue
+
+retstruct1:
+       btst    #6,%d2
+       jbeq    retstruct2
+       move.b  %d0,(%a1)
+       jbra    epilogue
+
+retstruct2:
+       btst    #7,%d2
+       jbeq    noretval
+       move.w  %d0,(%a1)
+
+noretval:
+epilogue:
+       move.l  (%sp)+,%d2
+       unlk    %fp
+       rts
+       CFI_ENDPROC()
+       .size   ffi_call_SYSV,.-ffi_call_SYSV
+
+       .globl  ffi_closure_SYSV
+       .type   ffi_closure_SYSV, @function
+       .align  4
+
+ffi_closure_SYSV:
+       CFI_STARTPROC()
+       link    %fp,#-12
+       CFI_OFFSET(14,-8)
+       CFI_DEF_CFA(14,8)
+       move.l  %sp,-12(%fp)
+       pea     8(%fp)
+       pea     -12(%fp)
+       move.l  %a0,-(%sp)
+#if !defined __PIC__
+       jsr     ffi_closure_SYSV_inner
+#else
+       bsr.l   ffi_closure_SYSV_inner@PLTPC
+#endif
+
+       lsr.l   #1,%d0
+       jne     1f
+       jcc     .Lcls_epilogue
+       move.l  -12(%fp),%d0
+.Lcls_epilogue:
+       unlk    %fp
+       rts
+1:
+       lea     -12(%fp),%a0
+       lsr.l   #2,%d0
+       jne     1f
+       jcs     .Lcls_ret_float
+       move.l  (%a0)+,%d0
+       move.l  (%a0),%d1
+       jra     .Lcls_epilogue
+.Lcls_ret_float:
+#if defined(__MC68881__)
+       fmove.s (%a0),%fp0
+#else
+       move.l  (%a0),%d0
+#endif
+       jra     .Lcls_epilogue
+1:
+       lsr.l   #2,%d0
+       jne     1f
+       jcs     .Lcls_ret_ldouble
+#if defined(__MC68881__)
+       fmove.d (%a0),%fp0
+#else
+       move.l  (%a0)+,%d0
+       move.l  (%a0),%d1
+#endif
+       jra     .Lcls_epilogue
+.Lcls_ret_ldouble:
+#if defined(__MC68881__)
+       fmove.x (%a0),%fp0
+#else
+       move.l  (%a0)+,%d0
+       move.l  (%a0)+,%d1
+       move.l  (%a0),%d2
+#endif
+       jra     .Lcls_epilogue
+1:
+       lsr.l   #2,%d0
+       jne     .Lcls_ret_struct2
+       jcs     .Lcls_ret_struct1
+       move.l  (%a0),%a0
+       move.l  %a0,%d0
+       jra     .Lcls_epilogue
+.Lcls_ret_struct1:
+       move.b  (%a0),%d0
+       jra     .Lcls_epilogue
+.Lcls_ret_struct2:
+       move.w  (%a0),%d0
+       jra     .Lcls_epilogue
+       CFI_ENDPROC()
+
+       .size   ffi_closure_SYSV,.-ffi_closure_SYSV
+
+       .globl  ffi_closure_struct_SYSV
+       .type   ffi_closure_struct_SYSV, @function
+       .align  4
+
+ffi_closure_struct_SYSV:
+       CFI_STARTPROC()
+       link    %fp,#0
+       CFI_OFFSET(14,-8)
+       CFI_DEF_CFA(14,8)
+       move.l  %sp,-12(%fp)
+       pea     8(%fp)
+       move.l  %a1,-(%sp)
+       move.l  %a0,-(%sp)
+#if !defined __PIC__
+       jsr     ffi_closure_SYSV_inner
+#else
+       bsr.l   ffi_closure_SYSV_inner@PLTPC
+#endif
+       unlk    %fp
+       rts
+       CFI_ENDPROC()
+       .size   ffi_closure_struct_SYSV,.-ffi_closure_struct_SYSV
+
+#if defined __ELF__ && defined __linux__
+       .section        .note.GNU-stack,"",@progbits
+#endif
diff --git a/.pc/m68k-patches/testsuite/libffi.call/return_sc.c b/.pc/m68k-patches/testsuite/libffi.call/return_sc.c
new file mode 100644 (file)
index 0000000..19608ee
--- /dev/null
@@ -0,0 +1,36 @@
+/* Area:       ffi_call
+   Purpose:    Check return value signed char.
+   Limitations:        none.
+   PR:         none.
+   Originator: From the original ffitest.c  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static signed char return_sc(signed char sc)
+{
+  return sc;
+}
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  ffi_arg rint;
+  signed char sc;
+
+  args[0] = &ffi_type_schar;
+  values[0] = &sc;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+                    &ffi_type_schar, args) == FFI_OK);
+
+  for (sc = (signed char) -127;
+       sc < (signed char) 127; sc++)
+    {
+      ffi_call(&cif, FFI_FN(return_sc), &rint, values);
+      CHECK(rint == (ffi_arg) sc);
+    }
+  exit(0);
+}
index f8e66eb..64d5b20 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2012-01-23  Alan Hourihane <alanh@fairlite.co.uk>
+
+       * src/m68k/ffi.c (ffi_prep_closure_loc): Fix ABI check.
+       * src/m68k/sysv.S: Support 68881.
+       * testsuite/libffi.call/return_sc.c (main): Fix test check.
+
 2012-01-19  Jakub Jelinek  <jakub@redhat.com>
 
        PR rtl-optimization/48496
diff --git a/patches/m68k-patches b/patches/m68k-patches
new file mode 100644 (file)
index 0000000..f756261
--- /dev/null
@@ -0,0 +1,85 @@
+Index: libffi/src/m68k/ffi.c
+===================================================================
+--- libffi.orig/src/m68k/ffi.c
++++ libffi/src/m68k/ffi.c
+@@ -261,7 +261,8 @@ ffi_prep_closure_loc (ffi_closure* closu
+                     void *user_data,
+                     void *codeloc)
+ {
+-  FFI_ASSERT (cif->abi == FFI_SYSV);
++  if (cif->abi != FFI_SYSV)
++    return FFI_BAD_ABI;
+   *(unsigned short *)closure->tramp = 0x207c;
+   *(void **)(closure->tramp + 2) = codeloc;
+Index: libffi/src/m68k/sysv.S
+===================================================================
+--- libffi.orig/src/m68k/sysv.S
++++ libffi/src/m68k/sysv.S
+@@ -109,7 +109,7 @@ retlongint:
+ retfloat:
+       btst    #2,%d2
+       jbeq    retdouble
+-#if defined(__MC68881__)
++#if defined(__MC68881__) || defined(__HAVE_68881__)
+       fmove.s %fp0,(%a1)
+ #else
+       move.l  %d0,(%a1)
+@@ -119,7 +119,7 @@ retfloat:
+ retdouble:
+       btst    #3,%d2
+       jbeq    retlongdouble
+-#if defined(__MC68881__)
++#if defined(__MC68881__) || defined(__HAVE_68881__)
+       fmove.d %fp0,(%a1)
+ #else
+       move.l  %d0,(%a1)+
+@@ -130,7 +130,7 @@ retdouble:
+ retlongdouble:
+       btst    #4,%d2
+       jbeq    retpointer
+-#if defined(__MC68881__)
++#if defined(__MC68881__) || defined(__HAVE_68881__)
+       fmove.x %fp0,(%a1)
+ #else
+       move.l  %d0,(%a1)+
+@@ -199,7 +199,7 @@ ffi_closure_SYSV:
+       move.l  (%a0),%d1
+       jra     .Lcls_epilogue
+ .Lcls_ret_float:
+-#if defined(__MC68881__)
++#if defined(__MC68881__) || defined(__HAVE_68881__)
+       fmove.s (%a0),%fp0
+ #else
+       move.l  (%a0),%d0
+@@ -209,7 +209,7 @@ ffi_closure_SYSV:
+       lsr.l   #2,%d0
+       jne     1f
+       jcs     .Lcls_ret_ldouble
+-#if defined(__MC68881__)
++#if defined(__MC68881__) || defined(__HAVE_68881__)
+       fmove.d (%a0),%fp0
+ #else
+       move.l  (%a0)+,%d0
+@@ -217,7 +217,7 @@ ffi_closure_SYSV:
+ #endif
+       jra     .Lcls_epilogue
+ .Lcls_ret_ldouble:
+-#if defined(__MC68881__)
++#if defined(__MC68881__) || defined(__HAVE_68881__)
+       fmove.x (%a0),%fp0
+ #else
+       move.l  (%a0)+,%d0
+Index: libffi/testsuite/libffi.call/return_sc.c
+===================================================================
+--- libffi.orig/testsuite/libffi.call/return_sc.c
++++ libffi/testsuite/libffi.call/return_sc.c
+@@ -30,7 +30,7 @@ int main (void)
+        sc < (signed char) 127; sc++)
+     {
+       ffi_call(&cif, FFI_FN(return_sc), &rint, values);
+-      CHECK(rint == (ffi_arg) sc);
++      CHECK((signed char)rint == sc);
+     }
+   exit(0);
+ }
index ee9013b..95c1ec9 100644 (file)
@@ -37,3 +37,4 @@ interix-patch
 remove-debug-code
 powerpc-ffi-softfloat
 variadic
+m68k-patches
index 0d4df1e..d95c72b 100644 (file)
@@ -261,7 +261,8 @@ ffi_prep_closure_loc (ffi_closure* closure,
                      void *user_data,
                      void *codeloc)
 {
-  FFI_ASSERT (cif->abi == FFI_SYSV);
+  if (cif->abi != FFI_SYSV)
+    return FFI_BAD_ABI;
 
   *(unsigned short *)closure->tramp = 0x207c;
   *(void **)(closure->tramp + 2) = codeloc;
index c782f51..6f17801 100644 (file)
@@ -109,7 +109,7 @@ retlongint:
 retfloat:
        btst    #2,%d2
        jbeq    retdouble
-#if defined(__MC68881__)
+#if defined(__MC68881__) || defined(__HAVE_68881__)
        fmove.s %fp0,(%a1)
 #else
        move.l  %d0,(%a1)
@@ -119,7 +119,7 @@ retfloat:
 retdouble:
        btst    #3,%d2
        jbeq    retlongdouble
-#if defined(__MC68881__)
+#if defined(__MC68881__) || defined(__HAVE_68881__)
        fmove.d %fp0,(%a1)
 #else
        move.l  %d0,(%a1)+
@@ -130,7 +130,7 @@ retdouble:
 retlongdouble:
        btst    #4,%d2
        jbeq    retpointer
-#if defined(__MC68881__)
+#if defined(__MC68881__) || defined(__HAVE_68881__)
        fmove.x %fp0,(%a1)
 #else
        move.l  %d0,(%a1)+
@@ -199,7 +199,7 @@ ffi_closure_SYSV:
        move.l  (%a0),%d1
        jra     .Lcls_epilogue
 .Lcls_ret_float:
-#if defined(__MC68881__)
+#if defined(__MC68881__) || defined(__HAVE_68881__)
        fmove.s (%a0),%fp0
 #else
        move.l  (%a0),%d0
@@ -209,7 +209,7 @@ ffi_closure_SYSV:
        lsr.l   #2,%d0
        jne     1f
        jcs     .Lcls_ret_ldouble
-#if defined(__MC68881__)
+#if defined(__MC68881__) || defined(__HAVE_68881__)
        fmove.d (%a0),%fp0
 #else
        move.l  (%a0)+,%d0
@@ -217,7 +217,7 @@ ffi_closure_SYSV:
 #endif
        jra     .Lcls_epilogue
 .Lcls_ret_ldouble:
-#if defined(__MC68881__)
+#if defined(__MC68881__) || defined(__HAVE_68881__)
        fmove.x (%a0),%fp0
 #else
        move.l  (%a0)+,%d0
index 19608ee..a36cf3e 100644 (file)
@@ -30,7 +30,7 @@ int main (void)
        sc < (signed char) 127; sc++)
     {
       ffi_call(&cif, FFI_FN(return_sc), &rint, values);
-      CHECK(rint == (ffi_arg) sc);
+      CHECK((signed char)rint == sc);
     }
   exit(0);
 }