st1

Store Multiple Single Elements

ST1 { <Vt>.<T>, ... }, [<Xn|SP>]

Stores one element structure from 1-4 registers to memory.

Details

Stores one element structure from 1-4 NEON vector registers to memory. The Q bit determines vector size (64-bit for Q=0, 128-bit for Q=1). No condition flags are affected. AArch64-only instruction; requires NEON extension support.

Pseudocode Operation

address ← Xn
for i = 0 to num_registers - 1 do
  memory[address + offset] ← Vt[i]
if postindex then Xn ← Xn + transfer_size

Example

ST1 [x1]

Encoding

Binary Layout
0
Q
0011010
0
0
0000
0
000
S
size
Rn
Rt
 
Format SIMD Load/Store
Opcode 0x0D000000
Extension NEON (SIMD)

Operands

  • Vt
    Src List
  • Xn
    First source / base 64-bit integer register

Reference (Arm A64 ISA)

Instruction Forms

Encoding Instruction ISA Bit pattern
0x0C007000 ST1 { <Vt>.<T> }, [<Xn|SP>] A64 0 | Q | 0011000 | 0 | 000000 | 0111 | size | Rn | Rt
0x0C00A000 ST1 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>] A64 0 | Q | 0011000 | 0 | 000000 | 1010 | size | Rn | Rt
0x0C006000 ST1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>] A64 0 | Q | 0011000 | 0 | 000000 | 0110 | size | Rn | Rt
0x0C002000 ST1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>] A64 0 | Q | 0011000 | 0 | 000000 | 0010 | size | Rn | Rt
0x0C9F7000 ST1 { <Vt>.<T> }, [<Xn|SP>], <imm> A64 0 | Q | 0011001 | 0 | 0 | 11111 | 0111 | size | Rn | Rt
0x0C807000 ST1 { <Vt>.<T> }, [<Xn|SP>], <Xm> A64 0 | Q | 0011001 | 0 | 0 | Rm | 0111 | size | Rn | Rt
0x0C9FA000 ST1 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm> A64 0 | Q | 0011001 | 0 | 0 | 11111 | 1010 | size | Rn | Rt
0x0C80A000 ST1 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm> A64 0 | Q | 0011001 | 0 | 0 | Rm | 1010 | size | Rn | Rt
0x0C9F6000 ST1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm> A64 0 | Q | 0011001 | 0 | 0 | 11111 | 0110 | size | Rn | Rt
0x0C806000 ST1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm> A64 0 | Q | 0011001 | 0 | 0 | Rm | 0110 | size | Rn | Rt
0x0C9F2000 ST1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm> A64 0 | Q | 0011001 | 0 | 0 | 11111 | 0010 | size | Rn | Rt
0x0C802000 ST1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm> A64 0 | Q | 0011001 | 0 | 0 | Rm | 0010 | size | Rn | Rt
0x0D000000 ST1 { <Vt>.B }[<index>], [<Xn|SP>] A64 0 | Q | 0011010 | 0 | 0 | 0000 | 0 | 000 | S | size | Rn | Rt
0x0D004000 ST1 { <Vt>.H }[<index>], [<Xn|SP>] A64 0 | Q | 0011010 | 0 | 0 | 0000 | 0 | 010 | S | size | Rn | Rt

Description

Store a single-element structure from one lane of one register. This instruction stores the specified element of a SIMD&FP register to memory. Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.

Operation

CheckFPAdvSIMDEnabled64();

bits(64) address;
bits(64) eaddr;
bits(64) offs;
bits(128) rval;
bits(esize) element;
constant integer ebytes = esize DIV 8;

AccessDescriptor accdesc = CreateAccDescASIMD(memop, nontemporal, tagchecked);

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

offs = Zeros(64);
if replicate then
    // load and replicate to all elements
    for s = 0 to selem-1
        eaddr = GenerateAddress(address, offs, accdesc);
        element = Mem[eaddr, ebytes, accdesc];
        // replicate to fill 128- or 64-bit register
        V[t, datasize] = Replicate(element, datasize DIV esize);
        offs = offs + ebytes;
        t = (t + 1) MOD 32;
else
    // load/store one element per register
    for s = 0 to selem-1
        rval = V[t, 128];
        eaddr = GenerateAddress(address, offs, accdesc);
        if memop == MemOp_LOAD then
            // insert into one lane of 128-bit register
            Elem[rval, index, esize] = Mem[eaddr, ebytes, accdesc];
            V[t, 128] = rval;
        else // memop == MemOp_STORE
            // extract from one lane of 128-bit register
            Mem[eaddr, ebytes, accdesc] = Elem[rval, index, esize];
        offs = offs + ebytes;
        t = (t + 1) MOD 32;

if wback then
    if m != 31 then
        offs = X[m, 64];
    address = GenerateAddress(address, offs, accdesc);
    if n == 31 then
        SP[] = address;
    else
        X[n, 64] = address;