11// Configuration shared with both libm and libm-test
22
3- use std:: env;
43use std:: path:: PathBuf ;
4+ use std:: process:: { Command , Stdio } ;
5+ use std:: { env, str} ;
56
67#[ allow( dead_code) ]
78pub struct Config {
89 pub manifest_dir : PathBuf ,
910 pub out_dir : PathBuf ,
1011 pub opt_level : String ,
1112 pub cargo_features : Vec < String > ,
13+ pub target_triple : String ,
1214 pub target_arch : String ,
1315 pub target_env : String ,
1416 pub target_family : Option < String > ,
1517 pub target_os : String ,
1618 pub target_string : String ,
1719 pub target_vendor : String ,
1820 pub target_features : Vec < String > ,
21+ pub reliable_f128 : bool ,
22+ pub reliable_f16 : bool ,
1923}
2024
2125impl Config {
2226 pub fn from_env ( ) -> Self {
27+ let target_triple = env:: var ( "TARGET" ) . unwrap ( ) ;
2328 let target_features = env:: var ( "CARGO_CFG_TARGET_FEATURE" )
2429 . map ( |feats| feats. split ( ',' ) . map ( ToOwned :: to_owned) . collect ( ) )
2530 . unwrap_or_default ( ) ;
@@ -28,7 +33,21 @@ impl Config {
2833 . map ( |s| s. to_lowercase ( ) . replace ( "_" , "-" ) )
2934 . collect ( ) ;
3035
36+ // Query rustc for options that Cargo does not provide env for. The bootstrap hack is used
37+ // to get consistent output regardless of channel (`f16`/`f128` config options are hidden
38+ // on stable otherwise).
39+ let mut cmd = Command :: new ( env:: var ( "RUSTC" ) . unwrap ( ) ) ;
40+ cmd. args ( [ "--print=cfg" , "--target" , & target_triple] )
41+ . env ( "RUSTC_BOOTSTRAP" , "1" )
42+ . stderr ( Stdio :: inherit ( ) ) ;
43+ let out = cmd
44+ . output ( )
45+ . unwrap_or_else ( |e| panic ! ( "failed to run `{cmd:?}`: {e}" ) ) ;
46+ assert ! ( out. status. success( ) , "failed to run `{cmd:?}`" ) ;
47+ let rustc_cfg = str:: from_utf8 ( & out. stdout ) . unwrap ( ) ;
48+
3149 Self {
50+ target_triple,
3251 manifest_dir : PathBuf :: from ( env:: var ( "CARGO_MANIFEST_DIR" ) . unwrap ( ) ) ,
3352 out_dir : PathBuf :: from ( env:: var ( "OUT_DIR" ) . unwrap ( ) ) ,
3453 opt_level : env:: var ( "OPT_LEVEL" ) . unwrap ( ) ,
@@ -40,6 +59,8 @@ impl Config {
4059 target_string : env:: var ( "TARGET" ) . unwrap ( ) ,
4160 target_vendor : env:: var ( "CARGO_CFG_TARGET_VENDOR" ) . unwrap ( ) ,
4261 target_features,
62+ reliable_f128 : rustc_cfg. lines ( ) . any ( |l| l == "target_has_reliable_f128" ) ,
63+ reliable_f16 : rustc_cfg. lines ( ) . any ( |l| l == "target_has_reliable_f16" ) ,
4364 }
4465 }
4566}
@@ -128,62 +149,18 @@ fn emit_f16_f128_cfg(cfg: &Config) {
128149 return ;
129150 }
130151
131- // Set whether or not `f16` and `f128` are supported at a basic level by LLVM. This only means
132- // that the backend will not crash when using these types and generates code that can be called
133- // without crashing (no infinite recursion). This does not mean that the platform doesn't have
134- // ABI or other bugs.
135- //
136- // We do this here rather than in `rust-lang/rust` because configuring via cargo features is
137- // not straightforward.
138- //
139- // Original source of this list:
140- // <https://github.com/rust-lang/compiler-builtins/pull/652#issuecomment-2266151350>
141- let f16_enabled = match cfg. target_arch . as_str ( ) {
142- // Unsupported <https://github.com/llvm/llvm-project/issues/94434>
143- "arm64ec" => false ,
144- // Selection failure <https://github.com/llvm/llvm-project/issues/50374>
145- "s390x" => false ,
146- // Infinite recursion <https://github.com/llvm/llvm-project/issues/97981>
147- // FIXME(llvm): loongarch fixed by <https://github.com/llvm/llvm-project/pull/107791>
148- "csky" => false ,
149- "hexagon" => false ,
150- "loongarch64" => false ,
151- "mips" | "mips64" | "mips32r6" | "mips64r6" => false ,
152- "powerpc" | "powerpc64" => false ,
153- "sparc" | "sparc64" => false ,
154- "wasm32" | "wasm64" => false ,
155- // Most everything else works as of LLVM 19
156- _ => true ,
157- } ;
158-
159- let f128_enabled = match cfg. target_arch . as_str ( ) {
160- // Unsupported (libcall is not supported) <https://github.com/llvm/llvm-project/issues/121122>
161- "amdgpu" => false ,
162- // Unsupported <https://github.com/llvm/llvm-project/issues/94434>
163- "arm64ec" => false ,
164- // Selection failure <https://github.com/llvm/llvm-project/issues/96432>
165- "mips64" | "mips64r6" => false ,
166- // Selection failure <https://github.com/llvm/llvm-project/issues/95471>
167- "nvptx64" => false ,
168- // Selection failure <https://github.com/llvm/llvm-project/issues/101545>
169- "powerpc64" if & cfg. target_os == "aix" => false ,
170- // Selection failure <https://github.com/llvm/llvm-project/issues/41838>
171- "sparc" => false ,
172- // Most everything else works as of LLVM 19
173- _ => true ,
174- } ;
175-
176- // If the feature is set, disable these types.
177- let disable_both = env:: var_os ( "CARGO_FEATURE_NO_F16_F128" ) . is_some ( ) ;
152+ /* See the compiler-builtins configure file for info about the meaning of these options */
178153
179- println ! ( "cargo:rustc-check-cfg=cfg(f16_enabled)" ) ;
180- println ! ( "cargo:rustc-check-cfg= cfg(f128_enabled) ") ;
154+ // If the feature is set, disable both of these types.
155+ let no_f16_f128 = cfg. cargo_features . iter ( ) . any ( |s| s == "no-f16-f128 ") ;
181156
182- if f16_enabled && !disable_both {
157+ println ! ( "cargo:rustc-check-cfg=cfg(f16_enabled)" ) ;
158+ if cfg. reliable_f16 && !no_f16_f128 {
183159 println ! ( "cargo:rustc-cfg=f16_enabled" ) ;
184160 }
185161
186- if f128_enabled && !disable_both {
162+ println ! ( "cargo:rustc-check-cfg=cfg(f128_enabled)" ) ;
163+ if cfg. reliable_f128 && !no_f16_f128 {
187164 println ! ( "cargo:rustc-cfg=f128_enabled" ) ;
188165 }
189166}
0 commit comments