From 94193a7f859ab0e08d95814c8a3d03904624eca5 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Fri, 14 Apr 2023 17:18:48 +0200 Subject: [PATCH 1/2] [wasm] Add PackedSimd saturating integer arith. --- .../Wasm/PackedSimd.PlatformNotSupported.cs | 37 ++++++++++ .../Runtime/Intrinsics/Wasm/PackedSimd.cs | 37 ++++++++++ .../ref/System.Runtime.Intrinsics.cs | 28 +++++++ src/mono/mono/mini/llvm-intrinsics.h | 17 ++++- src/mono/mono/mini/simd-intrinsics.c | 73 +++++++++++++++++++ src/mono/mono/mini/simd-methods.h | 2 + 6 files changed, 190 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.PlatformNotSupported.cs index d284f4221334d3..a1f1453091b42e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.PlatformNotSupported.cs @@ -123,6 +123,43 @@ public abstract class PackedSimd public static Vector128 AddPairwiseWidening(Vector128 value) { throw new PlatformNotSupportedException(); } public static Vector128 AddPairwiseWidening(Vector128 value) { throw new PlatformNotSupportedException(); } + // Saturating integer arithmetic + + public static Vector128 AddSaturate(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddSaturate(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddSaturate(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddSaturate(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + public static Vector128 MultiplyRoundedSaturateQ15(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + public static Vector128 Min(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Min(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Min(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Min(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Min(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Min(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + public static Vector128 Max(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Max(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Max(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Max(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Max(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 Max(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + public static Vector128 AverageRounded(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AverageRounded(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + public static Vector128 Abs(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 Abs(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 Abs(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 Abs(Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 Abs(Vector128 value) { throw new PlatformNotSupportedException(); } + // Bit shifts public static Vector128 ShiftLeft(Vector128 value, int count) { throw new PlatformNotSupportedException(); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.cs index d17d6164ef8598..ffd628ea543dac 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.cs @@ -515,6 +515,43 @@ public abstract class PackedSimd [Intrinsic] public static Vector128 AddPairwiseWidening(Vector128 value) => AddPairwiseWidening(value); + // Saturating integer arithmetic + + public static Vector128 AddSaturate(Vector128 left, Vector128 right) => AddSaturate(left, right); + public static Vector128 AddSaturate(Vector128 left, Vector128 right) => AddSaturate(left, right); + public static Vector128 AddSaturate(Vector128 left, Vector128 right) => AddSaturate(left, right); + public static Vector128 AddSaturate(Vector128 left, Vector128 right) => AddSaturate(left, right); + + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) => SubtractSaturate(left, right); + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) => SubtractSaturate(left, right); + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) => SubtractSaturate(left, right); + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) => SubtractSaturate(left, right); + + public static Vector128 MultiplyRoundedSaturateQ15(Vector128 left, Vector128 right) => MultiplyRoundedSaturateQ15(left, right); + + public static Vector128 Min(Vector128 left, Vector128 right) => Min(left, right); + public static Vector128 Min(Vector128 left, Vector128 right) => Min(left, right); + public static Vector128 Min(Vector128 left, Vector128 right) => Min(left, right); + public static Vector128 Min(Vector128 left, Vector128 right) => Min(left, right); + public static Vector128 Min(Vector128 left, Vector128 right) => Min(left, right); + public static Vector128 Min(Vector128 left, Vector128 right) => Min(left, right); + + public static Vector128 Max(Vector128 left, Vector128 right) => Max(left, right); + public static Vector128 Max(Vector128 left, Vector128 right) => Max(left, right); + public static Vector128 Max(Vector128 left, Vector128 right) => Max(left, right); + public static Vector128 Max(Vector128 left, Vector128 right) => Max(left, right); + public static Vector128 Max(Vector128 left, Vector128 right) => Max(left, right); + public static Vector128 Max(Vector128 left, Vector128 right) => Max(left, right); + + public static Vector128 AverageRounded(Vector128 left, Vector128 right) => AverageRounded(left, right); + public static Vector128 AverageRounded(Vector128 left, Vector128 right) => AverageRounded(left, right); + + public static Vector128 Abs(Vector128 value) => Abs(value); + public static Vector128 Abs(Vector128 value) => Abs(value); + public static Vector128 Abs(Vector128 value) => Abs(value); + public static Vector128 Abs(Vector128 value) => Abs(value); + public static Vector128 Abs(Vector128 value) => Abs(value); + // Bit shifts /// diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index 26affa796b3a1d..cf96868e2e29bc 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -5745,6 +5745,34 @@ public abstract partial class PackedSimd public static Vector128 AddPairwiseWidening(Vector128 value) { throw null; } public static Vector128 AddPairwiseWidening(Vector128 value) { throw null; } public static Vector128 AddPairwiseWidening(Vector128 value) { throw null; } + public static Vector128 AddSaturate(Vector128 left, Vector128 right) { throw null; } + public static Vector128 AddSaturate(Vector128 left, Vector128 right) { throw null; } + public static Vector128 AddSaturate(Vector128 left, Vector128 right) { throw null; } + public static Vector128 AddSaturate(Vector128 left, Vector128 right) { throw null; } + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) { throw null; } + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) { throw null; } + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) { throw null; } + public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) { throw null; } + public static Vector128 MultiplyRoundedSaturateQ15(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Min(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Min(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Min(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Min(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Min(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Min(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Max(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Max(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Max(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Max(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Max(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Max(Vector128 left, Vector128 right) { throw null; } + public static Vector128 AverageRounded(Vector128 left, Vector128 right) { throw null; } + public static Vector128 AverageRounded(Vector128 left, Vector128 right) { throw null; } + public static Vector128 Abs(Vector128 value) { throw null; } + public static Vector128 Abs(Vector128 value) { throw null; } + public static Vector128 Abs(Vector128 value) { throw null; } + public static Vector128 Abs(Vector128 value) { throw null; } + public static Vector128 Abs(Vector128 value) { throw null; } public static Vector128 ShiftLeft(Vector128 value, int count) { throw null; } public static Vector128 ShiftLeft(Vector128 value, int count) { throw null; } public static Vector128 ShiftLeft(Vector128 value, int count) { throw null; } diff --git a/src/mono/mono/mini/llvm-intrinsics.h b/src/mono/mono/mini/llvm-intrinsics.h index df1ec108d59f0a..33d259371b792d 100644 --- a/src/mono/mono/mini/llvm-intrinsics.h +++ b/src/mono/mono/mini/llvm-intrinsics.h @@ -242,16 +242,18 @@ INTRINS(AESNI_AESDECLAST, x86_aesni_aesdeclast, X86) INTRINS(AESNI_AESENC, x86_aesni_aesenc, X86) INTRINS(AESNI_AESENCLAST, x86_aesni_aesenclast, X86) INTRINS(AESNI_AESIMC, x86_aesni_aesimc, X86) -INTRINS_OVR(SSE_SADD_SATI8, sadd_sat, Generic, v128_i1_t) -INTRINS_OVR(SSE_UADD_SATI8, uadd_sat, Generic, v128_i1_t) -INTRINS_OVR(SSE_SADD_SATI16, sadd_sat, Generic, v128_i2_t) -INTRINS_OVR(SSE_UADD_SATI16, uadd_sat, Generic, v128_i2_t) INTRINS_OVR(SSE_SSUB_SATI8, ssub_sat, Generic, v128_i1_t) INTRINS_OVR(SSE_USUB_SATI8, usub_sat, Generic, v128_i1_t) INTRINS_OVR(SSE_SSUB_SATI16, ssub_sat, Generic, v128_i2_t) INTRINS_OVR(SSE_USUB_SATI16, usub_sat, Generic, v128_i2_t) #endif +#if defined(TARGET_AMD64) || defined(TARGET_X86) || defined(TARGET_WASM) +INTRINS_OVR(SSE_SADD_SATI8, sadd_sat, Generic, v128_i1_t) +INTRINS_OVR(SSE_UADD_SATI8, uadd_sat, Generic, v128_i1_t) +INTRINS_OVR(SSE_SADD_SATI16, sadd_sat, Generic, v128_i2_t) +INTRINS_OVR(SSE_UADD_SATI16, uadd_sat, Generic, v128_i2_t) +#endif #if defined(TARGET_WASM) INTRINS_OVR(WASM_EXTADD_PAIRWISE_SIGNED_V16, wasm_extadd_pairwise_signed, Wasm, sse_i2_t) INTRINS_OVR(WASM_EXTADD_PAIRWISE_SIGNED_V8, wasm_extadd_pairwise_signed, Wasm, sse_i4_t) @@ -265,6 +267,8 @@ INTRINS_OVR(WASM_ANYTRUE_V16, wasm_anytrue, Wasm, sse_i1_t) INTRINS_OVR(WASM_ANYTRUE_V8, wasm_anytrue, Wasm, sse_i2_t) INTRINS_OVR(WASM_ANYTRUE_V4, wasm_anytrue, Wasm, sse_i4_t) INTRINS_OVR(WASM_ANYTRUE_V2, wasm_anytrue, Wasm, sse_i8_t) +INTRINS_OVR(WASM_AVERAGE_ROUNDED_V16, wasm_avgr_unsigned, Wasm, sse_i1_t) +INTRINS_OVR(WASM_AVERAGE_ROUNDED_V8, wasm_avgr_unsigned, Wasm, sse_i2_t) INTRINS_OVR(WASM_BITMASK_V16, wasm_bitmask, Wasm, sse_i1_t) INTRINS_OVR(WASM_BITMASK_V8, wasm_bitmask, Wasm, sse_i2_t) INTRINS_OVR(WASM_BITMASK_V4, wasm_bitmask, Wasm, sse_i4_t) @@ -276,7 +280,12 @@ INTRINS_OVR_2_ARG(WASM_NARROW_SIGNED_V16, wasm_narrow_signed, Wasm, sse_i1_t, ss INTRINS_OVR_2_ARG(WASM_NARROW_SIGNED_V8, wasm_narrow_signed, Wasm, sse_i2_t, sse_i4_t) INTRINS_OVR_2_ARG(WASM_NARROW_UNSIGNED_V16, wasm_narrow_unsigned, Wasm, sse_i1_t, sse_i2_t) INTRINS_OVR_2_ARG(WASM_NARROW_UNSIGNED_V8, wasm_narrow_unsigned, Wasm, sse_i2_t, sse_i4_t) +INTRINS(WASM_Q15MULR_SAT_SIGNED, wasm_q15mulr_sat_signed, Wasm) INTRINS(WASM_SHUFFLE, wasm_shuffle, Wasm) +INTRINS_OVR(WASM_SUB_SAT_SIGNED_V16, wasm_sub_sat_signed, Wasm, sse_i1_t) +INTRINS_OVR(WASM_SUB_SAT_SIGNED_V8, wasm_sub_sat_signed, Wasm, sse_i2_t) +INTRINS_OVR(WASM_SUB_SAT_UNSIGNED_V16, wasm_sub_sat_unsigned, Wasm, sse_i1_t) +INTRINS_OVR(WASM_SUB_SAT_UNSIGNED_V8, wasm_sub_sat_unsigned, Wasm, sse_i2_t) INTRINS(WASM_SWIZZLE, wasm_swizzle, Wasm) #endif #if defined(TARGET_ARM64) diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index a01b2a7a2c0958..831bfbbde44c8f 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -4891,9 +4891,12 @@ static SimdIntrinsic wasmbase_methods [] = { }; static SimdIntrinsic packedsimd_methods [] = { + {SN_Abs, OP_VECTOR_IABS}, {SN_Add}, {SN_AddPairwiseWidening}, + {SN_AddSaturate}, {SN_And, OP_XBINOP_FORCEINT, XBINOP_FORCEINT_AND}, + {SN_AverageRounded}, {SN_Bitmask, OP_WASM_SIMD_BITMASK}, {SN_CompareEqual}, {SN_CompareNotEqual}, @@ -4901,7 +4904,10 @@ static SimdIntrinsic packedsimd_methods [] = { {SN_ConvertNarrowingUnsignedSaturate}, {SN_Dot, OP_XOP_X_X_X, INTRINS_WASM_DOT}, {SN_ExtractLane}, + {SN_Max, OP_XBINOP, OP_IMIN, OP_XBINOP, OP_IMIN_UN}, + {SN_Min, OP_XBINOP, OP_IMAX, OP_XBINOP, OP_IMAX_UN}, {SN_Multiply}, + {SN_MultiplyRoundedSaturateQ15, OP_XOP_X_X_X, INTRINS_WASM_Q15MULR_SAT_SIGNED}, {SN_MultiplyWideningLower, OP_WASM_EXTMUL_LOWER, 0, OP_WASM_EXTMUL_LOWER_U}, {SN_MultiplyWideningUpper, OP_WASM_EXTMUL_UPPER, 0, OP_WASM_EXTMUL_UPPER_U}, {SN_Negate}, @@ -4912,6 +4918,7 @@ static SimdIntrinsic packedsimd_methods [] = { {SN_Shuffle, OP_WASM_SIMD_SHUFFLE}, {SN_Splat}, {SN_Subtract}, + {SN_SubtractSaturate}, {SN_Swizzle, OP_WASM_SIMD_SWIZZLE}, {SN_get_IsSupported}, }; @@ -5018,6 +5025,48 @@ emit_wasm_supported_intrinsics ( return NULL; } + case SN_AddSaturate: { + op = OP_XOP_X_X_X; + + switch (arg0_type) { + case MONO_TYPE_I1: + c0 = INTRINS_SSE_SADD_SATI8; + break; + case MONO_TYPE_I2: + c0 = INTRINS_SSE_SADD_SATI16; + break; + case MONO_TYPE_U1: + c0 = INTRINS_SSE_UADD_SATI8; + break; + case MONO_TYPE_U2: + c0 = INTRINS_SSE_UADD_SATI16; + break; + } + + // continue with default emit + if (c0 != 0) + break; + + return NULL; + } + case SN_AverageRounded: { + op = OP_XOP_X_X_X; + + switch (arg0_type) { + case MONO_TYPE_U1: + c0 = INTRINS_WASM_AVERAGE_ROUNDED_V16; + break; + case MONO_TYPE_U2: + c0 = INTRINS_WASM_AVERAGE_ROUNDED_V8; + break; + } + + // continue with default emit + if (c0 != 0) + break; + + return NULL; + } case SN_CompareEqual: 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: @@ -5074,6 +5123,30 @@ emit_wasm_supported_intrinsics ( g_assert (fsig->param_count == 1 && mono_metadata_type_equal (fsig->params [0], etype)); return emit_simd_ins (cfg, klass, type_to_expand_op (etype->type), args [0]->dreg, -1); } + case SN_SubtractSaturate: { + op = OP_XOP_X_X_X; + + switch (arg0_type) { + case MONO_TYPE_I1: + c0 = INTRINS_WASM_SUB_SAT_SIGNED_V16; + break; + case MONO_TYPE_I2: + c0 = INTRINS_WASM_SUB_SAT_SIGNED_V8; + break; + case MONO_TYPE_U1: + c0 = INTRINS_WASM_SUB_SAT_UNSIGNED_V16; + break; + case MONO_TYPE_U2: + c0 = INTRINS_WASM_SUB_SAT_UNSIGNED_V8; + break; + } + + // continue with default emit + if (c0 != 0) + break; + + return NULL; + } } // default emit path for cases with op set diff --git a/src/mono/mono/mini/simd-methods.h b/src/mono/mono/mini/simd-methods.h index 0e38696380cc5c..1b8ddd3717efe8 100644 --- a/src/mono/mono/mini/simd-methods.h +++ b/src/mono/mono/mini/simd-methods.h @@ -634,10 +634,12 @@ METHOD(MultiplyRoundedDoublingScalarBySelectedScalarAndSubtractSaturateHigh) // Arm.Dp METHOD(DotProductBySelectedQuadruplet) // Wasm +METHOD(AverageRounded) METHOD(Bitmask) METHOD(ConvertNarrowingSignedSaturate) METHOD(ConvertNarrowingUnsignedSaturate) METHOD(ExtractLane) +METHOD(MultiplyRoundedSaturateQ15) METHOD(ReplaceLane) METHOD(ShiftLeft) METHOD(Splat) From 30ae02a95b47ed313597a3c269b63401ec58c10f Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Mon, 24 Apr 2023 12:58:25 +0200 Subject: [PATCH 2/2] Add doc comments --- .../Runtime/Intrinsics/Wasm/PackedSimd.cs | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.cs index ffd628ea543dac..22d5e58e05f0d2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.cs @@ -517,39 +517,123 @@ public abstract class PackedSimd // Saturating integer arithmetic + /// + /// i8x16.add.sat.s + /// public static Vector128 AddSaturate(Vector128 left, Vector128 right) => AddSaturate(left, right); + /// + /// i8x16.add.sat.u + /// public static Vector128 AddSaturate(Vector128 left, Vector128 right) => AddSaturate(left, right); + /// + /// i16x8.add.sat.s + /// public static Vector128 AddSaturate(Vector128 left, Vector128 right) => AddSaturate(left, right); + /// + /// i16x8.add.sat.u + /// public static Vector128 AddSaturate(Vector128 left, Vector128 right) => AddSaturate(left, right); + /// + /// i8x16.sub.sat.s + /// public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) => SubtractSaturate(left, right); + /// + /// i8x16.sub.sat.u + /// public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) => SubtractSaturate(left, right); + /// + /// i16x8.sub.sat.s + /// public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) => SubtractSaturate(left, right); + /// + /// i16x8.sub.sat.u + /// public static Vector128 SubtractSaturate(Vector128 left, Vector128 right) => SubtractSaturate(left, right); + /// + /// i16x8.q15mulr.sat.s + /// public static Vector128 MultiplyRoundedSaturateQ15(Vector128 left, Vector128 right) => MultiplyRoundedSaturateQ15(left, right); + /// + /// i8x16.min.s + /// public static Vector128 Min(Vector128 left, Vector128 right) => Min(left, right); + /// + /// i8x16.min.u + /// public static Vector128 Min(Vector128 left, Vector128 right) => Min(left, right); + /// + /// i16x8.min.s + /// public static Vector128 Min(Vector128 left, Vector128 right) => Min(left, right); + /// + /// i16x8.min.u + /// public static Vector128 Min(Vector128 left, Vector128 right) => Min(left, right); + /// + /// i32x4.min.s + /// public static Vector128 Min(Vector128 left, Vector128 right) => Min(left, right); + /// + /// i32x4.min.u + /// public static Vector128 Min(Vector128 left, Vector128 right) => Min(left, right); + /// + /// i8x16.max.s + /// public static Vector128 Max(Vector128 left, Vector128 right) => Max(left, right); + /// + /// i8x16.max.u + /// public static Vector128 Max(Vector128 left, Vector128 right) => Max(left, right); + /// + /// i16x8.max.s + /// public static Vector128 Max(Vector128 left, Vector128 right) => Max(left, right); + /// + /// i16x8.max.u + /// public static Vector128 Max(Vector128 left, Vector128 right) => Max(left, right); + /// + /// i32x4.max.s + /// public static Vector128 Max(Vector128 left, Vector128 right) => Max(left, right); + /// + /// i32x4.max.u + /// public static Vector128 Max(Vector128 left, Vector128 right) => Max(left, right); + /// + /// i8x16.avgr.u + /// public static Vector128 AverageRounded(Vector128 left, Vector128 right) => AverageRounded(left, right); + /// + /// i16x8.avgr.u + /// public static Vector128 AverageRounded(Vector128 left, Vector128 right) => AverageRounded(left, right); + /// + /// i8x16.abs + /// public static Vector128 Abs(Vector128 value) => Abs(value); + /// + /// i16x8.abs + /// public static Vector128 Abs(Vector128 value) => Abs(value); + /// + /// i32x4.abs + /// public static Vector128 Abs(Vector128 value) => Abs(value); + /// + /// i64x2.abs + /// public static Vector128 Abs(Vector128 value) => Abs(value); + /// + /// i32x4.abs + /// public static Vector128 Abs(Vector128 value) => Abs(value); // Bit shifts