@@ -2112,6 +2112,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
21122112 }
21132113#elif defined(TARGET_S390X )
21142114 if (type_enum_is_float (arg0_type )) {
2115+ if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4 ))
2116+ return NULL ;
21152117 return emit_simd_ins_for_sig (cfg , klass , arg0_type == MONO_TYPE_R8 ? OP_S390_VFLPDB : OP_S390_VFLPSB , -1 , arg0_type , fsig , args );
21162118 } else {
21172119 return emit_simd_ins_for_sig (cfg , klass , OP_VECTOR_IABS , -1 , arg0_type , fsig , args );
@@ -2135,6 +2137,13 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
21352137 if (!is_element_type_primitive (fsig -> params [0 ]) || !is_element_type_primitive (fsig -> params [1 ]))
21362138 return NULL ;
21372139
2140+ #if defined(TARGET_S390X )
2141+ if (!mono_hwcap_s390x_has_ve1 && arg0_type == MONO_TYPE_R4 )
2142+ return NULL ;
2143+ if (!mono_hwcap_s390x_has_ve1 && ((id == SN_Max ) || (id == SN_Min ) || (id == SN_MaxNative ) || (id == SN_MinNative )) && (arg0_type == MONO_TYPE_R8 ))
2144+ return NULL ;
2145+ #endif
2146+
21382147#if !defined(TARGET_ARM64 ) && !defined(TARGET_S390X )
21392148 if (((id == SN_Max ) || (id == SN_Min )) && type_enum_is_float (arg0_type ))
21402149 return NULL ;
@@ -2149,7 +2158,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
21492158 if (!is_element_type_primitive (fsig -> params [0 ]) ||
21502159 !(MONO_TYPE_IS_VECTOR_PRIMITIVE (fsig -> params [1 ]) || is_element_type_primitive (fsig -> params [1 ])))
21512160 return NULL ;
2152-
2161+ #if defined(TARGET_S390X )
2162+ if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4 ))
2163+ return NULL ;
2164+ #endif
21532165 return emit_simd_ins_for_binary_op (cfg , klass , fsig , args , arg0_type , id );
21542166 }
21552167 case SN_Multiply : {
@@ -2170,7 +2182,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
21702182 return NULL ;
21712183 } else if (!(is_element_type_primitive (fsig -> params [0 ]) && is_element_type_primitive (fsig -> params [1 ])))
21722184 return NULL ;
2173-
2185+ #if defined(TARGET_S390X )
2186+ if (!mono_hwcap_s390x_has_ve1 && (vector_inner_type == MONO_TYPE_R4 ))
2187+ return NULL ;
2188+ #endif
21742189 return emit_simd_ins_for_binary_op (cfg , klass , fsig , args , vector_inner_type , id );
21752190 }
21762191 case SN_AndNot : {
@@ -2198,13 +2213,17 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
21982213 int add_op ;
21992214
22002215 if (type_enum_is_float (arg0_type )) {
2216+ #if defined(TARGET_S390X )
2217+ if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4 ))
2218+ return NULL ;
2219+ #endif
22012220 mul_op = OP_FMUL ;
22022221 add_op = OP_FADD ;
22032222 } else {
22042223 mul_op = OP_IMUL ;
22052224 add_op = OP_IADD ;
22062225
2207- #ifdef TARGET_ARM64
2226+ #if defined( TARGET_ARM64 ) || defined( TARGET_S390X )
22082227 if (!COMPILE_LLVM (cfg ) && (arg0_type == MONO_TYPE_I8 || arg0_type == MONO_TYPE_U8 || arg0_type == MONO_TYPE_I || arg0_type == MONO_TYPE_U ))
22092228 return NULL ;
22102229#endif
@@ -2274,6 +2293,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
22742293 int ceil_or_floor = id == SN_Ceiling ? 10 : 9 ;
22752294 return emit_simd_ins_for_sig (cfg , klass , OP_SSE41_ROUNDP , ceil_or_floor , arg0_type , fsig , args );
22762295#elif defined(TARGET_S390X )
2296+ if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4 ))
2297+ return NULL ;
22772298 int ceil_or_floor = id == SN_Ceiling ? 6 : 7 ;
22782299 switch (arg0_type ){
22792300 case MONO_TYPE_R4 :
@@ -2464,6 +2485,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
24642485 return emit_vector_create_scalar (cfg , vklass , etype , args [0 ], is_unsafe );
24652486 }
24662487 case SN_Dot : {
2488+ #if defined(TARGET_S390X )
2489+ if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4 ))
2490+ return NULL ;
2491+ #endif
24672492 return emit_dot (cfg , klass , fsig -> params [0 ], arg0_type , args [0 ]-> dreg , args [1 ]-> dreg );
24682493 }
24692494 case SN_Equals :
@@ -2472,6 +2497,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
24722497 if (!is_element_type_primitive (fsig -> params [0 ]))
24732498 return NULL ;
24742499 MonoClass * arg_class = mono_class_from_mono_type_internal (fsig -> params [0 ]);
2500+ #ifdef TARGET_S390X
2501+ if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4 ))
2502+ return NULL ;
2503+ #endif
24752504 if (id == SN_Equals )
24762505 return emit_xcompare (cfg , klass , arg0_type , args [0 ], args [1 ]);
24772506
@@ -2733,7 +2762,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
27332762 case SN_LessThanOrEqual : {
27342763 if (!is_element_type_primitive (fsig -> params [0 ]))
27352764 return NULL ;
2736-
2765+ #ifdef TARGET_S390X
2766+ if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4 ))
2767+ return NULL ;
2768+ #endif
27372769 return emit_xcompare_for_intrinsic (cfg , klass , id , arg0_type , args [0 ], args [1 ]);
27382770 }
27392771 case SN_GreaterThanAll :
@@ -2750,7 +2782,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
27502782 g_assert (fsig -> param_count == 2 &&
27512783 fsig -> ret -> type == MONO_TYPE_BOOLEAN &&
27522784 mono_metadata_type_equal (fsig -> params [0 ], fsig -> params [1 ]));
2753-
2785+ #ifdef TARGET_S390X
2786+ if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4 ))
2787+ return NULL ;
2788+ #endif
27542789 gboolean is_all = FALSE;
27552790 switch (id ) {
27562791 case SN_GreaterThanAll :
@@ -2857,6 +2892,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
28572892 return NULL ;
28582893 if (!type_enum_is_float (arg0_type ))
28592894 return emit_xzero (cfg , klass );
2895+ #ifdef TARGET_S390X
2896+ if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4 ))
2897+ return NULL ;
2898+ #endif
28602899 int op = -1 ;
28612900#if defined(TARGET_ARM64 ) || defined(TARGET_AMD64 ) || defined(TARGET_WASM ) || defined(TARGET_S390X )
28622901 op = OP_ONES_COMPLEMENT ;
@@ -2879,7 +2918,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
28792918 return emit_xones (cfg , klass );
28802919 }
28812920 }
2882-
2921+ #ifdef TARGET_S390X
2922+ if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4 ))
2923+ return NULL ;
2924+ #endif
28832925 MonoInst * arg0 = args [0 ];
28842926 MonoClass * op_klass = klass ;
28852927
@@ -2907,6 +2949,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
29072949 case SN_IsPositiveInfinity : {
29082950 if (!is_element_type_primitive (fsig -> params [0 ]))
29092951 return NULL ;
2952+ #ifdef TARGET_S390X
2953+ if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4 ))
2954+ return NULL ;
2955+ #endif
29102956 if (arg0_type == MONO_TYPE_R4 ) {
29112957 guint32 value [4 ];
29122958
@@ -2984,6 +3030,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
29843030 case SN_IsZero : {
29853031 if (!is_element_type_primitive (fsig -> params [0 ]))
29863032 return NULL ;
3033+ #ifdef TARGET_S390X
3034+ if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4 ))
3035+ return NULL ;
3036+ #endif
29873037 return emit_xcompare (cfg , klass , arg0_type , args [0 ], emit_xzero (cfg , klass ));
29883038 }
29893039 case SN_Narrow : {
@@ -3129,6 +3179,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
31293179 case SN_OnesComplement : {
31303180 if (!is_element_type_primitive (fsig -> params [0 ]))
31313181 return NULL ;
3182+ #ifdef TARGET_S390X
3183+ if (!mono_hwcap_s390x_has_ve1 && (id == SN_Negate ) && (arg0_type == MONO_TYPE_R4 ))
3184+ return NULL ;
3185+ #endif
31323186 return emit_simd_ins_for_unary_op (cfg , klass , fsig , args , arg0_type , id );
31333187 }
31343188 case SN_Shuffle : {
@@ -3295,6 +3349,9 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
32953349
32963350 return emit_simd_ins_for_sig (cfg , klass , OP_XOP_X_X , instc0 , arg0_type , fsig , args );
32973351#elif defined(TARGET_S390X )
3352+ if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4 ))
3353+ return NULL ;
3354+
32983355 int instc0 = arg0_type == MONO_TYPE_R4 ? OP_S390_VFSQSB : OP_S390_VFSQDB ;
32993356 return emit_simd_ins_for_sig (cfg , klass , instc0 , 0 , arg0_type , fsig , args );
33003357#else
@@ -3792,6 +3849,10 @@ emit_sri_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f
37923849 if (fsig -> param_count != 2 )
37933850 return NULL ;
37943851 arg0_type = fsig -> param_count > 0 ? get_underlying_type (fsig -> params [0 ]) : MONO_TYPE_VOID ;
3852+ #ifdef TARGET_S390X
3853+ if (!mono_hwcap_s390x_has_ve1 && arg0_type == MONO_TYPE_R4 )
3854+ return NULL ;
3855+ #endif
37953856 return emit_simd_ins_for_binary_op (cfg , klass , fsig , args , arg0_type , id );
37963857
37973858 }
@@ -3800,6 +3861,10 @@ emit_sri_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f
38003861 if (fsig -> param_count != 2 )
38013862 return NULL ;
38023863 MonoClass * arg_class = mono_class_from_mono_type_internal (fsig -> params [0 ]);
3864+ #ifdef TARGET_S390X
3865+ if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4 ))
3866+ return NULL ;
3867+ #endif
38033868 switch (id ) {
38043869 case SN_op_Equality : return emit_xequal (cfg , arg_class , arg0_type , args [0 ], args [1 ]);
38053870 case SN_op_Inequality : return emit_not_xequal (cfg , arg_class , arg0_type , args [0 ], args [1 ]);
@@ -3810,6 +3875,10 @@ emit_sri_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f
38103875 case SN_op_UnaryNegation :
38113876 if (fsig -> param_count != 1 )
38123877 return NULL ;
3878+ #if defined(TARGET_S390X )
3879+ if (!mono_hwcap_s390x_has_ve1 && (id == SN_op_UnaryNegation ) && (arg0_type == MONO_TYPE_R4 ))
3880+ return NULL ;
3881+ #endif
38133882 return emit_simd_ins_for_unary_op (cfg , klass , fsig , args , arg0_type , id );
38143883 case SN_op_UnaryPlus :
38153884 if (fsig -> param_count != 1 )
@@ -3900,6 +3969,11 @@ emit_vector_2_3_4 (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f
39003969 return NULL ;
39013970#endif
39023971
3972+ #ifdef TARGET_S390X
3973+ if (!mono_hwcap_s390x_has_ve1 )
3974+ return NULL ;
3975+ #endif
3976+
39033977 if (!(cfg -> opt & MONO_OPT_SIMD ))
39043978 return NULL ;
39053979
@@ -4201,6 +4275,9 @@ emit_vector_2_3_4 (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f
42014275 ins = emit_simd_ins (cfg , klass , OP_XOP_X_X , args [0 ]-> dreg , -1 );
42024276 ins -> inst_c0 = (IntrinsicId )INTRINS_SIMD_SQRT_R4 ;
42034277 return ins ;
4278+ #elif defined(TARGET_S390X )
4279+ ins = emit_simd_ins (cfg , klass , OP_S390_VFSQSB , args [0 ]-> dreg , -1 );
4280+ return ins ;
42044281#else
42054282 return NULL ;
42064283#endif
@@ -6865,6 +6942,11 @@ static MonoInst*
68656942emit_simd_intrinsics (const char * class_ns , const char * class_name , MonoCompile * cfg , MonoMethod * cmethod , MonoMethodSignature * fsig , MonoInst * * args )
68666943{
68676944 MonoInst * ins ;
6945+ #ifdef TARGET_S390X
6946+ /* vector facility was introduced in z13 */
6947+ if (!mono_hwcap_s390x_has_vec )
6948+ return NULL ;
6949+ #endif
68686950
68696951 if (cfg -> opt & MONO_OPT_SIMD ) {
68706952 ins = arch_emit_simd_intrinsics (class_ns , class_name , cfg , cmethod , fsig , args );
0 commit comments