Skip to content

Commit 43755fb

Browse files
committed
Add math functions for f16 and f128
This adds missing functions for math operations on the new float types. Platform support is pretty spotty at this point, since even platforms with generally good support can be missing math functions. `std/build.rs` is updated to reflect this.
1 parent b6d0517 commit 43755fb

File tree

9 files changed

+3443
-92
lines changed

9 files changed

+3443
-92
lines changed

library/std/build.rs

+37
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ fn main() {
8585
println!("cargo:rustc-check-cfg=cfg(reliable_f16)");
8686
println!("cargo:rustc-check-cfg=cfg(reliable_f128)");
8787

88+
// This is a step beyond only having the types and basic functions available. Math functions
89+
// aren't consistently available or correct.
90+
println!("cargo:rustc-check-cfg=cfg(reliable_f16_math)");
91+
println!("cargo:rustc-check-cfg=cfg(reliable_f128_math)");
92+
8893
let has_reliable_f16 = match (target_arch.as_str(), target_os.as_str()) {
8994
// Selection failure until recent LLVM <https://github.com/llvm/llvm-project/issues/93894>
9095
// FIXME(llvm19): can probably be removed at the version bump
@@ -128,10 +133,42 @@ fn main() {
128133
_ => false,
129134
};
130135

136+
// These are currently empty, but will fill up as some platforms move from completely
137+
// unreliable to reliable basics but unreliable math.
138+
139+
// LLVM is currenlty adding missing routines, <https://github.com/llvm/llvm-project/issues/93566>
140+
let has_reliable_f16_math = has_reliable_f16
141+
&& match (target_arch.as_str(), target_os.as_str()) {
142+
// Currently nothing special. Hooray!
143+
// This will change as platforms gain better better support for standard ops but math
144+
// lags behind.
145+
_ => true,
146+
};
147+
148+
let has_reliable_f128_math = has_reliable_f128
149+
&& match (target_arch.as_str(), target_os.as_str()) {
150+
// LLVM lowers `fp128` math to `long double` symbols even on platforms where
151+
// `long double` is not IEEE binary128. See
152+
// <https://github.com/llvm/llvm-project/issues/44744>.
153+
//
154+
// This rules out anything that doesn't have `long double` = `binary128`; <= 32 bits
155+
// (ld is `f64`), anything other than Linux (Windows and MacOS use ``f64`), and `x86`
156+
// (ld is 80-bit extended precision).
157+
("x86_64", _) => false,
158+
(_, "linux") if target_pointer_width == 64 => true,
159+
_ => false,
160+
};
161+
131162
if has_reliable_f16 {
132163
println!("cargo:rustc-cfg=reliable_f16");
133164
}
134165
if has_reliable_f128 {
135166
println!("cargo:rustc-cfg=reliable_f128");
136167
}
168+
if has_reliable_f16_math {
169+
println!("cargo:rustc-cfg=reliable_f16_math");
170+
}
171+
if has_reliable_f128_math {
172+
println!("cargo:rustc-cfg=reliable_f128_math");
173+
}
137174
}

0 commit comments

Comments
 (0)