Floating-point quarter-tile outer product, accumulating
This instruction generates four independent quarter-tile floating-point outer products from the sub-matrices in the half-vectors of the one or two first and second source vectors and accumulates the results to the corresponding elements of a 16-bit, 32-bit, or 64-bit element ZA tile.
In case of the half-precision variant, each of the quarter-tile outer products is generated by multiplying the SVLH÷2 × 1 sub-matrix of half-precision values held in the half-vectors of the first source vectors by the 1 × SVLH÷2 sub-matrix of half-precision values held in the half-vectors of the second source vectors. In case of the single-precision variant, each of the quarter-tile outer products is generated by multiplying the SVLS÷2 × 1 sub-matrix of single-precision values held in the half-vectors of the first source vectors by the 1 × SVLS÷2 sub-matrix of single-precision values held in the half-vectors of the second source vectors. In case of the double-precision variant, each of the quarter-tile outer products is generated by multiplying the SVLD÷2 × 1 sub-matrix of double-precision values held in the half-vectors of the first source vectors by the 1 × SVLD÷2 sub-matrix of double-precision values held in the half-vectors of the second source vectors.
The resulting quarter-tile SVLH÷2 × SVLH÷2 half-precision outer products in case of the half-precision variant, SVLS÷2 × SVLS÷2 single-precision outer products in case of the single-precision variant, or SVLD÷2 × SVLD÷2 double-precision outer products in case of the double-precision variant are destructively added to the destination ZA tile. This is equivalent to performing a single multiply-accumulate to each of the destination tile elements.
This instruction follows SME ZA-targeting floating-point behaviors.
This instruction is unpredicated.
It has encodings from 12 classes: Half-precision, single and multiple vectors , Half-precision, single vectors , Half-precision, multiple and single vectors , Half-precision, multiple vectors , Single-precision, single and multiple vectors , Single-precision, single vectors , Single-precision, multiple and single vectors , Single-precision, multiple vectors , Double-precision, single and multiple vectors , Double-precision, single vectors , Double-precision, multiple and single vectors and Double-precision, multiple vectors
| 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | Zm | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | Zn | 0 | 0 | 1 | 0 | 0 | ZAda | ||||
| M | N | S | |||||||||||||||||||||||||||||
if !IsFeatureImplemented(FEAT_SME_MOP4) || !IsFeatureImplemented(FEAT_SME_F16F16) then EndOfDecode(Decode_UNDEF); end; let esize : integer{} = 16; let n : integer = UInt('0'::Zn::'0'); let m : integer = UInt('1'::Zm::'0'); let nreg : integer{} = 1; let mreg : integer = 2; let da : integer = UInt(ZAda); let sub_op : boolean = FALSE;
| 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | Zm | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | Zn | 0 | 0 | 1 | 0 | 0 | ZAda | ||||
| M | N | S | |||||||||||||||||||||||||||||
if !IsFeatureImplemented(FEAT_SME_MOP4) || !IsFeatureImplemented(FEAT_SME_F16F16) then EndOfDecode(Decode_UNDEF); end; let esize : integer{} = 16; let n : integer = UInt('0'::Zn::'0'); let m : integer = UInt('1'::Zm::'0'); let nreg : integer{} = 1; let mreg : integer = 1; let da : integer = UInt(ZAda); let sub_op : boolean = FALSE;
| 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | Zm | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | Zn | 0 | 0 | 1 | 0 | 0 | ZAda | ||||
| M | N | S | |||||||||||||||||||||||||||||
if !IsFeatureImplemented(FEAT_SME_MOP4) || !IsFeatureImplemented(FEAT_SME_F16F16) then EndOfDecode(Decode_UNDEF); end; let esize : integer{} = 16; let n : integer = UInt('0'::Zn::'0'); let m : integer = UInt('1'::Zm::'0'); let nreg : integer{} = 2; let mreg : integer = 1; let da : integer = UInt(ZAda); let sub_op : boolean = FALSE;
| 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | Zm | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | Zn | 0 | 0 | 1 | 0 | 0 | ZAda | ||||
| M | N | S | |||||||||||||||||||||||||||||
if !IsFeatureImplemented(FEAT_SME_MOP4) || !IsFeatureImplemented(FEAT_SME_F16F16) then EndOfDecode(Decode_UNDEF); end; let esize : integer{} = 16; let n : integer = UInt('0'::Zn::'0'); let m : integer = UInt('1'::Zm::'0'); let nreg : integer{} = 2; let mreg : integer = 2; let da : integer = UInt(ZAda); let sub_op : boolean = FALSE;
| 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | Zm | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | Zn | 0 | 0 | 0 | 0 | ZAda | |||||
| M | N | S | |||||||||||||||||||||||||||||
if !IsFeatureImplemented(FEAT_SME_MOP4) then EndOfDecode(Decode_UNDEF); end; let esize : integer{} = 32; let n : integer = UInt('0'::Zn::'0'); let m : integer = UInt('1'::Zm::'0'); let nreg : integer{} = 1; let mreg : integer = 2; let da : integer = UInt(ZAda); let sub_op : boolean = FALSE;
| 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | Zm | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | Zn | 0 | 0 | 0 | 0 | ZAda | |||||
| M | N | S | |||||||||||||||||||||||||||||
if !IsFeatureImplemented(FEAT_SME_MOP4) then EndOfDecode(Decode_UNDEF); end; let esize : integer{} = 32; let n : integer = UInt('0'::Zn::'0'); let m : integer = UInt('1'::Zm::'0'); let nreg : integer{} = 1; let mreg : integer = 1; let da : integer = UInt(ZAda); let sub_op : boolean = FALSE;
| 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | Zm | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | Zn | 0 | 0 | 0 | 0 | ZAda | |||||
| M | N | S | |||||||||||||||||||||||||||||
if !IsFeatureImplemented(FEAT_SME_MOP4) then EndOfDecode(Decode_UNDEF); end; let esize : integer{} = 32; let n : integer = UInt('0'::Zn::'0'); let m : integer = UInt('1'::Zm::'0'); let nreg : integer{} = 2; let mreg : integer = 1; let da : integer = UInt(ZAda); let sub_op : boolean = FALSE;
| 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | Zm | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | Zn | 0 | 0 | 0 | 0 | ZAda | |||||
| M | N | S | |||||||||||||||||||||||||||||
if !IsFeatureImplemented(FEAT_SME_MOP4) then EndOfDecode(Decode_UNDEF); end; let esize : integer{} = 32; let n : integer = UInt('0'::Zn::'0'); let m : integer = UInt('1'::Zm::'0'); let nreg : integer{} = 2; let mreg : integer = 2; let da : integer = UInt(ZAda); let sub_op : boolean = FALSE;
| 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | Zm | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | Zn | 0 | 0 | 1 | ZAda | ||||||
| M | N | S | |||||||||||||||||||||||||||||
if !IsFeatureImplemented(FEAT_SME_MOP4) || !IsFeatureImplemented(FEAT_SME_F64F64) then EndOfDecode(Decode_UNDEF); end; let esize : integer{} = 64; let n : integer = UInt('0'::Zn::'0'); let m : integer = UInt('1'::Zm::'0'); let nreg : integer{} = 1; let mreg : integer = 2; let da : integer = UInt(ZAda); let sub_op : boolean = FALSE;
| 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | Zm | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | Zn | 0 | 0 | 1 | ZAda | ||||||
| M | N | S | |||||||||||||||||||||||||||||
if !IsFeatureImplemented(FEAT_SME_MOP4) || !IsFeatureImplemented(FEAT_SME_F64F64) then EndOfDecode(Decode_UNDEF); end; let esize : integer{} = 64; let n : integer = UInt('0'::Zn::'0'); let m : integer = UInt('1'::Zm::'0'); let nreg : integer{} = 1; let mreg : integer = 1; let da : integer = UInt(ZAda); let sub_op : boolean = FALSE;
| 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | Zm | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | Zn | 0 | 0 | 1 | ZAda | ||||||
| M | N | S | |||||||||||||||||||||||||||||
if !IsFeatureImplemented(FEAT_SME_MOP4) || !IsFeatureImplemented(FEAT_SME_F64F64) then EndOfDecode(Decode_UNDEF); end; let esize : integer{} = 64; let n : integer = UInt('0'::Zn::'0'); let m : integer = UInt('1'::Zm::'0'); let nreg : integer{} = 2; let mreg : integer = 1; let da : integer = UInt(ZAda); let sub_op : boolean = FALSE;
| 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | Zm | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | Zn | 0 | 0 | 1 | ZAda | ||||||
| M | N | S | |||||||||||||||||||||||||||||
if !IsFeatureImplemented(FEAT_SME_MOP4) || !IsFeatureImplemented(FEAT_SME_F64F64) then EndOfDecode(Decode_UNDEF); end; let esize : integer{} = 64; let n : integer = UInt('0'::Zn::'0'); let m : integer = UInt('1'::Zm::'0'); let nreg : integer{} = 2; let mreg : integer = 2; let da : integer = UInt(ZAda); let sub_op : boolean = FALSE;
| <Zn> |
Is the name of the first source scalable vector register, registers in the range Z0-Z15, encoded as "Zn" times 2. |
| <Zm1> |
Is the name of the first scalable vector register of the second source multi-vector group, in the range Z16-Z31, encoded as "Zm" times 2 plus 16. |
| <Zm2> |
Is the name of the second scalable vector register of the second source multi-vector group, in the range Z16-Z31, encoded as "Zm" times 2 plus 17. |
| <Zm> |
Is the name of the second source scalable vector register, registers in the range Z16-Z31, encoded as "Zm" times 2 plus 16. |
| <Zn1> |
Is the name of the first scalable vector register of the first source multi-vector group, in the range Z0-Z15, encoded as "Zn" times 2. |
| <Zn2> |
Is the name of the second scalable vector register of the first source multi-vector group, in the range Z0-Z15, encoded as "Zn" times 2 plus 1. |
CheckStreamingSVEAndZAEnabled(); let VL : integer{} = CurrentVL(); let hvsize : integer{} = VL DIV 2; let dim : integer{} = hvsize DIV esize; let tilesize : integer{} = 4*dim*dim*esize; let op3 : bits(tilesize) = ZAtile{}(da, esize); var result : bits(tilesize); for outprod = 0 to 3 do let row_hv : integer = outprod DIVRM 2; let col_hv : integer = outprod MOD 2; let row_base : integer = row_hv * dim; let col_base : integer = col_hv * dim; let op1 : bits(VL) = Z{}(n + (nreg-1)*col_hv); let op2 : bits(VL) = Z{}(m + (mreg-1)*row_hv); for row = 0 to dim-1 do for col = 0 to dim-1 do let row_idx : integer = row_base + row; let col_idx : integer = col_base + col; let tile_idx : integer = row_idx * dim * 2 + col_idx; var elem1 : bits(esize) = op1[row_idx*:(esize)]; let elem2 : bits(esize) = op2[col_idx*:(esize)]; let elem3 : bits(esize) = op3[tile_idx*:(esize)]; if sub_op then elem1 = FPNeg{esize}(elem1, FPCR()); end; result[tile_idx*:(esize)] = FPMulAdd_ZA{esize}(elem3, elem1, elem2, FPCR()); end; end; end; ZAtile{tilesize}(da, esize) = result;
2026-03_rel 2026-03-26 20:48:11
Copyright © 2010-2026 Arm Limited or its affiliates. All rights reserved. This document is Non-Confidential.