mul

SVE Integer Multiply (Predicated)

MUL <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>

Multiplies two vectors under predicate.

Details

SVE Integer Multiply (Predicated) multiplies two scalable vector registers Zdn and Zm element-wise under predicate control, storing the result back in Zdn. Elements not selected by the predicate Pg are unchanged (merge behavior). The element type T is determined by the sz encoding (8, 16, 32, or 64 bits). Condition flags are not modified.

Pseudocode Operation

for i in 0 to VL/element_width - 1:
  if Pg[i] == 1:
    Zdn[i] ← Zdn[i] * Zm[i]
  // else: Zdn[i] remains unchanged

Example

MUL z0.s.T, p0/m/M, z0.s.T, z2.s.T

Encoding

Binary Layout
00000100
size
0100
0
0
000
Pg
Zm
Zdn
 
Format SVE Integer Binary
Opcode 0x04100000
Extension SVE

Operands

  • Zdn
    Dest/Src1
  • Pg
    Merge Mask
  • Zm
    Second source scalable vector register (SVE)

Reference (Arm A64 ISA)

Instruction Forms

Encoding Instruction ISA Bit pattern
0x0F008000 MUL <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>] A64 0 | Q | 0 | 01111 | size | L | M | Rm | 1000 | H | 0 | Rn | Rd
0x0E209C00 MUL <Vd>.<T>, <Vn>.<T>, <Vm>.<T> A64 0 | Q | 0 | 01110 | size | 1 | Rm | 10011 | 1 | Rn | Rd
0x1B007C00 MUL <Wd>, <Wn>, <Wm> A64 0 | 00 | 11011 | 000 | Rm | 0 | 11111 | Rn | Rd
0x9B007C00 MUL <Xd>, <Xn>, <Xm> A64 1 | 00 | 11011 | 000 | Rm | 0 | 11111 | Rn | Rd
0x04100000 MUL <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T> A64 00000100 | size | 0100 | 0 | 0 | 000 | Pg | Zm | Zdn
0x2530C000 MUL <Zdn>.<T>, <Zdn>.<T>, #<imm> A64 00100101 | size | 110 | 00 | 0 | 11 | 0 | imm8 | Zdn
0x04206000 MUL <Zd>.<T>, <Zn>.<T>, <Zm>.<T> A64 00000100 | size | 1 | Zm | 0110 | 0 | 0 | Zn | Zd
0x4420F800 MUL <Zd>.H, <Zn>.H, <Zm>.H[<imm>] A64 01000100 | 0 | i3h | 1 | i3l | Zm | 111110 | Zn | Zd
0x44A0F800 MUL <Zd>.S, <Zn>.S, <Zm>.S[<imm>] A64 01000100 | 1 | 0 | 1 | i2 | Zm | 111110 | Zn | Zd
0x44E0F800 MUL <Zd>.D, <Zn>.D, <Zm>.D[<imm>] A64 01000100 | 1 | 1 | 1 | i1 | Zm | 111110 | Zn | Zd

Description

Multiply active elements of the first source vector by corresponding elements of the second source vector and destructively place the results in the corresponding elements of the first source vector. Inactive elements in the destination vector register remain unmodified.

Operation

CheckSVEEnabled();
constant integer VL = CurrentVL;
constant integer PL = VL DIV 8;
constant integer elements = VL DIV esize;
bits(PL) mask = P[g, PL];
bits(VL) operand1 = Z[dn, VL];
bits(VL) operand2 = if AnyActiveElement(mask, esize) then Z[m, VL] else Zeros(VL);
bits(VL) result;

for e = 0 to elements-1
    integer element1 = UInt(Elem[operand1, e, esize]);
    integer element2 = UInt(Elem[operand2, e, esize]);
    if ActivePredicateElement(mask, e, esize) then
        integer product = element1 * element2;
        Elem[result, e, esize] = product<esize-1:0>;
    else
        Elem[result, e, esize] = Elem[operand1, e, esize];

Z[dn, VL] = result;