stgp

Store Allocation Tag and Pair

STGP <Xt>, <Xt2>, [<Xn|SP>, #<simm>]

Stores Tag and two 64-bit data values.

Details

Stores the Allocation Tag to a 16-byte memory address and simultaneously stores two 64-bit values from Xt and Xt2 (the pair register following Xt). The tag is derived from Xt, and the offset is scaled by 16. This instruction requires MTE support, does not modify the condition flags, and operates only in AArch64 execution state.

Pseudocode Operation

address ← (Xn | SP) + (simm7 << 4)
tag ← Xt[3:0]
memory[address:address+7] ← Xt[63:0]
memory[address+8:address+15] ← Xt2[63:0]
memory[address][3:0] ← tag

Example

STGP x3, x4, [x1, #-8]

Encoding

Binary Layout
01
101
0
010
0
simm7
Xt2
Xn
Xt
 
Format Load/Store
Opcode 0x69000000
Extension MTE (Memory Tagging)

Operands

  • Xt
    Data 1
  • Xt2
    Data 2
  • Xn
    First source / base 64-bit integer register

Reference (Arm A64 ISA)

Instruction Forms

Encoding Instruction ISA Bit pattern
0x68800000 STGP <Xt1>, <Xt2>, [<Xn|SP>], #<imm> A64 01 | 101 | 0 | 001 | 0 | simm7 | Xt2 | Xn | Xt
0x69800000 STGP <Xt1>, <Xt2>, [<Xn|SP>, #<imm>]! A64 01 | 101 | 0 | 011 | 0 | simm7 | Xt2 | Xn | Xt
0x69000000 STGP <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}] A64 01 | 101 | 0 | 010 | 0 | simm7 | Xt2 | Xn | Xt

Description

Store Allocation Tag and Pair of registers stores an Allocation Tag and two 64-bit doublewords to memory, from two registers. The address used for the store is calculated from the base register and an immediate signed offset scaled by the Tag granule. The Allocation Tag is calculated from the Logical Address Tag in the base register. This instruction generates an Unchecked access.

Operation

bits(64) address;
bits(64) address2;
bits(64) data1;
bits(64) data2;

if n == 31 then
    CheckSPAlignment();
    address = SP[];
else
    address = X[n, 64];

data1 = X[t, 64];
data2 = X[t2, 64];

AccessDescriptor accdesc = CreateAccDescLDGSTG(MemOp_STORE, FALSE);

if !postindex then
    address = GenerateAddress(address, offset, accdesc);

if !IsAligned(address, TAG_GRANULE) then
    AArch64.Abort(address, AlignmentFault(accdesc));

address2 = GenerateAddress(address, 8, accdesc);
Mem[address, 8, accdesc] = data1;
Mem[address2, 8, accdesc] = data2;

AArch64.MemTag[address, accdesc] = AArch64.AllocationTagFromAddress(address);

if writeback then
    if postindex then
        address = GenerateAddress(address, offset, accdesc);

    if n == 31 then
        SP[] = address;
    else
        X[n, 64] = address;