1- // FIXME: The assumes we're using the non-vector ABI, i.e., compiling
2- // for a pre-z13 machine or using -mno-vx.
1+ use crate :: abi:: call:: { ArgAbi , FnAbi , Reg , RegKind } ;
2+ use crate :: abi:: { Abi , HasDataLayout , TyAbiInterface , TyAndLayout } ;
3+ use crate :: spec:: { HasS390xVector , HasTargetSpec } ;
34
4- use crate :: abi:: call:: { ArgAbi , FnAbi , Reg } ;
5- use crate :: abi:: { HasDataLayout , TyAbiInterface } ;
6- use crate :: spec:: HasTargetSpec ;
5+ #[ derive( Debug , Clone , Copy , PartialEq ) ]
6+ enum ABI {
7+ NoVector , // no-vector ABI, i.e., compiling for a pre-z13 machine or using -C target-feature=-vector
8+ Vector , // vector ABI, i.e., compiling for a z13 or later machine or using -C target-feature=+vector
9+ }
10+ use ABI :: * ;
11+
12+ fn contains_vector < ' a , Ty , C > ( cx : & C , layout : TyAndLayout < ' a , Ty > ) -> bool
13+ where
14+ Ty : TyAbiInterface < ' a , C > + Copy ,
15+ {
16+ match layout. abi {
17+ Abi :: Uninhabited | Abi :: Scalar ( _) | Abi :: ScalarPair ( ..) => false ,
18+ Abi :: Vector { .. } => layout. size . bits ( ) == 128 ,
19+ Abi :: Aggregate { .. } => {
20+ for i in 0 ..layout. fields . count ( ) {
21+ if contains_vector ( cx, layout. field ( cx, i) ) {
22+ return true ;
23+ }
24+ }
25+ false
26+ }
27+ }
28+ }
729
8- fn classify_ret < Ty > ( ret : & mut ArgAbi < ' _ , Ty > ) {
9- if !ret. layout . is_aggregate ( ) && ret. layout . size . bits ( ) <= 64 {
30+ fn classify_ret < ' a , Ty , C > ( cx : & C , ret : & mut ArgAbi < ' a , Ty > , abi : ABI )
31+ where
32+ Ty : TyAbiInterface < ' a , C > + Copy ,
33+ {
34+ let size = ret. layout . size ;
35+ if !ret. layout . is_aggregate ( ) && size. bits ( ) <= 64 {
1036 ret. extend_integer_width_to ( 64 ) ;
11- } else {
12- ret. make_indirect ( ) ;
37+ return ;
38+ }
39+ if abi == Vector && size. bits ( ) == 128 && contains_vector ( cx, ret. layout ) {
40+ ret. cast_to ( Reg { kind : RegKind :: Vector , size } ) ;
41+ return ;
1342 }
43+ ret. make_indirect ( ) ;
1444}
1545
16- fn classify_arg < ' a , Ty , C > ( cx : & C , arg : & mut ArgAbi < ' a , Ty > )
46+ fn classify_arg < ' a , Ty , C > ( cx : & C , arg : & mut ArgAbi < ' a , Ty > , abi : ABI )
1747where
1848 Ty : TyAbiInterface < ' a , C > + Copy ,
1949 C : HasDataLayout + HasTargetSpec ,
@@ -32,19 +62,25 @@ where
3262 }
3363 return ;
3464 }
35- if !arg. layout . is_aggregate ( ) && arg. layout . size . bits ( ) <= 64 {
65+
66+ let size = arg. layout . size ;
67+ if !arg. layout . is_aggregate ( ) && size. bits ( ) <= 64 {
3668 arg. extend_integer_width_to ( 64 ) ;
3769 return ;
3870 }
71+ if abi == Vector && size. bits ( ) == 128 && contains_vector ( cx, arg. layout ) {
72+ arg. cast_to ( Reg { kind : RegKind :: Vector , size } ) ;
73+ return ;
74+ }
3975
4076 if arg. layout . is_single_fp_element ( cx) {
41- match arg . layout . size . bytes ( ) {
77+ match size. bytes ( ) {
4278 4 => arg. cast_to ( Reg :: f32 ( ) ) ,
4379 8 => arg. cast_to ( Reg :: f64 ( ) ) ,
4480 _ => arg. make_indirect ( ) ,
4581 }
4682 } else {
47- match arg . layout . size . bytes ( ) {
83+ match size. bytes ( ) {
4884 1 => arg. cast_to ( Reg :: i8 ( ) ) ,
4985 2 => arg. cast_to ( Reg :: i16 ( ) ) ,
5086 4 => arg. cast_to ( Reg :: i32 ( ) ) ,
@@ -57,13 +93,15 @@ where
5793pub ( crate ) fn compute_abi_info < ' a , Ty , C > ( cx : & C , fn_abi : & mut FnAbi < ' a , Ty > )
5894where
5995 Ty : TyAbiInterface < ' a , C > + Copy ,
60- C : HasDataLayout + HasTargetSpec ,
96+ C : HasDataLayout + HasTargetSpec + HasS390xVector ,
6197{
98+ let abi = if cx. has_s390x_vector ( ) { Vector } else { NoVector } ;
99+
62100 if !fn_abi. ret . is_ignore ( ) {
63- classify_ret ( & mut fn_abi. ret ) ;
101+ classify_ret ( cx , & mut fn_abi. ret , abi ) ;
64102 }
65103
66104 for arg in fn_abi. args . iter_mut ( ) {
67- classify_arg ( cx, arg) ;
105+ classify_arg ( cx, arg, abi ) ;
68106 }
69107}
0 commit comments