Introduction
SME, the Scalable Matrix Extension, adds a two-dimensional register and instructions that update a whole matrix at once. It uses the Z and P registers of SVE for its source operands.
ZA is the array register. It is a square of storage, with one row for each byte of the streaming vector length. If that length is SVL bits, ZA holds SVL ÷ 8 rows of SVL bits each, so its size follows the streaming vector length.
Instructions address ZA through tiles, square views made of elements of one size:
za0.bis the whole array, as 8-bit elements;za0.handza1.hare two tiles of 16-bit elements;za0.stoza3.sare four tiles of 32-bit elements;za0.dtoza7.dare eight tiles of 64-bit elements;za0.qtoza15.qare sixteen tiles of 128-bit elements.
Tiles of different sizes overlap. For example, za0.h is the same storage
as za0.d, za2.d, za4.d and za6.d.
A slice is one row or one column of a tile. An H after the tile number
means a horizontal slice and a V means a vertical slice: za0h.s[w12, 1] is
a row and za0v.s[w12, 1] is a column. The slice number is the sum of a
register, W12 to W15, and an immediate, modulo the number of slices in the tile.
Streaming SVE mode is a processor state, PSTATE.SM. In this mode the SVE registers have the streaming vector length, which can differ from the normal SVE vector length, and some other instructions are not available. ZA has its own enable bit, PSTATE.ZA.
The smstart and smstop instructions, aliases of
msr, change these two bits:
smstartenters streaming mode and enables ZA;smstart smandsmstart zado just one of the two;smstopleaves streaming mode and disables ZA;smstop smandsmstop zado just one of the two;- a change of PSTATE.SM sets the Z and P registers and FFR to zero;
- turning ZA on sets ZA to zero; turning it off leaves its contents unknown.
The instructions below need ZA to be enabled. All of them except
ldr, str and zero also need streaming mode. None
of the instructions on this page changes the NZCV flags.
Several instructions take two governing predicates, P0 to P7. The first predicate chooses rows of the tile and the second chooses columns.
The instructions
Moving between Z registers and ZA
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
mov | mov za0h.b[w12, 0], p0/m, z0.bmov z0.b, p0/m, za0h.b[w12, 0] | Copies a vector to a tile slice, or a tile slice to a vector. The elements can be .b, .h, .s, .d or .q. Inactive elements of the destination stay unchanged. This is an alias of mova. | – |
Loading and storing ZA
The slice loads and stores use a base register and an optional scaled register offset.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
ld1b, ld1h, ld1w, ld1d, ld1q | ld1b {za0h.b[w12, 0]}, p0/z, [x0]ld1w {za0v.s[w12, 3]}, p0/z, [x0, x1, lsl #2] | Loads bytes, halfwords, words, doublewords or quadwords from memory into a tile slice. Inactive elements are set to zero and do not read Device memory or fault. | – |
st1b, st1h, st1w, st1d, st1q | st1b {za0h.b[w12, 0]}, p0, [x0]st1w {za0v.s[w12, 3]}, p0, [x0, x1, lsl #2] | Stores the elements of a tile slice to memory. Inactive elements are not written to memory. | – |
ldr, str | ldr za[w12, 0], [x0]ldr za[w13, 1], [x0, #1, mul vl] | Loads or stores one horizontal row of ZA as a block of bytes, without a predicate. The immediate selects the row offset and also the memory offset, in multiples of the vector length. The access is by bytes, with no endian conversion. Streaming mode is not needed. | – |
Clearing ZA
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
zero | zero {za0.d, za1.d}zero {za}zero {} | Sets the listed 64-bit element tiles to zero and leaves the others unchanged. The list is an 8-bit mask, and disassembly uses the shortest list of tile names that matches it: {za} is all of ZA and {} is no tile. Streaming mode is not needed. | – |
Adding a vector across a tile
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
addha | addha za0.s, p0/m, p0/m, z0.saddha za0.d, p0/m, p0/m, z0.d | Adds each element of the vector to the matching element of each row of the tile. Inactive tile elements stay unchanged. | – |
addva | addva za0.s, p0/m, p0/m, z0.saddva za0.d, p0/m, p0/m, z0.d | Adds each element of the vector to the matching element of each column of the tile. Inactive tile elements stay unchanged. | – |
Integer sums of outer products
These multiply a matrix held in the first source vector by a matrix held in the second source vector. Each 32-bit or 64-bit container of a source vector holds four small integers, so each destination element gets the sum of four products. An inactive source element counts as 0.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
smopa, smops | smopa za0.s, p0/m, p0/m, z0.b, z0.bsmopa za0.d, p0/m, p0/m, z0.h, z0.h | Multiplies signed 8-bit or 16-bit integers. smopa adds the results to a 32-bit or 64-bit tile, and smops subtracts them from it. | – |
umopa, umops | umopa za0.s, p0/m, p0/m, z0.b, z0.b | The same, for unsigned integers. | – |
sumopa, sumops | sumopa za0.s, p0/m, p0/m, z0.b, z0.b | The same, for signed integers in the first source and unsigned integers in the second. | – |
usmopa, usmops | usmopa za0.s, p0/m, p0/m, z0.b, z0.b | The same, for unsigned integers in the first source and signed integers in the second. | – |
Floating-point outer products
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
fmopa, fmops | fmopa za0.s, p0/m, p0/m, z0.s, z0.sfmopa za0.d, p0/m, p0/m, z0.d, z0.dfmopa za0.s, p0/m, p0/m, z0.h, z0.h | Multiplies each element of the first vector by each element of the second. fmopa adds the products to a tile of the same element size, and fmops subtracts them. If either source element of a pair is inactive, the tile element stays unchanged. The .s tile with .h sources is a widening form: each destination gets a sum of two products, an inactive element counts as +0.0, and the tile element stays unchanged only if both pairs are inactive. | – |
bfmopa, bfmops | bfmopa za0.s, p0/m, p0/m, z0.h, z0.h | The widening form, for BFloat16 sources and a single-precision tile. An inactive element counts as +0.0. A tile element stays unchanged only if both pairs that feed it are inactive. | – |
Bitwise outer products
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
bmopa, bmops | bmopa za0.s, p0/m, p0/m, z0.s, z0.s | Takes the bitwise exclusive NOR of each pair of 32-bit elements, counts the set bits, and adds that count to a 32-bit tile element (bmopa) or subtracts it (bmops). If either source element is inactive, the tile element stays unchanged. Arm’s description places these two in SME2. | – |
Links
Reference
- Arm A64 Instruction Set Architecture – Arm’s description of each A64 instruction
- Arm Architecture Reference Manual for A-profile – the full architecture specification