Store unprivileged pair of registers
This instruction calculates an address from a base register value and an immediate offset, and stores two 64-bit doublewords to the calculated address, from two registers.
Explicit Memory effects produced by the instruction behave as if the instruction was executed at EL0 if the Effective value of PSTATE.UAO is 0 and either:
Otherwise, the Explicit Memory effects operate with the restrictions determined by the Exception level at which the instruction is executed.
For information about addressing modes, see Load/Store addressing modes.
Variants: FEAT_LSUI (ARMv9.6)
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | ||||||||||||||||||||||
opc | VR | L | imm7 | Rt2 | Rn | Rt |
---|
STTP <Xt1>, <Xt2>, [<Xn|SP>], #<imm>
if !IsFeatureImplemented(FEAT_LSUI) then EndOfDecode(Decode_UNDEF); constant boolean wback = TRUE; constant boolean postindex = TRUE;
Variants: FEAT_LSUI (ARMv9.6)
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
1 | 1 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | ||||||||||||||||||||||
opc | VR | L | imm7 | Rt2 | Rn | Rt |
---|
STTP <Xt1>, <Xt2>, [<Xn|SP>, #<imm>]!
if !IsFeatureImplemented(FEAT_LSUI) then EndOfDecode(Decode_UNDEF); constant boolean wback = TRUE; constant boolean postindex = FALSE;
Variants: FEAT_LSUI (ARMv9.6)
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
1 | 1 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | ||||||||||||||||||||||
opc | VR | L | imm7 | Rt2 | Rn | Rt |
---|
STTP <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]
if !IsFeatureImplemented(FEAT_LSUI) then EndOfDecode(Decode_UNDEF); constant boolean wback = FALSE; constant boolean postindex = FALSE;
constant integer t = UInt(Rt); constant integer t2 = UInt(Rt2); constant integer n = UInt(Rn); constant boolean nontemporal = FALSE; constant integer scale = 2 + UInt(opc<1>); constant integer datasize = 64; constant bits(64) offset = LSL(SignExtend(imm7, 64), scale); constant boolean tagchecked = wback || n != 31; boolean rt_unknown = FALSE; if wback && (t == n || t2 == n) && n != 31 then constant Constraint c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; case c of when Constraint_NONE rt_unknown = FALSE; // Value stored is pre-writeback when Constraint_UNKNOWN rt_unknown = TRUE; // Value stored is UNKNOWN when Constraint_UNDEF EndOfDecode(Decode_UNDEF); when Constraint_NOP EndOfDecode(Decode_NOP);
bits(64) address; bits(64) address2; bits(datasize) data1; bits(datasize) data2; constant integer dbytes = datasize DIV 8; constant boolean privileged = AArch64.IsUnprivAccessPriv(); constant AccessDescriptor accdesc = CreateAccDescGPR(MemOp_STORE, nontemporal, privileged, tagchecked); if n == 31 then CheckSPAlignment(); address = SP[64]; else address = X[n, 64]; if !postindex then address = AddressAdd(address, offset, accdesc); if rt_unknown && t == n then data1 = bits(datasize) UNKNOWN; else data1 = X[t, datasize]; if rt_unknown && t2 == n then data2 = bits(datasize) UNKNOWN; else data2 = X[t2, datasize]; if accdesc.ispair then constant bits(2*datasize) full_data = (if BigEndian(accdesc.acctype) then data1:data2 else data2:data1); Mem[address, 2 * dbytes, accdesc] = full_data; else address2 = AddressIncrement(address, dbytes, accdesc); Mem[address , dbytes, accdesc] = data1; Mem[address2, dbytes, accdesc] = data2; if wback then if postindex then address = AddressAdd(address, offset, accdesc); if n == 31 then SP[64] = address; else X[n, 64] = address;
If PSTATE.DIT is 1, the timing of this instruction is insensitive to the value of the data being loaded or stored.