Skip to content

Commit 7685cde

Browse files
committed
Fix f128 ABI on s390x
1 parent 1302a4f commit 7685cde

1 file changed

Lines changed: 32 additions & 23 deletions

File tree

src/abi/mod.rs

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -139,41 +139,50 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
139139
mut returns: Vec<AbiParam>,
140140
args: &[Value],
141141
) -> Cow<'_, [Value]> {
142+
// FIXME any way to reuse the abi adjustment code in rustc_target?
143+
142144
// Pass i128 arguments by-ref on Windows.
143-
let (params, args): (Vec<_>, Cow<'_, [_]>) = if self.tcx.sess.target.is_like_windows {
144-
let (params, args): (Vec<_>, Vec<_>) = params
145-
.into_iter()
146-
.zip(args)
147-
.map(|(param, &arg)| {
148-
if param.value_type == types::I128 {
149-
let arg_ptr = self.create_stack_slot(16, 16);
150-
arg_ptr.store(self, arg, MemFlagsData::trusted());
151-
(AbiParam::new(self.pointer_type), arg_ptr.get_addr(self))
152-
} else {
153-
(param, arg)
154-
}
155-
})
156-
.unzip();
145+
let (params, args): (Vec<_>, Cow<'_, [_]>) =
146+
if self.tcx.sess.target.is_like_windows || self.tcx.sess.target.arch == Arch::S390x {
147+
let (params, args): (Vec<_>, Vec<_>) = params
148+
.into_iter()
149+
.zip(args)
150+
.map(|(param, &arg)| {
151+
if param.value_type == types::I128
152+
|| (self.tcx.sess.target.arch == Arch::S390x
153+
&& param.value_type == types::F128)
154+
{
155+
let arg_ptr = self.create_stack_slot(16, 16);
156+
arg_ptr.store(self, arg, MemFlagsData::trusted());
157+
(AbiParam::new(self.pointer_type), arg_ptr.get_addr(self))
158+
} else {
159+
(param, arg)
160+
}
161+
})
162+
.unzip();
157163

158-
(params, args.into())
159-
} else {
160-
(params, args.into())
161-
};
164+
(params, args.into())
165+
} else {
166+
(params, args.into())
167+
};
162168

163-
let ret_single_i128 = returns.len() == 1 && returns[0].value_type == types::I128;
164-
if ret_single_i128 && self.tcx.sess.target.is_like_windows {
169+
if self.tcx.sess.target.is_like_windows
170+
&& matches!(*returns, [AbiParam { value_type: types::I128, .. }])
171+
{
165172
// Return i128 using the vector ABI on Windows
166173
returns[0].value_type = types::I64X2;
167174

168175
let ret = self.lib_call_unadjusted(name, params, returns, &args)[0];
169176

170177
Cow::Owned(vec![codegen_bitcast(self, types::I128, ret)])
171-
} else if ret_single_i128 && self.tcx.sess.target.arch == Arch::S390x {
172-
// Return i128 using a return area pointer on s390x.
178+
} else if self.tcx.sess.target.arch == Arch::S390x
179+
&& matches!(*returns, [AbiParam { value_type: types::I128 | types::F128, .. }])
180+
{
181+
// Return i128 and f128 using a return area pointer on s390x.
173182
let mut params = params;
174183
let mut args = args.to_vec();
175184

176-
params.insert(0, AbiParam::new(self.pointer_type));
185+
params.insert(0, AbiParam::special(self.pointer_type, ArgumentPurpose::StructReturn));
177186
let ret_ptr = self.create_stack_slot(16, 16);
178187
args.insert(0, ret_ptr.get_addr(self));
179188

0 commit comments

Comments
 (0)