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 pass_mode;
|
||||||
mod returning;
|
mod returning;
|
||||||
|
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use cranelift_module::ModuleError;
|
use cranelift_module::ModuleError;
|
||||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||||
use rustc_middle::ty::layout::FnAbiOf;
|
use rustc_middle::ty::layout::FnAbiOf;
|
||||||
@ -116,11 +118,11 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
|
|||||||
params: Vec<AbiParam>,
|
params: Vec<AbiParam>,
|
||||||
returns: Vec<AbiParam>,
|
returns: Vec<AbiParam>,
|
||||||
args: &[Value],
|
args: &[Value],
|
||||||
) -> &[Value] {
|
) -> Cow<'_, [Value]> {
|
||||||
if self.tcx.sess.target.is_like_windows
|
if self.tcx.sess.target.is_like_windows
|
||||||
&& params.iter().any(|param| param.value_type == types::I128)
|
&& params.iter().any(|param| param.value_type == types::I128)
|
||||||
{
|
{
|
||||||
let (params, args): (Vec<_>, Vec<_>) =
|
let (mut params, mut args): (Vec<_>, Vec<_>) =
|
||||||
params
|
params
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.zip(args)
|
.zip(args)
|
||||||
@ -136,7 +138,22 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.unzip();
|
.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 };
|
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);
|
let results = self.bcx.inst_results(call_inst);
|
||||||
assert!(results.len() <= 2, "{}", results.len());
|
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::Add | BinOp::Sub if !checked => None,
|
||||||
BinOp::Mul if !checked || is_signed => {
|
BinOp::Mul if !checked || is_signed => {
|
||||||
if !checked {
|
if !checked {
|
||||||
let val_ty = if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 };
|
let args = [lhs.load_scalar(fx), rhs.load_scalar(fx)];
|
||||||
if fx.tcx.sess.target.is_like_windows {
|
let ret_val = fx.lib_call(
|
||||||
let ret_place = CPlace::new_stack_slot(fx, lhs.layout());
|
"__multi3",
|
||||||
let args =
|
vec![AbiParam::new(types::I128), AbiParam::new(types::I128)],
|
||||||
[ret_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)];
|
vec![AbiParam::new(types::I128)],
|
||||||
fx.lib_call(
|
&args,
|
||||||
"__multi3",
|
)[0];
|
||||||
vec![
|
Some(CValue::by_val(
|
||||||
AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn),
|
ret_val,
|
||||||
AbiParam::new(types::I128),
|
fx.layout_of(if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }),
|
||||||
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)))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter());
|
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));
|
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());
|
ret_place.to_ptr().store(fx, ret, MemFlags::trusted());
|
||||||
Some(ret_place.to_cvalue(fx))
|
Some(ret_place.to_cvalue(fx))
|
||||||
} else {
|
} 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(
|
let ret_val = fx.lib_call(
|
||||||
name,
|
name,
|
||||||
vec![AbiParam::new(types::I128), AbiParam::new(types::I128)],
|
vec![AbiParam::new(types::I128), AbiParam::new(types::I128)],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user