sub

Subtract (Extended Register)

SUB <Wd|Wsp>, <Wn|Wsp>, <Wm> {, <extend> {#<amount>}}

Subtracts extended register from register.

Details

Subtracts an extended 32-bit register value from a 32-bit register and writes the result to the destination register. Sets the N, Z, C, V condition flags based on the result. AArch64-only instruction; supports sign/zero extension of Wm with optional left shift (0–4).

Pseudocode Operation

offset ← ExtendValue(Wm, option, imm3)
result ← Wn - offset
Wd ← result[31:0]
N ← result[31]
Z ← (result == 0)
C ← (unsigned_result == result)
V ← SignedOverflow(Wn, offset, result)

Example

SUB Wd, Wn, w2

Encoding

Binary Layout
0
1
0
01011
00
1
Rm
option
imm3
Rn
Rd
 
Format Data Processing
Opcode 0x4B200000
Extension Base

Operands

  • Wd
    Destination 32-bit integer register
  • Wn
    First source / base 32-bit integer register
  • Wm
    Second source / offset 32-bit integer register

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 (extended register) subtracts a sign or zero-extended register value, followed by an optional left shift amount, from a register value, and writes the result to the destination register. The argument that is extended from the <Rm> register can be a byte, halfword, word, or doubleword.

Operation

bits(datasize) result;
bits(datasize) operand1 = if n == 31 then SP[]<datasize-1:0> else X[n, datasize];
bits(datasize) operand2 = ExtendReg(m, extend_type, shift, datasize);

operand2 = NOT(operand2);
(result, -) = AddWithCarry(operand1, operand2, '1');

if d == 31 then
    SP[] = ZeroExtend(result, 64);
else
    X[d, datasize] = result;