ld2

Load Multiple 2-Element Structures

LD2 { <Vt1>.<T>, <Vt2>.<T> }, [<Xn|SP>]

Loads two-element structures from memory into two registers (De-interleave).

Details

Loads two consecutive 2-element SIMD structures from memory, de-interleaving them into two registers (Vt1 and Vt2). The element type T and Q field determine whether 64-bit (Q=0, per-register) or 128-bit (Q=1) structures are loaded; the base address in Xn is post-incremented by the number of bytes loaded. This AArch64 NEON instruction does not modify condition flags.

Pseudocode Operation

elements_per_struct ← 2; element_size ← GetElementSize(T); struct_bytes ← 2 * elements_per_struct * element_size; mem_addr ← Xn; (Vt1, Vt2) ← DeinterleaveLoad(mem_addr, struct_bytes, Q); Xn ← Xn + struct_bytes;

Example

LD2 [x1]

Encoding

Binary Layout
0
Q
0011000
1
000000
1000
size
Rn
Rt
 
Format SIMD Load/Store
Opcode 0x0C408000
Extension NEON (SIMD)

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
0x0C408000 LD2 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>] A64 0 | Q | 0011000 | 1 | 000000 | 1000 | size | Rn | Rt
0x0CDF8000 LD2 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm> A64 0 | Q | 0011001 | 1 | 0 | 11111 | 1000 | size | Rn | Rt
0x0CC08000 LD2 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm> A64 0 | Q | 0011001 | 1 | 0 | Rm | 1000 | size | Rn | Rt
0x0D600000 LD2 { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>] A64 0 | Q | 0011010 | 1 | 1 | 0000 | 0 | 000 | S | size | Rn | Rt
0x0D604000 LD2 { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>] A64 0 | Q | 0011010 | 1 | 1 | 0000 | 0 | 010 | S | size | Rn | Rt
0x0D608000 LD2 { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>] A64 0 | Q | 0011010 | 1 | 1 | 0000 | 0 | 100 | S | 00 | Rn | Rt
0x0D608400 LD2 { <Vt>.D, <Vt2>.D }[<index>], [<Xn|SP>] A64 0 | Q | 0011010 | 1 | 1 | 0000 | 0 | 100 | 0 | 01 | Rn | Rt
0x0DFF0000 LD2 { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>], #2 A64 0 | Q | 0011011 | 1 | 1 | 11111 | 000 | S | size | Rn | Rt
0x0DE00000 LD2 { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>], <Xm> A64 0 | Q | 0011011 | 1 | 1 | Rm | 000 | S | size | Rn | Rt
0x0DFF4000 LD2 { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>], #4 A64 0 | Q | 0011011 | 1 | 1 | 11111 | 010 | S | size | Rn | Rt
0x0DE04000 LD2 { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>], <Xm> A64 0 | Q | 0011011 | 1 | 1 | Rm | 010 | S | size | Rn | Rt
0x0DFF8000 LD2 { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>], #8 A64 0 | Q | 0011011 | 1 | 1 | 11111 | 100 | S | 00 | Rn | Rt
0x0DE08000 LD2 { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>], <Xm> A64 0 | Q | 0011011 | 1 | 1 | Rm | 100 | S | 00 | Rn | Rt
0x0DFF8400 LD2 { <Vt>.D, <Vt2>.D }[<index>], [<Xn|SP>], #16 A64 0 | Q | 0011011 | 1 | 1 | 11111 | 100 | 0 | 01 | Rn | Rt

Description

Load multiple 2-element structures to two registers. This instruction loads multiple 2-element structures from memory and writes the result to the two SIMD&FP registers, with de-interleaving. For an example of de-interleaving, see LD3 (multiple structures). 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(datasize) rval;
integer tt;
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);
for r = 0 to rpt-1
    for e = 0 to elements-1
        tt = (t + r) MOD 32;
        for s = 0 to selem-1
            rval = V[tt, datasize];
            eaddr = GenerateAddress(address, offs, accdesc);
            if memop == MemOp_LOAD then
                Elem[rval, e, esize] = Mem[eaddr, ebytes, accdesc];
                V[tt, datasize] = rval;
            else // memop == MemOp_STORE
                Mem[eaddr, ebytes, accdesc] = Elem[rval, e, esize];
            offs = offs + ebytes;
            tt = (tt + 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;