diff options
Diffstat (limited to 'thunk.c')
-rw-r--r-- | thunk.c | 55 |
1 files changed, 50 insertions, 5 deletions
@@ -31,6 +31,8 @@ /* 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) { int type; @@ -47,9 +49,9 @@ static inline const argtype *thunk_type_next(const argtype *type_ptr) case TYPE_PTRVOID: 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,6 +59,11 @@ 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; @@ -136,22 +143,48 @@ const argtype *thunk_convert(void *dst, const void *src, case TYPE_ULONGLONG: *(uint64_t *)dst = tswap64(*(uint64_t *)src); break; -#if HOST_LONG_BITS == 32 && TARGET_LONG_BITS == 32 +#if HOST_LONG_BITS == 32 && TARGET_ABI_BITS == 32 case TYPE_LONG: case TYPE_ULONG: case TYPE_PTRVOID: *(uint32_t *)dst = tswap32(*(uint32_t *)src); break; -#elif HOST_LONG_BITS == 64 && TARGET_LONG_BITS == 32 +#elif HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 32 case TYPE_LONG: 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 @@ -241,3 +274,15 @@ 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 */ |