Half-precision quarter-tile sums of two outer products, accumulating
This instruction generates four independent quarter-tile half-precision sums of 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 32-bit element ZA tile.
Each of the quarter-tile sums of outer products is generated by multiplying the SVLS÷2 × 2 sub-matrix of half-precision values held in the half-vectors of the first source vectors by the 2 × SVLS÷2 sub-matrix of half-precision values held in the half-vectors of the second source vectors. Each 32-bit container of the first source vectors holds 2 elements of each row of a SVLS÷2 × 2 sub-matrix. Similarly, each 32-bit container of the second source vectors holds 2 elements of each column of a 2 × SVLS÷2 sub-matrix.
The instruction widens the sub-matrices of half-precision values held in the first source vectors to single-precision values and multiplies them by the corresponding widened sub-matrices of half-precision values in the second source vectors to single-precision values. The resulting quarter-tile SVLS÷2 × SVLS÷2 single-precision sums of outer products are then destructively added to the single-precision destination tile. This is equivalent to performing a 2-way dot product and accumulate to each of the destination tile elements.
This instruction follows SME ZA-targeting floating-point behaviors.
This instruction is unpredicated.
Variants: FEAT_SME_MOP4 (ARMv9.6)
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 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ||||||||
M | Zm | N | Zn | S | ZAda |
---|
FMOP4A <ZAda>.S, <Zn>.H, { <Zm1>.H-<Zm2>.H }
if !IsFeatureImplemented(FEAT_SME_MOP4) then EndOfDecode(Decode_UNDEF); constant integer n = UInt('0':Zn:'0'); constant integer m = UInt('1':Zm:'0'); constant integer nreg = 1; constant integer mreg = 2; constant integer da = UInt(ZAda); constant boolean sub_op = FALSE;
Variants: FEAT_SME_MOP4 (ARMv9.6)
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 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ||||||||
M | Zm | N | Zn | S | ZAda |
---|
FMOP4A <ZAda>.S, <Zn>.H, <Zm>.H
if !IsFeatureImplemented(FEAT_SME_MOP4) then EndOfDecode(Decode_UNDEF); constant integer n = UInt('0':Zn:'0'); constant integer m = UInt('1':Zm:'0'); constant integer nreg = 1; constant integer mreg = 1; constant integer da = UInt(ZAda); constant boolean sub_op = FALSE;
Variants: FEAT_SME_MOP4 (ARMv9.6)
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 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | ||||||||
M | Zm | N | Zn | S | ZAda |
---|
FMOP4A <ZAda>.S, { <Zn1>.H-<Zn2>.H }, <Zm>.H
if !IsFeatureImplemented(FEAT_SME_MOP4) then EndOfDecode(Decode_UNDEF); constant integer n = UInt('0':Zn:'0'); constant integer m = UInt('1':Zm:'0'); constant integer nreg = 2; constant integer mreg = 1; constant integer da = UInt(ZAda); constant boolean sub_op = FALSE;
Variants: FEAT_SME_MOP4 (ARMv9.6)
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 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | ||||||||
M | Zm | N | Zn | S | ZAda |
---|
FMOP4A <ZAda>.S, { <Zn1>.H-<Zn2>.H }, { <Zm1>.H-<Zm2>.H }
if !IsFeatureImplemented(FEAT_SME_MOP4) then EndOfDecode(Decode_UNDEF); constant integer n = UInt('0':Zn:'0'); constant integer m = UInt('1':Zm:'0'); constant integer nreg = 2; constant integer mreg = 2; constant integer da = UInt(ZAda); constant boolean sub_op = FALSE;
CheckStreamingSVEAndZAEnabled(); constant integer VL = CurrentVL; constant integer hvsize = VL DIV 2; constant integer dim = hvsize DIV 32; constant integer tilesize = 4*dim*dim*32; constant bits(tilesize) op3 = ZAtile[da, 32, tilesize]; bits(tilesize) result; for outprod = 0 to 3 constant integer row_hv = outprod DIV 2; constant integer col_hv = outprod MOD 2; constant integer row_base = row_hv * dim; constant integer col_base = col_hv * dim; constant bits(VL) op1 = Z[n + (nreg-1)*col_hv, VL]; constant bits(VL) op2 = Z[m + (mreg-1)*row_hv, VL]; for row = 0 to dim-1 for col = 0 to dim-1 constant integer row_idx = row_base + row; constant integer col_idx = col_base + col; constant integer tile_idx = row_idx * dim * 2 + col_idx; constant bits(32) sum = Elem[op3, tile_idx, 32]; bits(16) erow_0 = Elem[op1, 2*row_idx + 0, 16]; bits(16) erow_1 = Elem[op1, 2*row_idx + 1, 16]; constant bits(16) ecol_0 = Elem[op2, 2*col_idx + 0, 16]; constant bits(16) ecol_1 = Elem[op2, 2*col_idx + 1, 16]; if sub_op then erow_0 = FPNeg(erow_0, FPCR); erow_1 = FPNeg(erow_1, FPCR); Elem[result, tile_idx, 32] = FPDotAdd_ZA(sum, erow_0, erow_1, ecol_0, ecol_1, FPCR); ZAtile[da, 32, tilesize] = result;