@@ -1596,6 +1596,158 @@ IFUNC requirements for dynamic linkers
15961596To resolve an ``R_AARCH64_IRELATIVE `` relocation the dynamic linker
15971597performs the calculation described in AAELF64 _ Dynamic Relocations.
15981598
1599+ Function Multi-versioning
1600+ -------------------------
1601+
1602+ Function Multi-versioning (FMV) is an Arm C Language Extension that
1603+ lets the compiler generate multiple function versions and auto-dispatch
1604+ between them. Each of the function versions is specialized for a set
1605+ of architecture extensions. The most suitable version is selected
1606+ at load time. This requires runtime information about the CPU features
1607+ available on the host. FMV is supported on GNU/Linux, Android, and
1608+ many of the BSD operating systems.
1609+
1610+ On System V platforms Function Multi-versioning is implemented using
1611+ GNU Indirect Functions (IFUNC). The compiler generated IFUNC resolver
1612+ may rely on the presence of a global variable ``__aarch64_cpu_features ``
1613+ provided by the runtime library. It contains information about the
1614+ available CPU features. The runtime library must also provide a
1615+ function ``__init_cpu_features_resolver `` that the IFUNC resolver
1616+ can call to initialize ``__aarch64_cpu_features ``.
1617+
1618+ .. code-block :: c
1619+
1620+ uint64_t __aarch64_cpu_features = 0;
1621+
1622+ The variable may contain the following fields:
1623+
1624+ .. table :: CPU features detected
1625+
1626+ +-------------------+----------+
1627+ | Name | Value |
1628+ +===================+==========+
1629+ | FEAT_RNG | 1U << 0 |
1630+ +-------------------+----------+
1631+ | FEAT_FLAGM | 1U << 1 |
1632+ +-------------------+----------+
1633+ | FEAT_FLAGM2 | 1U << 2 |
1634+ +-------------------+----------+
1635+ | FEAT_FLAGM2 | 1U << 3 |
1636+ +-------------------+----------+
1637+ | FEAT_FP16FML | 1U << 4 |
1638+ +-------------------+----------+
1639+ | FEAT_DOTPROD | 1U << 5 |
1640+ +-------------------+----------+
1641+ | FEAT_SM4 | 1U << 6 |
1642+ +-------------------+----------+
1643+ | FEAT_RDM | 1U << 7 |
1644+ +-------------------+----------+
1645+ | FEAT_LSE | 1U << 8 |
1646+ +-------------------+----------+
1647+ | FEAT_FP | 1U << 9 |
1648+ +-------------------+----------+
1649+ | FEAT_SIMD | 1U << 10 |
1650+ +-------------------+----------+
1651+ | FEAT_CRC | 1U << 11 |
1652+ +-------------------+----------+
1653+ | FEAT_CSSC | 1U << 12 |
1654+ +-------------------+----------+
1655+ | FEAT_SHA2 | 1U << 13 |
1656+ +-------------------+----------+
1657+ | FEAT_SHA3 | 1U << 14 |
1658+ +-------------------+----------+
1659+ | FEAT_PMULL | 1U << 16 |
1660+ +-------------------+----------+
1661+ | FEAT_FP16 | 1U << 17 |
1662+ +-------------------+----------+
1663+ | FEAT_DIT | 1U << 18 |
1664+ +-------------------+----------+
1665+ | FEAT_DPB | 1U << 19 |
1666+ +-------------------+----------+
1667+ | FEAT_DPB2 | 1U << 20 |
1668+ +-------------------+----------+
1669+ | FEAT_JSCVT | 1U << 21 |
1670+ +-------------------+----------+
1671+ | FEAT_FCMA | 1U << 22 |
1672+ +-------------------+----------+
1673+ | FEAT_RCPC | 1U << 23 |
1674+ +-------------------+----------+
1675+ | FEAT_RCPC2 | 1U << 24 |
1676+ +-------------------+----------+
1677+ | FEAT_FRINTTS | 1U << 25 |
1678+ +-------------------+----------+
1679+ | FEAT_I8MM | 1U << 27 |
1680+ +-------------------+----------+
1681+ | FEAT_BF16 | 1U << 28 |
1682+ +-------------------+----------+
1683+ | FEAT_SVE | 1U << 31 |
1684+ +-------------------+----------+
1685+ | FEAT_SVE_F32MM | 1U << 35 |
1686+ +-------------------+----------+
1687+ | FEAT_SVE_F64MM | 1U << 36 |
1688+ +-------------------+----------+
1689+ | FEAT_SVE2 | 1U << 37 |
1690+ +-------------------+----------+
1691+ | FEAT_SVE_PMULL128 | 1U << 39 |
1692+ +-------------------+----------+
1693+ | FEAT_SVE_BITPERM | 1U << 40 |
1694+ +-------------------+----------+
1695+ | FEAT_SVE_SHA3 | 1U << 41 |
1696+ +-------------------+----------+
1697+ | FEAT_SVE_SM4 | 1U << 42 |
1698+ +-------------------+----------+
1699+ | FEAT_SME | 1U << 43 |
1700+ +-------------------+----------+
1701+ | FEAT_MEMTAG2 | 1U << 45 |
1702+ +-------------------+----------+
1703+ | FEAT_SB | 1U << 47 |
1704+ +-------------------+----------+
1705+ | FEAT_SSBS2 | 1U << 50 |
1706+ +-------------------+----------+
1707+ | FEAT_BTI | 1U << 51 |
1708+ +-------------------+----------+
1709+ | FEAT_WFXT | 1U << 55 |
1710+ +-------------------+----------+
1711+ | FEAT_SME_F64 | 1U << 56 |
1712+ +-------------------+----------+
1713+ | FEAT_SME_I64 | 1U << 57 |
1714+ +-------------------+----------+
1715+ | FEAT_SME2 | 1U << 58 |
1716+ +-------------------+----------+
1717+ | FEAT_RCPC3 | 1U << 59 |
1718+ +-------------------+----------+
1719+ | FEAT_MOPS | 1U << 60 |
1720+ +-------------------+----------+
1721+
1722+ Implementing FMV using ``__aarch64_cpu_features `` is not required.
1723+ Accessing ``__aarch64_cpu_features `` is reserved for the compiler
1724+ generated code or the runtime library. If the variable is only
1725+ accessed by the FMV resolvers, then it may be placed in the
1726+ `Relocation Read Only (RELRO) `_ program segment to prevent it from
1727+ being modified after the FMV resolvers have run. The variable must
1728+ be defined as DSO-local with its symbol visibility set to
1729+ ``STV_HIDDEN ``.
1730+
1731+ .. note ::
1732+
1733+ The ``__aarch64_cpu_features `` variable may be used by the runtime
1734+ library or by compiler generated code besides FMV. In that case the
1735+ runtime library must ensure that the variable is initialized via a
1736+ constructor function and cannot be placed in the ``RELRO `` segment.
1737+
1738+ The ``__init_cpu_features_resolver `` function has the following
1739+ prototype:
1740+
1741+ .. code-block :: c
1742+
1743+ void __init_cpu_features_resolver (uint64_t, const uint64_t *);
1744+
1745+ The above interface expects the same parameters as a GNU Indirect
1746+ Function resolver. See `GNU C Library IFUNC interface `_. Other
1747+ platforms may use a different interface with the runtime library.
1748+ However, all implementations must provide a DSO-local definition
1749+ of the function by setting the symbol visibility to ``STV_HIDDEN ``.
1750+
15991751Initialization and Termination Functions
16001752----------------------------------------
16011753
0 commit comments