/*
 *  Generic thunking code to convert data between host and target CPU
 *
 *  Copyright (c) 2003 Fabrice Bellard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#ifndef THUNK_H
#define THUNK_H

#include "cpu.h"
#include "exec/user/abitypes.h"

/* types enums definitions */

typedef enum argtype {
    TYPE_NULL,
    TYPE_CHAR,
    TYPE_SHORT,
    TYPE_INT,
    TYPE_LONG,
    TYPE_ULONG,
    TYPE_PTRVOID, /* pointer on unknown data */
    TYPE_LONGLONG,
    TYPE_ULONGLONG,
    TYPE_PTR,
    TYPE_ARRAY,
    TYPE_STRUCT,
    TYPE_OLDDEVT,
} argtype;

#define MK_PTR(type) TYPE_PTR, type
#define MK_ARRAY(type, size) TYPE_ARRAY, (int)(size), type
#define MK_STRUCT(id) TYPE_STRUCT, id

#define THUNK_TARGET 0
#define THUNK_HOST   1

typedef struct {
    /* standard struct handling */
    const argtype *field_types;
    int nb_fields;
    int *field_offsets[2];
    /* special handling */
    void (*convert[2])(void *dst, const void *src);
    void (*print)(void *arg);
    int size[2];
    int align[2];
    const char *name;
} StructEntry;

/* Translation table for bitmasks... */
typedef struct bitmask_transtbl {
    unsigned int target_mask;
    unsigned int target_bits;
    unsigned int host_mask;
    unsigned int host_bits;
} bitmask_transtbl;

void thunk_register_struct(int id, const char *name, const argtype *types);
void thunk_register_struct_direct(int id, const char *name,
                                  const StructEntry *se1);
const argtype *thunk_convert(void *dst, const void *src,
                             const argtype *type_ptr, int to_host);
const argtype *thunk_print(void *arg, const argtype *type_ptr);

extern StructEntry *struct_entries;

int thunk_type_size_array(const argtype *type_ptr, int is_host);
int thunk_type_align_array(const argtype *type_ptr, int is_host);

static inline int thunk_type_size(const argtype *type_ptr, int is_host)
{
    int type, size;
    const StructEntry *se;

    type = *type_ptr;
    switch(type) {
    case TYPE_CHAR:
        return 1;
    case TYPE_SHORT:
        return 2;
    case TYPE_INT:
        return 4;
    case TYPE_LONGLONG:
    case TYPE_ULONGLONG:
        return 8;
    case TYPE_LONG:
    case TYPE_ULONG:
    case TYPE_PTRVOID:
    case TYPE_PTR:
        if (is_host) {
            return sizeof(void *);
        } else {
            return TARGET_ABI_BITS / 8;
        }
        break;
    case TYPE_OLDDEVT:
        if (is_host) {
#if defined(HOST_X86_64)
            return 8;
#elif defined(HOST_ALPHA) || defined(HOST_IA64) || defined(HOST_MIPS) || \
      defined(HOST_PARISC) || defined(HOST_SPARC64)
            return 4;
#elif defined(HOST_PPC)
            return sizeof(void *);
#else
            return 2;
#endif
        } else {
#if defined(TARGET_X86_64)
            return 8;
#elif defined(TARGET_ALPHA) || defined(TARGET_IA64) || defined(TARGET_MIPS) || \
      defined(TARGET_PARISC) || defined(TARGET_SPARC64)
            return 4;
#elif defined(TARGET_PPC)
            return TARGET_ABI_BITS / 8;
#else
            return 2;
#endif
        }
        break;
    case TYPE_ARRAY:
        size = type_ptr[1];
        return size * thunk_type_size_array(type_ptr + 2, is_host);
    case TYPE_STRUCT:
        se = struct_entries + type_ptr[1];
        return se->size[is_host];
    default:
        g_assert_not_reached();
    }
}

static inline int thunk_type_align(const argtype *type_ptr, int is_host)
{
    int type;
    const StructEntry *se;

    type = *type_ptr;
    switch(type) {
    case TYPE_CHAR:
        return 1;
    case TYPE_SHORT:
        if (is_host) {
            return __alignof__(short);
        } else {
            return ABI_SHORT_ALIGNMENT;
        }
    case TYPE_INT:
        if (is_host) {
            return __alignof__(int);
        } else {
            return ABI_INT_ALIGNMENT;
        }
    case TYPE_LONGLONG:
    case TYPE_ULONGLONG:
        if (is_host) {
            return __alignof__(long long);
        } else {
            return ABI_LLONG_ALIGNMENT;
        }
    case TYPE_LONG:
    case TYPE_ULONG:
    case TYPE_PTRVOID:
    case TYPE_PTR:
        if (is_host) {
            return __alignof__(long);
        } else {
            return ABI_LONG_ALIGNMENT;
        }
        break;
    case TYPE_OLDDEVT:
        return thunk_type_size(type_ptr, is_host);
    case TYPE_ARRAY:
        return thunk_type_align_array(type_ptr + 2, is_host);
    case TYPE_STRUCT:
        se = struct_entries + type_ptr[1];
        return se->align[is_host];
    default:
        g_assert_not_reached();
    }
}

unsigned int target_to_host_bitmask(unsigned int target_mask,
                                    const bitmask_transtbl * trans_tbl);
unsigned int host_to_target_bitmask(unsigned int host_mask,
                                    const bitmask_transtbl * trans_tbl);

void thunk_init(unsigned int max_structs);

#endif
