8000 WIP:Feature/arm64 simd support by tdermendjiev · Pull Request #414 · libffi/libffi · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

WIP:Feature/arm64 simd support #414

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ AM_CONDITIONAL(TESTSUBDIR, test -d $srcdir/testsuite)

TARGETDIR="unknown"
HAVE_LONG_DOUBLE_VARIANT=0
HAVE_EXT_VECTOR=0

. ${srcdir}/configure.host

Expand Down Expand Up @@ -106,6 +107,7 @@ if test -z "$HAVE_LONG_DOUBLE"; then
fi
AC_SUBST(HAVE_LONG_DOUBLE)
AC_SUBST(HAVE_LONG_DOUBLE_VARIANT)
AC_SUBST(HAVE_EXT_VECTOR)

AC_C_BIGENDIAN

Expand Down Expand Up @@ -203,6 +205,12 @@ case "$target" in
alternative means])
;;
esac

case "$target" in
aarch64-apple-darwin*)
HAVE_EXT_VECTOR=1
esac

AM_CONDITIONAL(FFI_EXEC_TRAMPOLINE_TABLE, test x$FFI_EXEC_TRAMPOLINE_TABLE = x1)
AC_SUBST(FFI_EXEC_TRAMPOLINE_TABLE)

Expand Down
11 changes: 10 additions & 1 deletion include/ffi.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -478,9 +478,18 @@ ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type,
#define FFI_TYPE_STRUCT 13
#define FFI_TYPE_POINTER 14
#define FFI_TYPE_COMPLEX 15
#if @HAVE_EXT_VECTOR@
#define FFI_TYPE_EXT_VECTOR 16
#else
#define FFI_TYPE_EXT_VECTOR FFI_TYPE_STRUCT
#endif

/* This should always refer to the last type code (for sanity checks). */
#define FFI_TYPE_LAST FFI_TYPE_COMPLEX
#if @HAVE_EXT_VECTOR@
#define FFI_TYPE_LAST FFI_TYPE_EXT_VECTOR
#else
#define FFI_TYPE_LAST FFI_TYPE_COMPLEX
#endif

#ifdef __cplusplus
}
Expand Down
60 changes: 52 additions & 8 deletions src/aarch64/ffi.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ ffi_clear_cache (void *start, void *end)

#endif

static int intlog2(int n) {
int targetlevel = 0;
while (n >>= 1) ++targetlevel;
return targetlevel;
}

/* A subroutine of is_vfp_type. Given a structure type, return the type code
of the first non-structure element. Recurse for structure elements.
Return -1 if the structure is in fact empty, i.e. no nested elements. */
Expand All @@ -95,7 +101,7 @@ is_hfa0 (const ffi_type *ty)
for (i = 0; elements[i]; ++i)
{
ret = elements[i]->type;
if (ret == FFI_TYPE_STRUCT || ret == FFI_TYPE_COMPLEX)
if (ret == FFI_TYPE_STRUCT || ret == FFI_TYPE_COMPLEX || ret == FFI_TYPE_EXT_VECTOR)
{
ret = is_hfa0 (elements[i]);
if (ret < 0)
Expand All @@ -107,6 +113,30 @@ is_hfa0 (const ffi_type *ty)
return ret;
}

static size_t is_simd(const ffi_type *ty) // return 0 if no SIMD elements
{
if (ty->type == FFI_TYPE_EXT_VECTOR || ty->type == FFI_TYPE_COMPLEX) {
return ty->size;
}
ffi_type **elements = ty->elements;
int i;

if (elements != NULL)
{
for (i = 0; elements[i]; ++i)
{
int element_type = elements[i]->type;
if (element_type == FFI_TYPE_STRUCT || element_type == FFI_TYPE_COMPLEX || element_type == FFI_TYPE_EXT_VECTOR)
{
return is_simd(elements[i]);
}
}
}

return 0;

}

/* A subroutine of is_vfp_type. Given a structure type, return true if all
of the non-structure elements are the same as CANDIDATE. */

Expand All @@ -120,7 +150,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 || t == FFI_TYPE_COMPLEX)
if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX || t == FFI_TYPE_EXT_VECTOR)
{
if (!is_hfa1 (elements[i], candidate))
return 0;
Expand All @@ -145,7 +175,7 @@ is_vfp_type (const ffi_type *ty)
{
ffi_type **elements;
int candidate, i;
size_t size, ele_count;
size_t size, ele_count, simd_size;

/* Quickest tests first. */
candidate = ty->type;
Expand All @@ -170,6 +200,7 @@ is_vfp_type (const ffi_type *ty)
}
return 0;
case FFI_TYPE_STRUCT:
case FFI_TYPE_EXT_VECTOR:
break;
}

Expand All @@ -181,7 +212,9 @@ 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 || candidate == FFI_TYPE_COMPLEX)
/* Find the size of the SIMD member, if any. */
simd_size = is_simd(ty);
if (candidate == FFI_TYPE_STRUCT || candidate == FFI_TYPE_COMPLEX || candidate == FFI_TYPE_EXT_VECTOR)
{
for (i = 0; ; ++i)
{
Expand Down Expand Up @@ -213,14 +246,14 @@ is_vfp_type (const ffi_type *ty)
default:
return 0;
}
if (ele_count > 4)
if ((ele_count > 4 && !simd_size) || (ele_count > 16 && simd_size))
return 0;

/* Finally, make sure that all scalar elements are the same type. */
for (i = 0; elements[i]; ++i)
{
int t = elements[i]->type;
if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX)
if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX || t == FFI_TYPE_EXT_VECTOR)
{
if (!is_hfa1 (elements[i], candidate))
return 0;
Expand All @@ -230,8 +263,16 @@ is_vfp_type (const ffi_type *ty)
}

/* All tests succeeded. Encode the result. */
done:
return candidate * 4 + (4 - (int)ele_count);
if (simd_size) {
size_t regSize = simd_size;

int num_registers = (int) size / regSize + (size % regSize ? 1 : 0);
int first_level_element_type = FFI_TYPE_FLOAT + intlog2((int)regSize) - 2;
return (int) (first_level_element_type * 4 + (4 - num_registers));
}

done:
return candidate * 4 + (4 - (int)ele_count);
}

/* Representation of the procedure call argument marshalling
Expand Down Expand Up @@ -497,6 +538,7 @@ ffi_prep_cif_machdep (ffi_cif *cif)
case FFI_TYPE_DOUBLE:
case FFI_TYPE_LONGDOUBLE:
case FFI_TYPE_STRUCT:
case FFI_TYPE_EXT_VECTOR:
case FFI_TYPE_COMPLEX:
flags = is_vfp_type (rtype);
if (flags == 0)
Expand Down Expand Up @@ -643,6 +685,7 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,
case FFI_TYPE_DOUBLE:
case FFI_TYPE_LONGDOUBLE:
case FFI_TYPE_STRUCT:
case FFI_TYPE_EXT_VECTOR:
case FFI_TYPE_COMPLEX:
{
void *dest;
Expand Down Expand Up @@ -866,6 +909,7 @@ ffi_closure_SYSV_inner (ffi_cif *cif,
case FFI_TYPE_DOUBLE:
case FFI_TYPE_LONGDOUBLE:
case FFI_TYPE_STRUCT:
case FFI_TYPE_EXT_VECTOR:
case FFI_TYPE_COMPLEX:
h = is_vfp_type (ty);
if (h)
Expand Down
4 changes: 3 additions & 1 deletion testsuite/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,6 @@ libffi.go/aa-direct.c libffi.go/ffitest.h libffi.go/go.exp \
libffi.go/static-chain.h libffi.bhaible/bhaible.exp \
libffi.bhaible/test-call.c libffi.bhaible/alignof.h \
libffi.bhaible/testcases.c libffi.bhaible/test-callback.c \
libffi.bhaible/Makefile libffi.bhaible/README config/default.exp
libffi.bhaible/Makefile libffi.bhaible/README config/default.exp \
libffi.call/simd_float_matrices.c \
libffi.call/simd_double_matrices.c
Loading
0