X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=thunk.h;h=597d753c79a668e4bc3919a51b00b23f6fea1322;hb=48c50a6234447c36d518457c6a1cbb95a1b557fe;hp=9a06847b68c7c420ca30e68b29f8fd1999c527a8;hpb=4f101ad7ff41d1b5f21c4042040c9be7b7817ca0;p=qemu diff --git a/thunk.h b/thunk.h index 9a06847..597d753 100644 --- a/thunk.h +++ b/thunk.h @@ -1,6 +1,6 @@ /* * 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 @@ -15,180 +15,13 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA */ #ifndef THUNK_H #define THUNK_H #include -#include "config.h" - -#ifdef HAVE_BYTESWAP_H -#include -#else - -#define bswap_16(x) \ -({ \ - uint16_t __x = (x); \ - ((uint16_t)( \ - (((uint16_t)(__x) & (uint16_t)0x00ffU) << 8) | \ - (((uint16_t)(__x) & (uint16_t)0xff00U) >> 8) )); \ -}) - -#define bswap_32(x) \ -({ \ - uint32_t __x = (x); \ - ((uint32_t)( \ - (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \ - (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \ - (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \ - (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )); \ -}) - -#define bswap_64(x) \ -({ \ - uint64_t __x = (x); \ - ((uint64_t)( \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000000000ffULL) << 56) | \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000000000ff00ULL) << 40) | \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000ff000000ULL) << 8) | \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0xff00000000000000ULL) >> 56) )); \ -}) - -#endif - -#ifdef WORDS_BIGENDIAN -#define BSWAP_NEEDED -#endif - -/* XXX: autoconf */ -#define TARGET_I386 -#define TARGET_LONG_BITS 32 - - -#if defined(__alpha__) || defined (__ia64__) -#define HOST_LONG_BITS 64 -#else -#define HOST_LONG_BITS 32 -#endif - -#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8) -#define HOST_LONG_SIZE (HOST_LONG_BITS / 8) - -static inline uint16_t bswap16(uint16_t x) -{ - return bswap_16(x); -} - -static inline uint32_t bswap32(uint32_t x) -{ - return bswap_32(x); -} - -static inline uint64_t bswap64(uint64_t x) -{ - return bswap_64(x); -} - -static inline void bswap16s(uint16_t *s) -{ - *s = bswap16(*s); -} - -static inline void bswap32s(uint32_t *s) -{ - *s = bswap32(*s); -} - -static inline void bswap64s(uint64_t *s) -{ - *s = bswap64(*s); -} - -#ifdef BSWAP_NEEDED - -static inline uint16_t tswap16(uint16_t s) -{ - return bswap16(s); -} - -static inline uint32_t tswap32(uint32_t s) -{ - return bswap32(s); -} - -static inline uint64_t tswap64(uint64_t s) -{ - return bswap64(s); -} - -static inline void tswap16s(uint16_t *s) -{ - *s = bswap16(*s); -} - -static inline void tswap32s(uint32_t *s) -{ - *s = bswap32(*s); -} - -static inline void tswap64s(uint64_t *s) -{ - *s = bswap64(*s); -} - -#else - -static inline uint16_t tswap16(uint16_t s) -{ - return s; -} - -static inline uint32_t tswap32(uint32_t s) -{ - return s; -} - -static inline uint64_t tswap64(uint64_t s) -{ - return s; -} - -static inline void tswap16s(uint16_t *s) -{ -} - -static inline void tswap32s(uint32_t *s) -{ -} - -static inline void tswap64s(uint64_t *s) -{ -} - -#endif - -#if TARGET_LONG_SIZE == 4 -#define tswapl(s) tswap32(s) -#define tswapls(s) tswap32s((uint32_t *)(s)) -#else -#define tswapl(s) tswap64(s) -#define tswapls(s) tswap64s((uint64_t *)(s)) -#endif - -#if TARGET_LONG_SIZE == 4 -typedef int32_t target_long; -typedef uint32_t target_ulong; -#elif TARGET_LONG_SIZE == 8 -typedef int64_t target_long; -typedef uint64_t target_ulong; -#else -#error TARGET_LONG_SIZE undefined -#endif +#include "cpu.h" /* types enums definitions */ @@ -235,13 +68,95 @@ typedef struct bitmask_transtbl { } bitmask_transtbl; void thunk_register_struct(int id, const char *name, const argtype *types); -void thunk_register_struct_direct(int id, const char *name, StructEntry *se1); -const argtype *thunk_convert(void *dst, const void *src, +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); - -unsigned int target_to_host_bitmask(unsigned int x86_mask, - bitmask_transtbl * trans_tbl); -unsigned int host_to_target_bitmask(unsigned int alpha_mask, - bitmask_transtbl * trans_tbl); +#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 HOST_LONG_SIZE; + } else { + return TARGET_ABI_BITS / 8; + } + 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 HOST_LONG_SIZE; + } else { + return TARGET_ABI_BITS / 8; + } + break; + 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); #endif