Skip to content

S.R.I.Wasm.PackedSimd API changes #88092

@radekdoulik

Description

@radekdoulik

S.R.I.Wasm.PackedSimd API changes

During implementation of the PackedSimd class and intrinsics I found few issues in the API. I changed the affected methods and kept them internal until now. I would like to get these approved and make public in the next preview release. These are in the "Required changes" section bellow.

In the "Other changes to consider" I also propose few more changes based on the things I noticed and on the comments from @kg and @vargaz. These are for methods which are already public, but were present only in the preview releases, so I think we can still change them if they would get through the API review.

Required changes

Rename ConvertToInt32Saturate methods with uint return type to avoid signature conflict with public static Vector128<int> ConvertToInt32Saturate(...). They had the same name and arguments, while returning different types, signed and unsigned integers.

* original approved API

    public static Vector128<uint> ConvertToInt32Saturate(Vector128<float> value);
    public static Vector128<uint> ConvertToInt32Saturate(Vector128<double> value);

* proposed change

    public static Vector128<uint> ConvertToUInt32Saturate(Vector128<float> value);
    public static Vector128<uint> ConvertToUInt32Saturate(Vector128<double> value);

Update the narrowing convert methods to have signed arguments. Also remove methods with 64bit vector arguments as there are not narrowing instructions for this size. This change is based on the wasm SIMD proposal, where it states Regardless of the whether the operation is signed or unsigned, the input lanes are interpreted as signed integers and on the test of the implementation.

* original approved API

    public static Vector128<sbyte>  ConvertNarrowingSaturate(Vector128<short>  lower, Vector128<short>  upper);
    public static Vector128<byte>   ConvertNarrowingSaturate(Vector128<ushort> lower, Vector128<ushort> upper);
    public static Vector128<short>  ConvertNarrowingSaturate(Vector128<int>    lower, Vector128<int>    upper);
    public static Vector128<ushort> ConvertNarrowingSaturate(Vector128<uint>   lower, Vector128<uint>   upper);
    public static Vector128<int>    ConvertNarrowingSaturate(Vector128<long>   lower, Vector128<long>   upper);
    public static Vector128<uint>   ConvertNarrowingSaturate(Vector128<ulong>  lower, Vector128<ulong>  upper);

* proposed change

    public static Vector128<sbyte>  ConvertNarrowingSaturateSigned(Vector128<short> lower, Vector128<short> upper);
    public static Vector128<short>  ConvertNarrowingSaturateSigned(Vector128<int>   lower, Vector128<int>   upper);
    public static Vector128<byte>   ConvertNarrowingSaturateUnsigned(Vector128<short> lower, Vector128<short> upper);
    public static Vector128<ushort> ConvertNarrowingSaturateUnsigned(Vector128<int>   lower, Vector128<int>   upper);

Other changes to consider

Unify the Scalar/Lane terms in the method names. Use Scalar everywhere to be consistent.

* original approved API

public static int    ExtractLane(Vector128<sbyte>  value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(15))] byte index);    // takes ImmLaneIdx16
public static uint   ExtractLane(Vector128<byte>   value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(15))] byte index);    // takes ImmLaneIdx16
public static int    ExtractLane(Vector128<short>  value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index);    // takes ImmLaneIdx8
public static uint   ExtractLane(Vector128<ushort> value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index);    // takes ImmLaneIdx8
public static int    ExtractLane(Vector128<int>    value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index);    // takes ImmLaneIdx4
public static uint   ExtractLane(Vector128<uint>   value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index);    // takes ImmLaneIdx4
public static long   ExtractLane(Vector128<long>   value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index);    // takes ImmLaneIdx2
public static ulong  ExtractLane(Vector128<ulong>  value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index);    // takes ImmLaneIdx2
public static float  ExtractLane(Vector128<float>  value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index);    // takes ImmLaneIdx4
public static double ExtractLane(Vector128<double> value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index);    // takes ImmLaneIdx2
public static nint   ExtractLane(Vector128<nint>   value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index);
public static nuint  ExtractLane(Vector128<nuint>  value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index);
public static Vector128<sbyte>  ReplaceLane(Vector128<sbyte>  vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(15))] byte imm, int    value);   // takes ImmLaneIdx16
public static Vector128<byte>   ReplaceLane(Vector128<byte>   vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(15))] byte imm, uint   value);   // takes ImmLaneIdx16
public static Vector128<short>  ReplaceLane(Vector128<short>  vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte imm, int    value);   // takes ImmLaneIdx8
public static Vector128<ushort> ReplaceLane(Vector128<ushort> vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte imm, uint   value);   // takes ImmLaneIdx8
public static Vector128<int>    ReplaceLane(Vector128<int>    vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte imm, int    value);   // takes ImmLaneIdx4
public static Vector128<int>    ReplaceLane(Vector128<uint>   vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte imm, uint   value);   // takes ImmLaneIdx4
public static Vector128<long>   ReplaceLane(Vector128<long>   vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte imm, long   value);   // takes ImmLaneIdx2
public static Vector128<ulong>  ReplaceLane(Vector128<ulong>  vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte imm, ulong  value);   // takes ImmLaneIdx2
public static Vector128<float>  ReplaceLane(Vector128<float>  vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte imm, float  value);   // takes ImmLaneIdx4
public static Vector128<double> ReplaceLane(Vector128<double> vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte imm, double value);   // takes ImmLaneIdx2
public static Vector128<nint>   ReplaceLane(Vector128<nint>   vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte imm, nint   value);
public static Vector128<nuint>  ReplaceLane(Vector128<nuint>  vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte imm, nuint  value);

* proposed change:

public static int    ExtractScalar(Vector128<sbyte>  value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(15))] byte index);    // takes ImmLaneIdx16
public static uint   ExtractScalar(Vector128<byte>   value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(15))] byte index);    // takes ImmLaneIdx16
public static int    ExtractScalar(Vector128<short>  value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index);    // takes ImmLaneIdx8
public static uint   ExtractScalar(Vector128<ushort> value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index);    // takes ImmLaneIdx8
public static int    ExtractScalar(Vector128<int>    value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index);    // takes ImmLaneIdx4
public static uint   ExtractScalar(Vector128<uint>   value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index);    // takes ImmLaneIdx4
public static long   ExtractScalar(Vector128<long>   value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index);    // takes ImmLaneIdx2
public static ulong  ExtractScalar(Vector128<ulong>  value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index);    // takes ImmLaneIdx2
public static float  ExtractScalar(Vector128<float>  value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index);    // takes ImmLaneIdx4
public static double ExtractScalar(Vector128<double> value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index);    // takes ImmLaneIdx2
public static nint   ExtractScalar(Vector128<nint>   value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index);
public static nuint  ExtractScalar(Vector128<nuint>  value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index);
public static Vector128<sbyte>  ReplaceScalar(Vector128<sbyte>  vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(15))] byte imm, int    value);   // takes ImmLaneIdx16
public static Vector128<byte>   ReplaceScalar(Vector128<byte>   vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(15))] byte imm, uint   value);   // takes ImmLaneIdx16
public static Vector128<short>  ReplaceScalar(Vector128<short>  vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte imm, int    value);   // takes ImmLaneIdx8
public static Vector128<ushort> ReplaceScalar(Vector128<ushort> vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte imm, uint   value);   // takes ImmLaneIdx8
public static Vector128<int>    ReplaceScalar(Vector128<int>    vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte imm, int    value);   // takes ImmLaneIdx4
public static Vector128<int>    ReplaceScalar(Vector128<uint>   vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte imm, uint   value);   // takes ImmLaneIdx4
public static Vector128<long>   ReplaceScalar(Vector128<long>   vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte imm, long   value);   // takes ImmLaneIdx2
public static Vector128<ulong>  ReplaceScalar(Vector128<ulong>  vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte imm, ulong  value);   // takes ImmLaneIdx2
public static Vector128<float>  ReplaceScalar(Vector128<float>  vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte imm, float  value);   // takes ImmLaneIdx4
public static Vector128<double> ReplaceScalar(Vector128<double> vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte imm, double value);   // takes ImmLaneIdx2
public static Vector128<nint>   ReplaceScalar(Vector128<nint>   vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte imm, nint   value);
public static Vector128<nuint>  ReplaceScalar(Vector128<nuint>  vector, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte imm, nuint  value);

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions