@@ -21,6 +21,7 @@ use rustc_session::Session;
2121use rustc_span:: source_map:: Spanned ;
2222use rustc_target:: callconv:: { Conv , FnAbi , PassMode } ;
2323
24+ pub ( crate ) use self :: pass_mode:: adjust_fn_abi_for_rust_abi_mistakes;
2425use self :: pass_mode:: * ;
2526pub ( crate ) use self :: returning:: codegen_return;
2627use crate :: prelude:: * ;
@@ -80,7 +81,10 @@ pub(crate) fn get_function_sig<'tcx>(
8081 clif_sig_from_fn_abi (
8182 tcx,
8283 default_call_conv,
83- & FullyMonomorphizedLayoutCx ( tcx) . fn_abi_of_instance ( inst, ty:: List :: empty ( ) ) ,
84+ & adjust_fn_abi_for_rust_abi_mistakes (
85+ tcx,
86+ FullyMonomorphizedLayoutCx ( tcx) . fn_abi_of_instance ( inst, ty:: List :: empty ( ) ) ,
87+ ) ,
8488 )
8589}
8690
@@ -126,7 +130,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
126130 args : & [ Value ] ,
127131 ) -> Cow < ' _ , [ Value ] > {
128132 if self . tcx . sess . target . is_like_windows {
129- let ( mut params, mut args) : ( Vec < _ > , Vec < _ > ) = params
133+ let ( params, args) : ( Vec < _ > , Vec < _ > ) = params
130134 . into_iter ( )
131135 . zip ( args)
132136 . map ( |( param, & arg) | {
@@ -140,29 +144,45 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
140144 } )
141145 . unzip ( ) ;
142146
143- let indirect_ret_val = returns. len ( ) == 1 && returns[ 0 ] . value_type == types:: I128 ;
147+ self . lib_call_unadjusted ( name, params, returns, & args)
148+ } else {
149+ self . lib_call_unadjusted ( name, params, returns, args)
150+ }
151+ }
144152
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( ) ) ] ) ;
153+ pub ( crate ) fn lib_call_unadjusted (
154+ & mut self ,
155+ name : & str ,
156+ mut params : Vec < AbiParam > ,
157+ returns : Vec < AbiParam > ,
158+ args : & [ Value ] ,
159+ ) -> Cow < ' _ , [ Value ] > {
160+ let adjust_ret_param =
161+ if self . tcx . sess . target . is_like_windows || self . tcx . sess . target . arch == "s390x" {
162+ returns. len ( ) == 1 && returns[ 0 ] . value_type == types:: I128
151163 } else {
152- return self . lib_call_unadjusted ( name, params, returns, & args) ;
153- }
164+ false
165+ } ;
166+
167+ if adjust_ret_param {
168+ params. insert ( 0 , AbiParam :: new ( self . pointer_type ) ) ;
169+ let ret_ptr = self . create_stack_slot ( 16 , 16 ) ;
170+ let mut args = args. to_vec ( ) ;
171+ args. insert ( 0 , ret_ptr. get_addr ( self ) ) ;
172+ self . lib_call_inner ( name, params, vec ! [ ] , & args) ;
173+ Cow :: Owned ( vec ! [ ret_ptr. load( self , types:: I128 , MemFlags :: trusted( ) ) ] )
174+ } else {
175+ Cow :: Borrowed ( self . lib_call_inner ( name, params, returns, & args) )
154176 }
155-
156- self . lib_call_unadjusted ( name, params, returns, args)
157177 }
158178
159- pub ( crate ) fn lib_call_unadjusted (
179+ fn lib_call_inner (
160180 & mut self ,
161181 name : & str ,
162182 params : Vec < AbiParam > ,
163183 returns : Vec < AbiParam > ,
164184 args : & [ Value ] ,
165- ) -> Cow < ' _ , [ Value ] > {
185+ ) -> & [ Value ] {
166186 let sig = Signature { params, returns, call_conv : self . target_config . default_call_conv } ;
167187 let func_id = self . module . declare_function ( name, Linkage :: Import , & sig) . unwrap ( ) ;
168188 let func_ref = self . module . declare_func_in_func ( func_id, & mut self . bcx . func ) ;
@@ -175,7 +195,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
175195 }
176196 let results = self . bcx . inst_results ( call_inst) ;
177197 assert ! ( results. len( ) <= 2 , "{}" , results. len( ) ) ;
178- Cow :: Borrowed ( results)
198+ results
179199 }
180200}
181201
@@ -437,11 +457,14 @@ pub(crate) fn codegen_terminator_call<'tcx>(
437457 let extra_args = fx. tcx . mk_type_list_from_iter (
438458 extra_args. iter ( ) . map ( |op_arg| fx. monomorphize ( op_arg. node . ty ( fx. mir , fx. tcx ) ) ) ,
439459 ) ;
440- let fn_abi = if let Some ( instance) = instance {
441- FullyMonomorphizedLayoutCx ( fx. tcx ) . fn_abi_of_instance ( instance, extra_args)
442- } else {
443- FullyMonomorphizedLayoutCx ( fx. tcx ) . fn_abi_of_fn_ptr ( fn_sig, extra_args)
444- } ;
460+ let fn_abi = adjust_fn_abi_for_rust_abi_mistakes (
461+ fx. tcx ,
462+ if let Some ( instance) = instance {
463+ FullyMonomorphizedLayoutCx ( fx. tcx ) . fn_abi_of_instance ( instance, extra_args)
464+ } else {
465+ FullyMonomorphizedLayoutCx ( fx. tcx ) . fn_abi_of_fn_ptr ( fn_sig, extra_args)
466+ } ,
467+ ) ;
445468
446469 let is_cold = if fn_sig. abi ( ) == ExternAbi :: RustCold {
447470 true
@@ -721,8 +744,11 @@ pub(crate) fn codegen_drop<'tcx>(
721744 def : ty:: InstanceKind :: Virtual ( drop_instance. def_id ( ) , 0 ) ,
722745 args : drop_instance. args ,
723746 } ;
724- let fn_abi = FullyMonomorphizedLayoutCx ( fx. tcx )
725- . fn_abi_of_instance ( virtual_drop, ty:: List :: empty ( ) ) ;
747+ let fn_abi = adjust_fn_abi_for_rust_abi_mistakes (
748+ fx. tcx ,
749+ FullyMonomorphizedLayoutCx ( fx. tcx )
750+ . fn_abi_of_instance ( virtual_drop, ty:: List :: empty ( ) ) ,
751+ ) ;
726752
727753 let sig = clif_sig_from_fn_abi ( fx. tcx , fx. target_config . default_call_conv , & fn_abi) ;
728754 let sig = fx. bcx . import_signature ( sig) ;
@@ -764,8 +790,11 @@ pub(crate) fn codegen_drop<'tcx>(
764790 def : ty:: InstanceKind :: Virtual ( drop_instance. def_id ( ) , 0 ) ,
765791 args : drop_instance. args ,
766792 } ;
767- let fn_abi = FullyMonomorphizedLayoutCx ( fx. tcx )
768- . fn_abi_of_instance ( virtual_drop, ty:: List :: empty ( ) ) ;
793+ let fn_abi = adjust_fn_abi_for_rust_abi_mistakes (
794+ fx. tcx ,
795+ FullyMonomorphizedLayoutCx ( fx. tcx )
796+ . fn_abi_of_instance ( virtual_drop, ty:: List :: empty ( ) ) ,
797+ ) ;
769798
770799 let sig = clif_sig_from_fn_abi ( fx. tcx , fx. target_config . default_call_conv , & fn_abi) ;
771800 let sig = fx. bcx . import_signature ( sig) ;
@@ -774,8 +803,11 @@ pub(crate) fn codegen_drop<'tcx>(
774803 _ => {
775804 assert ! ( !matches!( drop_instance. def, InstanceKind :: Virtual ( _, _) ) ) ;
776805
777- let fn_abi = FullyMonomorphizedLayoutCx ( fx. tcx )
778- . fn_abi_of_instance ( drop_instance, ty:: List :: empty ( ) ) ;
806+ let fn_abi = adjust_fn_abi_for_rust_abi_mistakes (
807+ fx. tcx ,
808+ FullyMonomorphizedLayoutCx ( fx. tcx )
809+ . fn_abi_of_instance ( drop_instance, ty:: List :: empty ( ) ) ,
810+ ) ;
779811
780812 let arg_value = drop_place. place_ref (
781813 fx,
0 commit comments