-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Summary
In addition to providing 512-bit versions of existing instructions, AVX512 also provides various new instructions that were not available in previous ISAs. It makes 128-bit and 256-bit versions of these instructions available under the AVX512VL ISA.
As described in #73604, AVX512VL is somewhat special in that it is not its own self-contained ISA. Rather, when the CPUID flag is present it extends each other AVX512 ISA with 128-bit and 256-bit instruction support.
Given we don't support multiple inheritance in .NET, the easiest way to model this using our existing semantics is to expose a nested class named VL. Just like with the nested X64 base class, it is only supported when the parent ISA is also supported. Likewise, for derived classes (such as Avx512BW), its own nested class can derive from Avx512F.VL and otherwise flow the normal ISA checks as expected. This also avoids needing to consider complexities for names such as Avx512BW_VL or some variant there-of.
API Proposal
We should expose the Avx512F.VL class as the first part of the AVX512 feature set.
public abstract partial class Avx512F : Avx2
{
public abstract partial class VL
{
public static bool IsSupported { get; }
// AVX512
public static Vector256<int> BroadcastToVector256(Vector128<int> value);
public static Vector256<uint> BroadcastToVector256(Vector128<uint> value);
public static Vector256<float> BroadcastToVector256(Vector128<float> value);
public static Vector128<byte> ConvertToVector128Byte(Vector256<int> value);
public static Vector128<byte> ConvertToVector128Byte(Vector128<int> value);
public static Vector128<byte> ConvertToVector128Byte(Vector256<long> value);
public static Vector128<byte> ConvertToVector128Byte(Vector128<long> value);
public static Vector128<byte> ConvertToVector128Byte(Vector256<uint> value);
public static Vector128<byte> ConvertToVector128Byte(Vector128<uint> value);
public static Vector128<byte> ConvertToVector128Byte(Vector256<ulong> value);
public static Vector128<byte> ConvertToVector128Byte(Vector128<ulong> value);
public static Vector128<byte> ConvertToVector128ByteWithSaturation(Vector256<uint> value);
public static Vector128<byte> ConvertToVector128ByteWithSaturation(Vector128<uint> value);
public static Vector128<byte> ConvertToVector128ByteWithSaturation(Vector256<ulong> value);
public static Vector128<byte> ConvertToVector128ByteWithSaturation(Vector128<ulong> value);
public static Vector128<short> ConvertToVector128Int16(Vector256<int> value);
public static Vector128<short> ConvertToVector128Int16(Vector128<int> value);
public static Vector128<short> ConvertToVector128Int16(Vector256<long> value);
public static Vector128<short> ConvertToVector128Int16(Vector128<long> value);
public static Vector128<short> ConvertToVector128Int16(Vector256<uint> value);
public static Vector128<short> ConvertToVector128Int16(Vector128<uint> value);
public static Vector128<short> ConvertToVector128Int16(Vector256<ulong> value);
public static Vector128<short> ConvertToVector128Int16(Vector128<ulong> value);
public static Vector128<int> ConvertToVector128Int32(Vector256<long> value);
public static Vector128<int> ConvertToVector128Int32(Vector128<long> value);
public static Vector128<int> ConvertToVector128Int32(Vector256<ulong> value);
public static Vector128<int> ConvertToVector128Int32(Vector128<ulong> value);
public static Vector128<int> ConvertToVector128Int32WithSaturation(Vector256<long> value);
public static Vector128<int> ConvertToVector128Int32WithSaturation(Vector128<long> value);
public static Vector128<short> ConvertToVector128Int16WithSaturation(Vector256<int> value);
public static Vector128<short> ConvertToVector128Int16WithSaturation(Vector128<int> value);
public static Vector128<short> ConvertToVector128Int16WithSaturation(Vector256<long> value);
public static Vector128<short> ConvertToVector128Int16WithSaturation(Vector128<long> value);
public static Vector128<sbyte> ConvertToVector128SByte(Vector256<int> value);
public static Vector128<sbyte> ConvertToVector128SByte(Vector128<int> value);
public static Vector128<sbyte> ConvertToVector128SByte(Vector256<long> value);
public static Vector128<sbyte> ConvertToVector128SByte(Vector128<long> value);
public static Vector128<sbyte> ConvertToVector128SByte(Vector256<uint> value);
public static Vector128<sbyte> ConvertToVector128SByte(Vector128<uint> value);
public static Vector128<sbyte> ConvertToVector128SByte(Vector256<ulong> value);
public static Vector128<sbyte> ConvertToVector128SByte(Vector128<ulong> value);
public static Vector128<sbyte> ConvertToVector128SByteWithSaturation(Vector256<int> value);
public static Vector128<sbyte> ConvertToVector128SByteWithSaturation(Vector128<int> value);
public static Vector128<sbyte> ConvertToVector128SByteWithSaturation(Vector256<long> value);
public static Vector128<sbyte> ConvertToVector128SByteWithSaturation(Vector128<long> value);
public static Vector128<ushort> ConvertToVector128UInt16(Vector256<int> value);
public static Vector128<ushort> ConvertToVector128UInt16(Vector128<int> value);
public static Vector128<ushort> ConvertToVector128UInt16(Vector256<long> value);
public static Vector128<ushort> ConvertToVector128UInt16(Vector128<long> value);
public static Vector128<ushort> ConvertToVector128UInt16(Vector256<uint> value);
public static Vector128<ushort> ConvertToVector128UInt16(Vector128<uint> value);
public static Vector128<ushort> ConvertToVector128UInt16(Vector256<ulong> value);
public static Vector128<ushort> ConvertToVector128UInt16(Vector128<ulong> value);
public static Vector128<ushort> ConvertToVector128UInt16WithSaturation(Vector256<uint> value);
public static Vector128<ushort> ConvertToVector128UInt16WithSaturation(Vector128<uint> value);
public static Vector128<short> ConvertToVector128UInt16WithSaturation(Vector256<long> value);
public static Vector128<short> ConvertToVector128UInt16WithSaturation(Vector128<long> value);
public static Vector128<uint> ConvertToVector128UInt32(Vector256<double> value);
public static Vector128<uint> ConvertToVector128UInt32(Vector128<float> value);
public static Vector128<uint> ConvertToVector128UInt32(Vector256<long> value);
public static Vector128<uint> ConvertToVector128UInt32(Vector128<long> value);
public static Vector128<uint> ConvertToVector128UInt32(Vector256<ulong> value);
public static Vector128<uint> ConvertToVector128UInt32(Vector128<ulong> value);
public static Vector128<uint> ConvertToVector128UInt32WithSaturation(Vector256<ulong> value);
public static Vector128<uint> ConvertToVector128UInt32WithSaturation(Vector128<ulong> value);
public static Vector256<double> ConvertToVector256Double(Vector128<uint> value);
public static Vector128<double> ConvertToVector128Double(Vector128<uint> value);
public static Vector256<float> ConvertToVector256Single(Vector128<uint> value);
public static Vector128<float> ConvertToVector128Single(Vector128<uint> value);
public static Vector256<double> Fixup(Vector256<double> left, Vector256<double> right, Vector256<long> table);
public static Vector128<double> Fixup(Vector128<double> left, Vector128<double> right, Vector128<long> table);
public static Vector256<float> Fixup(Vector256<float> left, Vector256<float> right, Vector256<int> table);
public static Vector128<float> Fixup(Vector128<float> left, Vector128<float> right, Vector128<int> table);
public static Vector256<double> GetExponent(Vector256<double> value);
public static Vector128<double> GetExponent(Vector128<double> value);
public static Vector256<float> GetExponent(Vector256<float> value);
public static Vector128<float> GetExponent(Vector128<float> value);
public static Vector256<double> GetMantissa(Vector256<double> value, byte interval, byte signControl);
public static Vector128<double> GetMantissa(Vector128<double> value, byte interval, byte signControl);
public static Vector256<float> GetMantissa(Vector256<float> value, byte interval, byte signControl);
public static Vector128<float> GetMantissa(Vector128<float> value, byte interval, byte signControl);
public static Vector128<double> PermuteVar2x64(Vector128<double> left, Vector128<double> right, Vector128<long> control);
public static Vector128<long> PermuteVar2x64(Vector128<long> left, Vector128<long> right, Vector128<long> control);
public static Vector128<ulong> PermuteVar2x64(Vector128<ulong> left, Vector128<ulong> right, Vector128<ulong> control);
public static Vector128<float> PermuteVar4x32(Vector128<float> left, Vector128<float> right>, Vector128<int> control);
public static Vector128<int> PermuteVar4x32(Vector128<int> left, Vector128<int> right, Vector128<int> control);
public static Vector128<uint> PermuteVar4x32(Vector128<uint> left, Vector128<uint> right, Vector128<uint> control);
public static Vector256<double> PermuteVar4x64(Vector256<double> value, Vector256<long> control);
public static Vector256<double> PermuteVar4x64(Vector256<double> left, Vector256<double> right, Vector256<long> control);
public static Vector256<long> PermuteVar4x64(Vector256<long> value, Vector256<long> control);
public static Vector256<long> PermuteVar4x64(Vector256<long> left, Vector256<long> right, Vector256<long> control);
public static Vector256<ulong> PermuteVar4x64(Vector256<ulong> value, Vector256<ulong> control);
public static Vector256<ulong> PermuteVar4x64(Vector256<ulong> left, Vector256<ulong> right, Vector256<ulong> control);
public static Vector256<float> PermuteVar8x32(Vector256<float> value, Vector256<int> control);
public static Vector256<float> PermuteVar8x32(Vector256<float> left, Vector256<float> right>, Vector256<int> control);
public static Vector256<int> PermuteVar8x32(Vector256<int> left, Vector256<int> right, Vector256<int> control);
public static Vector256<uint> PermuteVar8x32(Vector256<uint> left, Vector256<uint> right, Vector256<uint> control);
public static Vector256<long> ShiftRightArithmeticVariable(Vector256<long> value, Vector256<ulong> count);
public static Vector128<long> ShiftRightArithmeticVariable(Vector256<int> value, Vector256<uint> count);
public static Vector256<int> RotateLeft(Vector256<int> value, byte count);
public static Vector128<int> RotateLeft(Vector128<int> value, byte count);
public static Vector256<long> RotateLeft(Vector256<long> value, byte count);
public static Vector128<long> RotateLeft(Vector128<long> value, byte count);
public static Vector256<uint> RotateLeft(Vector256<uint> value, byte count);
public static Vector128<uint> RotateLeft(Vector128<uint> value, byte count);
public static Vector256<ulong> RotateLeft(Vector256<ulong> value, byte count);
public static Vector128<ulong> RotateLeft(Vector128<ulong> value, byte count);
public static Vector256<int> RotateLeftVariable(Vector256<int> value, Vector256<int> count);
public static Vector128<int> RotateLeftVariable(Vector128<int> value, Vector128<int> count);
public static Vector256<long> RotateLeftVariable(Vector256<long> value, Vector256<long> count);
public static Vector128<long> RotateLeftVariable(Vector128<long> value, Vector128<long> count);
public static Vector256<uint> RotateLeftVariable(Vector256<uint> value, Vector256<uint> count);
public static Vector128<uint> RotateLeftVariable(Vector128<uint> value, Vector128<uint> count);
public static Vector256<ulong> RotateLeftVariable(Vector256<ulong> value, Vector256<ulong> count);
public static Vector128<ulong> RotateLeftVariable(Vector128<ulong> value, Vector128<ulong> count);
public static Vector256<int> RotateRight(Vector256<int> value, byte count);
public static Vector128<int> RotateRight(Vector128<int> value, byte count);
public static Vector256<long> RotateRight(Vector256<long> value, byte count);
public static Vector128<long> RotateRight(Vector128<long> value, byte count);
public static Vector256<uint> RotateRight(Vector256<uint> value, byte count);
public static Vector128<uint> RotateRight(Vector128<uint> value, byte count);
public static Vector256<ulong> RotateRight(Vector256<ulong> value, byte count);
public static Vector128<ulong> RotateRight(Vector128<ulong> value, byte count);
public static Vector256<int> RotateRightVariable(Vector256<int> value, Vector256<int> count);
public static Vector128<int> RotateRightVariable(Vector128<int> value, Vector128<int> count);
public static Vector256<long> RotateRightVariable(Vector256<long> value, Vector256<long> count);
public static Vector128<long> RotateRightVariable(Vector128<long> value, Vector128<long> count);
public static Vector256<uint> RotateRightVariable(Vector256<uint> value, Vector256<uint> count);
public static Vector128<uint> RotateRightVariable(Vector128<uint> value, Vector128<uint> count);
public static Vector256<ulong> RotateRightVariable(Vector256<ulong> value, Vector256<ulong> count);
public static Vector128<ulong> RotateRightVariable(Vector128<ulong> value, Vector128<ulong> count);
public static void Scatter(double* baseAddress, Vector128<int> index, byte scale, Vector256<double> value);
public static void Scatter(double* baseAddress, Vector128<int> index, byte scale, Vector128<double> value);
public static void Scatter(double* baseAddress, Vector256<double> index, byte scale, Vector256<double> value);
public static void Scatter(double* baseAddress, Vector128<double> index, byte scale, Vector128<double> value);
public static void Scatter(int* baseAddress, Vector256<int> index, byte scale, Vector256<int> value);
public static void Scatter(int* baseAddress, Vector128<int> index, byte scale, Vector128<int> value);
public static void Scatter(int* baseAddress, Vector256<long> index, byte scale, Vector128<int> value);
public static void Scatter(int* baseAddress, Vector128<long> index, byte scale, Vector128<int> value);
public static void Scatter(long* baseAddress, Vector128<int> index, byte scale, Vector256<long> value);
public static void Scatter(long* baseAddress, Vector128<int> index, byte scale, Vector128<long> value);
public static void Scatter(long* baseAddress, Vector256<long> index, byte scale, Vector256<long> value);
public static void Scatter(long* baseAddress, Vector128<long> index, byte scale, Vector128<long> value);
public static void Scatter(float* baseAddress, Vector256<float> index, byte scale, Vector256<float> value);
public static void Scatter(float* baseAddress, Vector128<float> index, byte scale, Vector128<float> value);
public static void Scatter(float* baseAddress, Vector256<long> index, byte scale, Vector128<float> value);
public static void Scatter(float* baseAddress, Vector128<long> index, byte scale, Vector128<float> value);
public static Vector256<int> TernaryLogic(Vector256<int> left, Vector256<int> right, byte control);
public static Vector128<int> TernaryLogic(Vector128<int> left, Vector128<int> right, byte control);
public static Vector256<long> TernaryLogic(Vector256<long> left, Vector256<long> right, byte control);
public static Vector128<long> TernaryLogic(Vector128<long> left, Vector128<long> right, byte control);
public static Vector256<double> Reciprocal14(Vector256<double> value);
public static Vector128<double> Reciprocal14(Vector128<double> value);
public static Vector256<float> Reciprocal14(Vector256<float> value);
public static Vector128<float> Reciprocal14(Vector128<float> value);
public static Vector256<double> RoundScale(Vector256<double> value, byte scale);
public static Vector128<double> RoundScale(Vector128<double> value, byte scale);
public static Vector256<float> RoundScale(Vector256<float> value, byte scale);
public static Vector128<float> RoundScale(Vector128<float> value, byte scale);
public static Vector256<double> ReciprocalSqrt14(Vector256<double> value);
public static Vector128<double> ReciprocalSqrt14(Vector128<double> value);
public static Vector256<float> ReciprocalSqrt14(Vector256<float> value);
public static Vector128<float> ReciprocalSqrt14(Vector128<float> value);
public static Vector256<double> Scale(Vector256<double> value);
public static Vector128<double> Scale(Vector128<double> value);
public static Vector256<float> Scale(Vector256<float> value);
public static Vector128<float> Scale(Vector128<float> value););
public static Vector256<int> Shuffle(Vector256<int> left, Vector256<int> right, byte control);
}
}