Load vector register
Load a vector register from a memory address generated by a 64-bit scalar base, plus an immediate offset in the range -256 to 255 which is multiplied by the current vector register size in bytes. This instruction is unpredicated.
The load is performed as contiguous byte accesses, with no endian conversion and no guarantee of single-copy atomicity larger than a byte. However, if alignment is checked, then the base register must be aligned to 16 bytes.
Variants: FEAT_SVE || FEAT_SME (FEAT_SVE || FEAT_SME)
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 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | |||||||||||||||||||
imm9h | imm9l | Rn | Zt |
---|
LDR <Zt>, [<Xn|SP>{, #<imm>, MUL VL}]
if !IsFeatureImplemented(FEAT_SVE) && !IsFeatureImplemented(FEAT_SME) then EndOfDecode(Decode_UNDEF); constant integer t = UInt(Zt); constant integer n = UInt(Rn); constant integer imm = SInt(imm9h:imm9l);
CheckSVEEnabled(); constant integer VL = CurrentVL; constant integer PL = VL DIV 8; constant integer elements = VL DIV 8; bits(64) base; constant integer offset = imm * elements; bits(VL) result; constant boolean contiguous = TRUE; constant boolean nontemporal = FALSE; constant boolean tagchecked = n != 31; constant AccessDescriptor accdesc = CreateAccDescSVE(MemOp_LOAD, nontemporal, contiguous, tagchecked); if n == 31 then CheckSPAlignment(); base = SP[64]; else base = X[n, 64]; bits(64) addr = AddressAdd(base, offset, accdesc); constant boolean aligned = IsAligned(addr, 16); if !aligned && AlignmentEnforced() then constant FaultRecord fault = AlignmentFault(accdesc, addr); AArch64.Abort(fault); for e = 0 to elements-1 Elem[result, e, 8] = AArch64.MemSingle[addr, 1, accdesc, aligned]; addr = AddressIncrement(addr, 1, accdesc); Z[t, VL] = result;
If PSTATE.DIT is 1, the timing of this instruction is insensitive to the value of the data being loaded or stored.