Skip to content

Commit

Permalink
Have mono handle the vector as APIs that grow or shrink the vector type
Browse files Browse the repository at this point in the history
  • Loading branch information
tannergooding committed Jul 4, 2024
1 parent 6bfd058 commit 72c830d
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 6 deletions.
6 changes: 6 additions & 0 deletions src/mono/mono/mini/interp/interp-simd-intrins.def
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ 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_TO_V2, interp_v128_to_v2, -1)
INTERP_SIMD_INTRINSIC_P_P (INTERP_SIMD_INTRINSIC_V128_TO_V3, interp_v128_to_v3, -1)
INTERP_SIMD_INTRINSIC_P_P (INTERP_SIMD_INTRINSIC_V2_TO_V128, interp_v2_to_v128, -1)
INTERP_SIMD_INTRINSIC_P_P (INTERP_SIMD_INTRINSIC_V2_TO_V3, interp_v2_to_v3, -1)
INTERP_SIMD_INTRINSIC_P_P (INTERP_SIMD_INTRINSIC_V3_TO_V128, interp_v3_to_v128, -1)
INTERP_SIMD_INTRINSIC_P_P (INTERP_SIMD_INTRINSIC_V3_TO_V2, interp_v3_to_v2, -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)
Expand Down
52 changes: 52 additions & 0 deletions src/mono/mono/mini/interp/interp-simd.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,58 @@ interp_v128_bitcast (gpointer res, gpointer v1)
*(v128_i1*)res = *(v128_i1*)v1;
}

// Vector2 AsVector2(Vector128<float> v1)
static void
interp_v128_to_v2 (gpointer res, gpointer v1)
{
memcpy(res, v1, SIZEOF_V2);
}

// Vector3 AsVector3(Vector128<float> v1)
static void
interp_v128_to_v3 (gpointer res, gpointer v1)
{
memcpy(res, v1, SIZEOF_V3);
}

// Vector128<float> AsVector128(Vector2 v1)
static void
interp_v2_to_v128 (gpointer res, gpointer v1)
{
memcpy(res, v1, SIZEOF_V2);

guint32 *res_typed = (guint32*)res;
res_typed [2] = 0;
res_typed [3] = 0;
}

// Vector3 AsVector3(Vector2 v1)
static void
interp_v2_to_v3 (gpointer res, gpointer v1)
{
memcpy(res, v1, SIZEOF_V2);

guint32 *res_typed = (guint32*)res;
res_typed [2] = 0;
}

// Vector128<float> AsVector128(Vector3 v1)
static void
interp_v3_to_v128 (gpointer res, gpointer v1)
{
memcpy(res, v1, SIZEOF_V3);

guint32 *res_typed = (guint32*)res;
res_typed [3] = 0;
}

// Vector2 AsVector128(Vector3 v1)
static void
interp_v3_to_v2 (gpointer res, gpointer v1)
{
memcpy(res, v1, SIZEOF_V2);
}

// op_Addition
static void
interp_v128_i1_op_addition (gpointer res, gpointer v1, gpointer v2)
Expand Down
5 changes: 4 additions & 1 deletion src/mono/mono/mini/interp/simd-methods.def
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,11 @@ SIMD_METHOD(AsUInt16)
SIMD_METHOD(AsUInt32)
SIMD_METHOD(AsUInt64)
SIMD_METHOD(AsVector)
SIMD_METHOD(AsVector4)
SIMD_METHOD(AsVector128)
SIMD_METHOD(AsVector128Unsafe)
SIMD_METHOD(AsVector2)
SIMD_METHOD(AsVector3)
SIMD_METHOD(AsVector4)
SIMD_METHOD(ConditionalSelect)
SIMD_METHOD(Create)
SIMD_METHOD(CreateScalar)
Expand Down
45 changes: 43 additions & 2 deletions src/mono/mono/mini/interp/transform-simd.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,11 @@ static guint16 sri_vector128_methods [] = {
SN_AsUInt32,
SN_AsUInt64,
SN_AsVector,
SN_AsVector4,
SN_AsVector128,
SN_AsVector128Unsafe,
SN_AsVector2,
SN_AsVector3,
SN_AsVector4,
SN_ConditionalSelect,
SN_Create,
SN_CreateScalar,
Expand Down Expand Up @@ -470,6 +473,9 @@ emit_sri_vector128 (TransformData *td, MonoMethod *cmethod, MonoMethodSignature
}
case SN_AsVector:
case SN_AsVector128:
case SN_AsVector128Unsafe:
case SN_AsVector2:
case SN_AsVector3:
case SN_AsVector4: {
if (!is_element_type_primitive (csignature->ret) || !is_element_type_primitive (csignature->params [0]))
return FALSE;
Expand All @@ -485,7 +491,42 @@ emit_sri_vector128 (TransformData *td, MonoMethod *cmethod, MonoMethodSignature
simd_intrins = INTERP_SIMD_INTRINSIC_V128_BITCAST;
break;
}
return FALSE;

if ((ret_size != 8) && (ret_size != 12) && (ret_size != 16)) {
return FALSE;
}

if ((arg_size != 8) && (arg_size != 12) && (arg_size != 16)) {
return FALSE;
}

if (arg_size > ret_size) {
simd_opcode = MINT_SIMD_INTRINS_P_P;

if (ret_size == 8) {
if (arg_size == 16) {
simd_intrins = INTERP_SIMD_INTRINSIC_V128_TO_V2;
} else {
simd_intrins = INTERP_SIMD_INTRINSIC_V3_TO_V2;
}
} else {
simd_intrins = INTERP_SIMD_INTRINSIC_V128_TO_V3;
}
break;
} else {
simd_opcode = MINT_SIMD_INTRINS_P_P;

if (arg_size == 8) {
if (ret_size == 12) {
simd_intrins = INTERP_SIMD_INTRINSIC_V2_TO_V3;
} else {
simd_intrins = INTERP_SIMD_INTRINSIC_V2_TO_V128;
}
} else {
simd_intrins = INTERP_SIMD_INTRINSIC_V3_TO_V128;
}
break;
}
}
case SN_ConditionalSelect:
simd_opcode = MINT_SIMD_INTRINS_P_PPP;
Expand Down
50 changes: 47 additions & 3 deletions src/mono/mono/mini/simd-intrinsics.c
Original file line number Diff line number Diff line change
Expand Up @@ -1196,6 +1196,9 @@ static guint16 sri_vector_methods [] = {
SN_AsUInt64,
SN_AsVector,
SN_AsVector128,
SN_AsVector128Unsafe,
SN_AsVector2,
SN_AsVector3,
SN_AsVector4,
SN_BitwiseAnd,
SN_BitwiseOr,
Expand Down Expand Up @@ -1640,7 +1643,11 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
}
case SN_AsVector:
case SN_AsVector128:
case SN_AsVector4: {
case SN_AsVector128Unsafe:
case SN_AsVector2:
case SN_AsVector3:
case SN_AsVector4:
case SN_AsVector4Unsafe: {
if (!is_element_type_primitive (fsig->ret) || !is_element_type_primitive (fsig->params [0]))
return NULL;

Expand All @@ -1650,10 +1657,47 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
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)
if (arg_size == ret_size) {
return emit_simd_ins (cfg, klass, OP_XCAST, args [0]->dreg, -1);
}

return NULL;
if ((ret_size != 8) && (ret_size != 12) && (ret_size != 16)) {
return NULL;
}

if ((arg_size != 8) && (arg_size != 12) && (arg_size != 16)) {
return NULL;
}

bool isUnsafe = (id == SN_AsVector128Unsafe) || (id == SN_AsVector4Unsafe);

if (arg_size > ret_size) {
#ifdef TARGET_ARM64
if (ret_size == 8) {
return emit_simd_ins_for_sig (cfg, klass, OP_XLOWER, 0, arg0_type, fsig, args);
}
#endif
return emit_simd_ins (cfg, klass, OP_XCAST, args [0]->dreg, -1);
} else {
#ifdef TARGET_ARM64
if (arg_size == 8) {
int op = isUnsafe ? OP_XWIDEN : OP_XWIDEN_UNSAFE;
return emit_simd_ins_for_sig (cfg, klass, op, 0, arg0_type, fsig, args);
}
#endif
MonoInst *ins = args [0];

if (!isUnsafe) {
MonoInst *zero = emit_xzero (cfg, klass);
if (arg_size == 8) {
ins = emit_vector_insert_element (cfg, klass, ins, MONO_TYPE_R4, zero, 2, FALSE);
}
if (ret_size == 16) {
ins = emit_vector_insert_element (cfg, klass, ins, MONO_TYPE_R4, zero, 3, FALSE);
}
}
return emit_simd_ins (cfg, klass, OP_XCAST, ins->dreg, -1);
}
}
case SN_Ceiling:
case SN_Floor: {
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 @@ -82,10 +82,12 @@ METHOD(AsUInt32)
METHOD(AsUInt64)
METHOD(AsVector)
METHOD(AsVector128)
METHOD(AsVector128Unsafe)
METHOD(AsVector2)
METHOD(AsVector256)
METHOD(AsVector3)
METHOD(AsVector4)
METHOD(AsVector4Unsafe)
METHOD(BitwiseAnd)
METHOD(BitwiseOr)
METHOD(Create)
Expand Down

0 comments on commit 72c830d

Please sign in to comment.