subg

Subtract with Tag

SUBG <Xd|SP>, <Xn|SP>, #<uimm6>, #<uimm4>

Subtracts an immediate from an address, modifying the Allocation Tag (MTE).

Details

Subtracts a scaled immediate offset (uimm6 × 16) from an address in the source register and simultaneously updates the Memory Tagging Extension (MTE) Allocation Tag in bits [59:56] by adding uimm4. The result is stored in the destination register. This is an AArch64-only instruction that modifies both address and tag atomically. No condition flags are affected.

Pseudocode Operation

address_offset ← uimm6 × 16
tag_offset ← uimm4
if Xn == SP then
  Xd ← (Xn - address_offset)[63:0]
  Xd[59:56] ← (Xn[59:56] + tag_offset) AND 0xF
else
  Xd ← (Xn - address_offset)[63:0]
  Xd[59:56] ← (Xn[59:56] + tag_offset) AND 0xF

Example

SUBG x0, x1, #8, #3

Encoding

Binary Layout
1
1
0
1000110
uimm6
00
uimm4
Xn
Xd
 
Format Data Processing
Opcode 0xD1800000
Extension MTE (Memory Tagging)

Operands

  • Xd
    Destination 64-bit integer register
  • Xn
    First source / base 64-bit integer register
  • uimm6
    Address Offset
  • uimm4
    Tag Offset

Reference (Arm A64 ISA)

Instruction Forms

Encoding Instruction ISA Bit pattern
0xD1800000 SUBG <Xd|SP>, <Xn|SP>, #<uimm6>, #<uimm4> A64 1 | 1 | 0 | 1000110 | uimm6 | 00 | uimm4 | Xn | Xd

Description

Subtract with Tag subtracts an immediate value scaled by the Tag granule from the address in the source register, modifies the Logical Address Tag of the address using an immediate value, and writes the result to the destination register. Tags specified in GCR_EL1.Exclude are excluded from the possible outputs when modifying the Logical Address Tag.

Operation

bits(64) operand1 = if n == 31 then SP[] else X[n, 64];
bits(4) start_tag = AArch64.AllocationTagFromAddress(operand1);
bits(16) exclude = GCR_EL1.Exclude;
bits(64) result;
bits(4) rtag;

if AArch64.AllocationTagAccessIsEnabled(PSTATE.EL) then
    rtag = AArch64.ChooseNonExcludedTag(start_tag, uimm4, exclude);
else
    rtag = '0000';

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

result = AArch64.AddressWithAllocationTag(result, rtag);

if d == 31 then
    SP[] = result;
else
    X[d, 64] = result;