diff options
author | Richard Henderson <rth@redhat.com> | 2014-10-22 22:58:09 -0400 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2014-11-12 09:29:31 +0100 |
commit | a992f8789b5202ca180e67b16b47ee834160665c (patch) | |
tree | d69a0a6989a0ce13b1a2e37937bf8a2cddb6fc4e | |
parent | 658b2b56001e293848ea22b70068bd7f8daa7205 (diff) | |
download | libffi-a992f8789b5202ca180e67b16b47ee834160665c.tar.gz |
aarch64: Add support for complex types
-rw-r--r-- | src/aarch64/ffi.c | 34 | ||||
-rw-r--r-- | src/aarch64/ffitarget.h | 2 | ||||
-rw-r--r-- | testsuite/libffi.call/call.exp | 9 |
3 files changed, 32 insertions, 13 deletions
diff --git a/src/aarch64/ffi.c b/src/aarch64/ffi.c index b3e0b16..4f85140 100644 --- a/src/aarch64/ffi.c +++ b/src/aarch64/ffi.c @@ -85,7 +85,7 @@ is_hfa0 (const ffi_type *ty) for (i = 0; elements[i]; ++i) { ret = elements[i]->type; - if (ret == FFI_TYPE_STRUCT) + if (ret == FFI_TYPE_STRUCT || ret == FFI_TYPE_COMPLEX) { ret = is_hfa0 (elements[i]); if (ret < 0) @@ -110,7 +110,7 @@ is_hfa1 (const ffi_type *ty, int candidate) for (i = 0; elements[i]; ++i) { int t = elements[i]->type; - if (t == FFI_TYPE_STRUCT) + if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX) { if (!is_hfa1 (elements[i], candidate)) return 0; @@ -138,16 +138,27 @@ is_vfp_type (const ffi_type *ty) size_t size, ele_count; /* Quickest tests first. */ - switch (ty->type) + candidate = ty->type; + switch (candidate) { default: return 0; case FFI_TYPE_FLOAT: - return AARCH64_RET_S1; case FFI_TYPE_DOUBLE: - return AARCH64_RET_D1; case FFI_TYPE_LONGDOUBLE: - return AARCH64_RET_Q1; + ele_count = 1; + goto done; + case FFI_TYPE_COMPLEX: + candidate = ty->elements[0]->type; + switch (candidate) + { + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + case FFI_TYPE_LONGDOUBLE: + ele_count = 2; + goto done; + } + return 0; case FFI_TYPE_STRUCT: break; } @@ -160,7 +171,7 @@ is_vfp_type (const ffi_type *ty) /* Find the type of the first non-structure member. */ elements = ty->elements; candidate = elements[0]->type; - if (candidate == FFI_TYPE_STRUCT) + if (candidate == FFI_TYPE_STRUCT || candidate == FFI_TYPE_COMPLEX) { for (i = 0; ; ++i) { @@ -198,16 +209,18 @@ is_vfp_type (const ffi_type *ty) /* Finally, make sure that all scalar elements are the same type. */ for (i = 0; elements[i]; ++i) { - if (elements[i]->type == FFI_TYPE_STRUCT) + int t = elements[i]->type; + if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX) { if (!is_hfa1 (elements[i], candidate)) return 0; } - else if (elements[i]->type != candidate) + else if (t != candidate) return 0; } /* All tests succeeded. Encode the result. */ + done: return candidate * 4 + (4 - ele_count); } @@ -474,6 +487,7 @@ ffi_prep_cif_machdep (ffi_cif *cif) case FFI_TYPE_DOUBLE: case FFI_TYPE_LONGDOUBLE: case FFI_TYPE_STRUCT: + case FFI_TYPE_COMPLEX: flags = is_vfp_type (rtype); if (flags == 0) { @@ -618,6 +632,7 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *orig_rvalue, void **avalue) case FFI_TYPE_DOUBLE: case FFI_TYPE_LONGDOUBLE: case FFI_TYPE_STRUCT: + case FFI_TYPE_COMPLEX: { void *dest; @@ -788,6 +803,7 @@ ffi_closure_SYSV_inner (ffi_cif *cif, case FFI_TYPE_DOUBLE: case FFI_TYPE_LONGDOUBLE: case FFI_TYPE_STRUCT: + case FFI_TYPE_COMPLEX: h = is_vfp_type (ty); if (h) { diff --git a/src/aarch64/ffitarget.h b/src/aarch64/ffitarget.h index 6d6d3e6..7461386 100644 --- a/src/aarch64/ffitarget.h +++ b/src/aarch64/ffitarget.h @@ -52,4 +52,6 @@ typedef enum ffi_abi #define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs #endif +#define FFI_TARGET_HAS_COMPLEX_TYPE + #endif diff --git a/testsuite/libffi.call/call.exp b/testsuite/libffi.call/call.exp index d42dae5..676b323 100644 --- a/testsuite/libffi.call/call.exp +++ b/testsuite/libffi.call/call.exp @@ -26,10 +26,11 @@ run-many-tests $tlist "" # ??? We really should preprocess ffi.h and grep # for FFI_TARGET_HAS_COMPLEX_TYPE. -if { [istarget s390*] - || [istarget x86_64*] - || [istarget i?86*] } { - run-many-tests $ctlist "" +if { [istarget aarch64*] + || [istarget i?86*] + || [istarget s390*] + || [istarget x86_64*] } { + run-many-tests $ctlist "" } else { foreach test $ctlist { unsupported "$test" |