Moved m68k files
authorgreen <green>
Sun, 22 Apr 2001 18:13:22 +0000 (18:13 +0000)
committergreen <green>
Sun, 22 Apr 2001 18:13:22 +0000 (18:13 +0000)
libffi/m68k/ffi.c [new file with mode: 0644]
libffi/m68k/sysv.S [new file with mode: 0644]

diff --git a/libffi/m68k/ffi.c b/libffi/m68k/ffi.c
new file mode 100644 (file)
index 0000000..c5d9507
--- /dev/null
@@ -0,0 +1,184 @@
+/* -----------------------------------------------------------------------
+   ffi.c
+   
+   m68k Foreign Function Interface 
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space has
+   been allocated for the function's arguments.  */
+
+static void *
+ffi_prep_args (void *stack, extended_cif *ecif)
+{
+  unsigned int i;
+  int tmp;
+  unsigned int avn;
+  void **p_argv;
+  char *argp;
+  ffi_type **p_arg;
+  void *struct_value_ptr;
+
+  tmp = 0;
+  argp = stack;
+
+  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT
+      && ecif->cif->rtype->size > 8)
+    struct_value_ptr = ecif->rvalue;
+  else
+    struct_value_ptr = NULL;
+
+  avn = ecif->cif->nargs;
+  p_argv = ecif->avalue;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+       i != 0 && avn != 0;
+       i--, p_arg++)
+    {
+      size_t z;
+
+      /* Align if necessary.  */
+      if (((*p_arg)->alignment - 1) & (unsigned) argp)
+       argp = (char *) ALIGN (argp, (*p_arg)->alignment);
+
+      if (avn != 0) 
+       {
+         avn--;
+         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);
+         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_STRUCT       64
+
+/* 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:
+      if (cif->rtype->size > 4 && cif->rtype->size <= 8)
+       cif->flags = CIF_FLAGS_DINT;
+      else if (cif->rtype->size <= 4)
+       cif->flags = CIF_FLAGS_STRUCT;
+      else
+       cif->flags = 0;
+      break;
+
+    case FFI_TYPE_FLOAT:
+      cif->flags = CIF_FLAGS_FLOAT;
+      break;
+
+    case FFI_TYPE_DOUBLE:
+      cif->flags = CIF_FLAGS_DOUBLE;
+      break;
+
+    case FFI_TYPE_LONGDOUBLE:
+      cif->flags = CIF_FLAGS_LDOUBLE;
+      break;
+
+    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;
+}
+
+extern void ffi_call_SYSV (void *(*) (void *, extended_cif *), 
+                          extended_cif *, 
+                          unsigned, unsigned, unsigned,
+                          void *, void (*fn) ());
+
+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 (ffi_prep_args, &ecif, cif->bytes, 
+                    cif->flags, cif->rtype->size * 8,
+                    ecif.rvalue, fn);
+      break;
+
+    default:
+      FFI_ASSERT (0);
+      break;
+    }
+}
diff --git a/libffi/m68k/sysv.S b/libffi/m68k/sysv.S
new file mode 100644 (file)
index 0000000..a925d99
--- /dev/null
@@ -0,0 +1,96 @@
+/* -----------------------------------------------------------------------
+   sysv.S
+   
+   m68k Foreign Function Interface 
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM     
+#include <ffi.h>
+
+       .text
+
+       .globl  ffi_call_SYSV
+       .type   ffi_call_SYSV,@function
+
+ffi_call_SYSV:
+       link    %fp,#0
+       move.l  %d2,-(%sp)
+
+       | Make room for all of the new args.
+       sub.l   16(%fp),%sp
+
+       | Call ffi_prep_args
+       move.l  12(%fp),-(%sp)
+       pea     4(%sp)
+       move.l  8(%fp),%a0
+       jsr     (%a0)
+       addq.l  #8,%sp  
+
+       | Pass pointer to struct value, if any
+       move.l  %a0,%a1
+
+       | Call the function
+       move.l  32(%fp),%a0
+       jsr     (%a0)
+
+       | Remove the space we pushed for the args
+       add.l   16(%fp),%sp
+
+       | Load the pointer to storage for the return value
+       move.l  28(%fp),%a1
+
+       | Load the return type code 
+       move.l  20(%fp),%d2
+
+       | If the return value pointer is NULL, assume no return value.
+       tst.l   %a1
+       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
+       fmove.s %fp0,(%a1)
+       jbra    epilogue
+
+retdouble:
+       btst    #3,%d2
+       jbeq    retlongdouble
+       fmove.d %fp0,(%a1)
+       jbra    epilogue
+
+retlongdouble:
+       btst    #4,%d2
+       jbeq    retpointer
+       fmove.x %fp0,(%a1)
+       jbra    epilogue
+
+retpointer:
+       btst    #5,%d2
+       jbeq    retstruct
+       move.l  %a0,(%a1)
+       jbra    epilogue
+
+retstruct:
+       btst    #6,%d2
+       jbeq    noretval
+       move.l  24(%fp),%d2
+       bfins   %d0,(%a1){#0,%d2}
+
+noretval:
+epilogue:
+       move.l  (%sp)+,%d2
+       unlk    %a6
+       rts
+       .size   ffi_call_SYSV,.-ffi_call_SYSV