@@ -600,13 +600,13 @@ static guint16 sri_vector_methods [] = {
600
600
SN_AsUInt16 ,
601
601
SN_AsUInt32 ,
602
602
SN_AsUInt64 ,
603
- SN_BitwiseAnd ,
604
- SN_BitwiseOr ,
605
603
SN_AsVector128 ,
606
604
SN_AsVector2 ,
607
605
SN_AsVector256 ,
608
606
SN_AsVector3 ,
609
607
SN_AsVector4 ,
608
+ SN_BitwiseAnd ,
609
+ SN_BitwiseOr ,
610
610
SN_Ceiling ,
611
611
SN_ConditionalSelect ,
612
612
SN_ConvertToDouble ,
@@ -669,24 +669,33 @@ is_create_from_half_vectors_overload (MonoMethodSignature *fsig)
669
669
return mono_metadata_type_equal (fsig -> params [0 ], fsig -> params [1 ]);
670
670
}
671
671
672
+ static gboolean
673
+ is_element_type_primitive (MonoType * vector_type )
674
+ {
675
+ MonoType * element_type = get_vector_t_elem_type (vector_type );
676
+ return MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (element_type );
677
+ }
678
+
672
679
static MonoInst *
673
680
emit_sri_vector (MonoCompile * cfg , MonoMethod * cmethod , MonoMethodSignature * fsig , MonoInst * * args )
674
681
{
675
682
if (!COMPILE_LLVM (cfg ))
676
683
return NULL ;
677
684
678
- MonoClass * klass = cmethod -> klass ;
679
685
int id = lookup_intrins (sri_vector_methods , sizeof (sri_vector_methods ), cmethod );
680
686
if (id == -1 )
681
687
return NULL ;
682
688
683
689
if (!strcmp (m_class_get_name (cfg -> method -> klass ), "Vector256" ))
684
690
return NULL ; // TODO: Fix Vector256.WithUpper/WithLower
685
-
691
+
692
+ MonoClass * klass = cmethod -> klass ;
686
693
MonoTypeEnum arg0_type = fsig -> param_count > 0 ? get_underlying_type (fsig -> params [0 ]) : MONO_TYPE_VOID ;
687
694
688
695
switch (id ) {
689
696
case SN_Abs : {
697
+ if (!is_element_type_primitive (fsig -> params [0 ]))
698
+ return NULL ;
690
699
#ifdef TARGET_ARM64
691
700
switch (arg0_type ) {
692
701
case MONO_TYPE_U1 :
@@ -704,16 +713,22 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
704
713
#endif
705
714
}
706
715
case SN_Add :
716
+ case SN_Divide :
707
717
case SN_Max :
708
718
case SN_Min :
709
719
case SN_Multiply :
710
720
case SN_Subtract : {
721
+ if (!is_element_type_primitive (fsig -> params [0 ]))
722
+ return NULL ;
711
723
int instc0 = -1 ;
712
724
if (arg0_type == MONO_TYPE_R4 || arg0_type == MONO_TYPE_R8 ) {
713
725
switch (id ) {
714
726
case SN_Add :
715
727
instc0 = OP_FADD ;
716
728
break ;
729
+ case SN_Divide :
730
+ instc0 = OP_FDIV ;
731
+ break ;
717
732
case SN_Max :
718
733
instc0 = OP_FMAX ;
719
734
break ;
@@ -734,6 +749,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
734
749
case SN_Add :
735
750
instc0 = OP_IADD ;
736
751
break ;
752
+ case SN_Divide :
753
+ return NULL ;
737
754
case SN_Max :
738
755
instc0 = OP_IMAX ;
739
756
break ;
@@ -752,25 +769,34 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
752
769
}
753
770
return emit_simd_ins_for_sig (cfg , klass , OP_XBINOP , instc0 , arg0_type , fsig , args );
754
771
}
755
- case SN_Divide : {
756
- if ((arg0_type != MONO_TYPE_R4 ) && (arg0_type != MONO_TYPE_R8 ))
757
- return NULL ;
758
- return emit_simd_ins_for_sig (cfg , klass , OP_XBINOP , OP_FDIV , arg0_type , fsig , args );
759
- }
760
772
case SN_AndNot :
773
+ if (!is_element_type_primitive (fsig -> params [0 ]))
774
+ return NULL ;
761
775
#ifdef TARGET_ARM64
762
776
return emit_simd_ins_for_sig (cfg , klass , OP_ARM64_BIC , -1 , arg0_type , fsig , args );
763
777
#else
764
778
return NULL ;
765
779
#endif
766
780
case SN_BitwiseAnd :
767
- return emit_simd_ins_for_sig (cfg , klass , OP_XBINOP , OP_IAND , arg0_type , fsig , args );
768
781
case SN_BitwiseOr :
769
- return emit_simd_ins_for_sig (cfg , klass , OP_XBINOP , OP_IOR , arg0_type , fsig , args );
770
782
case SN_Xor : {
771
- if (( arg0_type == MONO_TYPE_R4 ) || ( arg0_type == MONO_TYPE_R8 ))
783
+ if (! is_element_type_primitive ( fsig -> params [ 0 ] ))
772
784
return NULL ;
773
- return emit_simd_ins_for_sig (cfg , klass , OP_XBINOP , OP_IXOR , arg0_type , fsig , args );
785
+ int instc0 = -1 ;
786
+ switch (id ) {
787
+ case SN_BitwiseAnd :
788
+ instc0 = XBINOP_FORCEINT_AND ;
789
+ break ;
790
+ case SN_BitwiseOr :
791
+ instc0 = XBINOP_FORCEINT_OR ;
792
+ break ;
793
+ case SN_Xor :
794
+ instc0 = XBINOP_FORCEINT_XOR ;
795
+ break ;
796
+ default :
797
+ g_assert_not_reached ();
798
+ }
799
+ return emit_simd_ins_for_sig (cfg , klass , OP_XBINOP_FORCEINT , instc0 , arg0_type , fsig , args );
774
800
}
775
801
case SN_As :
776
802
case SN_AsByte :
@@ -783,9 +809,7 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
783
809
case SN_AsUInt16 :
784
810
case SN_AsUInt32 :
785
811
case SN_AsUInt64 : {
786
- MonoType * ret_type = get_vector_t_elem_type (fsig -> ret );
787
- MonoType * arg_type = get_vector_t_elem_type (fsig -> params [0 ]);
788
- if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (ret_type ) || !MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (arg_type ))
812
+ if (!is_element_type_primitive (fsig -> ret ) || !is_element_type_primitive (fsig -> params [0 ]))
789
813
return NULL ;
790
814
return emit_simd_ins (cfg , klass , OP_XCAST , args [0 ]-> dreg , -1 );
791
815
}
@@ -801,6 +825,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
801
825
#endif
802
826
}
803
827
case SN_ConditionalSelect : {
828
+ if (!is_element_type_primitive (fsig -> params [0 ]))
829
+ return NULL ;
804
830
#ifdef TARGET_ARM64
805
831
return emit_simd_ins_for_sig (cfg , klass , OP_ARM64_BSL , -1 , arg0_type , fsig , args );
806
832
#else
@@ -851,10 +877,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
851
877
case SN_Equals :
852
878
case SN_EqualsAll :
853
879
case SN_EqualsAny : {
854
- MonoType * arg_type = get_vector_t_elem_type (fsig -> params [0 ]);
855
- if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (arg_type ))
880
+ if (!is_element_type_primitive (fsig -> params [0 ]))
856
881
return NULL ;
857
-
858
882
switch (id ) {
859
883
case SN_Equals :
860
884
return emit_xcompare (cfg , klass , arg0_type , args [0 ], args [1 ]);
@@ -870,10 +894,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
870
894
}
871
895
}
872
896
case SN_GetElement : {
897
+ if (!is_element_type_primitive (fsig -> params [0 ]))
898
+ return NULL ;
873
899
MonoClass * arg_class = mono_class_from_mono_type_internal (fsig -> params [0 ]);
874
900
MonoType * etype = mono_class_get_context (arg_class )-> class_inst -> type_argv [0 ];
875
- if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (etype ))
876
- return NULL ;
877
901
int size = mono_class_value_size (arg_class , NULL );
878
902
int esize = mono_class_value_size (mono_class_from_mono_type_internal (etype ), NULL );
879
903
int elems = size / esize ;
@@ -884,8 +908,7 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
884
908
}
885
909
case SN_GetLower :
886
910
case SN_GetUpper : {
887
- MonoType * arg_type = get_vector_t_elem_type (fsig -> params [0 ]);
888
- if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (arg_type ))
911
+ if (!is_element_type_primitive (fsig -> params [0 ]))
889
912
return NULL ;
890
913
int op = id == SN_GetLower ? OP_XLOWER : OP_XUPPER ;
891
914
return emit_simd_ins_for_sig (cfg , klass , op , 0 , arg0_type , fsig , args );
@@ -894,10 +917,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
894
917
case SN_GreaterThanOrEqual :
895
918
case SN_LessThan :
896
919
case SN_LessThanOrEqual : {
897
- MonoType * arg_type = get_vector_t_elem_type (fsig -> params [0 ]);
898
- if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (arg_type ))
920
+ if (!is_element_type_primitive (fsig -> params [0 ]))
899
921
return NULL ;
900
-
901
922
gboolean is_unsigned = type_is_unsigned (fsig -> params [0 ]);
902
923
MonoInst * ins = emit_xcompare (cfg , klass , arg0_type , args [0 ], args [1 ]);
903
924
switch (id ) {
@@ -920,6 +941,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
920
941
}
921
942
case SN_Negate :
922
943
case SN_OnesComplement : {
944
+ if (!is_element_type_primitive (fsig -> params [0 ]))
945
+ return NULL ;
923
946
#ifdef TARGET_ARM64
924
947
int op = id == SN_Negate ? OP_ARM64_XNEG : OP_ARM64_MVN ;
925
948
return emit_simd_ins_for_sig (cfg , klass , op , -1 , arg0_type , fsig , args );
@@ -928,6 +951,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
928
951
#endif
929
952
}
930
953
case SN_Sqrt : {
954
+ if (!is_element_type_primitive (fsig -> params [0 ]))
955
+ return NULL ;
931
956
#ifdef TARGET_ARM64
932
957
if ((arg0_type != MONO_TYPE_R4 ) && (arg0_type != MONO_TYPE_R8 ))
933
958
return NULL ;
@@ -937,25 +962,23 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
937
962
#endif
938
963
}
939
964
case SN_ToScalar : {
940
- MonoType * arg_type = get_vector_t_elem_type (fsig -> params [0 ]);
941
- if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (arg_type ))
965
+ if (!is_element_type_primitive (fsig -> params [0 ]))
942
966
return NULL ;
943
967
int extract_op = type_to_extract_op (arg0_type );
944
968
return emit_simd_ins_for_sig (cfg , klass , extract_op , 0 , arg0_type , fsig , args );
945
969
}
946
970
case SN_ToVector128 :
947
971
case SN_ToVector128Unsafe : {
948
- MonoType * arg_type = get_vector_t_elem_type (fsig -> params [0 ]);
949
- if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (arg_type ))
972
+ if (!is_element_type_primitive (fsig -> params [0 ]))
950
973
return NULL ;
951
974
int op = id == SN_ToVector128 ? OP_XWIDEN : OP_XWIDEN_UNSAFE ;
952
975
return emit_simd_ins_for_sig (cfg , klass , op , 0 , arg0_type , fsig , args );
953
976
}
954
977
case SN_WithElement : {
978
+ if (!is_element_type_primitive (fsig -> params [0 ]))
979
+ return NULL ;
955
980
MonoClass * arg_class = mono_class_from_mono_type_internal (fsig -> params [0 ]);
956
981
MonoType * etype = mono_class_get_context (arg_class )-> class_inst -> type_argv [0 ];
957
- if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (etype ))
958
- return NULL ;
959
982
int size = mono_class_value_size (arg_class , NULL );
960
983
int esize = mono_class_value_size (mono_class_from_mono_type_internal (etype ), NULL );
961
984
int elems = size / esize ;
@@ -969,8 +992,7 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
969
992
}
970
993
case SN_WithLower :
971
994
case SN_WithUpper : {
972
- MonoType * arg_type = get_vector_t_elem_type (fsig -> params [0 ]);
973
- if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (arg_type ))
995
+ if (!is_element_type_primitive (fsig -> params [0 ]))
974
996
return NULL ;
975
997
int op = id == SN_GetLower ? OP_XINSERT_LOWER : OP_XINSERT_UPPER ;
976
998
return emit_simd_ins_for_sig (cfg , klass , op , 0 , arg0_type , fsig , args );
@@ -1559,7 +1581,7 @@ static SimdIntrinsic advsimd_methods [] = {
1559
1581
{SN_AddScalar , OP_XBINOP_SCALAR , OP_IADD , None , None , OP_XBINOP_SCALAR , OP_FADD },
1560
1582
{SN_AddWideningLower , OP_ARM64_SADD , None , OP_ARM64_UADD },
1561
1583
{SN_AddWideningUpper , OP_ARM64_SADD2 , None , OP_ARM64_UADD2 },
1562
- {SN_And , OP_XBINOP_FORCEINT , XBINOP_FORCEINT_and },
1584
+ {SN_And , OP_XBINOP_FORCEINT , XBINOP_FORCEINT_AND },
1563
1585
{SN_BitwiseClear , OP_ARM64_BIC },
1564
1586
{SN_BitwiseSelect , OP_ARM64_BSL },
1565
1587
{SN_Ceiling , OP_XOP_OVR_X_X , INTRINS_AARCH64_ADV_SIMD_FRINTP },
@@ -1762,8 +1784,8 @@ static SimdIntrinsic advsimd_methods [] = {
1762
1784
{SN_NegateSaturateScalar , OP_XOP_OVR_SCALAR_X_X , INTRINS_AARCH64_ADV_SIMD_SQNEG },
1763
1785
{SN_NegateScalar , OP_ARM64_XNEG_SCALAR },
1764
1786
{SN_Not , OP_ARM64_MVN },
1765
- {SN_Or , OP_XBINOP_FORCEINT , XBINOP_FORCEINT_or },
1766
- {SN_OrNot , OP_XBINOP_FORCEINT , XBINOP_FORCEINT_ornot },
1787
+ {SN_Or , OP_XBINOP_FORCEINT , XBINOP_FORCEINT_OR },
1788
+ {SN_OrNot , OP_XBINOP_FORCEINT , XBINOP_FORCEINT_ORNOT },
1767
1789
{SN_PolynomialMultiply , OP_XOP_OVR_X_X_X , INTRINS_AARCH64_ADV_SIMD_PMUL },
1768
1790
{SN_PolynomialMultiplyWideningLower , OP_ARM64_PMULL },
1769
1791
{SN_PolynomialMultiplyWideningUpper , OP_ARM64_PMULL2 },
@@ -1883,7 +1905,7 @@ static SimdIntrinsic advsimd_methods [] = {
1883
1905
{SN_UnzipOdd , OP_ARM64_UZP2 },
1884
1906
{SN_VectorTableLookup , OP_XOP_OVR_X_X_X , INTRINS_AARCH64_ADV_SIMD_TBL1 },
1885
1907
{SN_VectorTableLookupExtension , OP_XOP_OVR_X_X_X_X , INTRINS_AARCH64_ADV_SIMD_TBX1 },
1886
- {SN_Xor , OP_XBINOP_FORCEINT , XBINOP_FORCEINT_xor },
1908
+ {SN_Xor , OP_XBINOP_FORCEINT , XBINOP_FORCEINT_XOR },
1887
1909
{SN_ZeroExtendWideningLower , OP_ARM64_UXTL },
1888
1910
{SN_ZeroExtendWideningUpper , OP_ARM64_UXTL2 },
1889
1911
{SN_ZipHigh , OP_ARM64_ZIP2 },
@@ -3351,6 +3373,12 @@ mono_emit_simd_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
3351
3373
}
3352
3374
#endif // defined(TARGET_ARM64) || defined(TARGET_AMD64)
3353
3375
3376
+ #if defined(TARGET_ARM64 )
3377
+ if (!strcmp (class_ns , "System.Numerics" ) && !strcmp (class_name , "Vector" )){
3378
+ return emit_sri_vector (cfg , cmethod , fsig , args );
3379
+ }
3380
+ #endif // defined(TARGET_ARM64)
3381
+
3354
3382
return emit_simd_intrinsics (class_ns , class_name , cfg , cmethod , fsig , args );
3355
3383
}
3356
3384
0 commit comments