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 ,
23
+ pub reliable_f128_math : bool ,
24
+ pub reliable_f16_math : bool ,
19
25
}
20
26
21
27
impl Config {
22
28
pub fn from_env ( ) -> Self {
29
+ let target_triple = env:: var ( "TARGET" ) . unwrap ( ) ;
23
30
let target_features = env:: var ( "CARGO_CFG_TARGET_FEATURE" )
24
31
. map ( |feats| feats. split ( ',' ) . map ( ToOwned :: to_owned) . collect ( ) )
25
32
. unwrap_or_default ( ) ;
@@ -28,7 +35,21 @@ impl Config {
28
35
. map ( |s| s. to_lowercase ( ) . replace ( "_" , "-" ) )
29
36
. collect ( ) ;
30
37
38
+ // Query rustc for options that Cargo does not provide env for. The bootstrap hack is used
39
+ // to get consistent output regardless of channel (`f16`/`f128` config options are hidden
40
+ // on stable otherwise).
41
+ let mut cmd = Command :: new ( env:: var ( "RUSTC" ) . unwrap ( ) ) ;
42
+ cmd. args ( [ "--print=cfg" , "--target" , & target_triple] )
43
+ . env ( "RUSTC_BOOTSTRAP" , "1" )
44
+ . stderr ( Stdio :: inherit ( ) ) ;
45
+ let out = cmd
46
+ . output ( )
47
+ . unwrap_or_else ( |e| panic ! ( "failed to run `{cmd:?}`: {e}" ) ) ;
48
+ assert ! ( out. status. success( ) , "failed to run `{cmd:?}`" ) ;
49
+ let rustc_cfg = str:: from_utf8 ( & out. stdout ) . unwrap ( ) ;
50
+
31
51
Self {
52
+ target_triple,
32
53
manifest_dir : PathBuf :: from ( env:: var ( "CARGO_MANIFEST_DIR" ) . unwrap ( ) ) ,
33
54
out_dir : PathBuf :: from ( env:: var ( "OUT_DIR" ) . unwrap ( ) ) ,
34
55
opt_level : env:: var ( "OPT_LEVEL" ) . unwrap ( ) ,
@@ -40,6 +61,14 @@ impl Config {
40
61
target_string : env:: var ( "TARGET" ) . unwrap ( ) ,
41
62
target_vendor : env:: var ( "CARGO_CFG_TARGET_VENDOR" ) . unwrap ( ) ,
42
63
target_features,
64
+ reliable_f128 : rustc_cfg. lines ( ) . any ( |l| l == "target_has_reliable_f128" ) ,
65
+ reliable_f16 : rustc_cfg. lines ( ) . any ( |l| l == "target_has_reliable_f16" ) ,
66
+ reliable_f128_math : rustc_cfg
67
+ . lines ( )
68
+ . any ( |l| l == "target_has_reliable_f128_math" ) ,
69
+ reliable_f16_math : rustc_cfg
70
+ . lines ( )
71
+ . any ( |l| l == "target_has_reliable_f16_math" ) ,
43
72
}
44
73
}
45
74
}
@@ -128,62 +157,18 @@ fn emit_f16_f128_cfg(cfg: &Config) {
128
157
return ;
129
158
}
130
159
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 ( ) ;
160
+ /* See the compiler-builtins configure file for info about the meaning of these options */
178
161
179
- println ! ( "cargo:rustc-check-cfg=cfg(f16_enabled)" ) ;
180
- println ! ( "cargo:rustc-check-cfg= cfg(f128_enabled) ") ;
162
+ // If the feature is set, disable both of these types.
163
+ let no_f16_f128 = cfg. cargo_features . iter ( ) . any ( |s| s == "no-f16-f128 ") ;
181
164
182
- if f16_enabled && !disable_both {
165
+ println ! ( "cargo:rustc-check-cfg=cfg(f16_enabled)" ) ;
166
+ if cfg. reliable_f16 && !no_f16_f128 {
183
167
println ! ( "cargo:rustc-cfg=f16_enabled" ) ;
184
168
}
185
169
186
- if f128_enabled && !disable_both {
170
+ println ! ( "cargo:rustc-check-cfg=cfg(f128_enabled)" ) ;
171
+ if cfg. reliable_f128 && !no_f16_f128 {
187
172
println ! ( "cargo:rustc-cfg=f128_enabled" ) ;
188
173
}
189
174
}
0 commit comments