ldnp

Load Pair of Registers (Non-temporal)

LDNP <Wt1>, <Wt2>, [<Xn|SP>, #<imm>]

Loads two words, hinting non-temporal data (no caching).

Details

Load Pair of Registers (Non-temporal) loads two 32-bit words from memory into two registers with a non-temporal hint indicating the data is unlikely to be reused soon, allowing the processor to avoid cache pollution. The instruction does not affect the condition flags. It executes in AArch64 state and is available at all privilege levels.

Pseudocode Operation

address ← Xn + (sign_extend(imm7) << 2); Wt1 ← [address]; Wt2 ← [address + 4]

Example

LDNP w3, w4, [x1, #16]

Encoding

Binary Layout
00
101
0
000
1
imm7
Rt2
Rn
Rt
 
Format Load/Store Pair
Opcode 0x28400000
Extension Base

Operands

  • Wt1
    Target 1
  • Wt2
    Target 2
  • Xn
    First source / base 64-bit integer register
  • imm
    Signed immediate value

Reference (Arm A64 ISA)

Instruction Forms

Encoding Instruction ISA Bit pattern
0x2C400000 LDNP <St1>, <St2>, [<Xn|SP>{, #<imm>}] A64 00 | 101 | 1 | 000 | 1 | imm7 | Rt2 | Rn | Rt
0x6C400000 LDNP <Dt1>, <Dt2>, [<Xn|SP>{, #<imm>}] A64 01 | 101 | 1 | 000 | 1 | imm7 | Rt2 | Rn | Rt
0xAC400000 LDNP <Qt1>, <Qt2>, [<Xn|SP>{, #<imm>}] A64 10 | 101 | 1 | 000 | 1 | imm7 | Rt2 | Rn | Rt
0x28400000 LDNP <Wt1>, <Wt2>, [<Xn|SP>{, #<imm>}] A64 00 | 101 | 0 | 000 | 1 | imm7 | Rt2 | Rn | Rt
0xA8400000 LDNP <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}] A64 10 | 101 | 0 | 000 | 1 | imm7 | Rt2 | Rn | Rt

Description

Load Pair of Registers, with non-temporal hint, calculates an address from a base register value and an immediate offset, loads two 32-bit words or two 64-bit doublewords from memory, and writes them to two registers. For information about memory accesses, see Load/Store addressing modes. For information about Non-temporal pair instructions, see Load/Store Non-temporal pair.

Operation

bits(64) address;
bits(64) address2;
bits(datasize) data1;
bits(datasize) data2;
constant integer dbytes = datasize DIV 8;
boolean privileged = PSTATE.EL != EL0;

AccessDescriptor accdesc = CreateAccDescGPR(MemOp_LOAD, TRUE, privileged, tagchecked);

if n == 31 then
    CheckSPAlignment();
    address = SP[];
else
    address = X[n, 64];

address = GenerateAddress(address, offset, accdesc);

if IsFeatureImplemented(FEAT_LSE2) then
    bits(2*datasize) full_data;
    accdesc.ispair = TRUE;
    full_data = Mem[address, 2*dbytes, accdesc];
    if BigEndian(accdesc.acctype) then
        data2 = full_data<(datasize-1):0>;
        data1 = full_data<(2*datasize-1):datasize>;
    else
        data1 = full_data<(datasize-1):0>;
        data2 = full_data<(2*datasize-1):datasize>;
else
    address2 = GenerateAddress(address, dbytes, accdesc);
    data1 = Mem[address, dbytes, accdesc];
    data2 = Mem[address2, dbytes, accdesc];
if rt_unknown then
    data1 = bits(datasize) UNKNOWN;
    data2 = bits(datasize) UNKNOWN;
X[t, datasize] = data1;
X[t2, datasize] = data2;