mul

SVE Integer Multiply (Predicated)

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

Multiplies two vectors under predicate.

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
31:24
size
23:22
0100
21:18
0
17
0
16
000
15:13
Pg
12:10
Zm
9:5
Zdn
4:0
 
Format SVE Integer Binary
Opcode 0x04100000
Extension SVE

Operands

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

Related

Other forms of mul

  • mul Vector Multiply (Integer)
  • mul Multiply (A32)

Across architectures

Integer Multiply : how x86, ARM, RISC-V, and PowerISA each do this.

More in SVE

Reference

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;