+/*
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
#ifndef THUNK_H
#define THUNK_H
#endif
-#ifdef WORDS_BIGENDIAN
+#if defined(WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
#define BSWAP_NEEDED
#endif
/* XXX: autoconf */
-#define TARGET_I386
#define TARGET_LONG_BITS 32
-
-#if defined(__alpha__)
+#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 (TARGET_LONG_BITS / 8)
+#define HOST_LONG_SIZE (HOST_LONG_BITS / 8)
static inline uint16_t bswap16(uint16_t x)
{
return bswap_64(x);
}
-static void inline bswap16s(uint16_t *s)
+static inline void bswap16s(uint16_t *s)
{
*s = bswap16(*s);
}
-static void inline bswap32s(uint32_t *s)
+static inline void bswap32s(uint32_t *s)
{
*s = bswap32(*s);
}
-static void inline bswap64s(uint64_t *s)
+static inline void bswap64s(uint64_t *s)
{
*s = bswap64(*s);
}
return bswap64(s);
}
-static void inline tswap16s(uint16_t *s)
+static inline void tswap16s(uint16_t *s)
{
*s = bswap16(*s);
}
-static void inline tswap32s(uint32_t *s)
+static inline void tswap32s(uint32_t *s)
{
*s = bswap32(*s);
}
-static void inline tswap64s(uint64_t *s)
+static inline void tswap64s(uint64_t *s)
{
*s = bswap64(*s);
}
return s;
}
-static void inline tswap16s(uint16_t *s)
+static inline void tswap16s(uint16_t *s)
{
}
-static void inline tswap32s(uint32_t *s)
+static inline void tswap32s(uint32_t *s)
{
}
-static void inline tswap64s(uint64_t *s)
+static inline void tswap64s(uint64_t *s)
{
}
void thunk_register_struct_direct(int id, const char *name, 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[];
+
+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_LONG_SIZE;
+ }
+ break;
+ case TYPE_ARRAY:
+ size = type_ptr[1];
+ return size * thunk_type_size(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_LONG_SIZE;
+ }
+ break;
+ case TYPE_ARRAY:
+ return thunk_type_align(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,
bitmask_transtbl * trans_tbl);