• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Configuration that is shared between `compiler_builtins` and `testcrate`.
2 
3 use std::env;
4 
5 #[derive(Debug)]
6 #[allow(dead_code)]
7 pub struct Target {
8     pub triple: String,
9     pub os: String,
10     pub arch: String,
11     pub vendor: String,
12     pub env: String,
13     pub pointer_width: u8,
14     pub little_endian: bool,
15     pub features: Vec<String>,
16 }
17 
18 impl Target {
from_env() -> Self19     pub fn from_env() -> Self {
20         let little_endian = match env::var("CARGO_CFG_TARGET_ENDIAN").unwrap().as_str() {
21             "little" => true,
22             "big" => false,
23             x => panic!("unknown endian {x}"),
24         };
25 
26         Self {
27             triple: env::var("TARGET").unwrap(),
28             os: env::var("CARGO_CFG_TARGET_OS").unwrap(),
29             arch: env::var("CARGO_CFG_TARGET_ARCH").unwrap(),
30             vendor: env::var("CARGO_CFG_TARGET_VENDOR").unwrap(),
31             env: env::var("CARGO_CFG_TARGET_ENV").unwrap(),
32             pointer_width: env::var("CARGO_CFG_TARGET_POINTER_WIDTH")
33                 .unwrap()
34                 .parse()
35                 .unwrap(),
36             little_endian,
37             features: env::var("CARGO_CFG_TARGET_FEATURE")
38                 .unwrap_or_default()
39                 .split(",")
40                 .map(ToOwned::to_owned)
41                 .collect(),
42         }
43     }
44 
45     #[allow(dead_code)]
has_feature(&self, feature: &str) -> bool46     pub fn has_feature(&self, feature: &str) -> bool {
47         self.features.iter().any(|f| f == feature)
48     }
49 }
50 
51 /// Configure whether or not `f16` and `f128` support should be enabled.
configure_f16_f128(target: &Target)52 pub fn configure_f16_f128(target: &Target) {
53     // Set whether or not `f16` and `f128` are supported at a basic level by LLVM. This only means
54     // that the backend will not crash when using these types. This does not mean that the
55     // backend does the right thing, or that the platform doesn't have ABI bugs.
56     //
57     // We do this here rather than in `rust-lang/rust` because configuring via cargo features is
58     // not straightforward.
59     //
60     // Original source of this list:
61     // <https://github.com/rust-lang/compiler-builtins/pull/652#issuecomment-2266151350>
62     let (f16_ok, f128_ok) = match target.arch.as_str() {
63         // `f16` and `f128` both crash <https://github.com/llvm/llvm-project/issues/94434>
64         "arm64ec" => (false, false),
65         // `f16` crashes <https://github.com/llvm/llvm-project/issues/50374>
66         "s390x" => (false, true),
67         // `f128` crashes <https://github.com/llvm/llvm-project/issues/96432>
68         "mips64" | "mips64r6" => (true, false),
69         // `f128` crashes <https://github.com/llvm/llvm-project/issues/101545>
70         "powerpc64" if &target.os == "aix" => (true, false),
71         // `f128` crashes <https://github.com/llvm/llvm-project/issues/41838>
72         "sparc" | "sparcv9" => (true, false),
73         // `f16` miscompiles <https://github.com/llvm/llvm-project/issues/96438>
74         "wasm32" | "wasm64" => (false, true),
75         // Most everything else works as of LLVM 19
76         _ => (true, true),
77     };
78 
79     // If the feature is set, disable these types.
80     let disable_both = env::var_os("CARGO_FEATURE_NO_F16_F128").is_some();
81 
82     println!("cargo::rustc-check-cfg=cfg(f16_enabled)");
83     println!("cargo::rustc-check-cfg=cfg(f128_enabled)");
84 
85     if f16_ok && !disable_both {
86         println!("cargo::rustc-cfg=f16_enabled");
87     }
88 
89     if f128_ok && !disable_both {
90         println!("cargo::rustc-cfg=f128_enabled");
91     }
92 }
93