@@ -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
@@ -125,7 +129,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
125129 returns : Vec < AbiParam > ,
126130 args : & [ Value ] ,
127131 ) -> Cow < ' _ , [ Value ] > {
128- if self . tcx . sess . target . is_like_windows {
132+ if self . tcx . sess . target . is_like_windows || self . tcx . sess . target . arch == "s390x" {
129133 let ( mut params, mut args) : ( Vec < _ > , Vec < _ > ) = params
130134 . into_iter ( )
131135 . zip ( args)
@@ -159,10 +163,36 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
159163 pub ( crate ) fn lib_call_unadjusted (
160164 & mut self ,
161165 name : & str ,
162- params : Vec < AbiParam > ,
166+ mut params : Vec < AbiParam > ,
163167 returns : Vec < AbiParam > ,
164168 args : & [ Value ] ,
165169 ) -> Cow < ' _ , [ Value ] > {
170+ let adjust_ret_param =
171+ if self . tcx . sess . target . is_like_windows || self . tcx . sess . target . arch == "s390x" {
172+ returns. len ( ) == 1 && returns[ 0 ] . value_type == types:: I128
173+ } else {
174+ false
175+ } ;
176+
177+ if adjust_ret_param {
178+ params. insert ( 0 , AbiParam :: new ( self . pointer_type ) ) ;
179+ let ret_ptr = self . create_stack_slot ( 16 , 16 ) ;
180+ let mut args = args. to_vec ( ) ;
181+ args. insert ( 0 , ret_ptr. get_addr ( self ) ) ;
182+ self . lib_call_inner ( name, params, vec ! [ ] , & args) ;
183+ Cow :: Owned ( vec ! [ ret_ptr. load( self , types:: I128 , MemFlags :: trusted( ) ) ] )
184+ } else {
185+ Cow :: Borrowed ( self . lib_call_inner ( name, params, returns, & args) )
186+ }
187+ }
188+
189+ fn lib_call_inner (
190+ & mut self ,
191+ name : & str ,
192+ params : Vec < AbiParam > ,
193+ returns : Vec < AbiParam > ,
194+ args : & [ Value ] ,
195+ ) -> & [ Value ] {
166196 let sig = Signature { params, returns, call_conv : self . target_config . default_call_conv } ;
167197 let func_id = self . module . declare_function ( name, Linkage :: Import , & sig) . unwrap ( ) ;
168198 let func_ref = self . module . declare_func_in_func ( func_id, & mut self . bcx . func ) ;
@@ -175,7 +205,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
175205 }
176206 let results = self . bcx . inst_results ( call_inst) ;
177207 assert ! ( results. len( ) <= 2 , "{}" , results. len( ) ) ;
178- Cow :: Borrowed ( results)
208+ results
179209 }
180210}
181211
@@ -437,11 +467,14 @@ pub(crate) fn codegen_terminator_call<'tcx>(
437467 let extra_args = fx. tcx . mk_type_list_from_iter (
438468 extra_args. iter ( ) . map ( |op_arg| fx. monomorphize ( op_arg. node . ty ( fx. mir , fx. tcx ) ) ) ,
439469 ) ;
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- } ;
470+ let fn_abi = adjust_fn_abi_for_rust_abi_mistakes (
471+ fx. tcx ,
472+ if let Some ( instance) = instance {
473+ FullyMonomorphizedLayoutCx ( fx. tcx ) . fn_abi_of_instance ( instance, extra_args)
474+ } else {
475+ FullyMonomorphizedLayoutCx ( fx. tcx ) . fn_abi_of_fn_ptr ( fn_sig, extra_args)
476+ } ,
477+ ) ;
445478
446479 let is_cold = if fn_sig. abi ( ) == ExternAbi :: RustCold {
447480 true
@@ -721,8 +754,11 @@ pub(crate) fn codegen_drop<'tcx>(
721754 def : ty:: InstanceKind :: Virtual ( drop_instance. def_id ( ) , 0 ) ,
722755 args : drop_instance. args ,
723756 } ;
724- let fn_abi = FullyMonomorphizedLayoutCx ( fx. tcx )
725- . fn_abi_of_instance ( virtual_drop, ty:: List :: empty ( ) ) ;
757+ let fn_abi = adjust_fn_abi_for_rust_abi_mistakes (
758+ fx. tcx ,
759+ FullyMonomorphizedLayoutCx ( fx. tcx )
760+ . fn_abi_of_instance ( virtual_drop, ty:: List :: empty ( ) ) ,
761+ ) ;
726762
727763 let sig = clif_sig_from_fn_abi ( fx. tcx , fx. target_config . default_call_conv , & fn_abi) ;
728764 let sig = fx. bcx . import_signature ( sig) ;
@@ -764,8 +800,11 @@ pub(crate) fn codegen_drop<'tcx>(
764800 def : ty:: InstanceKind :: Virtual ( drop_instance. def_id ( ) , 0 ) ,
765801 args : drop_instance. args ,
766802 } ;
767- let fn_abi = FullyMonomorphizedLayoutCx ( fx. tcx )
768- . fn_abi_of_instance ( virtual_drop, ty:: List :: empty ( ) ) ;
803+ let fn_abi = adjust_fn_abi_for_rust_abi_mistakes (
804+ fx. tcx ,
805+ FullyMonomorphizedLayoutCx ( fx. tcx )
806+ . fn_abi_of_instance ( virtual_drop, ty:: List :: empty ( ) ) ,
807+ ) ;
769808
770809 let sig = clif_sig_from_fn_abi ( fx. tcx , fx. target_config . default_call_conv , & fn_abi) ;
771810 let sig = fx. bcx . import_signature ( sig) ;
@@ -774,8 +813,11 @@ pub(crate) fn codegen_drop<'tcx>(
774813 _ => {
775814 assert ! ( !matches!( drop_instance. def, InstanceKind :: Virtual ( _, _) ) ) ;
776815
777- let fn_abi = FullyMonomorphizedLayoutCx ( fx. tcx )
778- . fn_abi_of_instance ( drop_instance, ty:: List :: empty ( ) ) ;
816+ let fn_abi = adjust_fn_abi_for_rust_abi_mistakes (
817+ fx. tcx ,
818+ FullyMonomorphizedLayoutCx ( fx. tcx )
819+ . fn_abi_of_instance ( drop_instance, ty:: List :: empty ( ) ) ,
820+ ) ;
779821
780822 let arg_value = drop_place. place_ref (
781823 fx,
0 commit comments