Skip to content

Commit e1d8614

Browse files
committed
Have mono handle the vector as APIs that grow or shrink the vector type
1 parent 6bfd058 commit e1d8614

7 files changed

+163
-6
lines changed

src/mono/mono/mini/interp/interp-internals.h

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#define MINT_STACK_ALIGNMENT (2 * MINT_STACK_SLOT_SIZE)
3232
#define MINT_SIMD_ALIGNMENT (MINT_STACK_ALIGNMENT)
3333
#define SIZEOF_V128 16
34+
#define SIZEOF_V2 8
35+
#define SIZEOF_V3 12
3436

3537
#define INTERP_STACK_SIZE (1024*1024)
3638
#define INTERP_REDZONE_SIZE (8*1024)

src/mono/mono/mini/interp/interp-simd-intrins.def

+6
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ INTERP_SIMD_INTRINSIC_P_PP (INTERP_SIMD_INTRINSIC_V128_R4_MULTIPLY, interp_v128_
7171
INTERP_SIMD_INTRINSIC_P_PP (INTERP_SIMD_INTRINSIC_V128_R4_DIVISION, interp_v128_r4_op_division, 231)
7272

7373
INTERP_SIMD_INTRINSIC_P_P (INTERP_SIMD_INTRINSIC_V128_BITCAST, interp_v128_bitcast, -1)
74+
INTERP_SIMD_INTRINSIC_P_P (INTERP_SIMD_INTRINSIC_V128_TO_V2, interp_v128_to_v2, -1)
75+
INTERP_SIMD_INTRINSIC_P_P (INTERP_SIMD_INTRINSIC_V128_TO_V3, interp_v128_to_v3, -1)
76+
INTERP_SIMD_INTRINSIC_P_P (INTERP_SIMD_INTRINSIC_V2_TO_V128, interp_v2_to_v128, -1)
77+
INTERP_SIMD_INTRINSIC_P_P (INTERP_SIMD_INTRINSIC_V2_TO_V3, interp_v2_to_v3, -1)
78+
INTERP_SIMD_INTRINSIC_P_P (INTERP_SIMD_INTRINSIC_V3_TO_V128, interp_v3_to_v128, -1)
79+
INTERP_SIMD_INTRINSIC_P_P (INTERP_SIMD_INTRINSIC_V3_TO_V2, interp_v3_to_v2, -1)
7480

7581
INTERP_SIMD_INTRINSIC_P_P (INTERP_SIMD_INTRINSIC_V128_I1_NEGATION, interp_v128_i1_op_negation, 97)
7682
INTERP_SIMD_INTRINSIC_P_P (INTERP_SIMD_INTRINSIC_V128_I2_NEGATION, interp_v128_i2_op_negation, 129)

src/mono/mono/mini/interp/interp-simd.c

+52
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,58 @@ interp_v128_bitcast (gpointer res, gpointer v1)
3535
*(v128_i1*)res = *(v128_i1*)v1;
3636
}
3737

38+
// Vector2 AsVector2(Vector128<float> v1)
39+
static void
40+
interp_v128_to_v2 (gpointer res, gpointer v1)
41+
{
42+
memcpy(res, v1, SIZEOF_V2);
43+
}
44+
45+
// Vector3 AsVector3(Vector128<float> v1)
46+
static void
47+
interp_v128_to_v3 (gpointer res, gpointer v1)
48+
{
49+
memcpy(res, v1, SIZEOF_V3);
50+
}
51+
52+
// Vector128<float> AsVector128(Vector2 v1)
53+
static void
54+
interp_v2_to_v128 (gpointer res, gpointer v1)
55+
{
56+
memcpy(res, v1, SIZEOF_V2);
57+
58+
guint32 *res_typed = (guint32*)res;
59+
res_typed [2] = 0;
60+
res_typed [3] = 0;
61+
}
62+
63+
// Vector3 AsVector3(Vector2 v1)
64+
static void
65+
interp_v2_to_v3 (gpointer res, gpointer v1)
66+
{
67+
memcpy(res, v1, SIZEOF_V2);
68+
69+
guint32 *res_typed = (guint32*)res;
70+
res_typed [2] = 0;
71+
}
72+
73+
// Vector128<float> AsVector128(Vector3 v1)
74+
static void
75+
interp_v3_to_v128 (gpointer res, gpointer v1)
76+
{
77+
memcpy(res, v1, SIZEOF_V3);
78+
79+
guint32 *res_typed = (guint32*)res;
80+
res_typed [3] = 0;
81+
}
82+
83+
// Vector2 AsVector128(Vector3 v1)
84+
static void
85+
interp_v3_to_v2 (gpointer res, gpointer v1)
86+
{
87+
memcpy(res, v1, SIZEOF_V2);
88+
}
89+
3890
// op_Addition
3991
static void
4092
interp_v128_i1_op_addition (gpointer res, gpointer v1, gpointer v2)

src/mono/mono/mini/interp/simd-methods.def

+4-1
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,11 @@ SIMD_METHOD(AsUInt16)
3939
SIMD_METHOD(AsUInt32)
4040
SIMD_METHOD(AsUInt64)
4141
SIMD_METHOD(AsVector)
42-
SIMD_METHOD(AsVector4)
4342
SIMD_METHOD(AsVector128)
43+
SIMD_METHOD(AsVector128Unsafe)
44+
SIMD_METHOD(AsVector2)
45+
SIMD_METHOD(AsVector3)
46+
SIMD_METHOD(AsVector4)
4447
SIMD_METHOD(ConditionalSelect)
4548
SIMD_METHOD(Create)
4649
SIMD_METHOD(CreateScalar)

src/mono/mono/mini/interp/transform-simd.c

+43-2
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,11 @@ static guint16 sri_vector128_methods [] = {
7272
SN_AsUInt32,
7373
SN_AsUInt64,
7474
SN_AsVector,
75-
SN_AsVector4,
7675
SN_AsVector128,
76+
SN_AsVector128Unsafe,
77+
SN_AsVector2,
78+
SN_AsVector3,
79+
SN_AsVector4,
7780
SN_ConditionalSelect,
7881
SN_Create,
7982
SN_CreateScalar,
@@ -470,6 +473,9 @@ emit_sri_vector128 (TransformData *td, MonoMethod *cmethod, MonoMethodSignature
470473
}
471474
case SN_AsVector:
472475
case SN_AsVector128:
476+
case SN_AsVector128Unsafe:
477+
case SN_AsVector2:
478+
case SN_AsVector3:
473479
case SN_AsVector4: {
474480
if (!is_element_type_primitive (csignature->ret) || !is_element_type_primitive (csignature->params [0]))
475481
return FALSE;
@@ -485,7 +491,42 @@ emit_sri_vector128 (TransformData *td, MonoMethod *cmethod, MonoMethodSignature
485491
simd_intrins = INTERP_SIMD_INTRINSIC_V128_BITCAST;
486492
break;
487493
}
488-
return FALSE;
494+
495+
if ((ret_size != 8) && (ret_size != 12) && (ret_size != 16)) {
496+
return FALSE;
497+
}
498+
499+
if ((arg_size != 8) && (arg_size != 12) && (arg_size != 16)) {
500+
return FALSE;
501+
}
502+
503+
if (arg_size > ret_size) {
504+
simd_opcode = MINT_SIMD_INTRINS_P_P;
505+
506+
if (ret_size == 8) {
507+
if (arg_size == 16) {
508+
simd_intrins = INTERP_SIMD_INTRINSIC_V128_TO_V2;
509+
} else {
510+
simd_intrins = INTERP_SIMD_INTRINSIC_V3_TO_V2;
511+
}
512+
} else {
513+
simd_intrins = INTERP_SIMD_INTRINSIC_V128_TO_V3;
514+
}
515+
break;
516+
} else {
517+
simd_opcode = MINT_SIMD_INTRINS_P_P;
518+
519+
if (arg_size == 8) {
520+
if (ret_size == 12) {
521+
simd_intrins = INTERP_SIMD_INTRINSIC_V2_TO_V3;
522+
} else {
523+
simd_intrins = INTERP_SIMD_INTRINSIC_V2_TO_V128;
524+
}
525+
} else {
526+
simd_intrins = INTERP_SIMD_INTRINSIC_V3_TO_V128;
527+
}
528+
break;
529+
}
489530
}
490531
case SN_ConditionalSelect:
491532
simd_opcode = MINT_SIMD_INTRINS_P_PPP;

src/mono/mono/mini/simd-intrinsics.c

+54-3
Original file line numberDiff line numberDiff line change
@@ -1196,6 +1196,9 @@ static guint16 sri_vector_methods [] = {
11961196
SN_AsUInt64,
11971197
SN_AsVector,
11981198
SN_AsVector128,
1199+
SN_AsVector128Unsafe,
1200+
SN_AsVector2,
1201+
SN_AsVector3,
11991202
SN_AsVector4,
12001203
SN_BitwiseAnd,
12011204
SN_BitwiseOr,
@@ -1640,7 +1643,11 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
16401643
}
16411644
case SN_AsVector:
16421645
case SN_AsVector128:
1643-
case SN_AsVector4: {
1646+
case SN_AsVector128Unsafe:
1647+
case SN_AsVector2:
1648+
case SN_AsVector3:
1649+
case SN_AsVector4:
1650+
case SN_AsVector4Unsafe: {
16441651
if (!is_element_type_primitive (fsig->ret) || !is_element_type_primitive (fsig->params [0]))
16451652
return NULL;
16461653

@@ -1650,10 +1657,54 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
16501657
MonoClass *arg_class = mono_class_from_mono_type_internal (fsig->params [0]);
16511658
int arg_size = mono_class_value_size (arg_class, NULL);
16521659

1653-
if (arg_size == ret_size)
1660+
if (arg_size == ret_size) {
16541661
return emit_simd_ins (cfg, klass, OP_XCAST, args [0]->dreg, -1);
1662+
}
16551663

1656-
return NULL;
1664+
if ((ret_size != 8) && (ret_size != 12) && (ret_size != 16)) {
1665+
return NULL;
1666+
}
1667+
1668+
if ((arg_size != 8) && (arg_size != 12) && (arg_size != 16)) {
1669+
return NULL;
1670+
}
1671+
1672+
bool isUnsafe = (id == SN_AsVector128Unsafe) || (id == SN_AsVector4Unsafe);
1673+
1674+
if (arg_size > ret_size) {
1675+
#ifdef TARGET_ARM64
1676+
if (ret_size == 8) {
1677+
return emit_simd_ins_for_sig (cfg, klass, OP_XLOWER, 0, arg0_type, fsig, args);
1678+
}
1679+
#endif
1680+
return emit_simd_ins (cfg, klass, OP_XCAST, args [0]->dreg, -1);
1681+
} else {
1682+
#ifdef TARGET_ARM64
1683+
if (arg_size == 8) {
1684+
int op = isUnsafe ? OP_XWIDEN : OP_XWIDEN_UNSAFE;
1685+
return emit_simd_ins_for_sig (cfg, klass, op, 0, arg0_type, fsig, args);
1686+
}
1687+
#endif
1688+
MonoInst *ins = args [0];
1689+
1690+
if (!isUnsafe) {
1691+
static float r4_0 = 0;
1692+
MonoInst *zero;
1693+
int zero_dreg = alloc_freg (cfg);
1694+
MONO_INST_NEW (cfg, zero, OP_R4CONST);
1695+
zero->inst_p0 = (void*)&r4_0;
1696+
zero->dreg = zero_dreg;
1697+
MONO_ADD_INS (cfg->cbb, zero);
1698+
1699+
if (arg_size == 8) {
1700+
ins = emit_vector_insert_element (cfg, klass, ins, MONO_TYPE_R4, zero, 2, FALSE);
1701+
}
1702+
if (ret_size == 16) {
1703+
ins = emit_vector_insert_element (cfg, klass, ins, MONO_TYPE_R4, zero, 3, FALSE);
1704+
}
1705+
}
1706+
return emit_simd_ins (cfg, klass, OP_XCAST, ins->dreg, -1);
1707+
}
16571708
}
16581709
case SN_Ceiling:
16591710
case SN_Floor: {

src/mono/mono/mini/simd-methods.h

+2
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,12 @@ METHOD(AsUInt32)
8282
METHOD(AsUInt64)
8383
METHOD(AsVector)
8484
METHOD(AsVector128)
85+
METHOD(AsVector128Unsafe)
8586
METHOD(AsVector2)
8687
METHOD(AsVector256)
8788
METHOD(AsVector3)
8889
METHOD(AsVector4)
90+
METHOD(AsVector4Unsafe)
8991
METHOD(BitwiseAnd)
9092
METHOD(BitwiseOr)
9193
METHOD(Create)

0 commit comments

Comments
 (0)