ld2r
Load 2-Element Structure Replicate
LD2R { <Vt1>.<T>, <Vt2>.<T> }, [<Xn|SP>]
Loads 2 elements and replicates them to all lanes.
Details
Loads two consecutive elements from memory and replicates each to all corresponding lanes of two destination NEON vector registers. The two elements are interleaved in memory; Q bit selects 64-bit (Q=0, 1 pair) or 128-bit (Q=1, 2 pairs) operation. No condition flags are affected; the instruction is AArch64 NEON-only.
Pseudocode Operation
address ← Xn|SP
element_size ← size_from_T
element1 ← mem[address + 0 * element_size]
element2 ← mem[address + 1 * element_size]
if Q == 1 then
lanes ← 16 / element_size
else
lanes ← 8 / element_size
for i = 0 to lanes - 1 do
Vt1[i] ← element1
Vt2[i] ← element2
Xn|SP ← (post-index mode) ? Xn|SP + (2 * element_size) : Xn|SP
Example
LD2R [x1]
Encoding
Binary Layout
0
Q
0011010
1
1
0000
0
110
0
size
Rn
Rt
Operands
-
Vt1
Dest 1 -
Vt2
Dest 2 -
Xn
First source / base 64-bit integer register
Reference (Arm A64 ISA)
Instruction Forms
| Encoding | Instruction | ISA | Bit pattern | ||
|---|---|---|---|---|---|
| 0x0D60C000 | LD2R { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>] | A64 | 0 | Q | 0011010 | 1 | 1 | 0000 | 0 | 110 | 0 | size | Rn | Rt | ||
| 0x0DFFC000 | LD2R { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm> | A64 | 0 | Q | 0011011 | 1 | 1 | 11111 | 110 | 0 | size | Rn | Rt | ||
| 0x0DE0C000 | LD2R { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm> | A64 | 0 | Q | 0011011 | 1 | 1 | Rm | 110 | 0 | size | Rn | Rt |
Description
Load single 2-element structure and Replicate to all lanes of two registers. This instruction loads a 2-element structure from memory and replicates the structure to all the lanes of the two SIMD&FP registers.
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;