Assembly (x86-64, AArch64, RISC-V) Module 19 – The three ISAs today, compared
AArch64 today: Armv9 features on real machines
Read Arm FEAT_ names and the version that made each feature optional or mandatory, then see which features one Apple silicon Mac reports and runs.
What you will learn
- Read an Arm FEAT_ name and find the version that made the feature optional or mandatory
- Identify the features a processor reports through macOS sysctl keys or Linux HWCAP bits
- Describe what PAC, BTI, MTE, LSE, SVE and SME each add to AArch64
- Recognise LSE, CSSC and SME instructions in compiler output and in runs on Apple silicon
- Compare the Apple, Linux and Windows platform ABIs for AArch64 in compiler output
Before you start
What you’ll learn · Before you start
What you will learn
- Read an Arm FEAT_ name and find the version that made the feature optional or mandatory
- Identify the features a processor reports through macOS sysctl keys or Linux HWCAP bits
- Describe what PAC, BTI, MTE, LSE, SVE and SME each add to AArch64
- Recognise LSE, CSSC and SME instructions in compiler output and in runs on Apple silicon
- Compare the Apple, Linux and Windows platform ABIs for AArch64 in compiler output
Before you start
On this page
On an Apple M5 Pro, macOS has 60 keys that carry Arm FEAT_ names, and 55 of them read 1; the Scalable Vector Extension, which Armv9 leaves optional, has no key at all. Each optional Arm feature has a FEAT_ name and a version that allowed it, and reading both, then reading what a machine reports, is how code uses what a processor has and nothing it lacks.
This page reads the names, the versions and one machine’s report. Its two further parts follow three features into compiler output and runs on that machine, and compare the rules Apple, Linux and Windows set on one instruction set.
Arm names each optional feature and dates it by version
Arm’s feature list gives every optional piece of the architecture a Arm feature name: The name Arm gives each optional part of its A-profile architecture, such as FEAT_LSE or FEAT_SME, listed with the version that made it optional and, for many, the version that made it mandatory. such as FEAT_LSE, a one-line title and two facts: the first version in which it is optional and, for many, the version from which it is mandatory. Code built for a version may assume its mandatory features and must test for the optional ones. Six names come up again and again:
- PAC (FEAT_PAuth) signs pointers with a short code in their unused high bits and checks it before use.
- BTI marks the instructions an indirect branch may land on.
- MTE gives memory and pointers small tags and can fault when they disagree.
- LSE adds atomic read-modify-write instructions such as
ldadd,casandswp. - SVE adds scalable vector: A SIMD extension whose vector length is picked by the implementation, so one binary runs on a 128-bit core and on a 2048-bit core without being recompiled. SVE on AArch64 and V 1.0 on RISC-V are scalable. More in “SIMD concepts and CPU feature detection”, whose length the processor chooses, from 128 to 2048 bits.
- SME adds matrix storage and a streaming mode: A processor state that SME adds to AArch64, entered with smstart sm and left with smstop sm, in which SVE instructions run at a streaming vector length of its own. More in “SIMD concepts and CPU feature detection” that runs vector code at its own length.
Walk through the versions to see when each became optional and when it became mandatory:
- Armv8.0
The A64 instruction set, with LSE optional optional LSE
Armv8.0 defines AArch64 and its A64 instructions. FEAT_LSE, the Large System Extensions with single-instruction atomics, is already allowed as an option.
- Armv8.1
LSE becomes mandatory mandatory LSE
From Armv8.1 every implementation has FEAT_LSE, so code built for Armv8.1 or later may use ldadd, cas and swp without testing for them.
- Armv8.2
SVE and pointer authentication allowed optional SVE, PAuth
FEAT_SVE, the Scalable Vector Extension, and FEAT_PAuth, pointer authentication, become optional; so do BF16 and FP16 arithmetic.
- Armv8.3
Pointer authentication becomes mandatory mandatory PAuth
From Armv8.3 FEAT_PAuth is mandatory, so every later processor can sign and check pointers.
- Armv8.4
BTI and MTE allowed, DIT mandatory
FEAT_BTI, branch target identification, and FEAT_MTE, the Memory Tagging Extension, become optional; FEAT_DIT, data-independent timing, becomes mandatory.
- Armv8.5
BTI becomes mandatory mandatory BTI
From Armv8.5 FEAT_BTI is mandatory. MTE stays optional in every later version, which is why a processor's report still matters.
- Armv8.7
CSSC allowed
FEAT_CSSC adds short scalar instructions such as cnt, ctz, abs and smin on general-purpose registers. It becomes optional here and mandatory from Armv8.9.
- Armv9.0
Armv8.5 plus a mandatory set of its own Armv9
An Armv9.0 implementation must be Armv8.5 compliant and add the mandatory Armv9.0 features. FEAT_SVE2 is optional from Armv9.0; Arm's list adds that Armv9-A systems for rich operating systems also provide hardware support for SVE2, yet no version makes SVE or SVE2 mandatory, so code still reads the report.
- Armv9.2
SME and SME2 allowed optional SME
FEAT_SME, the Scalable Matrix Extension, with its streaming mode, and FEAT_SME2 become optional. SVE stays optional too, so a processor may have SME without SVE.
The timeline has 9 events, from Armv8.0 to Armv9.2.
The pattern to keep is the gap between the two dates. LSE has been mandatory since Armv8.1 and BTI since Armv8.5, but MTE, SVE and SME stay optional in every version, Armv9 included. An Armv9.0 processor must be Armv8.5 compliant and add the Armv9.0 mandatory set, so Armv9 makes neither SVE nor MTE mandatory.
Checkpoint
Check: FEAT_ names and the versions behind them
A machine reports its features through the operating system
User code cannot read the processor’s ID registers directly, so each operating system reports them. macOS exposes one
sysctl key per feature, hw.optional.arm.FEAT_LSE and the rest; Linux sets bits in the
HWCAP: A word of bits the Linux kernel passes to every program in its auxiliary vector, one bit per processor feature it offers, such as HWCAP_ATOMICS on AArch64. Programs read it with getauxval(AT_HWCAP). words of the auxiliary vector, read with getauxval(AT_HWCAP), AT_HWCAP2 and
AT_HWCAP3. The session reads the keys on an Apple M5 Pro:
import pathlib
import sys
sys.path.insert(0, str(pathlib.Path(__file__).parent / "sessions"))
import session
session.run("""
# The processor, and how many Arm feature keys macOS reports for it, then how many of them are set to 1
/usr/sbin/sysctl -n machdep.cpu.brand_string
/usr/sbin/sysctl hw.optional.arm | grep -c 'FEAT_'
/usr/sbin/sysctl hw.optional.arm | grep -c 'FEAT_.*: 1$'
# The six features this page names, in the order the page names them
/usr/sbin/sysctl hw.optional.arm.FEAT_PAuth hw.optional.arm.FEAT_BTI hw.optional.arm.FEAT_MTE hw.optional.arm.FEAT_LSE
/usr/sbin/sysctl hw.optional.arm.FEAT_SME hw.optional.arm.FEAT_SME2
# SVE has no key at all on this processor
/usr/sbin/sysctl hw.optional.arm.FEAT_SVE
""") Output
# The processor, and how many Arm feature keys macOS reports for it, then how many of them are set to 1 $ /usr/sbin/sysctl -n machdep.cpu.brand_string Apple M5 Pro $ /usr/sbin/sysctl hw.optional.arm | grep -c 'FEAT_' 60 $ /usr/sbin/sysctl hw.optional.arm | grep -c 'FEAT_.*: 1$' 55 # The six features this page names, in the order the page names them $ /usr/sbin/sysctl hw.optional.arm.FEAT_PAuth hw.optional.arm.FEAT_BTI hw.optional.arm.FEAT_MTE hw.optional.arm.FEAT_LSE hw.optional.arm.FEAT_PAuth: 1 hw.optional.arm.FEAT_BTI: 1 hw.optional.arm.FEAT_MTE: 1 hw.optional.arm.FEAT_LSE: 1 $ /usr/sbin/sysctl hw.optional.arm.FEAT_SME hw.optional.arm.FEAT_SME2 hw.optional.arm.FEAT_SME: 1 hw.optional.arm.FEAT_SME2: 1 # SVE has no key at all on this processor $ /usr/sbin/sysctl hw.optional.arm.FEAT_SVE sysctl: unknown oid 'hw.optional.arm.FEAT_SVE' [exit status 1]
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 features_session.py
Of the six features above, five read 1 and FEAT_SVE is an unknown key. The same features have these names on Linux,
where the kernel documents which ID-register field each bit stands for:
| Feature | macOS sysctl key | Linux HWCAP bit | M5 Pro |
|---|---|---|---|
| LSE | hw.optional.arm.FEAT_LSE |
HWCAP_ATOMICS |
1 |
| PAC | hw.optional.arm.FEAT_PAuth |
HWCAP_PACA, HWCAP_PACG |
1 |
| BTI | hw.optional.arm.FEAT_BTI |
HWCAP2_BTI |
1 |
| MTE | hw.optional.arm.FEAT_MTE |
HWCAP2_MTE |
1 |
| SVE | hw.optional.arm.FEAT_SVE |
HWCAP_SVE |
no key |
| SME | hw.optional.arm.FEAT_SME |
HWCAP2_SME |
1 |
A report says what the processor and the kernel offer, not what a binary uses. That takes compiler options or run-time checks, the subject of this page’s first further part; its second compares the platform ABIs: Apple’s, Linux’s AAPCS64 and Windows on Arm’s.
Key idea
Read a feature’s name and its versions in Arm’s list, then read the machine’s report before using it: a version promises only the features it makes mandatory.
Checkpoint
Check: How a machine reports its features
Practise
- Run
sysctl hw.optional.armon any Apple silicon Mac and count theFEAT_keys at 1, as the session’s grep does; compare the count with the 55 above. - Pick two FEAT_ names from the session and find the version that made each optional in Arm’s feature list.
- On a Linux AArch64 machine, print
getauxval(AT_HWCAP)from a small C program and test theHWCAP_ATOMICSbit, as the kernel’s hwcaps documentation shows.
Practice that adapts to you
Practise this lesson
10 questions about 4 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.
Three features as instructions: LSE, CSSC and SME on Apple silicon Pro: opens with a Pro, Premium or Ultimate pass
A feature key becomes useful when it changes the instructions a program runs. This part builds code for three of those features, LSE, CSSC and SME, runs the CSSC and SME code on the M5 Pro, and runs one SVE instruction there too, although the report says the processor has no SVE.
In this part:
- An atomic increment becomes one instruction from Armv8.1
- A helper can choose between the two forms at run time
- CSSC appears only when the compiler knows the processor has it
- SME without SVE: one vector length reads, the other faults
4 runnable examples (C, Python, cssc.s, cssc_main.c, popcount.c, vl.s, vl_main.c) · about 5 minutes
Opening this part with your pass…
This part opens with any MySmartCoPilot pass.
- Pro pass · 1 week₹79$2.99
- 30 days₹179$5.99
- 1 year₹1,699$45
One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.
Passes can’t be bought right now, so this part can’t be opened at the moment. The free part above stands on its own. If you have a pass, enter your licence key.
It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).
Apple, Linux and Windows: three ABIs on one instruction set, measured Pro: opens with a Pro, Premium or Ultimate pass
The instructions are the same on every AArch64 platform, but the rules for calling, sizes and reserved registers are not. This part asks the compiler five questions for three targets and reads the answers in its output.
In this part:
- A char is signed on two platforms and unsigned on one
- long and long double change size by platform
- Variadic arguments go straight to the stack only on Apple
- A variadic double travels three different ways
- Two platforms keep x18 for themselves
2 runnable examples (C, Python) · about 5 minutes
Opening this part with your pass…
This part opens with any MySmartCoPilot pass.
- Pro pass · 1 week₹79$2.99
- 30 days₹179$5.99
- 1 year₹1,699$45
One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.
Passes can’t be bought right now, so this part can’t be opened at the moment. The free part above stands on its own. If you have a pass, enter your licence key.
It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).
Interview questions
What does a FEAT_ name such as FEAT_LSE tell you, and what does it not?
A FEAT_ name tells you which architectural feature you are talking about and, through Arm’s feature list, the version that made it optional and the version that made it mandatory: FEAT_LSE is optional from Armv8.0 and mandatory from Armv8.1. It does not tell you whether a given processor has it, or whether your binary uses it. For that you read the machine’s report, a sysctl key on macOS or a HWCAP bit on Linux, and the instructions your compiler emitted.
Three of this module’s bank questions start where this page stops: a fast path chosen at run time, a library ported between platform ABIs, and vector code for a processor with SME but no SVE.
-
Mid to senior
Your library has an LSE fast path and a load-exclusive fallback for its 64-bit counters. How would you choose between them at run time on macOS and on Linux, and which mistakes make the fast path crash or never run?
-
Mid to staff
A C parser passes every test on AArch64 Linux, but on Apple silicon and Windows on Arm it misreads some bytes, and one variadic logging call prints garbage on macOS. Which ABI differences would you check first, and how would you confirm each one?
-
Senior to staff
A teammate sees FEAT_SME2 set on an Apple M5-class Mac, enables the project's SVE kernels, and the program dies with SIGILL. Explain what happened, and how you would structure the vector code for that machine and for Linux servers with SVE.
Flashcards · 4 cards
Recall it, then check
Say the answer to yourself before you look: recalling it is what makes it stick.
-
What does a FEAT_ name such as FEAT_LSE tell you, and what does it not?
It names one architectural feature, and Arm's list gives the version that made it optional and often the one that made it mandatory: FEAT_LSE is optional from Armv8.0 and mandatory from Armv8.1. It does not say whether a given processor has it, or whether your binary uses it.
-
What does targeting an Arm architecture version promise about features?
Only the features that version makes mandatory. LSE is mandatory from Armv8.1 and BTI from Armv8.5, while MTE, SVE and SME stay optional even in Armv9.
-
How does a program learn which Arm features a machine really has?
It reads the operating system's report: sysctl keys on macOS, HWCAP bits on Linux, which a program reads with getauxval(AT_HWCAP), one bit per feature such as HWCAP_ATOMICS.
-
Besides the machine's report, what must you check before relying on an Arm feature?
The instructions your compiler actually emitted, since the feature name and the machine's support say nothing about whether the binary uses it.
Key takeaways
- Every optional Arm feature has a FEAT_ name, a version from which it is optional and often one from which it is mandatory, and a version promises only its mandatory features.
- LSE and BTI are mandatory from Armv8.1 and Armv8.5, while MTE, SVE and SME stay optional even in Armv9.
- macOS reports features as sysctl keys and Linux as HWCAP bits, and the recorded M5 Pro reports SME but has no SVE key.
Terms in this lesson
- Arm feature name
- The name Arm gives each optional part of its A-profile architecture, such as FEAT_LSE or FEAT_SME, listed with the version that made it optional and, for many, the version that made it mandatory.
- HWCAP
- A word of bits the Linux kernel passes to every program in its auxiliary vector, one bit per processor feature it offers, such as HWCAP_ATOMICS on AArch64. Programs read it with getauxval(AT_HWCAP).
References
- Feature names in A-profile architecture, issue 2026_09 (Arm Limited)
- Arm Architecture Reference Manual for A-profile architecture (DDI 0487) (Arm Limited)
- Arm A64 Instruction Set Architecture (DDI 0602) (Arm Limited)
- Determining instruction set characteristics (sysctl hw.optional keys) (Apple Inc.)
- Writing ARM64 code for Apple platforms (Apple Inc.)
- ARM64 ELF hwcaps (The kernel development community)
- Overview of ARM64 ABI conventions (Microsoft)
- Data Type Ranges (Microsoft C++) (Microsoft)
- Abstract Data Models (64-bit Windows, LLP64) (Microsoft)
- Using the GNU Compiler Collection: AArch64 Options (-moutline-atomics) (GNU Project)
- Procedure Call Standard for the Arm 64-bit Architecture (AAPCS64) (Arm Limited)
Report a problem with this lesson
Kept only in this browser. Your Learn progress