sub

SVE Integer Subtract (Predicated)

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

Subtracts vector Zm from Zdn under predicate.

Details

SVE Integer Subtract (Predicated) subtracts the scalable vector register Zm from Zdn 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

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

Encoding

Binary Layout
00000100
size
000
00
1
000
Pg
Zm
Zdn
 
Format SVE Integer Binary
Opcode 0x04010000
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
0x4B200000 SUB <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}} A64 0 | 1 | 0 | 01011 | 00 | 1 | Rm | option | imm3 | Rn | Rd
0xCB200000 SUB <Xd|SP>, <Xn|SP>, <R><m>{, <extend> {#<amount>}} A64 1 | 1 | 0 | 01011 | 00 | 1 | Rm | option | imm3 | Rn | Rd
0x51000000 SUB <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>} A64 0 | 1 | 0 | 100010 | sh | imm12 | Rn | Rd
0xD1000000 SUB <Xd|SP>, <Xn|SP>, #<imm>{, <shift>} A64 1 | 1 | 0 | 100010 | sh | imm12 | Rn | Rd
0x4B000000 SUB <Wd>, <Wn>, <Wm>{, <shift> #<amount>} A64 0 | 1 | 0 | 01011 | shift | 0 | Rm | imm6 | Rn | Rd
0xCB000000 SUB <Xd>, <Xn>, <Xm>{, <shift> #<amount>} A64 1 | 1 | 0 | 01011 | shift | 0 | Rm | imm6 | Rn | Rd
0x7EE08400 SUB D<d>, D<n>, D<m> A64 01 | 1 | 11110 | 11 | 1 | Rm | 10000 | 1 | Rn | Rd
0x2E208400 SUB <Vd>.<T>, <Vn>.<T>, <Vm>.<T> A64 0 | Q | 1 | 01110 | size | 1 | Rm | 10000 | 1 | Rn | Rd
0x04010000 SUB <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T> A64 00000100 | size | 000 | 00 | 1 | 000 | Pg | Zm | Zdn
0x2521C000 SUB <Zdn>.<T>, <Zdn>.<T>, #<imm>{, <shift>} A64 00100101 | size | 100 | 00 | 1 | 11 | sh | imm8 | Zdn
0x04200400 SUB <Zd>.<T>, <Zn>.<T>, <Zm>.<T> A64 00000100 | size | 1 | Zm | 000 | 00 | 1 | Zn | Zd
0xC1A01C18 SUB ZA.<T>[<Wv>, <offs>{, VGx2}], { <Zm1>.<T>-<Zm2>.<T> } A64 110000011 | sz | 1000000 | Rv | 111 | Zm | 01 | 1 | off3
0xC1A11C18 SUB ZA.<T>[<Wv>, <offs>{, VGx4}], { <Zm1>.<T>-<Zm4>.<T> } A64 110000011 | sz | 1000010 | Rv | 111 | Zm | 001 | 1 | off3
0xC1201818 SUB ZA.<T>[<Wv>, <offs>{, VGx2}], { <Zn1>.<T>-<Zn2>.<T> }, <Zm>.<T> A64 110000010 | sz | 10 | Zm | 0 | Rv | 110 | Zn | 1 | 1 | off3

Description

Subtract active elements of the second source vector from 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;