diff --git a/0053-aarch64-Improve-is_hfa.patch b/0053-aarch64-Improve-is_hfa.patch deleted file mode 100644 index bf3e77d2c4dc0e98c1300446d7a80238cbc7c065..0000000000000000000000000000000000000000 --- a/0053-aarch64-Improve-is_hfa.patch +++ /dev/null @@ -1,332 +0,0 @@ -From 38b54b9c180af13a3371e70a151a1a97e105b03f Mon Sep 17 00:00:00 2001 -From: Richard Henderson -Date: Tue, 21 Oct 2014 13:17:39 -0400 -Subject: [PATCH 053/415] aarch64: Improve is_hfa - -The set of functions get_homogeneous_type, element_count, and is_hfa -are all intertwined and recompute data. Return a compound quantity -from is_hfa that contains all the data and avoids the recomputation. ---- - src/aarch64/ffi.c | 212 +++++++++++++++++++++++++++++++++--------------------- - 1 file changed, 131 insertions(+), 81 deletions(-) - -diff --git a/src/aarch64/ffi.c b/src/aarch64/ffi.c -index cdb7816..0834614 100644 ---- a/src/aarch64/ffi.c -+++ b/src/aarch64/ffi.c -@@ -242,88 +242,132 @@ is_floating_type (unsigned short type) - || type == FFI_TYPE_LONGDOUBLE); - } - --/* Test for a homogeneous structure. */ -+/* A subroutine of is_hfa. 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. */ - --static unsigned short --get_homogeneous_type (ffi_type *ty) -+static int -+is_hfa0 (const ffi_type *ty) - { -- if (ty->type == FFI_TYPE_STRUCT && ty->elements) -- { -- unsigned i; -- unsigned short candidate_type -- = get_homogeneous_type (ty->elements[0]); -- for (i =1; ty->elements[i]; i++) -- { -- unsigned short iteration_type = 0; -- /* If we have a nested struct, we must find its homogeneous type. -- If that fits with our candidate type, we are still -- homogeneous. */ -- if (ty->elements[i]->type == FFI_TYPE_STRUCT -- && ty->elements[i]->elements) -- { -- iteration_type = get_homogeneous_type (ty->elements[i]); -- } -- else -- { -- iteration_type = ty->elements[i]->type; -- } -+ ffi_type **elements = ty->elements; -+ int i, ret = -1; - -- /* If we are not homogeneous, return FFI_TYPE_STRUCT. */ -- if (candidate_type != iteration_type) -- return FFI_TYPE_STRUCT; -- } -- return candidate_type; -- } -+ if (elements != NULL) -+ for (i = 0; elements[i]; ++i) -+ { -+ ret = elements[i]->type; -+ if (ret == FFI_TYPE_STRUCT) -+ { -+ ret = is_hfa0 (elements[i]); -+ if (ret < 0) -+ continue; -+ } -+ break; -+ } - -- /* Base case, we have no more levels of nesting, so we -- are a basic type, and so, trivially homogeneous in that type. */ -- return ty->type; -+ return ret; - } - --/* Determine the number of elements within a STRUCT. -+/* A subroutine of is_hfa. Given a structure type, return true if all -+ of the non-structure elements are the same as CANDIDATE. */ - -- Note, we must handle nested structs. -+static int -+is_hfa1 (const ffi_type *ty, int candidate) -+{ -+ ffi_type **elements = ty->elements; -+ int i; - -- If ty is not a STRUCT this function will return 0. */ -+ if (elements != NULL) -+ for (i = 0; elements[i]; ++i) -+ { -+ int t = elements[i]->type; -+ if (t == FFI_TYPE_STRUCT) -+ { -+ if (!is_hfa1 (elements[i], candidate)) -+ return 0; -+ } -+ else if (t != candidate) -+ return 0; -+ } - --static unsigned --element_count (ffi_type *ty) --{ -- if (ty->type == FFI_TYPE_STRUCT && ty->elements) -- { -- unsigned n; -- unsigned elems = 0; -- for (n = 0; ty->elements[n]; n++) -- { -- if (ty->elements[n]->type == FFI_TYPE_STRUCT -- && ty->elements[n]->elements) -- elems += element_count (ty->elements[n]); -- else -- elems++; -- } -- return elems; -- } -- return 0; -+ return 1; - } - --/* Test for a homogeneous floating point aggregate. -+/* Determine if TY is an homogenous floating point aggregate (HFA). -+ That is, a structure consisting of 1 to 4 members of all the same type, -+ where that type is a floating point scalar. - -- A homogeneous floating point aggregate is a homogeneous aggregate of -- a half- single- or double- precision floating point type with one -- to four elements. Note that this includes nested structs of the -- basic type. */ -+ Returns non-zero iff TY is an HFA. The result is an encoded value where -+ bits 0-7 contain the type code, and bits 8-10 contain the element count. */ - - static int --is_hfa (ffi_type *ty) -+is_hfa(const ffi_type *ty) - { -- if (ty->type == FFI_TYPE_STRUCT -- && ty->elements[0] -- && is_floating_type (get_homogeneous_type (ty))) -+ ffi_type **elements; -+ int candidate, i; -+ size_t size, ele_count; -+ -+ /* Quickest tests first. */ -+ if (ty->type != FFI_TYPE_STRUCT) -+ return 0; -+ -+ /* No HFA types are smaller than 4 bytes, or larger than 64 bytes. */ -+ size = ty->size; -+ if (size < 4 || size > 64) -+ return 0; -+ -+ /* Find the type of the first non-structure member. */ -+ elements = ty->elements; -+ candidate = elements[0]->type; -+ if (candidate == FFI_TYPE_STRUCT) - { -- unsigned n = element_count (ty); -- return n >= 1 && n <= 4; -+ for (i = 0; ; ++i) -+ { -+ candidate = is_hfa0 (elements[i]); -+ if (candidate >= 0) -+ break; -+ } - } -- return 0; -+ -+ /* If the first member is not a floating point type, it's not an HFA. -+ Also quickly re-check the size of the structure. */ -+ switch (candidate) -+ { -+ case FFI_TYPE_FLOAT: -+ ele_count = size / sizeof(float); -+ if (size != ele_count * sizeof(float)) -+ return 0; -+ break; -+ case FFI_TYPE_DOUBLE: -+ ele_count = size / sizeof(double); -+ if (size != ele_count * sizeof(double)) -+ return 0; -+ break; -+ case FFI_TYPE_LONGDOUBLE: -+ ele_count = size / sizeof(long double); -+ if (size != ele_count * sizeof(long double)) -+ return 0; -+ break; -+ default: -+ return 0; -+ } -+ if (ele_count > 4) -+ return 0; -+ -+ /* Finally, make sure that all scalar elements are the same type. */ -+ for (i = 0; elements[i]; ++i) -+ { -+ if (elements[i]->type == FFI_TYPE_STRUCT) -+ { -+ if (!is_hfa1 (elements[i], candidate)) -+ return 0; -+ } -+ else if (elements[i]->type != candidate) -+ return 0; -+ } -+ -+ /* All tests succeeded. Encode the result. */ -+ return (ele_count << 8) | candidate; - } - - /* Test if an ffi_type is a candidate for passing in a register. -@@ -559,7 +603,10 @@ copy_hfa_to_reg_or_stack (void *memory, - unsigned char *stack, - struct arg_state *state) - { -- unsigned elems = element_count (ty); -+ int h = is_hfa (ty); -+ int type = h & 0xff; -+ unsigned elems = h >> 8; -+ - if (available_v (state) < elems) - { - /* There are insufficient V registers. Further V register allocations -@@ -573,7 +620,6 @@ copy_hfa_to_reg_or_stack (void *memory, - else - { - int i; -- unsigned short type = get_homogeneous_type (ty); - for (i = 0; i < elems; i++) - { - void *reg = allocate_to_v (context, state); -@@ -813,6 +859,7 @@ void - ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) - { - extended_cif ecif; -+ int h; - - ecif.cif = cif; - ecif.avalue = avalue; -@@ -861,11 +908,12 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) - } - - case FFI_TYPE_STRUCT: -- if (is_hfa (cif->rtype)) -+ h = is_hfa (cif->rtype); -+ if (h) - { - int j; -- unsigned short type = get_homogeneous_type (cif->rtype); -- unsigned elems = element_count (cif->rtype); -+ int type = h & 0xff; -+ int elems = h >> 8; - for (j = 0; j < elems; j++) - { - void *reg = get_basic_type_addr (type, &context, j); -@@ -967,7 +1015,7 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, - ffi_cif *cif = closure->cif; - void **avalue = (void**) alloca (cif->nargs * sizeof (void*)); - void *rvalue = NULL; -- int i; -+ int i, h; - struct arg_state state; - - arg_init (&state, ALIGN(cif->bytes, 16)); -@@ -1002,9 +1050,10 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, - #endif - - case FFI_TYPE_STRUCT: -- if (is_hfa (ty)) -+ h = is_hfa (ty); -+ if (h) - { -- unsigned n = element_count (ty); -+ unsigned n = h >> 8; - if (available_v (&state) < n) - { - state.nsrn = N_V_ARG_REG; -@@ -1013,7 +1062,7 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, - } - else - { -- switch (get_homogeneous_type (ty)) -+ switch (h & 0xff) - { - case FFI_TYPE_FLOAT: - { -@@ -1027,9 +1076,9 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, - correctly. The fake can be tossed once the - closure function has returned hence alloca() - is sufficient. */ -- int j; -+ unsigned j; - UINT32 *p = avalue[i] = alloca (ty->size); -- for (j = 0; j < element_count (ty); j++) -+ for (j = 0; j < n; j++) - memcpy (&p[j], - allocate_to_s (context, &state), - sizeof (*p)); -@@ -1048,9 +1097,9 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, - correctly. The fake can be tossed once the - closure function has returned hence alloca() - is sufficient. */ -- int j; -+ unsigned j; - UINT64 *p = avalue[i] = alloca (ty->size); -- for (j = 0; j < element_count (ty); j++) -+ for (j = 0; j < n; j++) - memcpy (&p[j], - allocate_to_d (context, &state), - sizeof (*p)); -@@ -1143,11 +1192,12 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, - break; - } - case FFI_TYPE_STRUCT: -- if (is_hfa (cif->rtype)) -+ h = is_hfa (cif->rtype); -+ if (h) - { - int j; -- unsigned short type = get_homogeneous_type (cif->rtype); -- unsigned elems = element_count (cif->rtype); -+ int type = h & 0xff; -+ int elems = h >> 8; - for (j = 0; j < elems; j++) - { - void *reg = get_basic_type_addr (type, context, j); --- -2.7.4.huawei.3 - diff --git a/0054-aarch64-Always-distinguish-LONGDOUBLE.patch b/0054-aarch64-Always-distinguish-LONGDOUBLE.patch deleted file mode 100644 index 2fa2bb41e552bc5925e565ff8d8ec1ef01704955..0000000000000000000000000000000000000000 --- a/0054-aarch64-Always-distinguish-LONGDOUBLE.patch +++ /dev/null @@ -1,173 +0,0 @@ -From b5f147d84761dc673ffe01d6af82bcde4ea47928 Mon Sep 17 00:00:00 2001 -From: Richard Henderson -Date: Tue, 21 Oct 2014 13:27:57 -0400 -Subject: [PATCH 054/415] aarch64: Always distinguish LONGDOUBLE - -Avoid if-deffery by forcing FFI_TYPE_LONGDOUBLE different -from FFI_TYPE_DOUBLE. This will simply be unused on hosts -that define them identically. ---- - src/aarch64/ffi.c | 41 ++++++++++++++--------------------------- - 1 file changed, 14 insertions(+), 27 deletions(-) - -diff --git a/src/aarch64/ffi.c b/src/aarch64/ffi.c -index 0834614..f065be5 100644 ---- a/src/aarch64/ffi.c -+++ b/src/aarch64/ffi.c -@@ -20,11 +20,20 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - - #include -- -+#include - #include - #include - --#include -+/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE; -+ all further uses in this file will refer to the 128-bit type. */ -+#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE -+# if FFI_TYPE_LONGDOUBLE != 4 -+# error FFI_TYPE_LONGDOUBLE out of date -+# endif -+#else -+# undef FFI_TYPE_LONGDOUBLE -+# define FFI_TYPE_LONGDOUBLE 4 -+#endif - - /* Stack alignment requirement in bytes */ - #if defined (__APPLE__) -@@ -115,10 +124,8 @@ get_basic_type_addr (unsigned short type, struct call_context *context, - return get_s_addr (context, n); - case FFI_TYPE_DOUBLE: - return get_d_addr (context, n); --#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE - case FFI_TYPE_LONGDOUBLE: - return get_v_addr (context, n); --#endif - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - case FFI_TYPE_UINT16: -@@ -151,10 +158,8 @@ get_basic_type_alignment (unsigned short type) - #endif - case FFI_TYPE_DOUBLE: - return sizeof (UINT64); --#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE - case FFI_TYPE_LONGDOUBLE: - return sizeof (long double); --#endif - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - #if defined (__APPLE__) -@@ -193,10 +198,8 @@ get_basic_type_size (unsigned short type) - return sizeof (UINT32); - case FFI_TYPE_DOUBLE: - return sizeof (UINT64); --#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE - case FFI_TYPE_LONGDOUBLE: - return sizeof (long double); --#endif - case FFI_TYPE_UINT8: - return sizeof (UINT8); - case FFI_TYPE_SINT8: -@@ -390,9 +393,7 @@ is_register_candidate (ffi_type *ty) - case FFI_TYPE_VOID: - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: --#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE - case FFI_TYPE_LONGDOUBLE: --#endif - case FFI_TYPE_UINT8: - case FFI_TYPE_UINT16: - case FFI_TYPE_UINT32: -@@ -557,11 +558,9 @@ copy_basic_type (void *dest, void *source, unsigned short type) - case FFI_TYPE_DOUBLE: - *(double *) dest = *(double *) source; - break; --#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE - case FFI_TYPE_LONGDOUBLE: - *(long double *) dest = *(long double *) source; - break; --#endif - case FFI_TYPE_UINT8: - *(ffi_arg *) dest = *(UINT8 *) source; - break; -@@ -653,13 +652,11 @@ allocate_to_register_or_stack (struct call_context *context, - return allocate_to_d (context, state); - state->nsrn = N_V_ARG_REG; - break; --#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE - case FFI_TYPE_LONGDOUBLE: - if (state->nsrn < N_V_ARG_REG) - return allocate_to_v (context, state); - state->nsrn = N_V_ARG_REG; - break; --#endif - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - case FFI_TYPE_UINT16: -@@ -722,9 +719,7 @@ aarch64_prep_args (struct call_context *context, unsigned char *stack, - appropriate register, or if none are available, to the stack. */ - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: --#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE - case FFI_TYPE_LONGDOUBLE: --#endif - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - case FFI_TYPE_UINT16: -@@ -887,9 +882,7 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) - case FFI_TYPE_VOID: - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: --#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE - case FFI_TYPE_LONGDOUBLE: --#endif - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - case FFI_TYPE_UINT16: -@@ -1040,14 +1033,12 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, - case FFI_TYPE_POINTER: - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: -- case FFI_TYPE_FLOAT: -- case FFI_TYPE_DOUBLE: --#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE -- case FFI_TYPE_LONGDOUBLE: -+ case FFI_TYPE_FLOAT: -+ case FFI_TYPE_DOUBLE: -+ case FFI_TYPE_LONGDOUBLE: - avalue[i] = allocate_to_register_or_stack (context, stack, - &state, ty->type); - break; --#endif - - case FFI_TYPE_STRUCT: - h = is_hfa (ty); -@@ -1106,13 +1097,11 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, - break; - } - --#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE - case FFI_TYPE_LONGDOUBLE: - memcpy (&avalue[i], - allocate_to_v (context, &state), - sizeof (*avalue)); - break; --#endif - - default: - FFI_ASSERT (0); -@@ -1183,9 +1172,7 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, - case FFI_TYPE_SINT64: - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: --#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE - case FFI_TYPE_LONGDOUBLE: --#endif - { - void *addr = get_basic_type_addr (cif->rtype->type, context, 0); - copy_basic_type (addr, rvalue, cif->rtype->type); --- -2.7.4.huawei.3 - diff --git a/0055-aarch64-Simplify-AARCH64_STACK_ALIGN.patch b/0055-aarch64-Simplify-AARCH64_STACK_ALIGN.patch deleted file mode 100644 index 5e8c4b36af14162c5dc5cf2c9ed189b671eaf47d..0000000000000000000000000000000000000000 --- a/0055-aarch64-Simplify-AARCH64_STACK_ALIGN.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 77c4cddca6aeb6e545e21f235e29323e05f5a3a3 Mon Sep 17 00:00:00 2001 -From: Richard Henderson -Date: Tue, 21 Oct 2014 13:30:40 -0400 -Subject: [PATCH 055/415] aarch64: Simplify AARCH64_STACK_ALIGN - -The iOS abi doesn't require padding between arguments, but -that's not what AARCH64_STACK_ALIGN meant. The hardware will -in fact trap if the SP register is not 16 byte aligned. ---- - src/aarch64/ffi.c | 10 +--------- - 1 file changed, 1 insertion(+), 9 deletions(-) - -diff --git a/src/aarch64/ffi.c b/src/aarch64/ffi.c -index f065be5..a6fcc11 100644 ---- a/src/aarch64/ffi.c -+++ b/src/aarch64/ffi.c -@@ -35,13 +35,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - # define FFI_TYPE_LONGDOUBLE 4 - #endif - --/* Stack alignment requirement in bytes */ --#if defined (__APPLE__) --#define AARCH64_STACK_ALIGN 1 --#else --#define AARCH64_STACK_ALIGN 16 --#endif -- - #define N_X_ARG_REG 8 - #define N_V_ARG_REG 8 - -@@ -799,8 +792,7 @@ ffi_status - ffi_prep_cif_machdep (ffi_cif *cif) - { - /* Round the stack up to a multiple of the stack alignment requirement. */ -- cif->bytes = -- (cif->bytes + (AARCH64_STACK_ALIGN - 1)) & ~ (AARCH64_STACK_ALIGN - 1); -+ cif->bytes = ALIGN(cif->bytes, 16); - - /* Initialize our flags. We are interested if this CIF will touch a - vector register, if so we will enable context save and load to --- -2.7.4.huawei.3 - diff --git a/0056-aarch64-Reduce-the-size-of-register_context.patch b/0056-aarch64-Reduce-the-size-of-register_context.patch deleted file mode 100644 index 4247da6ba16f1f88b91b4632f3258c72a44290ec..0000000000000000000000000000000000000000 --- a/0056-aarch64-Reduce-the-size-of-register_context.patch +++ /dev/null @@ -1,346 +0,0 @@ -From 95a04af134431ccc8230aca1641541a5e8fcbdc9 Mon Sep 17 00:00:00 2001 -From: Richard Henderson -Date: Tue, 21 Oct 2014 22:41:07 -0400 -Subject: [PATCH 056/415] aarch64: Reduce the size of register_context - -We don't need to store 32 general and vector registers. -Only 8 of each are used for parameter passing. ---- - src/aarch64/ffi.c | 35 ++++++++--------- - src/aarch64/ffitarget.h | 6 --- - src/aarch64/internal.h | 26 +++++++++++++ - src/aarch64/sysv.S | 100 +++++++++++++++++++++++------------------------- - 4 files changed, 91 insertions(+), 76 deletions(-) - create mode 100644 src/aarch64/internal.h - -diff --git a/src/aarch64/ffi.c b/src/aarch64/ffi.c -index a6fcc11..58d088b 100644 ---- a/src/aarch64/ffi.c -+++ b/src/aarch64/ffi.c -@@ -21,8 +21,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - - #include - #include -+#include - #include - #include -+#include "internal.h" - - /* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE; - all further uses in this file will refer to the 128-bit type. */ -@@ -35,38 +37,35 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - # define FFI_TYPE_LONGDOUBLE 4 - #endif - --#define N_X_ARG_REG 8 --#define N_V_ARG_REG 8 -- --#define AARCH64_FFI_WITH_V (1 << AARCH64_FFI_WITH_V_BIT) -- - union _d - { - UINT64 d; - UINT32 s[2]; - }; - -+struct _v -+{ -+ union _d d[2] __attribute__((aligned(16))); -+}; -+ - struct call_context - { -- UINT64 x [AARCH64_N_XREG]; -- struct -- { -- union _d d[2]; -- } v [AARCH64_N_VREG]; -+ struct _v v[N_V_ARG_REG]; -+ UINT64 x[N_X_ARG_REG]; -+ UINT64 x8; - }; - - #if defined (__clang__) && defined (__APPLE__) --extern void --sys_icache_invalidate (void *start, size_t len); -+extern void sys_icache_invalidate (void *start, size_t len); - #endif - - static inline void - ffi_clear_cache (void *start, void *end) - { - #if defined (__clang__) && defined (__APPLE__) -- sys_icache_invalidate (start, (char *)end - (char *)start); -+ sys_icache_invalidate (start, (char *)end - (char *)start); - #elif defined (__GNUC__) -- __builtin___clear_cache (start, end); -+ __builtin___clear_cache (start, end); - #else - #error "Missing builtin to flush instruction cache" - #endif -@@ -802,7 +801,7 @@ ffi_prep_cif_machdep (ffi_cif *cif) - - if (is_v_register_candidate (cif->rtype)) - { -- cif->aarch64_flags |= AARCH64_FFI_WITH_V; -+ cif->aarch64_flags |= AARCH64_FLAG_ARG_V; - } - else - { -@@ -810,7 +809,7 @@ ffi_prep_cif_machdep (ffi_cif *cif) - for (i = 0; i < cif->nargs; i++) - if (is_v_register_candidate (cif->arg_types[i])) - { -- cif->aarch64_flags |= AARCH64_FFI_WITH_V; -+ cif->aarch64_flags |= AARCH64_FLAG_ARG_V; - break; - } - } -@@ -924,7 +923,7 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) - } - else - { -- memcpy (get_x_addr (&context, 8), &rvalue, sizeof (UINT64)); -+ context.x8 = (uintptr_t)rvalue; - ffi_call_SYSV (aarch64_prep_args, &context, &ecif, - stack_bytes, fn); - } -@@ -1201,7 +1200,7 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, - } - else - { -- memcpy (&rvalue, get_x_addr (context, 8), sizeof (UINT64)); -+ rvalue = (void *)(uintptr_t)context->x8; - (closure->fun) (cif, rvalue, avalue, closure->user_data); - } - } -diff --git a/src/aarch64/ffitarget.h b/src/aarch64/ffitarget.h -index 4bbced2..336f28a 100644 ---- a/src/aarch64/ffitarget.h -+++ b/src/aarch64/ffitarget.h -@@ -54,10 +54,4 @@ typedef enum ffi_abi - #define FFI_EXTRA_CIF_FIELDS unsigned aarch64_flags - #endif - --#define AARCH64_FFI_WITH_V_BIT 0 -- --#define AARCH64_N_XREG 32 --#define AARCH64_N_VREG 32 --#define AARCH64_CALL_CONTEXT_SIZE (AARCH64_N_XREG * 8 + AARCH64_N_VREG * 16) -- - #endif -diff --git a/src/aarch64/internal.h b/src/aarch64/internal.h -new file mode 100644 -index 0000000..b6b6104 ---- /dev/null -+++ b/src/aarch64/internal.h -@@ -0,0 +1,26 @@ -+/* -+Permission is hereby granted, free of charge, to any person obtaining -+a copy of this software and associated documentation files (the -+``Software''), to deal in the Software without restriction, including -+without limitation the rights to use, copy, modify, merge, publish, -+distribute, sublicense, and/or sell copies of the Software, and to -+permit persons to whom the Software is furnished to do so, subject to -+the following conditions: -+ -+The above copyright notice and this permission notice shall be -+included in all copies or substantial portions of the Software. -+ -+THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, -+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -+ -+#define AARCH64_FLAG_ARG_V_BIT 0 -+#define AARCH64_FLAG_ARG_V (1 << AARCH64_FLAG_ARG_V_BIT) -+ -+#define N_X_ARG_REG 8 -+#define N_V_ARG_REG 8 -+#define CALL_CONTEXT_SIZE (N_V_ARG_REG * 16 + N_X_ARG_REG * 8 + 16) -diff --git a/src/aarch64/sysv.S b/src/aarch64/sysv.S -index 169eab8..70870db 100644 ---- a/src/aarch64/sysv.S -+++ b/src/aarch64/sysv.S -@@ -22,6 +22,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - #define LIBFFI_ASM - #include - #include -+#include "internal.h" - - #ifdef HAVE_MACHINE_ASM_H - #include -@@ -43,13 +44,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - #define cfi_def_cfa_register(reg) .cfi_def_cfa_register reg - - .text -+ .align 2 -+ - .globl CNAME(ffi_call_SYSV) - #ifdef __ELF__ - .type CNAME(ffi_call_SYSV), #function - #endif --#ifdef __APPLE__ -- .align 2 --#endif - - /* ffi_call_SYSV() - -@@ -142,42 +142,40 @@ CNAME(ffi_call_SYSV): - mov x23, x0 - - /* Figure out if we should touch the vector registers. */ -- tbz x23, #AARCH64_FFI_WITH_V_BIT, 1f -+ tbz x23, #AARCH64_FLAG_ARG_V_BIT, 1f - - /* Load the vector argument passing registers. */ -- ldp q0, q1, [x21, #8*32 + 0] -- ldp q2, q3, [x21, #8*32 + 32] -- ldp q4, q5, [x21, #8*32 + 64] -- ldp q6, q7, [x21, #8*32 + 96] -+ ldp q0, q1, [x21, #0] -+ ldp q2, q3, [x21, #32] -+ ldp q4, q5, [x21, #64] -+ ldp q6, q7, [x21, #96] - 1: -- /* Load the core argument passing registers. */ -- ldp x0, x1, [x21, #0] -- ldp x2, x3, [x21, #16] -- ldp x4, x5, [x21, #32] -- ldp x6, x7, [x21, #48] -- -- /* Don't forget x8 which may be holding the address of a return buffer. -- */ -- ldr x8, [x21, #8*8] -+ /* Load the core argument passing registers, including -+ the structure return pointer. */ -+ ldp x0, x1, [x21, #16*N_V_ARG_REG + 0] -+ ldp x2, x3, [x21, #16*N_V_ARG_REG + 16] -+ ldp x4, x5, [x21, #16*N_V_ARG_REG + 32] -+ ldp x6, x7, [x21, #16*N_V_ARG_REG + 48] -+ ldr x8, [x21, #16*N_V_ARG_REG + 64] - - blr x24 - - /* Save the core argument passing registers. */ -- stp x0, x1, [x21, #0] -- stp x2, x3, [x21, #16] -- stp x4, x5, [x21, #32] -- stp x6, x7, [x21, #48] -+ stp x0, x1, [x21, #16*N_V_ARG_REG + 0] -+ stp x2, x3, [x21, #16*N_V_ARG_REG + 16] -+ stp x4, x5, [x21, #16*N_V_ARG_REG + 32] -+ stp x6, x7, [x21, #16*N_V_ARG_REG + 48] - - /* Note nothing useful ever comes back in x8! */ - - /* Figure out if we should touch the vector registers. */ -- tbz x23, #AARCH64_FFI_WITH_V_BIT, 1f -+ tbz x23, #AARCH64_FLAG_ARG_V_BIT, 1f - - /* Save the vector argument passing registers. */ -- stp q0, q1, [x21, #8*32 + 0] -- stp q2, q3, [x21, #8*32 + 32] -- stp q4, q5, [x21, #8*32 + 64] -- stp q6, q7, [x21, #8*32 + 96] -+ stp q0, q1, [x21, #0] -+ stp q2, q3, [x21, #32] -+ stp q4, q5, [x21, #64] -+ stp q6, q7, [x21, #96] - 1: - /* All done, unwind our stack frame. */ - ldp x21, x22, [x29, # - ffi_call_SYSV_FS] -@@ -203,7 +201,7 @@ CNAME(ffi_call_SYSV): - .size CNAME(ffi_call_SYSV), .-CNAME(ffi_call_SYSV) - #endif - --#define ffi_closure_SYSV_FS (8 * 2 + AARCH64_CALL_CONTEXT_SIZE) -+#define ffi_closure_SYSV_FS (8 * 2 + CALL_CONTEXT_SIZE) - - /* ffi_closure_SYSV - -@@ -243,10 +241,9 @@ CNAME(ffi_call_SYSV): - Voila! */ - - .text -- .globl CNAME(ffi_closure_SYSV) --#ifdef __APPLE__ - .align 2 --#endif -+ -+ .globl CNAME(ffi_closure_SYSV) - .cfi_startproc - CNAME(ffi_closure_SYSV): - stp x29, x30, [sp, #-16]! -@@ -268,24 +265,23 @@ CNAME(ffi_closure_SYSV): - /* Preserve our struct trampoline_data * */ - mov x22, x17 - -- /* Save the rest of the argument passing registers. */ -- stp x0, x1, [x21, #0] -- stp x2, x3, [x21, #16] -- stp x4, x5, [x21, #32] -- stp x6, x7, [x21, #48] -- /* Don't forget we may have been given a result scratch pad address. -- */ -- str x8, [x21, #64] -+ /* Save the rest of the argument passing registers, including -+ the structure return pointer. */ -+ stp x0, x1, [x21, #16*N_V_ARG_REG + 0] -+ stp x2, x3, [x21, #16*N_V_ARG_REG + 16] -+ stp x4, x5, [x21, #16*N_V_ARG_REG + 32] -+ stp x6, x7, [x21, #16*N_V_ARG_REG + 48] -+ str x8, [x21, #16*N_V_ARG_REG + 64] - - /* Figure out if we should touch the vector registers. */ - ldr x0, [x22, #8] -- tbz x0, #AARCH64_FFI_WITH_V_BIT, 1f -+ tbz x0, #AARCH64_FLAG_ARG_V_BIT, 1f - - /* Save the argument passing vector registers. */ -- stp q0, q1, [x21, #8*32 + 0] -- stp q2, q3, [x21, #8*32 + 32] -- stp q4, q5, [x21, #8*32 + 64] -- stp q6, q7, [x21, #8*32 + 96] -+ stp q0, q1, [x21, #0] -+ stp q2, q3, [x21, #32] -+ stp q4, q5, [x21, #64] -+ stp q6, q7, [x21, #96] - 1: - /* Load &ffi_closure.. */ - ldr x0, [x22, #0] -@@ -298,19 +294,19 @@ CNAME(ffi_closure_SYSV): - - /* Figure out if we should touch the vector registers. */ - ldr x0, [x22, #8] -- tbz x0, #AARCH64_FFI_WITH_V_BIT, 1f -+ tbz x0, #AARCH64_FLAG_ARG_V_BIT, 1f - - /* Load the result passing vector registers. */ -- ldp q0, q1, [x21, #8*32 + 0] -- ldp q2, q3, [x21, #8*32 + 32] -- ldp q4, q5, [x21, #8*32 + 64] -- ldp q6, q7, [x21, #8*32 + 96] -+ ldp q0, q1, [x21, #0] -+ ldp q2, q3, [x21, #32] -+ ldp q4, q5, [x21, #64] -+ ldp q6, q7, [x21, #96] - 1: - /* Load the result passing core registers. */ -- ldp x0, x1, [x21, #0] -- ldp x2, x3, [x21, #16] -- ldp x4, x5, [x21, #32] -- ldp x6, x7, [x21, #48] -+ ldp x0, x1, [x21, #16*N_V_ARG_REG + 0] -+ ldp x2, x3, [x21, #16*N_V_ARG_REG + 16] -+ ldp x4, x5, [x21, #16*N_V_ARG_REG + 32] -+ ldp x6, x7, [x21, #16*N_V_ARG_REG + 48] - /* Note nothing useful is returned in x8. */ - - /* We are done, unwind our frame. */ --- -2.7.4.huawei.3 - diff --git a/0058-aarch64-Treat-void-return-as-not-passed-in-registers.patch b/0058-aarch64-Treat-void-return-as-not-passed-in-registers.patch deleted file mode 100644 index 096414b57a65a186edfb0af01328df4884538285..0000000000000000000000000000000000000000 --- a/0058-aarch64-Treat-void-return-as-not-passed-in-registers.patch +++ /dev/null @@ -1,25 +0,0 @@ -From b55e03665ddf2423df9baee0d3172892ba781c26 Mon Sep 17 00:00:00 2001 -From: Richard Henderson -Date: Wed, 22 Oct 2014 12:33:59 -0400 -Subject: [PATCH 058/415] aarch64: Treat void return as not passed in registers - -This lets us do less post-processing when there's no return value. ---- - src/aarch64/ffi.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/aarch64/ffi.c b/src/aarch64/ffi.c -index 58d088b..6c338e1 100644 ---- a/src/aarch64/ffi.c -+++ b/src/aarch64/ffi.c -@@ -383,6 +383,7 @@ is_register_candidate (ffi_type *ty) - switch (ty->type) - { - case FFI_TYPE_VOID: -+ return 0; - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - case FFI_TYPE_LONGDOUBLE: --- -2.7.4.huawei.3 - diff --git a/0059-aarch64-Tidy-up-abi-manipulation.patch b/0059-aarch64-Tidy-up-abi-manipulation.patch deleted file mode 100644 index da34c98040a1c183f2ba903fbbef302173477e12..0000000000000000000000000000000000000000 --- a/0059-aarch64-Tidy-up-abi-manipulation.patch +++ /dev/null @@ -1,1162 +0,0 @@ -From 8c8161cb623585d5d0c783b9d494b9b74ada6ced Mon Sep 17 00:00:00 2001 -From: Richard Henderson -Date: Wed, 22 Oct 2014 12:52:07 -0400 -Subject: [PATCH 059/415] aarch64: Tidy up abi manipulation - -Avoid false abstraction, like get_x_addr. Avoid recomputing data -about the type being manipulated. Use NEON insns for HFA manipulation. - -Note that some of the inline assembly will go away in a subsequent patch. ---- - src/aarch64/ffi.c | 932 +++++++++++++++++++++--------------------------------- - 1 file changed, 367 insertions(+), 565 deletions(-) - -diff --git a/src/aarch64/ffi.c b/src/aarch64/ffi.c -index 6c338e1..d19384b 100644 ---- a/src/aarch64/ffi.c -+++ b/src/aarch64/ffi.c -@@ -71,152 +71,6 @@ ffi_clear_cache (void *start, void *end) - #endif - } - --static void * --get_x_addr (struct call_context *context, unsigned n) --{ -- return &context->x[n]; --} -- --static void * --get_s_addr (struct call_context *context, unsigned n) --{ --#if defined __AARCH64EB__ -- return &context->v[n].d[1].s[1]; --#else -- return &context->v[n].d[0].s[0]; --#endif --} -- --static void * --get_d_addr (struct call_context *context, unsigned n) --{ --#if defined __AARCH64EB__ -- return &context->v[n].d[1]; --#else -- return &context->v[n].d[0]; --#endif --} -- --static void * --get_v_addr (struct call_context *context, unsigned n) --{ -- return &context->v[n]; --} -- --/* Return the memory location at which a basic type would reside -- were it to have been stored in register n. */ -- --static void * --get_basic_type_addr (unsigned short type, struct call_context *context, -- unsigned n) --{ -- switch (type) -- { -- case FFI_TYPE_FLOAT: -- return get_s_addr (context, n); -- case FFI_TYPE_DOUBLE: -- return get_d_addr (context, n); -- case FFI_TYPE_LONGDOUBLE: -- return get_v_addr (context, n); -- case FFI_TYPE_UINT8: -- case FFI_TYPE_SINT8: -- case FFI_TYPE_UINT16: -- case FFI_TYPE_SINT16: -- case FFI_TYPE_UINT32: -- case FFI_TYPE_SINT32: -- case FFI_TYPE_INT: -- case FFI_TYPE_POINTER: -- case FFI_TYPE_UINT64: -- case FFI_TYPE_SINT64: -- return get_x_addr (context, n); -- case FFI_TYPE_VOID: -- return NULL; -- default: -- FFI_ASSERT (0); -- return NULL; -- } --} -- --/* Return the alignment width for each of the basic types. */ -- --static size_t --get_basic_type_alignment (unsigned short type) --{ -- switch (type) -- { -- case FFI_TYPE_FLOAT: --#if defined (__APPLE__) -- return sizeof (UINT32); --#endif -- case FFI_TYPE_DOUBLE: -- return sizeof (UINT64); -- case FFI_TYPE_LONGDOUBLE: -- return sizeof (long double); -- case FFI_TYPE_UINT8: -- case FFI_TYPE_SINT8: --#if defined (__APPLE__) -- return sizeof (UINT8); --#endif -- case FFI_TYPE_UINT16: -- case FFI_TYPE_SINT16: --#if defined (__APPLE__) -- return sizeof (UINT16); --#endif -- case FFI_TYPE_UINT32: -- case FFI_TYPE_INT: -- case FFI_TYPE_SINT32: --#if defined (__APPLE__) -- return sizeof (UINT32); --#endif -- case FFI_TYPE_POINTER: -- case FFI_TYPE_UINT64: -- case FFI_TYPE_SINT64: -- return sizeof (UINT64); -- -- default: -- FFI_ASSERT (0); -- return 0; -- } --} -- --/* Return the size in bytes for each of the basic types. */ -- --static size_t --get_basic_type_size (unsigned short type) --{ -- switch (type) -- { -- case FFI_TYPE_FLOAT: -- return sizeof (UINT32); -- case FFI_TYPE_DOUBLE: -- return sizeof (UINT64); -- case FFI_TYPE_LONGDOUBLE: -- return sizeof (long double); -- case FFI_TYPE_UINT8: -- return sizeof (UINT8); -- case FFI_TYPE_SINT8: -- return sizeof (SINT8); -- case FFI_TYPE_UINT16: -- return sizeof (UINT16); -- case FFI_TYPE_SINT16: -- return sizeof (SINT16); -- case FFI_TYPE_UINT32: -- return sizeof (UINT32); -- case FFI_TYPE_INT: -- case FFI_TYPE_SINT32: -- return sizeof (SINT32); -- case FFI_TYPE_POINTER: -- case FFI_TYPE_UINT64: -- return sizeof (UINT64); -- case FFI_TYPE_SINT64: -- return sizeof (SINT64); -- -- default: -- FFI_ASSERT (0); -- return 0; -- } --} -- - extern void - ffi_call_SYSV (unsigned (*)(struct call_context *context, unsigned char *, - extended_cif *), -@@ -468,223 +322,211 @@ arg_init (struct arg_state *state, size_t call_frame_size) - #endif - } - --/* Return the number of available consecutive core argument -- registers. */ -- --static unsigned --available_x (struct arg_state *state) --{ -- return N_X_ARG_REG - state->ngrn; --} -- --/* Return the number of available consecutive vector argument -- registers. */ -- --static unsigned --available_v (struct arg_state *state) --{ -- return N_V_ARG_REG - state->nsrn; --} -- --static void * --allocate_to_x (struct call_context *context, struct arg_state *state) --{ -- FFI_ASSERT (state->ngrn < N_X_ARG_REG); -- return get_x_addr (context, (state->ngrn)++); --} -- --static void * --allocate_to_s (struct call_context *context, struct arg_state *state) --{ -- FFI_ASSERT (state->nsrn < N_V_ARG_REG); -- return get_s_addr (context, (state->nsrn)++); --} -- --static void * --allocate_to_d (struct call_context *context, struct arg_state *state) --{ -- FFI_ASSERT (state->nsrn < N_V_ARG_REG); -- return get_d_addr (context, (state->nsrn)++); --} -- --static void * --allocate_to_v (struct call_context *context, struct arg_state *state) --{ -- FFI_ASSERT (state->nsrn < N_V_ARG_REG); -- return get_v_addr (context, (state->nsrn)++); --} -- - /* Allocate an aligned slot on the stack and return a pointer to it. */ - static void * --allocate_to_stack (struct arg_state *state, void *stack, size_t alignment, -- size_t size) -+allocate_to_stack (struct arg_state *state, void *stack, -+ size_t alignment, size_t size) - { -- void *allocation; -+ size_t nsaa = state->nsaa; - - /* Round up the NSAA to the larger of 8 or the natural - alignment of the argument's type. */ -- state->nsaa = ALIGN (state->nsaa, alignment); -- state->nsaa = ALIGN (state->nsaa, alignment); - #if defined (__APPLE__) -- if (state->allocating_variadic) -- state->nsaa = ALIGN (state->nsaa, 8); -+ if (state->allocating_variadic && alignment < 8) -+ alignment = 8; - #else -- state->nsaa = ALIGN (state->nsaa, 8); -+ if (alignment < 8) -+ alignment = 8; - #endif -+ -+ nsaa = ALIGN (nsaa, alignment); -+ state->nsaa = nsaa + size; - -- allocation = stack + state->nsaa; -- -- state->nsaa += size; -- return allocation; -+ return (char *)stack + nsaa; - } - --static void --copy_basic_type (void *dest, void *source, unsigned short type) -+static ffi_arg -+extend_integer_type (void *source, int type) - { -- /* This is necessary to ensure that basic types are copied -- sign extended to 64-bits as libffi expects. */ - switch (type) - { -- case FFI_TYPE_FLOAT: -- *(float *) dest = *(float *) source; -- break; -- case FFI_TYPE_DOUBLE: -- *(double *) dest = *(double *) source; -- break; -- case FFI_TYPE_LONGDOUBLE: -- *(long double *) dest = *(long double *) source; -- break; - case FFI_TYPE_UINT8: -- *(ffi_arg *) dest = *(UINT8 *) source; -- break; -+ return *(UINT8 *) source; - case FFI_TYPE_SINT8: -- *(ffi_sarg *) dest = *(SINT8 *) source; -- break; -+ return *(SINT8 *) source; - case FFI_TYPE_UINT16: -- *(ffi_arg *) dest = *(UINT16 *) source; -- break; -+ return *(UINT16 *) source; - case FFI_TYPE_SINT16: -- *(ffi_sarg *) dest = *(SINT16 *) source; -- break; -+ return *(SINT16 *) source; - case FFI_TYPE_UINT32: -- *(ffi_arg *) dest = *(UINT32 *) source; -- break; -+ return *(UINT32 *) source; - case FFI_TYPE_INT: - case FFI_TYPE_SINT32: -- *(ffi_sarg *) dest = *(SINT32 *) source; -- break; -- case FFI_TYPE_POINTER: -+ return *(SINT32 *) source; - case FFI_TYPE_UINT64: -- *(ffi_arg *) dest = *(UINT64 *) source; -- break; - case FFI_TYPE_SINT64: -- *(ffi_sarg *) dest = *(SINT64 *) source; -- break; -- case FFI_TYPE_VOID: -+ return *(UINT64 *) source; - break; -- -+ case FFI_TYPE_POINTER: -+ return *(uintptr_t *) source; - default: -- FFI_ASSERT (0); -+ abort(); - } - } - - static void --copy_hfa_to_reg_or_stack (void *memory, -- ffi_type *ty, -- struct call_context *context, -- unsigned char *stack, -- struct arg_state *state) --{ -- int h = is_hfa (ty); -- int type = h & 0xff; -- unsigned elems = h >> 8; -- -- if (available_v (state) < elems) -- { -- /* There are insufficient V registers. Further V register allocations -- are prevented, the NSAA is adjusted (by allocate_to_stack ()) -- and the argument is copied to memory at the adjusted NSAA. */ -- state->nsrn = N_V_ARG_REG; -- memcpy (allocate_to_stack (state, stack, ty->alignment, ty->size), -- memory, -- ty->size); -- } -- else -- { -- int i; -- for (i = 0; i < elems; i++) -- { -- void *reg = allocate_to_v (context, state); -- copy_basic_type (reg, memory, type); -- memory += get_basic_type_size (type); -- } -- } -+extend_hfa_type (void *dest, void *src, int h) -+{ -+ int n = (h >> 8); -+ int t = h & 0xff; -+ int f = (t - FFI_TYPE_FLOAT) * 4 + 4 - n; -+ void *x0; -+ -+ asm volatile ( -+ "adr %0, 0f\n" -+" add %0, %0, %1\n" -+" br %0\n" -+"0: ldp s16, s17, [%3]\n" /* S4 */ -+" ldp s18, s19, [%3, #8]\n" -+" b 4f\n" -+" ldp s16, s17, [%3]\n" /* S3 */ -+" ldr s18, [%3, #8]\n" -+" b 3f\n" -+" ldp s16, s17, [%3]\n" /* S2 */ -+" b 2f\n" -+" nop\n" -+" ldr s16, [%3]\n" /* S1 */ -+" b 1f\n" -+" nop\n" -+" ldp d16, d17, [%3]\n" /* D4 */ -+" ldp d18, d19, [%3, #16]\n" -+" b 4f\n" -+" ldp d16, d17, [%3]\n" /* D3 */ -+" ldr d18, [%3, #16]\n" -+" b 3f\n" -+" ldp d16, d17, [%3]\n" /* D2 */ -+" b 2f\n" -+" nop\n" -+" ldr d16, [%3]\n" /* D1 */ -+" b 1f\n" -+" nop\n" -+" ldp q16, q17, [%3]\n" /* Q4 */ -+" ldp q18, q19, [%3, #16]\n" -+" b 4f\n" -+" ldp q16, q17, [%3]\n" /* Q3 */ -+" ldr q18, [%3, #16]\n" -+" b 3f\n" -+" ldp q16, q17, [%3]\n" /* Q2 */ -+" b 2f\n" -+" nop\n" -+" ldr q16, [%3]\n" /* Q1 */ -+" b 1f\n" -+"4: str q19, [%2, #48]\n" -+"3: str q18, [%2, #32]\n" -+"2: str q17, [%2, #16]\n" -+"1: str q16, [%2]" -+ : "=&r"(x0) -+ : "r"(f * 12), "r"(dest), "r"(src) -+ : "memory", "v16", "v17", "v18", "v19"); - } - --/* Either allocate an appropriate register for the argument type, or if -- none are available, allocate a stack slot and return a pointer -- to the allocated space. */ -- - static void * --allocate_to_register_or_stack (struct call_context *context, -- unsigned char *stack, -- struct arg_state *state, -- unsigned short type) -+compress_hfa_type (void *dest, void *reg, int h) - { -- size_t alignment = get_basic_type_alignment (type); -- size_t size = alignment; -- switch (type) -+ int n = h >> 8; -+ switch (h & 0xff) - { - case FFI_TYPE_FLOAT: -- /* This is the only case for which the allocated stack size -- should not match the alignment of the type. */ -- size = sizeof (UINT32); -- /* Fall through. */ -+ switch (n) -+ { -+ default: -+ if (dest == reg) -+ { -+#ifdef __AARCH64EB__ -+ dest += 12; -+#endif -+ } -+ else -+ *(float *)dest = *(float *)reg; -+ break; -+ case 2: -+ asm("ldp q16, q17, [%1]\n\t" -+ "st2 { v16.s, v17.s }[0], [%0]" -+ : : "r"(dest), "r"(reg) : "memory", "v16", "v17"); -+ break; -+ case 3: -+ asm("ldp q16, q17, [%1]\n\t" -+ "ldr q18, [%1, #32]\n\t" -+ "st3 { v16.s, v17.s, v18.s }[0], [%0]" -+ : : "r"(dest), "r"(reg) : "memory", "v16", "v17", "v18"); -+ break; -+ case 4: -+ asm("ldp q16, q17, [%1]\n\t" -+ "ldp q18, q19, [%1, #32]\n\t" -+ "st4 { v16.s, v17.s, v18.s, v19.s }[0], [%0]" -+ : : "r"(dest), "r"(reg) : "memory", "v16", "v17", "v18", "v19"); -+ break; -+ } -+ break; -+ - case FFI_TYPE_DOUBLE: -- if (state->nsrn < N_V_ARG_REG) -- return allocate_to_d (context, state); -- state->nsrn = N_V_ARG_REG; -+ switch (n) -+ { -+ default: -+ if (dest == reg) -+ { -+#ifdef __AARCH64EB__ -+ dest += 8; -+#endif -+ } -+ else -+ *(double *)dest = *(double *)reg; -+ break; -+ case 2: -+ asm("ldp q16, q17, [%1]\n\t" -+ "st2 { v16.d, v17.d }[0], [%0]" -+ : : "r"(dest), "r"(reg) : "memory", "v16", "v17"); -+ break; -+ case 3: -+ asm("ldp q16, q17, [%1]\n\t" -+ "ldr q18, [%1, #32]\n\t" -+ "st3 { v16.d, v17.d, v18.d }[0], [%0]" -+ : : "r"(dest), "r"(reg) : "memory", "v16", "v17", "v18"); -+ break; -+ case 4: -+ asm("ldp q16, q17, [%1]\n\t" -+ "ldp q18, q19, [%1, #32]\n\t" -+ "st4 { v16.d, v17.d, v18.d, v19.d }[0], [%0]" -+ : : "r"(dest), "r"(reg) : "memory", "v16", "v17", "v18", "v19"); -+ break; -+ } - break; -+ - case FFI_TYPE_LONGDOUBLE: -- if (state->nsrn < N_V_ARG_REG) -- return allocate_to_v (context, state); -- state->nsrn = N_V_ARG_REG; -- break; -- case FFI_TYPE_UINT8: -- case FFI_TYPE_SINT8: -- case FFI_TYPE_UINT16: -- case FFI_TYPE_SINT16: -- case FFI_TYPE_UINT32: -- case FFI_TYPE_SINT32: -- case FFI_TYPE_INT: -- case FFI_TYPE_POINTER: -- case FFI_TYPE_UINT64: -- case FFI_TYPE_SINT64: -- if (state->ngrn < N_X_ARG_REG) -- return allocate_to_x (context, state); -- state->ngrn = N_X_ARG_REG; -+ if (dest != reg) -+ return memcpy (dest, reg, 16 * n); - break; -+ - default: - FFI_ASSERT (0); - } -- -- return allocate_to_stack (state, stack, alignment, size); -+ return dest; - } - --/* Copy a value to an appropriate register, or if none are -- available, to the stack. */ -+/* Either allocate an appropriate register for the argument type, or if -+ none are available, allocate a stack slot and return a pointer -+ to the allocated space. */ - --static void --copy_to_register_or_stack (struct call_context *context, -- unsigned char *stack, -- struct arg_state *state, -- void *value, -- unsigned short type) -+static void * -+allocate_int_to_reg_or_stack (struct call_context *context, -+ struct arg_state *state, -+ void *stack, size_t size) - { -- copy_basic_type ( -- allocate_to_register_or_stack (context, stack, state, type), -- value, -- type); -+ if (state->ngrn < N_X_ARG_REG) -+ return &context->x[state->ngrn++]; -+ -+ state->ngrn = N_X_ARG_REG; -+ return allocate_to_stack (state, stack, size, size); - } - - /* Marshall the arguments from FFI representation to procedure call -@@ -694,15 +536,21 @@ static unsigned - aarch64_prep_args (struct call_context *context, unsigned char *stack, - extended_cif *ecif) - { -- int i; -+ ffi_cif *cif = ecif->cif; -+ void **avalue = ecif->avalue; -+ int i, nargs = cif->nargs; - struct arg_state state; - -- arg_init (&state, ALIGN(ecif->cif->bytes, 16)); -+ arg_init (&state, cif->bytes); - -- for (i = 0; i < ecif->cif->nargs; i++) -+ for (i = 0; i < nargs; i++) - { -- ffi_type *ty = ecif->cif->arg_types[i]; -- switch (ty->type) -+ ffi_type *ty = cif->arg_types[i]; -+ size_t s = ty->size; -+ int h, t = ty->type; -+ void *a = avalue[i]; -+ -+ switch (t) - { - case FFI_TYPE_VOID: - FFI_ASSERT (0); -@@ -710,82 +558,114 @@ aarch64_prep_args (struct call_context *context, unsigned char *stack, - - /* If the argument is a basic type the argument is allocated to an - appropriate register, or if none are available, to the stack. */ -- case FFI_TYPE_FLOAT: -- case FFI_TYPE_DOUBLE: -- case FFI_TYPE_LONGDOUBLE: -+ case FFI_TYPE_INT: - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT16: - case FFI_TYPE_UINT32: -- case FFI_TYPE_INT: - case FFI_TYPE_SINT32: -- case FFI_TYPE_POINTER: - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: -- copy_to_register_or_stack (context, stack, &state, -- ecif->avalue[i], ty->type); -+ case FFI_TYPE_POINTER: -+ do_pointer: -+ { -+ ffi_arg ext = extend_integer_type (a, t); -+ if (state.ngrn < N_X_ARG_REG) -+ context->x[state.ngrn++] = ext; -+ else -+ { -+ void *d = allocate_to_stack (&state, stack, ty->alignment, s); -+ state.ngrn = N_X_ARG_REG; -+ /* Note that the default abi extends each argument -+ to a full 64-bit slot, while the iOS abi allocates -+ only enough space. */ -+#ifdef __APPLE__ -+ memcpy(d, a, s); -+#else -+ *(ffi_arg *)d = ext; -+#endif -+ } -+ } - break; - -- case FFI_TYPE_STRUCT: -- if (is_hfa (ty)) -- { -- copy_hfa_to_reg_or_stack (ecif->avalue[i], ty, context, -- stack, &state); -- } -- else if (ty->size > 16) -- { -- /* If the argument is a composite type that is larger than 16 -- bytes, then the argument has been copied to memory, and -- the argument is replaced by a pointer to the copy. */ -+ case FFI_TYPE_FLOAT: -+ case FFI_TYPE_DOUBLE: -+ case FFI_TYPE_LONGDOUBLE: -+ /* Scalar float is a degenerate case of HFA. */ -+ h = t + 0x100; -+ goto do_hfa; - -- copy_to_register_or_stack (context, stack, &state, -- &(ecif->avalue[i]), FFI_TYPE_POINTER); -- } -- else if (available_x (&state) >= (ty->size + 7) / 8) -- { -- /* If the argument is a composite type and the size in -- double-words is not more than the number of available -- X registers, then the argument is copied into consecutive -- X registers. */ -- int j; -- for (j = 0; j < (ty->size + 7) / 8; j++) -- { -- memcpy (allocate_to_x (context, &state), -- &(((UINT64 *) ecif->avalue[i])[j]), -- sizeof (UINT64)); -+ case FFI_TYPE_STRUCT: -+ { -+ void *dest; -+ int elems; -+ -+ h = is_hfa (ty); -+ if (h) -+ { -+ do_hfa: -+ elems = h >> 8; -+ if (state.nsrn + elems <= N_V_ARG_REG) -+ { -+ dest = &context->v[state.nsrn]; -+ state.nsrn += elems; -+ extend_hfa_type (dest, a, h); -+ break; -+ } -+ state.nsrn = N_V_ARG_REG; -+ dest = allocate_to_stack (&state, stack, ty->alignment, s); -+ } -+ else if (s > 16) -+ { -+ /* If the argument is a composite type that is larger than 16 -+ bytes, then the argument has been copied to memory, and -+ the argument is replaced by a pointer to the copy. */ -+ a = &avalue[i]; -+ t = FFI_TYPE_POINTER; -+ goto do_pointer; -+ } -+ else -+ { -+ size_t n = (s + 7) / 8; -+ if (state.ngrn + n <= N_X_ARG_REG) -+ { -+ /* If the argument is a composite type and the size in -+ double-words is not more than the number of available -+ X registers, then the argument is copied into -+ consecutive X registers. */ -+ dest = &context->x[state.ngrn]; -+ state.ngrn += n; -+ } -+ else -+ { -+ /* Otherwise, there are insufficient X registers. Further -+ X register allocations are prevented, the NSAA is -+ adjusted and the argument is copied to memory at the -+ adjusted NSAA. */ -+ state.ngrn = N_X_ARG_REG; -+ dest = allocate_to_stack (&state, stack, ty->alignment, s); -+ } - } -- } -- else -- { -- /* Otherwise, there are insufficient X registers. Further X -- register allocations are prevented, the NSAA is adjusted -- (by allocate_to_stack ()) and the argument is copied to -- memory at the adjusted NSAA. */ -- state.ngrn = N_X_ARG_REG; -- -- memcpy (allocate_to_stack (&state, stack, ty->alignment, -- ty->size), ecif->avalue[i], ty->size); -+ memcpy (dest, a, s); - } - break; - - default: -- FFI_ASSERT (0); -- break; -+ abort(); - } - - #if defined (__APPLE__) -- if (i + 1 == ecif->cif->aarch64_nfixedargs) -+ if (i + 1 == cif->aarch64_nfixedargs) - { - state.ngrn = N_X_ARG_REG; - state.nsrn = N_V_ARG_REG; -- - state.allocating_variadic = 1; - } - #endif - } - -- return ecif->cif->aarch64_flags; -+ return cif->aarch64_flags; - } - - ffi_status -@@ -846,94 +726,61 @@ void - ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) - { - extended_cif ecif; -- int h; -+ struct call_context context; -+ size_t stack_bytes; -+ int h, t; - - ecif.cif = cif; - ecif.avalue = avalue; - ecif.rvalue = rvalue; - -- switch (cif->abi) -+ stack_bytes = cif->bytes; -+ -+ memset (&context, 0, sizeof (context)); -+ if (is_register_candidate (cif->rtype)) - { -- case FFI_SYSV: -- { -- struct call_context context; -- size_t stack_bytes; -+ ffi_call_SYSV (aarch64_prep_args, &context, &ecif, stack_bytes, fn); - -- /* Figure out the total amount of stack space we need, the -- above call frame space needs to be 16 bytes aligned to -- ensure correct alignment of the first object inserted in -- that space hence the ALIGN applied to cif->bytes.*/ -- stack_bytes = ALIGN(cif->bytes, 16); -+ t = cif->rtype->type; -+ switch (t) -+ { -+ case FFI_TYPE_INT: -+ case FFI_TYPE_UINT8: -+ case FFI_TYPE_SINT8: -+ case FFI_TYPE_UINT16: -+ case FFI_TYPE_SINT16: -+ case FFI_TYPE_UINT32: -+ case FFI_TYPE_SINT32: -+ case FFI_TYPE_POINTER: -+ case FFI_TYPE_UINT64: -+ case FFI_TYPE_SINT64: -+ *(ffi_arg *)rvalue = extend_integer_type (&context.x[0], t); -+ break; - -- memset (&context, 0, sizeof (context)); -- if (is_register_candidate (cif->rtype)) -- { -- ffi_call_SYSV (aarch64_prep_args, &context, &ecif, stack_bytes, fn); -- switch (cif->rtype->type) -- { -- case FFI_TYPE_VOID: -- case FFI_TYPE_FLOAT: -- case FFI_TYPE_DOUBLE: -- case FFI_TYPE_LONGDOUBLE: -- case FFI_TYPE_UINT8: -- case FFI_TYPE_SINT8: -- case FFI_TYPE_UINT16: -- case FFI_TYPE_SINT16: -- case FFI_TYPE_UINT32: -- case FFI_TYPE_SINT32: -- case FFI_TYPE_POINTER: -- case FFI_TYPE_UINT64: -- case FFI_TYPE_INT: -- case FFI_TYPE_SINT64: -- { -- void *addr = get_basic_type_addr (cif->rtype->type, -- &context, 0); -- copy_basic_type (rvalue, addr, cif->rtype->type); -- break; -- } -+ case FFI_TYPE_FLOAT: -+ case FFI_TYPE_DOUBLE: -+ case FFI_TYPE_LONGDOUBLE: -+ compress_hfa_type (rvalue, &context.v[0], 0x100 + t); -+ break; - -- case FFI_TYPE_STRUCT: -- h = is_hfa (cif->rtype); -- if (h) -- { -- int j; -- int type = h & 0xff; -- int elems = h >> 8; -- for (j = 0; j < elems; j++) -- { -- void *reg = get_basic_type_addr (type, &context, j); -- copy_basic_type (rvalue, reg, type); -- rvalue += get_basic_type_size (type); -- } -- } -- else if ((cif->rtype->size + 7) / 8 < N_X_ARG_REG) -- { -- size_t size = ALIGN (cif->rtype->size, sizeof (UINT64)); -- memcpy (rvalue, get_x_addr (&context, 0), size); -- } -- else -- { -- FFI_ASSERT (0); -- } -- break; -- -- default: -- FFI_ASSERT (0); -- break; -- } -- } -- else -- { -- context.x8 = (uintptr_t)rvalue; -- ffi_call_SYSV (aarch64_prep_args, &context, &ecif, -- stack_bytes, fn); -- } -- break; -- } -+ case FFI_TYPE_STRUCT: -+ h = is_hfa (cif->rtype); -+ if (h) -+ compress_hfa_type (rvalue, &context.v[0], h); -+ else if ((cif->rtype->size + 7) / 8 < N_X_ARG_REG) -+ memcpy (rvalue, &context.x[0], cif->rtype->size); -+ else -+ abort(); -+ break; - -- default: -- FFI_ASSERT (0); -- break; -+ default: -+ abort(); -+ } -+ } -+ else -+ { -+ context.x8 = (uintptr_t)rvalue; -+ ffi_call_SYSV (aarch64_prep_args, &context, &ecif, stack_bytes, fn); - } - } - -@@ -1000,203 +847,158 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, - ffi_cif *cif = closure->cif; - void **avalue = (void**) alloca (cif->nargs * sizeof (void*)); - void *rvalue = NULL; -- int i, h; -+ int i, h, nargs = cif->nargs; - struct arg_state state; -+ ffi_type *rtype; - - arg_init (&state, ALIGN(cif->bytes, 16)); - -- for (i = 0; i < cif->nargs; i++) -+ for (i = 0; i < nargs; i++) - { - ffi_type *ty = cif->arg_types[i]; -+ int t = ty->type; -+ size_t n, s = ty->size; - -- switch (ty->type) -+ switch (t) - { - case FFI_TYPE_VOID: - FFI_ASSERT (0); - break; - -+ case FFI_TYPE_INT: - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT16: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: -- case FFI_TYPE_INT: -- case FFI_TYPE_POINTER: - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: -+ case FFI_TYPE_POINTER: -+ avalue[i] = allocate_int_to_reg_or_stack (context, &state, stack, s); -+ break; -+ - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - case FFI_TYPE_LONGDOUBLE: -- avalue[i] = allocate_to_register_or_stack (context, stack, -- &state, ty->type); -- break; -+ /* Scalar float is a degenerate case of HFA. */ -+ h = t + 0x100; -+ goto do_hfa; - - case FFI_TYPE_STRUCT: - h = is_hfa (ty); - if (h) - { -- unsigned n = h >> 8; -- if (available_v (&state) < n) -+ do_hfa: -+ n = h >> 8; -+ if (state.nsrn + n <= N_V_ARG_REG) - { -- state.nsrn = N_V_ARG_REG; -- avalue[i] = allocate_to_stack (&state, stack, ty->alignment, -- ty->size); -+ void *reg = &context->v[state.nsrn]; -+ state.nsrn += n; -+ -+ /* Eeek! We need a pointer to the structure, however the -+ homogeneous float elements are being passed in individual -+ registers, therefore for float and double the structure -+ is not represented as a contiguous sequence of bytes in -+ our saved register context. We don't need the original -+ contents of the register storage, so we reformat the -+ structure into the same memory. */ -+ avalue[i] = compress_hfa_type (reg, reg, h); - } - else - { -- switch (h & 0xff) -- { -- case FFI_TYPE_FLOAT: -- { -- /* Eeek! We need a pointer to the structure, -- however the homogeneous float elements are -- being passed in individual S registers, -- therefore the structure is not represented as -- a contiguous sequence of bytes in our saved -- register context. We need to fake up a copy -- of the structure laid out in memory -- correctly. The fake can be tossed once the -- closure function has returned hence alloca() -- is sufficient. */ -- unsigned j; -- UINT32 *p = avalue[i] = alloca (ty->size); -- for (j = 0; j < n; j++) -- memcpy (&p[j], -- allocate_to_s (context, &state), -- sizeof (*p)); -- break; -- } -- -- case FFI_TYPE_DOUBLE: -- { -- /* Eeek! We need a pointer to the structure, -- however the homogeneous float elements are -- being passed in individual S registers, -- therefore the structure is not represented as -- a contiguous sequence of bytes in our saved -- register context. We need to fake up a copy -- of the structure laid out in memory -- correctly. The fake can be tossed once the -- closure function has returned hence alloca() -- is sufficient. */ -- unsigned j; -- UINT64 *p = avalue[i] = alloca (ty->size); -- for (j = 0; j < n; j++) -- memcpy (&p[j], -- allocate_to_d (context, &state), -- sizeof (*p)); -- break; -- } -- -- case FFI_TYPE_LONGDOUBLE: -- memcpy (&avalue[i], -- allocate_to_v (context, &state), -- sizeof (*avalue)); -- break; -- -- default: -- FFI_ASSERT (0); -- break; -- } -+ state.nsrn = N_V_ARG_REG; -+ avalue[i] = allocate_to_stack (&state, stack, -+ ty->alignment, s); - } - } -- else if (ty->size > 16) -+ else if (s > 16) - { - /* Replace Composite type of size greater than 16 with a - pointer. */ -- memcpy (&avalue[i], -- allocate_to_register_or_stack (context, stack, -- &state, FFI_TYPE_POINTER), -- sizeof (avalue[i])); -- } -- else if (available_x (&state) >= (ty->size + 7) / 8) -- { -- avalue[i] = get_x_addr (context, state.ngrn); -- state.ngrn += (ty->size + 7) / 8; -+ avalue[i] = *(void **) -+ allocate_int_to_reg_or_stack (context, &state, stack, -+ sizeof (void *)); - } - else - { -- state.ngrn = N_X_ARG_REG; -- -- avalue[i] = allocate_to_stack (&state, stack, ty->alignment, -- ty->size); -+ n = (s + 7) / 8; -+ if (state.ngrn + n <= N_X_ARG_REG) -+ { -+ avalue[i] = &context->x[state.ngrn]; -+ state.ngrn += n; -+ } -+ else -+ { -+ state.ngrn = N_X_ARG_REG; -+ avalue[i] = allocate_to_stack (&state, stack, -+ ty->alignment, s); -+ } - } - break; - - default: -- FFI_ASSERT (0); -- break; -+ abort(); - } - } - -- /* Figure out where the return value will be passed, either in -- registers or in a memory block allocated by the caller and passed -- in x8. */ -- -- if (is_register_candidate (cif->rtype)) -+ /* Figure out where the return value will be passed, either in registers -+ or in a memory block allocated by the caller and passed in x8. */ -+ rtype = cif->rtype; -+ if (is_register_candidate (rtype)) - { -+ size_t s = rtype->size; -+ int t; -+ - /* Register candidates are *always* returned in registers. */ - - /* Allocate a scratchpad for the return value, we will let the - callee scrible the result into the scratch pad then move the - contents into the appropriate return value location for the - call convention. */ -- rvalue = alloca (cif->rtype->size); -+ rvalue = alloca (s); - (closure->fun) (cif, rvalue, avalue, closure->user_data); - - /* Copy the return value into the call context so that it is returned - as expected to our caller. */ -- switch (cif->rtype->type) -+ t = rtype->type; -+ switch (t) - { - case FFI_TYPE_VOID: - break; - -+ case FFI_TYPE_INT: - case FFI_TYPE_UINT8: - case FFI_TYPE_UINT16: - case FFI_TYPE_UINT32: -- case FFI_TYPE_POINTER: - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT8: - case FFI_TYPE_SINT16: -- case FFI_TYPE_INT: - case FFI_TYPE_SINT32: - case FFI_TYPE_SINT64: -+ case FFI_TYPE_POINTER: -+ context->x[0] = extend_integer_type (rvalue, t); -+ break; -+ - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - case FFI_TYPE_LONGDOUBLE: -- { -- void *addr = get_basic_type_addr (cif->rtype->type, context, 0); -- copy_basic_type (addr, rvalue, cif->rtype->type); -- break; -- } -+ extend_hfa_type (&context->v[0], rvalue, 0x100 + t); -+ break; -+ - case FFI_TYPE_STRUCT: - h = is_hfa (cif->rtype); - if (h) -- { -- int j; -- int type = h & 0xff; -- int elems = h >> 8; -- for (j = 0; j < elems; j++) -- { -- void *reg = get_basic_type_addr (type, context, j); -- copy_basic_type (reg, rvalue, type); -- rvalue += get_basic_type_size (type); -- } -- } -- else if ((cif->rtype->size + 7) / 8 < N_X_ARG_REG) -- { -- size_t size = ALIGN (cif->rtype->size, sizeof (UINT64)) ; -- memcpy (get_x_addr (context, 0), rvalue, size); -- } -+ extend_hfa_type (&context->v[0], rvalue, h); - else -- { -- FFI_ASSERT (0); -+ { -+ FFI_ASSERT (s <= 16); -+ memcpy (&context->x[0], rvalue, s); - } - break; -+ - default: -- FFI_ASSERT (0); -- break; -+ abort(); - } - } - else --- -2.7.4.huawei.3 - diff --git a/0199-Define-_GNU_SOURCE-on-Linux-for-mremap.patch b/0199-Define-_GNU_SOURCE-on-Linux-for-mremap.patch deleted file mode 100644 index 20185cdbd3f857726f3b7e26f3fe4a50a3f920ce..0000000000000000000000000000000000000000 --- a/0199-Define-_GNU_SOURCE-on-Linux-for-mremap.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 1e82e1cda43dacd8b6ab2d9ac4db33523d86f5dc Mon Sep 17 00:00:00 2001 -From: Berker Peksag -Date: Mon, 7 Mar 2016 18:38:10 +0200 -Subject: [PATCH 199/411] Define _GNU_SOURCE on Linux for mremap() - -This was committed to CPython's libffi copy in -https://bugs.python.org/issue10309 - -mremap() documentation says _GNU_SOURCE needs to -be defined in order to use mremap(): see the -synopsis section at http://linux.die.net/man/2/mremap - -Original commit: https://hg.python.org/cpython/rev/9986fff720a2 - -Original patch was written by Hallvard B Furuseth. ---- - src/dlmalloc.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/src/dlmalloc.c b/src/dlmalloc.c -index 7e4ea83..d63dd36 100644 ---- a/src/dlmalloc.c -+++ b/src/dlmalloc.c -@@ -438,6 +438,11 @@ DEFAULT_MMAP_THRESHOLD default: 256K - - */ - -+#if defined __linux__ && !defined _GNU_SOURCE -+/* mremap() on Linux requires this via sys/mman.h */ -+#define _GNU_SOURCE 1 -+#endif -+ - #ifndef WIN32 - #ifdef _WIN32 - #define WIN32 1 --- -1.8.3.1 - diff --git a/0208-Don-t-dereference-ecif-before-NULL-check.patch b/0208-Don-t-dereference-ecif-before-NULL-check.patch deleted file mode 100644 index db8022575e6734a5b28a9325f5f39fd99a89a53e..0000000000000000000000000000000000000000 --- a/0208-Don-t-dereference-ecif-before-NULL-check.patch +++ /dev/null @@ -1,32 +0,0 @@ -From cf4b2a50413ecb8931eb1a94437497694f189c47 Mon Sep 17 00:00:00 2001 -From: Tom Tromey -Date: Fri, 17 Jun 2016 10:09:44 +0100 -Subject: [PATCH 208/411] Don't dereference "ecif" before NULL check - -Fixes #260 ---- - src/microblaze/ffi.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/microblaze/ffi.c b/src/microblaze/ffi.c -index ea962ea..5733e6e 100644 ---- a/src/microblaze/ffi.c -+++ b/src/microblaze/ffi.c -@@ -46,12 +46,12 @@ void ffi_prep_args(void* stack, extended_cif* ecif) - void** p_argv; - void* stack_args_p = stack; - -- p_argv = ecif->avalue; -- - if (ecif == NULL || ecif->cif == NULL) { - return; /* no description to prepare */ - } - -+ p_argv = ecif->avalue; -+ - if ((ecif->cif->rtype != NULL) && - (ecif->cif->rtype->type == FFI_TYPE_STRUCT)) - { --- -1.8.3.1 - diff --git a/0252-Fix-misaligned-memory-access-in-ffi_call_int.patch b/0252-Fix-misaligned-memory-access-in-ffi_call_int.patch deleted file mode 100644 index 5f0b75f75eacb9314ec3c9a8b49cd4970eedfc36..0000000000000000000000000000000000000000 --- a/0252-Fix-misaligned-memory-access-in-ffi_call_int.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 9c12209d2eac40238eefb4255994277918e7eff1 Mon Sep 17 00:00:00 2001 -From: Francis Ricci -Date: Thu, 3 Aug 2017 10:46:28 -0700 -Subject: [PATCH 252/411] Fix misaligned memory access in ffi_call_int - ---- - src/x86/ffi64.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/x86/ffi64.c b/src/x86/ffi64.c -index 2603a3a..757930b 100644 ---- a/src/x86/ffi64.c -+++ b/src/x86/ffi64.c -@@ -646,10 +646,10 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue, - break; - case X86_64_SSE_CLASS: - case X86_64_SSEDF_CLASS: -- reg_args->sse[ssecount++].i64 = *(UINT64 *) a; -+ memcpy (®_args->sse[ssecount++].i64, a, sizeof(UINT64)); - break; - case X86_64_SSESF_CLASS: -- reg_args->sse[ssecount++].i32 = *(UINT32 *) a; -+ memcpy (®_args->sse[ssecount++].i32, a, sizeof(UINT32)); - break; - default: - abort(); --- -1.8.3.1 - diff --git a/0333-Fully-allocate-file-backing-writable-maps-389.patch b/0333-Fully-allocate-file-backing-writable-maps-389.patch deleted file mode 100644 index 3b07acc02a523d1b175a2b80c456b8e33e347c2e..0000000000000000000000000000000000000000 --- a/0333-Fully-allocate-file-backing-writable-maps-389.patch +++ /dev/null @@ -1,67 +0,0 @@ -From d46406088d28b038a0a0f7396d9621f431482f6a Mon Sep 17 00:00:00 2001 -From: "Ryan C. Underwood" -Date: Sun, 18 Mar 2018 07:00:42 -0700 -Subject: [PATCH 333/411] Fully allocate file backing writable maps (#389) - -When ftruncate() is used on a filesystem supporting sparse files, -space in the file is not actually allocated. Then, when the file -is mmap'd and libffi writes to the mapping, SIGBUS is thrown to -the calling application. Instead, always fully allocate the file -that will back writable maps. ---- - src/closures.c | 32 +++++++++++++++++++++++++++++++- - 1 file changed, 31 insertions(+), 1 deletion(-) - -diff --git a/src/closures.c b/src/closures.c -index 59ce828..15e6e0f 100644 ---- a/src/closures.c -+++ b/src/closures.c -@@ -723,6 +723,36 @@ open_temp_exec_file (void) - return fd; - } - -+/* We need to allocate space in a file that will be backing a writable -+ mapping. Several problems exist with the usual approaches: -+ - fallocate() is Linux-only -+ - posix_fallocate() is not available on all platforms -+ - ftruncate() does not allocate space on filesystems with sparse files -+ Failure to allocate the space will cause SIGBUS to be thrown when -+ the mapping is subsequently written to. */ -+static int -+allocate_space (int fd, off_t offset, off_t len) -+{ -+ static size_t page_size; -+ -+ /* Obtain system page size. */ -+ if (!page_size) -+ page_size = sysconf(_SC_PAGESIZE); -+ -+ unsigned char buf[page_size]; -+ memset (buf, 0, page_size); -+ -+ while (len > 0) -+ { -+ off_t to_write = (len < page_size) ? len : page_size; -+ if (write (fd, buf, to_write) < to_write) -+ return -1; -+ len -= to_write; -+ } -+ -+ return 0; -+} -+ - /* Map in a chunk of memory from the temporary exec file into separate - locations in the virtual memory address space, one writable and one - executable. Returns the address of the writable portion, after -@@ -744,7 +774,7 @@ dlmmap_locked (void *start, size_t length, int prot, int flags, off_t offset) - - offset = execsize; - -- if (ftruncate (execfd, offset + length)) -+ if (allocate_space (execfd, offset, length)) - return MFAIL; - - flags &= ~(MAP_PRIVATE | MAP_ANONYMOUS); --- -1.8.3.1 - diff --git a/ffi-multilib.h b/ffi-multilib.h deleted file mode 100644 index 50a6226d0fd0528912746758d325144742a44f1e..0000000000000000000000000000000000000000 --- a/ffi-multilib.h +++ /dev/null @@ -1,23 +0,0 @@ -/* This file is here to prevent a file conflict on multiarch systems. */ -#ifdef ffi_wrapper_h -#error "Do not define ffi_wrapper_h!" -#endif -#define ffi_wrapper_h - -#if defined(__i386__) -#include "ffi-i386.h" -#elif defined(__powerpc64__) -#include "ffi-ppc64.h" -#elif defined(__powerpc__) -#include "ffi-ppc.h" -#elif defined(__s390x__) -#include "ffi-s390x.h" -#elif defined(__s390__) -#include "ffi-s390.h" -#elif defined(__x86_64__) -#include "ffi-x86_64.h" -#else -#error "The libffi-devel package is not usable with the architecture." -#endif - -#undef ffi_wrapper_h diff --git a/ffitarget-multilib.h b/ffitarget-multilib.h deleted file mode 100644 index b2ed54595809d0a812884ff8ce477550ac51a7a1..0000000000000000000000000000000000000000 --- a/ffitarget-multilib.h +++ /dev/null @@ -1,23 +0,0 @@ -/* This file is here to prevent a file conflict on multiarch systems. */ -#ifdef ffitarget_wrapper_h -#error "Do not define ffitarget_wrapper_h!" -#endif -#define ffitarget_wrapper_h - -#if defined(__i386__) -#include "ffitarget-i386.h" -#elif defined(__powerpc64__) -#include "ffitarget-ppc64.h" -#elif defined(__powerpc__) -#include "ffitarget-ppc.h" -#elif defined(__s390x__) -#include "ffitarget-s390x.h" -#elif defined(__s390__) -#include "ffitarget-s390.h" -#elif defined(__x86_64__) -#include "ffitarget-x86_64.h" -#else -#error "The libffi-devel package is not usable with the architecture." -#endif - -#undef ffitarget_wrapper_h diff --git a/libffi-3.1-aarch64-fix-exec-stack.patch b/libffi-3.1-aarch64-fix-exec-stack.patch deleted file mode 100644 index e20c920723b2fadc5a28c62304273ca188aeddab..0000000000000000000000000000000000000000 --- a/libffi-3.1-aarch64-fix-exec-stack.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/src/aarch64/sysv.S -+++ b/src/aarch64/sysv.S -@@ -396,3 +396,8 @@ - #ifdef __ELF__ - .size CNAME(ffi_closure_SYSV), .-CNAME(ffi_closure_SYSV) - #endif -+ -+#if defined __ELF__ && defined __linux__ -+ .section .note.GNU-stack,"",%progbits -+#endif -+ diff --git a/libffi-3.1-fix-include-path.patch b/libffi-3.1-fix-include-path.patch deleted file mode 100644 index 5a3b7a5317c61107edd37778907a5ec0af8320ec..0000000000000000000000000000000000000000 --- a/libffi-3.1-fix-include-path.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff -up libffi-3.1/libffi.pc.in.fixpath libffi-3.1/libffi.pc.in ---- libffi-3.1/libffi.pc.in.fixpath 2014-04-25 19:45:13.000000000 +0200 -+++ libffi-3.1/libffi.pc.in 2014-06-12 12:06:06.000000000 +0200 -@@ -1,11 +1,10 @@ - prefix=@prefix@ - exec_prefix=@exec_prefix@ - libdir=@libdir@ --toolexeclibdir=@toolexeclibdir@ --includedir=${libdir}/@PACKAGE_NAME@-@PACKAGE_VERSION@/include -+includedir=@includedir@ - - Name: @PACKAGE_NAME@ - Description: Library supporting Foreign Function Interfaces - Version: @PACKAGE_VERSION@ --Libs: -L${toolexeclibdir} -lffi -+Libs: -L${libdir} -lffi - Cflags: -I${includedir} diff --git a/libffi-3.2.1.tar.gz b/libffi-3.2.1.tar.gz deleted file mode 100644 index 5c21bb01242a3a46e538fa54bf32f96f8d3cf85b..0000000000000000000000000000000000000000 Binary files a/libffi-3.2.1.tar.gz and /dev/null differ diff --git a/libffi-3.3.tar.gz b/libffi-3.3.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..fd3a325ee6bdaab020989979e30f4758e4bf2b44 Binary files /dev/null and b/libffi-3.3.tar.gz differ diff --git a/libffi-aarch64-rhbz1174037.patch b/libffi-aarch64-rhbz1174037.patch deleted file mode 100644 index dbf63080ea200fa7b1673913426c43046ff6d5d7..0000000000000000000000000000000000000000 --- a/libffi-aarch64-rhbz1174037.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- libffi-3.1/src/aarch64/ffi.c.orig 2014-04-25 18:45:13.000000000 +0100 -+++ libffi-3.1/src/aarch64/ffi.c 2015-01-15 02:36:56.314906455 +0000 -@@ -728,7 +728,7 @@ - state.ngrn = N_X_ARG_REG; - - memcpy (allocate_to_stack (&state, stack, ty->alignment, -- ty->size), ecif->avalue + i, ty->size); -+ ty->size), ecif->avalue[i], ty->size); - } - break; - diff --git a/libffi.spec b/libffi.spec index 60c2049b411b7526d403fa90669278885f07f362..abc731458e0068a5fa64d44fe7806c995c207be4 100644 --- a/libffi.spec +++ b/libffi.spec @@ -1,30 +1,10 @@ -%global target_arch %{ix86} x86_64 - Name: libffi -Version: 3.2.1 +Version: 3.3 Release: 1 Summary: A Portable Foreign Function Interface Library License: MIT -URL: http://sourceware.org/libffi - +URL: http://sourceware.org/libff Source0: ftp://sourceware.org/pub/libffi/%{name}-%{version}.tar.gz -Source1: ffi-multilib.h -Source2: ffitarget-multilib.h -Patch0: libffi-3.1-fix-include-path.patch -Patch1: libffi-aarch64-rhbz1174037.patch -Patch2: libffi-3.1-aarch64-fix-exec-stack.patch - -Patch6004:0053-aarch64-Improve-is_hfa.patch -Patch6005:0054-aarch64-Always-distinguish-LONGDOUBLE.patch -Patch6006:0055-aarch64-Simplify-AARCH64_STACK_ALIGN.patch -Patch6007:0056-aarch64-Reduce-the-size-of-register_context.patch -Patch6008:0058-aarch64-Treat-void-return-as-not-passed-in-registers.patch -Patch6009:0059-aarch64-Tidy-up-abi-manipulation.patch - -Patch6010:0199-Define-_GNU_SOURCE-on-Linux-for-mremap.patch -Patch6011:0208-Don-t-dereference-ecif-before-NULL-check.patch -Patch6012:0252-Fix-misaligned-memory-access-in-ffi_call_int.patch -Patch6013:0333-Fully-allocate-file-backing-writable-maps-389.patch BuildRequires: gcc @@ -67,35 +47,17 @@ BuildArch: noarch The help package contains man files. %prep -%autosetup -n %{name}-%{version} -p1 +%autosetup -n %{name}-%{version} %build %configure --disable-static -make %{?_smp_mflags} - +%make_build %install -make install DESTDIR=$RPM_BUILD_ROOT -find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';' +%make_install +%delete_la rm -f $RPM_BUILD_ROOT%{_infodir}/dir -base=%{_arch} -%ifarch %{ix86} -base=i386 -%endif - -mkdir -p $RPM_BUILD_ROOT%{_includedir} -%ifarch %{target_arch} -mv $RPM_BUILD_ROOT%{_libdir}/libffi-%{version}/include/ffi.h $RPM_BUILD_ROOT%{_includedir}/ffi-${base}.h -mv $RPM_BUILD_ROOT%{_libdir}/libffi-%{version}/include/ffitarget.h $RPM_BUILD_ROOT%{_includedir}/ffitarget-${base}.h -install -m644 %{SOURCE2} $RPM_BUILD_ROOT%{_includedir}/ffitarget.h -install -m644 %{SOURCE1} $RPM_BUILD_ROOT%{_includedir}/ffi.h -%else -mv $RPM_BUILD_ROOT%{_libdir}/libffi-%{version}/include/{ffi,ffitarget}.h $RPM_BUILD_ROOT%{_includedir} -%endif -rm -rf $RPM_BUILD_ROOT%{_libdir}/libffi-%{version} - - %ldconfig_scriptlets %check @@ -109,10 +71,8 @@ if [ $1 = 0 ] ;then /sbin/install-info --delete --info-dir=%{_infodir} %{_infodir}/libffi.info.gz || : fi - %files %license LICENSE -%doc README %{_libdir}/*.so.* %files devel @@ -125,6 +85,12 @@ fi %{_infodir}/libffi.info.gz %changelog +* Wed Jan 8 2020 chengquan - 3.3-1 +- Type:enhancement +- ID:NA +- SUG:NA +- DESC:update softwre to 3.3 + * Fri Oct 11 2019 hanzhijun - 3.2.1-1 - Type:enhancement - ID:NA