@@ -2112,6 +2112,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
2112
2112
}
2113
2113
#elif defined(TARGET_S390X )
2114
2114
if (type_enum_is_float (arg0_type )) {
2115
+ if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4 ))
2116
+ return NULL ;
2115
2117
return emit_simd_ins_for_sig (cfg , klass , arg0_type == MONO_TYPE_R8 ? OP_S390_VFLPDB : OP_S390_VFLPSB , -1 , arg0_type , fsig , args );
2116
2118
} else {
2117
2119
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
2135
2137
if (!is_element_type_primitive (fsig -> params [0 ]) || !is_element_type_primitive (fsig -> params [1 ]))
2136
2138
return NULL ;
2137
2139
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
+
2138
2147
#if !defined(TARGET_ARM64 ) && !defined(TARGET_S390X )
2139
2148
if (((id == SN_Max ) || (id == SN_Min )) && type_enum_is_float (arg0_type ))
2140
2149
return NULL ;
@@ -2149,7 +2158,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
2149
2158
if (!is_element_type_primitive (fsig -> params [0 ]) ||
2150
2159
!(MONO_TYPE_IS_VECTOR_PRIMITIVE (fsig -> params [1 ]) || is_element_type_primitive (fsig -> params [1 ])))
2151
2160
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
2153
2165
return emit_simd_ins_for_binary_op (cfg , klass , fsig , args , arg0_type , id );
2154
2166
}
2155
2167
case SN_Multiply : {
@@ -2170,7 +2182,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
2170
2182
return NULL ;
2171
2183
} else if (!(is_element_type_primitive (fsig -> params [0 ]) && is_element_type_primitive (fsig -> params [1 ])))
2172
2184
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
2174
2189
return emit_simd_ins_for_binary_op (cfg , klass , fsig , args , vector_inner_type , id );
2175
2190
}
2176
2191
case SN_AndNot : {
@@ -2198,13 +2213,17 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
2198
2213
int add_op ;
2199
2214
2200
2215
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
2201
2220
mul_op = OP_FMUL ;
2202
2221
add_op = OP_FADD ;
2203
2222
} else {
2204
2223
mul_op = OP_IMUL ;
2205
2224
add_op = OP_IADD ;
2206
2225
2207
- #ifdef TARGET_ARM64
2226
+ #if defined( TARGET_ARM64 ) || defined( TARGET_S390X )
2208
2227
if (!COMPILE_LLVM (cfg ) && (arg0_type == MONO_TYPE_I8 || arg0_type == MONO_TYPE_U8 || arg0_type == MONO_TYPE_I || arg0_type == MONO_TYPE_U ))
2209
2228
return NULL ;
2210
2229
#endif
@@ -2274,6 +2293,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
2274
2293
int ceil_or_floor = id == SN_Ceiling ? 10 : 9 ;
2275
2294
return emit_simd_ins_for_sig (cfg , klass , OP_SSE41_ROUNDP , ceil_or_floor , arg0_type , fsig , args );
2276
2295
#elif defined(TARGET_S390X )
2296
+ if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4 ))
2297
+ return NULL ;
2277
2298
int ceil_or_floor = id == SN_Ceiling ? 6 : 7 ;
2278
2299
switch (arg0_type ){
2279
2300
case MONO_TYPE_R4 :
@@ -2464,6 +2485,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
2464
2485
return emit_vector_create_scalar (cfg , vklass , etype , args [0 ], is_unsafe );
2465
2486
}
2466
2487
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
2467
2492
return emit_dot (cfg , klass , fsig -> params [0 ], arg0_type , args [0 ]-> dreg , args [1 ]-> dreg );
2468
2493
}
2469
2494
case SN_Equals :
@@ -2472,6 +2497,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
2472
2497
if (!is_element_type_primitive (fsig -> params [0 ]))
2473
2498
return NULL ;
2474
2499
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
2475
2504
if (id == SN_Equals )
2476
2505
return emit_xcompare (cfg , klass , arg0_type , args [0 ], args [1 ]);
2477
2506
@@ -2733,7 +2762,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
2733
2762
case SN_LessThanOrEqual : {
2734
2763
if (!is_element_type_primitive (fsig -> params [0 ]))
2735
2764
return NULL ;
2736
-
2765
+ #ifdef TARGET_S390X
2766
+ if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4 ))
2767
+ return NULL ;
2768
+ #endif
2737
2769
return emit_xcompare_for_intrinsic (cfg , klass , id , arg0_type , args [0 ], args [1 ]);
2738
2770
}
2739
2771
case SN_GreaterThanAll :
@@ -2750,7 +2782,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
2750
2782
g_assert (fsig -> param_count == 2 &&
2751
2783
fsig -> ret -> type == MONO_TYPE_BOOLEAN &&
2752
2784
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
2754
2789
gboolean is_all = FALSE;
2755
2790
switch (id ) {
2756
2791
case SN_GreaterThanAll :
@@ -2857,6 +2892,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
2857
2892
return NULL ;
2858
2893
if (!type_enum_is_float (arg0_type ))
2859
2894
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
2860
2899
int op = -1 ;
2861
2900
#if defined(TARGET_ARM64 ) || defined(TARGET_AMD64 ) || defined(TARGET_WASM ) || defined(TARGET_S390X )
2862
2901
op = OP_ONES_COMPLEMENT ;
@@ -2879,7 +2918,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
2879
2918
return emit_xones (cfg , klass );
2880
2919
}
2881
2920
}
2882
-
2921
+ #ifdef TARGET_S390X
2922
+ if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4 ))
2923
+ return NULL ;
2924
+ #endif
2883
2925
MonoInst * arg0 = args [0 ];
2884
2926
MonoClass * op_klass = klass ;
2885
2927
@@ -2907,6 +2949,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
2907
2949
case SN_IsPositiveInfinity : {
2908
2950
if (!is_element_type_primitive (fsig -> params [0 ]))
2909
2951
return NULL ;
2952
+ #ifdef TARGET_S390X
2953
+ if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4 ))
2954
+ return NULL ;
2955
+ #endif
2910
2956
if (arg0_type == MONO_TYPE_R4 ) {
2911
2957
guint32 value [4 ];
2912
2958
@@ -2984,6 +3030,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
2984
3030
case SN_IsZero : {
2985
3031
if (!is_element_type_primitive (fsig -> params [0 ]))
2986
3032
return NULL ;
3033
+ #ifdef TARGET_S390X
3034
+ if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4 ))
3035
+ return NULL ;
3036
+ #endif
2987
3037
return emit_xcompare (cfg , klass , arg0_type , args [0 ], emit_xzero (cfg , klass ));
2988
3038
}
2989
3039
case SN_Narrow : {
@@ -3129,6 +3179,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
3129
3179
case SN_OnesComplement : {
3130
3180
if (!is_element_type_primitive (fsig -> params [0 ]))
3131
3181
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
3132
3186
return emit_simd_ins_for_unary_op (cfg , klass , fsig , args , arg0_type , id );
3133
3187
}
3134
3188
case SN_Shuffle : {
@@ -3295,6 +3349,9 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
3295
3349
3296
3350
return emit_simd_ins_for_sig (cfg , klass , OP_XOP_X_X , instc0 , arg0_type , fsig , args );
3297
3351
#elif defined(TARGET_S390X )
3352
+ if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4 ))
3353
+ return NULL ;
3354
+
3298
3355
int instc0 = arg0_type == MONO_TYPE_R4 ? OP_S390_VFSQSB : OP_S390_VFSQDB ;
3299
3356
return emit_simd_ins_for_sig (cfg , klass , instc0 , 0 , arg0_type , fsig , args );
3300
3357
#else
@@ -3792,6 +3849,10 @@ emit_sri_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f
3792
3849
if (fsig -> param_count != 2 )
3793
3850
return NULL ;
3794
3851
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
3795
3856
return emit_simd_ins_for_binary_op (cfg , klass , fsig , args , arg0_type , id );
3796
3857
3797
3858
}
@@ -3800,6 +3861,10 @@ emit_sri_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f
3800
3861
if (fsig -> param_count != 2 )
3801
3862
return NULL ;
3802
3863
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
3803
3868
switch (id ) {
3804
3869
case SN_op_Equality : return emit_xequal (cfg , arg_class , arg0_type , args [0 ], args [1 ]);
3805
3870
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
3810
3875
case SN_op_UnaryNegation :
3811
3876
if (fsig -> param_count != 1 )
3812
3877
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
3813
3882
return emit_simd_ins_for_unary_op (cfg , klass , fsig , args , arg0_type , id );
3814
3883
case SN_op_UnaryPlus :
3815
3884
if (fsig -> param_count != 1 )
@@ -3900,6 +3969,11 @@ emit_vector_2_3_4 (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f
3900
3969
return NULL ;
3901
3970
#endif
3902
3971
3972
+ #ifdef TARGET_S390X
3973
+ if (!mono_hwcap_s390x_has_ve1 )
3974
+ return NULL ;
3975
+ #endif
3976
+
3903
3977
if (!(cfg -> opt & MONO_OPT_SIMD ))
3904
3978
return NULL ;
3905
3979
@@ -4201,6 +4275,9 @@ emit_vector_2_3_4 (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f
4201
4275
ins = emit_simd_ins (cfg , klass , OP_XOP_X_X , args [0 ]-> dreg , -1 );
4202
4276
ins -> inst_c0 = (IntrinsicId )INTRINS_SIMD_SQRT_R4 ;
4203
4277
return ins ;
4278
+ #elif defined(TARGET_S390X )
4279
+ ins = emit_simd_ins (cfg , klass , OP_S390_VFSQSB , args [0 ]-> dreg , -1 );
4280
+ return ins ;
4204
4281
#else
4205
4282
return NULL ;
4206
4283
#endif
@@ -6865,6 +6942,11 @@ static MonoInst*
6865
6942
emit_simd_intrinsics (const char * class_ns , const char * class_name , MonoCompile * cfg , MonoMethod * cmethod , MonoMethodSignature * fsig , MonoInst * * args )
6866
6943
{
6867
6944
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
6868
6950
6869
6951
if (cfg -> opt & MONO_OPT_SIMD ) {
6870
6952
ins = arch_emit_simd_intrinsics (class_ns , class_name , cfg , cmethod , fsig , args );
0 commit comments