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 } ;
3
4
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
+ }
7
29
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 {
10
36
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 ;
13
42
}
43
+ ret. make_indirect ( ) ;
14
44
}
15
45
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 )
17
47
where
18
48
Ty : TyAbiInterface < ' a , C > + Copy ,
19
49
C : HasDataLayout + HasTargetSpec ,
@@ -32,19 +62,25 @@ where
32
62
}
33
63
return ;
34
64
}
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 {
36
68
arg. extend_integer_width_to ( 64 ) ;
37
69
return ;
38
70
}
71
+ if abi == Vector && size. bits ( ) == 128 && contains_vector ( cx, arg. layout ) {
72
+ arg. cast_to ( Reg { kind : RegKind :: Vector , size } ) ;
73
+ return ;
74
+ }
39
75
40
76
if arg. layout . is_single_fp_element ( cx) {
41
- match arg . layout . size . bytes ( ) {
77
+ match size. bytes ( ) {
42
78
4 => arg. cast_to ( Reg :: f32 ( ) ) ,
43
79
8 => arg. cast_to ( Reg :: f64 ( ) ) ,
44
80
_ => arg. make_indirect ( ) ,
45
81
}
46
82
} else {
47
- match arg . layout . size . bytes ( ) {
83
+ match size. bytes ( ) {
48
84
1 => arg. cast_to ( Reg :: i8 ( ) ) ,
49
85
2 => arg. cast_to ( Reg :: i16 ( ) ) ,
50
86
4 => arg. cast_to ( Reg :: i32 ( ) ) ,
@@ -57,13 +93,15 @@ where
57
93
pub ( crate ) fn compute_abi_info < ' a , Ty , C > ( cx : & C , fn_abi : & mut FnAbi < ' a , Ty > )
58
94
where
59
95
Ty : TyAbiInterface < ' a , C > + Copy ,
60
- C : HasDataLayout + HasTargetSpec ,
96
+ C : HasDataLayout + HasTargetSpec + HasS390xVector ,
61
97
{
98
+ let abi = if cx. has_s390x_vector ( ) { Vector } else { NoVector } ;
99
+
62
100
if !fn_abi. ret . is_ignore ( ) {
63
- classify_ret ( & mut fn_abi. ret ) ;
101
+ classify_ret ( cx , & mut fn_abi. ret , abi ) ;
64
102
}
65
103
66
104
for arg in fn_abi. args . iter_mut ( ) {
67
- classify_arg ( cx, arg) ;
105
+ classify_arg ( cx, arg, abi ) ;
68
106
}
69
107
}
0 commit comments