1 use rustc_hir::def_id::LOCAL_CRATE;
2 use rustc_middle::ty::query::Providers;
3 use rustc_session::Session;
4 use rustc_span::symbol::sym;
5 use rustc_span::symbol::Symbol;
7 // When adding features to the below lists
8 // check whether they're named already elsewhere in rust
9 // e.g. in stdarch and whether the given name matches LLVM's
10 // if it doesn't, to_llvm_feature in llvm_util in rustc_codegen_llvm needs to be adapted
12 const ARM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
13 ("aclass", Some(sym::arm_target_feature)),
14 ("mclass", Some(sym::arm_target_feature)),
15 ("rclass", Some(sym::arm_target_feature)),
16 ("dsp", Some(sym::arm_target_feature)),
17 ("neon", Some(sym::arm_target_feature)),
18 ("crc", Some(sym::arm_target_feature)),
19 ("crypto", Some(sym::arm_target_feature)),
20 ("v5te", Some(sym::arm_target_feature)),
21 ("v6", Some(sym::arm_target_feature)),
22 ("v6k", Some(sym::arm_target_feature)),
23 ("v6t2", Some(sym::arm_target_feature)),
24 ("v7", Some(sym::arm_target_feature)),
25 ("v8", Some(sym::arm_target_feature)),
26 ("vfp2", Some(sym::arm_target_feature)),
27 ("vfp3", Some(sym::arm_target_feature)),
28 ("vfp4", Some(sym::arm_target_feature)),
29 // This is needed for inline assembly, but shouldn't be stabilized as-is
30 // since it should be enabled per-function using #[instruction_set], not
32 ("thumb-mode", Some(sym::arm_target_feature)),
35 const AARCH64_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
36 ("fp", Some(sym::aarch64_target_feature)),
37 ("neon", Some(sym::aarch64_target_feature)),
38 ("sve", Some(sym::aarch64_target_feature)),
39 ("crc", Some(sym::aarch64_target_feature)),
40 ("crypto", Some(sym::aarch64_target_feature)),
41 ("ras", Some(sym::aarch64_target_feature)),
42 ("lse", Some(sym::aarch64_target_feature)),
43 ("rdm", Some(sym::aarch64_target_feature)),
44 ("fp16", Some(sym::aarch64_target_feature)),
45 ("rcpc", Some(sym::aarch64_target_feature)),
46 ("dotprod", Some(sym::aarch64_target_feature)),
47 ("tme", Some(sym::aarch64_target_feature)),
48 ("v8.1a", Some(sym::aarch64_target_feature)),
49 ("v8.2a", Some(sym::aarch64_target_feature)),
50 ("v8.3a", Some(sym::aarch64_target_feature)),
53 const X86_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
54 ("adx", Some(sym::adx_target_feature)),
58 ("avx512bf16", Some(sym::avx512_target_feature)),
59 ("avx512bitalg", Some(sym::avx512_target_feature)),
60 ("avx512bw", Some(sym::avx512_target_feature)),
61 ("avx512cd", Some(sym::avx512_target_feature)),
62 ("avx512dq", Some(sym::avx512_target_feature)),
63 ("avx512er", Some(sym::avx512_target_feature)),
64 ("avx512f", Some(sym::avx512_target_feature)),
65 ("avx512gfni", Some(sym::avx512_target_feature)),
66 ("avx512ifma", Some(sym::avx512_target_feature)),
67 ("avx512pf", Some(sym::avx512_target_feature)),
68 ("avx512vaes", Some(sym::avx512_target_feature)),
69 ("avx512vbmi", Some(sym::avx512_target_feature)),
70 ("avx512vbmi2", Some(sym::avx512_target_feature)),
71 ("avx512vl", Some(sym::avx512_target_feature)),
72 ("avx512vnni", Some(sym::avx512_target_feature)),
73 ("avx512vp2intersect", Some(sym::avx512_target_feature)),
74 ("avx512vpclmulqdq", Some(sym::avx512_target_feature)),
75 ("avx512vpopcntdq", Some(sym::avx512_target_feature)),
78 ("cmpxchg16b", Some(sym::cmpxchg16b_target_feature)),
79 ("ermsb", Some(sym::ermsb_target_feature)),
80 ("f16c", Some(sym::f16c_target_feature)),
84 ("movbe", Some(sym::movbe_target_feature)),
89 ("rtm", Some(sym::rtm_target_feature)),
96 ("sse4a", Some(sym::sse4a_target_feature)),
98 ("tbm", Some(sym::tbm_target_feature)),
105 const HEXAGON_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
106 ("hvx", Some(sym::hexagon_target_feature)),
107 ("hvx-length128b", Some(sym::hexagon_target_feature)),
110 const POWERPC_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
111 ("altivec", Some(sym::powerpc_target_feature)),
112 ("power8-altivec", Some(sym::powerpc_target_feature)),
113 ("power9-altivec", Some(sym::powerpc_target_feature)),
114 ("power8-vector", Some(sym::powerpc_target_feature)),
115 ("power9-vector", Some(sym::powerpc_target_feature)),
116 ("vsx", Some(sym::powerpc_target_feature)),
119 const MIPS_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] =
120 &[("fp64", Some(sym::mips_target_feature)), ("msa", Some(sym::mips_target_feature))];
122 const RISCV_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
123 ("m", Some(sym::riscv_target_feature)),
124 ("a", Some(sym::riscv_target_feature)),
125 ("c", Some(sym::riscv_target_feature)),
126 ("f", Some(sym::riscv_target_feature)),
127 ("d", Some(sym::riscv_target_feature)),
128 ("e", Some(sym::riscv_target_feature)),
131 const WASM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
132 ("simd128", Some(sym::wasm_target_feature)),
133 ("atomics", Some(sym::wasm_target_feature)),
134 ("nontrapping-fptoint", Some(sym::wasm_target_feature)),
137 /// When rustdoc is running, provide a list of all known features so that all their respective
138 /// primitives may be documented.
140 /// IMPORTANT: If you're adding another feature list above, make sure to add it to this iterator!
141 pub fn all_known_features() -> impl Iterator<Item = (&'static str, Option<Symbol>)> {
143 .chain(ARM_ALLOWED_FEATURES.iter())
144 .chain(AARCH64_ALLOWED_FEATURES.iter())
145 .chain(X86_ALLOWED_FEATURES.iter())
146 .chain(HEXAGON_ALLOWED_FEATURES.iter())
147 .chain(POWERPC_ALLOWED_FEATURES.iter())
148 .chain(MIPS_ALLOWED_FEATURES.iter())
149 .chain(RISCV_ALLOWED_FEATURES.iter())
150 .chain(WASM_ALLOWED_FEATURES.iter())
154 pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Option<Symbol>)] {
155 match &*sess.target.arch {
156 "arm" => ARM_ALLOWED_FEATURES,
157 "aarch64" => AARCH64_ALLOWED_FEATURES,
158 "x86" | "x86_64" => X86_ALLOWED_FEATURES,
159 "hexagon" => HEXAGON_ALLOWED_FEATURES,
160 "mips" | "mips64" => MIPS_ALLOWED_FEATURES,
161 "powerpc" | "powerpc64" => POWERPC_ALLOWED_FEATURES,
162 "riscv32" | "riscv64" => RISCV_ALLOWED_FEATURES,
163 "wasm32" => WASM_ALLOWED_FEATURES,
168 pub(crate) fn provide(providers: &mut Providers) {
169 providers.supported_target_features = |tcx, cnum| {
170 assert_eq!(cnum, LOCAL_CRATE);
171 if tcx.sess.opts.actually_rustdoc {
172 // rustdoc needs to be able to document functions that use all the features, so
173 // whitelist them all
174 all_known_features().map(|(a, b)| (a.to_string(), b)).collect()
176 supported_target_features(tcx.sess).iter().map(|&(a, b)| (a.to_string(), b)).collect()