@@ -125,8 +125,9 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
125
125
returns : Vec < AbiParam > ,
126
126
args : & [ Value ] ,
127
127
) -> Cow < ' _ , [ Value ] > {
128
- if self . tcx . sess . target . is_like_windows {
129
- let ( mut params, mut args) : ( Vec < _ > , Vec < _ > ) = params
128
+ // Pass i128 arguments by-ref on Windows.
129
+ let ( params, args) : ( Vec < _ > , Cow < ' _ , [ _ ] > ) = if self . tcx . sess . target . is_like_windows {
130
+ let ( params, args) : ( Vec < _ > , Vec < _ > ) = params
130
131
. into_iter ( )
131
132
. zip ( args)
132
133
. map ( |( param, & arg) | {
@@ -140,29 +141,42 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
140
141
} )
141
142
. unzip ( ) ;
142
143
143
- let indirect_ret_val = returns. len ( ) == 1 && returns[ 0 ] . value_type == types:: I128 ;
144
+ ( params, args. into ( ) )
145
+ } else {
146
+ ( params, args. into ( ) )
147
+ } ;
144
148
145
- if indirect_ret_val {
146
- params. insert ( 0 , AbiParam :: new ( self . pointer_type ) ) ;
147
- let ret_ptr = self . create_stack_slot ( 16 , 16 ) ;
148
- args. insert ( 0 , ret_ptr. get_addr ( self ) ) ;
149
- self . lib_call_unadjusted ( name, params, vec ! [ ] , & args) ;
150
- return Cow :: Owned ( vec ! [ ret_ptr. load( self , types:: I128 , MemFlags :: trusted( ) ) ] ) ;
149
+ // Return i128 using a return area pointer on Windows and s390x.
150
+ let adjust_ret_param =
151
+ if self . tcx . sess . target . is_like_windows || self . tcx . sess . target . arch == "s390x" {
152
+ returns. len ( ) == 1 && returns[ 0 ] . value_type == types:: I128
151
153
} else {
152
- return self . lib_call_unadjusted ( name, params, returns, & args) ;
153
- }
154
- }
154
+ false
155
+ } ;
156
+
157
+ if adjust_ret_param {
158
+ let mut params = params;
159
+ let mut args = args. to_vec ( ) ;
155
160
156
- self . lib_call_unadjusted ( name, params, returns, args)
161
+ params. insert ( 0 , AbiParam :: new ( self . pointer_type ) ) ;
162
+ let ret_ptr = self . create_stack_slot ( 16 , 16 ) ;
163
+ args. insert ( 0 , ret_ptr. get_addr ( self ) ) ;
164
+
165
+ self . lib_call_unadjusted ( name, params, vec ! [ ] , & args) ;
166
+
167
+ Cow :: Owned ( vec ! [ ret_ptr. load( self , types:: I128 , MemFlags :: trusted( ) ) ] )
168
+ } else {
169
+ Cow :: Borrowed ( self . lib_call_unadjusted ( name, params, returns, & args) )
170
+ }
157
171
}
158
172
159
- pub ( crate ) fn lib_call_unadjusted (
173
+ fn lib_call_unadjusted (
160
174
& mut self ,
161
175
name : & str ,
162
176
params : Vec < AbiParam > ,
163
177
returns : Vec < AbiParam > ,
164
178
args : & [ Value ] ,
165
- ) -> Cow < ' _ , [ Value ] > {
179
+ ) -> & [ Value ] {
166
180
let sig = Signature { params, returns, call_conv : self . target_config . default_call_conv } ;
167
181
let func_id = self . module . declare_function ( name, Linkage :: Import , & sig) . unwrap ( ) ;
168
182
let func_ref = self . module . declare_func_in_func ( func_id, & mut self . bcx . func ) ;
@@ -175,7 +189,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
175
189
}
176
190
let results = self . bcx . inst_results ( call_inst) ;
177
191
assert ! ( results. len( ) <= 2 , "{}" , results. len( ) ) ;
178
- Cow :: Borrowed ( results)
192
+ results
179
193
}
180
194
}
181
195
0 commit comments