Skip to content

Expose AVX512BW, AVX512CD, and AVX512DQ #76579

Closed
@tannergooding

Description

@tannergooding

Summary

Continuing off #73604 where we exposed AVX512F, we should expose support for the additional ISAs that are part of the x86-64-v4 baseline.

API Proposal

We should expose the Avx512BW, AVX512CD, and AVX512DQ classes as the first part of the AVX512 feature set.

namespace System.Runtime.Intrinsics.X86;

public abstract partial class Avx512BW : Avx512F
{
    // SSE-SSE4.2

    public static Vector512<sbyte> Abs(Vector512<sbyte> value);
    public static Vector512<short> Abs(Vector512<short> value);

    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<sbyte>  Add(Vector512<sbyte>  left, Vector512<sbyte>  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<short>  AddSaturate(Vector512<short>  left, Vector512<short>  right);
    public static Vector512<byte>   AddSaturate(Vector512<byte>   left, Vector512<byte>   right);
    public static Vector512<ushort> AddSaturate(Vector512<ushort> left, Vector512<ushort> right);

    public static Vector512<byte>  AlignRight(Vector512<byte>  left, Vector512<sbyte>  right, byte mask);
    public static Vector512<sbyte> AlignRight(Vector512<sbyte> left, Vector512<ssbyte> right, 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<short> ConvertToVector512Int16(Vector256<byte>  value);
    public static Vector512<short> ConvertToVector512Int16(Vector512<sbyte> value);

    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<sbyte>  Max(Vector512<sbyte>  left, Vector512<sbyte>  right);
    public static Vector512<ushort> Max(Vector512<ushort> left, Vector512<ushort> 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<sbyte>  Min(Vector512<sbyte>  left, Vector512<sbyte>  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>   PackUnignedSaturate(Vector512<short> left, Vector512<short> right);
    public static Vector512<ushort> PackUnignedSaturate(Vector512<int>   left, Vector512<int>   right);

    public static Vector512<short>  ShiftLeftLogical(Vector512<short>  value, byte count);
    public static Vector512<ushort> ShiftLeftLogical(Vector512<ushort> value, byte count);
    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<byte>   ShiftLeftLogical128BitLane(Vector512<byte>   value, byte numBytes);
    public static Vector512<short>  ShiftLeftLogical128BitLane(Vector512<short>  value, byte numBytes);
    public static Vector512<int>    ShiftLeftLogical128BitLane(Vector512<int>    value, byte numBytes);
    public static Vector512<long>   ShiftLeftLogical128BitLane(Vector512<long>   value, byte numBytes);
    public static Vector512<sbyte>  ShiftLeftLogical128BitLane(Vector512<sbyte>  value, byte numBytes);
    public static Vector512<ushort> ShiftLeftLogical128BitLane(Vector512<ushort> value, byte numBytes);
    public static Vector512<uint>   ShiftLeftLogical128BitLane(Vector512<uint>   value, byte numBytes);
    public static Vector512<ulong>  ShiftLeftLogical128BitLane(Vector512<ulong>  value, byte numBytes);

    public static Vector512<short>  ShiftRightArithmetic(Vector512<short>  value, byte count);
    public static Vector512<short>  ShiftRightArithmetic(Vector512<short>  value, Vector128<short>  count);

    public static Vector512<short>  ShiftRightLogical(Vector512<short>  value, byte count);
    public static Vector512<ushort> ShiftRightLogical(Vector512<ushort> value, byte 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<byte>   ShiftRightLogical128BitLane(Vector512<byte>   value, byte numBytes);
    public static Vector512<short>  ShiftRightLogical128BitLane(Vector512<short>  value, byte numBytes);
    public static Vector512<int>    ShiftRightLogical128BitLane(Vector512<int>    value, byte numBytes);
    public static Vector512<long>   ShiftRightLogical128BitLane(Vector512<long>   value, byte numBytes);
    public static Vector512<sbyte>  ShiftRightLogical128BitLane(Vector512<sbyte>  value, byte numBytes);
    public static Vector512<ushort> ShiftRightLogical128BitLane(Vector512<ushort> value, byte numBytes);
    public static Vector512<uint>   ShiftRightLogical128BitLane(Vector512<uint>   value, byte numBytes);
    public static Vector512<ulong>  ShiftRightLogical128BitLane(Vector512<ulong>  value, byte numBytes);

    public static Vector512<byte>  Shuffle(Vector512<byte>  value, Vector512<byte>  mask);
    public static Vector512<sbyte> Shuffle(Vector512<sbyte> value, Vector512<sbyte> mask);

    public static Vector512<short>  ShuffleHigh(Vector512<short>  value, byte control);
    public static Vector512<ushort> ShuffleHigh(Vector512<ushort> value, byte control);

    public static Vector512<short>  ShuffleLow(Vector512<short>  value, byte control);
    public static Vector512<ushort> ShuffleLow(Vector512<ushort> value, byte control);

    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<sbyte>  Subtract(Vector512<sbyte>  left, Vector512<sbyte>  right);
    public static Vector512<ushort> Subtract(Vector512<ushort> left, Vector512<ushort> right);

    public static Vector512<byte>   SubtractSaturate(Vector512<byte>   left, Vector512<byte>   right);
    public static Vector512<short>  SubtractSaturate(Vector512<short>  left, Vector512<short>  right);
    public static Vector512<sbyte>  SubtractSaturate(Vector512<sbyte>  left, Vector512<sbyte>  right);
    public static Vector512<ushort> SubtractSaturate(Vector512<ushort> left, Vector512<ushort> right);

    public static Vector512<ushort> SumAbsoluteDifferences(Vector512<byte> byte, Vector512<byte> byte);

    public static Vector512<byte>   UnpackHigh(Vector512<byte>   left, Vector512<byte>   right);
    public static Vector512<sbyte>  UnpackHigh(Vector512<sbyte>  left, Vector512<sbyte>  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<byte>   UnpackLow(Vector512<byte>   left, Vector512<byte>   right);
    public static Vector512<short>  UnpackLow(Vector512<short>  left, Vector512<short>  right);
    public static Vector512<sbyte>  UnpackLow(Vector512<sbyte>  left, Vector512<sbyte>  right);
    public static Vector512<ushort> UnpackLow(Vector512<ushort> left, Vector512<ushort> right);

    // AVX-AVX2

    public static Vector512<byte>   BroadcastScalarToVector512(Vector128<byte>   value);
    public static Vector512<short>  BroadcastScalarToVector512(Vector128<short>  value);
    public static Vector512<sbyte>  BroadcastScalarToVector512(Vector128<sbyte>  value);
    public static Vector512<ushort> BroadcastScalarToVector512(Vector128<ushort> value);

    public static Vector512<short>  PermuteVar32x16(Vector512<short>  value, Vector512<short>  control);
    public static Vector512<ushort> PermuteVar32x16(Vector512<ushort> value, Vector512<ushort> control);

    // AVX512

    public static Vector512<byte> SumAbsoluteDifferencesWidening(Vector512<byte> left, Vector512<byte> right, byte control);

    public static Vector512<short>  PermuteVar32x16(Vector512<short>  left, Vector512<short>  right, Vector512<short>  control);
    public static Vector512<ushort> PermuteVar32x16(Vector512<ushort> left, Vector512<ushort> right, Vector512<ushort> control);

    public static Vector256<byte>  ConvertToVector256ByteWithSaturation (Vector512<ushort> value);
    public static Vector256<sbyte> ConvertToVector256SByteWithSaturation(Vector512<short>  value);

    public static Vector512<short>  ShiftLeftLogicalVariable(Vector512<short>  value, Vector512<short>  count);
    public static Vector512<ushort> ShiftLeftLogicalVariable(Vector512<ushort> value, Vector512<ushort> count);

    public static Vector512<short>  ShiftRightArithmeticVariable(Vector512<short> value, Vector512<short> count);

    public static Vector512<short>  ShiftRightLogicalVariable(Vector512<short> value, Vector512<short>  count);
    public static Vector512<ushort> ShiftRightLogicalVariable(Vector512<short> value, Vector512<ushort> count);
}

public abstract partial class Avx512CD : Avx512F
{
    // AVX512

    public static Vector512<int>   DetectConflicts(Vector512<int>   value);
    public static Vector512<long>  DetectConflicts(Vector512<long>  value);
    public static Vector512<uint>  DetectConflicts(Vector512<uint>  value);
    public static Vector512<ulong> DetectConflicts(Vector512<ulong> value);

    public static Vector512<int>   LeadingZeroCount(Vector512<int>   value);
    public static Vector512<long>  LeadingZeroCount(Vector512<long>  value);
    public static Vector512<uint>  LeadingZeroCount(Vector512<uint>  value);
    public static Vector512<ulong> LeadingZeroCount(Vector512<ulong> value);
}


public abstract partial class Avx512DQ : Avx512F
{
    // SSE-SSE4.2

    public static Vector512<double> And(Vector512<double> left, Vector512<double> right);
    public static Vector512<float>  And(Vector512<float>  left, Vector512<float>  right);

    public static Vector512<double> AndNot(Vector512<double> left, Vector512<double> right);
    public static Vector512<float>  AndNot(Vector512<float>  left, Vector512<float>  right);

    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<double> Or(Vector512<double> left, Vector512<double> right);
    public static Vector512<float>  Or(Vector512<float>  left, Vector512<float>  right);

    public static Vector512<double> Xor(Vector512<double> left, Vector512<double> right);
    public static Vector512<float>  Xor(Vector512<float>  left, Vector512<float>  right);

    // AVX-AVX2

    public static Vector128<double> ExtractVector128(Vector512<double> value, byte index);
    public static Vector128<long>   ExtractVector128(Vector512<long>   value, byte index);
    public static Vector128<ulong>  ExtractVector128(Vector512<ulong>  value, byte index);

    public static Vector256<int>   ExtractVector256(Vector512<int>   value, byte index);
    public static Vector256<float> ExtractVector256(Vector512<float> value, byte index);
    public static Vector256<uint>  ExtractVector256(Vector512<uint>  value, byte index);

    public static Vector512<double> InsertVector128(Vector512<double> value, Vector128<double> data, byte index);
    public static Vector512<long>   InsertVector128(Vector512<long>   value, Vector128<long>   data, byte index);
    public static Vector512<ulong>  InsertVector128(Vector512<ulong>  value, Vector128<ulong>  data, byte index);

    public static Vector512<int>   InsertVector256(Vector512<int>   value, Vector256<int>   data, byte index);
    public static Vector512<float> InsertVector256(Vector512<float> value, Vector256<float> data, byte index);
    public static Vector512<uint>  InsertVector256(Vector512<uint>  value, Vector256<uint>  data, byte index);

    public static Vector512<int>   BroadcastPairScalarToVector512(Vector128<int>  value);
    public static Vector512<uint>  BroadcastPairScalarToVector512(Vector128<uint> value);

    public static Vector512<long>  BroadcastToVector512(Vector128<long>  value);
    public static Vector512<ulong> BroadcastToVector512(Vector128<ulong> value);
    public static Vector512<int>   BroadcastToVector512(Vector256<int>   value);
    public static Vector512<uint>  BroadcastToVector512(Vector256<uint>  value);

    // AVX512

    public static Vector512<float> BroadcastPairScalarToVector512(Vector128<float> value);

    public static Vector512<double> BroadcastToVector512(Vector128<double> value);
    public static Vector512<float>  BroadcastToVector512(Vector256<float>  value);

    public static Vector256<float> ConvertToVector256Single(Vector512<long>  value);
    public static Vector256<float> ConvertToVector256Single(Vector512<long>  value, FloatRoundingMode mode);
    public static Vector256<float> ConvertToVector256Single(Vector512<ulong> value);
    public static Vector256<float> ConvertToVector256Single(Vector512<ulong> value, FloatRoundingMode mode);

    public static Vector512<double> ConvertToVector512Double(Vector512<long> value);
    public static Vector512<double> ConvertToVector512Double(Vector512<long> value, FloatRoundingMode mode);
    public static Vector512<double> ConvertToVector512Double(Vector512<ulong> value);
    public static Vector512<double> ConvertToVector512Double(Vector512<ulong> value, FloatRoundingMode mode);

    public static Vector512<long> ConvertToVector512Int64(Vector512<double> value);
    public static Vector512<long> ConvertToVector512Int64(Vector512<double> value, FloatRoundingMode mode);
    public static Vector512<long> ConvertToVector512Int64(Vector512<float>  value);
    public static Vector512<long> ConvertToVector512Int64(Vector512<float>  value, FloatRoundingMode mode);

    public static Vector512<long> ConvertToVector512Int64WithTruncation(Vector256<float>  value);
    public static Vector512<long> ConvertToVector512Int64WithTruncation(Vector256<float>  value, FloatRoundingMode mode);
    public static Vector512<long> ConvertToVector512Int64WithTruncation(Vector512<double> value);
    public static Vector512<long> ConvertToVector512Int64WithTruncation(Vector512<double> value, FloatRoundingMode mode);

    public static Vector512<ulong> ConvertToVector512UInt64(Vector256<float>  value);
    public static Vector512<ulong> ConvertToVector512UInt64(Vector256<float>  value, FloatRoundingMode mode);
    public static Vector512<ulong> ConvertToVector512UInt64(Vector512<double> value);
    public static Vector512<ulong> ConvertToVector512UInt64(Vector512<double> value, FloatRoundingMode mode);

    public static Vector512<double> RangeRestrict(Vector512<double> left, Vector512<double> right, byte control);
    public static Vector512<float>  RangeRestrict(Vector512<float>  left, Vector512<float>  right, byte control);

    public static Vector128<double> RangeRestrictScalar(Vector128<double> left,  Vector128<double> right, byte control);
    public static Vector128<float>  RangeRestrictScalar(Vector128<float>  left,  Vector128<float>  right, byte control);

    public static Vector128<double> RangeRestrictScalar(Vector128<double> upper, Vector128<double> left, Vector128<double> right, byte control);
    public static Vector128<float>  RangeRestrictScalar(Vector128<float>  upper, Vector128<float>  left, Vector128<float>  right, byte control);

    public static Vector512<double> ReductionTransform(Vector512<double> value, byte control);
    public static Vector512<float>  ReductionTransform(Vector512<float>  value, byte control);

    public static Vector128<double> ReductionTransformScalar(Vector128<double> upper, Vector128<double> value, byte control);
    public static Vector128<float>  ReductionTransformScalar(Vector128<float>  upper, Vector128<float>  value, byte control);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions