diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 64bc9ab6aab..4f8ede9cfbc 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -117,6 +117,28 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { returns: Vec<AbiParam>, args: &[Value], ) -> &[Value] { + if self.tcx.sess.target.is_like_windows + && params.iter().any(|param| param.value_type == types::I128) + { + let (params, args): (Vec<_>, Vec<_>) = + params + .into_iter() + .zip(args) + .map(|(param, &arg)| { + if param.value_type == types::I128 { + let arg_ptr = Pointer::stack_slot(self.bcx.create_sized_stack_slot( + StackSlotData { kind: StackSlotKind::ExplicitSlot, size: 16 }, + )); + arg_ptr.store(self, arg, MemFlags::trusted()); + (AbiParam::new(self.pointer_type), arg_ptr.get_addr(self)) + } else { + (param, arg) + } + }) + .unzip(); + return self.lib_call(name, params, returns, &args); + } + let sig = Signature { params, returns, call_conv: self.target_config.default_call_conv }; let func_id = self.module.declare_function(name, Linkage::Import, &sig).unwrap(); let func_ref = self.module.declare_func_in_func(func_id, &mut self.bcx.func); diff --git a/src/cast.rs b/src/cast.rs index a474acedcb0..8c23152cda7 100644 --- a/src/cast.rs +++ b/src/cast.rs @@ -64,29 +64,12 @@ pub(crate) fn clif_int_or_float_cast( }, ); - if fx.tcx.sess.target.is_like_windows { - // FIXME move this logic into lib_call - let arg_place = CPlace::new_stack_slot( - fx, - fx.layout_of(if from_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }), - ); - let arg_ptr = arg_place.to_ptr(); - arg_ptr.store(fx, from, MemFlags::trusted()); - let args = [arg_ptr.get_addr(fx)]; - return fx.lib_call( - &name, - vec![AbiParam::new(fx.pointer_type)], - vec![AbiParam::new(to_ty)], - &args, - )[0]; - } else { - return fx.lib_call( - &name, - vec![AbiParam::new(types::I128)], - vec![AbiParam::new(to_ty)], - &[from], - )[0]; - } + return fx.lib_call( + &name, + vec![AbiParam::new(types::I128)], + vec![AbiParam::new(to_ty)], + &[from], + )[0]; } // int-like -> float diff --git a/src/codegen_i128.rs b/src/codegen_i128.rs index af3356e8213..c2a2ce8ad6a 100644 --- a/src/codegen_i128.rs +++ b/src/codegen_i128.rs @@ -32,21 +32,14 @@ pub(crate) fn maybe_codegen<'tcx>( let val_ty = if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }; if fx.tcx.sess.target.is_like_windows { let ret_place = CPlace::new_stack_slot(fx, lhs.layout()); - let (lhs_ptr, lhs_extra) = lhs.force_stack(fx); - let (rhs_ptr, rhs_extra) = rhs.force_stack(fx); - assert!(lhs_extra.is_none()); - assert!(rhs_extra.is_none()); - let args = [ - ret_place.to_ptr().get_addr(fx), - lhs_ptr.get_addr(fx), - rhs_ptr.get_addr(fx), - ]; + let args = + [ret_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)]; fx.lib_call( "__multi3", vec![ AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn), - AbiParam::new(fx.pointer_type), - AbiParam::new(fx.pointer_type), + AbiParam::new(types::I128), + AbiParam::new(types::I128), ], vec![], &args, @@ -87,29 +80,12 @@ pub(crate) fn maybe_codegen<'tcx>( assert!(checked); let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter()); let out_place = CPlace::new_stack_slot(fx, fx.layout_of(out_ty)); - let (param_types, args) = if fx.tcx.sess.target.is_like_windows { - let (lhs_ptr, lhs_extra) = lhs.force_stack(fx); - let (rhs_ptr, rhs_extra) = rhs.force_stack(fx); - assert!(lhs_extra.is_none()); - assert!(rhs_extra.is_none()); - ( - vec![ - AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn), - AbiParam::new(fx.pointer_type), - AbiParam::new(fx.pointer_type), - ], - [out_place.to_ptr().get_addr(fx), lhs_ptr.get_addr(fx), rhs_ptr.get_addr(fx)], - ) - } else { - ( - vec![ - AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn), - AbiParam::new(types::I128), - AbiParam::new(types::I128), - ], - [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)], - ) - }; + let param_types = vec![ + AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn), + AbiParam::new(types::I128), + AbiParam::new(types::I128), + ]; + let args = [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)]; let name = match (bin_op, is_signed) { (BinOp::Add, false) => "__rust_u128_addo", (BinOp::Add, true) => "__rust_i128_addo", @@ -132,14 +108,10 @@ pub(crate) fn maybe_codegen<'tcx>( _ => unreachable!(), }; if fx.tcx.sess.target.is_like_windows { - let (lhs_ptr, lhs_extra) = lhs.force_stack(fx); - let (rhs_ptr, rhs_extra) = rhs.force_stack(fx); - assert!(lhs_extra.is_none()); - assert!(rhs_extra.is_none()); - let args = [lhs_ptr.get_addr(fx), rhs_ptr.get_addr(fx)]; + let args = [lhs.load_scalar(fx), rhs.load_scalar(fx)]; let ret = fx.lib_call( name, - vec![AbiParam::new(fx.pointer_type), AbiParam::new(fx.pointer_type)], + vec![AbiParam::new(types::I128), AbiParam::new(types::I128)], vec![AbiParam::new(types::I64X2)], &args, )[0];