Skip to content

Commit 6e22c5e

Browse files
authored
[FMV][AArch64] Document the interface for Function Multi-versioning. (#332)
Documents the Application Binary Interface requirements for Function Multi-versioning (FMV) on System V platforms. A global variable `__aarch64_cpu_features` provided by the runtime library contains information about the available CPU features. The variable must be defined as DSO-local with its symbol visibility set to `STV_HIDDEN`. A function `__init_cpu_features_resolver` provided by the runtime library is used for initializing the variable `__aarch64_cpu_features`. The function must be defined as DSO-local with its symbol visibility set to `STV_HIDDEN`. Accessing `__aarch64_cpu_features` is reserved for the compiler generated code or the runtime library. If the variable is only accessed for FMV, then it may be placed in the Relocation Read Only (RELRO) program segment to prevent it from being modified. Otherwise, if the variable is used besides FMV the runtime library must ensure that it is initialized via a constructor function and cannot be placed in the `RELRO` segment.
1 parent f5d025d commit 6e22c5e

File tree

1 file changed

+152
-0
lines changed

1 file changed

+152
-0
lines changed

sysvabi64/sysvabi64.rst

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1596,6 +1596,158 @@ IFUNC requirements for dynamic linkers
15961596
To resolve an ``R_AARCH64_IRELATIVE`` relocation the dynamic linker
15971597
performs 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+
15991751
Initialization and Termination Functions
16001752
----------------------------------------
16011753

0 commit comments

Comments
 (0)