STR (register, SIMD&FP) Store SIMD&FP register (register offset) This instruction stores a single SIMD&FP register to memory. The address that is used for the store is calculated from a base register value and an offset register value. The offset can be optionally shifted and extended. 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. If PSTATE.DIT is 1, the timing of this instruction is insensitive to the value of the data being loaded or stored. 1 1 1 1 0 0 x 0 1 1 0 0 0 0 Z N N STR <Bt>, [<Xn|SP>, (<Wm>|<Xm>), <extend> {<amount>}] 0 0 0 0 1 1 STR <Bt>, [<Xn|SP>, <Xm>{, LSL <amount>}] 0 1 0 STR <Ht>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}] 1 0 0 STR <St>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}] 1 1 0 STR <Dt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}] 0 0 1 STR <Qt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}] if option<1> == '0' then UNDEFINED; // sub-word index if opc<1> == '1' && size != '00' then UNDEFINED; constant integer scale = if opc<1> == '1' then 4 else UInt(size); constant ExtendType extend_type = DecodeRegExtend(option); constant integer shift = if S == '1' then scale else 0; <Bt> Is the 8-bit name of the SIMD&FP register to be transferred, encoded in the "Rt" field. <Xn|SP> Is the 64-bit name of the general-purpose base register or stack pointer, encoded in the "Rn" field. <Wm> When option<0> is set to 0, is the 32-bit name of the general-purpose index register, encoded in the "Rm" field. <Xm> When option<0> is set to 1, is the 64-bit name of the general-purpose index register, encoded in the "Rm" field. <extend> For the 8-bit variant: is the index extend specifier, option <extend> 010 UXTW 110 SXTW 111 SXTX
<extend> For the 128-bit, 16-bit, 32-bit and 64-bit variant: is the index extend/shift specifier, defaulting to LSL, and which must be omitted for the LSL option when <amount> is omitted. option <extend> 010 UXTW 011 LSL 110 SXTW 111 SXTX
<amount> For the 8-bit variant: is the index shift amount, it must be #0, encoded in "S" as 0 if omitted, or as 1 if present. <amount> For the 16-bit variant: is the index shift amount, optional only when <extend> is not LSL. Where it is permitted to be optional, it defaults to #0. It is S <amount> 0 #0 1 #1
<amount> For the 32-bit variant: is the index shift amount, optional only when <extend> is not LSL. Where it is permitted to be optional, it defaults to #0. It is S <amount> 0 #0 1 #2
<amount> For the 64-bit variant: is the index shift amount, optional only when <extend> is not LSL. Where it is permitted to be optional, it defaults to #0. It is S <amount> 0 #0 1 #3
<amount> For the 128-bit variant: is the index shift amount, optional only when <extend> is not LSL. Where it is permitted to be optional, it defaults to #0. It is S <amount> 0 #0 1 #4
<Ht> Is the 16-bit name of the SIMD&FP register to be transferred, encoded in the "Rt" field. <St> Is the 32-bit name of the SIMD&FP register to be transferred, encoded in the "Rt" field. <Dt> Is the 64-bit name of the SIMD&FP register to be transferred, encoded in the "Rt" field. <Qt> Is the 128-bit name of the SIMD&FP register to be transferred, encoded in the "Rt" field.
constant integer t = UInt(Rt); constant integer n = UInt(Rn); constant integer m = UInt(Rm); constant integer datasize = 8 << scale; constant boolean nontemporal = FALSE; constant boolean tagchecked = TRUE; CheckFPEnabled64(); constant bits(64) offset = ExtendReg(m, extend_type, shift, 64); bits(64) address; constant boolean privileged = PSTATE.EL != EL0; constant AccessDescriptor accdesc = CreateAccDescASIMD(MemOp_STORE, nontemporal, tagchecked, privileged); if n == 31 then CheckSPAlignment(); address = SP[]; else address = X[n, 64]; address = AddressAdd(address, offset, accdesc); Mem[address, datasize DIV 8, accdesc] = V[t, datasize];