/*
 *  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 "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
