@@ -1196,6 +1196,9 @@ static guint16 sri_vector_methods [] = {
1196
1196
SN_AsUInt64 ,
1197
1197
SN_AsVector ,
1198
1198
SN_AsVector128 ,
1199
+ SN_AsVector128Unsafe ,
1200
+ SN_AsVector2 ,
1201
+ SN_AsVector3 ,
1199
1202
SN_AsVector4 ,
1200
1203
SN_BitwiseAnd ,
1201
1204
SN_BitwiseOr ,
@@ -1640,7 +1643,11 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
1640
1643
}
1641
1644
case SN_AsVector :
1642
1645
case SN_AsVector128 :
1643
- case SN_AsVector4 : {
1646
+ case SN_AsVector128Unsafe :
1647
+ case SN_AsVector2 :
1648
+ case SN_AsVector3 :
1649
+ case SN_AsVector4 :
1650
+ case SN_AsVector4Unsafe : {
1644
1651
if (!is_element_type_primitive (fsig -> ret ) || !is_element_type_primitive (fsig -> params [0 ]))
1645
1652
return NULL ;
1646
1653
@@ -1650,10 +1657,54 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
1650
1657
MonoClass * arg_class = mono_class_from_mono_type_internal (fsig -> params [0 ]);
1651
1658
int arg_size = mono_class_value_size (arg_class , NULL );
1652
1659
1653
- if (arg_size == ret_size )
1660
+ if (arg_size == ret_size ) {
1654
1661
return emit_simd_ins (cfg , klass , OP_XCAST , args [0 ]-> dreg , -1 );
1662
+ }
1655
1663
1656
- return NULL ;
1664
+ if ((ret_size != 8 ) && (ret_size != 12 ) && (ret_size != 16 )) {
1665
+ return NULL ;
1666
+ }
1667
+
1668
+ if ((arg_size != 8 ) && (arg_size != 12 ) && (arg_size != 16 )) {
1669
+ return NULL ;
1670
+ }
1671
+
1672
+ bool isUnsafe = (id == SN_AsVector128Unsafe ) || (id == SN_AsVector4Unsafe );
1673
+
1674
+ if (arg_size > ret_size ) {
1675
+ #ifdef TARGET_ARM64
1676
+ if (ret_size == 8 ) {
1677
+ return emit_simd_ins_for_sig (cfg , klass , OP_XLOWER , 0 , arg0_type , fsig , args );
1678
+ }
1679
+ #endif
1680
+ return emit_simd_ins (cfg , klass , OP_XCAST , args [0 ]-> dreg , -1 );
1681
+ } else {
1682
+ #ifdef TARGET_ARM64
1683
+ if (arg_size == 8 ) {
1684
+ int op = isUnsafe ? OP_XWIDEN : OP_XWIDEN_UNSAFE ;
1685
+ return emit_simd_ins_for_sig (cfg , klass , op , 0 , arg0_type , fsig , args );
1686
+ }
1687
+ #endif
1688
+ MonoInst * ins = args [0 ];
1689
+
1690
+ if (!isUnsafe ) {
1691
+ static float r4_0 = 0 ;
1692
+ MonoInst * zero ;
1693
+ int zero_dreg = alloc_freg (cfg );
1694
+ MONO_INST_NEW (cfg , zero , OP_R4CONST );
1695
+ zero -> inst_p0 = (void * )& r4_0 ;
1696
+ zero -> dreg = zero_dreg ;
1697
+ MONO_ADD_INS (cfg -> cbb , zero );
1698
+
1699
+ if (arg_size == 8 ) {
1700
+ ins = emit_vector_insert_element (cfg , klass , ins , MONO_TYPE_R4 , zero , 2 , FALSE);
1701
+ }
1702
+ if (ret_size == 16 ) {
1703
+ ins = emit_vector_insert_element (cfg , klass , ins , MONO_TYPE_R4 , zero , 3 , FALSE);
1704
+ }
1705
+ }
1706
+ return emit_simd_ins (cfg , klass , OP_XCAST , ins -> dreg , -1 );
1707
+ }
1657
1708
}
1658
1709
case SN_Ceiling :
1659
1710
case SN_Floor : {
0 commit comments