diff --git a/src/mono/mono/mini/interp/simd-methods.def b/src/mono/mono/mini/interp/simd-methods.def index 6256c4ebca75c..a919c585114ed 100644 --- a/src/mono/mono/mini/interp/simd-methods.def +++ b/src/mono/mono/mini/interp/simd-methods.def @@ -31,11 +31,16 @@ SIMD_METHOD(AsInt32) SIMD_METHOD(AsInt64) SIMD_METHOD(AsNInt) SIMD_METHOD(AsNUInt) +SIMD_METHOD(AsPlane) +SIMD_METHOD(AsQuaternion) SIMD_METHOD(AsSByte) SIMD_METHOD(AsSingle) SIMD_METHOD(AsUInt16) SIMD_METHOD(AsUInt32) SIMD_METHOD(AsUInt64) +SIMD_METHOD(AsVector) +SIMD_METHOD(AsVector4) +SIMD_METHOD(AsVector128) SIMD_METHOD(ConditionalSelect) SIMD_METHOD(Create) SIMD_METHOD(CreateScalar) diff --git a/src/mono/mono/mini/interp/transform-simd.c b/src/mono/mono/mini/interp/transform-simd.c index 79f9e0c2970b5..2b64baff7f44a 100644 --- a/src/mono/mono/mini/interp/transform-simd.c +++ b/src/mono/mono/mini/interp/transform-simd.c @@ -64,11 +64,16 @@ static guint16 sri_vector128_methods [] = { SN_AsInt64, SN_AsNInt, SN_AsNUInt, + SN_AsPlane, + SN_AsQuaternion, SN_AsSByte, SN_AsSingle, SN_AsUInt16, SN_AsUInt32, SN_AsUInt64, + SN_AsVector, + SN_AsVector4, + SN_AsVector128, SN_ConditionalSelect, SN_Create, SN_CreateScalar, @@ -424,7 +429,13 @@ emit_sri_vector128 (TransformData *td, MonoMethod *cmethod, MonoMethodSignature gint16 simd_opcode = -1; gint16 simd_intrins = -1; - vector_klass = mono_class_from_mono_type_internal (csignature->ret); + if (csignature->ret->type == MONO_TYPE_GENERICINST) { + vector_klass = mono_class_from_mono_type_internal (csignature->ret); + } else if (csignature->params [0]->type == MONO_TYPE_GENERICINST) { + vector_klass = mono_class_from_mono_type_internal (csignature->params [0]); + } else { + return FALSE; + } MonoTypeEnum atype; int arg_size, scalar_arg; @@ -444,6 +455,8 @@ emit_sri_vector128 (TransformData *td, MonoMethod *cmethod, MonoMethodSignature case SN_AsInt64: case SN_AsNInt: case SN_AsNUInt: + case SN_AsPlane: + case SN_AsQuaternion: case SN_AsSByte: case SN_AsSingle: case SN_AsUInt16: @@ -455,6 +468,25 @@ emit_sri_vector128 (TransformData *td, MonoMethod *cmethod, MonoMethodSignature simd_intrins = INTERP_SIMD_INTRINSIC_V128_BITCAST; break; } + case SN_AsVector: + case SN_AsVector128: + case SN_AsVector4: { + if (!is_element_type_primitive (csignature->ret) || !is_element_type_primitive (csignature->params [0])) + return FALSE; + + MonoClass *ret_class = mono_class_from_mono_type_internal (csignature->ret); + int ret_size = mono_class_value_size (ret_class, NULL); + + MonoClass *arg_class = mono_class_from_mono_type_internal (csignature->params [0]); + int arg_size = mono_class_value_size (arg_class, NULL); + + if (arg_size == ret_size) { + simd_opcode = MINT_SIMD_INTRINS_P_P; + simd_intrins = INTERP_SIMD_INTRINSIC_V128_BITCAST; + break; + } + return FALSE; + } case SN_ConditionalSelect: simd_opcode = MINT_SIMD_INTRINS_P_PPP; simd_intrins = INTERP_SIMD_INTRINSIC_V128_CONDITIONAL_SELECT; diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index 4bbc0a09e0869..bcd4ae0639e92 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -1187,11 +1187,16 @@ static guint16 sri_vector_methods [] = { SN_AsInt64, SN_AsNInt, SN_AsNUInt, + SN_AsPlane, + SN_AsQuaternion, SN_AsSByte, SN_AsSingle, SN_AsUInt16, SN_AsUInt32, SN_AsUInt64, + SN_AsVector, + SN_AsVector128, + SN_AsVector4, SN_BitwiseAnd, SN_BitwiseOr, SN_Ceiling, @@ -1622,6 +1627,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi case SN_AsInt64: case SN_AsNInt: case SN_AsNUInt: + case SN_AsPlane: + case SN_AsQuaternion: case SN_AsSByte: case SN_AsSingle: case SN_AsUInt16: @@ -1631,6 +1638,23 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi return NULL; return emit_simd_ins (cfg, klass, OP_XCAST, args [0]->dreg, -1); } + case SN_AsVector: + case SN_AsVector128: + case SN_AsVector4: { + if (!is_element_type_primitive (fsig->ret) || !is_element_type_primitive (fsig->params [0])) + return NULL; + + MonoClass *ret_class = mono_class_from_mono_type_internal (fsig->ret); + int ret_size = mono_class_value_size (ret_class, NULL); + + MonoClass *arg_class = mono_class_from_mono_type_internal (fsig->params [0]); + int arg_size = mono_class_value_size (arg_class, NULL); + + if (arg_size == ret_size) + return emit_simd_ins (cfg, klass, OP_XCAST, args [0]->dreg, -1); + + return NULL; + } case SN_Ceiling: case SN_Floor: { if (!type_enum_is_float (arg0_type)) diff --git a/src/mono/mono/mini/simd-methods.h b/src/mono/mono/mini/simd-methods.h index fbf4098406819..071da07c9e5bf 100644 --- a/src/mono/mono/mini/simd-methods.h +++ b/src/mono/mono/mini/simd-methods.h @@ -73,11 +73,14 @@ METHOD(AsInt32) METHOD(AsInt64) METHOD(AsNInt) METHOD(AsNUInt) +METHOD(AsPlane) +METHOD(AsQuaternion) METHOD(AsSByte) METHOD(AsSingle) METHOD(AsUInt16) METHOD(AsUInt32) METHOD(AsUInt64) +METHOD(AsVector) METHOD(AsVector128) METHOD(AsVector2) METHOD(AsVector256)