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 , Size , 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 :: * ;
711
8- fn classify_ret < Ty > ( ret : & mut ArgAbi < ' _ , Ty > ) {
9- if !ret. layout . is_aggregate ( ) && ret. layout . size . bits ( ) <= 64 {
12+ fn contains_vector < ' a , Ty , C > ( cx : & C , layout : TyAndLayout < ' a , Ty > , expected_size : Size ) -> 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 == expected_size,
19+ Abi :: Aggregate { .. } => {
20+ for i in 0 ..layout. fields . count ( ) {
21+ if contains_vector ( cx, layout. field ( cx, i) , expected_size) {
22+ return true ;
23+ }
24+ }
25+ false
26+ }
27+ }
28+ }
29+
30+ fn classify_ret < Ty > ( ret : & mut ArgAbi < ' _ , Ty > , abi : ABI ) {
31+ let size = ret. layout . size ;
32+ if abi == Vector && size. bits ( ) <= 128 && matches ! ( ret. layout. abi, Abi :: Vector { .. } ) {
33+ ret. cast_to ( Reg { kind : RegKind :: Vector , size } ) ; // FIXME: this cast is unneeded?
34+ return ;
35+ }
36+ if !ret. layout . is_aggregate ( ) && size. bits ( ) <= 64 {
1037 ret. extend_integer_width_to ( 64 ) ;
11- } else {
12- ret. make_indirect ( ) ;
38+ return ;
1339 }
40+ ret. make_indirect ( ) ;
1441}
1542
16- fn classify_arg < ' a , Ty , C > ( cx : & C , arg : & mut ArgAbi < ' a , Ty > )
43+ fn classify_arg < ' a , Ty , C > ( cx : & C , arg : & mut ArgAbi < ' a , Ty > , abi : ABI )
1744where
1845 Ty : TyAbiInterface < ' a , C > + Copy ,
1946 C : HasDataLayout + HasTargetSpec ,
@@ -32,19 +59,25 @@ where
3259 }
3360 return ;
3461 }
35- if !arg. layout . is_aggregate ( ) && arg. layout . size . bits ( ) <= 64 {
62+
63+ let size = arg. layout . size ;
64+ if abi == Vector && size. bits ( ) <= 128 && contains_vector ( cx, arg. layout , size) {
65+ arg. cast_to ( Reg { kind : RegKind :: Vector , size } ) ;
66+ return ;
67+ }
68+ if !arg. layout . is_aggregate ( ) && size. bits ( ) <= 64 {
3669 arg. extend_integer_width_to ( 64 ) ;
3770 return ;
3871 }
3972
4073 if arg. layout . is_single_fp_element ( cx) {
41- match arg . layout . size . bytes ( ) {
74+ match size. bytes ( ) {
4275 4 => arg. cast_to ( Reg :: f32 ( ) ) ,
4376 8 => arg. cast_to ( Reg :: f64 ( ) ) ,
4477 _ => arg. make_indirect ( ) ,
4578 }
4679 } else {
47- match arg . layout . size . bytes ( ) {
80+ match size. bytes ( ) {
4881 1 => arg. cast_to ( Reg :: i8 ( ) ) ,
4982 2 => arg. cast_to ( Reg :: i16 ( ) ) ,
5083 4 => arg. cast_to ( Reg :: i32 ( ) ) ,
@@ -57,13 +90,15 @@ where
5790pub ( crate ) fn compute_abi_info < ' a , Ty , C > ( cx : & C , fn_abi : & mut FnAbi < ' a , Ty > )
5891where
5992 Ty : TyAbiInterface < ' a , C > + Copy ,
60- C : HasDataLayout + HasTargetSpec ,
93+ C : HasDataLayout + HasTargetSpec + HasS390xVector ,
6194{
95+ let abi = if cx. has_s390x_vector ( ) { Vector } else { NoVector } ;
96+
6297 if !fn_abi. ret . is_ignore ( ) {
63- classify_ret ( & mut fn_abi. ret ) ;
98+ classify_ret ( & mut fn_abi. ret , abi ) ;
6499 }
65100
66101 for arg in fn_abi. args . iter_mut ( ) {
67- classify_arg ( cx, arg) ;
102+ classify_arg ( cx, arg, abi ) ;
68103 }
69104}
0 commit comments