@@ -41,64 +41,23 @@ where
4141 } )
4242}
4343
44- fn classify_ret < ' a , Ty , C > ( cx : & C , ret : & mut ArgAbi < ' a , Ty > , abi : ABI )
44+ fn classify < ' a , Ty , C > ( cx : & C , arg : & mut ArgAbi < ' a , Ty > , abi : ABI , is_ret : bool )
4545where
4646 Ty : TyAbiInterface < ' a , C > + Copy ,
4747 C : HasDataLayout ,
4848{
49- if !ret . layout . is_sized ( ) {
49+ if arg . is_ignore ( ) || !arg . layout . is_sized ( ) {
5050 // Not touching this...
5151 return ;
5252 }
53- if !ret . layout . is_aggregate ( ) {
54- ret . extend_integer_width_to ( 64 ) ;
53+ if !arg . layout . is_aggregate ( ) {
54+ arg . extend_integer_width_to ( 64 ) ;
5555 return ;
5656 }
5757
5858 // The ELFv1 ABI doesn't return aggregates in registers
59- if abi == ELFv1 {
60- ret. make_indirect ( ) ;
61- return ;
62- }
63-
64- if let Some ( uniform) = is_homogeneous_aggregate ( cx, ret, abi) {
65- ret. cast_to ( uniform) ;
66- return ;
67- }
68-
69- let size = ret. layout . size ;
70- let bits = size. bits ( ) ;
71- if bits <= 128 {
72- let unit = if cx. data_layout ( ) . endian == Endian :: Big {
73- Reg { kind : RegKind :: Integer , size }
74- } else if bits <= 8 {
75- Reg :: i8 ( )
76- } else if bits <= 16 {
77- Reg :: i16 ( )
78- } else if bits <= 32 {
79- Reg :: i32 ( )
80- } else {
81- Reg :: i64 ( )
82- } ;
83-
84- ret. cast_to ( Uniform :: new ( unit, size) ) ;
85- return ;
86- }
87-
88- ret. make_indirect ( ) ;
89- }
90-
91- fn classify_arg < ' a , Ty , C > ( cx : & C , arg : & mut ArgAbi < ' a , Ty > , abi : ABI )
92- where
93- Ty : TyAbiInterface < ' a , C > + Copy ,
94- C : HasDataLayout ,
95- {
96- if !arg. layout . is_sized ( ) {
97- // Not touching this...
98- return ;
99- }
100- if !arg. layout . is_aggregate ( ) {
101- arg. extend_integer_width_to ( 64 ) ;
59+ if is_ret && abi == ELFv1 {
60+ arg. make_indirect ( ) ;
10261 return ;
10362 }
10463
@@ -108,7 +67,10 @@ where
10867 }
10968
11069 let size = arg. layout . size ;
111- if size. bits ( ) <= 64 {
70+ if is_ret && size. bits ( ) > 128 {
71+ // Non-homogeneous aggregates larger than two doublewords are returned indirectly.
72+ arg. make_indirect ( ) ;
73+ } else if size. bits ( ) <= 64 {
11274 // Aggregates smaller than a doubleword should appear in
11375 // the least-significant bits of the parameter doubleword.
11476 arg. cast_to ( Reg { kind : RegKind :: Integer , size } )
@@ -138,14 +100,9 @@ where
138100 }
139101 } ;
140102
141- if !fn_abi. ret . is_ignore ( ) {
142- classify_ret ( cx, & mut fn_abi. ret , abi) ;
143- }
103+ classify ( cx, & mut fn_abi. ret , abi, true ) ;
144104
145105 for arg in fn_abi. args . iter_mut ( ) {
146- if arg. is_ignore ( ) {
147- continue ;
148- }
149- classify_arg ( cx, arg, abi) ;
106+ classify ( cx, arg, abi, false ) ;
150107 }
151108}
0 commit comments