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
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;