Skip to content

Commit d8edcd5

Browse files
committed
Handle abi adjusting in lib_call correctly for s390x
1 parent 9fd3b18 commit d8edcd5

File tree

1 file changed

+29
-15
lines changed

1 file changed

+29
-15
lines changed

src/abi/mod.rs

+29-15
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,20 +141,33 @@ 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

159173
fn lib_call_unadjusted(
@@ -162,7 +176,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
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

0 commit comments

Comments
 (0)