add

SVE Integer Add (Predicated)

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

Adds two vectors under predicate control.

Details

SVE Integer Add (Predicated) adds 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

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

Encoding

Binary Layout
00000100
size
000
00
0
000
Pg
Zm
Zdn
 
Format SVE Integer Binary
Opcode 0x04000000
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
0x0B200000 ADD <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}} A64 0 | 0 | 0 | 01011 | 00 | 1 | Rm | option | imm3 | Rn | Rd
0x8B200000 ADD <Xd|SP>, <Xn|SP>, <R><m>{, <extend> {#<amount>}} A64 1 | 0 | 0 | 01011 | 00 | 1 | Rm | option | imm3 | Rn | Rd
0x11000000 ADD <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>} A64 0 | 0 | 0 | 100010 | sh | imm12 | Rn | Rd
0x91000000 ADD <Xd|SP>, <Xn|SP>, #<imm>{, <shift>} A64 1 | 0 | 0 | 100010 | sh | imm12 | Rn | Rd
0x0B000000 ADD <Wd>, <Wn>, <Wm>{, <shift> #<amount>} A64 0 | 0 | 0 | 01011 | shift | 0 | Rm | imm6 | Rn | Rd
0x8B000000 ADD <Xd>, <Xn>, <Xm>{, <shift> #<amount>} A64 1 | 0 | 0 | 01011 | shift | 0 | Rm | imm6 | Rn | Rd
0x5EE08400 ADD D<d>, D<n>, D<m> A64 01 | 0 | 11110 | 11 | 1 | Rm | 10000 | 1 | Rn | Rd
0x0E208400 ADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T> A64 0 | Q | 0 | 01110 | size | 1 | Rm | 10000 | 1 | Rn | Rd
0xC120A300 ADD { <Zdn1>.<T>-<Zdn2>.<T> }, { <Zdn1>.<T>-<Zdn2>.<T> }, <Zm>.<T> A64 11000001 | size | 10 | Zm | 101000 | 11000 | Zdn | 0
0xC120AB00 ADD { <Zdn1>.<T>-<Zdn4>.<T> }, { <Zdn1>.<T>-<Zdn4>.<T> }, <Zm>.<T> A64 11000001 | size | 10 | Zm | 101010 | 11000 | Zdn | 0 | 0
0x04000000 ADD <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T> A64 00000100 | size | 000 | 00 | 0 | 000 | Pg | Zm | Zdn
0x2520C000 ADD <Zdn>.<T>, <Zdn>.<T>, #<imm>{, <shift>} A64 00100101 | size | 100 | 00 | 0 | 11 | sh | imm8 | Zdn
0x04200000 ADD <Zd>.<T>, <Zn>.<T>, <Zm>.<T> A64 00000100 | size | 1 | Zm | 000 | 00 | 0 | Zn | Zd
0xC1A01C10 ADD ZA.<T>[<Wv>, <offs>{, VGx2}], { <Zm1>.<T>-<Zm2>.<T> } A64 110000011 | sz | 1000000 | Rv | 111 | Zm | 01 | 0 | off3

Description

Add active elements of the second source vector to corresponding elements of the first 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
    bits(esize) element1 = Elem[operand1, e, esize];
    bits(esize) element2 = Elem[operand2, e, esize];
    if ActivePredicateElement(mask, e, esize) then
        Elem[result, e, esize] = element1 + element2;
    else
        Elem[result, e, esize] = Elem[operand1, e, esize];

Z[dn, VL] = result;