summaryrefslogtreecommitdiff
path: root/libffi/src/prep_cif.c
diff options
context:
space:
mode:
Diffstat (limited to 'libffi/src/prep_cif.c')
-rw-r--r--libffi/src/prep_cif.c47
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);
}