[wasm] Add narrow methods to PackedSimd (#83084)
authorRadek Doulik <radek.doulik@gmail.com>
Tue, 7 Mar 2023 15:21:36 +0000 (16:21 +0100)
committerGitHub <noreply@github.com>
Tue, 7 Mar 2023 15:21:36 +0000 (16:21 +0100)
* [wasm] Add narrow methods to PackedSimd

Add them as internal as the approved API contains wrong methods for
these. https://github.com/dotnet/runtime/issues/53730#issuecomment-1453900537

This will allow faster implementation of IndexOfAnyValues for wasm.
https://github.com/dotnet/runtime/pull/82789#issuecomment-1451056305

* Fix build

src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.PlatformNotSupported.cs
src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.cs
src/mono/mono/mini/simd-intrinsics.c
src/mono/mono/mini/simd-methods.h

index 2720f30..69f53e6 100644 (file)
@@ -151,5 +151,11 @@ namespace System.Runtime.Intrinsics.Wasm
         public static Vector128<double> CompareNotEqual(Vector128<double> left, Vector128<double> right) { throw new PlatformNotSupportedException(); }
         public static Vector128<nint>   CompareNotEqual(Vector128<nint>   left, Vector128<nint>   right) { throw new PlatformNotSupportedException(); }
         public static Vector128<nuint>  CompareNotEqual(Vector128<nuint>  left, Vector128<nuint>  right) { throw new PlatformNotSupportedException(); }
+
+        internal static Vector128<sbyte>  ConvertNarrowingSignedSaturate(Vector128<short>   lower, Vector128<short> upper) { throw new PlatformNotSupportedException(); }
+        internal static Vector128<short>  ConvertNarrowingSignedSaturate(Vector128<int>     lower, Vector128<int>   upper) { throw new PlatformNotSupportedException(); }
+
+        internal static Vector128<byte>   ConvertNarrowingUnsignedSaturate(Vector128<short> lower, Vector128<short> upper) { throw new PlatformNotSupportedException(); }
+        internal static Vector128<ushort> ConvertNarrowingUnsignedSaturate(Vector128<int>   lower, Vector128<int>   upper) { throw new PlatformNotSupportedException(); }
     }
 }
index ab5da4a..d4d37df 100644 (file)
@@ -665,5 +665,29 @@ namespace System.Runtime.Intrinsics.Wasm
         /// </summary>
         [Intrinsic]
         public static Vector128<nuint>  CompareNotEqual(Vector128<nuint>  left, Vector128<nuint>  right) => CompareNotEqual(left, right);
+
+        /// <summary>
+        ///   i8x16.narrow_i16x8_s
+        /// </summary>
+        [Intrinsic]
+        internal static Vector128<sbyte> ConvertNarrowingSignedSaturate(Vector128<short> lower, Vector128<short> upper) => ConvertNarrowingSignedSaturate(lower, upper);
+
+        /// <summary>
+        ///   i16x8.narrow_i32x4_s
+        /// </summary>
+        [Intrinsic]
+        internal static Vector128<short> ConvertNarrowingSignedSaturate(Vector128<int>   lower, Vector128<int>   upper) => ConvertNarrowingSignedSaturate(lower, upper);
+
+        /// <summary>
+        ///   i8x16.narrow_i16x8_u
+        /// </summary>
+        [Intrinsic]
+        internal static Vector128<byte>  ConvertNarrowingUnsignedSaturate(Vector128<short> lower, Vector128<short> upper) => ConvertNarrowingUnsignedSaturate(lower, upper);
+
+        /// <summary>
+        ///   i16x8.narrow_i32x4_u
+        /// </summary>
+        [Intrinsic]
+        internal static Vector128<ushort> ConvertNarrowingUnsignedSaturate(Vector128<int>  lower, Vector128<int>   upper) => ConvertNarrowingUnsignedSaturate(lower, upper);
     }
 }
index c0db54a..6ee5a4f 100644 (file)
@@ -4613,6 +4613,8 @@ static SimdIntrinsic packedsimd_methods [] = {
        {SN_Bitmask},
        {SN_CompareEqual},
        {SN_CompareNotEqual},
+       {SN_ConvertNarrowingSignedSaturate},
+       {SN_ConvertNarrowingUnsignedSaturate},
        {SN_Dot},
        {SN_ExtractLane},
        {SN_Multiply},
@@ -4708,6 +4710,36 @@ emit_wasm_supported_intrinsics (
                                return emit_simd_ins_for_sig (cfg, klass, type_enum_is_float (arg0_type) ? OP_XCOMPARE_FP : OP_XCOMPARE, CMP_EQ, arg0_type, fsig, args);
                        case SN_CompareNotEqual:
                                return emit_simd_ins_for_sig (cfg, klass, type_enum_is_float (arg0_type) ? OP_XCOMPARE_FP : OP_XCOMPARE, CMP_NE, arg0_type, fsig, args);
+                       case SN_ConvertNarrowingSignedSaturate: {
+                               int intrins = -1;
+                               switch (arg0_type) {
+                               case MONO_TYPE_I2:
+                                               intrins = INTRINS_WASM_NARROW_SIGNED_V16;
+                                               break;
+                               case MONO_TYPE_I4:
+                                               intrins = INTRINS_WASM_NARROW_SIGNED_V8;
+                                               break;
+                               }
+                               if (intrins != -1)
+                                               return emit_simd_ins_for_sig (cfg, klass, OP_XOP_X_X_X, intrins, arg0_type, fsig, args);
+
+                               return NULL;
+                       }
+                       case SN_ConvertNarrowingUnsignedSaturate: {
+                               int intrins = -1;
+                               switch (arg0_type) {
+                               case MONO_TYPE_I2:
+                                               intrins = INTRINS_WASM_NARROW_UNSIGNED_V16;
+                                               break;
+                               case MONO_TYPE_I4:
+                                               intrins = INTRINS_WASM_NARROW_UNSIGNED_V8;
+                                               break;
+                               }
+                               if (intrins != -1)
+                                               return emit_simd_ins_for_sig (cfg, klass, OP_XOP_X_X_X, intrins, arg0_type, fsig, args);
+
+                               return NULL;
+                       }
                        case SN_ExtractLane: {
                                int extract_op = type_to_xextract_op (arg0_type);
                                return emit_simd_ins_for_sig (cfg, klass, extract_op, -1, arg0_type, fsig, args);
index 2d4b6dd..5b442c3 100644 (file)
@@ -639,3 +639,5 @@ METHOD(Splat)
 METHOD(ExtractLane)
 METHOD(ReplaceLane)
 METHOD(Swizzle)
+METHOD(ConvertNarrowingSignedSaturate)
+METHOD(ConvertNarrowingUnsignedSaturate)