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

Commit ede7cde

Browse files
committed
Move windows i128 argument by-ref handling to lib_call
1 parent 7bd3b77 commit ede7cde

File tree

3 files changed

+40
-63
lines changed

3 files changed

+40
-63
lines changed

src/abi/mod.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,28 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
117117
returns: Vec<AbiParam>,
118118
args: &[Value],
119119
) -> &[Value] {
120+
if self.tcx.sess.target.is_like_windows
121+
&& params.iter().any(|param| param.value_type == types::I128)
122+
{
123+
let (params, args): (Vec<_>, Vec<_>) =
124+
params
125+
.into_iter()
126+
.zip(args)
127+
.map(|(param, &arg)| {
128+
if param.value_type == types::I128 {
129+
let arg_ptr = Pointer::stack_slot(self.bcx.create_sized_stack_slot(
130+
StackSlotData { kind: StackSlotKind::ExplicitSlot, size: 16 },
131+
));
132+
arg_ptr.store(self, arg, MemFlags::trusted());
133+
(AbiParam::new(self.pointer_type), arg_ptr.get_addr(self))
134+
} else {
135+
(param, arg)
136+
}
137+
})
138+
.unzip();
139+
return self.lib_call(name, params, returns, &args);
140+
}
141+
120142
let sig = Signature { params, returns, call_conv: self.target_config.default_call_conv };
121143
let func_id = self.module.declare_function(name, Linkage::Import, &sig).unwrap();
122144
let func_ref = self.module.declare_func_in_func(func_id, &mut self.bcx.func);

src/cast.rs

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -64,29 +64,12 @@ pub(crate) fn clif_int_or_float_cast(
6464
},
6565
);
6666

67-
if fx.tcx.sess.target.is_like_windows {
68-
// FIXME move this logic into lib_call
69-
let arg_place = CPlace::new_stack_slot(
70-
fx,
71-
fx.layout_of(if from_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }),
72-
);
73-
let arg_ptr = arg_place.to_ptr();
74-
arg_ptr.store(fx, from, MemFlags::trusted());
75-
let args = [arg_ptr.get_addr(fx)];
76-
return fx.lib_call(
77-
&name,
78-
vec![AbiParam::new(fx.pointer_type)],
79-
vec![AbiParam::new(to_ty)],
80-
&args,
81-
)[0];
82-
} else {
83-
return fx.lib_call(
84-
&name,
85-
vec![AbiParam::new(types::I128)],
86-
vec![AbiParam::new(to_ty)],
87-
&[from],
88-
)[0];
89-
}
67+
return fx.lib_call(
68+
&name,
69+
vec![AbiParam::new(types::I128)],
70+
vec![AbiParam::new(to_ty)],
71+
&[from],
72+
)[0];
9073
}
9174

9275
// int-like -> float

src/codegen_i128.rs

Lines changed: 12 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,14 @@ pub(crate) fn maybe_codegen<'tcx>(
3232
let val_ty = if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 };
3333
if fx.tcx.sess.target.is_like_windows {
3434
let ret_place = CPlace::new_stack_slot(fx, lhs.layout());
35-
let (lhs_ptr, lhs_extra) = lhs.force_stack(fx);
36-
let (rhs_ptr, rhs_extra) = rhs.force_stack(fx);
37-
assert!(lhs_extra.is_none());
38-
assert!(rhs_extra.is_none());
39-
let args = [
40-
ret_place.to_ptr().get_addr(fx),
41-
lhs_ptr.get_addr(fx),
42-
rhs_ptr.get_addr(fx),
43-
];
35+
let args =
36+
[ret_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)];
4437
fx.lib_call(
4538
"__multi3",
4639
vec![
4740
AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn),
48-
AbiParam::new(fx.pointer_type),
49-
AbiParam::new(fx.pointer_type),
41+
AbiParam::new(types::I128),
42+
AbiParam::new(types::I128),
5043
],
5144
vec![],
5245
&args,
@@ -87,29 +80,12 @@ pub(crate) fn maybe_codegen<'tcx>(
8780
assert!(checked);
8881
let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter());
8982
let out_place = CPlace::new_stack_slot(fx, fx.layout_of(out_ty));
90-
let (param_types, args) = if fx.tcx.sess.target.is_like_windows {
91-
let (lhs_ptr, lhs_extra) = lhs.force_stack(fx);
92-
let (rhs_ptr, rhs_extra) = rhs.force_stack(fx);
93-
assert!(lhs_extra.is_none());
94-
assert!(rhs_extra.is_none());
95-
(
96-
vec![
97-
AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn),
98-
AbiParam::new(fx.pointer_type),
99-
AbiParam::new(fx.pointer_type),
100-
],
101-
[out_place.to_ptr().get_addr(fx), lhs_ptr.get_addr(fx), rhs_ptr.get_addr(fx)],
102-
)
103-
} else {
104-
(
105-
vec![
106-
AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn),
107-
AbiParam::new(types::I128),
108-
AbiParam::new(types::I128),
109-
],
110-
[out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)],
111-
)
112-
};
83+
let param_types = vec![
84+
AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn),
85+
AbiParam::new(types::I128),
86+
AbiParam::new(types::I128),
87+
];
88+
let args = [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)];
11389
let name = match (bin_op, is_signed) {
11490
(BinOp::Add, false) => "__rust_u128_addo",
11591
(BinOp::Add, true) => "__rust_i128_addo",
@@ -132,14 +108,10 @@ pub(crate) fn maybe_codegen<'tcx>(
132108
_ => unreachable!(),
133109
};
134110
if fx.tcx.sess.target.is_like_windows {
135-
let (lhs_ptr, lhs_extra) = lhs.force_stack(fx);
136-
let (rhs_ptr, rhs_extra) = rhs.force_stack(fx);
137-
assert!(lhs_extra.is_none());
138-
assert!(rhs_extra.is_none());
139-
let args = [lhs_ptr.get_addr(fx), rhs_ptr.get_addr(fx)];
111+
let args = [lhs.load_scalar(fx), rhs.load_scalar(fx)];
140112
let ret = fx.lib_call(
141113
name,
142-
vec![AbiParam::new(fx.pointer_type), AbiParam::new(fx.pointer_type)],
114+
vec![AbiParam::new(types::I128), AbiParam::new(types::I128)],
143115
vec![AbiParam::new(types::I64X2)],
144116
&args,
145117
)[0];

0 commit comments

Comments
 (0)