Skip to content

Commit c6407b0

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 d9b1de5 commit c6407b0

File tree

7 files changed

+3452
-92
lines changed

7 files changed

+3452
-92
lines changed

Diff for: 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
@@ -130,10 +135,42 @@ fn main() {
130135
_ => false,
131136
};
132137

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

0 commit comments

Comments
 (0)