@@ -260,6 +260,29 @@ emit_xcompare (MonoCompile *cfg, MonoClass *klass, MonoTypeEnum etype, MonoInst
260
260
return ins ;
261
261
}
262
262
263
+ static MonoInst *
264
+ emit_xequal (MonoCompile * cfg , MonoClass * klass , MonoInst * arg1 , MonoInst * arg2 )
265
+ {
266
+ return emit_simd_ins (cfg , klass , OP_XEQUAL , arg1 -> dreg , arg2 -> dreg );
267
+ }
268
+
269
+ static MonoInst *
270
+ emit_not_xequal (MonoCompile * cfg , MonoClass * klass , MonoInst * arg1 , MonoInst * arg2 )
271
+ {
272
+ MonoInst * ins = emit_simd_ins (cfg , klass , OP_XEQUAL , arg1 -> dreg , arg2 -> dreg );
273
+ int sreg = ins -> dreg ;
274
+ int dreg = alloc_ireg (cfg );
275
+ MONO_EMIT_NEW_BIALU_IMM (cfg , OP_COMPARE_IMM , -1 , sreg , 0 );
276
+ EMIT_NEW_UNALU (cfg , ins , OP_CEQ , dreg , -1 );
277
+ return ins ;
278
+ }
279
+
280
+ static MonoInst *
281
+ emit_xzero (MonoCompile * cfg , MonoClass * klass )
282
+ {
283
+ return emit_simd_ins (cfg , klass , OP_XZERO , -1 , -1 );
284
+ }
285
+
263
286
static gboolean
264
287
is_intrinsics_vector_type (MonoType * vector_type )
265
288
{
@@ -492,7 +515,7 @@ emit_vector_create_elementwise (
492
515
{
493
516
int op = type_to_insert_op (etype );
494
517
MonoClass * vklass = mono_class_from_mono_type_internal (vtype );
495
- MonoInst * ins = emit_simd_ins (cfg , vklass , OP_XZERO , -1 , -1 );
518
+ MonoInst * ins = emit_xzero (cfg , vklass );
496
519
for (int i = 0 ; i < fsig -> param_count ; ++ i ) {
497
520
ins = emit_simd_ins (cfg , vklass , op , ins -> dreg , args [i ]-> dreg );
498
521
ins -> inst_c0 = i ;
@@ -590,10 +613,17 @@ static guint16 sri_vector_methods [] = {
590
613
SN_CreateScalar ,
591
614
SN_CreateScalarUnsafe ,
592
615
SN_Divide ,
616
+ SN_Equals ,
617
+ SN_EqualsAll ,
618
+ SN_EqualsAny ,
593
619
SN_Floor ,
594
620
SN_GetElement ,
595
621
SN_GetLower ,
596
622
SN_GetUpper ,
623
+ SN_GreaterThan ,
624
+ SN_GreaterThanOrEqual ,
625
+ SN_LessThan ,
626
+ SN_LessThanOrEqual ,
597
627
SN_Max ,
598
628
SN_Min ,
599
629
SN_Multiply ,
@@ -788,6 +818,27 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
788
818
return emit_simd_ins_for_sig (cfg , klass , OP_CREATE_SCALAR , -1 , arg0_type , fsig , args );
789
819
case SN_CreateScalarUnsafe :
790
820
return emit_simd_ins_for_sig (cfg , klass , OP_CREATE_SCALAR_UNSAFE , -1 , arg0_type , fsig , args );
821
+ case SN_Equals :
822
+ case SN_EqualsAll :
823
+ case SN_EqualsAny : {
824
+ MonoType * arg_type = get_vector_t_elem_type (fsig -> params [0 ]);
825
+ if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (arg_type ))
826
+ return NULL ;
827
+
828
+ switch (id ) {
829
+ case SN_Equals :
830
+ return emit_xcompare (cfg , klass , arg0_type , args [0 ], args [1 ]);
831
+ case SN_EqualsAll :
832
+ return emit_xequal (cfg , klass , args [0 ], args [1 ]);
833
+ case SN_EqualsAny : {
834
+ MonoClass * arg_class = mono_class_from_mono_type_internal (fsig -> params [0 ]);
835
+ MonoInst * cmp_eq = emit_xcompare (cfg , arg_class , arg0_type , args [0 ], args [1 ]);
836
+ MonoInst * zero = emit_xzero (cfg , arg_class );
837
+ return emit_not_xequal (cfg , arg_class , cmp_eq , zero );
838
+ }
839
+ default : g_assert_not_reached ();
840
+ }
841
+ }
791
842
case SN_GetElement : {
792
843
MonoClass * arg_class = mono_class_from_mono_type_internal (fsig -> params [0 ]);
793
844
MonoType * etype = mono_class_get_context (arg_class )-> class_inst -> type_argv [0 ];
@@ -809,6 +860,34 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
809
860
int op = id == SN_GetLower ? OP_XLOWER : OP_XUPPER ;
810
861
return emit_simd_ins_for_sig (cfg , klass , op , 0 , arg0_type , fsig , args );
811
862
}
863
+ case SN_GreaterThan :
864
+ case SN_GreaterThanOrEqual :
865
+ case SN_LessThan :
866
+ case SN_LessThanOrEqual : {
867
+ MonoType * arg_type = get_vector_t_elem_type (fsig -> params [0 ]);
868
+ if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (arg_type ))
869
+ return NULL ;
870
+
871
+ gboolean is_unsigned = type_is_unsigned (fsig -> params [0 ]);
872
+ MonoInst * ins = emit_xcompare (cfg , klass , arg0_type , args [0 ], args [1 ]);
873
+ switch (id ) {
874
+ case SN_GreaterThan :
875
+ ins -> inst_c0 = is_unsigned ? CMP_GT_UN : CMP_GT ;
876
+ break ;
877
+ case SN_GreaterThanOrEqual :
878
+ ins -> inst_c0 = is_unsigned ? CMP_GE_UN : CMP_GE ;
879
+ break ;
880
+ case SN_LessThan :
881
+ ins -> inst_c0 = is_unsigned ? CMP_LT_UN : CMP_LT ;
882
+ break ;
883
+ case SN_LessThanOrEqual :
884
+ ins -> inst_c0 = is_unsigned ? CMP_LE_UN : CMP_LE ;
885
+ break ;
886
+ default :
887
+ g_assert_not_reached ();
888
+ }
889
+ return ins ;
890
+ }
812
891
case SN_Negate :
813
892
case SN_OnesComplement : {
814
893
#ifdef TARGET_ARM64
@@ -879,6 +958,8 @@ static guint16 vector64_vector128_t_methods [] = {
879
958
SN_get_Count ,
880
959
SN_get_IsSupported ,
881
960
SN_get_Zero ,
961
+ SN_op_Equality ,
962
+ SN_op_Inequality ,
882
963
};
883
964
884
965
static MonoInst *
@@ -928,10 +1009,10 @@ emit_vector64_vector128_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
928
1009
return ins ;
929
1010
}
930
1011
case SN_get_Zero : {
931
- return emit_simd_ins (cfg , klass , OP_XZERO , -1 , -1 );
1012
+ return emit_xzero (cfg , klass );
932
1013
}
933
1014
case SN_get_AllBitsSet : {
934
- MonoInst * ins = emit_simd_ins (cfg , klass , OP_XZERO , -1 , -1 );
1015
+ MonoInst * ins = emit_xzero (cfg , klass );
935
1016
return emit_xcompare (cfg , klass , etype -> type , ins , ins );
936
1017
}
937
1018
case SN_Equals : {
@@ -941,6 +1022,16 @@ emit_vector64_vector128_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
941
1022
}
942
1023
break ;
943
1024
}
1025
+ case SN_op_Equality :
1026
+ case SN_op_Inequality :
1027
+ g_assert (fsig -> param_count == 2 && fsig -> ret -> type == MONO_TYPE_BOOLEAN &&
1028
+ mono_metadata_type_equal (fsig -> params [0 ], type ) &&
1029
+ mono_metadata_type_equal (fsig -> params [1 ], type ));
1030
+ switch (id ) {
1031
+ case SN_op_Equality : return emit_xequal (cfg , klass , args [0 ], args [1 ]);
1032
+ case SN_op_Inequality : return emit_not_xequal (cfg , klass , args [0 ], args [1 ]);
1033
+ default : g_assert_not_reached ();
1034
+ }
944
1035
default :
945
1036
break ;
946
1037
}
@@ -1086,7 +1177,7 @@ emit_sys_numerics_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSig
1086
1177
return ins ;
1087
1178
case SN_get_Zero :
1088
1179
g_assert (fsig -> param_count == 0 && mono_metadata_type_equal (fsig -> ret , type ));
1089
- return emit_simd_ins (cfg , klass , OP_XZERO , -1 , -1 );
1180
+ return emit_xzero (cfg , klass );
1090
1181
case SN_get_One : {
1091
1182
g_assert (fsig -> param_count == 0 && mono_metadata_type_equal (fsig -> ret , type ));
1092
1183
MonoInst * one = NULL ;
@@ -1115,7 +1206,7 @@ emit_sys_numerics_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSig
1115
1206
}
1116
1207
case SN_get_AllBitsSet : {
1117
1208
/* Compare a zero vector with itself */
1118
- ins = emit_simd_ins (cfg , klass , OP_XZERO , -1 , -1 );
1209
+ ins = emit_xzero (cfg , klass );
1119
1210
return emit_xcompare (cfg , klass , etype -> type , ins , ins );
1120
1211
}
1121
1212
case SN_get_Item : {
@@ -1222,14 +1313,11 @@ emit_sys_numerics_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSig
1222
1313
g_assert (fsig -> param_count == 2 && fsig -> ret -> type == MONO_TYPE_BOOLEAN &&
1223
1314
mono_metadata_type_equal (fsig -> params [0 ], type ) &&
1224
1315
mono_metadata_type_equal (fsig -> params [1 ], type ));
1225
- ins = emit_simd_ins (cfg , klass , OP_XEQUAL , args [0 ]-> dreg , args [1 ]-> dreg );
1226
- if (id == SN_op_Inequality ) {
1227
- int sreg = ins -> dreg ;
1228
- int dreg = alloc_ireg (cfg );
1229
- MONO_EMIT_NEW_BIALU_IMM (cfg , OP_COMPARE_IMM , -1 , sreg , 0 );
1230
- EMIT_NEW_UNALU (cfg , ins , OP_CEQ , dreg , -1 );
1316
+ switch (id ) {
1317
+ case SN_op_Equality : return emit_xequal (cfg , klass , args [0 ], args [1 ]);
1318
+ case SN_op_Inequality : return emit_not_xequal (cfg , klass , args [0 ], args [1 ]);
1319
+ default : g_assert_not_reached ();
1231
1320
}
1232
- return ins ;
1233
1321
case SN_GreaterThan :
1234
1322
case SN_GreaterThanOrEqual :
1235
1323
case SN_LessThan :
0 commit comments