-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Closed
Labels
api-approvedAPI was approved in API review, it can be implementedAPI was approved in API review, it can be implementedarea-System.Runtime.Intrinsicsarm-sveWork related to arm64 SVE/SVE2 supportWork related to arm64 SVE/SVE2 support
Milestone
Description
namespace System.Runtime.Intrinsics.Arm;
/// VectorT Summary
public abstract partial class Sve : AdvSimd /// Feature: FEAT_SVE Category: firstfaulting
{
/// T: [int, uint], [long, ulong]
public static unsafe Vector<T> GatherVectorByteZeroExtendFirstFaulting(Vector<T> mask, Vector<T2> bases); // LDFF1B
/// T: uint, ulong
public static unsafe Vector<T> GatherVectorByteZeroExtendFirstFaulting(Vector<T> mask, Vector<T> bases); // LDFF1B
/// T: int, uint, long, ulong
public static unsafe Vector<T> GatherVectorByteZeroExtendFirstFaulting(Vector<T> mask, byte* base, Vector<T> offsets); // LDFF1B
/// T: [uint, int], [int, uint], [ulong, long], [long, ulong]
public static unsafe Vector<T> GatherVectorByteZeroExtendFirstFaulting(Vector<T> mask, byte* base, Vector<T2> offsets); // LDFF1B
/// T: [int, uint], [long, ulong]
public static unsafe Vector<T> GatherVectorByteZeroExtendFirstFaulting(Vector<T> mask, Vector<T2> bases, long offset); // LDFF1B
/// T: uint, ulong
public static unsafe Vector<T> GatherVectorByteZeroExtendFirstFaulting(Vector<T> mask, Vector<T> bases, long offset); // LDFF1B
/// T: [float, uint], [int, uint], [double, ulong], [long, ulong]
public static unsafe Vector<T> GatherVectorFirstFaulting(Vector<T> mask, Vector<T2> bases); // LDFF1W or LDFF1D
/// T: uint, ulong
public static unsafe Vector<T> GatherVectorFirstFaulting(Vector<T> mask, Vector<T> bases); // LDFF1W or LDFF1D
/// T: [float, int], [uint, int], [float, uint], [int, uint], [double, long], [ulong, long], [double, ulong], [long, ulong]
public static unsafe Vector<T> GatherVectorFirstFaulting(Vector<T> mask, T* base, Vector<T2> offsets); // LDFF1W or LDFF1D
/// T: int, uint, long, ulong
public static unsafe Vector<T> GatherVectorFirstFaulting(Vector<T> mask, T* base, Vector<T> offsets); // LDFF1W or LDFF1D
/// T: [float, int], [uint, int], [float, uint], [int, uint], [double, long], [ulong, long], [double, ulong], [long, ulong]
public static unsafe Vector<T> GatherVectorFirstFaulting(Vector<T> mask, T* base, Vector<T2> indices); // LDFF1W or LDFF1D
/// T: int, uint, long, ulong
public static unsafe Vector<T> GatherVectorFirstFaulting(Vector<T> mask, T* base, Vector<T> indices); // LDFF1W or LDFF1D
/// T: [float, uint], [int, uint], [double, ulong], [long, ulong]
public static unsafe Vector<T> GatherVectorFirstFaulting(Vector<T> mask, Vector<T2> bases, long offset); // LDFF1W or LDFF1D
/// T: uint, ulong
public static unsafe Vector<T> GatherVectorFirstFaulting(Vector<T> mask, Vector<T> bases, long offset); // LDFF1W or LDFF1D
/// T: [float, uint], [int, uint], [double, ulong], [long, ulong]
public static unsafe Vector<T> GatherVectorFirstFaulting(Vector<T> mask, Vector<T2> bases, long index); // LDFF1W or LDFF1D
/// T: uint, ulong
public static unsafe Vector<T> GatherVectorFirstFaulting(Vector<T> mask, Vector<T> bases, long index); // LDFF1W or LDFF1D
/// T: [int, uint], [long, ulong]
public static unsafe Vector<T> GatherVectorInt16SignExtendFirstFaulting(Vector<T> mask, Vector<T2> bases); // LDFF1SH
/// T: uint, ulong
public static unsafe Vector<T> GatherVectorInt16SignExtendFirstFaulting(Vector<T> mask, Vector<T> bases); // LDFF1SH
/// T: int, uint, long, ulong
public static unsafe Vector<T> GatherVectorInt16SignExtendFirstFaulting(Vector<T> mask, short* base, Vector<T> offsets); // LDFF1SH
/// T: [uint, int], [int, uint], [ulong, long], [long, ulong]
public static unsafe Vector<T> GatherVectorInt16SignExtendFirstFaulting(Vector<T> mask, short* base, Vector<T2> offsets); // LDFF1SH
/// T: int, uint, long, ulong
public static unsafe Vector<T> GatherVectorInt16SignExtendFirstFaulting(Vector<T> mask, short* base, Vector<T> indices); // LDFF1SH
/// T: [uint, int], [int, uint], [ulong, long], [long, ulong]
public static unsafe Vector<T> GatherVectorInt16SignExtendFirstFaulting(Vector<T> mask, short* base, Vector<T2> indices); // LDFF1SH
/// T: [int, uint], [long, ulong]
public static unsafe Vector<T> GatherVectorInt16SignExtendFirstFaulting(Vector<T> mask, Vector<T2> bases, long offset); // LDFF1SH
/// T: uint, ulong
public static unsafe Vector<T> GatherVectorInt16SignExtendFirstFaulting(Vector<T> mask, Vector<T> bases, long offset); // LDFF1SH
/// T: [int, uint], [long, ulong]
public static unsafe Vector<T> GatherVectorInt16SignExtendFirstFaulting(Vector<T> mask, Vector<T2> bases, long index); // LDFF1SH
/// T: uint, ulong
public static unsafe Vector<T> GatherVectorInt16SignExtendFirstFaulting(Vector<T> mask, Vector<T> bases, long index); // LDFF1SH
/// T: [int, uint], [long, ulong]
public static unsafe Vector<T> GatherVectorInt16ZeroExtendFirstFaulting(Vector<T> mask, Vector<T2> bases); // LDFF1H
/// T: uint, ulong
public static unsafe Vector<T> GatherVectorInt16ZeroExtendFirstFaulting(Vector<T> mask, Vector<T> bases); // LDFF1H
/// T: int, uint, long, ulong
public static unsafe Vector<T> GatherVectorInt16ZeroExtendFirstFaulting(Vector<T> mask, ushort* base, Vector<T> offsets); // LDFF1H
/// T: [uint, int], [int, uint], [ulong, long], [long, ulong]
public static unsafe Vector<T> GatherVectorInt16ZeroExtendFirstFaulting(Vector<T> mask, ushort* base, Vector<T2> offsets); // LDFF1H
/// T: int, uint, long, ulong
public static unsafe Vector<T> GatherVectorInt16ZeroExtendFirstFaulting(Vector<T> mask, ushort* base, Vector<T> indices); // LDFF1H
/// T: [uint, int], [int, uint], [ulong, long], [long, ulong]
public static unsafe Vector<T> GatherVectorInt16ZeroExtendFirstFaulting(Vector<T> mask, ushort* base, Vector<T2> indices); // LDFF1H
/// T: [int, uint], [long, ulong]
public static unsafe Vector<T> GatherVectorInt16ZeroExtendFirstFaulting(Vector<T> mask, Vector<T2> bases, long offset); // LDFF1H
/// T: uint, ulong
public static unsafe Vector<T> GatherVectorInt16ZeroExtendFirstFaulting(Vector<T> mask, Vector<T> bases, long offset); // LDFF1H
/// T: [int, uint], [long, ulong]
public static unsafe Vector<T> GatherVectorInt16ZeroExtendFirstFaulting(Vector<T> mask, Vector<T2> bases, long index); // LDFF1H
/// T: uint, ulong
public static unsafe Vector<T> GatherVectorInt16ZeroExtendFirstFaulting(Vector<T> mask, Vector<T> bases, long index); // LDFF1H
public static unsafe Vector<long> GatherVectorInt32SignExtendFirstFaulting(Vector<long> mask, Vector<ulong> bases); // LDFF1SW
public static unsafe Vector<ulong> GatherVectorInt32SignExtendFirstFaulting(Vector<ulong> mask, Vector<ulong> bases); // LDFF1SW
/// T: long, ulong
public static unsafe Vector<T> GatherVectorInt32SignExtendFirstFaulting(Vector<T> mask, int* base, Vector<T> offsets); // LDFF1SW
/// T: [ulong, long], [long, ulong]
public static unsafe Vector<T> GatherVectorInt32SignExtendFirstFaulting(Vector<T> mask, int* base, Vector<T2> offsets); // LDFF1SW
/// T: long, ulong
public static unsafe Vector<T> GatherVectorInt32SignExtendFirstFaulting(Vector<T> mask, int* base, Vector<T> indices); // LDFF1SW
/// T: [ulong, long], [long, ulong]
public static unsafe Vector<T> GatherVectorInt32SignExtendFirstFaulting(Vector<T> mask, int* base, Vector<T2> indices); // LDFF1SW
public static unsafe Vector<long> GatherVectorInt32SignExtendFirstFaulting(Vector<long> mask, Vector<ulong> bases, long offset); // LDFF1SW
public static unsafe Vector<ulong> GatherVectorInt32SignExtendFirstFaulting(Vector<ulong> mask, Vector<ulong> bases, long offset); // LDFF1SW
public static unsafe Vector<long> GatherVectorInt32SignExtendFirstFaulting(Vector<long> mask, Vector<ulong> bases, long index); // LDFF1SW
public static unsafe Vector<ulong> GatherVectorInt32SignExtendFirstFaulting(Vector<ulong> mask, Vector<ulong> bases, long index); // LDFF1SW
public static unsafe Vector<long> GatherVectorInt32ZeroExtendFirstFaulting(Vector<long> mask, Vector<ulong> bases); // LDFF1W
public static unsafe Vector<ulong> GatherVectorInt32ZeroExtendFirstFaulting(Vector<ulong> mask, Vector<ulong> bases); // LDFF1W
/// T: long, ulong
public static unsafe Vector<T> GatherVectorInt32ZeroExtendFirstFaulting(Vector<T> mask, uint* base, Vector<T> offsets); // LDFF1W
/// T: [ulong, long], [long, ulong]
public static unsafe Vector<T> GatherVectorInt32ZeroExtendFirstFaulting(Vector<T> mask, uint* base, Vector<T2> offsets); // LDFF1W
/// T: long, ulong
public static unsafe Vector<T> GatherVectorInt32ZeroExtendFirstFaulting(Vector<T> mask, uint* base, Vector<T> indices); // LDFF1W
/// T: [ulong, long], [long, ulong]
public static unsafe Vector<T> GatherVectorInt32ZeroExtendFirstFaulting(Vector<T> mask, uint* base, Vector<T2> indices); // LDFF1W
public static unsafe Vector<long> GatherVectorInt32ZeroExtendFirstFaulting(Vector<long> mask, Vector<ulong> bases, long offset); // LDFF1W
public static unsafe Vector<ulong> GatherVectorInt32ZeroExtendFirstFaulting(Vector<ulong> mask, Vector<ulong> bases, long offset); // LDFF1W
public static unsafe Vector<long> GatherVectorInt32ZeroExtendFirstFaulting(Vector<long> mask, Vector<ulong> bases, long index); // LDFF1W
public static unsafe Vector<ulong> GatherVectorInt32ZeroExtendFirstFaulting(Vector<ulong> mask, Vector<ulong> bases, long index); // LDFF1W
/// T: [int, uint], [long, ulong]
public static unsafe Vector<T> GatherVectorSByteSignExtendFirstFaulting(Vector<T> mask, Vector<T2> bases); // LDFF1SB
/// T: uint, ulong
public static unsafe Vector<T> GatherVectorSByteSignExtendFirstFaulting(Vector<T> mask, Vector<T> bases); // LDFF1SB
/// T: int, uint, long, ulong
public static unsafe Vector<T> GatherVectorSByteSignExtendFirstFaulting(Vector<T> mask, sbyte* base, Vector<T> offsets); // LDFF1SB
/// T: [uint, int], [int, uint], [ulong, long], [long, ulong]
public static unsafe Vector<T> GatherVectorSByteSignExtendFirstFaulting(Vector<T> mask, sbyte* base, Vector<T2> offsets); // LDFF1SB
/// T: [int, uint], [long, ulong]
public static unsafe Vector<T> GatherVectorSByteSignExtendFirstFaulting(Vector<T> mask, Vector<T2> bases, long offset); // LDFF1SB
/// T: uint, ulong
public static unsafe Vector<T> GatherVectorSByteSignExtendFirstFaulting(Vector<T> mask, Vector<T> bases, long offset); // LDFF1SB
/// T: sbyte, short, int, long, byte, ushort, uint, ulong
public static unsafe Vector<T> GetFFR(); // RDFFR // predicated
/// T: short, int, long, ushort, uint, ulong
public static unsafe Vector<T> LoadVectorByteZeroExtendFirstFaulting(byte* address); // LDFF1B // predicated
/// T: float, double, sbyte, short, int, long, byte, ushort, uint, ulong
public static unsafe Vector<T> LoadVectorFirstFaulting(T* address); // LDFF1W or LDFF1D or LDFF1B or LDFF1H // predicated
/// T: int, long, uint, ulong
public static unsafe Vector<T> LoadVectorInt16SignExtendFirstFaulting(short* address); // LDFF1SH // predicated
/// T: int, long, uint, ulong
public static unsafe Vector<T> LoadVectorInt16ZeroExtendFirstFaulting(ushort* address); // LDFF1H // predicated
/// T: long, ulong
public static unsafe Vector<T> LoadVectorInt32SignExtendFirstFaulting(int* address); // LDFF1SW // predicated
/// T: long, ulong
public static unsafe Vector<T> LoadVectorInt32ZeroExtendFirstFaulting(uint* address); // LDFF1W // predicated
/// T: short, int, long, ushort, uint, ulong
public static unsafe Vector<T> LoadVectorSByteSignExtendFirstFaulting(sbyte* address); // LDFF1SB // predicated
public static unsafe void SetFFR(); // SETFFR
/// T: sbyte, short, int, long, byte, ushort, uint, ulong
public static unsafe void WriteFFR(Vector<T> value); // WRFFR
/// total method signatures: 72
}First Faulting Loads
Each First Faulting LoadVector method matches a non-faulting version in #94006.
Loads a vector element by element. If loading that element would cause a fault, then stop the load and set the first faulting register for each element that completed. If no elements fault, then the load completes as per the non-faulting version.
After calling a first faulting load, the first faulting mask should always be read to determine if the load completed.
GetFFR(), SetFFR() and WriteFFR() are used to access the ffr mask for the last first faulting load.
// Look for the 0 at the end of the buffer
long strlen(byte *buffer)
{
long i = 0;
Sve.SetFFR();
while (1)
{
// Load data from the buffer. maskfrr contains the elements that were loaded.
Vector<byte> data = Sve.LoadVectorFirstFaulting(buffer + i);
Vector<byte> maskfrr = Sve.GetFFR(all);
// Look for zeros in the loaded data
Vector<byte> zeromask = Sve.ConditionalSelect(maskfrr, Sve.CompareEquals(data, 0), Vector<byte>.Zero);
if (Sve.ConditionalSelect(Sve.MaskTestAnyTrue(zeromask))) {
// There was a zero in the loaded data. Increment up to the zero and exit the loop
zeromask = Sve.BreakBefore(zeromask);
i += Sve.GetActiveElementCount(zeromask);
break;
} else if (Sve.MaskTestLastTrue(maskffr)) {
// Final bit in the ffr mask is set, therefore the load completed. Increment and continue.
i += Sve.Count8BitElements();
} else {
// The load faulted. Increment by the number of loaded elements and continue.
Sve.SetFFR();
i += Sve.GetActiveElementCount(maskfrr);
}
}
return i;
}Metadata
Metadata
Assignees
Labels
api-approvedAPI was approved in API review, it can be implementedAPI was approved in API review, it can be implementedarea-System.Runtime.Intrinsicsarm-sveWork related to arm64 SVE/SVE2 supportWork related to arm64 SVE/SVE2 support