ldff1w

SVE Load First-Fault Contiguous Words

LDFF1W { <Zt>.S }, <Pg>/Z, [<Xn|SP>]

Loads words speculatively; suppresses faults after the first active element.

Details

Loads words from memory into a scalable vector register with first-fault semantics; subsequent faults are suppressed if any active element has already been loaded. Only elements where the predicate is true are loaded. This instruction is AArch64-only and requires SVE. No condition flags are set.

Pseudocode Operation

for i ← 0 to (VL/32 - 1) do if Pg[i] then Zt[i*32+31:i*32] ← [Xn + i*4]; faulted ← false; end if; if fault_occurs and faulted then suppress_fault; faulted ← true; end if; end for

Example

LDFF1W p0/m/Z, [x1]

Encoding

Binary Layout
1000010
1
0
xs
0
Zm
0
1
1
Pg
Rn
Zt
 
Format SVE Load
Opcode 0x85006000
Extension SVE

Operands

  • Zt
    Transfer scalable vector register (SVE load/store)
  • Pg
    Predicate
  • Xn
    First source / base 64-bit integer register

Reference (Arm A64 ISA)

Instruction Forms

Encoding Instruction ISA Bit pattern
0x8520E000 LDFF1W { <Zt>.S }, <Pg>/Z, [<Zn>.S{, #<imm>}] A64 1000010 | 1 | 0 | 01 | imm5 | 1 | 1 | 1 | Pg | Zn | Zt
0xC520E000 LDFF1W { <Zt>.D }, <Pg>/Z, [<Zn>.D{, #<imm>}] A64 1100010 | 1 | 0 | 01 | imm5 | 1 | 1 | 1 | Pg | Zn | Zt
0xA5406000 LDFF1W { <Zt>.S }, <Pg>/Z, [<Xn|SP>{, <Xm>, LSL #2}] A64 1010010 | 101 | 0 | Rm | 011 | Pg | Rn | Zt
0xA5606000 LDFF1W { <Zt>.D }, <Pg>/Z, [<Xn|SP>{, <Xm>, LSL #2}] A64 1010010 | 101 | 1 | Rm | 011 | Pg | Rn | Zt
0x85206000 LDFF1W { <Zt>.S }, <Pg>/Z, [<Xn|SP>, <Zm>.S, <mod> #2] A64 100001010 | xs | 1 | Zm | 0 | 1 | 1 | Pg | Rn | Zt
0xC5206000 LDFF1W { <Zt>.D }, <Pg>/Z, [<Xn|SP>, <Zm>.D, <mod> #2] A64 1100010 | 1 | 0 | xs | 1 | Zm | 0 | 1 | 1 | Pg | Rn | Zt
0xC5006000 LDFF1W { <Zt>.D }, <Pg>/Z, [<Xn|SP>, <Zm>.D, <mod>] A64 1100010 | 1 | 0 | xs | 0 | Zm | 0 | 1 | 1 | Pg | Rn | Zt
0x85006000 LDFF1W { <Zt>.S }, <Pg>/Z, [<Xn|SP>, <Zm>.S, <mod>] A64 1000010 | 1 | 0 | xs | 0 | Zm | 0 | 1 | 1 | Pg | Rn | Zt
0xC560E000 LDFF1W { <Zt>.D }, <Pg>/Z, [<Xn|SP>, <Zm>.D, LSL #2] A64 1100010 | 1 | 0 | 11 | Zm | 1 | 1 | 1 | Pg | Rn | Zt
0xC540E000 LDFF1W { <Zt>.D }, <Pg>/Z, [<Xn|SP>, <Zm>.D] A64 1100010 | 1 | 0 | 10 | Zm | 1 | 1 | 1 | Pg | Rn | Zt

Description

Gather load with first-faulting behavior of unsigned words to active elements of a vector register from memory addresses generated by a 64-bit scalar base plus vector index. The index values are optionally first sign or zero-extended from 32 to 64 bits and then optionally multiplied by 4. Inactive elements will not cause a read from Device memory or signal faults, and are set to zero in the destination vector. This instruction is illegal when executed in Streaming SVE mode, unless FEAT_SME_FA64 is implemented and enabled.

Operation

CheckNonStreamingSVEEnabled();
constant integer VL = CurrentVL;
constant integer PL = VL DIV 8;
constant integer elements = VL DIV esize;
bits(PL) mask = P[g, PL];
bits(64) base;
bits(VL) offset;
bits(VL) result;
bits(VL) orig = Z[t, VL];
bits(msize) data;
constant integer mbytes = msize DIV 8;
boolean fault = FALSE;
boolean faulted = FALSE;
boolean unknown = FALSE;
boolean contiguous = FALSE;
boolean tagchecked = TRUE;
AccessDescriptor accdesc = CreateAccDescSVEFF(contiguous, tagchecked);

if !AnyActiveElement(mask, esize) then
    if n == 31 && ConstrainUnpredictableBool(Unpredictable_CHECKSPNONEACTIVE) then
        CheckSPAlignment();
else
    if n == 31 then CheckSPAlignment();
    base = if n == 31 then SP[] else X[n, 64];
    offset = Z[m, VL];

assert accdesc.first;

for e = 0 to elements-1
    if ActivePredicateElement(mask, e, esize) then
        integer off = Int(Elem[offset, e, esize]<offs_size-1:0>, offs_unsigned);
        bits(64) addr = GenerateAddress(base, off << scale, accdesc);
        if accdesc.first then
            // Mem[] will not return if a fault is detected for the first active element
            data = Mem[addr, mbytes, accdesc];
            accdesc.first = FALSE;
        else
            // MemNF[] will return fault=TRUE if access is not performed for any reason
            (data, fault) = MemNF[addr, mbytes, accdesc];
    else
        (data, fault) = (Zeros(msize), FALSE);

    // FFR elements set to FALSE following a suppressed access/fault
    faulted = faulted || fault;
    if faulted then
        ElemFFR[e, esize] = '0';

    // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE
    unknown = unknown || ElemFFR[e, esize] == '0';
    if unknown then
        if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then
            Elem[result, e, esize] = Extend(data, esize, unsigned);
        elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then
            Elem[result, e, esize] = Zeros(esize);
        else  // merge
            Elem[result, e, esize] = Elem[orig, e, esize];
    else
        Elem[result, e, esize] = Extend(data, esize, unsigned);

Z[t, VL] = result;