@@ -306,6 +306,19 @@ emit_simd_ins_for_binary_op (MonoCompile *cfg, MonoClass *klass, MonoMethodSigna
306306 break ;
307307 case SN_Multiply :
308308 case SN_op_Multiply :
309+ if (fsig -> params [1 ]-> type != MONO_TYPE_GENERICINST ) {
310+ MonoInst * ins = emit_simd_ins (cfg , klass , OP_CREATE_SCALAR_UNSAFE , args [1 ]-> dreg , -1 );
311+ ins -> inst_c1 = arg_type ;
312+ ins = emit_simd_ins (cfg , klass , OP_XBINOP_BYSCALAR , args [0 ]-> dreg , ins -> dreg );
313+ ins -> inst_c0 = OP_FMUL ;
314+ return ins ;
315+ } else if (fsig -> params [0 ]-> type != MONO_TYPE_GENERICINST ) {
316+ MonoInst * ins = emit_simd_ins (cfg , klass , OP_CREATE_SCALAR_UNSAFE , args [0 ]-> dreg , -1 );
317+ ins -> inst_c1 = arg_type ;
318+ ins = emit_simd_ins (cfg , klass , OP_XBINOP_BYSCALAR , ins -> dreg , args [1 ]-> dreg );
319+ ins -> inst_c0 = OP_FMUL ;
320+ return ins ;
321+ }
309322 instc0 = OP_FMUL ;
310323 break ;
311324 case SN_Subtract :
@@ -332,6 +345,19 @@ emit_simd_ins_for_binary_op (MonoCompile *cfg, MonoClass *klass, MonoMethodSigna
332345 break ;
333346 case SN_Multiply :
334347 case SN_op_Multiply :
348+ if (fsig -> params [1 ]-> type != MONO_TYPE_GENERICINST ) {
349+ MonoInst * ins = emit_simd_ins (cfg , klass , OP_CREATE_SCALAR_UNSAFE , args [1 ]-> dreg , -1 );
350+ ins -> inst_c1 = arg_type ;
351+ ins = emit_simd_ins (cfg , klass , OP_XBINOP_BYSCALAR , args [0 ]-> dreg , ins -> dreg );
352+ ins -> inst_c0 = OP_IMUL ;
353+ return ins ;
354+ } else if (fsig -> params [0 ]-> type != MONO_TYPE_GENERICINST ) {
355+ MonoInst * ins = emit_simd_ins (cfg , klass , OP_CREATE_SCALAR_UNSAFE , args [0 ]-> dreg , -1 );
356+ ins -> inst_c1 = arg_type ;
357+ ins = emit_simd_ins (cfg , klass , OP_XBINOP_BYSCALAR , ins -> dreg , args [1 ]-> dreg );
358+ ins -> inst_c0 = OP_IMUL ;
359+ return ins ;
360+ }
335361 instc0 = OP_IMUL ;
336362 break ;
337363 case SN_Subtract :
@@ -812,15 +838,9 @@ type_to_extract_op (MonoTypeEnum type)
812838}
813839
814840static MonoClass *
815- create_class_instance (MonoCompile * cfg , MonoMethodSignature * fsig , const char * name_space , const char * name , gboolean same_type , MonoType * param_type )
841+ create_class_instance (const char * name_space , const char * name , MonoType * param_type )
816842{
817843 MonoClass * ivector = mono_class_load_from_name (mono_defaults .corlib , name_space , name );
818- if (same_type ) {
819- MonoClass * arg_class = mono_class_from_mono_type_internal (fsig -> params [0 ]);
820- param_type = mono_class_get_generic_class (arg_class )-> context .class_inst -> type_argv [0 ];
821- } else {
822- g_assert (param_type != NULL );
823- }
824844
825845 MonoType * args [ ] = { param_type };
826846 MonoGenericContext ctx ;
@@ -905,6 +925,7 @@ static guint16 sri_vector_methods [] = {
905925 SN_WidenUpper ,
906926 SN_WithElement ,
907927 SN_Xor ,
928+ SN_get_IsHardwareAccelerated ,
908929};
909930
910931/* nint and nuint haven't been enabled yet for System.Runtime.Intrinsics.
@@ -957,8 +978,19 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
957978
958979 MonoClass * klass = cmethod -> klass ;
959980 MonoTypeEnum arg0_type = fsig -> param_count > 0 ? get_underlying_type (fsig -> params [0 ]) : MONO_TYPE_VOID ;
981+
982+ gboolean supported = FALSE;
983+ #ifdef MONO_ARCH_SIMD_INTRINSICS
984+ supported = TRUE;
985+ #endif
960986
961987 switch (id ) {
988+ case SN_get_IsHardwareAccelerated : {
989+ MonoInst * ins ;
990+ EMIT_NEW_ICONST (cfg , ins , supported ? 1 : 0 );
991+ ins -> type = STACK_I4 ;
992+ return ins ;
993+ }
962994 case SN_Abs : {
963995 if (!is_element_type_primitive (fsig -> params [0 ]))
964996 return NULL ;
@@ -1240,7 +1272,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
12401272 ins2 -> inst_c0 = 0 ;
12411273 ins2 -> inst_c1 = arg0_type ;
12421274
1243- MonoClass * ivector128_inst = create_class_instance (cfg , fsig , "System.Runtime.Intrinsics" , "Vector128`1" , TRUE, NULL );
1275+ MonoType * param_type = get_vector_t_elem_type (fsig -> params [0 ]);
1276+ MonoClass * ivector128_inst = create_class_instance ("System.Runtime.Intrinsics" , "Vector128`1" , param_type );
12441277
12451278 ins1 = emit_simd_ins (cfg , ivector128_inst , OP_XINSERT_R8 , ins1 -> dreg , ins2 -> dreg );
12461279 ins1 -> sreg3 = tmp ;
@@ -1268,9 +1301,9 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
12681301 type_new = m_class_get_byval_arg (mono_defaults .int64_class );
12691302 type_enum_new = MONO_TYPE_I8 ;
12701303 }
1271- MonoClass * ivector128_64_inst = create_class_instance (cfg , fsig , "System.Runtime.Intrinsics" , "Vector128`1" , FALSE , type_new );
1304+ MonoClass * ivector128_64_inst = create_class_instance ("System.Runtime.Intrinsics" , "Vector128`1" , type_new );
12721305 arg0 = emit_simd_ins (cfg , ivector128_64_inst , OP_XCAST , arg0 -> dreg , -1 );
1273- MonoClass * ivector64_64_inst = create_class_instance (cfg , fsig , "System.Runtime.Intrinsics" , "Vector64`1" , FALSE , type_new );
1306+ MonoClass * ivector64_64_inst = create_class_instance ("System.Runtime.Intrinsics" , "Vector64`1" , type_new );
12741307 MonoInst * arg1 = emit_simd_ins (cfg , ivector64_64_inst , OP_XCAST , args [1 ]-> dreg , -1 );
12751308
12761309 //Insert arg1 to arg0
@@ -1279,7 +1312,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
12791312 arg1 = emit_simd_ins (cfg , ivector64_64_inst , OP_EXTRACT_I8 , arg1 -> dreg , -1 );
12801313 arg1 -> inst_c0 = 0 ;
12811314 arg1 -> inst_c1 = type_enum_new ;
1282- MonoClass * ivector128_inst = create_class_instance (cfg , fsig , "System.Runtime.Intrinsics" , "Vector128`1" , TRUE, NULL );
1315+ MonoType * param_type = get_vector_t_elem_type (fsig -> params [0 ]);
1316+ MonoClass * ivector128_inst = create_class_instance ("System.Runtime.Intrinsics" , "Vector128`1" , param_type );
12831317 MonoInst * ins = emit_simd_ins (cfg , ivector128_64_inst , OP_XINSERT_I8 , arg0 -> dreg , arg1 -> dreg );
12841318 ins -> sreg3 = tmp ;
12851319 ins -> inst_c1 = type_enum_new ;
@@ -3701,23 +3735,50 @@ emit_amd64_intrinsics (const char *class_ns, const char *class_name, MonoCompile
37013735#ifdef TARGET_ARM64
37023736static
37033737MonoInst *
3704- emit_simd_intrinsics (const char * class_ns , const char * class_name , MonoCompile * cfg , MonoMethod * cmethod , MonoMethodSignature * fsig , MonoInst * * args )
3738+ arch_emit_simd_intrinsics (const char * class_ns , const char * class_name , MonoCompile * cfg , MonoMethod * cmethod , MonoMethodSignature * fsig , MonoInst * * args )
37053739{
3706- // FIXME: implement Vector64<T>, Vector128<T> and Vector<T> for Arm64
37073740 if (!strcmp (class_ns , "System.Runtime.Intrinsics.Arm" )) {
37083741 return emit_hardware_intrinsics (cfg , cmethod , fsig , args ,
37093742 supported_arm_intrinsics , sizeof (supported_arm_intrinsics ),
37103743 emit_arm64_intrinsics );
37113744 }
37123745
3746+ if (!strcmp (class_ns , "System.Runtime.Intrinsics" )) {
3747+ if (!strcmp (class_name , "Vector128" ) || !strcmp (class_name , "Vector64" ))
3748+ return emit_sri_vector (cfg , cmethod , fsig , args );
3749+ }
3750+
3751+ if (!strcmp (class_ns , "System.Runtime.Intrinsics" )) {
3752+ if (!strcmp (class_name , "Vector128`1" ) || !strcmp (class_name , "Vector64`1" ))
3753+ return emit_vector64_vector128_t (cfg , cmethod , fsig , args );
3754+ }
3755+
3756+ if (!strcmp (class_ns , "System.Numerics" ) && !strcmp (class_name , "Vector" )){
3757+ return emit_sri_vector (cfg , cmethod , fsig , args );
3758+ }
3759+
3760+ if (!strcmp (class_ns , "System.Numerics" ) && !strcmp (class_name , "Vector`1" )){
3761+ return emit_vector64_vector128_t (cfg , cmethod , fsig , args );
3762+ }
3763+
37133764 return NULL ;
37143765}
37153766#elif TARGET_AMD64
37163767// TODO: test and enable for x86 too
37173768static
37183769MonoInst *
3719- emit_simd_intrinsics (const char * class_ns , const char * class_name , MonoCompile * cfg , MonoMethod * cmethod , MonoMethodSignature * fsig , MonoInst * * args )
3770+ arch_emit_simd_intrinsics (const char * class_ns , const char * class_name , MonoCompile * cfg , MonoMethod * cmethod , MonoMethodSignature * fsig , MonoInst * * args )
37203771{
3772+ if (!strcmp (class_ns , "System.Runtime.Intrinsics" )) {
3773+ if (!strcmp (class_name , "Vector128" ) || !strcmp (class_name , "Vector64" ))
3774+ return emit_sri_vector (cfg , cmethod , fsig , args );
3775+ }
3776+
3777+ if (!strcmp (class_ns , "System.Runtime.Intrinsics" )) {
3778+ if (!strcmp (class_name , "Vector128`1" ) || !strcmp (class_name , "Vector64`1" ))
3779+ return emit_vector64_vector128_t (cfg , cmethod , fsig , args );
3780+ }
3781+
37213782 MonoInst * simd_inst = emit_amd64_intrinsics (class_ns , class_name , cfg , cmethod , fsig , args );
37223783 if (simd_inst != NULL )
37233784 cfg -> uses_simd_intrinsics |= MONO_CFG_USES_SIMD_INTRINSICS ;
@@ -3726,7 +3787,7 @@ emit_simd_intrinsics (const char *class_ns, const char *class_name, MonoCompile
37263787#else
37273788static
37283789MonoInst *
3729- emit_simd_intrinsics (const char * class_ns , const char * class_name , MonoCompile * cfg , MonoMethod * cmethod , MonoMethodSignature * fsig , MonoInst * * args )
3790+ arch_emit_simd_intrinsics (const char * class_ns , const char * class_name , MonoCompile * cfg , MonoMethod * cmethod , MonoMethodSignature * fsig , MonoInst * * args )
37303791{
37313792 return NULL ;
37323793}
@@ -3749,25 +3810,7 @@ mono_emit_simd_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
37493810 if (m_class_get_nested_in (cmethod -> klass ))
37503811 class_ns = m_class_get_name_space (m_class_get_nested_in (cmethod -> klass ));
37513812
3752- #if defined(TARGET_ARM64 ) || defined(TARGET_AMD64 )
3753- if (!strcmp (class_ns , "System.Runtime.Intrinsics" )) {
3754- if (!strcmp (class_name , "Vector128" ) || !strcmp (class_name , "Vector64" ))
3755- return emit_sri_vector (cfg , cmethod , fsig , args );
3756- }
3757-
3758- if (!strcmp (class_ns , "System.Runtime.Intrinsics" )) {
3759- if (!strcmp (class_name , "Vector128`1" ) || !strcmp (class_name , "Vector64`1" ))
3760- return emit_vector64_vector128_t (cfg , cmethod , fsig , args );
3761- }
3762- #endif // defined(TARGET_ARM64) || defined(TARGET_AMD64)
3763-
3764- #if defined(TARGET_ARM64 )
3765- if (!strcmp (class_ns , "System.Numerics" ) && !strcmp (class_name , "Vector" )){
3766- return emit_sri_vector (cfg , cmethod , fsig , args );
3767- }
3768- #endif // defined(TARGET_ARM64)
3769-
3770- return emit_simd_intrinsics (class_ns , class_name , cfg , cmethod , fsig , args );
3813+ return arch_emit_simd_intrinsics (class_ns , class_name , cfg , cmethod , fsig , args );
37713814}
37723815
37733816/*
0 commit comments