@@ -125,8 +125,9 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
125125 returns : Vec < AbiParam > ,
126126 args : & [ Value ] ,
127127 ) -> 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
130131 . into_iter ( )
131132 . zip ( args)
132133 . map ( |( param, & arg) | {
@@ -140,29 +141,42 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
140141 } )
141142 . unzip ( ) ;
142143
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+ } ;
144148
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
151153 } 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 ( ) ;
155160
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+ }
157171 }
158172
159- pub ( crate ) fn lib_call_unadjusted (
173+ fn lib_call_unadjusted (
160174 & mut self ,
161175 name : & str ,
162176 params : Vec < AbiParam > ,
163177 returns : Vec < AbiParam > ,
164178 args : & [ Value ] ,
165- ) -> Cow < ' _ , [ Value ] > {
179+ ) -> & [ Value ] {
166180 let sig = Signature { params, returns, call_conv : self . target_config . default_call_conv } ;
167181 let func_id = self . module . declare_function ( name, Linkage :: Import , & sig) . unwrap ( ) ;
168182 let func_ref = self . module . declare_func_in_func ( func_id, & mut self . bcx . func ) ;
@@ -175,7 +189,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
175189 }
176190 let results = self . bcx . inst_results ( call_inst) ;
177191 assert ! ( results. len( ) <= 2 , "{}" , results. len( ) ) ;
178- Cow :: Borrowed ( results)
192+ results
179193 }
180194}
181195
0 commit comments