@@ -41,64 +41,23 @@ where
41
41
} )
42
42
}
43
43
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 )
45
45
where
46
46
Ty : TyAbiInterface < ' a , C > + Copy ,
47
47
C : HasDataLayout ,
48
48
{
49
- if !ret . layout . is_sized ( ) {
49
+ if arg . is_ignore ( ) || !arg . layout . is_sized ( ) {
50
50
// Not touching this...
51
51
return ;
52
52
}
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 ) ;
55
55
return ;
56
56
}
57
57
58
58
// 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 ( ) ;
102
61
return ;
103
62
}
104
63
@@ -108,7 +67,10 @@ where
108
67
}
109
68
110
69
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 {
112
74
// Aggregates smaller than a doubleword should appear in
113
75
// the least-significant bits of the parameter doubleword.
114
76
arg. cast_to ( Reg { kind : RegKind :: Integer , size } )
@@ -138,14 +100,9 @@ where
138
100
}
139
101
} ;
140
102
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 ) ;
144
104
145
105
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 ) ;
150
107
}
151
108
}
0 commit comments