Description
Background and motivation
Intel's latest AVX
offering, AVX10
, introduces a converged vector ISA that will be supported on all Intel processors. Please find full details in the AVX10 technical paper and AVX10 architectural specification.
For brevity, we highlight the following relevant features from the technical paper and specification:
-
AVX10
will be a versioned ISA, where a version N will include all instructions/features of version N-1, N-2 etc. -
AVX10
supports multiple vector lengths, where CPUID exposes the max vector length available for a processor. -
AVX10.1
will supportAVX512
and the following extensions for vector lengths 128, 256, and 512 bits:-
AVX512F
,AVX512BW
,AVX512DQ
, andAVX512CD
-
AVX512_VBMI
,AVX512_IFMA
-
AVX512_VNNI
-
AVX512_BF16
-
AVX512_VPOPCNTDQ,
,AVX512_VBMI2
,VAES
,GFNI
,VPCLMULQDQ
,AVX512_BITALG
-
AVX512_FP16
-
-
On future Performance-cores (P-cores) based processors, the maximum vector length will be 512-bit; On future Efficient-cores (E-cores) based processors it will be 256-bit.
API Proposal
AVX10 Versioning
As part of AVX10
versioning, developers can expect that all features and capabilities of version N
will be included in version N+1
. As such, we propose that we capture this incremental versioning via class inheritance with the nomenclature Avx10vN
:
class Avx10v1
{
}
class Avx10v2 : Avx10v1
{
}
class Avx10v3 : Avx10v2
{
}
Developers will be able to continue to check for ISA support via Avx10vN.IsSupported
as is currently done for specific .NET ISA APIs.
AVX10 Vector Length
As AVX10
allows implementations to support different maximum vector lengths, we propose the following nested class structure:
class Avx10v1
{
public static Vector128<ulong> Abs(Vector128<long> v);
class V256
{
public static Vector256<ulong> Abs(Vector256<long> v);
}
class V512
{
public static Vector512<ulong> Abs(Vector512<long> v);
}
}
Avx10v1.IsSupported()
returns true
if 128-bit vectors are enabled via the CPUID vector length bits for AVX10
. As the AVX10
architecture specification states that the highest enumerated vector length implies all smaller vector lengths are supported, a developer may check Avx10v1.V256.IsSupported()
and safely use Avx10v1
methods.
AVX10 and AVX512
AVX10.1
represents a pre-enabling step for AVX10
, and is the convergence of the previously listed AVX512
instruction sets --- there is overlap with existing exposed .NET AVX512
ISA APIs. We propose that if AVX10v1.V512.IsSupported()
returns true, then the corresponding AVX512
APIs for the aforementioned extensions can safely be used:
Vector512<long> v1 = Vector512.Create((long)someParam);
if (Avx10v1.V512.IsSupported()) {
Vector512<ulong> v2 = Avx512F.Abs(v1);
Vector512<double> v3 = Avx512DQ.ConvertToVector512Double(v2);
// etc
}
For an AVX10/256
implementation, the subset of VL
instructions for existing AVX512
instruction sets will be available _without the presence of 512-bit
support. As existing AVX512VL
(and the associated nested VL
classes in .NET APIs) implies 512-bit, we will expose the 128-bit VL instructions under the top level Avx10v1
class and 256-bit VL instructions under the V256
nested classes. For clarity, it is possible to have AVX10v1.V256.IsSupported() == true
but AVX512F.IsSupported() == false
on AVX10/256
implementation.
Avx10v1 API
Given the aforementioned API discussion, we propose the following API, where all current AVX512VL
family instructions are consolidated under the top level Avx10v1
and V256
nested classes:
namespace System.Runtime.Intrinsics.X86;
public abstract class Avx10v1 : Avx2
{
public static new bool IsSupported { get; }
/// From AVX512F VL
public static Vector128<ulong> Abs(Vector128<long> value);
public static Vector128<int> AlignRight32(Vector128<int> left, Vector128<int> right, [ConstantExpected] byte mask);
public static Vector128<uint> AlignRight32(Vector128<uint> left, Vector128<uint> right, [ConstantExpected] byte mask);
public static Vector128<long> AlignRight64(Vector128<long> left, Vector128<long> right, [ConstantExpected] byte mask);
public static Vector128<ulong> AlignRight64(Vector128<ulong> left, Vector128<ulong> right, [ConstantExpected] byte mask);
public static Vector128<int> CompareGreaterThanOrEqual(Vector128<int> left, Vector128<int> right);
public static Vector128<int> CompareLessThan(Vector128<int> left, Vector128<int> right);
public static Vector128<int> CompareLessThanOrEqual(Vector128<int> left, Vector128<int> right);
public static Vector128<int> CompareNotEqual(Vector128<int> left, Vector128<int> right);
public static Vector128<long> CompareGreaterThanOrEqual(Vector128<long> left, Vector128<long> right);
public static Vector128<long> CompareLessThan(Vector128<long> left, Vector128<long> right);
public static Vector128<long> CompareLessThanOrEqual(Vector128<long> left, Vector128<long> right);
public static Vector128<long> CompareNotEqual(Vector128<long> left, Vector128<long> right);
public static Vector128<uint> CompareGreaterThan(Vector128<uint> left, Vector128<uint> right);
public static Vector128<uint> CompareGreaterThanOrEqual(Vector128<uint> left, Vector128<uint> right);
public static Vector128<uint> CompareLessThan(Vector128<uint> left, Vector128<uint> right);
public static Vector128<uint> CompareLessThanOrEqual(Vector128<uint> left, Vector128<uint> right);
public static Vector128<uint> CompareNotEqual(Vector128<uint> left, Vector128<uint> right);
public static Vector128<ulong> CompareGreaterThan(Vector128<ulong> left, Vector128<ulong> right);
public static Vector128<ulong> CompareGreaterThanOrEqual(Vector128<ulong> left, Vector128<ulong> right);
public static Vector128<ulong> CompareLessThan(Vector128<ulong> left, Vector128<ulong> right);
public static Vector128<ulong> CompareLessThanOrEqual(Vector128<ulong> left, Vector128<ulong> right);
public static Vector128<ulong> CompareNotEqual(Vector128<ulong> left, Vector128<ulong> right);
public static Vector128<byte> ConvertToVector128Byte(Vector128<int> value);
public static Vector128<byte> ConvertToVector128Byte(Vector128<long> value);
public static Vector128<byte> ConvertToVector128Byte(Vector128<uint> value);
public static Vector128<byte> ConvertToVector128Byte(Vector128<ulong> value);
public static Vector128<byte> ConvertToVector128ByteWithSaturation(Vector128<uint> value);
public static Vector128<byte> ConvertToVector128ByteWithSaturation(Vector128<ulong> value);
public static Vector128<double> ConvertToVector128Double(Vector128<uint> value);
public static Vector128<short> ConvertToVector128Int16(Vector128<int> value);
public static Vector128<short> ConvertToVector128Int16(Vector128<long> value);
public static Vector128<short> ConvertToVector128Int16(Vector128<uint> value);
public static Vector128<short> ConvertToVector128Int16(Vector128<ulong> value);
public static Vector128<short> ConvertToVector128Int16WithSaturation(Vector128<int> value);
public static Vector128<short> ConvertToVector128Int16WithSaturation(Vector128<long> value);
public static Vector128<int> ConvertToVector128Int32(Vector128<long> value);
public static Vector128<int> ConvertToVector128Int32(Vector128<ulong> value);
public static Vector128<int> ConvertToVector128Int32WithSaturation(Vector128<long> value);
public static Vector128<sbyte> ConvertToVector128SByte(Vector128<int> value);
public static Vector128<sbyte> ConvertToVector128SByte(Vector128<long> value);
public static Vector128<sbyte> ConvertToVector128SByte(Vector128<uint> value);
public static Vector128<sbyte> ConvertToVector128SByte(Vector128<ulong> value);
public static Vector128<sbyte> ConvertToVector128SByteWithSaturation(Vector128<int> value);
public static Vector128<sbyte> ConvertToVector128SByteWithSaturation(Vector128<long> value);
public static Vector128<float> ConvertToVector128Single(Vector128<uint> value);
public static Vector128<ushort> ConvertToVector128UInt16(Vector128<int> value);
public static Vector128<ushort> ConvertToVector128UInt16(Vector128<long> value);
public static Vector128<ushort> ConvertToVector128UInt16(Vector128<uint> value);
public static Vector128<ushort> ConvertToVector128UInt16(Vector128<ulong> value);
public static Vector128<ushort> ConvertToVector128UInt16WithSaturation(Vector128<uint> value);
public static Vector128<ushort> ConvertToVector128UInt16WithSaturation(Vector128<ulong> value);
public static Vector128<uint> ConvertToVector128UInt32(Vector128<long> value);
public static Vector128<uint> ConvertToVector128UInt32(Vector128<ulong> value);
public static Vector128<uint> ConvertToVector128UInt32(Vector128<float> value);
public static Vector128<uint> ConvertToVector128UInt32(Vector128<double> value);
public static Vector128<uint> ConvertToVector128UInt32WithSaturation(Vector128<ulong> value);
public static Vector128<uint> ConvertToVector128UInt32WithTruncation(Vector128<float> value);
public static Vector128<uint> ConvertToVector128UInt32WithTruncation(Vector128<double> value);
public static Vector128<float> Fixup(Vector128<float> left, Vector128<float> right, Vector128<int> table, [ConstantExpected] byte control);
public static Vector128<double> Fixup(Vector128<double> left, Vector128<double> right, Vector128<long> table, [ConstantExpected] byte control);
public static Vector128<float> GetExponent(Vector128<float> value);
public static Vector128<double> GetExponent(Vector128<double> value);
public static Vector128<float> GetMantissa(Vector128<float> value, [ConstantExpected(Max = (byte)(0x0F))] byte control);
public static Vector128<double> GetMantissa(Vector128<double> value, [ConstantExpected(Max = (byte)(0x0F))] byte control);
public static Vector128<long> Max(Vector128<long> left, Vector128<long> right);
public static Vector128<ulong> Max(Vector128<ulong> left, Vector128<ulong> right);
public static Vector128<long> Min(Vector128<long> left, Vector128<long> right);
public static Vector128<ulong> Min(Vector128<ulong> left, Vector128<ulong> right);
public static Vector128<long> PermuteVar2x64x2(Vector128<long> lower, Vector128<long> indices, Vector128<long> upper);
public static Vector128<ulong> PermuteVar2x64x2(Vector128<ulong> lower, Vector128<ulong> indices, Vector128<ulong> upper);
public static Vector128<double> PermuteVar2x64x2(Vector128<double> lower, Vector128<long> indices, Vector128<double> upper);
public static Vector128<int> PermuteVar4x32x2(Vector128<int> lower, Vector128<int> indices, Vector128<int> upper);
public static Vector128<uint> PermuteVar4x32x2(Vector128<uint> lower, Vector128<uint> indices, Vector128<uint> upper);
public static Vector128<float> PermuteVar4x32x2(Vector128<float> lower, Vector128<int> indices, Vector128<float> upper);
public static Vector128<float> Reciprocal14(Vector128<float> value);
public static Vector128<double> Reciprocal14(Vector128<double> value);
public static Vector128<float> ReciprocalSqrt14(Vector128<float> value);
public static Vector128<double> ReciprocalSqrt14(Vector128<double> value);
public static Vector128<int> RotateLeft(Vector128<int> value, [ConstantExpected] byte count);
public static Vector128<uint> RotateLeft(Vector128<uint> value, [ConstantExpected] byte count);
public static Vector128<long> RotateLeft(Vector128<long> value, [ConstantExpected] byte count);
public static Vector128<ulong> RotateLeft(Vector128<ulong> value, [ConstantExpected] byte count);
public static Vector128<int> RotateLeftVariable(Vector128<int> value, Vector128<uint> count);
public static Vector128<uint> RotateLeftVariable(Vector128<uint> value, Vector128<uint> count);
public static Vector128<long> RotateLeftVariable(Vector128<long> value, Vector128<ulong> count);
public static Vector128<ulong> RotateLeftVariable(Vector128<ulong> value, Vector128<ulong> count);
public static Vector128<int> RotateRight(Vector128<int> value, [ConstantExpected] byte count);
public static Vector128<uint> RotateRight(Vector128<uint> value, [ConstantExpected] byte count);
public static Vector128<long> RotateRight(Vector128<long> value, [ConstantExpected] byte count);
public static Vector128<ulong> RotateRight(Vector128<ulong> value, [ConstantExpected] byte count);
public static Vector128<int> RotateRightVariable(Vector128<int> value, Vector128<uint> count);
public static Vector128<uint> RotateRightVariable(Vector128<uint> value, Vector128<uint> count);
public static Vector128<long> RotateRightVariable(Vector128<long> value, Vector128<ulong> count);
public static Vector128<ulong> RotateRightVariable(Vector128<ulong> value, Vector128<ulong> count);
public static Vector128<float> RoundScale(Vector128<float> value, [ConstantExpected] byte control);
public static Vector128<double> RoundScale(Vector128<double> value, [ConstantExpected] byte control);
public static Vector128<float> Scale(Vector128<float> left, Vector128<float> right);
public static Vector128<double> Scale(Vector128<double> left, Vector128<double> right);
public static Vector128<long> ShiftRightArithmetic(Vector128<long> value, Vector128<long> count);
public static Vector128<long> ShiftRightArithmetic(Vector128<long> value, [ConstantExpected] byte count);
public static Vector128<long> ShiftRightArithmeticVariable(Vector128<long> value, Vector128<ulong> count);
public static Vector128<sbyte> TernaryLogic(Vector128<sbyte> a, Vector128<sbyte> b, Vector128<sbyte> c, [ConstantExpected] byte control);
public static Vector128<byte> TernaryLogic(Vector128<byte> a, Vector128<byte> b, Vector128<byte> c, [ConstantExpected] byte control);
public static Vector128<short> TernaryLogic(Vector128<short> a, Vector128<short> b, Vector128<short> c, [ConstantExpected] byte control);
public static Vector128<ushort> TernaryLogic(Vector128<ushort> a, Vector128<ushort> b, Vector128<ushort> c, [ConstantExpected] byte control);
public static Vector128<int> TernaryLogic(Vector128<int> a, Vector128<int> b, Vector128<int> c, [ConstantExpected] byte control);
public static Vector128<uint> TernaryLogic(Vector128<uint> a, Vector128<uint> b, Vector128<uint> c, [ConstantExpected] byte control);
public static Vector128<long> TernaryLogic(Vector128<long> a, Vector128<long> b, Vector128<long> c, [ConstantExpected] byte control);
public static Vector128<ulong> TernaryLogic(Vector128<ulong> a, Vector128<ulong> b, Vector128<ulong> c, [ConstantExpected] byte control);
public static Vector128<float> TernaryLogic(Vector128<float> a, Vector128<float> b, Vector128<float> c, [ConstantExpected] byte control);
public static Vector128<double> TernaryLogic(Vector128<double> a, Vector128<double> b, Vector128<double> c, [ConstantExpected] byte control);
/// From AVX512BW VL
public static Vector128<byte> CompareGreaterThan(Vector128<byte> left, Vector128<byte> right);
public static Vector128<byte> CompareGreaterThanOrEqual(Vector128<byte> left, Vector128<byte> right);
public static Vector128<byte> CompareLessThan(Vector128<byte> left, Vector128<byte> right);
public static Vector128<byte> CompareLessThanOrEqual(Vector128<byte> left, Vector128<byte> right);
public static Vector128<byte> CompareNotEqual(Vector128<byte> left, Vector128<byte> right);
public static Vector128<short> CompareGreaterThanOrEqual(Vector128<short> left, Vector128<short> right);
public static Vector128<short> CompareLessThan(Vector128<short> left, Vector128<short> right);
public static Vector128<short> CompareLessThanOrEqual(Vector128<short> left, Vector128<short> right);
public static Vector128<short> CompareNotEqual(Vector128<short> left, Vector128<short> right);
public static Vector128<sbyte> CompareGreaterThanOrEqual(Vector128<sbyte> left, Vector128<sbyte> right);
public static Vector128<sbyte> CompareLessThan(Vector128<sbyte> left, Vector128<sbyte> right);
public static Vector128<sbyte> CompareLessThanOrEqual(Vector128<sbyte> left, Vector128<sbyte> right);
public static Vector128<sbyte> CompareNotEqual(Vector128<sbyte> left, Vector128<sbyte> right);
public static Vector128<ushort> CompareGreaterThan(Vector128<ushort> left, Vector128<ushort> right);
public static Vector128<ushort> CompareGreaterThanOrEqual(Vector128<ushort> left, Vector128<ushort> right);
public static Vector128<ushort> CompareLessThan(Vector128<ushort> left, Vector128<ushort> right);
public static Vector128<ushort> CompareLessThanOrEqual(Vector128<ushort> left, Vector128<ushort> right);
public static Vector128<ushort> CompareNotEqual(Vector128<ushort> left, Vector128<ushort> right);
public static Vector128<byte> ConvertToVector128Byte(Vector128<short> value);
public static Vector128<byte> ConvertToVector128Byte(Vector128<ushort> value);
public static Vector128<byte> ConvertToVector128ByteWithSaturation(Vector128<ushort> value);
public static Vector128<sbyte> ConvertToVector128SByte(Vector128<short> value);
public static Vector128<sbyte> ConvertToVector128SByte(Vector128<ushort> value);
public static Vector128<sbyte> ConvertToVector128SByteWithSaturation(Vector128<short> value);
public static Vector128<short> PermuteVar8x16(Vector128<short> left, Vector128<short> control);
public static Vector128<ushort> PermuteVar8x16(Vector128<ushort> left, Vector128<ushort> control);
public static Vector128<short> PermuteVar8x16x2(Vector128<short> lower, Vector128<short> indices, Vector128<short> upper);
public static Vector128<ushort> PermuteVar8x16x2(Vector128<ushort> lower, Vector128<ushort> indices, Vector128<ushort> upper);
public static Vector128<short> ShiftLeftLogicalVariable(Vector128<short> value, Vector128<ushort> count);
public static Vector128<ushort> ShiftLeftLogicalVariable(Vector128<ushort> value, Vector128<ushort> count);
public static Vector128<short> ShiftRightArithmeticVariable(Vector128<short> value, Vector128<ushort> count);
public static Vector128<short> ShiftRightLogicalVariable(Vector128<short> value, Vector128<ushort> count);
public static Vector128<ushort> ShiftRightLogicalVariable(Vector128<ushort> value, Vector128<ushort> count);
public static Vector128<ushort> SumAbsoluteDifferencesInBlock32(Vector128<byte> left, Vector128<byte> right, [ConstantExpected] byte control);
/// From AVX512CD VL
public static Vector128<int> DetectConflicts(Vector128<int> value);
public static Vector128<uint> DetectConflicts(Vector128<uint> value);
public static Vector128<long> DetectConflicts(Vector128<long> value);
public static Vector128<ulong> DetectConflicts(Vector128<ulong> value);
public static Vector128<int> LeadingZeroCount(Vector128<int> value);
public static Vector128<uint> LeadingZeroCount(Vector128<uint> value);
public static Vector128<long> LeadingZeroCount(Vector128<long> value);
public static Vector128<ulong> LeadingZeroCount(Vector128<ulong> value);
/// From AVX512DQ VL
public static Vector128<int> BroadcastPairScalarToVector128(Vector128<int> value);
public static Vector128<uint> BroadcastPairScalarToVector128(Vector128<uint> value);
public static Vector128<double> ConvertToVector128Double(Vector128<long> value);
public static Vector128<double> ConvertToVector128Double(Vector128<ulong> value);
public static Vector128<long> ConvertToVector128Int64(Vector128<float> value);
public static Vector128<long> ConvertToVector128Int64(Vector128<double> value);
public static Vector128<long> ConvertToVector128Int64WithTruncation(Vector128<float> value);
public static Vector128<long> ConvertToVector128Int64WithTruncation(Vector128<double> value);
public static Vector128<float> ConvertToVector128Single(Vector128<long> value);
public static Vector128<float> ConvertToVector128Single(Vector128<ulong> value);
public static Vector128<ulong> ConvertToVector128UInt64(Vector128<float> value);
public static Vector128<ulong> ConvertToVector128UInt64(Vector128<double> value);
public static Vector128<ulong> ConvertToVector128UInt64WithTruncation(Vector128<float> value);
public static Vector128<ulong> ConvertToVector128UInt64WithTruncation(Vector128<double> value);
public static Vector128<long> MultiplyLow(Vector128<long> left, Vector128<long> right);
public static Vector128<ulong> MultiplyLow(Vector128<ulong> left, Vector128<ulong> right);
public static Vector128<float> Range(Vector128<float> left, Vector128<float> right, [ConstantExpected(Max = (byte)(0x0F))] byte control);
public static Vector128<double> Range(Vector128<double> left, Vector128<double> right, [ConstantExpected(Max = (byte)(0x0F))] byte control);
public static Vector128<float> Reduce(Vector128<float> value, [ConstantExpected] byte control);
public static Vector128<double> Reduce(Vector128<double> value, [ConstantExpected] byte control);
/// From AVX512_Vbmi_VL
public static Vector128<sbyte> PermuteVar16x8(Vector128<sbyte> left, Vector128<sbyte> control);
public static Vector128<byte> PermuteVar16x8(Vector128<byte> left, Vector128<byte> control);
public static Vector128<byte> PermuteVar16x8x2(Vector128<byte> lower, Vector128<byte> indices, Vector128<byte> upper);
public static Vector128<sbyte> PermuteVar16x8x2(Vector128<sbyte> lower, Vector128<sbyte> indices, Vector128<sbyte> upper);
public abstract class V256 : Avx2
{
public static new bool IsSupported { get; }
/// From AVX512F VL
public static Vector256<ulong> Abs(Vector256<long> value);
public static Vector256<int> AlignRight32(Vector256<int> left, Vector256<int> right, [ConstantExpected] byte mask);
public static Vector256<uint> AlignRight32(Vector256<uint> left, Vector256<uint> right, [ConstantExpected] byte mask);
public static Vector256<long> AlignRight64(Vector256<long> left, Vector256<long> right, [ConstantExpected] byte mask);
public static Vector256<ulong> AlignRight64(Vector256<ulong> left, Vector256<ulong> right, [ConstantExpected] byte mask);
public static Vector256<int> CompareGreaterThanOrEqual(Vector256<int> left, Vector256<int> right);
public static Vector256<int> CompareLessThan(Vector256<int> left, Vector256<int> right);
public static Vector256<int> CompareLessThanOrEqual(Vector256<int> left, Vector256<int> right);
public static Vector256<int> CompareNotEqual(Vector256<int> left, Vector256<int> right);
public static Vector256<long> CompareGreaterThanOrEqual(Vector256<long> left, Vector256<long> right);
public static Vector256<long> CompareLessThan(Vector256<long> left, Vector256<long> right);
public static Vector256<long> CompareLessThanOrEqual(Vector256<long> left, Vector256<long> right);
public static Vector256<long> CompareNotEqual(Vector256<long> left, Vector256<long> right);
public static Vector256<uint> CompareGreaterThan(Vector256<uint> left, Vector256<uint> right);
public static Vector256<uint> CompareGreaterThanOrEqual(Vector256<uint> left, Vector256<uint> right);
public static Vector256<uint> CompareLessThan(Vector256<uint> left, Vector256<uint> right);
public static Vector256<uint> CompareLessThanOrEqual(Vector256<uint> left, Vector256<uint> right);
public static Vector256<uint> CompareNotEqual(Vector256<uint> left, Vector256<uint> right);
public static Vector256<ulong> CompareGreaterThan(Vector256<ulong> left, Vector256<ulong> right);
public static Vector256<ulong> CompareGreaterThanOrEqual(Vector256<ulong> left, Vector256<ulong> right);
public static Vector256<ulong> CompareLessThan(Vector256<ulong> left, Vector256<ulong> right);
public static Vector256<ulong> CompareLessThanOrEqual(Vector256<ulong> left, Vector256<ulong> right);
public static Vector256<ulong> CompareNotEqual(Vector256<ulong> left, Vector256<ulong> right);
public static Vector128<byte> ConvertToVector128Byte(Vector256<int> value);
public static Vector128<byte> ConvertToVector128Byte(Vector256<long> value);
public static Vector128<byte> ConvertToVector128Byte(Vector256<uint> value);
public static Vector128<byte> ConvertToVector128Byte(Vector256<ulong> value);
public static Vector128<byte> ConvertToVector128ByteWithSaturation(Vector256<uint> value);
public static Vector128<byte> ConvertToVector128ByteWithSaturation(Vector256<ulong> value);
public static Vector128<short> ConvertToVector128Int16(Vector256<int> value);
public static Vector128<short> ConvertToVector128Int16(Vector256<long> value);
public static Vector128<short> ConvertToVector128Int16(Vector256<uint> value);
public static Vector128<short> ConvertToVector128Int16(Vector256<ulong> value);
public static Vector128<short> ConvertToVector128Int16WithSaturation(Vector256<int> value);
public static Vector128<short> ConvertToVector128Int16WithSaturation(Vector256<long> value);
public static Vector128<int> ConvertToVector128Int32(Vector256<long> value);
public static Vector128<int> ConvertToVector128Int32(Vector256<ulong> value);
public static Vector128<int> ConvertToVector128Int32WithSaturation(Vector256<long> value);
public static Vector128<sbyte> ConvertToVector128SByte(Vector256<int> value);
public static Vector128<sbyte> ConvertToVector128SByte(Vector256<long> value);
public static Vector128<sbyte> ConvertToVector128SByte(Vector256<uint> value);
public static Vector128<sbyte> ConvertToVector128SByte(Vector256<ulong> value);
public static Vector128<sbyte> ConvertToVector128SByteWithSaturation(Vector256<int> value);
public static Vector128<sbyte> ConvertToVector128SByteWithSaturation(Vector256<long> value);
public static Vector128<ushort> ConvertToVector128UInt16(Vector256<int> value);
public static Vector128<ushort> ConvertToVector128UInt16(Vector256<long> value);
public static Vector128<ushort> ConvertToVector128UInt16(Vector256<uint> value);
public static Vector128<ushort> ConvertToVector128UInt16(Vector256<ulong> value);
public static Vector128<ushort> ConvertToVector128UInt16WithSaturation(Vector256<uint> value);
public static Vector128<ushort> ConvertToVector128UInt16WithSaturation(Vector256<ulong> value);
public static Vector128<uint> ConvertToVector128UInt32(Vector256<long> value);
public static Vector128<uint> ConvertToVector128UInt32(Vector256<ulong> value);
public static Vector128<uint> ConvertToVector128UInt32(Vector256<double> value);
public static Vector128<uint> ConvertToVector128UInt32WithSaturation(Vector256<ulong> value);
public static Vector128<uint> ConvertToVector128UInt32WithTruncation(Vector256<double> value);
public static Vector256<double> ConvertToVector256Double(Vector128<uint> value);
public static Vector256<float> ConvertToVector256Single(Vector256<uint> value);
public static Vector256<uint> ConvertToVector256UInt32(Vector256<float> value);
public static Vector256<uint> ConvertToVector256UInt32WithTruncation(Vector256<float> value);
public static Vector256<float> Fixup(Vector256<float> left, Vector256<float> right, Vector256<int> table, [ConstantExpected] byte control);
public static Vector256<double> Fixup(Vector256<double> left, Vector256<double> right, Vector256<long> table, [ConstantExpected] byte control);
public static Vector256<float> GetExponent(Vector256<float> value);
public static Vector256<double> GetExponent(Vector256<double> value);
public static Vector256<float> GetMantissa(Vector256<float> value, [ConstantExpected(Max = (byte)(0x0F))] byte control);
public static Vector256<double> GetMantissa(Vector256<double> value, [ConstantExpected(Max = (byte)(0x0F))] byte control);
public static Vector256<long> Max(Vector256<long> left, Vector256<long> right);
public static Vector256<ulong> Max(Vector256<ulong> left, Vector256<ulong> right);
public static Vector256<long> Min(Vector256<long> left, Vector256<long> right);
public static Vector256<ulong> Min(Vector256<ulong> left, Vector256<ulong> right);
public static Vector256<long> PermuteVar4x64(Vector256<long> value, Vector256<long> control);
public static Vector256<ulong> PermuteVar4x64(Vector256<ulong> value, Vector256<ulong> control);
public static Vector256<double> PermuteVar4x64(Vector256<double> value, Vector256<long> control);
public static Vector256<long> PermuteVar4x64x2(Vector256<long> lower, Vector256<long> indices, Vector256<long> upper);
public static Vector256<ulong> PermuteVar4x64x2(Vector256<ulong> lower, Vector256<ulong> indices, Vector256<ulong> upper);
public static Vector256<double> PermuteVar4x64x2(Vector256<double> lower, Vector256<long> indices, Vector256<double> upper);
public static Vector256<int> PermuteVar8x32x2(Vector256<int> lower, Vector256<int> indices, Vector256<int> upper);
public static Vector256<uint> PermuteVar8x32x2(Vector256<uint> lower, Vector256<uint> indices, Vector256<uint> upper);
public static Vector256<float> PermuteVar8x32x2(Vector256<float> lower, Vector256<int> indices, Vector256<float> upper);
public static Vector256<float> Reciprocal14(Vector256<float> value);
public static Vector256<double> Reciprocal14(Vector256<double> value);
public static Vector256<float> ReciprocalSqrt14(Vector256<float> value);
public static Vector256<double> ReciprocalSqrt14(Vector256<double> value);
public static Vector256<int> RotateLeft(Vector256<int> value, [ConstantExpected] byte count);
public static Vector256<uint> RotateLeft(Vector256<uint> value, [ConstantExpected] byte count);
public static Vector256<long> RotateLeft(Vector256<long> value, [ConstantExpected] byte count);
public static Vector256<ulong> RotateLeft(Vector256<ulong> value, [ConstantExpected] byte count);
public static Vector256<int> RotateLeftVariable(Vector256<int> value, Vector256<uint> count);
public static Vector256<uint> RotateLeftVariable(Vector256<uint> value, Vector256<uint> count);
public static Vector256<long> RotateLeftVariable(Vector256<long> value, Vector256<ulong> count);
public static Vector256<ulong> RotateLeftVariable(Vector256<ulong> value, Vector256<ulong> count);
public static Vector256<int> RotateRight(Vector256<int> value, [ConstantExpected] byte count);
public static Vector256<uint> RotateRight(Vector256<uint> value, [ConstantExpected] byte count);
public static Vector256<long> RotateRight(Vector256<long> value, [ConstantExpected] byte count);
public static Vector256<ulong> RotateRight(Vector256<ulong> value, [ConstantExpected] byte count);
public static Vector256<int> RotateRightVariable(Vector256<int> value, Vector256<uint> count);
public static Vector256<uint> RotateRightVariable(Vector256<uint> value, Vector256<uint> count);
public static Vector256<long> RotateRightVariable(Vector256<long> value, Vector256<ulong> count);
public static Vector256<ulong> RotateRightVariable(Vector256<ulong> value, Vector256<ulong> count);
public static Vector256<float> RoundScale(Vector256<float> value, [ConstantExpected] byte control);
public static Vector256<double> RoundScale(Vector256<double> value, [ConstantExpected] byte control);
public static Vector256<float> Scale(Vector256<float> left, Vector256<float> right);
public static Vector256<double> Scale(Vector256<double> left, Vector256<double> right);
public static Vector256<long> ShiftRightArithmetic(Vector256<long> value, Vector128<long> count);
public static Vector256<long> ShiftRightArithmetic(Vector256<long> value, [ConstantExpected] byte count);
public static Vector256<long> ShiftRightArithmeticVariable(Vector256<long> value, Vector256<ulong> count);
public static Vector256<double> Shuffle2x128(Vector256<double> left, Vector256<double> right, [ConstantExpected] byte control);
public static Vector256<int> Shuffle2x128(Vector256<int> left, Vector256<int> right, [ConstantExpected] byte control);
public static Vector256<long> Shuffle2x128(Vector256<long> left, Vector256<long> right, [ConstantExpected] byte control);
public static Vector256<float> Shuffle2x128(Vector256<float> left, Vector256<float> right, [ConstantExpected] byte control);
public static Vector256<uint> Shuffle2x128(Vector256<uint> left, Vector256<uint> right, [ConstantExpected] byte control);
public static Vector256<ulong> Shuffle2x128(Vector256<ulong> left, Vector256<ulong> right, [ConstantExpected] byte control);
public static Vector256<sbyte> TernaryLogic(Vector256<sbyte> a, Vector256<sbyte> b, Vector256<sbyte> c, [ConstantExpected] byte control);
public static Vector256<byte> TernaryLogic(Vector256<byte> a, Vector256<byte> b, Vector256<byte> c, [ConstantExpected] byte control);
public static Vector256<short> TernaryLogic(Vector256<short> a, Vector256<short> b, Vector256<short> c, [ConstantExpected] byte control);
public static Vector256<ushort> TernaryLogic(Vector256<ushort> a, Vector256<ushort> b, Vector256<ushort> c, [ConstantExpected] byte control);
public static Vector256<int> TernaryLogic(Vector256<int> a, Vector256<int> b, Vector256<int> c, [ConstantExpected] byte control);
public static Vector256<uint> TernaryLogic(Vector256<uint> a, Vector256<uint> b, Vector256<uint> c, [ConstantExpected] byte control);
public static Vector256<long> TernaryLogic(Vector256<long> a, Vector256<long> b, Vector256<long> c, [ConstantExpected] byte control);
public static Vector256<ulong> TernaryLogic(Vector256<ulong> a, Vector256<ulong> b, Vector256<ulong> c, [ConstantExpected] byte control);
public static Vector256<float> TernaryLogic(Vector256<float> a, Vector256<float> b, Vector256<float> c, [ConstantExpected] byte control);
public static Vector256<double> TernaryLogic(Vector256<double> a, Vector256<double> b, Vector256<double> c, [ConstantExpected] byte control);
/// From AVX512BW VL
public static Vector256<byte> CompareGreaterThan(Vector256<byte> left, Vector256<byte> right);
public static Vector256<byte> CompareGreaterThanOrEqual(Vector256<byte> left, Vector256<byte> right);
public static Vector256<byte> CompareLessThan(Vector256<byte> left, Vector256<byte> right);
public static Vector256<byte> CompareLessThanOrEqual(Vector256<byte> left, Vector256<byte> right);
public static Vector256<byte> CompareNotEqual(Vector256<byte> left, Vector256<byte> right);
public static Vector256<short> CompareGreaterThanOrEqual(Vector256<short> left, Vector256<short> right);
public static Vector256<short> CompareLessThan(Vector256<short> left, Vector256<short> right);
public static Vector256<short> CompareLessThanOrEqual(Vector256<short> left, Vector256<short> right);
public static Vector256<short> CompareNotEqual(Vector256<short> left, Vector256<short> right);
public static Vector256<sbyte> CompareGreaterThanOrEqual(Vector256<sbyte> left, Vector256<sbyte> right);
public static Vector256<sbyte> CompareLessThan(Vector256<sbyte> left, Vector256<sbyte> right);
public static Vector256<sbyte> CompareLessThanOrEqual(Vector256<sbyte> left, Vector256<sbyte> right);
public static Vector256<sbyte> CompareNotEqual(Vector256<sbyte> left, Vector256<sbyte> right);
public static Vector256<ushort> CompareGreaterThan(Vector256<ushort> left, Vector256<ushort> right);
public static Vector256<ushort> CompareGreaterThanOrEqual(Vector256<ushort> left, Vector256<ushort> right);
public static Vector256<ushort> CompareLessThan(Vector256<ushort> left, Vector256<ushort> right);
public static Vector256<ushort> CompareLessThanOrEqual(Vector256<ushort> left, Vector256<ushort> right);
public static Vector256<ushort> CompareNotEqual(Vector256<ushort> left, Vector256<ushort> right);
public static Vector128<byte> ConvertToVector128Byte(Vector256<short> value);
public static Vector128<byte> ConvertToVector128Byte(Vector256<ushort> value);
public static Vector128<byte> ConvertToVector128ByteWithSaturation(Vector256<ushort> value);
public static Vector128<sbyte> ConvertToVector128SByte(Vector256<short> value);
public static Vector128<sbyte> ConvertToVector128SByte(Vector256<ushort> value);
public static Vector128<sbyte> ConvertToVector128SByteWithSaturation(Vector256<short> value);
public static Vector256<short> PermuteVar16x16(Vector256<short> left, Vector256<short> control);
public static Vector256<ushort> PermuteVar16x16(Vector256<ushort> left, Vector256<ushort> control);
public static Vector256<short> PermuteVar16x16x2(Vector256<short> lower, Vector256<short> indices, Vector256<short> upper);
public static Vector256<ushort> PermuteVar16x16x2(Vector256<ushort> lower, Vector256<ushort> indices, Vector256<ushort> upper);
public static Vector256<short> ShiftLeftLogicalVariable(Vector256<short> value, Vector256<ushort> count);
public static Vector256<ushort> ShiftLeftLogicalVariable(Vector256<ushort> value, Vector256<ushort> count);
public static Vector256<short> ShiftRightArithmeticVariable(Vector256<short> value, Vector256<ushort> count);
public static Vector256<short> ShiftRightLogicalVariable(Vector256<short> value, Vector256<ushort> count);
public static Vector256<ushort> ShiftRightLogicalVariable(Vector256<ushort> value, Vector256<ushort> count);
public static Vector256<ushort> SumAbsoluteDifferencesInBlock32(Vector256<byte> left, Vector256<byte> right, [ConstantExpected] byte control);
/// FROM AVX512CD VL
public static Vector256<int> DetectConflicts(Vector256<int> value);
public static Vector256<uint> DetectConflicts(Vector256<uint> value);
public static Vector256<long> DetectConflicts(Vector256<long> value);
public static Vector256<ulong> DetectConflicts(Vector256<ulong> value);
public static Vector256<int> LeadingZeroCount(Vector256<int> value);
public static Vector256<uint> LeadingZeroCount(Vector256<uint> value);
public static Vector256<long> LeadingZeroCount(Vector256<long> value);
public static Vector256<ulong> LeadingZeroCount(Vector256<ulong> value);
/// From AVX512DQ VL
public static Vector256<int> BroadcastPairScalarToVector256(Vector128<int> value);
public static Vector256<uint> BroadcastPairScalarToVector256(Vector128<uint> value);
public static Vector256<float> BroadcastPairScalarToVector256(Vector128<float> value);
public static Vector128<float> ConvertToVector128Single(Vector256<long> value);
public static Vector128<float> ConvertToVector128Single(Vector256<ulong> value);
public static Vector256<double> ConvertToVector256Double(Vector256<long> value);
public static Vector256<double> ConvertToVector256Double(Vector256<ulong> value);
public static Vector256<long> ConvertToVector256Int64(Vector128<float> value);
public static Vector256<long> ConvertToVector256Int64(Vector256<double> value);
public static Vector256<long> ConvertToVector256Int64WithTruncation(Vector128<float> value);
public static Vector256<long> ConvertToVector256Int64WithTruncation(Vector256<double> value);
public static Vector256<ulong> ConvertToVector256UInt64(Vector128<float> value);
public static Vector256<ulong> ConvertToVector256UInt64(Vector256<double> value);
public static Vector256<ulong> ConvertToVector256UInt64WithTruncation(Vector128<float> value);
public static Vector256<ulong> ConvertToVector256UInt64WithTruncation(Vector256<double> value);
public static Vector256<long> MultiplyLow(Vector256<long> left, Vector256<long> right);
public static Vector256<ulong> MultiplyLow(Vector256<ulong> left, Vector256<ulong> right);
public static Vector256<float> Range(Vector256<float> left, Vector256<float> right, [ConstantExpected(Max = (byte)(0x0F))] byte control);
public static Vector256<double> Range(Vector256<double> left, Vector256<double> right, [ConstantExpected(Max = (byte)(0x0F))] byte control);
public static Vector256<float> Reduce(Vector256<float> value, [ConstantExpected] byte control);
public static Vector256<double> Reduce(Vector256<double> value, [ConstantExpected] byte control);
/// From AVX512_Vbmi_VL
public static Vector256<sbyte> PermuteVar32x8(Vector256<sbyte> left, Vector256<sbyte> control);
public static Vector256<byte> PermuteVar32x8(Vector256<byte> left, Vector256<byte> control);
public static Vector256<byte> PermuteVar32x8x2(Vector256<byte> lower, Vector256<byte> indices, Vector256<byte> upper);
public static Vector256<sbyte> PermuteVar32x8x2(Vector256<sbyte> lower, Vector256<sbyte> indices, Vector256<sbyte> upper);
}
public abstract class V512 : Avx512F
{
public static new bool IsSupported { get; }
// no changes, place holder for future versions
}
}
In the above surface areas, we have consolidated existing AVX512VL
APIs from .NET. The following is the full set of covered extensions, which we will continue to add on.
This includes the VL
subsets for the following extensions:
-
AVX512F
,AVX512BW
,AVX512DQ
, andAVX512CD
-
AVX512_VBMI
,AVX512_IFMA
-
AVX512_VNNI
-
AVX512_BF16
-
AVX512_VPOPCNTDQ,
,AVX512_VBMI2
,VAES
,GFNI
,VPCLMULQDQ
,AVX512_BITALG
-
AVX512_FP16
Note that for Avx10v1
and Avx10v1.V256
, AVX IFMA
and AVX VNNI
are implied, but we cannot directly inherit. Likewise, for V512
, the above extensions are implied: those which currently have existing .NET implementations include AVX512BW
, AVX512DQ
, AVX512CD
, and AVX512Vbmi
API Usage
Please see the aforementioned discussion.
Alternative Designs
Alternative Versioning
One alternative design we are considering is to expose all `AVX10`` methods under a single class and provide a form of versioning --- defined via method attributes --- on the API:
class Avx10
{
public static bool VersionIsAtLeast(ulong version);
[SupportedAvx10Version(1)]
public static Vector128<ulong> Method1(Vector128<long> v);
[SupportedAvx10Version(2)]
public static Vector128<ulong> Method2(Vector128<long> v);
class V256
{
[SupportedAvx10Version(1)]
public static Vector256<ulong> Method1(Vector256<long> v);
[SupportedAvx10Version(2)]
public static Vector256<ulong> Method2(Vector256<long> v);
}
class V512
{
[SupportedAvx10Version(2)]
public static Vector512<ulong> Method2(Vector512<long> v);
}
}
The developer may check for the specific Avx10
version necessary and then may use it and all preceding version methods without having to explicitly refer to additional classes Avx10v1
, Avx10v2
etc:
Vector256<ulong> v1 = ...;
if (Avx10.VersionIsAtLeast(2))
{
v1 = Avx10.V256.Method1(v1);
v1 = Avx10.V256.Method2(v1);
}
To help developers ensure they are using the API correctly, we propose to create an analyzer that will ensure that a proper version check is in place for all methods used, and flag a warning if a method is used outside of a proper version check.
V512 Surface Area
For developer ease-of-us, one alternative design is to duplicate the AVX512
512-bit API surface in the V512
class, so the developer does not have to explicitly reference existing AVX512
APIs. Note that this requires duplicating a large amount of API surface.
namespace System.Runtime.Intrinsics.X86;
public abstract class Avx10v1 : Avx2
{
// defined above
public abstract class V256
{
// defined above
}
public abstract class V512
{
public static new bool IsSupported { get; }
/// From AVX512BW
public static Vector512<byte> Abs(Vector512<sbyte> value);
public static Vector512<ushort> Abs(Vector512<short> value);
public static Vector512<sbyte> Add(Vector512<sbyte> left, Vector512<sbyte> right);
public static Vector512<byte> Add(Vector512<byte> left, Vector512<byte> right);
public static Vector512<short> Add(Vector512<short> left, Vector512<short> right);
public static Vector512<ushort> Add(Vector512<ushort> left, Vector512<ushort> right);
public static Vector512<sbyte> AddSaturate(Vector512<sbyte> left, Vector512<sbyte> right);
public static Vector512<byte> AddSaturate(Vector512<byte> left, Vector512<byte> right);
public static Vector512<short> AddSaturate(Vector512<short> left, Vector512<short> right);
public static Vector512<ushort> AddSaturate(Vector512<ushort> left, Vector512<ushort> right);
public static Vector512<sbyte> AlignRight(Vector512<sbyte> left, Vector512<sbyte> right, [ConstantExpected] byte mask);
public static Vector512<byte> AlignRight(Vector512<byte> left, Vector512<byte> right, [ConstantExpected] byte mask);
public static Vector512<byte> Average(Vector512<byte> left, Vector512<byte> right);
public static Vector512<ushort> Average(Vector512<ushort> left, Vector512<ushort> right);
public static Vector512<byte> BlendVariable(Vector512<byte> left, Vector512<byte> right, Vector512<byte> mask);
public static Vector512<short> BlendVariable(Vector512<short> left, Vector512<short> right, Vector512<short> mask);
public static Vector512<sbyte> BlendVariable(Vector512<sbyte> left, Vector512<sbyte> right, Vector512<sbyte> mask);
public static Vector512<ushort> BlendVariable(Vector512<ushort> left, Vector512<ushort> right, Vector512<ushort> mask);
public static Vector512<byte> BroadcastScalarToVector512(Vector128<byte> value);
public static Vector512<sbyte> BroadcastScalarToVector512(Vector128<sbyte> value);
public static Vector512<short> BroadcastScalarToVector512(Vector128<short> value);
public static Vector512<ushort> BroadcastScalarToVector512(Vector128<ushort> value);
public static Vector512<byte> CompareEqual(Vector512<byte> left, Vector512<byte> right);
public static Vector512<byte> CompareGreaterThan(Vector512<byte> left, Vector512<byte> right);
public static Vector512<byte> CompareGreaterThanOrEqual(Vector512<byte> left, Vector512<byte> right);
public static Vector512<byte> CompareLessThan(Vector512<byte> left, Vector512<byte> right);
public static Vector512<byte> CompareLessThanOrEqual(Vector512<byte> left, Vector512<byte> right);
public static Vector512<byte> CompareNotEqual(Vector512<byte> left, Vector512<byte> right);
public static Vector512<short> CompareEqual(Vector512<short> left, Vector512<short> right);
public static Vector512<short> CompareGreaterThan(Vector512<short> left, Vector512<short> right);
public static Vector512<short> CompareGreaterThanOrEqual(Vector512<short> left, Vector512<short> right);
public static Vector512<short> CompareLessThan(Vector512<short> left, Vector512<short> right);
public static Vector512<short> CompareLessThanOrEqual(Vector512<short> left, Vector512<short> right);
public static Vector512<short> CompareNotEqual(Vector512<short> left, Vector512<short> right);
public static Vector512<sbyte> CompareEqual(Vector512<sbyte> left, Vector512<sbyte> right);
public static Vector512<sbyte> CompareGreaterThan(Vector512<sbyte> left, Vector512<sbyte> right);
public static Vector512<sbyte> CompareGreaterThanOrEqual(Vector512<sbyte> left, Vector512<sbyte> right);
public static Vector512<sbyte> CompareLessThan(Vector512<sbyte> left, Vector512<sbyte> right);
public static Vector512<sbyte> CompareLessThanOrEqual(Vector512<sbyte> left, Vector512<sbyte> right);
public static Vector512<sbyte> CompareNotEqual(Vector512<sbyte> left, Vector512<sbyte> right);
public static Vector512<ushort> CompareEqual(Vector512<ushort> left, Vector512<ushort> right);
public static Vector512<ushort> CompareGreaterThan(Vector512<ushort> left, Vector512<ushort> right);
public static Vector512<ushort> CompareGreaterThanOrEqual(Vector512<ushort> left, Vector512<ushort> right);
public static Vector512<ushort> CompareLessThan(Vector512<ushort> left, Vector512<ushort> right);
public static Vector512<ushort> CompareLessThanOrEqual(Vector512<ushort> left, Vector512<ushort> right);
public static Vector512<ushort> CompareNotEqual(Vector512<ushort> left, Vector512<ushort> right);
public static Vector256<byte> ConvertToVector256Byte(Vector512<short> value);
public static Vector256<byte> ConvertToVector256Byte(Vector512<ushort> value);
public static Vector256<byte> ConvertToVector256ByteWithSaturation(Vector512<ushort> value);
public static Vector256<sbyte> ConvertToVector256SByte(Vector512<short> value);
public static Vector256<sbyte> ConvertToVector256SByte(Vector512<ushort> value);
public static Vector256<sbyte> ConvertToVector256SByteWithSaturation(Vector512<short> value);
public static Vector512<short> ConvertToVector512Int16(Vector256<sbyte> value);
public static Vector512<short> ConvertToVector512Int16(Vector256<byte> value);
public static Vector512<ushort> ConvertToVector512UInt16(Vector256<sbyte> value);
public static Vector512<ushort> ConvertToVector512UInt16(Vector256<byte> value);
public static new unsafe Vector512<sbyte> LoadVector512(sbyte* address);
public static new unsafe Vector512<byte> LoadVector512(byte* address);
public static new unsafe Vector512<short> LoadVector512(short* address);
public static new unsafe Vector512<ushort> LoadVector512(ushort* address);
public static Vector512<sbyte> Max(Vector512<sbyte> left, Vector512<sbyte> right);
public static Vector512<byte> Max(Vector512<byte> left, Vector512<byte> right);
public static Vector512<short> Max(Vector512<short> left, Vector512<short> right);
public static Vector512<ushort> Max(Vector512<ushort> left, Vector512<ushort> right);
public static Vector512<sbyte> Min(Vector512<sbyte> left, Vector512<sbyte> right);
public static Vector512<byte> Min(Vector512<byte> left, Vector512<byte> right);
public static Vector512<short> Min(Vector512<short> left, Vector512<short> right);
public static Vector512<ushort> Min(Vector512<ushort> left, Vector512<ushort> right);
public static Vector512<int> MultiplyAddAdjacent(Vector512<short> left, Vector512<short> right);
public static Vector512<short> MultiplyAddAdjacent(Vector512<byte> left, Vector512<sbyte> right);
public static Vector512<short> MultiplyHigh(Vector512<short> left, Vector512<short> right);
public static Vector512<ushort> MultiplyHigh(Vector512<ushort> left, Vector512<ushort> right);
public static Vector512<short> MultiplyHighRoundScale(Vector512<short> left, Vector512<short> right);
public static Vector512<short> MultiplyLow(Vector512<short> left, Vector512<short> right);
public static Vector512<ushort> MultiplyLow(Vector512<ushort> left, Vector512<ushort> right);
public static Vector512<sbyte> PackSignedSaturate(Vector512<short> left, Vector512<short> right);
public static Vector512<short> PackSignedSaturate(Vector512<int> left, Vector512<int> right);
public static Vector512<byte> PackUnsignedSaturate(Vector512<short> left, Vector512<short> right);
public static Vector512<ushort> PackUnsignedSaturate(Vector512<int> left, Vector512<int> right);
public static Vector512<short> PermuteVar32x16(Vector512<short> left, Vector512<short> control);
public static Vector512<ushort> PermuteVar32x16(Vector512<ushort> left, Vector512<ushort> control);
public static Vector512<short> PermuteVar32x16x2(Vector512<short> lower, Vector512<short> indices, Vector512<short> upper);
public static Vector512<ushort> PermuteVar32x16x2(Vector512<ushort> lower, Vector512<ushort> indices, Vector512<ushort> upper);
public static Vector512<short> ShiftLeftLogical(Vector512<short> value, Vector128<short> count);
public static Vector512<ushort> ShiftLeftLogical(Vector512<ushort> value, Vector128<ushort> count);
public static Vector512<short> ShiftLeftLogical(Vector512<short> value, [ConstantExpected] byte count);
public static Vector512<ushort> ShiftLeftLogical(Vector512<ushort> value, [ConstantExpected] byte count);
public static Vector512<sbyte> ShiftLeftLogical128BitLane(Vector512<sbyte> value, [ConstantExpected] byte numBytes);
public static Vector512<byte> ShiftLeftLogical128BitLane(Vector512<byte> value, [ConstantExpected] byte numBytes);
public static Vector512<short> ShiftLeftLogicalVariable(Vector512<short> value, Vector512<ushort> count);
public static Vector512<ushort> ShiftLeftLogicalVariable(Vector512<ushort> value, Vector512<ushort> count);
public static Vector512<short> ShiftRightArithmetic(Vector512<short> value, Vector128<short> count);
public static Vector512<short> ShiftRightArithmetic(Vector512<short> value, [ConstantExpected] byte count);
public static Vector512<short> ShiftRightArithmeticVariable(Vector512<short> value, Vector512<ushort> count);
public static Vector512<short> ShiftRightLogical(Vector512<short> value, Vector128<short> count);
public static Vector512<ushort> ShiftRightLogical(Vector512<ushort> value, Vector128<ushort> count);
public static Vector512<short> ShiftRightLogical(Vector512<short> value, [ConstantExpected] byte count);
public static Vector512<ushort> ShiftRightLogical(Vector512<ushort> value, [ConstantExpected] byte count);
public static Vector512<sbyte> ShiftRightLogical128BitLane(Vector512<sbyte> value, [ConstantExpected] byte numBytes);
public static Vector512<byte> ShiftRightLogical128BitLane(Vector512<byte> value, [ConstantExpected] byte numBytes);
public static Vector512<short> ShiftRightLogicalVariable(Vector512<short> value, Vector512<ushort> count);
public static Vector512<ushort> ShiftRightLogicalVariable(Vector512<ushort> value, Vector512<ushort> count);
public static Vector512<sbyte> Shuffle(Vector512<sbyte> value, Vector512<sbyte> mask);
public static Vector512<byte> Shuffle(Vector512<byte> value, Vector512<byte> mask);
public static Vector512<short> ShuffleHigh(Vector512<short> value, [ConstantExpected] byte control);
public static Vector512<ushort> ShuffleHigh(Vector512<ushort> value, [ConstantExpected] byte control);
public static Vector512<short> ShuffleLow(Vector512<short> value, [ConstantExpected] byte control);
public static Vector512<ushort> ShuffleLow(Vector512<ushort> value, [ConstantExpected] byte control);
public static new unsafe void Store(sbyte* address, Vector512<sbyte> source);
public static new unsafe void Store(byte* address, Vector512<byte> source);
public static new unsafe void Store(short* address, Vector512<short> source);
public static new unsafe void Store(ushort* address, Vector512<ushort> source);
public static Vector512<sbyte> Subtract(Vector512<sbyte> left, Vector512<sbyte> right);
public static Vector512<byte> Subtract(Vector512<byte> left, Vector512<byte> right);
public static Vector512<short> Subtract(Vector512<short> left, Vector512<short> right);
public static Vector512<ushort> Subtract(Vector512<ushort> left, Vector512<ushort> right);
public static Vector512<sbyte> SubtractSaturate(Vector512<sbyte> left, Vector512<sbyte> right);
public static Vector512<short> SubtractSaturate(Vector512<short> left, Vector512<short> right);
public static Vector512<byte> SubtractSaturate(Vector512<byte> left, Vector512<byte> right);
public static Vector512<ushort> SubtractSaturate(Vector512<ushort> left, Vector512<ushort> right);
public static Vector512<ushort> SumAbsoluteDifferences(Vector512<byte> left, Vector512<byte> right);
public static Vector512<ushort> SumAbsoluteDifferencesInBlock32(Vector512<byte> left, Vector512<byte> right, [ConstantExpected] byte control);
public static Vector512<sbyte> UnpackHigh(Vector512<sbyte> left, Vector512<sbyte> right);
public static Vector512<byte> UnpackHigh(Vector512<byte> left, Vector512<byte> right);
public static Vector512<short> UnpackHigh(Vector512<short> left, Vector512<short> right);
public static Vector512<ushort> UnpackHigh(Vector512<ushort> left, Vector512<ushort> right);
public static Vector512<sbyte> UnpackLow(Vector512<sbyte> left, Vector512<sbyte> right);
public static Vector512<byte> UnpackLow(Vector512<byte> left, Vector512<byte> right);
public static Vector512<short> UnpackLow(Vector512<short> left, Vector512<short> right);
public static Vector512<ushort> UnpackLow(Vector512<ushort> left, Vector512<ushort> right);
/// From AVX512CD
public static Vector512<int> DetectConflicts(Vector512<int> value);
public static Vector512<uint> DetectConflicts(Vector512<uint> value);
public static Vector512<long> DetectConflicts(Vector512<long> value);
public static Vector512<ulong> DetectConflicts(Vector512<ulong> value);
public static Vector512<int> LeadingZeroCount(Vector512<int> value);
public static Vector512<uint> LeadingZeroCount(Vector512<uint> value);
public static Vector512<long> LeadingZeroCount(Vector512<long> value);
public static Vector512<ulong> LeadingZeroCount(Vector512<ulong> value);
/// From AVX512DQ
public static Vector512<float> And(Vector512<float> left, Vector512<float> right);
public static Vector512<double> And(Vector512<double> left, Vector512<double> right);
public static Vector512<float> AndNot(Vector512<float> left, Vector512<float> right);
public static Vector512<double> AndNot(Vector512<double> left, Vector512<double> right);
public static Vector512<int> BroadcastPairScalarToVector512(Vector128<int> value);
public static Vector512<uint> BroadcastPairScalarToVector512(Vector128<uint> value);
public static Vector512<float> BroadcastPairScalarToVector512(Vector128<float> value);
public static unsafe Vector512<long> BroadcastVector128ToVector512(long* address);
public static unsafe Vector512<ulong> BroadcastVector128ToVector512(ulong* address);
public static unsafe Vector512<double> BroadcastVector128ToVector512(double* address);
public static unsafe Vector512<int> BroadcastVector256ToVector512(int* address);
public static unsafe Vector512<uint> BroadcastVector256ToVector512(uint* address);
public static unsafe Vector512<float> BroadcastVector256ToVector512(float* address);
public static Vector256<float> ConvertToVector256Single(Vector512<long> value);
public static Vector256<float> ConvertToVector256Single(Vector512<ulong> value);
public static Vector512<double> ConvertToVector512Double(Vector512<long> value);
public static Vector512<double> ConvertToVector512Double(Vector512<ulong> value);
public static Vector512<long> ConvertToVector512Int64(Vector256<float> value);
public static Vector512<long> ConvertToVector512Int64(Vector512<double> value);
public static Vector512<long> ConvertToVector512Int64WithTruncation(Vector256<float> value);
public static Vector512<long> ConvertToVector512Int64WithTruncation(Vector512<double> value);
public static Vector512<ulong> ConvertToVector512UInt64(Vector256<float> value);
public static Vector512<ulong> ConvertToVector512UInt64(Vector512<double> value);
public static Vector512<ulong> ConvertToVector512UInt64WithTruncation(Vector256<float> value);
public static Vector512<ulong> ConvertToVector512UInt64WithTruncation(Vector512<double> value);
public static new Vector128<long> ExtractVector128(Vector512<long> value, [ConstantExpected] byte index);
public static new Vector128<ulong> ExtractVector128(Vector512<ulong> value, [ConstantExpected] byte index);
public static new Vector128<double> ExtractVector128(Vector512<double> value, [ConstantExpected] byte index);
public static new Vector256<int> ExtractVector256(Vector512<int> value, [ConstantExpected] byte index);
public static new Vector256<uint> ExtractVector256(Vector512<uint> value, [ConstantExpected] byte index);
public static new Vector256<float> ExtractVector256(Vector512<float> value, [ConstantExpected] byte index);
public static new Vector512<long> InsertVector128(Vector512<long> value, Vector128<long> data, [ConstantExpected] byte index);
public static new Vector512<ulong> InsertVector128(Vector512<ulong> value, Vector128<ulong> data, [ConstantExpected] byte index);
public static new Vector512<double> InsertVector128(Vector512<double> value, Vector128<double> data, [ConstantExpected] byte index);
public static new Vector512<int> InsertVector256(Vector512<int> value, Vector256<int> data, [ConstantExpected] byte index);
public static new Vector512<uint> InsertVector256(Vector512<uint> value, Vector256<uint> data, [ConstantExpected] byte index);
public static new Vector512<float> InsertVector256(Vector512<float> value, Vector256<float> data, [ConstantExpected] byte index);
public static Vector512<long> MultiplyLow(Vector512<long> left, Vector512<long> right);
public static Vector512<ulong> MultiplyLow(Vector512<ulong> left, Vector512<ulong> right);
public static Vector512<float> Or(Vector512<float> left, Vector512<float> right);
public static Vector512<double> Or(Vector512<double> left, Vector512<double> right);
public static Vector512<float> Range(Vector512<float> left, Vector512<float> right, [ConstantExpected(Max = (byte)(0x0F))] byte control);
public static Vector512<double> Range(Vector512<double> left, Vector512<double> right, [ConstantExpected(Max = (byte)(0x0F))] byte control);
public static Vector512<float> Reduce(Vector512<float> value, [ConstantExpected] byte control);
public static Vector512<double> Reduce(Vector512<double> value, [ConstantExpected] byte control);
public static Vector512<float> Xor(Vector512<float> left, Vector512<float> right);
public static Vector512<double> Xor(Vector512<double> left, Vector512<double> right);
/// From AVX512Vbmi
public static Vector512<sbyte> PermuteVar64x8(Vector512<sbyte> left, Vector512<sbyte> control);
public static Vector512<byte> PermuteVar64x8(Vector512<byte> left, Vector512<byte> control);
public static Vector512<byte> PermuteVar64x8x2(Vector512<byte> lower, Vector512<byte> indices, Vector512<byte> upper);
public static Vector512<sbyte> PermuteVar64x8x2(Vector512<sbyte> lower, Vector512<sbyte> indices, Vector512<sbyte> upper);
}
}
Risks
No response