X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/992f48a036cccf7101e31bf3e5d901ce5320e886..54c54f8b56047d3c2420e1ae06a6a8890c220ac4:/thunk.c diff --git a/thunk.c b/thunk.c index 0347d6d049..f501fd72fc 100644 --- a/thunk.c +++ b/thunk.c @@ -14,22 +14,21 @@ * 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 + * License along with this library; if not, see . */ #include #include #include #include "qemu.h" -#include "thunk.h" +#include "exec/user/thunk.h" //#define DEBUG -#define MAX_STRUCTS 128 +static unsigned int max_struct_entries; +StructEntry *struct_entries; -/* XXX: make it dynamic */ -StructEntry struct_entries[MAX_STRUCTS]; +static const argtype *thunk_type_next_ptr(const argtype *type_ptr); static inline const argtype *thunk_type_next(const argtype *type_ptr) { @@ -45,11 +44,12 @@ static inline const argtype *thunk_type_next(const argtype *type_ptr) case TYPE_LONG: case TYPE_ULONG: case TYPE_PTRVOID: + case TYPE_OLDDEVT: return type_ptr; case TYPE_PTR: - return thunk_type_next(type_ptr); + return thunk_type_next_ptr(type_ptr); case TYPE_ARRAY: - return thunk_type_next(type_ptr + 1); + return thunk_type_next_ptr(type_ptr + 1); case TYPE_STRUCT: return type_ptr + 1; default: @@ -57,12 +57,18 @@ static inline const argtype *thunk_type_next(const argtype *type_ptr) } } +static const argtype *thunk_type_next_ptr(const argtype *type_ptr) +{ + return thunk_type_next(type_ptr); +} + void thunk_register_struct(int id, const char *name, const argtype *types) { const argtype *type_ptr; StructEntry *se; int nb_fields, offset, max_align, align, size, i, j; + assert(id < max_struct_entries); se = struct_entries + id; /* first we count the number of fields */ @@ -106,9 +112,12 @@ void thunk_register_struct(int id, const char *name, const argtype *types) } } -void thunk_register_struct_direct(int id, const char *name, StructEntry *se1) +void thunk_register_struct_direct(int id, const char *name, + const StructEntry *se1) { StructEntry *se; + + assert(id < max_struct_entries); se = struct_entries + id; *se = *se1; se->name = name; @@ -147,14 +156,67 @@ const argtype *thunk_convert(void *dst, const void *src, case TYPE_ULONG: case TYPE_PTRVOID: if (to_host) { - *(uint64_t *)dst = tswap32(*(uint32_t *)src); + if (type == TYPE_LONG) { + /* sign extension */ + *(uint64_t *)dst = (int32_t)tswap32(*(uint32_t *)src); + } else { + *(uint64_t *)dst = tswap32(*(uint32_t *)src); + } } else { *(uint32_t *)dst = tswap32(*(uint64_t *)src & 0xffffffff); } break; +#elif HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 64 + case TYPE_LONG: + case TYPE_ULONG: + case TYPE_PTRVOID: + *(uint64_t *)dst = tswap64(*(uint64_t *)src); + break; +#elif HOST_LONG_BITS == 32 && TARGET_ABI_BITS == 64 + case TYPE_LONG: + case TYPE_ULONG: + case TYPE_PTRVOID: + if (to_host) { + *(uint32_t *)dst = tswap64(*(uint64_t *)src); + } else { + if (type == TYPE_LONG) { + /* sign extension */ + *(uint64_t *)dst = tswap64(*(int32_t *)src); + } else { + *(uint64_t *)dst = tswap64(*(uint32_t *)src); + } + } + break; #else #warning unsupported conversion #endif + case TYPE_OLDDEVT: + { + uint64_t val = 0; + switch (thunk_type_size(type_ptr - 1, !to_host)) { + case 2: + val = *(uint16_t *)src; + break; + case 4: + val = *(uint32_t *)src; + break; + case 8: + val = *(uint64_t *)src; + break; + } + switch (thunk_type_size(type_ptr - 1, to_host)) { + case 2: + *(uint16_t *)dst = tswap16(val); + break; + case 4: + *(uint32_t *)dst = tswap32(val); + break; + case 8: + *(uint64_t *)dst = tswap64(val); + break; + } + break; + } case TYPE_ARRAY: { int array_length, i, dst_size, src_size; @@ -183,6 +245,7 @@ const argtype *thunk_convert(void *dst, const void *src, const argtype *field_types; const int *dst_offsets, *src_offsets; + assert(*type_ptr < max_struct_entries); se = struct_entries + *type_ptr++; if (se->convert[0] != NULL) { /* specific conversion is needed */ @@ -215,9 +278,9 @@ const argtype *thunk_convert(void *dst, const void *src, * between X86 and Alpha formats... */ unsigned int target_to_host_bitmask(unsigned int x86_mask, - bitmask_transtbl * trans_tbl) + const bitmask_transtbl * trans_tbl) { - bitmask_transtbl * btp; + const bitmask_transtbl *btp; unsigned int alpha_mask = 0; for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) { @@ -229,9 +292,9 @@ unsigned int target_to_host_bitmask(unsigned int x86_mask, } unsigned int host_to_target_bitmask(unsigned int alpha_mask, - bitmask_transtbl * trans_tbl) + const bitmask_transtbl * trans_tbl) { - bitmask_transtbl * btp; + const bitmask_transtbl *btp; unsigned int x86_mask = 0; for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) { @@ -241,3 +304,21 @@ unsigned int host_to_target_bitmask(unsigned int alpha_mask, } return(x86_mask); } + +#ifndef NO_THUNK_TYPE_SIZE +int thunk_type_size_array(const argtype *type_ptr, int is_host) +{ + return thunk_type_size(type_ptr, is_host); +} + +int thunk_type_align_array(const argtype *type_ptr, int is_host) +{ + return thunk_type_align(type_ptr, is_host); +} +#endif /* ndef NO_THUNK_TYPE_SIZE */ + +void thunk_init(unsigned int max_structs) +{ + max_struct_entries = max_structs; + struct_entries = g_new0(StructEntry, max_structs); +}