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(); }
+
+ public static Vector128<short> SignExtendWideningLower(Vector128<sbyte> value) { throw new PlatformNotSupportedException(); }
+ public static Vector128<ushort> SignExtendWideningLower(Vector128<byte> value) { throw new PlatformNotSupportedException(); }
+ public static Vector128<int> SignExtendWideningLower(Vector128<short> value) { throw new PlatformNotSupportedException(); }
+ public static Vector128<uint> SignExtendWideningLower(Vector128<ushort> value) { throw new PlatformNotSupportedException(); }
+ public static Vector128<long> SignExtendWideningLower(Vector128<int> value) { throw new PlatformNotSupportedException(); }
+ public static Vector128<ulong> SignExtendWideningLower(Vector128<uint> value) { throw new PlatformNotSupportedException(); }
+
+ public static Vector128<short> SignExtendWideningUpper(Vector128<sbyte> value) { throw new PlatformNotSupportedException(); }
+ public static Vector128<ushort> SignExtendWideningUpper(Vector128<byte> value) { throw new PlatformNotSupportedException(); }
+ public static Vector128<int> SignExtendWideningUpper(Vector128<short> value) { throw new PlatformNotSupportedException(); }
+ public static Vector128<uint> SignExtendWideningUpper(Vector128<ushort> value) { throw new PlatformNotSupportedException(); }
+ public static Vector128<long> SignExtendWideningUpper(Vector128<int> value) { throw new PlatformNotSupportedException(); }
+ public static Vector128<ulong> SignExtendWideningUpper(Vector128<uint> value) { throw new PlatformNotSupportedException(); }
+
+ public static Vector128<short> ZeroExtendWideningLower(Vector128<sbyte> value) { throw new PlatformNotSupportedException(); }
+ public static Vector128<ushort> ZeroExtendWideningLower(Vector128<byte> value) { throw new PlatformNotSupportedException(); }
+ public static Vector128<int> ZeroExtendWideningLower(Vector128<short> value) { throw new PlatformNotSupportedException(); }
+ public static Vector128<uint> ZeroExtendWideningLower(Vector128<ushort> value) { throw new PlatformNotSupportedException(); }
+ public static Vector128<long> ZeroExtendWideningLower(Vector128<int> value) { throw new PlatformNotSupportedException(); }
+ public static Vector128<ulong> ZeroExtendWideningLower(Vector128<uint> value) { throw new PlatformNotSupportedException(); }
+
+ public static Vector128<short> ZeroExtendWideningUpper(Vector128<sbyte> value) { throw new PlatformNotSupportedException(); }
+ public static Vector128<ushort> ZeroExtendWideningUpper(Vector128<byte> value) { throw new PlatformNotSupportedException(); }
+ public static Vector128<int> ZeroExtendWideningUpper(Vector128<short> value) { throw new PlatformNotSupportedException(); }
+ public static Vector128<uint> ZeroExtendWideningUpper(Vector128<ushort> value) { throw new PlatformNotSupportedException(); }
+ public static Vector128<long> ZeroExtendWideningUpper(Vector128<int> value) { throw new PlatformNotSupportedException(); }
+ public static Vector128<ulong> ZeroExtendWideningUpper(Vector128<uint> value) { throw new PlatformNotSupportedException(); }
}
}
/// </summary>
[Intrinsic]
internal static Vector128<ushort> ConvertNarrowingUnsignedSaturate(Vector128<int> lower, Vector128<int> upper) => ConvertNarrowingUnsignedSaturate(lower, upper);
+
+ /// <summary>
+ /// i16x8.extend_low_i8x16_s
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<short> SignExtendWideningLower(Vector128<sbyte> value) => SignExtendWideningLower(value);
+ /// <summary>
+ /// i16x8.extend_low_i8x16_s
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<ushort> SignExtendWideningLower(Vector128<byte> value) => SignExtendWideningLower(value);
+ /// <summary>
+ /// i32x4.extend_low_i16x8_s
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<int> SignExtendWideningLower(Vector128<short> value) => SignExtendWideningLower(value);
+ /// <summary>
+ /// i32x4.extend_low_i16x8_s
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<uint> SignExtendWideningLower(Vector128<ushort> value) => SignExtendWideningLower(value);
+ /// <summary>
+ /// i64x2.extend_low_i32x4_s
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<long> SignExtendWideningLower(Vector128<int> value) => SignExtendWideningLower(value);
+ /// <summary>
+ /// i64x2.extend_low_i32x4_s
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<ulong> SignExtendWideningLower(Vector128<uint> value) => SignExtendWideningLower(value);
+
+ /// <summary>
+ /// i16x8.extend_high_i8x16_s
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<short> SignExtendWideningUpper(Vector128<sbyte> value) => SignExtendWideningUpper(value);
+ /// <summary>
+ /// i16x8.extend_high_i8x16_s
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<ushort> SignExtendWideningUpper(Vector128<byte> value) => SignExtendWideningUpper(value);
+ /// <summary>
+ /// i32x4.extend_high_i16x8_s
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<int> SignExtendWideningUpper(Vector128<short> value) => SignExtendWideningUpper(value);
+ /// <summary>
+ /// i32x4.extend_high_i16x8_s
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<uint> SignExtendWideningUpper(Vector128<ushort> value) => SignExtendWideningUpper(value);
+ /// <summary>
+ /// i64x2.extend_high_i32x4_s
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<long> SignExtendWideningUpper(Vector128<int> value) => SignExtendWideningUpper(value);
+ /// <summary>
+ /// i64x2.extend_high_i32x4_s
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<ulong> SignExtendWideningUpper(Vector128<uint> value) => SignExtendWideningUpper(value);
+
+ /// <summary>
+ /// i16x8.extend_low_i8x16_u
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<short> ZeroExtendWideningLower(Vector128<sbyte> value) => ZeroExtendWideningLower(value);
+ /// <summary>
+ /// i16x8.extend_low_i8x16_u
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<ushort> ZeroExtendWideningLower(Vector128<byte> value) => ZeroExtendWideningLower(value);
+ /// <summary>
+ /// i32x4.extend_low_i16x8_u
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<int> ZeroExtendWideningLower(Vector128<short> value) => ZeroExtendWideningLower(value);
+ /// <summary>
+ /// i32x4.extend_low_i16x8_u
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<uint> ZeroExtendWideningLower(Vector128<ushort> value) => ZeroExtendWideningLower(value);
+ /// <summary>
+ /// i64x2.extend_low_i32x4_u
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<long> ZeroExtendWideningLower(Vector128<int> value) => ZeroExtendWideningLower(value);
+ /// <summary>
+ /// i64x2.extend_low_i32x4_u
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<ulong> ZeroExtendWideningLower(Vector128<uint> value) => ZeroExtendWideningLower(value);
+
+ /// <summary>
+ /// i16x8.extend_high_i8x16_u
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<short> ZeroExtendWideningUpper(Vector128<sbyte> value) => ZeroExtendWideningUpper(value);
+ /// <summary>
+ /// i16x8.extend_high_i8x16_u
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<ushort> ZeroExtendWideningUpper(Vector128<byte> value) => ZeroExtendWideningUpper(value);
+ /// <summary>
+ /// i32x4.extend_high_i16x8_u
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<int> ZeroExtendWideningUpper(Vector128<short> value) => ZeroExtendWideningUpper(value);
+ /// <summary>
+ /// i32x4.extend_high_i16x8_u
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<uint> ZeroExtendWideningUpper(Vector128<ushort> value) => ZeroExtendWideningUpper(value);
+ /// <summary>
+ /// i64x2.extend_high_i32x4_u
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<long> ZeroExtendWideningUpper(Vector128<int> value) => ZeroExtendWideningUpper(value);
+ /// <summary>
+ /// i64x2.extend_high_i32x4_u
+ /// </summary>
+ [Intrinsic]
+ public static Vector128<ulong> ZeroExtendWideningUpper(Vector128<uint> value) => ZeroExtendWideningUpper(value);
}
}
public static Vector128<double> ConvertToDoubleLower(Vector128<float> value) { throw null; }
public static Vector128<int> ConvertToInt32Saturate(Vector128<float> value) { throw null; }
public static Vector128<int> ConvertToInt32Saturate(Vector128<double> value) { throw null; }
+ public static Vector128<short> SignExtendWideningLower(Vector128<sbyte> value) { throw null; }
+ public static Vector128<ushort> SignExtendWideningLower(Vector128<byte> value) { throw null; }
+ public static Vector128<int> SignExtendWideningLower(Vector128<short> value) { throw null; }
+ public static Vector128<uint> SignExtendWideningLower(Vector128<ushort> value) { throw null; }
+ public static Vector128<long> SignExtendWideningLower(Vector128<int> value) { throw null; }
+ public static Vector128<ulong> SignExtendWideningLower(Vector128<uint> value) { throw null; }
+ public static Vector128<short> SignExtendWideningUpper(Vector128<sbyte> value) { throw null; }
+ public static Vector128<ushort> SignExtendWideningUpper(Vector128<byte> value) { throw null; }
+ public static Vector128<int> SignExtendWideningUpper(Vector128<short> value) { throw null; }
+ public static Vector128<uint> SignExtendWideningUpper(Vector128<ushort> value) { throw null; }
+ public static Vector128<long> SignExtendWideningUpper(Vector128<int> value) { throw null; }
+ public static Vector128<ulong> SignExtendWideningUpper(Vector128<uint> value) { throw null; }
+ public static Vector128<short> ZeroExtendWideningLower(Vector128<sbyte> value) { throw null; }
+ public static Vector128<ushort> ZeroExtendWideningLower(Vector128<byte> value) { throw null; }
+ public static Vector128<int> ZeroExtendWideningLower(Vector128<short> value) { throw null; }
+ public static Vector128<uint> ZeroExtendWideningLower(Vector128<ushort> value) { throw null; }
+ public static Vector128<long> ZeroExtendWideningLower(Vector128<int> value) { throw null; }
+ public static Vector128<ulong> ZeroExtendWideningLower(Vector128<uint> value) { throw null; }
+ public static Vector128<short> ZeroExtendWideningUpper(Vector128<sbyte> value) { throw null; }
+ public static Vector128<ushort> ZeroExtendWideningUpper(Vector128<byte> value) { throw null; }
+ public static Vector128<int> ZeroExtendWideningUpper(Vector128<short> value) { throw null; }
+ public static Vector128<uint> ZeroExtendWideningUpper(Vector128<ushort> value) { throw null; }
+ public static Vector128<long> ZeroExtendWideningUpper(Vector128<int> value) { throw null; }
+ public static Vector128<ulong> ZeroExtendWideningUpper(Vector128<uint> value) { throw null; }
}
}
return extract_half_elements (ctx, src_vec, FALSE);
}
+static G_GNUC_UNUSED LLVMTypeRef extended_type (LLVMTypeRef src_t)
+{
+ int nelems = LLVMGetVectorSize (src_t) / 2;
+ unsigned int width = mono_llvm_get_prim_size_bits (LLVMGetElementType(src_t));
+ LLVMTypeRef int_t = LLVMIntType (width * 2);
+ return LLVMVectorType (int_t, nelems);
+}
+
static LLVMValueRef
keep_lowest_element (EmitContext *ctx, LLVMTypeRef dst_t, LLVMValueRef vec)
{
}
#endif
#if defined(TARGET_WASM)
+ case OP_WASM_SIMD_SEXT_LOWER:
+ case OP_WASM_SIMD_SEXT_UPPER:
+ case OP_WASM_SIMD_ZEXT_LOWER:
+ case OP_WASM_SIMD_ZEXT_UPPER: {
+ LLVMTypeRef ret_t = extended_type (LLVMTypeOf (lhs));
+ gboolean upper = (ins->opcode == OP_WASM_SIMD_SEXT_UPPER || ins->opcode == OP_WASM_SIMD_ZEXT_UPPER);
+ gboolean sext = (ins->opcode == OP_WASM_SIMD_SEXT_LOWER || ins->opcode == OP_WASM_SIMD_SEXT_UPPER);
+ LLVMValueRef ext = upper ? extract_high_elements (ctx, lhs) : extract_low_elements (ctx, lhs);
+ values [ins->dreg] = sext ? LLVMBuildSExt (builder, ext, ret_t, "") : LLVMBuildZExt (builder, ext, ret_t, "");
+ break;
+ }
case OP_WASM_SIMD_CONV_R8_TO_R4: {
LLVMValueRef val = LLVMBuildFPTrunc (builder, lhs, v64_r4_t, "");
values [ins->dreg] = LLVMBuildShuffleVector (builder, val, LLVMConstNull(v64_r4_t), create_const_vector_4_i32 (0, 1, 2, 3), "");
case OP_WASM_EXTMUL_UPPER_U:
case OP_WASM_EXTMUL_LOWER:
case OP_WASM_EXTMUL_UPPER: {
- LLVMTypeRef src_t = LLVMTypeOf (lhs);
- int nelems = LLVMGetVectorSize (src_t) / 2;
- unsigned int width = mono_llvm_get_prim_size_bits (LLVMGetElementType(src_t));
- LLVMTypeRef int_t = LLVMIntType (width * 2);
- LLVMTypeRef ret_t = LLVMVectorType (int_t, nelems);
+ LLVMTypeRef ret_t = extended_type (LLVMTypeOf (lhs));
int lower = ins->opcode == OP_WASM_EXTMUL_LOWER || ins->opcode == OP_WASM_EXTMUL_LOWER_U;
gboolean is_unsigned = ins->opcode == OP_WASM_EXTMUL_LOWER_U || ins->opcode == OP_WASM_EXTMUL_UPPER_U;
LLVMValueRef part1 = lower ? extract_low_elements (ctx, lhs) : extract_high_elements(ctx, lhs);
MINI_OP(OP_WASM_SIMD_CONV_R8_TO_R4, "wasm_simd_conv_r8_to_r4", XREG, XREG, NONE)
MINI_OP(OP_WASM_SIMD_CONV_R8_TO_I4_ZERO, "wasm_simd_conv_r8_to_i4_zero", XREG, XREG, NONE)
MINI_OP(OP_WASM_SIMD_CONV_U4_TO_R8_LOW, "wasm_simd_conv_u4_to_r8_low", XREG, XREG, NONE)
+MINI_OP(OP_WASM_SIMD_SEXT_LOWER, "wasm_simd_ext_lower_s", XREG, XREG, NONE)
+MINI_OP(OP_WASM_SIMD_SEXT_UPPER, "wasm_simd_ext_upper_s", XREG, XREG, NONE)
+MINI_OP(OP_WASM_SIMD_ZEXT_LOWER, "wasm_simd_ext_lower_u", XREG, XREG, NONE)
+MINI_OP(OP_WASM_SIMD_ZEXT_UPPER, "wasm_simd_ext_upper_u", XREG, XREG, NONE)
#endif
#if defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_WASM)
{SN_ShiftRightArithmetic, OP_SIMD_SSHR},
{SN_ShiftRightLogical, OP_SIMD_USHR},
{SN_Shuffle, OP_WASM_SIMD_SHUFFLE},
+ {SN_SignExtendWideningLower, OP_WASM_SIMD_SEXT_LOWER},
+ {SN_SignExtendWideningUpper, OP_WASM_SIMD_SEXT_UPPER},
{SN_Splat},
{SN_Sqrt},
{SN_Subtract},
{SN_Swizzle, OP_WASM_SIMD_SWIZZLE},
{SN_Truncate, OP_XOP_OVR_X_X, INTRINS_SIMD_TRUNC},
{SN_Xor, OP_XBINOP_FORCEINT, XBINOP_FORCEINT_XOR},
+ {SN_ZeroExtendWideningLower, OP_WASM_SIMD_ZEXT_LOWER},
+ {SN_ZeroExtendWideningUpper, OP_WASM_SIMD_ZEXT_UPPER},
{SN_get_IsSupported},
};