Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/mono/mono/mini/interp/interp-simd-intrins.def
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ INTERP_SIMD_INTRINSIC_P_PP (INTERP_SIMD_INTRINSIC_V128_R4_MULTIPLY, interp_v128_

INTERP_SIMD_INTRINSIC_P_PP (INTERP_SIMD_INTRINSIC_V128_R4_DIVISION, interp_v128_r4_op_division, 231)

INTERP_SIMD_INTRINSIC_P_P (INTERP_SIMD_INTRINSIC_V128_BITCAST, interp_v128_bitcast, -1)

INTERP_SIMD_INTRINSIC_P_P (INTERP_SIMD_INTRINSIC_V128_I1_NEGATION, interp_v128_i1_op_negation, 97)
INTERP_SIMD_INTRINSIC_P_P (INTERP_SIMD_INTRINSIC_V128_I2_NEGATION, interp_v128_i2_op_negation, 129)
INTERP_SIMD_INTRINSIC_P_P (INTERP_SIMD_INTRINSIC_V128_I4_NEGATION, interp_v128_i4_op_negation, 161)
Expand Down
7 changes: 7 additions & 0 deletions src/mono/mono/mini/interp/interp-simd.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ interp_v128_i4_all_bits_set (gpointer res)
memset (res, 0xff, SIZEOF_V128);
}

// Vector128<TTo> As<TFrom, TTo>(Vector128<TFrom> v1)
static void
interp_v128_bitcast (gpointer res, gpointer v1)
{
*(v128_i1*)res = *(v128_i1*)v1;
}

// op_Addition
static void
interp_v128_i1_op_addition (gpointer res, gpointer v1, gpointer v2)
Expand Down
13 changes: 13 additions & 0 deletions src/mono/mono/mini/interp/simd-methods.def
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,19 @@ SIMD_METHOD(op_UnaryNegation)
SIMD_METHOD(op_UnsignedRightShift)

SIMD_METHOD(AndNot)
SIMD_METHOD(As)
SIMD_METHOD(AsByte)
SIMD_METHOD(AsDouble)
SIMD_METHOD(AsInt16)
SIMD_METHOD(AsInt32)
SIMD_METHOD(AsInt64)
SIMD_METHOD(AsNInt)
SIMD_METHOD(AsNUInt)
SIMD_METHOD(AsSByte)
SIMD_METHOD(AsSingle)
SIMD_METHOD(AsUInt16)
SIMD_METHOD(AsUInt32)
SIMD_METHOD(AsUInt64)
SIMD_METHOD(ConditionalSelect)
SIMD_METHOD(Create)
SIMD_METHOD(CreateScalar)
Expand Down
68 changes: 68 additions & 0 deletions src/mono/mono/mini/interp/transform-simd.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,19 @@ lookup_intrins (guint16 *intrinsics, int size, MonoMethod *cmethod)
// i.e. all 'get_' and 'op_' need to come after regular title-case names
static guint16 sri_vector128_methods [] = {
SN_AndNot,
SN_As,
SN_AsByte,
SN_AsDouble,
SN_AsInt16,
SN_AsInt32,
SN_AsInt64,
SN_AsNInt,
SN_AsNUInt,
SN_AsSByte,
SN_AsSingle,
SN_AsUInt16,
SN_AsUInt32,
SN_AsUInt64,
SN_ConditionalSelect,
SN_Create,
SN_CreateScalar,
Expand Down Expand Up @@ -310,6 +323,42 @@ get_common_simd_info (MonoClass *vector_klass, MonoMethodSignature *csignature,
return TRUE;
}

static MonoType*
get_vector_t_elem_type (MonoType *vector_type)
{
MonoClass *klass;
MonoType *etype;

g_assert (vector_type->type == MONO_TYPE_GENERICINST);
klass = mono_class_from_mono_type_internal (vector_type);
g_assert (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also check the namespace?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We aren't doing so in simd-intrinsics.c, notably, but we could if desired.

I believe the expectation is that we're already only hitting this path for System.Runtime.Intrinsics or System.Numerics due to the higher level functions that can dispatch to these code paths.

!strcmp (m_class_get_name (klass), "Vector`1") ||
!strcmp (m_class_get_name (klass), "Vector64`1") ||
!strcmp (m_class_get_name (klass), "Vector128`1") ||
!strcmp (m_class_get_name (klass), "Vector256`1") ||
!strcmp (m_class_get_name (klass), "Vector512`1"));
etype = mono_class_get_context (klass)->class_inst->type_argv [0];
return etype;
}

static gboolean
is_element_type_primitive (MonoType *vector_type)
{
if (vector_type->type == MONO_TYPE_GENERICINST) {
MonoType *element_type = get_vector_t_elem_type (vector_type);
return MONO_TYPE_IS_VECTOR_PRIMITIVE (element_type);
} else {
MonoClass *klass = mono_class_from_mono_type_internal (vector_type);
g_assert (
!strcmp (m_class_get_name (klass), "Plane") ||
!strcmp (m_class_get_name (klass), "Quaternion") ||
!strcmp (m_class_get_name (klass), "Vector2") ||
!strcmp (m_class_get_name (klass), "Vector3") ||
!strcmp (m_class_get_name (klass), "Vector4"));
return TRUE;
}
}

static void
emit_common_simd_epilogue (TransformData *td, MonoClass *vector_klass, MonoMethodSignature *csignature, int vector_size, gboolean allow_void)
{
Expand Down Expand Up @@ -387,6 +436,25 @@ emit_sri_vector128 (TransformData *td, MonoMethod *cmethod, MonoMethodSignature
simd_opcode = MINT_SIMD_INTRINS_P_PP;
simd_intrins = INTERP_SIMD_INTRINSIC_V128_AND_NOT;
break;
case SN_As:
case SN_AsByte:
case SN_AsDouble:
case SN_AsInt16:
case SN_AsInt32:
case SN_AsInt64:
case SN_AsNInt:
case SN_AsNUInt:
case SN_AsSByte:
case SN_AsSingle:
case SN_AsUInt16:
case SN_AsUInt32:
case SN_AsUInt64: {
if (!is_element_type_primitive (csignature->ret) || !is_element_type_primitive (csignature->params [0]))
return FALSE;
simd_opcode = MINT_SIMD_INTRINS_P_P;
simd_intrins = INTERP_SIMD_INTRINSIC_V128_BITCAST;
break;
}
case SN_ConditionalSelect:
simd_opcode = MINT_SIMD_INTRINS_P_PPP;
simd_intrins = INTERP_SIMD_INTRINSIC_V128_CONDITIONAL_SELECT;
Expand Down
4 changes: 4 additions & 0 deletions src/mono/mono/mini/simd-intrinsics.c
Original file line number Diff line number Diff line change
Expand Up @@ -1185,6 +1185,8 @@ static guint16 sri_vector_methods [] = {
SN_AsInt16,
SN_AsInt32,
SN_AsInt64,
SN_AsNInt,
SN_AsNUInt,
SN_AsSByte,
SN_AsSingle,
SN_AsUInt16,
Expand Down Expand Up @@ -1618,6 +1620,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
case SN_AsInt16:
case SN_AsInt32:
case SN_AsInt64:
case SN_AsNInt:
case SN_AsNUInt:
case SN_AsSByte:
case SN_AsSingle:
case SN_AsUInt16:
Expand Down
2 changes: 2 additions & 0 deletions src/mono/mono/mini/simd-methods.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ METHOD(AsDouble)
METHOD(AsInt16)
METHOD(AsInt32)
METHOD(AsInt64)
METHOD(AsNInt)
METHOD(AsNUInt)
METHOD(AsSByte)
METHOD(AsSingle)
METHOD(AsUInt16)
Expand Down