From 0d2960ade23b29ccefceb7f99040c20c491f7245 Mon Sep 17 00:00:00 2001 From: "Node.js GitHub Bot" Date: Sun, 9 Aug 2026 00:31:13 +0000 Subject: [PATCH] deps: update libffi to 3.8.0 --- deps/libffi/ChangeLog | 607 ++++++++++++++++++ deps/libffi/README.md | 22 + deps/libffi/configure | 28 +- deps/libffi/configure.ac | 2 +- deps/libffi/doc/libffi.info | 132 +++- deps/libffi/doc/libffi.pdf | Bin 178018 -> 210793 bytes deps/libffi/doc/libffi.texi | 98 +++ deps/libffi/doc/stamp-vti | 8 +- deps/libffi/doc/version.texi | 8 +- deps/libffi/generate-headers.py | 4 +- deps/libffi/include/ffi.h.in | 12 +- deps/libffi/libffi.map.in | 9 + deps/libffi/libtool-version | 2 +- deps/libffi/src/aarch64/ffi.c | 120 +++- deps/libffi/src/aarch64/ffitarget.h | 4 + deps/libffi/src/debug.c | 3 +- deps/libffi/src/ia64/ia64_flags.h | 11 + deps/libffi/src/ia64/unix.S | 6 + deps/libffi/src/java_raw_api.c | 3 +- deps/libffi/src/pa/ffitarget.h | 9 +- deps/libffi/src/powerpc/darwin_closure.S | 131 ++-- deps/libffi/src/powerpc/ffi_darwin.c | 23 + deps/libffi/src/powerpc/ffi_linux64.c | 137 +++- deps/libffi/src/powerpc/linux64_closure.S | 15 + deps/libffi/src/prep_cif.c | 110 +++- deps/libffi/src/raw_api.c | 8 +- deps/libffi/src/tramp.c | 12 +- deps/libffi/src/x86/ffi.c | 2 +- deps/libffi/src/x86/ffi64.c | 56 +- deps/libffi/src/x86/ffitarget.h | 19 + deps/libffi/src/x86/win64.S | 5 + deps/libffi/src/x86/win64_intel.S | 5 + deps/libffi/testsuite/Makefile.am | 14 +- deps/libffi/testsuite/Makefile.in | 14 +- .../closure_thiscall_fastcall_pop.c | 131 ++++ .../libffi.call/many_large_structs.c | 88 +++ deps/libffi/testsuite/libffi.call/plan_size.c | 77 +++ .../testsuite/libffi.vector/cls_vector.c | 67 ++ deps/libffi/testsuite/libffi.vector/ffitest.h | 1 + .../libffi/testsuite/libffi.vector/vector.exp | 59 ++ deps/libffi/testsuite/libffi.vector/vector.h | 32 + .../libffi.vector/vector_args_spill.c | 85 +++ .../testsuite/libffi.vector/vector_double2.c | 53 ++ .../testsuite/libffi.vector/vector_double4.c | 81 +++ .../libffi.vector/vector_float32x2.c | 53 ++ .../libffi.vector/vector_float32x4.c | 54 ++ .../testsuite/libffi.vector/vector_hva.c | 74 +++ .../testsuite/libffi.vector/vector_int32x4.c | 54 ++ .../testsuite/libffi.vector/vector_validate.c | 103 +++ .../testsuite/libffi.vector/vector_vec3.c | 73 +++ 50 files changed, 2565 insertions(+), 159 deletions(-) create mode 100644 deps/libffi/testsuite/libffi.call/closure_thiscall_fastcall_pop.c create mode 100644 deps/libffi/testsuite/libffi.call/many_large_structs.c create mode 100644 deps/libffi/testsuite/libffi.call/plan_size.c create mode 100644 deps/libffi/testsuite/libffi.vector/cls_vector.c create mode 100644 deps/libffi/testsuite/libffi.vector/ffitest.h create mode 100644 deps/libffi/testsuite/libffi.vector/vector.exp create mode 100644 deps/libffi/testsuite/libffi.vector/vector.h create mode 100644 deps/libffi/testsuite/libffi.vector/vector_args_spill.c create mode 100644 deps/libffi/testsuite/libffi.vector/vector_double2.c create mode 100644 deps/libffi/testsuite/libffi.vector/vector_double4.c create mode 100644 deps/libffi/testsuite/libffi.vector/vector_float32x2.c create mode 100644 deps/libffi/testsuite/libffi.vector/vector_float32x4.c create mode 100644 deps/libffi/testsuite/libffi.vector/vector_hva.c create mode 100644 deps/libffi/testsuite/libffi.vector/vector_int32x4.c create mode 100644 deps/libffi/testsuite/libffi.vector/vector_validate.c create mode 100644 deps/libffi/testsuite/libffi.vector/vector_vec3.c diff --git a/deps/libffi/ChangeLog b/deps/libffi/ChangeLog index 0dde93e6adad..f64d5d5c46ac 100644 --- a/deps/libffi/ChangeLog +++ b/deps/libffi/ChangeLog @@ -1,3 +1,610 @@ +commit 12ffd1f9dc56fcea79d2f742f424301ae668d663 +Author: Anthony Green +Date: Sat Aug 8 18:08:29 2026 -0400 + + README: order 3.8.0 notes by decreasing importance + + Lead with new capabilities (VECTOR types, ffi_call_plan_size, ppc64 + _Complex long double), then correctness fixes by severity, then the + trampoline caching optimization. + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit 8f2a41d9d89dd8ee2c2438f1e2f9cf04aa9a53d4 +Author: Anthony Green +Date: Sat Aug 8 18:05:33 2026 -0400 + + Release 3.8.0 + + Bump version to 3.8.0, soname to libffi.so.8.5.0 (libtool 13:0:5) for the + new public interfaces added this cycle (FFI_TYPE_VECTOR, ffi_call_plan_size), + date the README history section, and update doc/version.texi. + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit d956fe177ccfd4bb91ae7cb3ccaa0f8935a76522 +Author: Anthony Green +Date: Sat Aug 8 17:38:40 2026 -0400 + + testsuite: distribute plan_size.c + + The ffi_call_plan_size test added in #1006 was not listed in EXTRA_DIST, + so it would be omitted from release tarballs (it still runs from a git + checkout, where dejagnu globs *.c). Add it alongside the other plan_*.c + tests. + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit 670a0327b7d1576712a3cad7b9297f59f23d5430 +Author: Anthony Green +Date: Sat Aug 8 17:09:22 2026 -0400 + + README: note i386 BSD small-struct register return + + Follow-up to #1010, which returns small structs in registers on i386 + FreeBSD/OpenBSD but did not update the History section. + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit f744bc303fa4c69f1202ce283b866ebc768e0432 +Merge: abc18be0 5b8fa3fe +Author: Anthony Green +Date: Sat Aug 8 17:09:02 2026 -0400 + + Merge pull request #1010 from DTW-Thalion/x86-bsd-small-struct-return + + x86: return small structs in registers on the BSD i386 targets + +commit abc18be0d9ba9cc37c955b317e63cd52fd0d90ee +Merge: ed742112 5f24e6a0 +Author: Anthony Green +Date: Sat Aug 8 16:57:36 2026 -0400 + + Merge pull request #1006 from rvandermeulen/call-plan-size + + call_plan: add ffi_call_plan_size to report a plan's allocation + +commit ed7421122880e4daff87f1c8623d508a2e2c5c9a +Merge: e43f2548 e6db2d38 +Author: Anthony Green +Date: Sat Aug 8 16:41:24 2026 -0400 + + Merge pull request #1009 from libffi/fix-jumptable-desync-family + + Fix FFI_TYPE_LAST/vector jump-table desyncs on ia64, ppc64 (BE ELFv2), and aarch64 + +commit e6db2d38decee8bf6321472dff5147ad311e639a +Author: Anthony Green +Date: Fri Aug 7 17:00:49 2026 -0400 + + aarch64: reject sub-4-byte vector lanes in HVA classification + + is_vfp_type() maps a homogeneous vector aggregate's lane width onto the + S/D/Q register classes via FFI_TYPE_FLOAT + intlog2(reg_size) - 2, and + encodes the result as an AARCH64_RET_* code. A lane narrower than 4 bytes + (e.g. a struct of two 2-byte vectors, which libffi's own initialize_vector + accepts) yields intlog2(reg_size) < 2, producing a code below + AARCH64_RET_S4. extend_hfa_type() then computes a negative jump-table + offset (h - AARCH64_RET_S4) and branches before its table -- a wild + computed branch during ffi_call argument marshalling. + + Such a type has no short-vector register class under AAPCS64, so reject it + in is_vfp_type() (returning 0 routes it through the generic aggregate + path). Fixing it at the source covers both the argument path + (extend_hfa_type) and the return path. Verified on aarch64 (Fedora under + qemu-aarch64): a call passing such an HVA segfaults before the fix and + returns correctly after it. + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit 159268174ece06f6854c6d1bca1a9b95961f6ae9 +Author: Anthony Green +Date: Fri Aug 7 08:18:51 2026 -0400 + + powerpc64: fix big-endian ELFv2 closure returns of 5/6/7-byte structs + + On big-endian ppc64 ELFv2, ffi_closure_helper_LINUX64 returns the load + codes PPC64_LD_STRUCT_5/6/7 (17/18/19) for closures returning a 5-, 6-, + or 7-byte struct, but linux64_closure.S only defined return jump-table + entries through PPC64_LD_STRUCT_3 (16). The E() macro places each 16-byte + slot with .align 4 (no .org), so codes 17/18/19 fell through into the + .Lmoredouble continuation: the closure loaded FP registers and returned + without writing r3, so the ELFv2 caller read back the computed jump + target -- a libffi code address -- as the struct value (wrong result plus + a code-pointer disclosure). Little-endian ELFv2 is unaffected (those + codes alias PPC_LD_R3/I64); big-endian ELFv1 returns structs by reference + and never emits the codes. + + Add the three missing handlers, loading the struct right-justified into + r3 per the ELFv2 convention. Verified on big-endian ppc64 ELFv2 (Adélie + Linux under qemu-ppc64): testsuite/libffi.closures/cls_{5,6,7}_1_byte.c + abort before the fix and pass after it. + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit 3fdd99b5d2fb4c8f940d82fc4b1e530e743c685b +Author: Anthony Green +Date: Fri Aug 7 06:11:00 2026 -0400 + + ia64: fix return jump-table desync after FFI_TYPE_LAST bump + + The .Lst_table/.Lld_table return-value dispatch tables in unix.S are + indexed by the FFI_IA64_TYPE_SMALL_STRUCT/HFA_* codes, which are + FFI_TYPE_LAST-relative, but the tables hardcoded 20 entries assuming + FFI_TYPE_LAST == FFI_TYPE_COMPLEX (15). The conditional __int128 + support added in 3.6.0 advanced FFI_TYPE_LAST to SINT128 (17), and + FFI_TYPE_VECTOR advanced it to 18, shifting SMALL_STRUCT to 19 -- so a + small-struct return dispatched to the HFA-ldouble handler's 16-byte + stfe store, an out-of-bounds write past rvalue, and HFA returns indexed + off the end of the table entirely. + + Add the missing UINT128/SINT128/VECTOR slots to both tables (pointing at + the existing not-implemented void handler, matching FFI_TYPE_COMPLEX) + and a FFI_TYPE_LAST tripwire, mirroring the pa and win64 guards. + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit 5b8fa3fed84ce17768eeb379f5b81663172482e9 +Author: Todd White +Date: Fri Aug 7 19:40:05 2026 -0400 + + x86: return small structs in registers on the BSD i386 targets + + i386 FreeBSD and OpenBSD return a struct of 1, 2, 4 or 8 bytes in eax and + edx, as Darwin and win32 do. ffi_prep_cif_machdep applied the size test + only under X86_WIN32 and X86_DARWIN, so on these targets it recorded + X86_RET_STRUCTPOP and allocated a return pointer the callee never writes, + and a struct return through ffi_call or through a closure read a value + that was never stored. + + configure.host already maps i?86-*-freebsd* and i?86-*-openbsd* to + TARGET=X86_FREEBSD, and include/ffi.h.in defines that name, so extend the + condition to it. Sizes 3, 6 and 12 continue to be returned in memory. + +commit 5f24e6a05574b1aa74cca77b1ecd6413a8105f62 +Author: Ryan VanderMeulen +Date: Wed Aug 5 11:09:51 2026 -0400 + + call_plan: add ffi_call_plan_size to report a plan's allocation + + ffi_call_plan is opaque, so an embedder that tracks the memory a long-lived + plan holds has no way to ask how big it is. The only options are to hardcode + a guess or to hardcode knowledge of the private struct layout, and both go + stale silently on the next release. + + The x86-64 backend records the byte count in ffi_plan at the point it is + passed to malloc, so the reported value cannot drift from the allocation it + describes; ffi_call_plan_size adds that to the handle and treats a signature + with no fast path as owning nothing beyond it. The generic backend's plan is + a bare handle, so it reports sizeof (struct ffi_call_plan). The counter lives + in ffi_plan rather than in the handle so that only plans that actually own a + move-list pay for it, and plans without one pay nothing. + + Computing the size in the query from cif->nargs instead would duplicate + build_plan's allocation formula in a second place, and would report the wrong + number if the cif were re-prepared with a different argument count after the + plan was built. + + The new symbol gets its own version node rather than joining + LIBFFI_CALL_PLAN_8.4, which shipped in 3.7.0: adding to a released node would + let a binary that needs ffi_call_plan_size look satisfiable against a 3.7.x + library that exports the node without the symbol, turning a clean link error + into a runtime failure. libtool-version is left alone, since rule 2 in that + file defers version updates to immediately before a release. + +commit e43f254881f9010a26c48f595928461c0432c7b4 +Merge: 2fd434cd 04d721cc +Author: Anthony Green +Date: Thu Aug 6 00:40:32 2026 -0400 + + Merge pull request #1008 from libffi/fix-win64-vector-small-struct-flags + + x86: fix Win64 small-struct returns broken by FFI_TYPE_VECTOR + +commit 04d721cc448316dbba5af506be46315efabd80e3 +Author: Anthony Green +Date: Wed Aug 5 22:59:29 2026 -0400 + + x86: fix Win64 small-struct returns broken by FFI_TYPE_VECTOR + + Adding FFI_TYPE_VECTOR (#1000) moved FFI_TYPE_LAST from FFI_TYPE_SINT128 + (17) to FFI_TYPE_VECTOR (18). The Win64 return pseudo-types + + FFI_TYPE_SMALL_STRUCT_1B/2B/4B = FFI_TYPE_LAST + 1..3 + + are FFI_TYPE_LAST-relative, so they shifted from 18/19/20 to 19/20/21. + The win64.S / win64_intel.S return-value dispatch is a computed jump + table indexed by cif->flags (base + flags*8) whose handlers are emitted + contiguously right after FFI_TYPE_SINT128, with no slot for value 18. + Under the sequential E() variant used by the MSVC/ml64 build, the + size-1/2/4 small-struct handlers therefore sat one 8-byte slot below the + flag values ffiw64.c now emits, so small structs returned by value were + written with the wrong width (or fell off the table into abort). This + showed up as 14 execution failures in the "Windows 64-bit Visual C++" CI + job (s55, struct3, struct_by_value_small, struct_return_2H, the small + cls_* / single_entry_structs closures, and bhaible DGTEST 47/53/55). + + Add an FFI_TYPE_VECTOR abort stub between SINT128 and SMALL_STRUCT_1B in + both tables so the jump table stays contiguous and the small-struct + entries realign with their (shifted) code values. Win64 does not marshal + vectors -- ffi_prep_cif_core rejects them since FFI_TARGET_HAS_VECTOR_TYPE + is undefined there -- so the slot is never reached at runtime. + + Also add a pa-style compile-time tripwire to src/x86/ffitarget.h so the + next generic type added bumps FFI_TYPE_LAST and #errors until the win64 + tables are updated in step. 32-bit x86 is unaffected: sysv.S indexes its + store table by the independent X86_RET_* enum, not FFI_TYPE_LAST. + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit 2fd434cd9ada4d3d97b355e62c3ce3a969682230 +Merge: a00279c2 2aa33761 +Author: Anthony Green +Date: Sun Aug 2 10:18:45 2026 -0400 + + Merge pull request #1005 from libffi/tramp-cache-unsupported-verdict + + tramp: cache the static trampoline "unsupported" verdict + +commit 2aa33761c0536339f9f322902b9bb3a981114724 +Merge: 76883c62 a00279c2 +Author: Anthony Green +Date: Sun Aug 2 10:18:33 2026 -0400 + + Merge branch 'master' into tramp-cache-unsupported-verdict + +commit 76883c628a5273f71fb025e75bf1076adae3bb4b +Author: Anthony Green +Date: Sun Aug 2 10:05:22 2026 -0400 + + tramp: cache the static trampoline "unsupported" verdict + + ffi_tramp_init() bailed out with a plain `return 0` when the system page + size exceeds the trampoline code table mapping, without recording the + outcome in tramp_globals.status. Because that early return was the only + failure exit that left status as UNINITIALIZED, every subsequent + ffi_tramp_alloc()/ffi_tramp_is_supported() call re-ran the full + initialization (ffi_tramp_arch(), sysconf(), etc.) instead of + short-circuiting on the cached verdict like the other two failure paths. + + The comparison is between two process-lifetime invariants -- map_size is + a compile-time constant from ffi_tramp_arch(), and page_size is fixed for + the life of the process (and only checked when sysconf() returned a valid + value) -- so it can never flip. Caching FAILED is therefore safe and + matches the intent of the status field. + + Affects hosts with pages larger than the 16K table, in practice 64K-page + aarch64 kernels, where static trampolines are correctly declined but the + decline was recomputed on every closure allocation. No functional change + on 4K/16K-page hosts. + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit a00279c2dc8e191ae5136b46bf6ae0e7a8da5b7a +Author: Anthony Green +Date: Sat Aug 1 07:17:23 2026 -0400 + + Note unreleased development changes in README history + + Add a "Development source only" History block for changes on master + since 3.7.1: FFI_TYPE_VECTOR SIMD support (#1000), powerpc64 _Complex + long double (#1003), and the powerpc Darwin closure fix (#1002). + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit ce77ca107a5cb0d10d5525c9422f0207e6c79ebf +Merge: d257b084 19dbdb53 +Author: Anthony Green +Date: Sat Aug 1 07:09:17 2026 -0400 + + Merge pull request #1000 from edusperoni/feat/vector-types + + Add FFI_TYPE_VECTOR: vector (SIMD) type support with libffi-computed layout + +commit d257b08495e95248f66b7bd50dd106ea19124df9 +Merge: 333d87cf b2170647 +Author: Anthony Green +Date: Tue Jul 28 00:47:29 2026 -0400 + + Merge pull request #1004 from libffi/fix-1002-ppc-darwin-closure + + powerpc: fix Darwin closure returns broken by #951 + +commit b2170647583461f42dc2d9f201211fcafda2429f +Author: Anthony Green +Date: Mon Jul 27 20:08:15 2026 -0400 + + powerpc: fix Darwin closure returns broken by #951 + + PR #951 (840add3b) changed the shared PowerPC closure helper, + ffi_closure_helper_common, to return a small PPC_LD_* jump-table index + instead of the ffi_type*, and rewrote aix_closure.S to consume it -- but + left darwin_closure.S expecting the old ffi_type* and dereferencing it. + With the helper now returning a small integer, ffi_closure_ASM + dereferenced e.g. 0 (PPC_LD_NONE, a void return) as a pointer, faulting + on a load from address 0. This crashed essentially every closure call + -- including every gobject-introspection signal handler -- on 32- and + 64-bit PowerPC Darwin (SIGBUS at ffi_closure_ASM, dar=0; issue #1002). + + Convert darwin_closure.S to the PPC_LD_* convention, mirroring + aix_closure.S: drop the ffi_type* dereference, use the returned index + directly, and reorder the return-value jump table into PPC_LD_* order + (NONE, R3, R3R4, F32, F64, F128, U8, S8, U16, S16, and on ppc64 U32, S32). + + Darwin, unlike AIX, returns small structs by value in registers, which + the existing assembly handles (Lsmallstruct/Lfour/Lstructend). The + helper's return code is a single small integer with no room for + cif->rtype, which that assembly needs, so for a by-value struct return + the helper now stashes cif->rtype in the first parameter-save slot (dead + by return time) and returns a new PPC_LD_STRUCT code; the PPC_LD_STRUCT + fragment recovers it and drives the unchanged struct machinery. By- + reference struct returns still return PPC_LD_NONE. + + Based on the approach in a patch by Sergey Fedorov (@barracuda156); the + jump table here is reordered to the PPC_LD_* layout so that float, + double, long double, sub-word and 64-bit returns also dispatch correctly. + + I have no PowerPC Darwin hardware; the jump-table fragment offsets were + checked by assembling for powerpc and powerpc64, but runtime + confirmation on 10.5/10.6 is still needed. + + Fixes #1002. + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit 333d87cf201ee279c9870fb5ad3e48e3a08aa6e5 +Merge: 46cb2e38 d7cd3a61 +Author: Anthony Green +Date: Mon Jul 27 08:52:34 2026 -0400 + + Merge pull request #1003 from libffi/fix-ppc64le-complex-longdouble + + powerpc64: implement _Complex long double for both IBM-128 and IEEE-128 + +commit d7cd3a6194885c85255c77782a05a153a42b29a5 +Author: Anthony Green +Date: Mon Jul 27 07:06:39 2026 -0400 + + powerpc64: implement _Complex long double for both IBM-128 and IEEE-128 + + Complex support for POWERPC64 ELFv2 (f0ca157, #970) defined + FFI_TARGET_HAS_COMPLEX_TYPE, which flips complex.exp from marking the + libffi.complex suite UNSUPPORTED to running it. _Complex long double + was deliberately deferred with FFI_BAD_TYPEDEF, so ffi_prep_cif failed + and every libffi.complex/*longdouble* test aborted. This was not caught + upstream because an XFAIL entry in the rlgl CI policy masked the FAILs. + + Implement both long double formats: + + - IBM-128 (double-double): each _Complex long double is passed and + returned as four doubles (real hi/lo, imag hi/lo) in f1-f4, with a + GPR shadow doubleword per FPR, and returned as a double homogeneous + aggregate. + + - IEEE binary128: real in v2, imag in v3; each half occupies a vector + register (or a 16-byte-aligned parameter save slot with two GPR + shadow doublewords) and is returned via the vector-homogeneous + small-struct path. + + discover_homogeneous_aggregate now accepts FFI_TYPE_LONGDOUBLE as a + _Complex inner type so struct-of-complex-longdouble is treated as an HFA. + Covers ffi_prep_cif, ffi_prep_args64, and the closure decode/return + paths. + + Fixes #1001. + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit debc00a0114d8530d6d691862028c607aa17dd6a +Author: Anthony Green +Date: Sun Jul 26 07:28:36 2026 -0400 + + Update doc version + +commit 19dbdb53e869e07fbff05c86d634e8c08c9a7f61 +Author: Eduardo Speroni +Date: Tue Jul 21 20:32:24 2026 -0300 + + testsuite: fix vector suite CI failures on gcc and MSVC + + Two fixes for the libffi.vector suite: + + - vector_double4.c: the non-aarch64 branch built its own void_args + array and never read the already-populated args, tripping gcc's + -Wunused-but-set-variable (an excess-errors FAIL on Linux x86-64 + with gcc; clang does not emit this warning). Use args for the + negative argument-passing check instead. + + - vector.exp: the suite only probed FFI_TARGET_HAS_VECTOR_TYPE, but + the tests are written with the GCC/Clang vector extension. On + Windows ARM64 the aarch64 port enables the feature while MSVC + cannot compile __attribute__ ((vector_size)), so every test failed + to build. Add a compile probe and mark the suite unsupported when + the compiler lacks the syntax. + +commit 71a95a2cd433b151b3fcf83a0a830eb9aa38fa3a +Author: Eduardo Speroni +Date: Tue Jul 21 16:44:26 2026 -0300 + + testsuite: add libffi.vector suite for vector (SIMD) types + + Model a new testsuite/libffi.vector/ directory on testsuite/libffi.complex: + vector.exp reuses the same dg/run-many-tests driver and skips every test as + "unsupported" on ports whose headers do not define + FFI_TARGET_HAS_VECTOR_TYPE (libffi_feature_test), so unsupported targets + still compile the gating cleanly. + + Vector types are built with the portable __attribute__((vector_size)) via a + small make_vector_type() helper (vector.h); each test cross-checks the value + returned through ffi against a direct native call. Coverage: + + - vector_float32x4 / vector_float32x2 / vector_double2 / vector_int32x4: + pass and return 8- and 16-byte float, double and integer vectors + (float32x4 is the vec4 shape of libffi/libffi#773); + - vector_args_spill: ten vectors interleaved with int/double scalars, + exhausting the vector argument registers and spilling to the stack; + - vector_vec3: Clang-only ext_vector_type(3), verifying the 12->16 byte + power-of-two padding matches a natively compiled callee (a no-op on + other compilers); + - vector_double4: on AArch64 a 32-byte vector round-trips (by reference / + in memory); elsewhere ffi_prep_cif must return FFI_BAD_TYPEDEF, checked + for both return and argument; + - vector_hva: a struct of two identical vectors (HVA) passes and returns + on both AArch64 (Q-register pair) and x86-64 (SSE struct classification); + - cls_vector: a closure receiving vector arguments and returning a vector; + - vector_validate: heterogeneous lanes, an empty vector, and a non-scalar + lane are each rejected with FFI_BAD_TYPEDEF, and a well-formed vector is + accepted with the computed power-of-two size and min(size,16) alignment. + + The files are added to testsuite/Makefile.am EXTRA_DIST, matching how + libffi.complex is distributed. + + References: libffi/libffi#414, libffi/libffi#773. + +commit 93b274cec912ac2395575a8bd4dfcb527f61599c +Author: Eduardo Speroni +Date: Tue Jul 21 16:32:04 2026 -0300 + + x86-64: marshal vector (SIMD) types per the System V psABI + + Define FFI_TARGET_HAS_VECTOR_TYPE for the SysV x86-64 backend (ffi64.c; + 32-bit x86 and the Windows ffiw64.c backend are excluded) and integrate + FFI_TYPE_VECTOR into the existing psABI classifier without restructuring + it: + + - classify_argument gains a FFI_TYPE_VECTOR case: an 8-byte vector is + one SSE eightbyte (X86_64_SSE_CLASS); a 16-byte vector is one %xmm + register (X86_64_SSE_CLASS + X86_64_SSEUP_CLASS). The existing + INTEGERSI/SSESF/SSEDF/UINT128 handling is untouched, and the SSE+SSEUP + argument marshalling already merges both eightbytes into one %xmm. + - ffi_prep_cif_machdep classifies vector returns symmetrically: 8 bytes + in %xmm0 (UNIX64_RET_XMM64), 16 bytes in %xmm0 (UNIX64_RET_XMM128). + - Vectors wider than 16 bytes return FFI_BAD_TYPEDEF from + ffi_prep_cif_machdep, for both returns and arguments. Correct + %ymm/%zmm passing needs unix64.S register-save changes and is left as + a v1 limitation rather than silently passing them in memory. + + Closures need no separate change: the closure paths reuse + classify_argument for arguments and cif->flags for the return. + + References: libffi/libffi#414. + +commit 5eaa8a389de61fc3b056f62c48ceade1931b5413 +Author: Eduardo Speroni +Date: Tue Jul 21 16:30:12 2026 -0300 + + aarch64: marshal vector (SIMD) types per AAPCS64 + + Define FFI_TARGET_HAS_VECTOR_TYPE for AArch64 and teach is_vfp_type to + classify FFI_TYPE_VECTOR, so ffi_call and closures pass and return + vectors the way AAPCS64 (and current GCC/Clang) do: + + - 8- and 16-byte vectors travel in a single V/Q register (a Short + Vector), for float, double and integer lane types alike; + - homogeneous vector aggregates -- a struct of up to four identical + 8- or 16-byte vectors -- travel in that many consecutive V/Q + registers (an HVA), e.g. struct{float32x4 a,b} in {q0,q1}; + - a bare vector wider than 16 bytes (e.g. a 32-byte double4) has no + short-vector register class, so is_vfp_type returns 0 and the + existing composite path passes it by invisible reference and returns + it in memory -- exactly what a natively compiled callee expects. + + is_simd() reports the width of one Neon register slot (a bare vector's + whole size, or one lane vector of an HVA); is_vfp_type() encodes + num_registers slots of that width onto the existing AARCH64_RET_{D,Q}* + codes via intlog2. is_hfa0/is_hfa1 recurse through FFI_TYPE_VECTOR so + HVA homogeneity is checked, and the three fundamental-type dispatch + switches (machdep return, ffi_call_int, ffi_closure_SYSV_inner) route + FFI_TYPE_VECTOR through is_vfp_type alongside FFI_TYPE_STRUCT. + + Ported from the battle-tested NativeScript aarch64 vector marshaller, + adapted to the FFI_TYPE_VECTOR API and extended so that integer-lane + vectors (e.g. int32x4) are classified into V registers too -- the + original only handled floating-point lanes. + + References: libffi/libffi#414, libffi/libffi#773 (aarch64 vec4 return). + +commit b6b8be54acc90f7db1dcf3d1c91238a5a9bca185 +Author: Eduardo Speroni +Date: Tue Jul 21 16:26:33 2026 -0300 + + core: add FFI_TYPE_VECTOR fundamental type with computed layout + + Introduce a portable API for marshalling vector (SIMD) types -- the + values produced by GCC's __attribute__((vector_size)) and Clang's + ext_vector_type. This answers the stalled PR #414 and the maintainer's + 2018 design questions + (https://sourceware.org/legacy-ml/libffi-discuss/2018/msg00020.html): + rather than requiring callers to hand-compute a vector's size and + alignment (and gating the feature behind configure), libffi now derives + the layout itself and the type code is defined unconditionally. + + A vector is described exactly like a struct: type == FFI_TYPE_VECTOR and + a NULL-terminated elements[] array, except every element must point to + the SAME fundamental scalar (float, double, or a fixed-width integer + UINT8..SINT64) and the count is the number of lanes. The caller leaves + size and alignment at zero; ffi_prep_cif computes: + + size = lane_size * count, rounded up to the next power of two + (matches Clang ext_vector_type storage: 3 x float -> 16, + 3 x double -> 32; GCC vector_size already requires pow2 + totals so it is identical there); + alignment = min(size, 16). + + Validation (identical scalar lanes, count >= 1, scalar-only) yields + FFI_BAD_TYPEDEF otherwise. + + - include/ffi.h.in: FFI_TYPE_VECTOR = 18 (after SINT128 = 17), + FFI_TYPE_LAST bumped. Defined unconditionally, no configure gating. + - src/prep_cif.c: initialize_vector() computes the layout in + initialize_aggregate; ffi_type_contains_vector() rejects vectors + (including nested in structs, argument or return) with + FFI_BAD_TYPEDEF on any port that does not define + FFI_TARGET_HAS_VECTOR_TYPE -- no aborts. Vector returns reserve the + hidden return-pointer slot like structs. + - src/raw_api.c, src/java_raw_api.c: plumb FFI_TYPE_VECTOR alongside + FFI_TYPE_STRUCT, mirroring how FFI_TYPE_COMPLEX is handled. + - src/debug.c: ffi_type_test requires elements != NULL for vectors. + - src/pa/ffitarget.h: bump the FFI_PA_TYPE_LAST tripwire; PA gates + vectors out in prep_cif so its jump tables are never reached. + - doc/libffi.texi: new "Vector Types" node documenting the API, the + computed-layout rule, the psABI framing, and the per-port support + table. + + No port defines FFI_TARGET_HAS_VECTOR_TYPE yet, so this commit rejects + every vector signature; the per-architecture ports follow. + + References: libffi/libffi#414, libffi/libffi#773. + +commit 46cb2e3871059f7f5113329ddcca818de3a8cfae +Merge: ca86812c 8cd11a77 +Author: Anthony Green +Date: Fri Jul 10 16:51:18 2026 -0400 + + Merge pull request #998 from bgilbert/tests + + testsuite: Remember to distribute tests added for 3.7.1 + +commit 8cd11a772d8a0b687f43390697baa002ae6504d5 +Author: Benjamin Gilbert +Date: Fri Jul 10 11:56:55 2026 -0700 + + testsuite: Remember to distribute tests added for 3.7.1 + +commit ca86812cd430cff3018e491ba75a4f3c9ea969d2 +Author: Anthony Green +Date: Fri Jul 10 10:56:47 2026 -0400 + + ci: Don't publish rlgl reports on tag pushes + + A tag and its commit fire two CI runs at the same SHA. Both run the + publish-reports job, which deploys a fixed-name github-pages artifact + via actions/deploy-pages; the two deployments collide and one fails + with BlobNotFound (seen on the v3.7.1 tag run). The same-SHA branch + push already publishes the reports, so gate the job off tag pushes. + + Co-Authored-By: Claude Fable 5 + commit 5c1c43091ed611fdea774374355eb938c73a9157 Author: Anthony Green Date: Fri Jul 10 09:50:53 2026 -0400 diff --git a/deps/libffi/README.md b/deps/libffi/README.md index 19f78f632b0c..797d0fd9aa8e 100644 --- a/deps/libffi/README.md +++ b/deps/libffi/README.md @@ -201,6 +201,28 @@ History See the git log for details at http://github.com/libffi/libffi. + 3.8.0 August-8-2026 + Add FFI_TYPE_VECTOR (SIMD) type support with libffi-computed + layout, for aarch64 and x86-64 (#1000, closes #773). + Add ffi_call_plan_size to report the total memory a reusable call + plan owns, for embedders that account for the memory held by + long-lived plans. + Add powerpc64 ELFv2 _Complex long double support for both + IBM-128 (double-double) and IEEE-128 formats (#1003, closes #1001). + Fix powerpc64 big-endian ELFv2 closures returning 5-, 6-, or + 7-byte structs: missing return jump-table entries produced a + wrong result and leaked a libffi code pointer. + Fix ia64 return-value jump-table desync after the FFI_TYPE_LAST + bump, which corrupted small-struct and HFA returns. + Fix powerpc Darwin closure returns broken by #951 (#1002). + Return small (1, 2, 4 or 8 byte) structs in registers on the i386 + FreeBSD and OpenBSD targets, matching the platform ABI and + fixing a segfault on struct returns through ffi_call and closures. + Cache the static trampoline "unsupported" result on hosts whose + page size exceeds the trampoline table mapping, avoiding + redundant re-initialization on every closure allocation + (e.g. 64K-page aarch64). + 3.7.1 July-10-2026 Fix aarch64 ffi_call memory corruption when passing many large structs by value. diff --git a/deps/libffi/configure b/deps/libffi/configure index e050ddc8675d..7b8a4cb375d1 100755 --- a/deps/libffi/configure +++ b/deps/libffi/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for libffi 3.7.1. +# Generated by GNU Autoconf 2.71 for libffi 3.8.0. # # Report bugs to . # @@ -621,8 +621,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libffi' PACKAGE_TARNAME='libffi' -PACKAGE_VERSION='3.7.1' -PACKAGE_STRING='libffi 3.7.1' +PACKAGE_VERSION='3.8.0' +PACKAGE_STRING='libffi 3.8.0' PACKAGE_BUGREPORT='http://github.com/libffi/libffi/issues' PACKAGE_URL='' @@ -1417,7 +1417,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libffi 3.7.1 to adapt to many kinds of systems. +\`configure' configures libffi 3.8.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1489,7 +1489,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libffi 3.7.1:";; + short | recursive ) echo "Configuration of libffi 3.8.0:";; esac cat <<\_ACEOF @@ -1628,7 +1628,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libffi configure 3.7.1 +libffi configure 3.8.0 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -2259,7 +2259,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libffi $as_me 3.7.1, which was +It was created by libffi $as_me 3.8.0, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -3233,10 +3233,10 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers fficonfig.h" -FFI_VERSION_STRING="3.7.1" -ffi_version_major=`echo "3.7.1" | cut -d. -f1` -ffi_version_minor=`echo "3.7.1" | cut -d. -f2 | sed 's/[^0-9].*//'` -ffi_version_micro=`echo "3.7.1" | cut -d. -f3 | sed 's/[^0-9].*//'` +FFI_VERSION_STRING="3.8.0" +ffi_version_major=`echo "3.8.0" | cut -d. -f1` +ffi_version_minor=`echo "3.8.0" | cut -d. -f2 | sed 's/[^0-9].*//'` +ffi_version_micro=`echo "3.8.0" | cut -d. -f3 | sed 's/[^0-9].*//'` FFI_VERSION_NUMBER=`expr ${ffi_version_major:-0} \* 10000 + ${ffi_version_minor:-0} \* 100 + ${ffi_version_micro:-0}` @@ -3986,7 +3986,7 @@ fi # Define the identity of the package. PACKAGE='libffi' - VERSION='3.7.1' + VERSION='3.8.0' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -20661,7 +20661,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libffi $as_me 3.7.1, which was +This file was extended by libffi $as_me 3.8.0, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -20729,7 +20729,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -libffi config.status 3.7.1 +libffi config.status 3.8.0 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/deps/libffi/configure.ac b/deps/libffi/configure.ac index 3370acc3a396..826b453b8353 100644 --- a/deps/libffi/configure.ac +++ b/deps/libffi/configure.ac @@ -2,7 +2,7 @@ dnl Process this with autoconf to create configure AC_PREREQ([2.68]) -AC_INIT([libffi],[3.7.1],[http://github.com/libffi/libffi/issues]) +AC_INIT([libffi],[3.8.0],[http://github.com/libffi/libffi/issues]) AC_CONFIG_HEADERS([fficonfig.h]) dnl Derive the version macros from AC_INIT so they cannot drift when the diff --git a/deps/libffi/doc/libffi.info b/deps/libffi/doc/libffi.info index b43246f8ed4e..4c1abc85f777 100644 --- a/deps/libffi/doc/libffi.info +++ b/deps/libffi/doc/libffi.info @@ -301,6 +301,7 @@ File: libffi.info, Node: Types, Next: Multiple ABIs, Prev: Simple Example, U * Type Example:: Structure type example. * Complex:: Complex types. * Complex Type Example:: Complex type example. +* Vector Types:: Vector (SIMD) types.  File: libffi.info, Node: Primitive Types, Next: Structures, Up: Types @@ -660,7 +661,7 @@ functions ‘ffi_prep_cif’ and ‘ffi_prep_args’ abort the program if they encounter a complex type.  -File: libffi.info, Node: Complex Type Example, Prev: Complex, Up: Types +File: libffi.info, Node: Complex Type Example, Next: Vector Types, Prev: Complex, Up: Types 2.3.7 Complex Type Example -------------------------- @@ -746,6 +747,92 @@ compilers that support them: The new type descriptors can then be used like one of the built-in type descriptors in the previous example. + +File: libffi.info, Node: Vector Types, Prev: Complex Type Example, Up: Types + +2.3.8 Vector Types +------------------ + +‘libffi’ can marshal vector (SIMD) types -- the values produced by GCC's +‘__attribute__((vector_size (N)))’ and Clang's ‘ext_vector_type’ -- on +the platforms listed in the support table below. A vector is described +just like a structure, except that every element pointer refers to the +_same_ fundamental scalar type and the number of elements is the number +of vector lanes. + + -- Data type: ffi_type + ‘size_t size’ + This must be set to ‘0’. ‘libffi’ computes the storage size + (see below) from the element type and lane count. + + ‘unsigned short alignment’ + This must be set to ‘0’. ‘libffi’ computes the alignment. + + ‘unsigned short type’ + For a vector type, this must be set to ‘FFI_TYPE_VECTOR’. + + ‘ffi_type **elements’ + This is a ‘NULL’-terminated array of pointers to ‘ffi_type’ + objects. Every entry must point to the same scalar element + type, and the number of entries is the vector's lane count N + (N >= 1). The element type must be one of ‘ffi_type_float’, + ‘ffi_type_double’, or a fixed-width integer (‘ffi_type_uint8’ + through ‘ffi_type_sint64’); ‘long double’ and aggregate + element types are not permitted. + +Computed layout +............... + +Because the caller leaves ‘size’ and ‘alignment’ at ‘0’, ‘libffi’ +derives them so that applications need not encode compiler- or +platform-specific rules: + + • ‘size’ is lane\_size \times N rounded _up_ to the next power of + two. This matches Clang's ‘ext_vector_type’ storage -- for example + a three-lane ‘float’ vector occupies 16 bytes and a three-lane + ‘double’ vector occupies 32 bytes. GCC's ‘vector_size’ already + requires power-of-two byte totals, so the rule is identical there. + + • ‘alignment’ is ‘min(size, 16)’. + + If the element list is heterogeneous, empty, or uses a disallowed +element type, ‘ffi_prep_cif’ returns ‘FFI_BAD_TYPEDEF’. + +psABI framing +............. + +At the call boundary the platform's processor-specific ABI (AAPCS64 on +AArch64, the System V x86-64 psABI on x86-64) decides how a vector is +passed and returned, independently of which compiler produced it. The +historical divergence between GCC's ‘vector_size’ and Clang's +‘ext_vector_type’ concerns only in-memory _layout_ (notably the padding +of odd-lane vectors such as ‘float3’); the power-of-two size rule above +pins that layout down, so a value marshalled by ‘libffi’ matches what a +natively compiled caller or callee expects. + +Per-port support +................ + +Port Vector support +-------------------------------------------------------------------------- +AArch64 (AAPCS64) 8- and 16-byte vectors in a single V/Q register; + homogeneous vector aggregates (structs of up to + four identical 8- or 16-byte vectors) in + consecutive V/Q registers. A bare vector larger + than 16 bytes (for example a 32-byte ‘double4’) + has no short-vector register class and is passed + and returned in memory, exactly as AAPCS64 and + current compilers do. +x86-64 (System V 8- and 16-byte vectors in an SSE register (‘%xmm0’ +psABI) for returns). A bare vector larger than 16 bytes + needs ‘%ymm’/‘%zmm’ register handling that this + port does not yet implement, so ‘ffi_prep_cif’ + returns ‘FFI_BAD_TYPEDEF’ for it. +Other ports Not supported: ‘ffi_prep_cif’ returns + ‘FFI_BAD_TYPEDEF’ for any signature that mentions + a vector type, including one nested inside a + struct. +  File: libffi.info, Node: Multiple ABIs, Next: Reusable Call Plans, Prev: Types, Up: Using libffi @@ -795,6 +882,14 @@ prepared ‘ffi_cif’. is harmless. The ‘ffi_cif’ the plan was built from is not affected. + -- Function: size_t ffi_call_plan_size (ffi_call_plan *PLAN) + Returns the total number of bytes ‘libffi’ allocated for PLAN, + including any internal argument-placement data it owns. Returns + zero when PLAN is ‘NULL’. The result does not include the + ‘ffi_cif’, which the caller owns. This is intended for embedders + that account for the memory held by long-lived plans and would + otherwise have to guess at the size of an opaque type. +  File: libffi.info, Node: The Closure API, Next: Closure Example, Prev: Reusable Call Plans, Up: Using libffi @@ -1056,6 +1151,7 @@ Index * ffi_call_plan_alloc: Reusable Call Plans. (line 12) * ffi_call_plan_free: Reusable Call Plans. (line 32) * ffi_call_plan_invoke: Reusable Call Plans. (line 22) +* ffi_call_plan_size: Reusable Call Plans. (line 37) * ffi_closure_alloc: The Closure API. (line 19) * ffi_closure_free: The Closure API. (line 26) * FFI_CLOSURES: The Closure API. (line 13) @@ -1075,6 +1171,8 @@ Index * ffi_type <1>: Structures. (line 10) * ffi_type <2>: Complex. (line 15) * ffi_type <3>: Complex. (line 15) +* ffi_type <4>: Vector Types. (line 13) +* ffi_type <5>: Vector Types. (line 13) * ffi_type_complex_double: Primitive Types. (line 82) * ffi_type_complex_float: Primitive Types. (line 79) * ffi_type_complex_longdouble: Primitive Types. (line 85) @@ -1101,6 +1199,7 @@ Index * ffi_type_void: Primitive Types. (line 10) * Foreign Function Interface: Introduction. (line 31) * size_t: The Basics. (line 125) +* size_t <1>: Reusable Call Plans. (line 37) * unsigned int: The Basics. (line 122) * unsigned long: The Basics. (line 117) * void: The Basics. (line 72) @@ -1118,21 +1217,22 @@ Node: Using libffi4569 Node: The Basics5172 Node: Simple Example11346 Node: Types12403 -Node: Primitive Types12914 -Node: Structures15231 -Node: Size and Alignment16342 -Node: Arrays Unions Enums18613 -Node: Type Example21590 -Node: Complex22896 -Node: Complex Type Example24410 -Node: Multiple ABIs27462 -Node: Reusable Call Plans27849 -Node: The Closure API29566 -Node: Closure Example33908 -Node: Thread Safety35552 -Node: Memory Usage36385 -Node: Missing Features37660 -Node: Index38037 +Node: Primitive Types12967 +Node: Structures15284 +Node: Size and Alignment16395 +Node: Arrays Unions Enums18666 +Node: Type Example21643 +Node: Complex22949 +Node: Complex Type Example24463 +Node: Vector Types27536 +Node: Multiple ABIs31575 +Node: Reusable Call Plans31962 +Node: The Closure API34155 +Node: Closure Example38497 +Node: Thread Safety40141 +Node: Memory Usage40974 +Node: Missing Features42249 +Node: Index42626  End Tag Table diff --git a/deps/libffi/doc/libffi.pdf b/deps/libffi/doc/libffi.pdf index 250d34faf71159260bc7d8905a68cd9885767592..75458a8f7d5d231e322b5f49c1af24ca709ae283 100644 GIT binary patch delta 100558 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

FKzd=w=h0 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 diff --git a/deps/libffi/doc/libffi.texi b/deps/libffi/doc/libffi.texi index 251214f890d3..4d2802c5bd97 100644 --- a/deps/libffi/doc/libffi.texi +++ b/deps/libffi/doc/libffi.texi @@ -320,6 +320,7 @@ int main() * Type Example:: Structure type example. * Complex:: Complex types. * Complex Type Example:: Complex type example. +* Vector Types:: Vector (SIMD) types. @end menu @node Primitive Types @@ -802,6 +803,93 @@ FFI_COMPLEX_TYPEDEF(uchar, unsigned char, ffi_type_uint8); The new type descriptors can then be used like one of the built-in type descriptors in the previous example. +@node Vector Types +@subsection Vector Types + +@code{libffi} can marshal vector (SIMD) types --- the values produced +by GCC's @code{__attribute__((vector_size (N)))} and Clang's +@code{ext_vector_type} --- on the platforms listed in the support table +below. A vector is described just like a structure, except that every +element pointer refers to the @emph{same} fundamental scalar type and the +number of elements is the number of vector lanes. + +@tindex ffi_type +@deftp {Data type} ffi_type +@table @code +@item size_t size +This must be set to @code{0}. @code{libffi} computes the storage size +(see below) from the element type and lane count. + +@item unsigned short alignment +This must be set to @code{0}. @code{libffi} computes the alignment. + +@item unsigned short type +For a vector type, this must be set to @code{FFI_TYPE_VECTOR}. + +@item ffi_type **elements +This is a @samp{NULL}-terminated array of pointers to @code{ffi_type} +objects. Every entry must point to the same scalar element type, and the +number of entries is the vector's lane count @math{N} (@math{N >= 1}). The +element type must be one of @code{ffi_type_float}, @code{ffi_type_double}, +or a fixed-width integer (@code{ffi_type_uint8} through +@code{ffi_type_sint64}); @code{long double} and aggregate element types are +not permitted. +@end table +@end deftp + +@subsubheading Computed layout + +Because the caller leaves @code{size} and @code{alignment} at @code{0}, +@code{libffi} derives them so that applications need not encode +compiler- or platform-specific rules: + +@itemize @bullet +@item +@code{size} is @math{lane\_size \times N} rounded @emph{up} to the next +power of two. This matches Clang's @code{ext_vector_type} storage --- for +example a three-lane @code{float} vector occupies 16 bytes and a three-lane +@code{double} vector occupies 32 bytes. GCC's @code{vector_size} already +requires power-of-two byte totals, so the rule is identical there. + +@item +@code{alignment} is @code{min(size, 16)}. +@end itemize + +If the element list is heterogeneous, empty, or uses a disallowed element +type, @code{ffi_prep_cif} returns @code{FFI_BAD_TYPEDEF}. + +@subsubheading psABI framing + +At the call boundary the platform's processor-specific ABI (AAPCS64 on +AArch64, the System V x86-64 psABI on x86-64) decides how a vector is +passed and returned, independently of which compiler produced it. The +historical divergence between GCC's @code{vector_size} and Clang's +@code{ext_vector_type} concerns only in-memory @emph{layout} (notably the +padding of odd-lane vectors such as @code{float3}); the power-of-two size +rule above pins that layout down, so a value marshalled by @code{libffi} +matches what a natively compiled caller or callee expects. + +@subsubheading Per-port support + +@multitable @columnfractions .28 .72 +@headitem Port @tab Vector support +@item AArch64 (AAPCS64) +@tab 8- and 16-byte vectors in a single V/Q register; homogeneous vector +aggregates (structs of up to four identical 8- or 16-byte vectors) in +consecutive V/Q registers. A bare vector larger than 16 bytes (for +example a 32-byte @code{double4}) has no short-vector register class and is +passed and returned in memory, exactly as AAPCS64 and current compilers do. +@item x86-64 (System V psABI) +@tab 8- and 16-byte vectors in an SSE register (@code{%xmm0} for returns). +A bare vector larger than 16 bytes needs @code{%ymm}/@code{%zmm} register +handling that this port does not yet implement, so @code{ffi_prep_cif} +returns @code{FFI_BAD_TYPEDEF} for it. +@item Other ports +@tab Not supported: @code{ffi_prep_cif} returns @code{FFI_BAD_TYPEDEF} for +any signature that mentions a vector type, including one nested inside a +struct. +@end multitable + @node Multiple ABIs @section Multiple ABIs @@ -853,6 +941,16 @@ Releases a plan returned by @code{ffi_call_plan_alloc}. Passing not affected. @end defun +@findex ffi_call_plan_size +@defun size_t ffi_call_plan_size (ffi_call_plan *@var{plan}) +Returns the total number of bytes @code{libffi} allocated for @var{plan}, +including any internal argument-placement data it owns. Returns zero when +@var{plan} is @code{NULL}. The result does not include the +@code{ffi_cif}, which the caller owns. This is intended for embedders that +account for the memory held by long-lived plans and would otherwise have to +guess at the size of an opaque type. +@end defun + @node The Closure API @section The Closure API diff --git a/deps/libffi/doc/stamp-vti b/deps/libffi/doc/stamp-vti index e755454e9c82..dc281e38e0f6 100644 --- a/deps/libffi/doc/stamp-vti +++ b/deps/libffi/doc/stamp-vti @@ -1,4 +1,4 @@ -@set UPDATED 10 July 2026 -@set UPDATED-MONTH July 2026 -@set EDITION 3.7.1 -@set VERSION 3.7.1 +@set UPDATED 8 August 2026 +@set UPDATED-MONTH August 2026 +@set EDITION 3.8.0 +@set VERSION 3.8.0 diff --git a/deps/libffi/doc/version.texi b/deps/libffi/doc/version.texi index e755454e9c82..dc281e38e0f6 100644 --- a/deps/libffi/doc/version.texi +++ b/deps/libffi/doc/version.texi @@ -1,4 +1,4 @@ -@set UPDATED 10 July 2026 -@set UPDATED-MONTH July 2026 -@set EDITION 3.7.1 -@set VERSION 3.7.1 +@set UPDATED 8 August 2026 +@set UPDATED-MONTH August 2026 +@set EDITION 3.8.0 +@set VERSION 3.8.0 diff --git a/deps/libffi/generate-headers.py b/deps/libffi/generate-headers.py index e2d2942deffb..fb58edf17b66 100644 --- a/deps/libffi/generate-headers.py +++ b/deps/libffi/generate-headers.py @@ -7,8 +7,8 @@ from pathlib import Path -LIBFFI_VERSION = '3.7.1' -LIBFFI_VERSION_NUMBER = '30701' +LIBFFI_VERSION = '3.8.0' +LIBFFI_VERSION_NUMBER = '30800' def normalize_arch(target_arch): aliases = { diff --git a/deps/libffi/include/ffi.h.in b/deps/libffi/include/ffi.h.in index 35f09cf43315..cb0a7dbcaaa3 100644 --- a/deps/libffi/include/ffi.h.in +++ b/deps/libffi/include/ffi.h.in @@ -79,9 +79,10 @@ extern "C" { #define FFI_TYPE_COMPLEX 15 #define FFI_TYPE_UINT128 16 #define FFI_TYPE_SINT128 17 +#define FFI_TYPE_VECTOR 18 /* This should always refer to the last type code (for sanity checks). */ -#define FFI_TYPE_LAST FFI_TYPE_SINT128 +#define FFI_TYPE_LAST FFI_TYPE_VECTOR #include @@ -535,7 +536,11 @@ void ffi_call(ffi_cif *cif, ffi_call_plan_alloc returns NULL only on allocation failure; a signature with no fast path is still valid and ffi_call_plan_invoke falls back to ffi_call for it. A plan is immutable once built, so it may be shared and - invoked concurrently from multiple threads. */ + invoked concurrently from multiple threads. + + ffi_call_plan_size reports the total number of bytes libffi allocated for a + plan, so that callers tracking the footprint of long-lived plans do not have + to guess at the size of an opaque type. */ typedef struct ffi_call_plan ffi_call_plan; FFI_API @@ -550,6 +555,9 @@ void ffi_call_plan_invoke (ffi_call_plan *plan, FFI_API void ffi_call_plan_free (ffi_call_plan *plan); +FFI_API +size_t ffi_call_plan_size (ffi_call_plan *plan); + FFI_API ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type, size_t *offsets); diff --git a/deps/libffi/libffi.map.in b/deps/libffi/libffi.map.in index f4e366eb60bc..6151f10cbdce 100644 --- a/deps/libffi/libffi.map.in +++ b/deps/libffi/libffi.map.in @@ -69,6 +69,15 @@ LIBFFI_CALL_PLAN_8.4 { ffi_call_plan_free; } LIBFFI_BASE_8.1; +/* ---------------------------------------------------------------------- + Call plan footprint query (ffi_call_plan_size). A fresh node because + LIBFFI_CALL_PLAN_8.4 has already shipped. + -------------------------------------------------------------------- */ +LIBFFI_CALL_PLAN_8.5 { + global: + ffi_call_plan_size; +} LIBFFI_CALL_PLAN_8.4; + #ifdef FFI_TARGET_HAS_COMPLEX_TYPE LIBFFI_COMPLEX_8.0 { global: diff --git a/deps/libffi/libtool-version b/deps/libffi/libtool-version index c5545eab8bf6..814c6e21d925 100644 --- a/deps/libffi/libtool-version +++ b/deps/libffi/libtool-version @@ -26,4 +26,4 @@ # release, then set age to 0. # # CURRENT:REVISION:AGE -12:1:4 +13:0:5 diff --git a/deps/libffi/src/aarch64/ffi.c b/deps/libffi/src/aarch64/ffi.c index 2e6a2ad2624c..1eb90dd565ad 100644 --- a/deps/libffi/src/aarch64/ffi.c +++ b/deps/libffi/src/aarch64/ffi.c @@ -92,6 +92,19 @@ ffi_clear_cache (void *start, void *end) #endif +/* Return the base-2 logarithm of N (N assumed to be a power of two). Used + to map a vector register width (8 or 16 bytes) onto the D-/Q-register + AARCH64_RET_* encoding. */ + +static int +intlog2 (int n) +{ + int level = 0; + while (n >>= 1) + ++level; + return level; +} + /* 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. */ @@ -106,7 +119,8 @@ 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_VECTOR + || ret == FFI_TYPE_COMPLEX) { ret = is_hfa0 (elements[i]); if (ret < 0) @@ -118,6 +132,33 @@ is_hfa0 (const ffi_type *ty) return ret; } +/* A subroutine of is_vfp_type. Return the size in bytes of the vector (SIMD) + member of TY, i.e. the width of a single Neon register slot, or 0 if TY + neither is nor contains a vector. For a bare vector this is its whole size; + for a homogeneous vector aggregate it is the size of one lane vector. */ + +static size_t +is_simd (const ffi_type *ty) +{ + ffi_type **elements; + int i; + + if (ty->type == FFI_TYPE_VECTOR) + return ty->size; + + elements = ty->elements; + if (elements != NULL) + for (i = 0; elements[i]; ++i) + { + int t = elements[i]->type; + if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX + || t == FFI_TYPE_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. */ @@ -131,7 +172,8 @@ 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_VECTOR + || t == FFI_TYPE_COMPLEX) { if (!is_hfa1 (elements[i], candidate)) return 0; @@ -156,7 +198,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; @@ -181,18 +223,24 @@ is_vfp_type (const ffi_type *ty) } return 0; case FFI_TYPE_STRUCT: + case FFI_TYPE_VECTOR: break; } - /* No HFA types are smaller than 4 bytes, or larger than 64 bytes. */ + /* No HFA/HVA 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. */ + /* Determine the width of the vector (SIMD) member, if any: 0 for a plain + floating-point HFA, else the size in bytes of one Neon register slot. */ + simd_size = is_simd (ty); + + /* Find the type of the first non-aggregate member. */ elements = ty->elements; candidate = elements[0]->type; - if (candidate == FFI_TYPE_STRUCT || candidate == FFI_TYPE_COMPLEX) + if (candidate == FFI_TYPE_STRUCT || candidate == FFI_TYPE_VECTOR + || candidate == FFI_TYPE_COMPLEX) { for (i = 0; ; ++i) { @@ -202,6 +250,63 @@ is_vfp_type (const ffi_type *ty) } } + if (simd_size) + { + /* Vector or homogeneous vector aggregate (HVA). A single Neon slot is + at most 16 bytes (a Q register). A bare vector wider than 16 bytes + (e.g. a 32-byte double4) has no short-vector register class under + AAPCS64, so bail and let the generic composite path pass it by + reference / return it in memory -- matching what current compilers do. + The scalar lane type does not affect register selection (an integer + and a floating-point 16-byte vector both occupy one Q register), so, + unlike the floating-point HFA path below, CANDIDATE is used only to + confirm the lanes are homogeneous. */ + size_t reg_size = simd_size; + int num_registers; + int first_level_element_type; + + /* A Neon register slot is an S (4B), D (8B) or Q (16B). A lane narrower + than 4 bytes has no short-vector register class under AAPCS64 and would + map below AARCH64_RET_S4, making extend_hfa_type() branch before its + jump table; reject it and let the generic aggregate path handle it. */ + if (reg_size < 4 || reg_size > 16 || size % reg_size != 0) + return 0; + num_registers = (int) (size / reg_size); + if (num_registers > 4) + return 0; + + /* For an aggregate, every member must itself be a vector (or nested + vector aggregate) of the same register width: this rejects a struct + that mixes a bare scalar with a vector even when the scalar's type + matches the vector's lane type. A bare vector needs no such check -- + its lanes were validated when its layout was computed. */ + if (ty->type != FFI_TYPE_VECTOR) + for (i = 0; elements[i]; ++i) + if (is_simd (elements[i]) != reg_size) + return 0; + + /* Every lane must be the identical scalar type across the whole HVA + (this rejects, e.g., an aggregate mixing float and integer vectors). */ + for (i = 0; elements[i]; ++i) + { + int t = elements[i]->type; + if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_VECTOR + || t == FFI_TYPE_COMPLEX) + { + if (!is_hfa1 (elements[i], candidate)) + return 0; + } + else if (t != candidate) + return 0; + } + + /* Reuse the AARCH64_RET_{S,D,Q}* codes, which are laid out as + (type * 4) + (4 - count) with FLOAT->S(4B), DOUBLE->D(8B), + LONGDOUBLE->Q(16B). Map the register width onto that type axis. */ + first_level_element_type = FFI_TYPE_FLOAT + intlog2 ((int) reg_size) - 2; + return first_level_element_type * 4 + (4 - num_registers); + } + /* 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) @@ -614,6 +719,7 @@ ffi_prep_cif_machdep (ffi_cif *cif) case FFI_TYPE_DOUBLE: case FFI_TYPE_LONGDOUBLE: case FFI_TYPE_STRUCT: + case FFI_TYPE_VECTOR: case FFI_TYPE_COMPLEX: flags = is_vfp_type (rtype); if (flags == 0) @@ -802,6 +908,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_VECTOR: case FFI_TYPE_COMPLEX: { h = is_vfp_type (ty); @@ -1089,6 +1196,7 @@ ffi_closure_SYSV_inner (ffi_cif *cif, case FFI_TYPE_DOUBLE: case FFI_TYPE_LONGDOUBLE: case FFI_TYPE_STRUCT: + case FFI_TYPE_VECTOR: case FFI_TYPE_COMPLEX: h = is_vfp_type (ty); if (h) diff --git a/deps/libffi/src/aarch64/ffitarget.h b/deps/libffi/src/aarch64/ffitarget.h index 46e2687ae7fe..8ba86799e113 100644 --- a/deps/libffi/src/aarch64/ffitarget.h +++ b/deps/libffi/src/aarch64/ffitarget.h @@ -94,6 +94,10 @@ typedef enum ffi_abi #define FFI_TARGET_HAS_COMPLEX_TYPE #endif +/* AAPCS64 passes 8- and 16-byte vectors in V/Q registers and homogeneous + vector aggregates in consecutive V/Q registers; see is_vfp_type. */ +#define FFI_TARGET_HAS_VECTOR_TYPE + #define FFI_TARGET_HAS_INT128 1 #endif diff --git a/deps/libffi/src/debug.c b/deps/libffi/src/debug.c index 63321dc013cc..cf847f3b1107 100644 --- a/deps/libffi/src/debug.c +++ b/deps/libffi/src/debug.c @@ -54,7 +54,8 @@ void ffi_type_test(ffi_type *a, const char *file, int line) FFI_ASSERT_AT(a->type <= FFI_TYPE_LAST, file, line); FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->size > 0, file, line); FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->alignment > 0, file, line); - FFI_ASSERT_AT((a->type != FFI_TYPE_STRUCT && a->type != FFI_TYPE_COMPLEX) + FFI_ASSERT_AT((a->type != FFI_TYPE_STRUCT && a->type != FFI_TYPE_COMPLEX + && a->type != FFI_TYPE_VECTOR) || a->elements != NULL, file, line); FFI_ASSERT_AT(a->type != FFI_TYPE_COMPLEX || (a->elements != NULL diff --git a/deps/libffi/src/ia64/ia64_flags.h b/deps/libffi/src/ia64/ia64_flags.h index 9d652cef14ce..bfe102c7d86f 100644 --- a/deps/libffi/src/ia64/ia64_flags.h +++ b/deps/libffi/src/ia64/ia64_flags.h @@ -38,3 +38,14 @@ #define FFI_IA64_TYPE_HFA_FLOAT (FFI_TYPE_LAST + 2) #define FFI_IA64_TYPE_HFA_DOUBLE (FFI_TYPE_LAST + 3) #define FFI_IA64_TYPE_HFA_LDOUBLE (FFI_TYPE_LAST + 4) + +/* Tripwire: the .Lst_table / .Lld_table return-value jump tables in unix.S place + the FFI_IA64_TYPE_* pseudo-types (which are FFI_TYPE_LAST-relative) immediately + after the generic FFI_TYPE_* codes. Adding a new generic type bumps + FFI_TYPE_LAST, shifts those codes, and desyncs the tables -- silently + misdispatching small-struct/HFA returns. When this fires: add a matching slot + for the new type to both tables in unix.S, then bump FFI_IA64_TYPE_LAST. */ +#define FFI_IA64_TYPE_LAST FFI_TYPE_VECTOR +#if FFI_TYPE_LAST != FFI_IA64_TYPE_LAST +# error "new FFI_TYPE_* added: sync the unix.S jump tables and bump FFI_IA64_TYPE_LAST" +#endif diff --git a/deps/libffi/src/ia64/unix.S b/deps/libffi/src/ia64/unix.S index 04908368c3e2..b8e347169e2e 100644 --- a/deps/libffi/src/ia64/unix.S +++ b/deps/libffi/src/ia64/unix.S @@ -553,6 +553,9 @@ ffi_closure_unix: data8 @pcrel(.Lst_void) // FFI_TYPE_STRUCT data8 @pcrel(.Lst_int64) // FFI_TYPE_POINTER data8 @pcrel(.Lst_void) // FFI_TYPE_COMPLEX (not implemented) + data8 @pcrel(.Lst_void) // FFI_TYPE_UINT128 (not implemented) + data8 @pcrel(.Lst_void) // FFI_TYPE_SINT128 (not implemented) + data8 @pcrel(.Lst_void) // FFI_TYPE_VECTOR (rejected in ffi_prep_cif_core) data8 @pcrel(.Lst_small_struct) // FFI_IA64_TYPE_SMALL_STRUCT data8 @pcrel(.Lst_hfa_float) // FFI_IA64_TYPE_HFA_FLOAT data8 @pcrel(.Lst_hfa_double) // FFI_IA64_TYPE_HFA_DOUBLE @@ -575,6 +578,9 @@ ffi_closure_unix: data8 @pcrel(.Lld_void) // FFI_TYPE_STRUCT data8 @pcrel(.Lld_int) // FFI_TYPE_POINTER data8 @pcrel(.Lld_void) // FFI_TYPE_COMPLEX (not implemented) + data8 @pcrel(.Lld_void) // FFI_TYPE_UINT128 (not implemented) + data8 @pcrel(.Lld_void) // FFI_TYPE_SINT128 (not implemented) + data8 @pcrel(.Lld_void) // FFI_TYPE_VECTOR (rejected in ffi_prep_cif_core) data8 @pcrel(.Lld_small_struct) // FFI_IA64_TYPE_SMALL_STRUCT data8 @pcrel(.Lld_hfa_float) // FFI_IA64_TYPE_HFA_FLOAT data8 @pcrel(.Lld_hfa_double) // FFI_IA64_TYPE_HFA_DOUBLE diff --git a/deps/libffi/src/java_raw_api.c b/deps/libffi/src/java_raw_api.c index 114d3e47fcde..e0a02ef27432 100644 --- a/deps/libffi/src/java_raw_api.c +++ b/deps/libffi/src/java_raw_api.c @@ -58,7 +58,8 @@ ffi_java_raw_size (ffi_cif *cif) result += 2 * FFI_SIZEOF_JAVA_RAW; break; case FFI_TYPE_STRUCT: - /* No structure parameters in Java. */ + case FFI_TYPE_VECTOR: + /* No structure or vector parameters in Java. */ abort(); case FFI_TYPE_COMPLEX: /* Not supported yet. */ diff --git a/deps/libffi/src/pa/ffitarget.h b/deps/libffi/src/pa/ffitarget.h index f6f09975cfac..aeaacc167ef2 100644 --- a/deps/libffi/src/pa/ffitarget.h +++ b/deps/libffi/src/pa/ffitarget.h @@ -89,8 +89,13 @@ typedef enum ffi_abi { to the default case and is mapped to FFI_TYPE_INT, so cif->flags never exceeds FFI_TYPE_COMPLEX and the existing tables remain sufficient. Bump FFI_PA_TYPE_LAST to the current FFI_TYPE_LAST once you have confirmed any - newly added generic type is likewise handled (or the tables extended). */ -#define FFI_PA_TYPE_LAST FFI_TYPE_SINT128 + newly added generic type is likewise handled (or the tables extended). + + FFI_TYPE_VECTOR (18) is likewise not reached here: PA does not define + FFI_TARGET_HAS_VECTOR_TYPE, so ffi_prep_cif_core rejects any vector + signature with FFI_BAD_TYPEDEF before machdep runs. Bumping the tripwire + past it is therefore safe. */ +#define FFI_PA_TYPE_LAST FFI_TYPE_VECTOR /* Tripwire: when a new generic type is added FFI_TYPE_LAST changes and this fires, forcing a review of ffi_prep_cif_machdep and the linux.S / hpux32.S diff --git a/deps/libffi/src/powerpc/darwin_closure.S b/deps/libffi/src/powerpc/darwin_closure.S index 3121e6ac26d3..08cbe4bc1389 100644 --- a/deps/libffi/src/powerpc/darwin_closure.S +++ b/deps/libffi/src/powerpc/darwin_closure.S @@ -186,19 +186,17 @@ LCFI1: /* Make the call. */ bl BLCLS_HELP - /* r3 contains the rtype pointer... save it since we will need - it later. */ - sg r3,LINKAGE_SIZE(r1) ; ffi_type * result_type - lg r0,0(r3) ; size => r0 - lhz r3,FFI_TYPE_TYPE(r3) ; type => r3 - - /* The helper will have intercepted structure returns and inserted - the caller`s destination address for structs returned by ref. */ - - /* r3 contains the return type so use it to look up in a table - so we know how to deal with each type. */ - - addi r5,r1,(SAVE_SIZE-RESULT_BYTES) /* Otherwise, our return is here. */ + /* r3 now holds a small PPC_LD_* jump-table index (see the PPC_LD_* + defines in ffi_darwin.c), not an ffi_type* as this file previously + assumed: ffi_closure_helper_common cannot return both an ffi_type* + and the dispatch index through r3, so it returns the index. The + helper has already intercepted by-reference struct returns (writing + the result to the caller`s buffer and returning PPC_LD_NONE); for a + by-value struct return it returns PPC_LD_STRUCT and stashes cif->rtype + in the first parameter-save slot, which the PPC_LD_STRUCT fragment + below recovers. */ + + addi r5,r1,(SAVE_SIZE-RESULT_BYTES) /* Our return value is here. */ bl Lget_ret_type0_addr /* Get pointer to Lret_type0 into LR. */ mflr r4 /* Move to r4. */ slwi r3,r3,4 /* Now multiply return type by 16. */ @@ -218,43 +216,60 @@ LFE1: Lget_ret_type0_addr: blrl -/* case FFI_TYPE_VOID */ +/* The fragments below are indexed by the PPC_LD_* return code that + ffi_closure_helper_common handed back in r3, so their order must match the + PPC_LD_* values in ffi_darwin.c. Each is exactly 16 bytes (four + instructions), except the final PPC_LD_STRUCT fragment. */ + +/* case PPC_LD_NONE (void, or a struct returned by reference) */ Lret_type0: b Lfinish nop nop nop -/* case FFI_TYPE_INT */ +/* case PPC_LD_R3 (one GPR: int, pointer, and on ppc64 also 64-bit ints) */ Lret_type1: lg r3,0(r5) b Lfinish nop nop -/* case FFI_TYPE_FLOAT */ +/* case PPC_LD_R3R4 (two GPRs: the 32-bit ABI`s 64-bit integer) */ Lret_type2: +#if defined(__ppc64__) + lg r3,0(r5) + lg r4,8(r5) +#else + lwz r3,0(r5) + lwz r4,4(r5) +#endif + b Lfinish + nop + +/* case PPC_LD_F32 */ +Lret_type3: lfs f1,0(r5) b Lfinish nop nop -/* case FFI_TYPE_DOUBLE */ -Lret_type3: +/* case PPC_LD_F64 */ +Lret_type4: lfd f1,0(r5) b Lfinish nop nop -/* case FFI_TYPE_LONGDOUBLE */ -Lret_type4: +/* case PPC_LD_F128 (128-bit long double: two doubles) */ +Lret_type5: lfd f1,0(r5) lfd f2,8(r5) b Lfinish nop -/* case FFI_TYPE_UINT8 */ -Lret_type5: +/* case PPC_LD_U8 */ +Lret_type6: #if defined(__ppc64__) lbz r3,7(r5) #else @@ -264,8 +279,8 @@ Lret_type5: nop nop -/* case FFI_TYPE_SINT8 */ -Lret_type6: +/* case PPC_LD_S8 */ +Lret_type7: #if defined(__ppc64__) lbz r3,7(r5) #else @@ -275,8 +290,8 @@ Lret_type6: b Lfinish nop -/* case FFI_TYPE_UINT16 */ -Lret_type7: +/* case PPC_LD_U16 */ +Lret_type8: #if defined(__ppc64__) lhz r3,6(r5) #else @@ -286,8 +301,8 @@ Lret_type7: nop nop -/* case FFI_TYPE_SINT16 */ -Lret_type8: +/* case PPC_LD_S16 */ +Lret_type9: #if defined(__ppc64__) lha r3,6(r5) #else @@ -297,77 +312,43 @@ Lret_type8: nop nop -/* case FFI_TYPE_UINT32 */ -Lret_type9: #if defined(__ppc64__) - lwz r3,4(r5) -#else - lwz r3,0(r5) -#endif - b Lfinish - nop - nop - -/* case FFI_TYPE_SINT32 */ +/* case PPC_LD_U32 (ppc64 only; the 32-bit ABI aliases U32 to PPC_LD_R3) */ Lret_type10: -#if defined(__ppc64__) lwz r3,4(r5) -#else - lwz r3,0(r5) -#endif b Lfinish nop nop -/* case FFI_TYPE_UINT64 */ +/* case PPC_LD_S32 (ppc64 only; the 32-bit ABI aliases S32 to PPC_LD_R3) */ Lret_type11: -#if defined(__ppc64__) - lg r3,0(r5) - b Lfinish - nop -#else - lwz r3,0(r5) - lwz r4,4(r5) + lwa r3,4(r5) b Lfinish -#endif nop - -/* case FFI_TYPE_SINT64 */ -Lret_type12: -#if defined(__ppc64__) - lg r3,0(r5) - b Lfinish nop -#else - lwz r3,0(r5) - lwz r4,4(r5) - b Lfinish #endif - nop -/* case FFI_TYPE_STRUCT */ -Lret_type13: +/* case PPC_LD_STRUCT (a by-value struct return). This is the final, + variable-length fragment, so it need not be padded to 16 bytes. The helper + stashed cif->rtype in the first parameter-save slot (see ffi_darwin.c), + because the small dispatch index in r3 left no room for it. */ +Lret_type_struct: + lg r6,PARENT_PARM_BASE(r1) ; cif->rtype + sg r6,LINKAGE_SIZE(r1) ; where the struct code below expects it + lg r0,0(r6) ; size => r0 #if defined(__ppc64__) lg r3,0(r5) ; we need at least this... cmpi 0,r0,4 bgt Lstructend ; not a special small case b Lsmallstruct ; see if we need more. #else - cmpwi 0,r0,4 - bgt Lfinish ; not by value - lg r3,0(r5) + lg r3,0(r5) ; a <=4-byte struct, returned in r3 b Lfinish #endif -/* case FFI_TYPE_POINTER */ -Lret_type14: - lg r3,0(r5) - b Lfinish - nop - nop #if defined(__ppc64__) Lsmallstruct: - beq Lfour ; continuation of Lret13. + beq Lfour ; continuation of Lret_type_struct. cmpi 0,r0,3 beq Lfinish ; don`t adjust this - can`t be any floats here... srdi r3,r3,48 diff --git a/deps/libffi/src/powerpc/ffi_darwin.c b/deps/libffi/src/powerpc/ffi_darwin.c index 01e2a43701d7..64449c38e156 100644 --- a/deps/libffi/src/powerpc/ffi_darwin.c +++ b/deps/libffi/src/powerpc/ffi_darwin.c @@ -60,11 +60,13 @@ struct ffi_aix_trampoline_struct { # define PPC_LD_S32 PPC_LD_R3 # define PPC_LD_PTR PPC_LD_R3 # define PPC_LD_I64 PPC_LD_R3R4 +# define PPC_LD_STRUCT 10 #else # define PPC_LD_U32 10 # define PPC_LD_S32 11 # define PPC_LD_PTR PPC_LD_R3 # define PPC_LD_I64 PPC_LD_R3 +# define PPC_LD_STRUCT 12 #endif extern void ffi_closure_ASM (void); @@ -1260,6 +1262,13 @@ ffi_closure_helper_common (ffi_cif* cif, long i, avn; ffi_dblfl * end_pfr = pfr + NUM_FPR_ARG_REGISTERS; unsigned size_al; + int struct_ret_by_value = 0; + /* When a struct is returned by value, ffi_closure_ASM's jump-table + dispatch carries only a small integer return code (see PPC_LD_* above), + with no room for cif->rtype. We hand cif->rtype back in the first + parameter-save slot -- which is dead by the time we return -- for the + PPC_LD_STRUCT fragment in darwin_closure.S to recover. */ + unsigned long * pgr0 = pgr; #if defined(POWERPC_DARWIN64) unsigned fpsused = 0; #endif @@ -1275,12 +1284,16 @@ ffi_closure_helper_common (ffi_cif* cif, rvalue = (void *) *pgr; pgr++; } + else + struct_ret_by_value = 1; #elif defined(DARWIN_PPC) if (cif->rtype->size > 4) { rvalue = (void *) *pgr; pgr++; } + else + struct_ret_by_value = 1; #else /* assume we return by ref. */ rvalue = (void *) *pgr; pgr++; @@ -1480,7 +1493,17 @@ ffi_closure_helper_common (ffi_cif* cif, switch (cif->rtype->type) { case FFI_TYPE_VOID: + return PPC_LD_NONE; case FFI_TYPE_STRUCT: + /* A by-reference struct return needs nothing further here: the result + was written straight to the caller's buffer. A by-value struct + return is loaded into registers by darwin_closure.S, which needs + cif->rtype -- hand it back in the first parameter-save slot. */ + if (struct_ret_by_value) + { + *pgr0 = (unsigned long) cif->rtype; + return PPC_LD_STRUCT; + } return PPC_LD_NONE; case FFI_TYPE_FLOAT: return PPC_LD_F32; diff --git a/deps/libffi/src/powerpc/ffi_linux64.c b/deps/libffi/src/powerpc/ffi_linux64.c index b1f1468ed5f8..e92f88c46973 100644 --- a/deps/libffi/src/powerpc/ffi_linux64.c +++ b/deps/libffi/src/powerpc/ffi_linux64.c @@ -107,8 +107,13 @@ discover_homogeneous_aggregate (ffi_abi abi, unsigned int inner_elnum = 0; unsigned int inner = discover_homogeneous_aggregate (abi, t->elements[0], &inner_elnum); - if (inner == FFI_TYPE_FLOAT || inner == FFI_TYPE_DOUBLE) + if (inner == FFI_TYPE_FLOAT || inner == FFI_TYPE_DOUBLE + || inner == FFI_TYPE_LONGDOUBLE) { + /* A _Complex of an FP base counts as two of that base: an + FP-HFA struct member. For IBM-128 long double each half is + itself two FPRs (inner_elnum == 2), so a _Complex long double + contributes four FPRs. */ *elnum = 2 * inner_elnum; return inner; } @@ -257,11 +262,17 @@ ffi_prep_cif_linux64_core (ffi_cif *cif) goto homogeneous; #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE case FFI_TYPE_LONGDOUBLE: - /* Only the 64-bit long double case is wired up; IBM-128 and - IEEE-binary128 _Complex are left as a follow-up. */ - if ((cif->abi & (FFI_LINUX_LONG_DOUBLE_128 - | FFI_LINUX_LONG_DOUBLE_IEEE128)) != 0) - return FFI_BAD_TYPEDEF; + if ((cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0) + { + /* IEEE-128 _Complex long double: real in v2, imag in v3. + Return via the vector-homogeneous small-struct path. */ + flags |= FLAG_RETURNS_SMST | FLAG_RETURNS_VEC; + break; + } + /* IBM-128 _Complex long double is returned like a homogeneous + aggregate of doubles: real in f1:f2, imag in f3:f4. (For a + 64-bit long double this reduces to the FFI_TYPE_DOUBLE case, + real in f1 and imag in f2.) */ flags |= FLAG_RETURNS_SMST; rtype = FFI_TYPE_DOUBLE; goto homogeneous; @@ -393,11 +404,21 @@ ffi_prep_cif_linux64_core (ffi_cif *cif) break; #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE case FFI_TYPE_LONGDOUBLE: - if ((cif->abi & (FFI_LINUX_LONG_DOUBLE_128 - | FFI_LINUX_LONG_DOUBLE_IEEE128)) != 0) - return FFI_BAD_TYPEDEF; - fparg_count += 2; - intarg_count += 2; + if ((cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0) + { + /* Two IEEE-128 halves: each occupies a vector register plus + two GPR shadow doublewords, the pair 16-byte aligned. */ + vecarg_count += 2; + intarg_count = (intarg_count + 1) & ~0x1; + intarg_count += 4; + if (vecarg_count > NUM_VEC_ARG_REGISTERS64) + flags |= FLAG_ARG_NEEDS_PSAVE; + break; + } + /* IBM-128: each half is a pair of FPRs, and each FPR half + consumes a GPR shadow doubleword -- four of each in total. */ + fparg_count += 4; + intarg_count += 4; if (fparg_count > NUM_FPR_ARG_REGISTERS64) flags |= FLAG_ARG_NEEDS_PSAVE; break; @@ -755,10 +776,51 @@ ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack) case FFI_TYPE_COMPLEX: elt = (*ptr)->elements[0]->type; #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - /* 64-bit long double is equivalent to double; the IBM-128 and - IEEE-binary128 variants were rejected in prep_cif. */ + if (elt == FFI_TYPE_LONGDOUBLE + && (ecif->cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0) + { + /* IEEE-128 _Complex long double: each half goes in its own + vector register (or the parameter save area), 16-byte + aligned, consuming two GPR shadow doublewords. */ + float128 *cval = (float128 *) *p_argv.v; + unsigned int j; + for (j = 0; j < 2; j++) + { + next_arg.p = FFI_ALIGN (next_arg.p, 16); + if (next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; + if (vecarg_count < NUM_VEC_ARG_REGISTERS64 && i < nfixedargs) + memcpy (vec_base.f128++, cval + j, sizeof (float128)); + else + memcpy (next_arg.f128, cval + j, sizeof (float128)); + if (++next_arg.f128 == gpr_end.f128) + next_arg.f128 = rest.f128; + vecarg_count++; + } + FFI_ASSERT (flags & FLAG_VEC_ARGUMENTS); + break; + } if (elt == FFI_TYPE_LONGDOUBLE) - elt = FFI_TYPE_DOUBLE; + { + /* IBM-128 _Complex long double: four doubles (real hi/lo, + imag hi/lo) into consecutive FPRs, each with a GPR shadow + doubleword. */ + double *cval = (double *) *p_argv.v; + unsigned int j; + for (j = 0; j < 4; j++) + { + double_tmp = cval[j]; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs) + *fpr_base.d++ = double_tmp; + else + *next_arg.d = double_tmp; + if (++next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; + fparg_count++; + } + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); + break; + } #endif if (elt == FFI_TYPE_FLOAT) { @@ -1336,8 +1398,45 @@ ffi_closure_helper_LINUX64 (ffi_cif *cif, unsigned int j; elt = arg_types[i]->elements[0]->type; #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + if (elt == FFI_TYPE_LONGDOUBLE + && (cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0) + { + /* IEEE-128: each half arrives in a vector register (or the + 16-byte-aligned parameter save area) with two GPR shadow + doublewords. */ + float128 *cval = alloca (2 * sizeof (float128)); + if (((unsigned long) pst & 0xF) != 0) + ++pst; + for (j = 0; j < 2; j++) + { + if (pvec < end_pvec && i < nfixedargs) + memcpy (&cval[j], pvec++, sizeof (float128)); + else + memcpy (&cval[j], pst, sizeof (float128)); + pst += 2; + } + avalue[i] = cval; + break; + } if (elt == FFI_TYPE_LONGDOUBLE) - elt = FFI_TYPE_DOUBLE; + { + /* IBM-128: four doubles, each in an FPR (or one GPR shadow + doubleword) -- real hi/lo then imag hi/lo. */ + double *cval = alloca (4 * sizeof (double)); + for (j = 0; j < 4; j++) + { + if (pfr < end_pfr && i < nfixedargs) + { + cval[j] = pfr->d; + pfr++; + } + else + cval[j] = *(double *) pst; + pst++; + } + avalue[i] = cval; + break; + } #endif if (elt == FFI_TYPE_FLOAT) { @@ -1448,7 +1547,13 @@ ffi_closure_helper_LINUX64 (ffi_cif *cif, int inner = cif->rtype->elements[0]->type; #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE if (inner == FFI_TYPE_LONGDOUBLE) - inner = FFI_TYPE_DOUBLE; + { + /* IEEE-128 _Complex long double returns in v2:v3; IBM-128 in + f1:f2 (real) and f3:f4 (imag), i.e. as a double HFA. */ + if ((cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0) + return PPC64_LD_VECTOR_HOMOG; + inner = FFI_TYPE_DOUBLE; + } #endif if (inner == FFI_TYPE_FLOAT) return PPC64_LD_FLOAT_HOMOG; diff --git a/deps/libffi/src/powerpc/linux64_closure.S b/deps/libffi/src/powerpc/linux64_closure.S index 405b2cfc47a1..3071bec0d22a 100644 --- a/deps/libffi/src/powerpc/linux64_closure.S +++ b/deps/libffi/src/powerpc/linux64_closure.S @@ -345,6 +345,21 @@ E PPC64_LD_STRUCT_3 lwz %r3, RETVAL+4(%r1) srd %r3, %r3, 8 epilogue + +E PPC64_LD_STRUCT_5 + ld %r3, RETVAL+0(%r1) + srdi %r3, %r3, 24 + epilogue + +E PPC64_LD_STRUCT_6 + ld %r3, RETVAL+0(%r1) + srdi %r3, %r3, 16 + epilogue + +E PPC64_LD_STRUCT_7 + ld %r3, RETVAL+0(%r1) + srdi %r3, %r3, 8 + epilogue #endif .Lmoredouble: diff --git a/deps/libffi/src/prep_cif.c b/deps/libffi/src/prep_cif.c index 1836270d1a9c..8a448ebbf81f 100644 --- a/deps/libffi/src/prep_cif.c +++ b/deps/libffi/src/prep_cif.c @@ -32,6 +32,72 @@ #define STACK_ARG_SIZE(x) FFI_ALIGN(x, FFI_SIZEOF_ARG) +/* Compute the machine-independent layout of a vector (SIMD) type. + + A vector is described exactly like a struct -- arg->elements is a + NULL-terminated array of pointers -- but every element must point to the + SAME fundamental scalar type, and the count is the number of lanes. The + caller leaves arg->size and arg->alignment as zero; libffi derives them: + + size = lane_size * lane_count, rounded UP to the next power of two + (matching Clang's ext_vector_type storage, e.g. 3 x float + -> 16; GCC's vector_size already requires power-of-two totals + so the rule is identical there); + alignment = min(size, 16). + + Only float, double and the fixed-width integer scalars (UINT8..SINT64) are + valid lane types. Anything else -- a heterogeneous element list, an + aggregate lane, long double, or a zero-length vector -- is FFI_BAD_TYPEDEF. */ + +static ffi_status +initialize_vector (ffi_type *arg) +{ + ffi_type **ptr = arg->elements; + ffi_type *elem; + size_t count = 0; + size_t total, p2; + + if (UNLIKELY (ptr == NULL || *ptr == NULL)) + return FFI_BAD_TYPEDEF; + + elem = *ptr; + switch (elem->type) + { + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + 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_UINT64: + case FFI_TYPE_SINT64: + break; + default: + return FFI_BAD_TYPEDEF; + } + + /* Every lane must be the identical scalar type. */ + for (; *ptr != NULL; ptr++) + { + if ((*ptr)->type != elem->type || (*ptr)->size != elem->size) + return FFI_BAD_TYPEDEF; + count++; + } + + if (UNLIKELY (count < 1 || elem->size == 0)) + return FFI_BAD_TYPEDEF; + + total = elem->size * count; + for (p2 = 1; p2 < total; p2 <<= 1) + ; + + arg->size = p2; + arg->alignment = p2 < 16 ? p2 : 16; + return FFI_OK; +} + /* Perform machine independent initialization of aggregate type specifications. */ @@ -42,6 +108,9 @@ static ffi_status initialize_aggregate(ffi_type *arg, size_t *offsets) if (UNLIKELY(arg == NULL || arg->elements == NULL)) return FFI_BAD_TYPEDEF; + if (arg->type == FFI_TYPE_VECTOR) + return initialize_vector (arg); + arg->size = 0; arg->alignment = 0; @@ -92,6 +161,28 @@ static ffi_status initialize_aggregate(ffi_type *arg, size_t *offsets) return FFI_OK; } +#ifndef FFI_TARGET_HAS_VECTOR_TYPE +/* Recursively test whether TY is, or contains, a vector (SIMD) type. Ports + that do not define FFI_TARGET_HAS_VECTOR_TYPE cannot marshal vectors, so + ffi_prep_cif_core rejects any signature that mentions one (directly or + nested inside a struct) with FFI_BAD_TYPEDEF rather than aborting. */ +static int +ffi_type_contains_vector (ffi_type *ty) +{ + ffi_type **p; + + if (ty == NULL) + return 0; + if (ty->type == FFI_TYPE_VECTOR) + return 1; + if (ty->type == FFI_TYPE_STRUCT && ty->elements != NULL) + for (p = ty->elements; *p != NULL; p++) + if (ffi_type_contains_vector (*p)) + return 1; + return 0; +} +#endif /* !FFI_TARGET_HAS_VECTOR_TYPE */ + #ifndef __CRIS__ /* The CRIS ABI specifies structure elements to have byte alignment only, so it completely overrides this functions, @@ -129,6 +220,15 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, cif->nargs = ntotalargs; cif->rtype = rtype; +#ifndef FFI_TARGET_HAS_VECTOR_TYPE + /* Vector (SIMD) types are only marshalled on ports that opt in. */ + if (ffi_type_contains_vector (rtype)) + return FFI_BAD_TYPEDEF; + for (i = 0; i < ntotalargs; i++) + if (ffi_type_contains_vector (atypes[i])) + return FFI_BAD_TYPEDEF; +#endif + cif->flags = 0; #if (defined(_M_ARM64) || defined(__aarch64__)) && defined(_WIN32) cif->is_variadic = isvariadic; @@ -152,7 +252,8 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, /* x86, x86-64 and s390 stack space allocation is handled in prep_machdep. */ #if !defined FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION /* Make space for the return structure pointer */ - if (cif->rtype->type == FFI_TYPE_STRUCT + if ((cif->rtype->type == FFI_TYPE_STRUCT + || cif->rtype->type == FFI_TYPE_VECTOR) #ifdef TILE && (cif->rtype->size > 10 * FFI_SIZEOF_ARG) #endif @@ -316,4 +417,11 @@ ffi_call_plan_free (ffi_call_plan *plan) free (plan); } +size_t +ffi_call_plan_size (ffi_call_plan *plan) +{ + /* The generic plan is a bare handle; there is no separate move-list. */ + return plan != NULL ? sizeof (struct ffi_call_plan) : 0; +} + #endif /* generic ffi_call_plan fallback */ diff --git a/deps/libffi/src/raw_api.c b/deps/libffi/src/raw_api.c index be156116cb0d..670d56d948a3 100644 --- a/deps/libffi/src/raw_api.c +++ b/deps/libffi/src/raw_api.c @@ -42,7 +42,7 @@ ffi_raw_size (ffi_cif *cif) for (i = cif->nargs-1; i >= 0; i--, at++) { #if !FFI_NO_STRUCTS - if ((*at)->type == FFI_TYPE_STRUCT) + if ((*at)->type == FFI_TYPE_STRUCT || (*at)->type == FFI_TYPE_VECTOR) result += FFI_ALIGN (sizeof (void*), FFI_SIZEOF_ARG); else #endif @@ -82,8 +82,9 @@ ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args) break; #endif -#if !FFI_NO_STRUCTS +#if !FFI_NO_STRUCTS case FFI_TYPE_STRUCT: + case FFI_TYPE_VECTOR: *args = (raw++)->ptr; break; #endif @@ -110,7 +111,7 @@ ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args) for (i = 0; i < cif->nargs; i++, tp++, args++) { #if !FFI_NO_STRUCTS - if ((*tp)->type == FFI_TYPE_STRUCT) + if ((*tp)->type == FFI_TYPE_STRUCT || (*tp)->type == FFI_TYPE_VECTOR) { *args = (raw++)->ptr; } @@ -172,6 +173,7 @@ ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw) #if !FFI_NO_STRUCTS case FFI_TYPE_STRUCT: + case FFI_TYPE_VECTOR: (raw++)->ptr = *args; break; #endif diff --git a/deps/libffi/src/tramp.c b/deps/libffi/src/tramp.c index 525f81547156..a04188858af6 100644 --- a/deps/libffi/src/tramp.c +++ b/deps/libffi/src/tramp.c @@ -417,9 +417,19 @@ ffi_tramp_init (void) &tramp_globals.map_size); tramp_globals.ntramp = tramp_globals.map_size / tramp_globals.size; + /* + * The trampoline code table is a single, fixed-size mapping. If the + * system page size is larger than that mapping, the static trampoline + * mechanism cannot be used. Both values are invariant for the life of + * the process, so cache the FAILED verdict rather than re-running the + * whole initialization on every allocation. + */ page_size = sysconf (_SC_PAGESIZE); if (page_size >= 0 && (size_t)page_size > tramp_globals.map_size) - return 0; + { + tramp_globals.status = TRAMP_GLOBALS_FAILED; + return 0; + } if (ffi_tramp_init_os ()) { diff --git a/deps/libffi/src/x86/ffi.c b/deps/libffi/src/x86/ffi.c index 27f17b0c8849..a953891362d5 100644 --- a/deps/libffi/src/x86/ffi.c +++ b/deps/libffi/src/x86/ffi.c @@ -118,7 +118,7 @@ ffi_prep_cif_machdep(ffi_cif *cif) break; case FFI_TYPE_STRUCT: { -#if defined(X86_WIN32) || defined(X86_DARWIN) +#if defined(X86_WIN32) || defined(X86_DARWIN) || defined(X86_FREEBSD) size_t size = cif->rtype->size; if (size == 1) flags = X86_RET_STRUCT_1B; diff --git a/deps/libffi/src/x86/ffi64.c b/deps/libffi/src/x86/ffi64.c index c24db38c4364..c2c78f3fbbfb 100644 --- a/deps/libffi/src/x86/ffi64.c +++ b/deps/libffi/src/x86/ffi64.c @@ -330,6 +330,25 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[], } return words; } + case FFI_TYPE_VECTOR: + /* A Short Vector occupies SSE registers: an 8-byte vector is a single + SSE eightbyte; a 16-byte vector is one %xmm register (SSE + SSEUP). + Wider vectors would need %ymm/%zmm handling this port does not + implement; classify them as memory here and reject them outright in + ffi_prep_cif_machdep so the caller gets FFI_BAD_TYPEDEF, not a + silently wrong in-memory pass. */ + if (type->size == 8) + { + classes[0] = X86_64_SSE_CLASS; + return 1; + } + else if (type->size == 16) + { + classes[0] = X86_64_SSE_CLASS; + classes[1] = X86_64_SSEUP_CLASS; + return 2; + } + return 0; case FFI_TYPE_COMPLEX: { ffi_type *inner = type->elements[0]; @@ -533,6 +552,16 @@ ffi_prep_cif_machdep (ffi_cif *cif) } } break; + case FFI_TYPE_VECTOR: + /* An 8-byte vector returns in the low half of %xmm0; a 16-byte vector + fills %xmm0 (SSE + SSEUP). Wider vectors are unsupported here. */ + if (rtype_size == 8) + flags = UNIX64_RET_XMM64; + else if (rtype_size == 16) + flags = UNIX64_RET_XMM128; + else + return FFI_BAD_TYPEDEF; + break; case FFI_TYPE_COMPLEX: switch (rtype->elements[0]->type) { @@ -577,6 +606,15 @@ ffi_prep_cif_machdep (ffi_cif *cif) return FFI_BAD_TYPEDEF; } + /* Reject vectors wider than 16 bytes as arguments: correct %ymm/%zmm + passing needs unix64.S register-save changes that are out of scope for + this port, and classify_argument would otherwise silently treat them as + an in-memory aggregate. */ + for (i = 0, avn = cif->nargs; i < avn; i++) + if (cif->arg_types[i]->type == FFI_TYPE_VECTOR + && cif->arg_types[i]->size > 16) + return FFI_BAD_TYPEDEF; + /* Go over all arguments and determine the way they should be passed. If it's in a register and there is space for it, let that be so. If not, add it's size to the stack byte count. */ @@ -782,6 +820,7 @@ typedef struct unsigned fast; /* nonzero -> lean trampoline eligible */ unsigned retcode; /* UNIX64_RET_* (low byte of flags) for the store */ int thunk_n; /* >=0 -> ffi_gp_thunks[thunk_n], else -1 */ + unsigned alloc_bytes; /* malloc'd size, reported by ffi_call_plan_size */ ffi_move moves[]; } ffi_plan; @@ -828,7 +867,7 @@ build_plan (ffi_cif *cif) unsigned i, avn = cif->nargs; enum x86_64_reg_class classes[MAX_CLASSES]; unsigned nm, gprcount, ssecount; - size_t argp_off; + size_t argp_off, nbytes; ffi_plan *plan; int all_gp64 = 1; /* every arg is exactly one 64-bit GP move? */ @@ -848,9 +887,11 @@ build_plan (ffi_cif *cif) } /* One self-contained allocation: header + moves, released with plain free(). */ - plan = malloc (sizeof (ffi_plan) + sizeof (ffi_move) * (2 * avn + 1)); + nbytes = sizeof (ffi_plan) + sizeof (ffi_move) * (2 * avn + 1); + plan = malloc (nbytes); if (plan == NULL) return NULL; + plan->alloc_bytes = (unsigned) nbytes; nm = gprcount = ssecount = 0; argp_off = 0; @@ -1070,6 +1111,17 @@ ffi_call_plan_free (ffi_call_plan *plan) } } +size_t +ffi_call_plan_size (ffi_call_plan *plan) +{ + if (plan == NULL) + return 0; + /* The move-list carries its own size; a signature with no fast path owns + nothing beyond the handle. */ + return sizeof (struct ffi_call_plan) + + (plan->fast != NULL ? plan->fast->alloc_bytes : 0); +} + extern void ffi_call_efi64(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue); #endif diff --git a/deps/libffi/src/x86/ffitarget.h b/deps/libffi/src/x86/ffitarget.h index d702235f90fe..eaf6a910a4f5 100644 --- a/deps/libffi/src/x86/ffitarget.h +++ b/deps/libffi/src/x86/ffitarget.h @@ -58,6 +58,13 @@ #define FFI_TARGET_HAS_INT128 #endif +/* The System V x86-64 psABI passes 8- and 16-byte vectors in SSE registers; + this is implemented by the ffi64.c (FFI_UNIX64) backend only. 32-bit x86 + and the Windows x86-64 backend (ffiw64.c) do not marshal vectors. */ +#if defined(X86_64) && !defined(X86_WIN64) +#define FFI_TARGET_HAS_VECTOR_TYPE +#endif + /* ---- Generic type definitions ----------------------------------------- */ #ifndef LIBFFI_ASM @@ -138,6 +145,18 @@ typedef enum ffi_abi { #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3) #define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4) +/* Tripwire: the win64.S / win64_intel.S return-value jump tables use one + 8-byte slot per code value and place the FFI_TYPE_SMALL_STRUCT_* pseudo-types + (which are FFI_TYPE_LAST-relative) immediately after the generic FFI_TYPE_* + codes. Adding a new generic type bumps FFI_TYPE_LAST, shifts those codes, + and opens a gap in the tables that silently misaligns small-struct returns. + When this fires: add a matching E() slot for the new type in both win64.S + and win64_intel.S, then bump FFI_X86_TYPE_LAST to match. */ +#define FFI_X86_TYPE_LAST FFI_TYPE_VECTOR +#if FFI_TYPE_LAST != FFI_X86_TYPE_LAST +# error "new FFI_TYPE_* added: sync the win64.S/win64_intel.S jump tables and bump FFI_X86_TYPE_LAST" +#endif + #if defined (X86_64) || defined(X86_WIN64) \ || (defined (__x86_64__) && defined (X86_DARWIN)) /* 4 bytes of ENDBR64 + 7 bytes of LEA + 6 bytes of JMP + 7 bytes of NOP diff --git a/deps/libffi/src/x86/win64.S b/deps/libffi/src/x86/win64.S index 185f0a3048fb..f23a5fa29e8e 100644 --- a/deps/libffi/src/x86/win64.S +++ b/deps/libffi/src/x86/win64.S @@ -151,6 +151,11 @@ E(0b, FFI_TYPE_UINT128) E(0b, FFI_TYPE_SINT128) movdqu %xmm0, (%r8) epilogue +/* Win64 does not marshal vectors (ffi_prep_cif_core rejects them), but the + FFI_TYPE_SMALL_STRUCT_* codes are FFI_TYPE_LAST-relative, so this slot must + exist to keep the table contiguous and the small-struct entries aligned. */ +E(0b, FFI_TYPE_VECTOR) + call PLT(C(abort)) E(0b, FFI_TYPE_SMALL_STRUCT_1B) movb %al, (%r8) epilogue diff --git a/deps/libffi/src/x86/win64_intel.S b/deps/libffi/src/x86/win64_intel.S index e9eff00da3ce..807f5b3e98f7 100644 --- a/deps/libffi/src/x86/win64_intel.S +++ b/deps/libffi/src/x86/win64_intel.S @@ -152,6 +152,11 @@ E(0b, FFI_TYPE_UINT128) E(0b, FFI_TYPE_SINT128) movdqu xmmword ptr [r8], xmm0 epilogue +/* Win64 does not marshal vectors (ffi_prep_cif_core rejects them), but the + FFI_TYPE_SMALL_STRUCT_* codes are FFI_TYPE_LAST-relative, so this slot must + exist to keep the table contiguous and the small-struct entries aligned. */ +E(0b, FFI_TYPE_VECTOR) + call PLT(C(abort)) E(0b, FFI_TYPE_SMALL_STRUCT_1B) mov byte ptr [r8], al ; movb %al, (%r8) epilogue diff --git a/deps/libffi/testsuite/Makefile.am b/deps/libffi/testsuite/Makefile.am index c14a880959d8..702461d02418 100644 --- a/deps/libffi/testsuite/Makefile.am +++ b/deps/libffi/testsuite/Makefile.am @@ -13,15 +13,17 @@ EXTRA_DIST = config/default.exp emscripten/build.sh emscripten/conftest.py \ libffi.bhaible/alignof.h libffi.bhaible/bhaible.exp libffi.bhaible/test-call.c \ libffi.bhaible/test-callback.c libffi.bhaible/testcases.c libffi.call/align_mixed.c \ libffi.call/align_stdcall.c libffi.call/bpo_38748.c libffi.call/call.exp \ + libffi.call/closure_thiscall_fastcall_pop.c \ libffi.call/err_bad_typedef.c libffi.call/ffitest.h libffi.call/float.c \ libffi.call/float1.c libffi.call/float2.c libffi.call/float3.c \ libffi.call/float4.c libffi.call/float_va.c libffi.call/i128-1.c \ libffi.call/large_struct_by_value.c libffi.call/many.c \ - libffi.call/many2.c libffi.call/many_double.c libffi.call/many_mixed.c \ + libffi.call/many2.c libffi.call/many_double.c \ + libffi.call/many_large_structs.c libffi.call/many_mixed.c \ libffi.call/many_small_structs.c \ libffi.call/negint.c libffi.call/offsets.c libffi.call/overread.c \ libffi.call/plan.c libffi.call/plan_mixed.c libffi.call/plan_spill.c \ - libffi.call/plan_struct.c libffi.call/plan_var.c \ + libffi.call/plan_struct.c libffi.call/plan_size.c libffi.call/plan_var.c \ libffi.call/pr1172638.c libffi.call/promotion.c libffi.call/pyobjc_tc.c libffi.call/return_dbl.c \ libffi.call/return_dbl1.c libffi.call/return_dbl2.c libffi.call/return_fl.c \ libffi.call/return_fl1.c libffi.call/return_fl2.c libffi.call/return_fl3.c \ @@ -90,4 +92,10 @@ EXTRA_DIST = config/default.exp emscripten/build.sh emscripten/conftest.py \ libffi.complex/return_complex_float.c libffi.complex/return_complex_longdouble.c libffi.go/aa-direct.c \ libffi.go/closure1.c libffi.go/ffitest.h libffi.go/go.exp \ libffi.go/static-chain.h Makefile.am Makefile.in \ - libffi.threads/ffitest.h libffi.threads/threads.exp libffi.threads/tsan.c + libffi.threads/ffitest.h libffi.threads/threads.exp libffi.threads/tsan.c \ + libffi.vector/vector.exp libffi.vector/ffitest.h libffi.vector/vector.h \ + libffi.vector/vector_float32x4.c libffi.vector/vector_float32x2.c \ + libffi.vector/vector_double2.c libffi.vector/vector_int32x4.c \ + libffi.vector/vector_args_spill.c libffi.vector/vector_vec3.c \ + libffi.vector/vector_double4.c libffi.vector/vector_hva.c \ + libffi.vector/cls_vector.c libffi.vector/vector_validate.c diff --git a/deps/libffi/testsuite/Makefile.in b/deps/libffi/testsuite/Makefile.in index 1b29b90d3633..30b417735d5e 100644 --- a/deps/libffi/testsuite/Makefile.in +++ b/deps/libffi/testsuite/Makefile.in @@ -301,15 +301,17 @@ EXTRA_DIST = config/default.exp emscripten/build.sh emscripten/conftest.py \ libffi.bhaible/alignof.h libffi.bhaible/bhaible.exp libffi.bhaible/test-call.c \ libffi.bhaible/test-callback.c libffi.bhaible/testcases.c libffi.call/align_mixed.c \ libffi.call/align_stdcall.c libffi.call/bpo_38748.c libffi.call/call.exp \ + libffi.call/closure_thiscall_fastcall_pop.c \ libffi.call/err_bad_typedef.c libffi.call/ffitest.h libffi.call/float.c \ libffi.call/float1.c libffi.call/float2.c libffi.call/float3.c \ libffi.call/float4.c libffi.call/float_va.c libffi.call/i128-1.c \ libffi.call/large_struct_by_value.c libffi.call/many.c \ - libffi.call/many2.c libffi.call/many_double.c libffi.call/many_mixed.c \ + libffi.call/many2.c libffi.call/many_double.c \ + libffi.call/many_large_structs.c libffi.call/many_mixed.c \ libffi.call/many_small_structs.c \ libffi.call/negint.c libffi.call/offsets.c libffi.call/overread.c \ libffi.call/plan.c libffi.call/plan_mixed.c libffi.call/plan_spill.c \ - libffi.call/plan_struct.c libffi.call/plan_var.c \ + libffi.call/plan_struct.c libffi.call/plan_size.c libffi.call/plan_var.c \ libffi.call/pr1172638.c libffi.call/promotion.c libffi.call/pyobjc_tc.c libffi.call/return_dbl.c \ libffi.call/return_dbl1.c libffi.call/return_dbl2.c libffi.call/return_fl.c \ libffi.call/return_fl1.c libffi.call/return_fl2.c libffi.call/return_fl3.c \ @@ -378,7 +380,13 @@ EXTRA_DIST = config/default.exp emscripten/build.sh emscripten/conftest.py \ libffi.complex/return_complex_float.c libffi.complex/return_complex_longdouble.c libffi.go/aa-direct.c \ libffi.go/closure1.c libffi.go/ffitest.h libffi.go/go.exp \ libffi.go/static-chain.h Makefile.am Makefile.in \ - libffi.threads/ffitest.h libffi.threads/threads.exp libffi.threads/tsan.c + libffi.threads/ffitest.h libffi.threads/threads.exp libffi.threads/tsan.c \ + libffi.vector/vector.exp libffi.vector/ffitest.h libffi.vector/vector.h \ + libffi.vector/vector_float32x4.c libffi.vector/vector_float32x2.c \ + libffi.vector/vector_double2.c libffi.vector/vector_int32x4.c \ + libffi.vector/vector_args_spill.c libffi.vector/vector_vec3.c \ + libffi.vector/vector_double4.c libffi.vector/vector_hva.c \ + libffi.vector/cls_vector.c libffi.vector/vector_validate.c all: all-am diff --git a/deps/libffi/testsuite/libffi.call/closure_thiscall_fastcall_pop.c b/deps/libffi/testsuite/libffi.call/closure_thiscall_fastcall_pop.c new file mode 100644 index 000000000000..9cc0b091943f --- /dev/null +++ b/deps/libffi/testsuite/libffi.call/closure_thiscall_fastcall_pop.c @@ -0,0 +1,131 @@ +/* Area: closure, ffi_prep_closure_loc + Purpose: Check i386 THISCALL/FASTCALL closures pop the stack correctly. + Limitations: i386 + GNU inline asm only; a no-op elsewhere. + PR: none. + Originator: i386 closure stack-pop accounting regression. + + THISCALL and FASTCALL are callee-clean: the closure must remove its + stack-resident arguments on return (ret $n). When a 64-bit integer or + a struct argument is placed on the stack, the closure return path used + to compute the pop as cif->bytes - narg_reg*4 with narg_reg force-bumped + to 2, discounting register slots that were never used and under-popping + the stack. A caller that relies on callee cleanup is then left with the + argument bytes where its return address should be. + + This test invokes the generated closure through a minimal callee-clean + call site and checks that ESP is balanced across the call (delta 0). + Without the fix the delta is 8 (FASTCALL uint64) or 4 (THISCALL). */ + +/* { dg-do run } */ +#include "ffitest.h" + +#if defined(__i386__) && defined(__GNUC__) && !defined(__APPLE__) + +static uint64_t received; +static int ran; + +static void +cb (ffi_cif *cif, void *resp, void **args, void *userdata) +{ + (void) cif; (void) resp; (void) userdata; + received = *(uint64_t *) args[cif->nargs - 1]; + ran++; +} + +/* Push an 8-byte stack argument, load ECX (the thiscall "this" register, + ignored by the fastcall callee), call the closure, and return how many + bytes the callee under-popped (0 == it popped exactly what was pushed). + + Every operand is read into a register up front, while ESP is still at + its incoming value, so nothing is referenced through an ESP-relative + memory operand after we start moving ESP (which would otherwise read a + stale slot, on clang at -O2 in particular). The stack is then 16-byte + aligned at the call as the i386 psABI requires, so the -O2-built closure + body may use aligned SSE without faulting; the alignment cancels out of + the delta. ESP is restored to its exact incoming value before the delta + is stored, so a wrong pop cannot corrupt our frame. Not using EBX keeps + this compatible with -fPIC; the delta is returned via memory so no free + register is needed for it. */ +static int +esp_delta (void *code, uint64_t stackarg, unsigned ecxv) +{ + unsigned delta; + unsigned lo = (unsigned) stackarg; + unsigned hi = (unsigned) (stackarg >> 32); + __asm__ volatile ( + "movl %[lo], %%eax\n\t" /* stash all operands in registers */ + "movl %[hi], %%edx\n\t" /* before ESP moves */ + "movl %[code], %%edi\n\t" + "movl %[ecxv], %%ecx\n\t" /* thiscall 'this' */ + "movl %%esp, %%esi\n\t" /* remember the real esp */ + "andl $-16, %%esp\n\t" /* 16-byte align, then bias by the */ + "subl $8, %%esp\n\t" /* 8 arg bytes so 'call' is 0 mod 16 */ + "pushl %%edx\n\t" /* high dword */ + "pushl %%eax\n\t" /* low dword */ + "calll *%%edi\n\t" + "movl %%esi, %%eax\n\t" /* recompute esp just before the */ + "andl $-16, %%eax\n\t" /* pushes... */ + "subl $8, %%eax\n\t" + "subl %%esp, %%eax\n\t" /* eax = under-popped byte count */ + "movl %%esi, %%esp\n\t" /* restore before touching memory */ + "movl %%eax, %[delta]\n\t" + : [delta] "=m" (delta) + : [lo] "m" (lo), [hi] "m" (hi), [code] "m" (code), [ecxv] "m" (ecxv) + : "memory", "cc", "eax", "ecx", "edx", "esi", "edi"); + return (int) delta; +} + +static int +check_abi (ffi_abi abi, unsigned nargs, ffi_type **atypes, unsigned ecx) +{ + ffi_cif cif; + ffi_closure *closure; + void *code; + int delta; + + closure = ffi_closure_alloc (sizeof (ffi_closure), &code); + CHECK (closure != NULL); + CHECK (ffi_prep_cif (&cif, abi, nargs, &ffi_type_void, atypes) == FFI_OK); + CHECK (ffi_prep_closure_loc (closure, &cif, cb, NULL, code) == FFI_OK); + + ran = 0; + received = 0; + delta = esp_delta (code, 0x1122334455667788ULL, ecx); + + CHECK (ran == 1); + CHECK (received == 0x1122334455667788ULL); + ffi_closure_free (closure); + return delta; +} + +int +main (void) +{ + ffi_type *fastcall_args[1] = { &ffi_type_uint64 }; + ffi_type *thiscall_args[2] = { &ffi_type_pointer, &ffi_type_uint64 }; + int d; + + /* FASTCALL void cb(uint64_t): the uint64 is stack-resident; pop must be 8. */ + d = check_abi (FFI_FASTCALL, 1, fastcall_args, 0); + printf ("FASTCALL uint64 esp delta: %d\n", d); + CHECK (d == 0); + + /* THISCALL void cb(void*, uint64_t): 'this' in ECX, uint64 on the stack; + pop must be 8 (not 4). */ + d = check_abi (FFI_THISCALL, 2, thiscall_args, 0xdeadbeef); + printf ("THISCALL this+uint64 esp delta: %d\n", d); + CHECK (d == 0); + + exit (0); +} + +#else + +int +main (void) +{ + /* Not an i386 GNU target: nothing to check here. */ + exit (0); +} + +#endif diff --git a/deps/libffi/testsuite/libffi.call/many_large_structs.c b/deps/libffi/testsuite/libffi.call/many_large_structs.c new file mode 100644 index 000000000000..9f766a9113c6 --- /dev/null +++ b/deps/libffi/testsuite/libffi.call/many_large_structs.c @@ -0,0 +1,88 @@ +/* Area: ffi_call + Purpose: Pass many large by-value structs on AArch64. + Limitations: none. + PR: none. + Originator: AArch64 large-struct stack accounting regression. + + Regression test: on AArch64, composites larger than 16 bytes are passed + by invisible reference. ffi_call copies each payload into the argument + slab (growing down from the top) and, once X0-X7 are exhausted, also + spills the by-ref pointer into the same slab (the NSAA, growing up). + The generic prep_cif budget in cif->bytes only charged the payload copy, + not the 8-byte pointer slot, so with enough large structs the two regions + collided and a later payload copy overwrote an already-spilled pointer, + leaving the callee with a corrupt pointer for a by-value argument. + Passing sixteen 32-byte (non-HFA) structs by value -- eight more than the + argument registers -- must marshal every argument intact. */ + +/* { dg-do run } */ +#include "ffitest.h" + +#define NARGS 16 +#define SSIZE 32 + +typedef struct { unsigned char b[SSIZE]; } big_struct; + +/* Sum every byte of every argument. A corrupted by-ref pointer makes the + callee read the wrong memory, so the sum no longer matches. */ +static int ABI_ATTR +sum_bytes (big_struct s0, big_struct s1, big_struct s2, big_struct s3, + big_struct s4, big_struct s5, big_struct s6, big_struct s7, + big_struct s8, big_struct s9, big_struct s10, big_struct s11, + big_struct s12, big_struct s13, big_struct s14, big_struct s15) +{ + big_struct *all[NARGS]; + int i, j, sum = 0; + + all[0] = &s0; all[1] = &s1; all[2] = &s2; all[3] = &s3; + all[4] = &s4; all[5] = &s5; all[6] = &s6; all[7] = &s7; + all[8] = &s8; all[9] = &s9; all[10] = &s10; all[11] = &s11; + all[12] = &s12; all[13] = &s13; all[14] = &s14; all[15] = &s15; + + for (i = 0; i < NARGS; i++) + for (j = 0; j < SSIZE; j++) + sum += all[i]->b[j]; + + return sum; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[NARGS]; + void *values[NARGS]; + ffi_type bs_type; + ffi_type *bs_elements[SSIZE + 1]; + big_struct in[NARGS]; + ffi_arg result = 0; + int i, j, expected = 0; + + bs_type.size = 0; + bs_type.alignment = 0; + bs_type.type = FFI_TYPE_STRUCT; + for (i = 0; i < SSIZE; i++) + bs_elements[i] = &ffi_type_uchar; + bs_elements[SSIZE] = NULL; + bs_type.elements = bs_elements; + + /* Fill struct i with the distinct byte value (i + 1) so any pointer + mix-up between arguments changes the total. */ + for (i = 0; i < NARGS; i++) + { + for (j = 0; j < SSIZE; j++) + { + in[i].b[j] = (unsigned char) (i + 1); + expected += (i + 1); + } + args[i] = &bs_type; + values[i] = &in[i]; + } + + CHECK(ffi_prep_cif(&cif, ABI_NUM, NARGS, &ffi_type_sint, args) == FFI_OK); + + ffi_call(&cif, FFI_FN(sum_bytes), &result, values); + + CHECK((int) result == expected); + + exit(0); +} diff --git a/deps/libffi/testsuite/libffi.call/plan_size.c b/deps/libffi/testsuite/libffi.call/plan_size.c new file mode 100644 index 000000000000..b8398fbee991 --- /dev/null +++ b/deps/libffi/testsuite/libffi.call/plan_size.c @@ -0,0 +1,77 @@ +/* Area: ffi_call_plan_size + Purpose: Check that a plan reports its own allocation size, that the + size is stable across invocations, and that a NULL plan has + no footprint. + Limitations: The exact byte count is implementation defined, so this only + checks the invariants callers may rely on. + PR: none. + Originator: ffi_call_plan tests */ + +/* { dg-do run } */ +#include "ffitest.h" + +static uint64_t gp2(uint64_t a, uint64_t b) +{ + return a + b * 2; +} + +static uint64_t gp6(uint64_t a, uint64_t b, uint64_t c, + uint64_t d, uint64_t e, uint64_t f) +{ + return a + b * 2 + c * 3 + d * 4 + e * 5 + f * 6; +} + +int main (void) +{ + ffi_cif cif2, cif6; + ffi_type *args[6]; + void *values[6]; + ffi_call_plan *plan2, *plan6; + size_t size2, size6; + uint64_t a[6], r; + int i; + + for (i = 0; i < 6; i++) + { + args[i] = &ffi_type_uint64; + a[i] = (uint64_t) (i + 1); + values[i] = &a[i]; + } + + CHECK(ffi_prep_cif(&cif2, FFI_DEFAULT_ABI, 2, &ffi_type_uint64, args) + == FFI_OK); + CHECK(ffi_prep_cif(&cif6, FFI_DEFAULT_ABI, 6, &ffi_type_uint64, args) + == FFI_OK); + + /* A NULL plan has no footprint, mirroring ffi_call_plan_free(NULL). */ + CHECK(ffi_call_plan_size(NULL) == 0); + + plan2 = ffi_call_plan_alloc(&cif2); + CHECK(plan2 != NULL); + plan6 = ffi_call_plan_alloc(&cif6); + CHECK(plan6 != NULL); + + size2 = ffi_call_plan_size(plan2); + size6 = ffi_call_plan_size(plan6); + + /* Every plan owns at least its handle, and a wider signature never needs + less memory than a narrower one of the same shape. Targets without a + fast path report the same constant for both. */ + CHECK(size2 > 0); + CHECK(size6 >= size2); + + /* The plan is immutable, so querying it must not disturb invocation and + the reported size must not drift across calls. */ + ffi_call_plan_invoke(plan6, FFI_FN(gp6), &r, values); + CHECK(r == gp6(a[0], a[1], a[2], a[3], a[4], a[5])); + CHECK(ffi_call_plan_size(plan6) == size6); + + ffi_call_plan_invoke(plan2, FFI_FN(gp2), &r, values); + CHECK(r == gp2(a[0], a[1])); + CHECK(ffi_call_plan_size(plan2) == size2); + + ffi_call_plan_free(plan2); + ffi_call_plan_free(plan6); + + exit(0); +} diff --git a/deps/libffi/testsuite/libffi.vector/cls_vector.c b/deps/libffi/testsuite/libffi.vector/cls_vector.c new file mode 100644 index 000000000000..18d8806b51b5 --- /dev/null +++ b/deps/libffi/testsuite/libffi.vector/cls_vector.c @@ -0,0 +1,67 @@ +/* Area: closure_call + Purpose: A closure that receives two vector arguments (and a scalar) and + returns a vector. Exercises the closure argument-extraction and + vector return paths. + Limitations: none. + PR: none. + Originator: libffi vector support. */ + +/* { dg-do run } */ + +#include "vector.h" + +typedef float f32x4 __attribute__((vector_size (16))); + +static void +cls_vector_fn (ffi_cif *cif __UNUSED__, void *resp, void **args, + void *userdata __UNUSED__) +{ + f32x4 a = *(f32x4 *) args[0]; + f32x4 b = *(f32x4 *) args[1]; + int scale = *(int *) args[2]; + f32x4 *r = (f32x4 *) resp; + + *r = (a + b) * (float) scale; +} + +typedef f32x4 (*cls_vector_t) (f32x4, f32x4, int); + +int +main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc (sizeof (ffi_closure), &code); + ffi_type vec_type; + ffi_type *vec_elems[5]; + ffi_type *arg_types[3]; + f32x4 a = { 1, 2, 3, 4 }; + f32x4 b = { 10, 20, 30, 40 }; + f32x4 res; + int scale = 2; + int i; + + CHECK (pcl != NULL); + + make_vector_type (&vec_type, vec_elems, &ffi_type_float, 4); + + arg_types[0] = &vec_type; + arg_types[1] = &vec_type; + arg_types[2] = &ffi_type_sint; + + CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 3, &vec_type, arg_types) + == FFI_OK); + CHECK (ffi_prep_closure_loc (pcl, &cif, cls_vector_fn, NULL, code) + == FFI_OK); + + res = ((cls_vector_t) code) (a, b, scale); + + for (i = 0; i < 4; i++) + { + float want = (a[i] + b[i]) * (float) scale; + printf ("res[%d] = %g (want %g)\n", i, (double) res[i], (double) want); + CHECK (res[i] == want); + } + + exit (0); +} diff --git a/deps/libffi/testsuite/libffi.vector/ffitest.h b/deps/libffi/testsuite/libffi.vector/ffitest.h new file mode 100644 index 000000000000..d27d362d6a6e --- /dev/null +++ b/deps/libffi/testsuite/libffi.vector/ffitest.h @@ -0,0 +1 @@ +#include "../libffi.call/ffitest.h" diff --git a/deps/libffi/testsuite/libffi.vector/vector.exp b/deps/libffi/testsuite/libffi.vector/vector.exp new file mode 100644 index 000000000000..a76957ee4d33 --- /dev/null +++ b/deps/libffi/testsuite/libffi.vector/vector.exp @@ -0,0 +1,59 @@ +# Copyright (C) 2026 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING3. If not see +# . + +dg-init +libffi-init + +global srcdir subdir + +# The tests are written with the GCC/Clang vector extension +# (__attribute__ ((vector_size (N)))). A target port can support +# FFI_TYPE_VECTOR at the ABI level while the compiler under test (e.g. +# MSVC) cannot compile that syntax, so probe the compiler with an actual +# compilation, not just a preprocessor check. +proc libffi_vector_syntax_test { } { + set src "vecprobe[pid].c" + set obj "vecprobe[pid].o" + + set f [open $src "w"] + puts $f "typedef float probe_v4 __attribute__ ((vector_size (16)));" + puts $f "probe_v4 probe_var;" + puts $f "int main (void) { return 0; }" + close $f + + set lines [libffi_target_compile $src $obj object ""] + file delete $src + file delete $obj + + return [string match "" $lines] +} + +set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.{c,cc}]] + +if { [libffi_feature_test "#ifdef FFI_TARGET_HAS_VECTOR_TYPE"] + && [libffi_vector_syntax_test] } { + run-many-tests $tlist "" +} else { + foreach test $tlist { + unsupported "$test" + } +} + +dg-finish + +# Local Variables: +# tcl-indent-level:4 +# End: diff --git a/deps/libffi/testsuite/libffi.vector/vector.h b/deps/libffi/testsuite/libffi.vector/vector.h new file mode 100644 index 000000000000..7baf832d37e4 --- /dev/null +++ b/deps/libffi/testsuite/libffi.vector/vector.h @@ -0,0 +1,32 @@ +/* -*-c-*- */ +/* Shared helpers for the libffi vector (SIMD) tests. + + Vectors are built with the portable GCC/Clang spelling + __attribute__((vector_size (N))) so the tests compile on both compilers. + A vector ffi_type is described exactly like a struct, except every element + points at the SAME scalar ffi_type and the count is the lane count; the + caller leaves size and alignment at zero and libffi computes them. */ + +#ifndef LIBFFI_VECTOR_H +#define LIBFFI_VECTOR_H + +#include "ffitest.h" + +/* Build (into the caller-provided ELEMS array of length COUNT + 1 and the + ffi_type object TY) a vector type descriptor of COUNT lanes of scalar type + ELEM. ELEMS must have room for COUNT + 1 pointers (NULL terminator). */ +static inline void +make_vector_type (ffi_type *ty, ffi_type **elems, ffi_type *elem, + unsigned count) +{ + unsigned i; + for (i = 0; i < count; i++) + elems[i] = elem; + elems[count] = NULL; + ty->size = 0; + ty->alignment = 0; + ty->type = FFI_TYPE_VECTOR; + ty->elements = elems; +} + +#endif /* LIBFFI_VECTOR_H */ diff --git a/deps/libffi/testsuite/libffi.vector/vector_args_spill.c b/deps/libffi/testsuite/libffi.vector/vector_args_spill.c new file mode 100644 index 000000000000..dec6ab2e62af --- /dev/null +++ b/deps/libffi/testsuite/libffi.vector/vector_args_spill.c @@ -0,0 +1,85 @@ +/* Area: ffi_call + Purpose: Pass many vector arguments interleaved with scalars, enough to + exhaust the vector argument registers and spill onto the stack. + Limitations: none. + PR: none. + Originator: libffi vector support. */ + +/* { dg-do run } */ + +#include "vector.h" + +typedef float f32x4 __attribute__((vector_size (16))); + +/* Ten vectors exceeds the 8 vector argument registers on both AArch64 and + x86-64, so v8/v9 are passed on the stack. The scalars are interleaved to + make sure the two register files advance independently. */ +static float +mix (int i0, f32x4 v0, f32x4 v1, double d0, f32x4 v2, f32x4 v3, + f32x4 v4, int i1, f32x4 v5, f32x4 v6, f32x4 v7, double d1, + f32x4 v8, f32x4 v9) +{ + float acc = 0; + acc += 1 * v0[0] + v0[3]; + acc += 2 * v1[0] + v1[3]; + acc += 3 * v2[0] + v2[3]; + acc += 4 * v3[0] + v3[3]; + acc += 5 * v4[0] + v4[3]; + acc += 6 * v5[0] + v5[3]; + acc += 7 * v6[0] + v6[3]; + acc += 8 * v7[0] + v7[3]; + acc += 9 * v8[0] + v8[3]; + acc += 10 * v9[0] + v9[3]; + acc += i0 + i1 + (float) d0 + (float) d1; + return acc; +} + +int +main (void) +{ + ffi_cif cif; + ffi_type vec_type; + ffi_type *vec_elems[5]; + ffi_type *args[14]; + void *values[14]; + f32x4 v[10]; + int i0 = 100, i1 = 7; + double d0 = 3.5, d1 = 0.25; + float r, ref; + unsigned k; + + make_vector_type (&vec_type, vec_elems, &ffi_type_float, 4); + + for (k = 0; k < 10; k++) + { + f32x4 t = { (float) (k + 1), 0, 0, (float) (100 + k) }; + v[k] = t; + } + + args[0] = &ffi_type_sint; values[0] = &i0; + args[1] = &vec_type; values[1] = &v[0]; + args[2] = &vec_type; values[2] = &v[1]; + args[3] = &ffi_type_double; values[3] = &d0; + args[4] = &vec_type; values[4] = &v[2]; + args[5] = &vec_type; values[5] = &v[3]; + args[6] = &vec_type; values[6] = &v[4]; + args[7] = &ffi_type_sint; values[7] = &i1; + args[8] = &vec_type; values[8] = &v[5]; + args[9] = &vec_type; values[9] = &v[6]; + args[10] = &vec_type; values[10] = &v[7]; + args[11] = &ffi_type_double; values[11] = &d1; + args[12] = &vec_type; values[12] = &v[8]; + args[13] = &vec_type; values[13] = &v[9]; + + CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 14, &ffi_type_float, args) + == FFI_OK); + + ffi_call (&cif, FFI_FN (mix), &r, values); + + ref = mix (i0, v[0], v[1], d0, v[2], v[3], v[4], i1, v[5], v[6], v[7], + d1, v[8], v[9]); + printf ("r = %g (want %g)\n", (double) r, (double) ref); + CHECK (r == ref); + + exit (0); +} diff --git a/deps/libffi/testsuite/libffi.vector/vector_double2.c b/deps/libffi/testsuite/libffi.vector/vector_double2.c new file mode 100644 index 000000000000..dd45878b5afe --- /dev/null +++ b/deps/libffi/testsuite/libffi.vector/vector_double2.c @@ -0,0 +1,53 @@ +/* Area: ffi_call + Purpose: Pass and return a 16-byte double2 vector (single Q/SSE reg). + Limitations: none. + PR: none. + Originator: libffi vector support. */ + +/* { dg-do run } */ + +#include "vector.h" + +typedef double d2 __attribute__((vector_size (16))); + +static d2 +add_d2 (d2 a, d2 b) +{ + return a + b; +} + +int +main (void) +{ + ffi_cif cif; + ffi_type vec_type; + ffi_type *vec_elems[3]; + ffi_type *args[2]; + void *values[2]; + d2 a = { 1.5, 2.5 }; + d2 b = { 10.0, 20.0 }; + d2 r, ref; + int i; + + make_vector_type (&vec_type, vec_elems, &ffi_type_double, 2); + + args[0] = &vec_type; + args[1] = &vec_type; + values[0] = &a; + values[1] = &b; + + CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 2, &vec_type, args) == FFI_OK); + CHECK (vec_type.size == 16); + CHECK (vec_type.alignment == 16); + + ffi_call (&cif, FFI_FN (add_d2), &r, values); + + ref = add_d2 (a, b); + for (i = 0; i < 2; i++) + { + printf ("r[%d] = %g (want %g)\n", i, r[i], ref[i]); + CHECK (r[i] == ref[i]); + } + + exit (0); +} diff --git a/deps/libffi/testsuite/libffi.vector/vector_double4.c b/deps/libffi/testsuite/libffi.vector/vector_double4.c new file mode 100644 index 000000000000..9f4473935929 --- /dev/null +++ b/deps/libffi/testsuite/libffi.vector/vector_double4.c @@ -0,0 +1,81 @@ +/* Area: ffi_call + Purpose: A 32-byte double4 vector. On AArch64 a bare vector wider than + 16 bytes is passed by reference and returned in memory (no + short-vector register class), so the call must round-trip. On + x86-64 wider-than-16-byte vectors are not implemented, so + ffi_prep_cif must report FFI_BAD_TYPEDEF. + Limitations: none. + PR: none. + Originator: libffi vector support. */ + +/* { dg-do run } */ + +#include "vector.h" + +typedef double d4 __attribute__((vector_size (32))); + +/* Only called on ports that can actually marshal a 32-byte vector. */ +static d4 add_d4 (d4 a, d4 b) __UNUSED__; + +static d4 +add_d4 (d4 a, d4 b) +{ + return a + b; +} + +int +main (void) +{ + ffi_cif cif; + ffi_type vec_type; + ffi_type *vec_elems[5]; + ffi_type *args[2]; + + make_vector_type (&vec_type, vec_elems, &ffi_type_double, 4); + args[0] = &vec_type; + args[1] = &vec_type; + +#if defined(__aarch64__) || defined(_M_ARM64) + { + void *values[2]; + d4 a = { 1, 2, 3, 4 }; + d4 b = { 10, 20, 30, 40 }; + d4 r, ref; + int i; + + values[0] = &a; + values[1] = &b; + + CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 2, &vec_type, args) == FFI_OK); + CHECK (vec_type.size == 32); + CHECK (vec_type.alignment == 16); + + ffi_call (&cif, FFI_FN (add_d4), &r, values); + + ref = add_d4 (a, b); + for (i = 0; i < 4; i++) + { + printf ("r[%d] = %g (want %g)\n", i, r[i], ref[i]); + CHECK (r[i] == ref[i]); + } + } +#else + { + /* x86-64 (and any other opted-in port without >16B support): the >16-byte + vector must be rejected, both as a return type and as an argument. */ + ffi_status s_ret, s_arg; + + s_ret = ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 0, &vec_type, NULL); + printf ("32-byte vector return: status %d (want %d = FFI_BAD_TYPEDEF)\n", + s_ret, FFI_BAD_TYPEDEF); + CHECK (s_ret == FFI_BAD_TYPEDEF); + + s_arg = ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 1, &ffi_type_void, args); + printf ("32-byte vector argument: status %d (want %d = FFI_BAD_TYPEDEF)\n", + s_arg, FFI_BAD_TYPEDEF); + CHECK (s_arg == FFI_BAD_TYPEDEF); + } +#endif + + exit (0); +} diff --git a/deps/libffi/testsuite/libffi.vector/vector_float32x2.c b/deps/libffi/testsuite/libffi.vector/vector_float32x2.c new file mode 100644 index 000000000000..f613687a2988 --- /dev/null +++ b/deps/libffi/testsuite/libffi.vector/vector_float32x2.c @@ -0,0 +1,53 @@ +/* Area: ffi_call + Purpose: Pass and return an 8-byte float32x2 vector (single D/SSE reg). + Limitations: none. + PR: none. + Originator: libffi vector support. */ + +/* { dg-do run } */ + +#include "vector.h" + +typedef float f32x2 __attribute__((vector_size (8))); + +static f32x2 +add_f32x2 (f32x2 a, f32x2 b) +{ + return a + b; +} + +int +main (void) +{ + ffi_cif cif; + ffi_type vec_type; + ffi_type *vec_elems[3]; + ffi_type *args[2]; + void *values[2]; + f32x2 a = { 3, 4 }; + f32x2 b = { 5, 6 }; + f32x2 r, ref; + int i; + + make_vector_type (&vec_type, vec_elems, &ffi_type_float, 2); + + args[0] = &vec_type; + args[1] = &vec_type; + values[0] = &a; + values[1] = &b; + + CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 2, &vec_type, args) == FFI_OK); + CHECK (vec_type.size == 8); + CHECK (vec_type.alignment == 8); + + ffi_call (&cif, FFI_FN (add_f32x2), &r, values); + + ref = add_f32x2 (a, b); + for (i = 0; i < 2; i++) + { + printf ("r[%d] = %g (want %g)\n", i, (double) r[i], (double) ref[i]); + CHECK (r[i] == ref[i]); + } + + exit (0); +} diff --git a/deps/libffi/testsuite/libffi.vector/vector_float32x4.c b/deps/libffi/testsuite/libffi.vector/vector_float32x4.c new file mode 100644 index 000000000000..971814aaf66c --- /dev/null +++ b/deps/libffi/testsuite/libffi.vector/vector_float32x4.c @@ -0,0 +1,54 @@ +/* Area: ffi_call + Purpose: Pass and return a 16-byte float32x4 vector (the vec4 shape of + libffi/libffi#773). + Limitations: none. + PR: libffi/libffi#773. + Originator: libffi vector support. */ + +/* { dg-do run } */ + +#include "vector.h" + +typedef float f32x4 __attribute__((vector_size (16))); + +static f32x4 +add_f32x4 (f32x4 a, f32x4 b) +{ + return a + b; +} + +int +main (void) +{ + ffi_cif cif; + ffi_type vec_type; + ffi_type *vec_elems[5]; + ffi_type *args[2]; + void *values[2]; + f32x4 a = { 1, 2, 3, 4 }; + f32x4 b = { 10, 20, 30, 40 }; + f32x4 r, ref; + int i; + + make_vector_type (&vec_type, vec_elems, &ffi_type_float, 4); + + args[0] = &vec_type; + args[1] = &vec_type; + values[0] = &a; + values[1] = &b; + + CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 2, &vec_type, args) == FFI_OK); + CHECK (vec_type.size == 16); + CHECK (vec_type.alignment == 16); + + ffi_call (&cif, FFI_FN (add_f32x4), &r, values); + + ref = add_f32x4 (a, b); + for (i = 0; i < 4; i++) + { + printf ("r[%d] = %g (want %g)\n", i, (double) r[i], (double) ref[i]); + CHECK (r[i] == ref[i]); + } + + exit (0); +} diff --git a/deps/libffi/testsuite/libffi.vector/vector_hva.c b/deps/libffi/testsuite/libffi.vector/vector_hva.c new file mode 100644 index 000000000000..5f80da07dfde --- /dev/null +++ b/deps/libffi/testsuite/libffi.vector/vector_hva.c @@ -0,0 +1,74 @@ +/* Area: ffi_call + Purpose: Pass and return a homogeneous vector aggregate: a struct of two + identical 16-byte vectors. On AArch64 this is an HVA carried in + a pair of Q registers; on x86-64 the existing SSE struct + classification handles it (four SSE eightbytes). Both round-trip. + Limitations: none. + PR: none. + Originator: libffi vector support. */ + +/* { dg-do run } */ + +#include "vector.h" + +typedef float f32x4 __attribute__((vector_size (16))); + +struct hva2 +{ + f32x4 a; + f32x4 b; +}; + +static struct hva2 +bump (struct hva2 s) +{ + s.a = s.a + 1; + s.b = s.b + 2; + return s; +} + +int +main (void) +{ + ffi_cif cif; + ffi_type vec_type; + ffi_type *vec_elems[5]; + ffi_type struct_type; + ffi_type *struct_elems[3]; + ffi_type *args[1]; + void *values[1]; + struct hva2 in = { { 1, 2, 3, 4 }, { 10, 20, 30, 40 } }; + struct hva2 out, ref; + int i; + + make_vector_type (&vec_type, vec_elems, &ffi_type_float, 4); + + struct_elems[0] = &vec_type; + struct_elems[1] = &vec_type; + struct_elems[2] = NULL; + struct_type.size = 0; + struct_type.alignment = 0; + struct_type.type = FFI_TYPE_STRUCT; + struct_type.elements = struct_elems; + + args[0] = &struct_type; + values[0] = ∈ + + CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 1, &struct_type, args) + == FFI_OK); + CHECK (struct_type.size == 32); + + ffi_call (&cif, FFI_FN (bump), &out, values); + + ref = bump (in); + for (i = 0; i < 4; i++) + { + printf ("a[%d] = %g (want %g), b[%d] = %g (want %g)\n", + i, (double) out.a[i], (double) ref.a[i], + i, (double) out.b[i], (double) ref.b[i]); + CHECK (out.a[i] == ref.a[i]); + CHECK (out.b[i] == ref.b[i]); + } + + exit (0); +} diff --git a/deps/libffi/testsuite/libffi.vector/vector_int32x4.c b/deps/libffi/testsuite/libffi.vector/vector_int32x4.c new file mode 100644 index 000000000000..eaa6b802bab5 --- /dev/null +++ b/deps/libffi/testsuite/libffi.vector/vector_int32x4.c @@ -0,0 +1,54 @@ +/* Area: ffi_call + Purpose: Pass and return a 16-byte int32x4 integer vector. Integer + lanes still travel in a vector register, unlike an HFA of ints. + Limitations: none. + PR: none. + Originator: libffi vector support. */ + +/* { dg-do run } */ + +#include "vector.h" + +typedef int i32x4 __attribute__((vector_size (16))); + +static i32x4 +add_i32x4 (i32x4 a, i32x4 b) +{ + return a + b; +} + +int +main (void) +{ + ffi_cif cif; + ffi_type vec_type; + ffi_type *vec_elems[5]; + ffi_type *args[2]; + void *values[2]; + i32x4 a = { 1, 2, 3, 4 }; + i32x4 b = { 5, 6, 7, 8 }; + i32x4 r, ref; + int i; + + make_vector_type (&vec_type, vec_elems, &ffi_type_sint32, 4); + + args[0] = &vec_type; + args[1] = &vec_type; + values[0] = &a; + values[1] = &b; + + CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 2, &vec_type, args) == FFI_OK); + CHECK (vec_type.size == 16); + CHECK (vec_type.alignment == 16); + + ffi_call (&cif, FFI_FN (add_i32x4), &r, values); + + ref = add_i32x4 (a, b); + for (i = 0; i < 4; i++) + { + printf ("r[%d] = %d (want %d)\n", i, r[i], ref[i]); + CHECK (r[i] == ref[i]); + } + + exit (0); +} diff --git a/deps/libffi/testsuite/libffi.vector/vector_validate.c b/deps/libffi/testsuite/libffi.vector/vector_validate.c new file mode 100644 index 000000000000..d923ab465fe4 --- /dev/null +++ b/deps/libffi/testsuite/libffi.vector/vector_validate.c @@ -0,0 +1,103 @@ +/* Area: ffi_prep_cif + Purpose: Validate that malformed vector type descriptors are rejected + with FFI_BAD_TYPEDEF, and that a well-formed vector is accepted + with the computed power-of-two size and min(size,16) alignment. + Limitations: none. + PR: none. + Originator: libffi vector support. */ + +/* { dg-do run } */ + +#include "vector.h" + +int +main (void) +{ + ffi_cif cif; + + /* Heterogeneous lanes (float mixed with double) -> FFI_BAD_TYPEDEF. */ + { + ffi_type vt; + ffi_type *elems[3]; + ffi_type *args[1]; + elems[0] = &ffi_type_float; + elems[1] = &ffi_type_double; + elems[2] = NULL; + vt.size = 0; + vt.alignment = 0; + vt.type = FFI_TYPE_VECTOR; + vt.elements = elems; + args[0] = &vt; + CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 1, &ffi_type_void, args) + == FFI_BAD_TYPEDEF); + } + + /* An empty (zero-lane) vector -> FFI_BAD_TYPEDEF. */ + { + ffi_type vt; + ffi_type *elems[1]; + ffi_type *args[1]; + elems[0] = NULL; + vt.size = 0; + vt.alignment = 0; + vt.type = FFI_TYPE_VECTOR; + vt.elements = elems; + args[0] = &vt; + CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 1, &ffi_type_void, args) + == FFI_BAD_TYPEDEF); + } + + /* A non-scalar (struct) lane type -> FFI_BAD_TYPEDEF. */ + { + ffi_type inner; + ffi_type *inner_elems[2]; + ffi_type vt; + ffi_type *elems[3]; + ffi_type *args[1]; + inner_elems[0] = &ffi_type_float; + inner_elems[1] = NULL; + inner.size = 0; + inner.alignment = 0; + inner.type = FFI_TYPE_STRUCT; + inner.elements = inner_elems; + elems[0] = &inner; + elems[1] = &inner; + elems[2] = NULL; + vt.size = 0; + vt.alignment = 0; + vt.type = FFI_TYPE_VECTOR; + vt.elements = elems; + args[0] = &vt; + CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 1, &ffi_type_void, args) + == FFI_BAD_TYPEDEF); + } + + /* A well-formed 3 x float vector is accepted with computed layout. */ + { + ffi_type vt; + ffi_type *elems[4]; + ffi_type *args[1]; + make_vector_type (&vt, elems, &ffi_type_float, 3); + args[0] = &vt; + CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 1, &ffi_type_void, args) + == FFI_OK); + CHECK (vt.size == 16); /* 12 rounded up to 16 */ + CHECK (vt.alignment == 16); /* min(16, 16) */ + } + + /* An 8-byte vector gets alignment 8 = min(8, 16). */ + { + ffi_type vt; + ffi_type *elems[3]; + ffi_type *args[1]; + make_vector_type (&vt, elems, &ffi_type_float, 2); + args[0] = &vt; + CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 1, &ffi_type_void, args) + == FFI_OK); + CHECK (vt.size == 8); + CHECK (vt.alignment == 8); + } + + printf ("vector validation ok\n"); + exit (0); +} diff --git a/deps/libffi/testsuite/libffi.vector/vector_vec3.c b/deps/libffi/testsuite/libffi.vector/vector_vec3.c new file mode 100644 index 000000000000..5a0367283023 --- /dev/null +++ b/deps/libffi/testsuite/libffi.vector/vector_vec3.c @@ -0,0 +1,73 @@ +/* Area: ffi_call + Purpose: Pass and return a three-lane float vector. Clang's + ext_vector_type(3) has 12 bytes of data padded to 16-byte + storage; libffi's power-of-two size rule must reproduce that + layout so a natively compiled callee agrees. + Limitations: Clang only (GCC's vector_size requires power-of-two totals and + rejects a 12-byte vector). A no-op on other compilers. + PR: none. + Originator: libffi vector support. */ + +/* { dg-do run } */ + +#include "vector.h" + +#ifdef __clang__ + +typedef float f3 __attribute__((ext_vector_type (3))); + +static f3 +scale3 (f3 v) +{ + f3 r; + r[0] = v[0] + 1; + r[1] = v[1] + 2; + r[2] = v[2] + 3; + return r; +} + +int +main (void) +{ + ffi_cif cif; + ffi_type vec_type; + ffi_type *vec_elems[4]; + ffi_type *args[1]; + void *values[1]; + f3 a = { 10, 20, 30 }; + f3 r, ref; + int i; + + make_vector_type (&vec_type, vec_elems, &ffi_type_float, 3); + + args[0] = &vec_type; + values[0] = &a; + + CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 1, &vec_type, args) == FFI_OK); + /* 3 x float = 12, rounded up to 16 (matches ext_vector_type storage). */ + CHECK (vec_type.size == 16); + CHECK (vec_type.alignment == 16); + CHECK (sizeof (f3) == 16); + + ffi_call (&cif, FFI_FN (scale3), &r, values); + + ref = scale3 (a); + for (i = 0; i < 3; i++) + { + printf ("r[%d] = %g (want %g)\n", i, (double) r[i], (double) ref[i]); + CHECK (r[i] == ref[i]); + } + + exit (0); +} + +#else + +int +main (void) +{ + /* ext_vector_type is a Clang extension; nothing to test elsewhere. */ + exit (0); +} + +#endif