/* -----------------------------------------------------------------------
   ffi.c - Copyright (c) 2015 Michael Knyszek <mknyszek@berkeley.edu>
                         2015 Andrew Waterman <waterman@cs.berkeley.edu>
                         2018 Stef O'Rear <sorear2@gmail.com>
   Based on MIPS N32/64 port

   RISC-V 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.
   ----------------------------------------------------------------------- */

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

#include <stdlib.h>
#include <stdint.h>

#if __riscv_float_abi_double
#define ABI_FLEN 64
#define ABI_FLOAT double
#elif __riscv_float_abi_single
#define ABI_FLEN 32
#define ABI_FLOAT float
#endif

#define NARGREG 8
#define STKALIGN 16
#define MAXCOPYARG (2 * sizeof(double))

typedef struct call_context
{
#if ABI_FLEN
    ABI_FLOAT fa[8];
#endif
    size_t a[8];
    /* used by the assembly code to in-place construct its own stack frame */
    char frame[16];
} call_context;

typedef struct call_builder
{
    call_context *aregs;
    int used_integer;
    int used_float;
    size_t *used_stack;
} call_builder;

/* integer (not pointer) less than ABI XLEN */
/* FFI_TYPE_INT does not appear to be used */
#if __SIZEOF_POINTER__ == 8
#define IS_INT(type) ((type) >= FFI_TYPE_UINT8 && (type) <= FFI_TYPE_SINT64)
#else
#define IS_INT(type) ((type) >= FFI_TYPE_UINT8 && (type) <= FFI_TYPE_SINT32)
#endif

#if ABI_FLEN
typedef struct {
    char as_elements, type1, offset2, type2;
} float_struct_info;

#if ABI_FLEN >= 64
#define IS_FLOAT(type) ((type) >= FFI_TYPE_FLOAT && (type) <= FFI_TYPE_DOUBLE)
#else
#define IS_FLOAT(type) ((type) == FFI_TYPE_FLOAT)
#endif

static ffi_type **flatten_struct(ffi_type *in, ffi_type **out, ffi_type **out_end) {
    int i;
    if (out == out_end) return out;
    if (in->type != FFI_TYPE_STRUCT) {
        *(out++) = in;
    } else {
        for (i = 0; in->elements[i]; i++)
            out = flatten_struct(in->elements[i], out, out_end);
    }
    return out;
}

/* Structs with at most two fields after flattening, one of which is of
   floating point type, are passed in multiple registers if sufficient
   registers are available. */
static float_struct_info struct_passed_as_elements(call_builder *cb, ffi_type *top) {
    float_struct_info ret = {0, 0, 0, 0};
    ffi_type *fields[3];
    int num_floats, num_ints;
    int num_fields = flatten_struct(top, fields, fields + 3) - fields;

    if (num_fields == 1) {
        if (IS_FLOAT(fields[0]->type)) {
            ret.as_elements = 1;
            ret.type1 = fields[0]->type;
        }
    } else if (num_fields == 2) {
        num_floats = IS_FLOAT(fields[0]->type) + IS_FLOAT(fields[1]->type);
        num_ints = IS_INT(fields[0]->type) + IS_INT(fields[1]->type);
        if (num_floats == 0 || num_floats + num_ints != 2)
            return ret;
        if (cb->used_float + num_floats > NARGREG || cb->used_integer + (2 - num_floats) > NARGREG)
            return ret;
        if (!IS_FLOAT(fields[0]->type) && !IS_FLOAT(fields[1]->type))
            return ret;

        ret.type1 = fields[0]->type;
        ret.type2 = fields[1]->type;
        ret.offset2 = FFI_ALIGN(fields[0]->size, fields[1]->alignment);
        ret.as_elements = 1;
    }

    return ret;
}
#endif

/* allocates a single register, float register, or XLEN-sized stack slot to a datum */
static void marshal_atom(call_builder *cb, int type, void *data) {
    size_t value = 0;
    switch (type) {
        case FFI_TYPE_UINT8: value = *(uint8_t *)data; break;
        case FFI_TYPE_SINT8: value = *(int8_t *)data; break;
        case FFI_TYPE_UINT16: value = *(uint16_t *)data; break;
        case FFI_TYPE_SINT16: value = *(int16_t *)data; break;
        /* 32-bit quantities are always sign-extended in the ABI */
        case FFI_TYPE_UINT32: value = *(int32_t *)data; break;
        case FFI_TYPE_SINT32: value = *(int32_t *)data; break;
#if __SIZEOF_POINTER__ == 8
        case FFI_TYPE_UINT64: value = *(uint64_t *)data; break;
        case FFI_TYPE_SINT64: value = *(int64_t *)data; break;
#endif
        case FFI_TYPE_POINTER: value = *(size_t *)data; break;

        /* float values may be recoded in an implementation-defined way
           by hardware conforming to 2.1 or earlier, so use asm to
           reinterpret floats as doubles */
#if ABI_FLEN >= 32
        case FFI_TYPE_FLOAT:
            asm("" : "=f"(cb->aregs->fa[cb->used_float++]) : "0"(*(float *)data));
            return;
#endif
#if ABI_FLEN >= 64
        case FFI_TYPE_DOUBLE:
            asm("" : "=f"(cb->aregs->fa[cb->used_float++]) : "0"(*(double *)data));
            return;
#endif
        default: FFI_ASSERT(0); break;
    }

    if (cb->used_integer == NARGREG) {
        *cb->used_stack++ = value;
    } else {
        cb->aregs->a[cb->used_integer++] = value;
    }
}

static void unmarshal_atom(call_builder *cb, int type, void *data) {
    size_t value;
    switch (type) {
#if ABI_FLEN >= 32
        case FFI_TYPE_FLOAT:
            asm("" : "=f"(*(float *)data) : "0"(cb->aregs->fa[cb->used_float++]));
            return;
#endif
#if ABI_FLEN >= 64
        case FFI_TYPE_DOUBLE:
            asm("" : "=f"(*(double *)data) : "0"(cb->aregs->fa[cb->used_float++]));
            return;
#endif
    }

    if (cb->used_integer == NARGREG) {
        value = *cb->used_stack++;
    } else {
        value = cb->aregs->a[cb->used_integer++];
    }

    switch (type) {
        case FFI_TYPE_UINT8: *(uint8_t *)data = value; break;
        case FFI_TYPE_SINT8: *(uint8_t *)data = value; break;
        case FFI_TYPE_UINT16: *(uint16_t *)data = value; break;
        case FFI_TYPE_SINT16: *(uint16_t *)data = value; break;
        case FFI_TYPE_UINT32: *(uint32_t *)data = value; break;
        case FFI_TYPE_SINT32: *(uint32_t *)data = value; break;
#if __SIZEOF_POINTER__ == 8
        case FFI_TYPE_UINT64: *(uint64_t *)data = value; break;
        case FFI_TYPE_SINT64: *(uint64_t *)data = value; break;
#endif
        case FFI_TYPE_POINTER: *(size_t *)data = value; break;
        default: FFI_ASSERT(0); break;
    }
}

/* adds an argument to a call, or a not by reference return value */
static void marshal(call_builder *cb, ffi_type *type, int var, void *data) {
    size_t realign[2];

#if ABI_FLEN
    if (!var && type->type == FFI_TYPE_STRUCT) {
        float_struct_info fsi = struct_passed_as_elements(cb, type);
        if (fsi.as_elements) {
            marshal_atom(cb, fsi.type1, data);
            if (fsi.offset2)
                marshal_atom(cb, fsi.type2, ((char*)data) + fsi.offset2);
            return;
        }
    }

    if (!var && cb->used_float < NARGREG && IS_FLOAT(type->type)) {
        marshal_atom(cb, type->type, data);
        return;
    }
#endif

    if (type->size > 2 * __SIZEOF_POINTER__) {
        /* pass by reference */
        marshal_atom(cb, FFI_TYPE_POINTER, &data);
    } else if (IS_INT(type->type) || type->type == FFI_TYPE_POINTER) {
        marshal_atom(cb, type->type, data);
    } else {
        /* overlong integers, soft-float floats, and structs without special
           float handling are treated identically from this point on */

        /* variadics are aligned even in registers */
        if (type->alignment > __SIZEOF_POINTER__) {
            if (var)
                cb->used_integer = FFI_ALIGN(cb->used_integer, 2);
            cb->used_stack = (size_t *)FFI_ALIGN(cb->used_stack, 2*__SIZEOF_POINTER__);
        }

        memcpy(realign, data, type->size);
        if (type->size > 0)
            marshal_atom(cb, FFI_TYPE_POINTER, realign);
        if (type->size > __SIZEOF_POINTER__)
            marshal_atom(cb, FFI_TYPE_POINTER, realign + 1);
    }
}

/* for arguments passed by reference returns the pointer, otherwise the arg is copied (up to MAXCOPYARG bytes) */
static void *unmarshal(call_builder *cb, ffi_type *type, int var, void *data) {
    size_t realign[2];
    void *pointer;

#if ABI_FLEN
    if (!var && type->type == FFI_TYPE_STRUCT) {
        float_struct_info fsi = struct_passed_as_elements(cb, type);
        if (fsi.as_elements) {
            unmarshal_atom(cb, fsi.type1, data);
            if (fsi.offset2)
                unmarshal_atom(cb, fsi.type2, ((char*)data) + fsi.offset2);
            return data;
        }
    }

    if (!var && cb->used_float < NARGREG && IS_FLOAT(type->type)) {
        unmarshal_atom(cb, type->type, data);
        return data;
    }
#endif

    if (type->size > 2 * __SIZEOF_POINTER__) {
        /* pass by reference */
        unmarshal_atom(cb, FFI_TYPE_POINTER, (char*)&pointer);
        return pointer;
    } else if (IS_INT(type->type) || type->type == FFI_TYPE_POINTER) {
        unmarshal_atom(cb, type->type, data);
        return data;
    } else {
        /* overlong integers, soft-float floats, and structs without special
           float handling are treated identically from this point on */

        /* variadics are aligned even in registers */
        if (type->alignment > __SIZEOF_POINTER__) {
            if (var)
                cb->used_integer = FFI_ALIGN(cb->used_integer, 2);
            cb->used_stack = (size_t *)FFI_ALIGN(cb->used_stack, 2*__SIZEOF_POINTER__);
        }

        if (type->size > 0)
            unmarshal_atom(cb, FFI_TYPE_POINTER, realign);
        if (type->size > __SIZEOF_POINTER__)
            unmarshal_atom(cb, FFI_TYPE_POINTER, realign + 1);
        memcpy(data, realign, type->size);
        return data;
    }
}

static int passed_by_ref(call_builder *cb, ffi_type *type, int var) {
#if ABI_FLEN
    if (!var && type->type == FFI_TYPE_STRUCT) {
        float_struct_info fsi = struct_passed_as_elements(cb, type);
        if (fsi.as_elements) return 0;
    }
#endif

    return type->size > 2 * __SIZEOF_POINTER__;
}

/* Perform machine dependent cif processing */
ffi_status ffi_prep_cif_machdep(ffi_cif *cif) {
    cif->riscv_nfixedargs = cif->nargs;
    return FFI_OK;
}

/* Perform machine dependent cif processing when we have a variadic function */

ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned int nfixedargs, unsigned int ntotalargs) {
    cif->riscv_nfixedargs = nfixedargs;
    return FFI_OK;
}

/* Low level routine for calling functions */
extern void ffi_call_asm(void *stack, struct call_context *regs, void (*fn)(void)) FFI_HIDDEN;

void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
{
    /* this is a conservative estimate, assuming a complex return value and
       that all remaining arguments are long long / __int128 */
    size_t arg_bytes = cif->nargs <= 3 ? 0 :
        FFI_ALIGN(2 * sizeof(size_t) * (cif->nargs - 3), STKALIGN);
    size_t rval_bytes = 0;
    if (rvalue == NULL && cif->rtype->size > 2*__SIZEOF_POINTER__)
        rval_bytes = FFI_ALIGN(cif->rtype->size, STKALIGN);
    size_t alloc_size = arg_bytes + rval_bytes + sizeof(call_context);

    /* the assembly code will deallocate all stack data at lower addresses
       than the argument region, so we need to allocate the frame and the
       return value after the arguments in a single allocation */
    size_t alloc_base;
    /* Argument region must be 16-byte aligned */
    if (_Alignof(max_align_t) >= STKALIGN) {
        /* since sizeof long double is normally 16, the compiler will
           guarantee alloca alignment to at least that much */
        alloc_base = (size_t)alloca(alloc_size);
    } else {
        alloc_base = FFI_ALIGN(alloca(alloc_size + STKALIGN - 1), STKALIGN);
    }

    if (rval_bytes)
        rvalue = (void*)(alloc_base + arg_bytes);

    call_builder cb;
    cb.used_float = cb.used_integer = 0;
    cb.aregs = (call_context*)(alloc_base + arg_bytes + rval_bytes);
    cb.used_stack = (void*)alloc_base;

    int return_by_ref = passed_by_ref(&cb, cif->rtype, 0);
    if (return_by_ref)
        marshal(&cb, &ffi_type_pointer, 0, &rvalue);

    int i;
    for (i = 0; i < cif->nargs; i++)
        marshal(&cb, cif->arg_types[i], i >= cif->riscv_nfixedargs, avalue[i]);

    ffi_call_asm((void*)alloc_base, cb.aregs, fn);

    cb.used_float = cb.used_integer = 0;
    if (!return_by_ref && rvalue)
        unmarshal(&cb, cif->rtype, 0, rvalue);
}

extern void ffi_closure_asm(void) FFI_HIDDEN;

ffi_status ffi_prep_closure_loc(ffi_closure *closure, ffi_cif *cif, void (*fun)(ffi_cif*,void*,void**,void*), void *user_data, void *codeloc)
{
    uint32_t *tramp = (uint32_t *) &closure->tramp[0];
    uint64_t fn = (uint64_t) (uintptr_t) ffi_closure_asm;

    if (cif->abi <= FFI_FIRST_ABI || cif->abi >= FFI_LAST_ABI)
        return FFI_BAD_ABI;

    /* we will call ffi_closure_inner with codeloc, not closure, but as long
       as the memory is readable it should work */

    tramp[0] = 0x00000317; /* auipc t1, 0 (i.e. t0 <- codeloc) */
#if __SIZEOF_POINTER__ == 8
    tramp[1] = 0x01033383; /* ld t2, 16(t1) */
#else
    tramp[1] = 0x01032383; /* lw t2, 16(t1) */
#endif
    tramp[2] = 0x00038067; /* jr t2 */
    tramp[3] = 0x00000013; /* nop */
    tramp[4] = fn;
    tramp[5] = fn >> 32;

    closure->cif = cif;
    closure->fun = fun;
    closure->user_data = user_data;

    __builtin___clear_cache(codeloc, codeloc + FFI_TRAMPOLINE_SIZE);

    return FFI_OK;
}

/* Called by the assembly code with aregs pointing to saved argument registers
   and stack pointing to the stacked arguments.  Return values passed in
   registers will be reloaded from aregs. */
void FFI_HIDDEN ffi_closure_inner(size_t *stack, call_context *aregs, ffi_closure *closure) {
    ffi_cif *cif = closure->cif;
    void **avalue = alloca(cif->nargs * sizeof(void*));
    /* storage for arguments which will be copied by unmarshal().  We could
       theoretically avoid the copies in many cases and use at most 128 bytes
       of memory, but allocating disjoint storage for each argument is
       simpler. */
    char *astorage = alloca(cif->nargs * MAXCOPYARG);
    void *rvalue;
    call_builder cb;
    int return_by_ref;
    int i;

    cb.aregs = aregs;
    cb.used_integer = cb.used_float = 0;
    cb.used_stack = stack;

    return_by_ref = passed_by_ref(&cb, cif->rtype, 0);
    if (return_by_ref)
        unmarshal(&cb, &ffi_type_pointer, 0, &rvalue);
    else
        rvalue = alloca(cif->rtype->size);

    for (i = 0; i < cif->nargs; i++)
        avalue[i] = unmarshal(&cb, cif->arg_types[i],
            i >= cif->riscv_nfixedargs, astorage + i*MAXCOPYARG);

    (closure->fun)(cif, rvalue, avalue, closure->user_data);

    if (!return_by_ref && cif->rtype->type != FFI_TYPE_VOID) {
        cb.used_integer = cb.used_float = 0;
        marshal(&cb, cif->rtype, 0, rvalue);
    }
}
