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