1
1
// Configuration shared with both libm and libm-test
2
2
3
- use std:: env;
4
3
use std:: path:: PathBuf ;
4
+ use std:: process:: { Command , Stdio } ;
5
+ use std:: { env, str} ;
5
6
6
7
#[ allow( dead_code) ]
7
8
pub struct Config {
8
9
pub manifest_dir : PathBuf ,
9
10
pub out_dir : PathBuf ,
10
11
pub opt_level : String ,
11
12
pub cargo_features : Vec < String > ,
13
+ pub target_triple : String ,
12
14
pub target_arch : String ,
13
15
pub target_env : String ,
14
16
pub target_family : Option < String > ,
15
17
pub target_os : String ,
16
18
pub target_string : String ,
17
19
pub target_vendor : String ,
18
20
pub target_features : Vec < String > ,
21
+ pub reliable_f128 : bool ,
22
+ pub reliable_f16 : bool ,
19
23
}
20
24
21
25
impl Config {
22
26
pub fn from_env ( ) -> Self {
27
+ let target_triple = env:: var ( "TARGET" ) . unwrap ( ) ;
23
28
let target_features = env:: var ( "CARGO_CFG_TARGET_FEATURE" )
24
29
. map ( |feats| feats. split ( ',' ) . map ( ToOwned :: to_owned) . collect ( ) )
25
30
. unwrap_or_default ( ) ;
@@ -28,7 +33,21 @@ impl Config {
28
33
. map ( |s| s. to_lowercase ( ) . replace ( "_" , "-" ) )
29
34
. collect ( ) ;
30
35
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
+
31
49
Self {
50
+ target_triple,
32
51
manifest_dir : PathBuf :: from ( env:: var ( "CARGO_MANIFEST_DIR" ) . unwrap ( ) ) ,
33
52
out_dir : PathBuf :: from ( env:: var ( "OUT_DIR" ) . unwrap ( ) ) ,
34
53
opt_level : env:: var ( "OPT_LEVEL" ) . unwrap ( ) ,
@@ -40,6 +59,8 @@ impl Config {
40
59
target_string : env:: var ( "TARGET" ) . unwrap ( ) ,
41
60
target_vendor : env:: var ( "CARGO_CFG_TARGET_VENDOR" ) . unwrap ( ) ,
42
61
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" ) ,
43
64
}
44
65
}
45
66
}
@@ -128,62 +149,18 @@ fn emit_f16_f128_cfg(cfg: &Config) {
128
149
return ;
129
150
}
130
151
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 */
178
153
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 ") ;
181
156
182
- if f16_enabled && !disable_both {
157
+ println ! ( "cargo:rustc-check-cfg=cfg(f16_enabled)" ) ;
158
+ if cfg. reliable_f16 && !no_f16_f128 {
183
159
println ! ( "cargo:rustc-cfg=f16_enabled" ) ;
184
160
}
185
161
186
- if f128_enabled && !disable_both {
162
+ println ! ( "cargo:rustc-check-cfg=cfg(f128_enabled)" ) ;
163
+ if cfg. reliable_f128 && !no_f16_f128 {
187
164
println ! ( "cargo:rustc-cfg=f128_enabled" ) ;
188
165
}
189
166
}
0 commit comments