Would somebody be able to point me to where x86 return ABI is figured out, specifically on Windows? I assume it has to be somewhere here but I can't find it https://github.com/bytecodealliance/wasmtime/blob/90ae123dc4f1c4d2e8c3bffaa61094d9a970d650/cranelift/codegen/src/isa/x64/abi.rs
f129 is currently returned in xmm0 but LLVM recently changed to return indirectly (matching GCC) so I'm looking to do the same update here
I think you'll want code somewhere around here perhaps (in that abi.rs file)
That and the block below it seem to only be for argument handling (at least, based on ArgsOrRets)
I was kind of trying to trace where the i128 handling would be since that's similar-ish, returning in registers on most platforms but xmm on Windows. But I couldn't seem to find it anywhere
the if above that I know I've seen before in terms of handling returns-of-i128, but I'm not immediately seeing where it connects to regalloc and such
it might be this loop though where reg_tys will have two elements for i64 I believe
Hm hm rc_for_type doesn't do any special handling for i128 and I don't see anything specific for Windows in that loop. Maybe clif doesn't actually have specific handling for windows i128 and the frontend handles that instead?
Since you're around, how do you get rustc to emit the .clif? I thought --emit=clif worked but it seems it doesn't
I wouldn't be surprised yeah if it's a frontend thing, I don't think we have native tests in cranelift itself about Rust code using a plain extern "C" to call an i128-returning function
for rustc emitting clif I'd ask bjorn3, I'm not sure myself
@bjorn3 do you happen to know more about how/where this works?
--emit=llvm-ir should work
Ah, it errors but still creates the files
RUSTFLAGS="-Zcodegen-backend=cranelift" cargo rustc -- --emit=llvm-ir
Compiling clif-f128 v0.1.0 (~/projects/scratch/clif-f128)
error: could not copy "/Users/tmgross/Documents/projects/scratch/clif-f128/target/debug/deps/clif_f128-d2d7b61ef0548f3f.edabakgdnj4dr38hhli25hfbo.0k4dnte.rcgu.ll" to "/Users/tmgross/Documents/projects/scratch/clif-f128/target/debug/deps/clif_f128-d2d7b61ef0548f3f.ll": No such file or directory (os error 2)
error: could not compile `clif-f128` (lib) due to 1 previous error
tmgross@quince-2 clif-f128 > fd . -e clif target
target/debug/deps/clif_f128-d2d7b61ef0548f3f.clif/
target/debug/deps/clif_f128-d2d7b61ef0548f3f.clif/pass_f128.opt.clif
target/debug/deps/clif_f128-d2d7b61ef0548f3f.clif/pass_f128.unopt.clif
target/debug/deps/clif_f128-d2d7b61ef0548f3f.clif/ret_f128.opt.clif
target/debug/deps/clif_f128-d2d7b61ef0548f3f.clif/ret_f128.unopt.clif
The windows i128 abi is implemented in rustc (through abi adjustments) and (for libcalls) in cg_clif (eg https://github.com/rust-lang/rustc_codegen_cranelift/blob/5bbb9e4f6618aa7c32bde230875fa36608e60bdf/src/abi/mod.rs#L164)
the rustc side: https://github.com/rust-lang/rust/blob/7ef36edc23ac10760eb9f097d32edbab2e1e8928/compiler/rustc_target/src/callconv/x86_win64.rs#L21
the copy error is because cg_ssa expects a single .ll file to be generated, while cg_clif produces a directory of files.
Doesn't cranelift itself need knowledge of the ABI? For knowing how to emit libcalls
(I'm looking at this all because of https://github.com/rust-lang/rust/pull/158918)
all 128bit libcalls are emitted as regular calls on the cg_clif side. Cranelift itself doesn't have libcalls for 128bit operations.
you could adjust the cg_clif code i linked to apply for f128 in addition to i128. together with the abi adjustment change you already do in your PR that should be enough to make it work.
Ah - so e.g. f128 * f128 is changed to __multf2 in the rustc backend before even hitting cranelift's codegen?
__multif3, but yes: https://github.com/rust-lang/rustc_codegen_cranelift/blob/5bbb9e4f6618aa7c32bde230875fa36608e60bdf/src/codegen_f16_f128.rs#L137
Alright, that all makes a lot more sense. Thanks for the help clearing this up
Last updated: Jul 29 2026 at 05:03 UTC