ldff1b

SVE Load First-Fault Contiguous Bytes

LDFF1B { <Zt>.B }, <Pg>/Z, [<Xn|SP>]

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

Details

Loads bytes 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/8 - 1) do if Pg[i] then Zt[i*8+7:i*8] ← [Xn + i]; faulted ← false; end if; if fault_occurs and faulted then suppress_fault; faulted ← true; end if; end for

Example

LDFF1B p0/m/Z, [x1]

Encoding

Binary Layout
1010010
000
0
Rm
011
Pg
Rn
Zt
 
Format SVE Load
Opcode 0xA4006000
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
0x8420E000 LDFF1B { <Zt>.S }, <Pg>/Z, [<Zn>.S{, #<imm>}] A64 1000010 | 0 | 0 | 01 | imm5 | 1 | 1 | 1 | Pg | Zn | Zt
0xC420E000 LDFF1B { <Zt>.D }, <Pg>/Z, [<Zn>.D{, #<imm>}] A64 1100010 | 0 | 0 | 01 | imm5 | 1 | 1 | 1 | Pg | Zn | Zt
0xA4006000 LDFF1B { <Zt>.B }, <Pg>/Z, [<Xn|SP>{, <Xm>}] A64 1010010 | 000 | 0 | Rm | 011 | Pg | Rn | Zt
0xA4206000 LDFF1B { <Zt>.H }, <Pg>/Z, [<Xn|SP>{, <Xm>}] A64 1010010 | 000 | 1 | Rm | 011 | Pg | Rn | Zt
0xA4406000 LDFF1B { <Zt>.S }, <Pg>/Z, [<Xn|SP>{, <Xm>}] A64 1010010 | 001 | 0 | Rm | 011 | Pg | Rn | Zt
0xA4606000 LDFF1B { <Zt>.D }, <Pg>/Z, [<Xn|SP>{, <Xm>}] A64 1010010 | 001 | 1 | Rm | 011 | Pg | Rn | Zt
0xC4006000 LDFF1B { <Zt>.D }, <Pg>/Z, [<Xn|SP>, <Zm>.D, <mod>] A64 1100010 | 0 | 0 | xs | 0 | Zm | 0 | 1 | 1 | Pg | Rn | Zt
0x84006000 LDFF1B { <Zt>.S }, <Pg>/Z, [<Xn|SP>, <Zm>.S, <mod>] A64 1000010 | 0 | 0 | xs | 0 | Zm | 0 | 1 | 1 | Pg | Rn | Zt
0xC440E000 LDFF1B { <Zt>.D }, <Pg>/Z, [<Xn|SP>, <Zm>.D] A64 1100010 | 0 | 0 | 10 | Zm | 1 | 1 | 1 | Pg | Rn | Zt

Description

Contiguous load with first-faulting behavior of unsigned bytes to elements of a vector register from the memory address generated by a 64-bit scalar base and scalar index which is added to the base address. After each element access the index value is incremented, but the index register is not updated. Inactive elements will not cause a read from Device memory or signal a fault, 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(64) base;
bits(PL) mask = P[g, PL];
bits(VL) result;
bits(VL) orig = Z[t, VL];
bits(msize) data;
bits(64) offset;
constant integer mbytes = msize DIV 8;
boolean fault = FALSE;
boolean faulted = FALSE;
boolean unknown = FALSE;
boolean contiguous = TRUE;
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 = X[m, 64];

assert accdesc.first;

for e = 0 to elements-1
    if ActivePredicateElement(mask, e, esize) then
        integer eoff = UInt(offset) + e;
        bits(64) addr = GenerateAddress(base, eoff * mbytes, 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;