Move windows i128 indirect return handling to lib_call

This commit is contained in:
bjorn3 2023-02-17 10:41:31 +00:00
parent ede7cde065
commit c6a0d3716b
2 changed files with 33 additions and 31 deletions

View File

@ -4,6 +4,8 @@ mod comments;
mod pass_mode;
mod returning;
use std::borrow::Cow;
use cranelift_module::ModuleError;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::ty::layout::FnAbiOf;
@ -116,11 +118,11 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
params: Vec<AbiParam>,
returns: Vec<AbiParam>,
args: &[Value],
) -> &[Value] {
) -> Cow<'_, [Value]> {
if self.tcx.sess.target.is_like_windows
&& params.iter().any(|param| param.value_type == types::I128)
{
let (params, args): (Vec<_>, Vec<_>) =
let (mut params, mut args): (Vec<_>, Vec<_>) =
params
.into_iter()
.zip(args)
@ -136,7 +138,22 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
}
})
.unzip();
return self.lib_call(name, params, returns, &args);
let indirect_ret_val = returns.len() == 1 && returns[0].value_type == types::I128;
if indirect_ret_val {
params.insert(0, AbiParam::new(types::I128));
let ret_ptr =
Pointer::stack_slot(self.bcx.create_sized_stack_slot(StackSlotData {
kind: StackSlotKind::ExplicitSlot,
size: 16,
}));
args.insert(0, ret_ptr.get_addr(self));
self.lib_call(name, params, vec![], &args);
return Cow::Owned(vec![ret_ptr.load(self, types::I128, MemFlags::trusted())]);
} else {
return self.lib_call(name, params, returns, &args);
}
}
let sig = Signature { params, returns, call_conv: self.target_config.default_call_conv };
@ -151,7 +168,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
}
let results = self.bcx.inst_results(call_inst);
assert!(results.len() <= 2, "{}", results.len());
results
Cow::Borrowed(results)
}
}

View File

@ -29,32 +29,17 @@ pub(crate) fn maybe_codegen<'tcx>(
BinOp::Add | BinOp::Sub if !checked => None,
BinOp::Mul if !checked || is_signed => {
if !checked {
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 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(types::I128),
AbiParam::new(types::I128),
],
vec![],
&args,
);
Some(ret_place.to_cvalue(fx))
} else {
let args: Vec<_> = vec![lhs.load_scalar(fx), rhs.load_scalar(fx)];
let ret_val = fx.lib_call(
"__multi3",
vec![AbiParam::new(types::I128), AbiParam::new(types::I128)],
vec![AbiParam::new(types::I128)],
&args,
)[0];
Some(CValue::by_val(ret_val, fx.layout_of(val_ty)))
}
let args = [lhs.load_scalar(fx), rhs.load_scalar(fx)];
let ret_val = fx.lib_call(
"__multi3",
vec![AbiParam::new(types::I128), AbiParam::new(types::I128)],
vec![AbiParam::new(types::I128)],
&args,
)[0];
Some(CValue::by_val(
ret_val,
fx.layout_of(if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }),
))
} else {
let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter());
let oflow = CPlace::new_stack_slot(fx, fx.layout_of(fx.tcx.types.i32));
@ -120,7 +105,7 @@ pub(crate) fn maybe_codegen<'tcx>(
ret_place.to_ptr().store(fx, ret, MemFlags::trusted());
Some(ret_place.to_cvalue(fx))
} else {
let args: Vec<_> = vec![lhs.load_scalar(fx), rhs.load_scalar(fx)];
let args = [lhs.load_scalar(fx), rhs.load_scalar(fx)];
let ret_val = fx.lib_call(
name,
vec![AbiParam::new(types::I128), AbiParam::new(types::I128)],