/* -----------------------------------------------------------------------
   java_raw_api.c - Copyright (c) 1999  Red Hat, Inc.

   Cloned from raw_api.c

   Raw_api.c author: Kresten Krab Thorup <krab@gnu.org>
   Java_raw_api.c author: Hans-J. Boehm <hboehm@hpl.hp.com>

   $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.
   ----------------------------------------------------------------------- */

/* This defines a Java- and 64-bit specific variant of the raw API.	*/
/* It assumes that "raw" argument blocks look like Java stacks on a	*/
/* 64-bit machine.  Arguments that can be stored in a single stack	*/
/* stack slots (longs, doubles) occupy 128 bits, but only the first	*/
/* 64 bits are actually used.						*/

#include <ffi.h>
#include <ffi_common.h>
#include <stdlib.h>

#if !defined(NO_JAVA_RAW_API) && !defined(FFI_NO_RAW_API)

size_t
ffi_java_raw_size (ffi_cif *cif)
{
  size_t result = 0;
  int i;

  ffi_type **at = cif->arg_types;

  for (i = cif->nargs-1; i >= 0; i--, at++)
    {
      switch((*at) -> type) {
	case FFI_TYPE_UINT64:
	case FFI_TYPE_SINT64:
	case FFI_TYPE_DOUBLE:
	  result += 2 * FFI_SIZEOF_ARG;
	  break;
	case FFI_TYPE_STRUCT:
	  /* No structure parameters in Java.	*/
	  abort();
	default:
	  result += FFI_SIZEOF_ARG;
      }
    }

  return result;
}


void
ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)
{
  unsigned i;
  ffi_type **tp = cif->arg_types;

#if WORDS_BIGENDIAN

  for (i = 0; i < cif->nargs; i++, tp++, args++)
    {
      switch ((*tp)->type)
	{
	case FFI_TYPE_UINT8:
	case FFI_TYPE_SINT8:
	  *args = (void*) ((char*)(raw++) + 3);
	  break;

	case FFI_TYPE_UINT16:
	case FFI_TYPE_SINT16:
	  *args = (void*) ((char*)(raw++) + 2);
	  break;

#if FFI_SIZEOF_ARG == 8
	case FFI_TYPE_UINT64:
	case FFI_TYPE_SINT64:
	case FFI_TYPE_DOUBLE:
	  *args = (void *)raw;
	  raw += 2;
	  break;
#endif

	case FFI_TYPE_POINTER:
	  *args = (void*) &(raw++)->ptr;
	  break;

	default:
	  *args = raw;
	  raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
	}
    }

#else /* WORDS_BIGENDIAN */

#if !PDP

  /* then assume little endian */
  for (i = 0; i < cif->nargs; i++, tp++, args++)
    {
#if FFI_SIZEOF_ARG == 8
      switch((*tp)->type) {
	case FFI_TYPE_UINT64:
	case FFI_TYPE_SINT64:
	case FFI_TYPE_DOUBLE:
	  *args = (void*) raw;
	  raw += 2;
	  break;
	default:
	  *args = (void*) raw++;
      }
#else /* FFI_SIZEOF_ARG != 8 */
	*args = (void*) raw;
	raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*);
#endif /* FFI_SIZEOF_ARG == 8 */
    }

#else
#error "pdp endian not supported"
#endif /* ! PDP */

#endif /* WORDS_BIGENDIAN */
}

void
ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw)
{
  unsigned i;
  ffi_type **tp = cif->arg_types;

  for (i = 0; i < cif->nargs; i++, tp++, args++)
    {
      switch ((*tp)->type)
	{
	case FFI_TYPE_UINT8:
#if WORDS_BIGENDIAN
	  *(UINT32*)(raw++) = *(UINT8*) (*args);
#else
	  (raw++)->uint = *(UINT8*) (*args);
#endif
	  break;

	case FFI_TYPE_SINT8:
#if WORDS_BIGENDIAN
	  *(SINT32*)(raw++) = *(SINT8*) (*args);
#else
	  (raw++)->sint = *(SINT8*) (*args);
#endif
	  break;

	case FFI_TYPE_UINT16:
#if WORDS_BIGENDIAN
	  *(UINT32*)(raw++) = *(UINT16*) (*args);
#else
	  (raw++)->uint = *(UINT16*) (*args);
#endif
	  break;

	case FFI_TYPE_SINT16:
#if WORDS_BIGENDIAN
	  *(SINT32*)(raw++) = *(SINT16*) (*args);
#else
	  (raw++)->sint = *(SINT16*) (*args);
#endif
	  break;

	case FFI_TYPE_UINT32:
#if WORDS_BIGENDIAN
	  *(UINT32*)(raw++) = *(UINT32*) (*args);
#else
	  (raw++)->uint = *(UINT32*) (*args);
#endif
	  break;

	case FFI_TYPE_SINT32:
#if WORDS_BIGENDIAN
	  *(SINT32*)(raw++) = *(SINT32*) (*args);
#else
	  (raw++)->sint = *(SINT32*) (*args);
#endif
	  break;

	case FFI_TYPE_FLOAT:
	  (raw++)->flt = *(FLOAT32*) (*args);
	  break;

#if FFI_SIZEOF_ARG == 8
	case FFI_TYPE_UINT64:
	case FFI_TYPE_SINT64:
	case FFI_TYPE_DOUBLE:
	  raw->uint = *(UINT64*) (*args);
	  raw += 2;
	  break;
#endif

	case FFI_TYPE_POINTER:
	  (raw++)->ptr = **(void***) args;
	  break;

	default:
#if FFI_SIZEOF_ARG == 8
	  FFI_ASSERT(0);	/* Should have covered all cases */
#else
	  memcpy ((void*) raw->data, (void*)*args, (*tp)->size);
	  raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
#endif
	}
    }
}

#if !FFI_NATIVE_RAW_API

static void
ffi_java_rvalue_to_raw (ffi_cif *cif, void *rvalue)
{
#if WORDS_BIGENDIAN && FFI_SIZEOF_ARG == 8
  switch (cif->rtype->type)
    {
    case FFI_TYPE_UINT8:
    case FFI_TYPE_UINT16:
    case FFI_TYPE_UINT32:
      *(UINT64 *)rvalue <<= 32;
      break;

    case FFI_TYPE_SINT8:
    case FFI_TYPE_SINT16:
    case FFI_TYPE_SINT32:
    case FFI_TYPE_INT:
      *(SINT64 *)rvalue <<= 32;
      break;

    default:
      break;
    }
#endif
}

static void
ffi_java_raw_to_rvalue (ffi_cif *cif, void *rvalue)
{
#if WORDS_BIGENDIAN && FFI_SIZEOF_ARG == 8
  switch (cif->rtype->type)
    {
    case FFI_TYPE_UINT8:
    case FFI_TYPE_UINT16:
    case FFI_TYPE_UINT32:
      *(UINT64 *)rvalue >>= 32;
      break;

    case FFI_TYPE_SINT8:
    case FFI_TYPE_SINT16:
    case FFI_TYPE_SINT32:
    case FFI_TYPE_INT:
      *(SINT64 *)rvalue >>= 32;
      break;

    default:
      break;
    }
#endif
}

/* This is a generic definition of ffi_raw_call, to be used if the
 * native system does not provide a machine-specific implementation.
 * Having this, allows code to be written for the raw API, without
 * the need for system-specific code to handle input in that format;
 * these following couple of functions will handle the translation forth
 * and back automatically. */

void ffi_java_raw_call (ffi_cif *cif, void (*fn)(), void *rvalue, ffi_raw *raw)
{
  void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
  ffi_java_raw_to_ptrarray (cif, raw, avalue);
  ffi_call (cif, fn, rvalue, avalue);
  ffi_java_rvalue_to_raw (cif, rvalue);
}

#if FFI_CLOSURES		/* base system provides closures */

static void
ffi_java_translate_args (ffi_cif *cif, void *rvalue,
		    void **avalue, void *user_data)
{
  ffi_raw *raw = (ffi_raw*)alloca (ffi_java_raw_size (cif));
  ffi_raw_closure *cl = (ffi_raw_closure*)user_data;

  ffi_java_ptrarray_to_raw (cif, avalue, raw);
  (*cl->fun) (cif, rvalue, raw, cl->user_data);
  ffi_java_raw_to_rvalue (cif, rvalue);
}

/* Again, here is the generic version of ffi_prep_raw_closure, which
 * will install an intermediate "hub" for translation of arguments from
 * the pointer-array format, to the raw format */

ffi_status
ffi_prep_java_raw_closure (ffi_raw_closure* cl,
		      ffi_cif *cif,
		      void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
		      void *user_data)
{
  ffi_status status;

  status = ffi_prep_closure ((ffi_closure*) cl,
			     cif,
			     &ffi_java_translate_args,
			     (void*)cl);
  if (status == FFI_OK)
    {
      cl->fun       = fun;
      cl->user_data = user_data;
    }

  return status;
}

#endif /* FFI_CLOSURES */
#endif /* !FFI_NATIVE_RAW_API */
#endif /* !FFI_NO_RAW_API */
