Move windows i128 indirect return handling to lib_call
This commit is contained in:
parent
ede7cde065
commit
c6a0d3716b
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)],
|
||||
|
Loading…
x
Reference in New Issue
Block a user