Windows x86: Change i128 to return via the vector ABI

Clang and GCC both return `i128` in xmm0 on windows-msvc and
windows-gnu. Currently, Rust returns the type on the stack. Add a
calling convention adjustment so we also return scalar `i128`s using the
vector ABI, which makes our `i128` compatible with C.

In the future, Clang may change to return `i128` on the stack for its
`-msvc` targets (more at [1]). If this happens, the change here will
need to be adjusted to only affect MinGW.

Link: https://github.com/rust-lang/rust/issues/134288
This commit is contained in:
Trevor Gross
2024-12-14 00:32:39 +00:00
parent 581e0ac90c
commit a44a20ee4a
5 changed files with 44 additions and 67 deletions

View File

@@ -96,25 +96,9 @@ pub(crate) fn clif_int_or_float_cast(
},
);
if fx.tcx.sess.target.is_like_windows {
let ret = fx.lib_call(
&name,
vec![AbiParam::new(from_ty)],
vec![AbiParam::new(types::I64X2)],
&[from],
)[0];
// FIXME(bytecodealliance/wasmtime#6104) use bitcast instead of store to get from i64x2 to i128
let ret_ptr = fx.create_stack_slot(16, 16);
ret_ptr.store(fx, ret, MemFlags::trusted());
ret_ptr.load(fx, types::I128, MemFlags::trusted())
} else {
fx.lib_call(
&name,
vec![AbiParam::new(from_ty)],
vec![AbiParam::new(types::I128)],
&[from],
)[0]
}
fx.lib_call(&name, vec![AbiParam::new(from_ty)], vec![AbiParam::new(types::I128)], &[
from,
])[0]
} else if to_ty == types::I8 || to_ty == types::I16 {
// FIXME implement fcvt_to_*int_sat.i8/i16
let val = if to_signed {