Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit c6a0d37

Browse files
committed
Move windows i128 indirect return handling to lib_call
1 parent ede7cde commit c6a0d37

File tree

2 files changed

+33
-31
lines changed

2 files changed

+33
-31
lines changed

src/abi/mod.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ mod comments;
44
mod pass_mode;
55
mod returning;
66

7+
use std::borrow::Cow;
8+
79
use cranelift_module::ModuleError;
810
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
911
use rustc_middle::ty::layout::FnAbiOf;
@@ -116,11 +118,11 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
116118
params: Vec<AbiParam>,
117119
returns: Vec<AbiParam>,
118120
args: &[Value],
119-
) -> &[Value] {
121+
) -> Cow<'_, [Value]> {
120122
if self.tcx.sess.target.is_like_windows
121123
&& params.iter().any(|param| param.value_type == types::I128)
122124
{
123-
let (params, args): (Vec<_>, Vec<_>) =
125+
let (mut params, mut args): (Vec<_>, Vec<_>) =
124126
params
125127
.into_iter()
126128
.zip(args)
@@ -136,7 +138,22 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
136138
}
137139
})
138140
.unzip();
139-
return self.lib_call(name, params, returns, &args);
141+
142+
let indirect_ret_val = returns.len() == 1 && returns[0].value_type == types::I128;
143+
144+
if indirect_ret_val {
145+
params.insert(0, AbiParam::new(types::I128));
146+
let ret_ptr =
147+
Pointer::stack_slot(self.bcx.create_sized_stack_slot(StackSlotData {
148+
kind: StackSlotKind::ExplicitSlot,
149+
size: 16,
150+
}));
151+
args.insert(0, ret_ptr.get_addr(self));
152+
self.lib_call(name, params, vec![], &args);
153+
return Cow::Owned(vec![ret_ptr.load(self, types::I128, MemFlags::trusted())]);
154+
} else {
155+
return self.lib_call(name, params, returns, &args);
156+
}
140157
}
141158

142159
let sig = Signature { params, returns, call_conv: self.target_config.default_call_conv };
@@ -151,7 +168,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
151168
}
152169
let results = self.bcx.inst_results(call_inst);
153170
assert!(results.len() <= 2, "{}", results.len());
154-
results
171+
Cow::Borrowed(results)
155172
}
156173
}
157174

src/codegen_i128.rs

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -29,32 +29,17 @@ pub(crate) fn maybe_codegen<'tcx>(
2929
BinOp::Add | BinOp::Sub if !checked => None,
3030
BinOp::Mul if !checked || is_signed => {
3131
if !checked {
32-
let val_ty = if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 };
33-
if fx.tcx.sess.target.is_like_windows {
34-
let ret_place = CPlace::new_stack_slot(fx, lhs.layout());
35-
let args =
36-
[ret_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)];
37-
fx.lib_call(
38-
"__multi3",
39-
vec![
40-
AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn),
41-
AbiParam::new(types::I128),
42-
AbiParam::new(types::I128),
43-
],
44-
vec![],
45-
&args,
46-
);
47-
Some(ret_place.to_cvalue(fx))
48-
} else {
49-
let args: Vec<_> = vec![lhs.load_scalar(fx), rhs.load_scalar(fx)];
50-
let ret_val = fx.lib_call(
51-
"__multi3",
52-
vec![AbiParam::new(types::I128), AbiParam::new(types::I128)],
53-
vec![AbiParam::new(types::I128)],
54-
&args,
55-
)[0];
56-
Some(CValue::by_val(ret_val, fx.layout_of(val_ty)))
57-
}
32+
let args = [lhs.load_scalar(fx), rhs.load_scalar(fx)];
33+
let ret_val = fx.lib_call(
34+
"__multi3",
35+
vec![AbiParam::new(types::I128), AbiParam::new(types::I128)],
36+
vec![AbiParam::new(types::I128)],
37+
&args,
38+
)[0];
39+
Some(CValue::by_val(
40+
ret_val,
41+
fx.layout_of(if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }),
42+
))
5843
} else {
5944
let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter());
6045
let oflow = CPlace::new_stack_slot(fx, fx.layout_of(fx.tcx.types.i32));
@@ -120,7 +105,7 @@ pub(crate) fn maybe_codegen<'tcx>(
120105
ret_place.to_ptr().store(fx, ret, MemFlags::trusted());
121106
Some(ret_place.to_cvalue(fx))
122107
} else {
123-
let args: Vec<_> = vec![lhs.load_scalar(fx), rhs.load_scalar(fx)];
108+
let args = [lhs.load_scalar(fx), rhs.load_scalar(fx)];
124109
let ret_val = fx.lib_call(
125110
name,
126111
vec![AbiParam::new(types::I128), AbiParam::new(types::I128)],

0 commit comments

Comments
 (0)