/*
 *  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 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 <inttypes.h>
#include "cpu.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, 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);
    int size[2];
    int align[2];
    const char *name;
} StructEntry;

/* Translation table for bitmasks... */
typedef struct bitmask_transtbl {
	unsigned int	x86_mask;
	unsigned int	x86_bits;
	unsigned int	alpha_mask;
	unsigned int	alpha_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);
#ifndef NO_THUNK_TYPE_SIZE

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:
        return -1;
    }
}

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:
        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:
        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:
        return -1;
    }
}

#endif /* NO_THUNK_TYPE_SIZE */

unsigned int target_to_host_bitmask(unsigned int x86_mask,
                                    const bitmask_transtbl * trans_tbl);
unsigned int host_to_target_bitmask(unsigned int alpha_mask,
                                    const bitmask_transtbl * trans_tbl);

void thunk_init(unsigned int max_structs);

#endif
