diff options
Diffstat (limited to 'libffi/src/prep_cif.c')
-rw-r--r-- | libffi/src/prep_cif.c | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/libffi/src/prep_cif.c b/libffi/src/prep_cif.c index 866ed3471e3..5881cebd784 100644 --- a/libffi/src/prep_cif.c +++ b/libffi/src/prep_cif.c @@ -76,6 +76,13 @@ static ffi_status initialize_aggregate(ffi_type *arg) total size of 3*sizeof(long). */ arg->size = ALIGN (arg->size, arg->alignment); + /* On some targets, the ABI defines that structures have an additional + alignment beyond the "natural" one based on their elements. */ +#ifdef FFI_AGGREGATE_ALIGNMENT + if (FFI_AGGREGATE_ALIGNMENT > arg->alignment) + arg->alignment = FFI_AGGREGATE_ALIGNMENT; +#endif + if (arg->size == 0) return FFI_BAD_TYPEDEF; else @@ -111,13 +118,8 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, FFI_ASSERT((!isvariadic) || (nfixedargs >= 1)); FFI_ASSERT(nfixedargs <= ntotalargs); -#ifndef X86_WIN32 if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI)) return FFI_BAD_ABI; -#else - if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI || abi == FFI_THISCALL)) - return FFI_BAD_ABI; -#endif cif->abi = abi; cif->arg_types = atypes; @@ -134,19 +136,26 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK)) return FFI_BAD_TYPEDEF; +#ifndef FFI_TARGET_HAS_COMPLEX_TYPE + if (rtype->type == FFI_TYPE_COMPLEX) + abort(); +#endif /* Perform a sanity check on the return type */ FFI_ASSERT_VALID_TYPE(cif->rtype); /* x86, x86-64 and s390 stack space allocation is handled in prep_machdep. */ -#if !defined M68K && !defined X86_ANY && !defined S390 && !defined PA +#if !defined FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION /* Make space for the return structure pointer */ if (cif->rtype->type == FFI_TYPE_STRUCT -#ifdef SPARC - && (cif->abi != FFI_V9 || cif->rtype->size > 32) -#endif #ifdef TILE && (cif->rtype->size > 10 * FFI_SIZEOF_ARG) #endif +#ifdef XTENSA + && (cif->rtype->size > 16) +#endif +#ifdef NIOS2 + && (cif->rtype->size > 8) +#endif ) bytes = STACK_ARG_SIZE(sizeof(void*)); #endif @@ -158,23 +167,19 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) return FFI_BAD_TYPEDEF; +#ifndef FFI_TARGET_HAS_COMPLEX_TYPE + if ((*ptr)->type == FFI_TYPE_COMPLEX) + abort(); +#endif /* Perform a sanity check on the argument type, do this check after the initialization. */ FFI_ASSERT_VALID_TYPE(*ptr); -#if !defined X86_ANY && !defined S390 && !defined PA -#ifdef SPARC - if (((*ptr)->type == FFI_TYPE_STRUCT - && ((*ptr)->size > 16 || cif->abi != FFI_V9)) - || ((*ptr)->type == FFI_TYPE_LONGDOUBLE - && cif->abi != FFI_V9)) - bytes += sizeof(void*); - else -#endif +#if !defined FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION { /* Add any padding if necessary */ if (((*ptr)->alignment - 1) & bytes) - bytes = ALIGN(bytes, (*ptr)->alignment); + bytes = (unsigned)ALIGN(bytes, (*ptr)->alignment); #ifdef TILE if (bytes < 10 * FFI_SIZEOF_ARG && @@ -185,6 +190,10 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, bytes = 10 * FFI_SIZEOF_ARG; } #endif +#ifdef XTENSA + if (bytes <= 6*4 && bytes + STACK_ARG_SIZE((*ptr)->size) > 6*4) + bytes = 6*4; +#endif bytes += STACK_ARG_SIZE((*ptr)->size); } |