diff --git a/src/mono/mono/mini/mini-llvm.c b/src/mono/mono/mini/mini-llvm.c
index 1d78c8dd81d825..0a17d60a2bf04a 100644
--- a/src/mono/mono/mini/mini-llvm.c
+++ b/src/mono/mono/mini/mini-llvm.c
@@ -7644,10 +7644,10 @@ MONO_RESTORE_WARNING
break;
}
#if defined(TARGET_ARM64) || defined(TARGET_WASM)
- case OP_FCVTL:
- case OP_FCVTL2: {
+ case OP_SIMD_FCVTL:
+ case OP_SIMD_FCVTL2: {
LLVMTypeRef ret_t = simd_class_to_llvm_type (ctx, ins->klass);
- gboolean high = ins->opcode == OP_FCVTL2;
+ gboolean high = ins->opcode == OP_SIMD_FCVTL2;
LLVMValueRef result = lhs;
if (high)
result = extract_high_elements (ctx, result);
@@ -7655,19 +7655,19 @@ MONO_RESTORE_WARNING
values [ins->dreg] = result;
break;
}
- case OP_SHL:
- case OP_SSHR:
- case OP_SSRA:
- case OP_USHR:
- case OP_USRA: {
+ case OP_SIMD_SHL:
+ case OP_SIMD_SSHR:
+ case OP_SIMD_SSRA:
+ case OP_SIMD_USHR:
+ case OP_SIMD_USRA: {
gboolean right = FALSE;
gboolean add = FALSE;
gboolean arith = FALSE;
switch (ins->opcode) {
- case OP_USHR: right = TRUE; break;
- case OP_USRA: right = TRUE; add = TRUE; break;
- case OP_SSHR: arith = TRUE; break;
- case OP_SSRA: arith = TRUE; add = TRUE; break;
+ case OP_SIMD_USHR: right = TRUE; break;
+ case OP_SIMD_USRA: right = TRUE; add = TRUE; break;
+ case OP_SIMD_SSHR: arith = TRUE; break;
+ case OP_SIMD_SSRA: arith = TRUE; add = TRUE; break;
}
LLVMValueRef shiftarg = lhs;
LLVMValueRef shift = rhs;
@@ -7688,16 +7688,16 @@ MONO_RESTORE_WARNING
values [ins->dreg] = result;
break;
}
- case OP_SSHLL:
- case OP_SSHLL2:
- case OP_USHLL:
- case OP_USHLL2: {
+ case OP_SIMD_SSHLL:
+ case OP_SIMD_SSHLL2:
+ case OP_SIMD_USHLL:
+ case OP_SIMD_USHLL2: {
LLVMTypeRef ret_t = simd_class_to_llvm_type (ctx, ins->klass);
gboolean high = FALSE;
gboolean is_unsigned = FALSE;
switch (ins->opcode) {
- case OP_SSHLL2: high = TRUE; break;
- case OP_USHLL2: high = TRUE; case OP_USHLL: is_unsigned = TRUE; break;
+ case OP_SIMD_SSHLL2: high = TRUE; break;
+ case OP_SIMD_USHLL2: high = TRUE; case OP_SIMD_USHLL: is_unsigned = TRUE; break;
}
LLVMValueRef result = lhs;
if (high)
diff --git a/src/mono/mono/mini/mini-ops.h b/src/mono/mono/mini/mini-ops.h
index 162711201ad142..0482a3ee68275b 100644
--- a/src/mono/mono/mini/mini-ops.h
+++ b/src/mono/mono/mini/mini-ops.h
@@ -1757,17 +1757,17 @@ MINI_OP3(OP_ARM64_SQRDMLSH_SCALAR, "arm64_sqrdmlsh_scalar", XREG, XREG, XREG, XR
#endif // TARGET_ARM64
-MINI_OP(OP_FCVTL, "convert_to_higher_precision", XREG, XREG, NONE)
-MINI_OP(OP_FCVTL2, "convert_to_higher_precision_2", XREG, XREG, NONE)
-MINI_OP(OP_USHLL, "unsigned_shift_left_long", XREG, XREG, IREG)
-MINI_OP(OP_USHLL2, "unsigned_shift_left_long_2", XREG, XREG, IREG)
-MINI_OP(OP_SSHLL, "signed_shift_left_long", XREG, XREG, IREG)
-MINI_OP(OP_SSHLL2, "signed_shift_left_long_2", XREG, XREG, IREG)
-MINI_OP(OP_SHL, "shl", XREG, XREG, IREG)
-MINI_OP(OP_SSHR, "sshr", XREG, XREG, IREG)
-MINI_OP(OP_USHR, "ushr", XREG, XREG, IREG)
-MINI_OP3(OP_USRA, "usra", XREG, XREG, XREG, IREG)
-MINI_OP3(OP_SSRA, "ssra", XREG, XREG, XREG, IREG)
+MINI_OP(OP_SIMD_FCVTL, "simd_convert_to_higher_precision", XREG, XREG, NONE)
+MINI_OP(OP_SIMD_FCVTL2, "simd_convert_to_higher_precision_2", XREG, XREG, NONE)
+MINI_OP(OP_SIMD_USHLL, "simd_unsigned_shift_left_long", XREG, XREG, IREG)
+MINI_OP(OP_SIMD_USHLL2, "simd_unsigned_shift_left_long_2", XREG, XREG, IREG)
+MINI_OP(OP_SIMD_SSHLL, "simd_signed_shift_left_long", XREG, XREG, IREG)
+MINI_OP(OP_SIMD_SSHLL2, "simd_signed_shift_left_long_2", XREG, XREG, IREG)
+MINI_OP(OP_SIMD_SHL, "simd_shl", XREG, XREG, IREG)
+MINI_OP(OP_SIMD_SSHR, "simd_sshr", XREG, XREG, IREG)
+MINI_OP(OP_SIMD_USHR, "simd_ushr", XREG, XREG, IREG)
+MINI_OP3(OP_SIMD_USRA, "simd_usra", XREG, XREG, XREG, IREG)
+MINI_OP3(OP_SIMD_SSRA, "simd_ssra", XREG, XREG, XREG, IREG)
#if defined(TARGET_WASM)
MINI_OP(OP_WASM_ONESCOMPLEMENT, "wasm_onescomplement", XREG, XREG, NONE)
diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c
index 633167c6335841..21e2b4c919450f 100644
--- a/src/mono/mono/mini/simd-intrinsics.c
+++ b/src/mono/mono/mini/simd-intrinsics.c
@@ -1856,11 +1856,11 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
int op = id == SN_WidenLower ? OP_XLOWER : OP_XUPPER;
MonoInst *lower_or_upper_half = emit_simd_ins_for_sig (cfg, klass, op, 0, arg0_type, fsig, args);
if (type_enum_is_float (arg0_type)) {
- return emit_simd_ins (cfg, klass, OP_FCVTL, lower_or_upper_half->dreg, -1);
+ return emit_simd_ins (cfg, klass, OP_SIMD_FCVTL, lower_or_upper_half->dreg, -1);
} else {
int zero = alloc_ireg (cfg);
MONO_EMIT_NEW_ICONST (cfg, zero, 0);
- op = type_enum_is_unsigned (arg0_type) ? OP_USHLL : OP_SSHLL;
+ op = type_enum_is_unsigned (arg0_type) ? OP_SIMD_USHLL : OP_SIMD_SSHLL;
return emit_simd_ins (cfg, klass, op, lower_or_upper_half->dreg, zero);
}
#else
@@ -2946,9 +2946,9 @@ static SimdIntrinsic advsimd_methods [] = {
{SN_CompareLessThanScalar, OP_XCOMPARE_SCALAR, CMP_LT, OP_XCOMPARE_SCALAR, CMP_LT_UN, OP_XCOMPARE_FP_SCALAR, CMP_LT},
{SN_CompareTest, OP_ARM64_CMTST},
{SN_CompareTestScalar, OP_ARM64_CMTST},
- {SN_ConvertToDouble, OP_CVT_SI_FP, None, OP_CVT_UI_FP, None, OP_FCVTL},
+ {SN_ConvertToDouble, OP_CVT_SI_FP, None, OP_CVT_UI_FP, None, OP_SIMD_FCVTL},
{SN_ConvertToDoubleScalar, OP_CVT_SI_FP_SCALAR, None, OP_CVT_UI_FP_SCALAR},
- {SN_ConvertToDoubleUpper, OP_FCVTL2},
+ {SN_ConvertToDoubleUpper, OP_SIMD_FCVTL2},
{SN_ConvertToInt32RoundAwayFromZero, OP_XOP_OVR_X_X, INTRINS_AARCH64_ADV_SIMD_FCVTAS},
{SN_ConvertToInt32RoundAwayFromZeroScalar, OP_XOP_OVR_SCALAR_X_X, INTRINS_AARCH64_ADV_SIMD_FCVTAS},
{SN_ConvertToInt32RoundToEven, OP_XOP_OVR_X_X, INTRINS_AARCH64_ADV_SIMD_FCVTNS},
@@ -3180,14 +3180,14 @@ static SimdIntrinsic advsimd_methods [] = {
{SN_ShiftArithmeticScalar, OP_XOP_OVR_X_X_X, INTRINS_AARCH64_ADV_SIMD_SSHL},
{SN_ShiftLeftAndInsert, OP_ARM64_SLI},
{SN_ShiftLeftAndInsertScalar, OP_ARM64_SLI},
- {SN_ShiftLeftLogical, OP_SHL},
+ {SN_ShiftLeftLogical, OP_SIMD_SHL},
{SN_ShiftLeftLogicalSaturate},
{SN_ShiftLeftLogicalSaturateScalar},
{SN_ShiftLeftLogicalSaturateUnsigned, OP_ARM64_SQSHLU},
{SN_ShiftLeftLogicalSaturateUnsignedScalar, OP_ARM64_SQSHLU_SCALAR},
- {SN_ShiftLeftLogicalScalar, OP_SHL},
- {SN_ShiftLeftLogicalWideningLower, OP_SSHLL, None, OP_USHLL},
- {SN_ShiftLeftLogicalWideningUpper, OP_SSHLL2, None, OP_USHLL2},
+ {SN_ShiftLeftLogicalScalar, OP_SIMD_SHL},
+ {SN_ShiftLeftLogicalWideningLower, OP_SIMD_SSHLL, None, OP_SIMD_USHLL},
+ {SN_ShiftLeftLogicalWideningUpper, OP_SIMD_SSHLL2, None, OP_SIMD_USHLL2},
{SN_ShiftLogical, OP_XOP_OVR_X_X_X, INTRINS_AARCH64_ADV_SIMD_USHL},
{SN_ShiftLogicalRounded, OP_XOP_OVR_X_X_X, INTRINS_AARCH64_ADV_SIMD_URSHL},
{SN_ShiftLogicalRoundedSaturate, OP_XOP_OVR_X_X_X, INTRINS_AARCH64_ADV_SIMD_UQRSHL},
@@ -3198,9 +3198,9 @@ static SimdIntrinsic advsimd_methods [] = {
{SN_ShiftLogicalScalar, OP_XOP_OVR_X_X_X, INTRINS_AARCH64_ADV_SIMD_USHL},
{SN_ShiftRightAndInsert, OP_ARM64_SRI},
{SN_ShiftRightAndInsertScalar, OP_ARM64_SRI},
- {SN_ShiftRightArithmetic, OP_SSHR},
- {SN_ShiftRightArithmeticAdd, OP_SSRA},
- {SN_ShiftRightArithmeticAddScalar, OP_SSRA},
+ {SN_ShiftRightArithmetic, OP_SIMD_SSHR},
+ {SN_ShiftRightArithmeticAdd, OP_SIMD_SSRA},
+ {SN_ShiftRightArithmeticAddScalar, OP_SIMD_SSRA},
{SN_ShiftRightArithmeticNarrowingSaturateLower, OP_ARM64_XNSHIFT, INTRINS_AARCH64_ADV_SIMD_SQSHRN},
{SN_ShiftRightArithmeticNarrowingSaturateScalar, OP_ARM64_XNSHIFT_SCALAR, INTRINS_AARCH64_ADV_SIMD_SQSHRN},
{SN_ShiftRightArithmeticNarrowingSaturateUnsignedLower, OP_ARM64_XNSHIFT, INTRINS_AARCH64_ADV_SIMD_SQSHRUN},
@@ -3217,10 +3217,10 @@ static SimdIntrinsic advsimd_methods [] = {
{SN_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper, OP_ARM64_XNSHIFT2, INTRINS_AARCH64_ADV_SIMD_SQRSHRUN},
{SN_ShiftRightArithmeticRoundedNarrowingSaturateUpper, OP_ARM64_XNSHIFT2, INTRINS_AARCH64_ADV_SIMD_SQRSHRN},
{SN_ShiftRightArithmeticRoundedScalar, OP_ARM64_SRSHR},
- {SN_ShiftRightArithmeticScalar, OP_SSHR},
- {SN_ShiftRightLogical, OP_USHR},
- {SN_ShiftRightLogicalAdd, OP_USRA},
- {SN_ShiftRightLogicalAddScalar, OP_USRA},
+ {SN_ShiftRightArithmeticScalar, OP_SIMD_SSHR},
+ {SN_ShiftRightLogical, OP_SIMD_USHR},
+ {SN_ShiftRightLogicalAdd, OP_SIMD_USRA},
+ {SN_ShiftRightLogicalAddScalar, OP_SIMD_USRA},
{SN_ShiftRightLogicalNarrowingLower, OP_ARM64_SHRN},
{SN_ShiftRightLogicalNarrowingSaturateLower, OP_ARM64_XNSHIFT, INTRINS_AARCH64_ADV_SIMD_UQSHRN},
{SN_ShiftRightLogicalNarrowingSaturateScalar, OP_ARM64_XNSHIFT_SCALAR, INTRINS_AARCH64_ADV_SIMD_UQSHRN},
@@ -3235,7 +3235,7 @@ static SimdIntrinsic advsimd_methods [] = {
{SN_ShiftRightLogicalRoundedNarrowingSaturateUpper, OP_ARM64_XNSHIFT2, INTRINS_AARCH64_ADV_SIMD_UQRSHRN},
{SN_ShiftRightLogicalRoundedNarrowingUpper, OP_ARM64_XNSHIFT2, INTRINS_AARCH64_ADV_SIMD_RSHRN},
{SN_ShiftRightLogicalRoundedScalar, OP_ARM64_URSHR},
- {SN_ShiftRightLogicalScalar, OP_USHR},
+ {SN_ShiftRightLogicalScalar, OP_SIMD_USHR},
{SN_SignExtendWideningLower, OP_ARM64_SXTL},
{SN_SignExtendWideningUpper, OP_ARM64_SXTL2},
{SN_Sqrt, OP_XOP_OVR_X_X, INTRINS_AARCH64_ADV_SIMD_FSQRT},
@@ -4707,24 +4707,24 @@ static SimdIntrinsic wasmbase_methods [] = {
static SimdIntrinsic packedsimd_methods [] = {
{SN_Add},
- {SN_And},
- {SN_Bitmask},
+ {SN_And, OP_XBINOP_FORCEINT, XBINOP_FORCEINT_AND},
+ {SN_Bitmask, OP_WASM_SIMD_BITMASK},
{SN_CompareEqual},
{SN_CompareNotEqual},
{SN_ConvertNarrowingSignedSaturate},
{SN_ConvertNarrowingUnsignedSaturate},
- {SN_Dot},
+ {SN_Dot, OP_XOP_X_X_X, INTRINS_WASM_DOT},
{SN_ExtractLane},
{SN_Multiply},
{SN_Negate},
{SN_ReplaceLane},
- {SN_ShiftLeft},
- {SN_ShiftRightArithmetic},
- {SN_ShiftRightLogical},
- {SN_Shuffle},
+ {SN_ShiftLeft, OP_SIMD_SHL},
+ {SN_ShiftRightArithmetic, OP_SIMD_SSHR},
+ {SN_ShiftRightLogical, OP_SIMD_USHR},
+ {SN_Shuffle, OP_WASM_SIMD_SHUFFLE},
{SN_Splat},
{SN_Subtract},
- {SN_Swizzle},
+ {SN_Swizzle, OP_WASM_SIMD_SWIZZLE},
{SN_get_IsSupported},
};
@@ -4796,6 +4796,9 @@ emit_wasm_supported_intrinsics (
id == SN_Splat && !MONO_TYPE_IS_VECTOR_PRIMITIVE(fsig->params [0]))
return NULL;
+ uint16_t op = info->default_op;
+ uint16_t c0 = info->default_instc0;
+
switch (id) {
case SN_Add:
case SN_Subtract:
@@ -4803,47 +4806,49 @@ emit_wasm_supported_intrinsics (
return emit_simd_ins_for_binary_op (cfg, klass, fsig, args, arg0_type, id);
case SN_Negate:
return emit_simd_ins_for_unary_op (cfg, klass, fsig, args, arg0_type, id);
- case SN_And:
- return emit_simd_ins_for_sig (cfg, klass, OP_XBINOP_FORCEINT, XBINOP_FORCEINT_AND, arg0_type, fsig, args);
- case SN_Bitmask:
- return emit_simd_ins_for_sig (cfg, klass, OP_WASM_SIMD_BITMASK, -1, -1, fsig, args);
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:
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;
+ op = OP_XOP_X_X_X;
+
switch (arg0_type) {
case MONO_TYPE_I2:
- intrins = INTRINS_WASM_NARROW_SIGNED_V16;
+ c0 = INTRINS_WASM_NARROW_SIGNED_V16;
break;
case MONO_TYPE_I4:
- intrins = INTRINS_WASM_NARROW_SIGNED_V8;
+ c0 = 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);
+
+ // continue with default emit
+ if (c0 != 0)
+ break;
return NULL;
}
case SN_ConvertNarrowingUnsignedSaturate: {
- int intrins = -1;
+ op = OP_XOP_X_X_X;
+
switch (arg0_type) {
case MONO_TYPE_I2:
- intrins = INTRINS_WASM_NARROW_UNSIGNED_V16;
+ c0 = INTRINS_WASM_NARROW_UNSIGNED_V16;
break;
case MONO_TYPE_I4:
- intrins = INTRINS_WASM_NARROW_UNSIGNED_V8;
+ c0 = 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);
+
+ // continue with default emit
+ if (c0 != 0)
+ break;
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);
+ op = type_to_xextract_op (arg0_type);
+ break;
}
case SN_ReplaceLane: {
int insert_op = type_to_xinsert_op (arg0_type);
@@ -4852,25 +4857,18 @@ emit_wasm_supported_intrinsics (
ins->inst_c1 = arg0_type;
return ins;
}
- case SN_ShiftLeft:
- return emit_simd_ins_for_sig (cfg, klass, OP_SHL, -1, -1, fsig, args);
- case SN_ShiftRightArithmetic:
- return emit_simd_ins_for_sig (cfg, klass, OP_SSHR, -1, -1, fsig, args);
- case SN_ShiftRightLogical:
- return emit_simd_ins_for_sig (cfg, klass, OP_USHR, -1, -1, fsig, args);
case SN_Splat: {
MonoType *etype = get_vector_t_elem_type (fsig->ret);
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_Dot:
- return emit_simd_ins_for_sig (cfg, klass, OP_XOP_X_X_X, INTRINS_WASM_DOT, -1, fsig, args);
- case SN_Shuffle:
- return emit_simd_ins_for_sig (cfg, klass, OP_WASM_SIMD_SHUFFLE, -1, -1, fsig, args);
- case SN_Swizzle:
- return emit_simd_ins_for_sig (cfg, klass, OP_WASM_SIMD_SWIZZLE, -1, -1, fsig, args);
}
+
+ // default emit path for cases with op set
+ if (op != 0)
+ return emit_simd_ins_for_sig (cfg, klass, op, c0, arg0_type, fsig, args);
}
+
g_assert_not_reached ();
return NULL;
diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets
index bf3a33b057d03c..ec442cd949babb 100644
--- a/src/mono/wasm/build/WasmApp.Native.targets
+++ b/src/mono/wasm/build/WasmApp.Native.targets
@@ -582,6 +582,7 @@
+