@@ -156,15 +156,28 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
156156 } ;
157157
158158 let ret_single_i128 = returns. len ( ) == 1 && returns[ 0 ] . value_type == types:: I128 ;
159+ let ret_single_f128 = returns. len ( ) == 1 && returns[ 0 ] . value_type == types:: F128 ;
159160 if ret_single_i128 && self . tcx . sess . target . is_like_windows {
160161 // Return i128 using the vector ABI on Windows
161162 returns[ 0 ] . value_type = types:: I64X2 ;
162163
163164 let ret = self . lib_call_unadjusted ( name, params, returns, & args) [ 0 ] ;
164165
165166 Cow :: Owned ( vec ! [ codegen_bitcast( self , types:: I128 , ret) ] )
166- } else if ret_single_i128 && self . tcx . sess . target . arch == "s390x" {
167- // Return i128 using a return area pointer on s390x.
167+ } else if ret_single_f128 && self . tcx . sess . target . is_like_windows {
168+ // Return f128 using a return area pointer on Windows.
169+ let mut params = params;
170+ let mut args = args. to_vec ( ) ;
171+
172+ params. insert ( 0 , AbiParam :: new ( self . pointer_type ) ) ;
173+ let ret_ptr = self . create_stack_slot ( 16 , 16 ) ;
174+ args. insert ( 0 , ret_ptr. get_addr ( self ) ) ;
175+
176+ self . lib_call_unadjusted ( name, params, vec ! [ ] , & args) ;
177+
178+ Cow :: Owned ( vec ! [ ret_ptr. load( self , types:: I128 , MemFlags :: trusted( ) ) ] )
179+ } else if ( ret_single_i128 || ret_single_f128) && self . tcx . sess . target . arch == "s390x" {
180+ // Return i128/f128 using a return area pointer on s390x.
168181 let mut params = params;
169182 let mut args = args. to_vec ( ) ;
170183
0 commit comments