From c27f813900a3c114562efbb8df1065e94766fc48 Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Tue, 10 Feb 2009 15:43:59 -0800 Subject: auto import from //branches/cupcake/...@130745 --- thunk.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 60 insertions(+), 15 deletions(-) (limited to 'thunk.c') diff --git a/thunk.c b/thunk.c index bc9bd28..7331aeb 100644 --- a/thunk.c +++ b/thunk.c @@ -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 @@ -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; @@ -64,7 +71,7 @@ void thunk_register_struct(int id, const char *name, const argtype *types) int nb_fields, offset, max_align, align, size, i, j; se = struct_entries + id; - + /* first we count the number of fields */ type_ptr = types; nb_fields = 0; @@ -76,7 +83,7 @@ void thunk_register_struct(int id, const char *name, const argtype *types) se->nb_fields = nb_fields; se->name = name; #ifdef DEBUG - printf("struct %s: id=%d nb_fields=%d\n", + printf("struct %s: id=%d nb_fields=%d\n", se->name, id, se->nb_fields); #endif /* now we can alloc the data */ @@ -100,7 +107,7 @@ void thunk_register_struct(int id, const char *name, const argtype *types) se->size[i] = offset; se->align[i] = max_align; #ifdef DEBUG - printf("%s: size=%d align=%d\n", + printf("%s: size=%d align=%d\n", i == THUNK_HOST ? "host" : "target", offset, max_align); #endif } @@ -116,7 +123,7 @@ void thunk_register_struct_direct(int id, const char *name, StructEntry *se1) /* now we can define the main conversion functions */ -const argtype *thunk_convert(void *dst, const void *src, +const argtype *thunk_convert(void *dst, const void *src, const argtype *type_ptr, int to_host) { int type; @@ -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 @@ -182,7 +215,7 @@ const argtype *thunk_convert(void *dst, const void *src, uint8_t *d; const argtype *field_types; const int *dst_offsets, *src_offsets; - + se = struct_entries + *type_ptr++; if (se->convert[0] != NULL) { /* specific conversion is needed */ @@ -195,8 +228,8 @@ const argtype *thunk_convert(void *dst, const void *src, d = dst; s = src; for(i = 0;i < se->nb_fields; i++) { - field_types = thunk_convert(d + dst_offsets[i], - s + src_offsets[i], + field_types = thunk_convert(d + dst_offsets[i], + s + src_offsets[i], field_types, to_host); } } @@ -214,7 +247,7 @@ const argtype *thunk_convert(void *dst, const void *src, /* Utility function: Table-driven functions to translate bitmasks * between X86 and Alpha formats... */ -unsigned int target_to_host_bitmask(unsigned int x86_mask, +unsigned int target_to_host_bitmask(unsigned int x86_mask, bitmask_transtbl * trans_tbl) { bitmask_transtbl * btp; @@ -228,7 +261,7 @@ unsigned int target_to_host_bitmask(unsigned int x86_mask, return(alpha_mask); } -unsigned int host_to_target_bitmask(unsigned int alpha_mask, +unsigned int host_to_target_bitmask(unsigned int alpha_mask, bitmask_transtbl * trans_tbl) { bitmask_transtbl * btp; @@ -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 */ -- cgit v1.1