Skip to content

Commit 7e0d1b6

Browse files
authored
Merge pull request rust-lang#1546 from rust-lang/libcall_abi_fixes
Fix the ABI for libcalls
2 parents 0974099 + d8edcd5 commit 7e0d1b6

File tree

2 files changed

+36
-37
lines changed

2 files changed

+36
-37
lines changed

src/abi/mod.rs

+30-16
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,9 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
125125
returns: Vec<AbiParam>,
126126
args: &[Value],
127127
) -> Cow<'_, [Value]> {
128-
if self.tcx.sess.target.is_like_windows {
129-
let (mut params, mut args): (Vec<_>, Vec<_>) = params
128+
// Pass i128 arguments by-ref on Windows.
129+
let (params, args): (Vec<_>, Cow<'_, [_]>) = if self.tcx.sess.target.is_like_windows {
130+
let (params, args): (Vec<_>, Vec<_>) = params
130131
.into_iter()
131132
.zip(args)
132133
.map(|(param, &arg)| {
@@ -140,29 +141,42 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
140141
})
141142
.unzip();
142143

143-
let indirect_ret_val = returns.len() == 1 && returns[0].value_type == types::I128;
144+
(params, args.into())
145+
} else {
146+
(params, args.into())
147+
};
144148

145-
if indirect_ret_val {
146-
params.insert(0, AbiParam::new(self.pointer_type));
147-
let ret_ptr = self.create_stack_slot(16, 16);
148-
args.insert(0, ret_ptr.get_addr(self));
149-
self.lib_call_unadjusted(name, params, vec![], &args);
150-
return Cow::Owned(vec![ret_ptr.load(self, types::I128, MemFlags::trusted())]);
149+
// Return i128 using a return area pointer on Windows and s390x.
150+
let adjust_ret_param =
151+
if self.tcx.sess.target.is_like_windows || self.tcx.sess.target.arch == "s390x" {
152+
returns.len() == 1 && returns[0].value_type == types::I128
151153
} else {
152-
return self.lib_call_unadjusted(name, params, returns, &args);
153-
}
154-
}
154+
false
155+
};
156+
157+
if adjust_ret_param {
158+
let mut params = params;
159+
let mut args = args.to_vec();
155160

156-
self.lib_call_unadjusted(name, params, returns, args)
161+
params.insert(0, AbiParam::new(self.pointer_type));
162+
let ret_ptr = self.create_stack_slot(16, 16);
163+
args.insert(0, ret_ptr.get_addr(self));
164+
165+
self.lib_call_unadjusted(name, params, vec![], &args);
166+
167+
Cow::Owned(vec![ret_ptr.load(self, types::I128, MemFlags::trusted())])
168+
} else {
169+
Cow::Borrowed(self.lib_call_unadjusted(name, params, returns, &args))
170+
}
157171
}
158172

159-
pub(crate) fn lib_call_unadjusted(
173+
fn lib_call_unadjusted(
160174
&mut self,
161175
name: &str,
162176
params: Vec<AbiParam>,
163177
returns: Vec<AbiParam>,
164178
args: &[Value],
165-
) -> Cow<'_, [Value]> {
179+
) -> &[Value] {
166180
let sig = Signature { params, returns, call_conv: self.target_config.default_call_conv };
167181
let func_id = self.module.declare_function(name, Linkage::Import, &sig).unwrap();
168182
let func_ref = self.module.declare_func_in_func(func_id, &mut self.bcx.func);
@@ -175,7 +189,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
175189
}
176190
let results = self.bcx.inst_results(call_inst);
177191
assert!(results.len() <= 2, "{}", results.len());
178-
Cow::Borrowed(results)
192+
results
179193
}
180194
}
181195

src/codegen_i128.rs

+6-21
Original file line numberDiff line numberDiff line change
@@ -81,26 +81,6 @@ pub(crate) fn maybe_codegen_checked<'tcx>(
8181
match bin_op {
8282
BinOp::BitAnd | BinOp::BitOr | BinOp::BitXor => unreachable!(),
8383
BinOp::Add | BinOp::Sub => None,
84-
BinOp::Mul if is_signed => {
85-
let out_ty = Ty::new_tup(fx.tcx, &[lhs.layout().ty, fx.tcx.types.bool]);
86-
let oflow = CPlace::new_stack_slot(fx, fx.layout_of(fx.tcx.types.i32));
87-
let lhs = lhs.load_scalar(fx);
88-
let rhs = rhs.load_scalar(fx);
89-
let oflow_ptr = oflow.to_ptr().get_addr(fx);
90-
let res = fx.lib_call_unadjusted(
91-
"__muloti4",
92-
vec![
93-
AbiParam::new(types::I128),
94-
AbiParam::new(types::I128),
95-
AbiParam::new(fx.pointer_type),
96-
],
97-
vec![AbiParam::new(types::I128)],
98-
&[lhs, rhs, oflow_ptr],
99-
)[0];
100-
let oflow = oflow.to_cvalue(fx).load_scalar(fx);
101-
let oflow = fx.bcx.ins().ireduce(types::I8, oflow);
102-
Some(CValue::by_val_pair(res, oflow, fx.layout_of(out_ty)))
103-
}
10484
BinOp::Mul => {
10585
let out_ty = Ty::new_tup(fx.tcx, &[lhs.layout().ty, fx.tcx.types.bool]);
10686
let out_place = CPlace::new_stack_slot(fx, fx.layout_of(out_ty));
@@ -110,7 +90,12 @@ pub(crate) fn maybe_codegen_checked<'tcx>(
11090
AbiParam::new(types::I128),
11191
];
11292
let args = [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)];
113-
fx.lib_call("__rust_u128_mulo", param_types, vec![], &args);
93+
fx.lib_call(
94+
if is_signed { "__rust_i128_mulo" } else { "__rust_u128_mulo" },
95+
param_types,
96+
vec![],
97+
&args,
98+
);
11499
Some(out_place.to_cvalue(fx))
115100
}
116101
BinOp::AddUnchecked | BinOp::SubUnchecked | BinOp::MulUnchecked => unreachable!(),

0 commit comments

Comments
 (0)