Skip to content

Commit 80b917a

Browse files
[SME] Add __arm_agnostic("sme_za_state") keyword attribute (#336)
The `__arm_agnostic` keyword attribute enables the user to specify that a function is agnostic to a specified piece of architectural state. That means that the function must preserve this state when it exists, or otherwise ignores its contents. The reason for not naming this something like `__arm_za_compatible` was so that we might want use the attribute keyword for other architectural state in the future.
1 parent ff7467b commit 80b917a

File tree

1 file changed

+52
-10
lines changed

1 file changed

+52
-10
lines changed

main/acle.md

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ Armv8.4-A [[ARMARMv84]](#ARMARMv84). Support is added for the Dot Product intrin
432432
[`arm_neon_sve_bridge.h`](#arm_neon_sve_bridge.h) header file, rather
433433
than the [NEON-SVE bridge](#neon-sve-bridge) intrinsics.
434434
* Removed extraneous `const` from SVE2.1 store intrinsics.
435+
* Added [`__arm_agnostic`](#arm_agnostic) keyword attribute.
435436

436437
### References
437438

@@ -861,6 +862,7 @@ predefine the associated macro to a nonzero value.
861862

862863
| **Name** | **Target** | **Predefined macro** |
863864
| ----------------------------------------------------------- | --------------------- | --------------------------------- |
865+
| [`__arm_agnostic`](#arm_agnostic) | function type | `__ARM_FEATURE_SME` |
864866
| [`__arm_locally_streaming`](#arm_locally_streaming) | function declaration | `__ARM_FEATURE_LOCALLY_STREAMING` |
865867
| [`__arm_in`](#ways-of-sharing-state) | function type | Argument-dependent |
866868
| [`__arm_inout`](#ways-of-sharing-state) | function type | Argument-dependent |
@@ -5059,6 +5061,31 @@ if such a restoration is necessary. For example:
50595061
}
50605062
```
50615063

5064+
## `__arm_agnostic`
5065+
5066+
A function with the `__arm_agnostic` [keyword attribute](#keyword-attributes)
5067+
must preserve the architectural state that is specified by its arguments when
5068+
such state exists at runtime. The function is otherwise unconcerned with this
5069+
state.
5070+
5071+
The `__arm_agnostic` [keyword attribute](#keyword-attributes) applies to
5072+
**function types** and accepts the following arguments:
5073+
5074+
```"sme_za_state"```
5075+
5076+
* This attribute affects the ABI of a function, which must implement an
5077+
[agnostic-ZA interface](#agnostic-za). It is the compiler's responsibility
5078+
to ensure that the function's object code honors the ABI requirements.
5079+
5080+
* The use of `__arm_agnostic("sme_za_state")` allows writing functions that
5081+
are compatible with ZA state without having to share ZA state with the
5082+
caller, as required by `__arm_preserves`. The use of this attribute
5083+
does not imply that SME is available.
5084+
5085+
* It is not valid for a function declaration with
5086+
`__arm_agnostic("sme_za_state")` to [share](#shares-state) PSTATE.ZA state
5087+
with its caller.
5088+
50625089
## Mapping to the Procedure Call Standard
50635090

50645091
[[AAPCS64]](#AAPCS64) classifies functions as having one of the following
@@ -5070,13 +5097,21 @@ interfaces:
50705097

50715098
* a “shared-ZA” interface
50725099

5073-
If a C or C++ function F forms part of the object code's ABI, that
5074-
object code function has a shared-ZA interface if and only if at least
5075-
one of the following is true:
5100+
<span id="agnostic-za"></span>
5101+
5102+
* an "agnostic-ZA" interface
5103+
5104+
If a C or C++ function F forms part of the object code's ABI:
50765105

5077-
* F shares ZA with its caller
5106+
* the object code function has a shared-ZA interface if and only if at least
5107+
one of the following is true:
50785108

5079-
* F shares ZT0 with its caller
5109+
* F shares ZA with its caller
5110+
5111+
* F shares ZT0 with its caller
5112+
5113+
* the object code function has an agnostic-ZA interface if and only if F's type
5114+
has an `__arm_agnostic("sme_za_state")` attribute.
50805115

50815116
All other functions have a private-ZA interface.
50825117

@@ -5161,12 +5196,15 @@ function F if at least one of the following is true:
51615196
Otherwise, ZA can be in any state on entry to A if at least one of the
51625197
following is true:
51635198

5164-
* F [uses](#uses-state) `"za"`
5199+
* F [uses](#uses-state) `"za"`.
5200+
5201+
* F [uses](#uses-state) `"zt0"`.
51655202

5166-
* F [uses](#uses-state) `"zt0"`
5203+
* F's type has an [`__arm_agnostic("sme_za_state")` attribute](#agnostic-za)
5204+
and A's clobber-list includes neither `"za"` nor `"zt0"`.
51675205

5168-
Otherwise, ZA can be off or dormant on entry to A, as for what AAPCS64
5169-
calls “private-ZA” functions.
5206+
Otherwise, ZA can be off or dormant on entry to A, in the same way as if F were
5207+
to call what the [[AAPCS64]](#AAPCS64) describes as a "private-ZA" function.
51705208

51715209
If ZA is active on entry to A then A's instructions must ensure that
51725210
ZA is also active when the asm finishes.
@@ -5193,7 +5231,11 @@ depend on ZT0 as well as ZA.
51935231
| off | off | F's uses and A's clobbers are disjoint |
51945232
| dormant | dormant | " " " |
51955233
| dormant | off | " " ", and A clobbers `"za"` |
5196-
| active | active | F uses `"za"` and/or `"zt0"` |
5234+
| active | active | F uses `"za"` and/or `"zt0"`, or |
5235+
| | | F's type has an |
5236+
| | | `__arm_agnostic("sme_za_state")` |
5237+
| | | attribute with A's clobber-list |
5238+
| | | including neither `"za"` nor `"zt0"` |
51975239

51985240
The [`__ARM_STATE` macros](#state-strings) indicate whether a compiler
51995241
is guaranteed to support a particular clobber string. For example,

0 commit comments

Comments
 (0)