@@ -1268,6 +1268,7 @@ is_element_type_primitive (MonoType *vector_type)
12681268 }
12691269}
12701270
1271+ #ifdef TARGET_ARM64
12711272static MonoInst *
12721273emit_msb_vector_mask (MonoCompile * cfg , MonoClass * arg_class , MonoTypeEnum arg_type )
12731274{
@@ -1358,6 +1359,7 @@ emit_msb_shift_vector_constant (MonoCompile *cfg, MonoClass *arg_class, MonoType
13581359 msb_shift_vec -> klass = arg_class ;
13591360 return msb_shift_vec ;
13601361}
1362+ #endif
13611363
13621364/*
13631365 * Emit intrinsics in System.Numerics.Vector and System.Runtime.Intrinsics.Vector64/128/256/512.
@@ -1800,13 +1802,30 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
18001802 g_assert_not_reached ();
18011803 }
18021804 case SN_ExtractMostSignificantBits : {
1803- if (!is_element_type_primitive (fsig -> params [0 ]) || type_enum_is_float ( arg0_type ) )
1805+ if (!is_element_type_primitive (fsig -> params [0 ]))
18041806 return NULL ;
18051807#ifdef TARGET_WASM
1808+ if (type_enum_is_float (arg0_type ))
1809+ return NULL ;
1810+
18061811 return emit_simd_ins_for_sig (cfg , klass , OP_WASM_SIMD_BITMASK , -1 , -1 , fsig , args );
18071812#elif defined(TARGET_ARM64 )
1808- MonoInst * result_ins = NULL ;
1809- MonoClass * arg_class = mono_class_from_mono_type_internal (fsig -> params [0 ]);
1813+ MonoClass * arg_class ;
1814+ if (type_enum_is_float (arg0_type )) {
1815+ MonoClass * cast_class ;
1816+ if (arg0_type == MONO_TYPE_R4 ) {
1817+ arg0_type = MONO_TYPE_I4 ;
1818+ cast_class = mono_defaults .int32_class ;
1819+ } else {
1820+ arg0_type = MONO_TYPE_I8 ;
1821+ cast_class = mono_defaults .int64_class ;
1822+ }
1823+ arg_class = create_class_instance ("System.Runtime.Intrinsics" , m_class_get_name (klass ), m_class_get_byval_arg (cast_class ));
1824+ } else {
1825+ arg_class = mono_class_from_mono_type_internal (fsig -> params [0 ]);
1826+ }
1827+
1828+ // FIXME: Add support for Vector64 on arm64
18101829 int size = mono_class_value_size (arg_class , NULL );
18111830 if (size != 16 )
18121831 return NULL ;
@@ -1816,11 +1835,12 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
18161835 and_res_vec -> sreg2 = msb_mask_vec -> dreg ;
18171836
18181837 MonoInst * msb_shift_vec = emit_msb_shift_vector_constant (cfg , arg_class , arg0_type );
1819-
1838+
18201839 MonoInst * shift_res_vec = emit_simd_ins (cfg , arg_class , OP_XOP_OVR_X_X_X , and_res_vec -> dreg , msb_shift_vec -> dreg );
18211840 shift_res_vec -> inst_c0 = INTRINS_AARCH64_ADV_SIMD_USHL ;
18221841 shift_res_vec -> inst_c1 = arg0_type ;
18231842
1843+ MonoInst * result_ins = NULL ;
18241844 if (arg0_type == MONO_TYPE_I1 || arg0_type == MONO_TYPE_U1 ) {
18251845 // Always perform unsigned operations as vector sum and extract operations could sign-extend the result into the GP register
18261846 // making the final result invalid. This is not needed for wider type as the maximum sum of extracted MSB cannot be larger than 8bits
0 commit comments