subg

Subtract with Tag

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

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

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
31
1
30
0
29
1000110
28:22
uimm6
21:16
00
15:14
uimm4
13:10
Xn
9:5
Xd
4:0
 
Format Data Processing
Opcode 0xD1800000

Operands

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

Related

More in MTE (Memory Tagging)

Reference

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;