@@ -139,41 +139,50 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
139139 mut returns : Vec < AbiParam > ,
140140 args : & [ Value ] ,
141141 ) -> Cow < ' _ , [ Value ] > {
142+ // FIXME any way to reuse the abi adjustment code in rustc_target?
143+
142144 // Pass i128 arguments by-ref on Windows.
143- let ( params, args) : ( Vec < _ > , Cow < ' _ , [ _ ] > ) = if self . tcx . sess . target . is_like_windows {
144- let ( params, args) : ( Vec < _ > , Vec < _ > ) = params
145- . into_iter ( )
146- . zip ( args)
147- . map ( |( param, & arg) | {
148- if param. value_type == types:: I128 {
149- let arg_ptr = self . create_stack_slot ( 16 , 16 ) ;
150- arg_ptr. store ( self , arg, MemFlagsData :: trusted ( ) ) ;
151- ( AbiParam :: new ( self . pointer_type ) , arg_ptr. get_addr ( self ) )
152- } else {
153- ( param, arg)
154- }
155- } )
156- . unzip ( ) ;
145+ let ( params, args) : ( Vec < _ > , Cow < ' _ , [ _ ] > ) =
146+ if self . tcx . sess . target . is_like_windows || self . tcx . sess . target . arch == Arch :: S390x {
147+ let ( params, args) : ( Vec < _ > , Vec < _ > ) = params
148+ . into_iter ( )
149+ . zip ( args)
150+ . map ( |( param, & arg) | {
151+ if param. value_type == types:: I128
152+ || ( self . tcx . sess . target . arch == Arch :: S390x
153+ && param. value_type == types:: F128 )
154+ {
155+ let arg_ptr = self . create_stack_slot ( 16 , 16 ) ;
156+ arg_ptr. store ( self , arg, MemFlagsData :: trusted ( ) ) ;
157+ ( AbiParam :: new ( self . pointer_type ) , arg_ptr. get_addr ( self ) )
158+ } else {
159+ ( param, arg)
160+ }
161+ } )
162+ . unzip ( ) ;
157163
158- ( params, args. into ( ) )
159- } else {
160- ( params, args. into ( ) )
161- } ;
164+ ( params, args. into ( ) )
165+ } else {
166+ ( params, args. into ( ) )
167+ } ;
162168
163- let ret_single_i128 = returns. len ( ) == 1 && returns[ 0 ] . value_type == types:: I128 ;
164- if ret_single_i128 && self . tcx . sess . target . is_like_windows {
169+ if self . tcx . sess . target . is_like_windows
170+ && matches ! ( * returns, [ AbiParam { value_type: types:: I128 , .. } ] )
171+ {
165172 // Return i128 using the vector ABI on Windows
166173 returns[ 0 ] . value_type = types:: I64X2 ;
167174
168175 let ret = self . lib_call_unadjusted ( name, params, returns, & args) [ 0 ] ;
169176
170177 Cow :: Owned ( vec ! [ codegen_bitcast( self , types:: I128 , ret) ] )
171- } else if ret_single_i128 && self . tcx . sess . target . arch == Arch :: S390x {
172- // Return i128 using a return area pointer on s390x.
178+ } else if self . tcx . sess . target . arch == Arch :: S390x
179+ && matches ! ( * returns, [ AbiParam { value_type: types:: I128 | types:: F128 , .. } ] )
180+ {
181+ // Return i128 and f128 using a return area pointer on s390x.
173182 let mut params = params;
174183 let mut args = args. to_vec ( ) ;
175184
176- params. insert ( 0 , AbiParam :: new ( self . pointer_type ) ) ;
185+ params. insert ( 0 , AbiParam :: special ( self . pointer_type , ArgumentPurpose :: StructReturn ) ) ;
177186 let ret_ptr = self . create_stack_slot ( 16 , 16 ) ;
178187 args. insert ( 0 , ret_ptr. get_addr ( self ) ) ;
179188
0 commit comments