1use rustc_data_structures::fx::{FxHashMap, FxHashSet};
5use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
6use rustc_span::{Symbol, sym};
7
8use crate::spec::{FloatAbi, RustcAbi, Target};
9
10pub const RUSTC_SPECIFIC_FEATURES: &[&str] = &["crt-static"];
13
14pub const RUSTC_SPECIAL_FEATURES: &[&str] = &["backchain"];
18
19#[derive(Debug, Copy, Clone)]
21pub enum Stability {
22 Stable,
25 Unstable(
28 Symbol,
31 ),
32 Forbidden { reason: &'static str },
37}
38use Stability::*;
39
40impl<CTX> HashStable<CTX> for Stability {
41 #[inline]
42 fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
43 std::mem::discriminant(self).hash_stable(hcx, hasher);
44 match self {
45 Stability::Stable => {}
46 Stability::Unstable(nightly_feature) => {
47 nightly_feature.hash_stable(hcx, hasher);
48 }
49 Stability::Forbidden { reason } => {
50 reason.hash_stable(hcx, hasher);
51 }
52 }
53 }
54}
55
56impl Stability {
57 pub fn in_cfg(&self) -> bool {
61 !matches!(self, Stability::Forbidden { .. })
62 }
63
64 pub fn requires_nightly(&self) -> Option<Symbol> {
73 match *self {
74 Stability::Unstable(nightly_feature) => Some(nightly_feature),
75 Stability::Stable { .. } => None,
76 Stability::Forbidden { .. } => panic!("forbidden features should not reach this far"),
77 }
78 }
79
80 pub fn toggle_allowed(&self) -> Result<(), &'static str> {
84 match self {
85 Stability::Forbidden { reason } => Err(reason),
86 _ => Ok(()),
87 }
88 }
89}
90
91type ImpliedFeatures = &'static [&'static str];
133
134static ARM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
135 ("aclass", Unstable(sym::arm_target_feature), &[]),
137 ("aes", Unstable(sym::arm_target_feature), &["neon"]),
138 (
139 "atomics-32",
140 Stability::Forbidden { reason: "unsound because it changes the ABI of atomic operations" },
141 &[],
142 ),
143 ("crc", Unstable(sym::arm_target_feature), &[]),
144 ("d32", Unstable(sym::arm_target_feature), &[]),
145 ("dotprod", Unstable(sym::arm_target_feature), &["neon"]),
146 ("dsp", Unstable(sym::arm_target_feature), &[]),
147 ("fp-armv8", Unstable(sym::arm_target_feature), &["vfp4"]),
148 ("fp16", Unstable(sym::arm_target_feature), &["neon"]),
149 ("fpregs", Unstable(sym::arm_target_feature), &[]),
150 ("i8mm", Unstable(sym::arm_target_feature), &["neon"]),
151 ("mclass", Unstable(sym::arm_target_feature), &[]),
152 ("neon", Unstable(sym::arm_target_feature), &["vfp3"]),
153 ("rclass", Unstable(sym::arm_target_feature), &[]),
154 ("sha2", Unstable(sym::arm_target_feature), &["neon"]),
155 ("soft-float", Unstable(sym::arm_target_feature), &[]),
160 ("thumb-mode", Unstable(sym::arm_target_feature), &[]),
164 ("thumb2", Unstable(sym::arm_target_feature), &[]),
165 ("trustzone", Unstable(sym::arm_target_feature), &[]),
166 ("v5te", Unstable(sym::arm_target_feature), &[]),
167 ("v6", Unstable(sym::arm_target_feature), &["v5te"]),
168 ("v6k", Unstable(sym::arm_target_feature), &["v6"]),
169 ("v6t2", Unstable(sym::arm_target_feature), &["v6k", "thumb2"]),
170 ("v7", Unstable(sym::arm_target_feature), &["v6t2"]),
171 ("v8", Unstable(sym::arm_target_feature), &["v7"]),
172 ("vfp2", Unstable(sym::arm_target_feature), &[]),
173 ("vfp3", Unstable(sym::arm_target_feature), &["vfp2", "d32"]),
174 ("vfp4", Unstable(sym::arm_target_feature), &["vfp3"]),
175 ("virtualization", Unstable(sym::arm_target_feature), &[]),
176 ];
178
179static AARCH64_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
180 ("aes", Stable, &["neon"]),
183 ("bf16", Stable, &[]),
185 ("bti", Stable, &[]),
187 ("crc", Stable, &[]),
189 ("cssc", Unstable(sym::aarch64_unstable_target_feature), &[]),
191 ("dit", Stable, &[]),
193 ("dotprod", Stable, &["neon"]),
195 ("dpb", Stable, &[]),
197 ("dpb2", Stable, &["dpb"]),
199 ("ecv", Unstable(sym::aarch64_unstable_target_feature), &[]),
201 ("f32mm", Stable, &["sve"]),
203 ("f64mm", Stable, &["sve"]),
205 ("faminmax", Unstable(sym::aarch64_unstable_target_feature), &[]),
207 ("fcma", Stable, &["neon"]),
209 ("fhm", Stable, &["fp16"]),
211 ("flagm", Stable, &[]),
213 ("flagm2", Unstable(sym::aarch64_unstable_target_feature), &[]),
215 ("fp-armv8", Stability::Forbidden { reason: "Rust ties `fp-armv8` to `neon`" }, &[]),
217 ("fp16", Stable, &["neon"]),
220 ("fp8", Unstable(sym::aarch64_unstable_target_feature), &["faminmax", "lut", "bf16"]),
222 ("fp8dot2", Unstable(sym::aarch64_unstable_target_feature), &["fp8dot4"]),
224 ("fp8dot4", Unstable(sym::aarch64_unstable_target_feature), &["fp8fma"]),
226 ("fp8fma", Unstable(sym::aarch64_unstable_target_feature), &["fp8"]),
228 ("frintts", Stable, &[]),
230 ("hbc", Unstable(sym::aarch64_unstable_target_feature), &[]),
232 ("i8mm", Stable, &[]),
234 ("jsconv", Stable, &["neon"]),
237 ("lor", Stable, &[]),
239 ("lse", Stable, &[]),
241 ("lse128", Unstable(sym::aarch64_unstable_target_feature), &["lse"]),
243 ("lse2", Unstable(sym::aarch64_unstable_target_feature), &[]),
245 ("lut", Unstable(sym::aarch64_unstable_target_feature), &[]),
247 ("mops", Unstable(sym::aarch64_unstable_target_feature), &[]),
249 ("mte", Stable, &[]),
251 ("neon", Stable, &[]),
253 ("paca", Stable, &[]),
255 ("pacg", Stable, &[]),
257 ("pan", Stable, &[]),
259 ("pauth-lr", Unstable(sym::aarch64_unstable_target_feature), &[]),
261 ("pmuv3", Stable, &[]),
263 ("rand", Stable, &[]),
265 ("ras", Stable, &[]),
267 ("rcpc", Stable, &[]),
269 ("rcpc2", Stable, &["rcpc"]),
271 ("rcpc3", Unstable(sym::aarch64_unstable_target_feature), &["rcpc2"]),
273 ("rdm", Stable, &["neon"]),
275 ("reserve-x18", Unstable(sym::aarch64_unstable_target_feature), &[]),
281 ("sb", Stable, &[]),
283 ("sha2", Stable, &["neon"]),
285 ("sha3", Stable, &["sha2"]),
287 ("sm4", Stable, &["neon"]),
289 ("sme", Unstable(sym::aarch64_unstable_target_feature), &["bf16"]),
291 ("sme-b16b16", Unstable(sym::aarch64_unstable_target_feature), &["bf16", "sme2", "sve-b16b16"]),
293 ("sme-f16f16", Unstable(sym::aarch64_unstable_target_feature), &["sme2"]),
295 ("sme-f64f64", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
297 ("sme-f8f16", Unstable(sym::aarch64_unstable_target_feature), &["sme-f8f32"]),
299 ("sme-f8f32", Unstable(sym::aarch64_unstable_target_feature), &["sme2", "fp8"]),
301 ("sme-fa64", Unstable(sym::aarch64_unstable_target_feature), &["sme", "sve2"]),
303 ("sme-i16i64", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
305 ("sme-lutv2", Unstable(sym::aarch64_unstable_target_feature), &[]),
307 ("sme2", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
309 ("sme2p1", Unstable(sym::aarch64_unstable_target_feature), &["sme2"]),
311 ("spe", Stable, &[]),
313 ("ssbs", Stable, &[]),
315 ("ssve-fp8dot2", Unstable(sym::aarch64_unstable_target_feature), &["ssve-fp8dot4"]),
317 ("ssve-fp8dot4", Unstable(sym::aarch64_unstable_target_feature), &["ssve-fp8fma"]),
319 ("ssve-fp8fma", Unstable(sym::aarch64_unstable_target_feature), &["sme2", "fp8"]),
321 ("sve", Stable, &["neon"]),
329 ("sve-b16b16", Unstable(sym::aarch64_unstable_target_feature), &["bf16"]),
331 ("sve2", Stable, &["sve"]),
333 ("sve2-aes", Stable, &["sve2", "aes"]),
335 ("sve2-bitperm", Stable, &["sve2"]),
337 ("sve2-sha3", Stable, &["sve2", "sha3"]),
339 ("sve2-sm4", Stable, &["sve2", "sm4"]),
341 ("sve2p1", Unstable(sym::aarch64_unstable_target_feature), &["sve2"]),
343 ("tme", Stable, &[]),
345 (
346 "v8.1a",
347 Unstable(sym::aarch64_ver_target_feature),
348 &["crc", "lse", "rdm", "pan", "lor", "vh"],
349 ),
350 ("v8.2a", Unstable(sym::aarch64_ver_target_feature), &["v8.1a", "ras", "dpb"]),
351 (
352 "v8.3a",
353 Unstable(sym::aarch64_ver_target_feature),
354 &["v8.2a", "rcpc", "paca", "pacg", "jsconv"],
355 ),
356 ("v8.4a", Unstable(sym::aarch64_ver_target_feature), &["v8.3a", "dotprod", "dit", "flagm"]),
357 ("v8.5a", Unstable(sym::aarch64_ver_target_feature), &["v8.4a", "ssbs", "sb", "dpb2", "bti"]),
358 ("v8.6a", Unstable(sym::aarch64_ver_target_feature), &["v8.5a", "bf16", "i8mm"]),
359 ("v8.7a", Unstable(sym::aarch64_ver_target_feature), &["v8.6a", "wfxt"]),
360 ("v8.8a", Unstable(sym::aarch64_ver_target_feature), &["v8.7a", "hbc", "mops"]),
361 ("v8.9a", Unstable(sym::aarch64_ver_target_feature), &["v8.8a", "cssc"]),
362 ("v9.1a", Unstable(sym::aarch64_ver_target_feature), &["v9a", "v8.6a"]),
363 ("v9.2a", Unstable(sym::aarch64_ver_target_feature), &["v9.1a", "v8.7a"]),
364 ("v9.3a", Unstable(sym::aarch64_ver_target_feature), &["v9.2a", "v8.8a"]),
365 ("v9.4a", Unstable(sym::aarch64_ver_target_feature), &["v9.3a", "v8.9a"]),
366 ("v9.5a", Unstable(sym::aarch64_ver_target_feature), &["v9.4a"]),
367 ("v9a", Unstable(sym::aarch64_ver_target_feature), &["v8.5a", "sve2"]),
368 ("vh", Stable, &[]),
370 ("wfxt", Unstable(sym::aarch64_unstable_target_feature), &[]),
372 ];
374
375const AARCH64_TIED_FEATURES: &[&[&str]] = &[
376 &["paca", "pacg"], ];
378
379static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
380 ("adx", Stable, &[]),
382 ("aes", Stable, &["sse2"]),
383 ("amx-bf16", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
384 ("amx-complex", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
385 ("amx-fp16", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
386 ("amx-int8", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
387 ("amx-tile", Unstable(sym::x86_amx_intrinsics), &[]),
388 ("avx", Stable, &["sse4.2"]),
389 ("avx2", Stable, &["avx"]),
390 ("avx512bf16", Unstable(sym::avx512_target_feature), &["avx512bw"]),
391 ("avx512bitalg", Unstable(sym::avx512_target_feature), &["avx512bw"]),
392 ("avx512bw", Unstable(sym::avx512_target_feature), &["avx512f"]),
393 ("avx512cd", Unstable(sym::avx512_target_feature), &["avx512f"]),
394 ("avx512dq", Unstable(sym::avx512_target_feature), &["avx512f"]),
395 ("avx512f", Unstable(sym::avx512_target_feature), &["avx2", "fma", "f16c"]),
396 ("avx512fp16", Unstable(sym::avx512_target_feature), &["avx512bw", "avx512vl", "avx512dq"]),
397 ("avx512ifma", Unstable(sym::avx512_target_feature), &["avx512f"]),
398 ("avx512vbmi", Unstable(sym::avx512_target_feature), &["avx512bw"]),
399 ("avx512vbmi2", Unstable(sym::avx512_target_feature), &["avx512bw"]),
400 ("avx512vl", Unstable(sym::avx512_target_feature), &["avx512f"]),
401 ("avx512vnni", Unstable(sym::avx512_target_feature), &["avx512f"]),
402 ("avx512vp2intersect", Unstable(sym::avx512_target_feature), &["avx512f"]),
403 ("avx512vpopcntdq", Unstable(sym::avx512_target_feature), &["avx512f"]),
404 ("avxifma", Unstable(sym::avx512_target_feature), &["avx2"]),
405 ("avxneconvert", Unstable(sym::avx512_target_feature), &["avx2"]),
406 ("avxvnni", Unstable(sym::avx512_target_feature), &["avx2"]),
407 ("avxvnniint16", Unstable(sym::avx512_target_feature), &["avx2"]),
408 ("avxvnniint8", Unstable(sym::avx512_target_feature), &["avx2"]),
409 ("bmi1", Stable, &[]),
410 ("bmi2", Stable, &[]),
411 ("cmpxchg16b", Stable, &[]),
412 ("ermsb", Unstable(sym::ermsb_target_feature), &[]),
413 ("f16c", Stable, &["avx"]),
414 ("fma", Stable, &["avx"]),
415 ("fxsr", Stable, &[]),
416 ("gfni", Unstable(sym::avx512_target_feature), &["sse2"]),
417 ("kl", Unstable(sym::keylocker_x86), &["sse2"]),
418 ("lahfsahf", Unstable(sym::lahfsahf_target_feature), &[]),
419 ("lzcnt", Stable, &[]),
420 ("movbe", Stable, &[]),
421 ("pclmulqdq", Stable, &["sse2"]),
422 ("popcnt", Stable, &[]),
423 ("prfchw", Unstable(sym::prfchw_target_feature), &[]),
424 ("rdrand", Stable, &[]),
425 ("rdseed", Stable, &[]),
426 ("rtm", Unstable(sym::rtm_target_feature), &[]),
427 ("sha", Stable, &["sse2"]),
428 ("sha512", Unstable(sym::sha512_sm_x86), &["avx2"]),
429 ("sm3", Unstable(sym::sha512_sm_x86), &["avx"]),
430 ("sm4", Unstable(sym::sha512_sm_x86), &["avx2"]),
431 ("soft-float", Stability::Unstable(sym::x87_target_feature), &[]),
434 ("sse", Stable, &[]),
435 ("sse2", Stable, &["sse"]),
436 ("sse3", Stable, &["sse2"]),
437 ("sse4.1", Stable, &["ssse3"]),
438 ("sse4.2", Stable, &["sse4.1"]),
439 ("sse4a", Unstable(sym::sse4a_target_feature), &["sse3"]),
440 ("ssse3", Stable, &["sse3"]),
441 ("tbm", Unstable(sym::tbm_target_feature), &[]),
442 ("vaes", Unstable(sym::avx512_target_feature), &["avx2", "aes"]),
443 ("vpclmulqdq", Unstable(sym::avx512_target_feature), &["avx", "pclmulqdq"]),
444 ("widekl", Unstable(sym::keylocker_x86), &["kl"]),
445 ("x87", Unstable(sym::x87_target_feature), &[]),
446 ("xop", Unstable(sym::xop_target_feature), &["avx", "sse4a"]),
447 ("xsave", Stable, &[]),
448 ("xsavec", Stable, &["xsave"]),
449 ("xsaveopt", Stable, &["xsave"]),
450 ("xsaves", Stable, &["xsave"]),
451 ];
453
454const HEXAGON_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
455 ("hvx", Unstable(sym::hexagon_target_feature), &[]),
457 ("hvx-length128b", Unstable(sym::hexagon_target_feature), &["hvx"]),
458 ];
460
461static POWERPC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
462 ("altivec", Unstable(sym::powerpc_target_feature), &[]),
464 ("msync", Unstable(sym::powerpc_target_feature), &[]),
465 ("partword-atomics", Unstable(sym::powerpc_target_feature), &[]),
466 ("power10-vector", Unstable(sym::powerpc_target_feature), &["power9-vector"]),
467 ("power8-altivec", Unstable(sym::powerpc_target_feature), &["altivec"]),
468 ("power8-crypto", Unstable(sym::powerpc_target_feature), &["power8-altivec"]),
469 ("power8-vector", Unstable(sym::powerpc_target_feature), &["vsx", "power8-altivec"]),
470 ("power9-altivec", Unstable(sym::powerpc_target_feature), &["power8-altivec"]),
471 ("power9-vector", Unstable(sym::powerpc_target_feature), &["power8-vector", "power9-altivec"]),
472 ("quadword-atomics", Unstable(sym::powerpc_target_feature), &[]),
473 ("vsx", Unstable(sym::powerpc_target_feature), &["altivec"]),
474 ];
476
477const MIPS_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
478 ("fp64", Unstable(sym::mips_target_feature), &[]),
480 ("msa", Unstable(sym::mips_target_feature), &[]),
481 ("virt", Unstable(sym::mips_target_feature), &[]),
482 ];
484
485static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
486 ("a", Stable, &["zaamo", "zalrsc"]),
488 ("c", Stable, &[]),
489 ("d", Unstable(sym::riscv_target_feature), &["f"]),
490 ("e", Unstable(sym::riscv_target_feature), &[]),
491 ("f", Unstable(sym::riscv_target_feature), &[]),
492 (
493 "forced-atomics",
494 Stability::Forbidden { reason: "unsound because it changes the ABI of atomic operations" },
495 &[],
496 ),
497 ("m", Stable, &[]),
498 ("relax", Unstable(sym::riscv_target_feature), &[]),
499 ("unaligned-scalar-mem", Unstable(sym::riscv_target_feature), &[]),
500 ("v", Unstable(sym::riscv_target_feature), &[]),
501 ("za128rs", Unstable(sym::riscv_target_feature), &[]),
502 ("za64rs", Unstable(sym::riscv_target_feature), &[]),
503 ("zaamo", Unstable(sym::riscv_target_feature), &[]),
504 ("zabha", Unstable(sym::riscv_target_feature), &["zaamo"]),
505 ("zacas", Unstable(sym::riscv_target_feature), &["zaamo"]),
506 ("zalrsc", Unstable(sym::riscv_target_feature), &[]),
507 ("zama16b", Unstable(sym::riscv_target_feature), &[]),
508 ("zawrs", Unstable(sym::riscv_target_feature), &[]),
509 ("zba", Stable, &[]),
510 ("zbb", Stable, &[]),
511 ("zbc", Stable, &[]),
512 ("zbkb", Stable, &[]),
513 ("zbkc", Stable, &[]),
514 ("zbkx", Stable, &[]),
515 ("zbs", Stable, &[]),
516 ("zdinx", Unstable(sym::riscv_target_feature), &["zfinx"]),
517 ("zfh", Unstable(sym::riscv_target_feature), &["zfhmin"]),
518 ("zfhmin", Unstable(sym::riscv_target_feature), &["f"]),
519 ("zfinx", Unstable(sym::riscv_target_feature), &[]),
520 ("zhinx", Unstable(sym::riscv_target_feature), &["zhinxmin"]),
521 ("zhinxmin", Unstable(sym::riscv_target_feature), &["zfinx"]),
522 ("zk", Stable, &["zkn", "zkr", "zkt"]),
523 ("zkn", Stable, &["zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"]),
524 ("zknd", Stable, &[]),
525 ("zkne", Stable, &[]),
526 ("zknh", Stable, &[]),
527 ("zkr", Stable, &[]),
528 ("zks", Stable, &["zbkb", "zbkc", "zbkx", "zksed", "zksh"]),
529 ("zksed", Stable, &[]),
530 ("zksh", Stable, &[]),
531 ("zkt", Stable, &[]),
532 ];
534
535static WASM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
536 ("atomics", Unstable(sym::wasm_target_feature), &[]),
538 ("bulk-memory", Stable, &[]),
539 ("exception-handling", Unstable(sym::wasm_target_feature), &[]),
540 ("extended-const", Stable, &[]),
541 ("multivalue", Stable, &[]),
542 ("mutable-globals", Stable, &[]),
543 ("nontrapping-fptoint", Stable, &[]),
544 ("reference-types", Stable, &[]),
545 ("relaxed-simd", Stable, &["simd128"]),
546 ("sign-ext", Stable, &[]),
547 ("simd128", Stable, &[]),
548 ("tail-call", Stable, &[]),
549 ("wide-arithmetic", Unstable(sym::wasm_target_feature), &[]),
550 ];
552
553const BPF_FEATURES: &[(&str, Stability, ImpliedFeatures)] =
554 &[("alu32", Unstable(sym::bpf_target_feature), &[])];
555
556static CSKY_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
557 ("10e60", Unstable(sym::csky_target_feature), &["7e10"]),
559 ("2e3", Unstable(sym::csky_target_feature), &["e2"]),
560 ("3e3r1", Unstable(sym::csky_target_feature), &[]),
561 ("3e3r2", Unstable(sym::csky_target_feature), &["3e3r1", "doloop"]),
562 ("3e3r3", Unstable(sym::csky_target_feature), &["doloop"]),
563 ("3e7", Unstable(sym::csky_target_feature), &["2e3"]),
564 ("7e10", Unstable(sym::csky_target_feature), &["3e7"]),
565 ("cache", Unstable(sym::csky_target_feature), &[]),
566 ("doloop", Unstable(sym::csky_target_feature), &[]),
567 ("dsp1e2", Unstable(sym::csky_target_feature), &[]),
568 ("dspe60", Unstable(sym::csky_target_feature), &[]),
569 ("e1", Unstable(sym::csky_target_feature), &["elrw"]),
570 ("e2", Unstable(sym::csky_target_feature), &["e2"]),
571 ("edsp", Unstable(sym::csky_target_feature), &[]),
572 ("elrw", Unstable(sym::csky_target_feature), &[]),
573 ("float1e2", Unstable(sym::csky_target_feature), &[]),
574 ("float1e3", Unstable(sym::csky_target_feature), &[]),
575 ("float3e4", Unstable(sym::csky_target_feature), &[]),
576 ("float7e60", Unstable(sym::csky_target_feature), &[]),
577 ("floate1", Unstable(sym::csky_target_feature), &[]),
578 ("hard-tp", Unstable(sym::csky_target_feature), &[]),
579 ("high-registers", Unstable(sym::csky_target_feature), &[]),
580 ("hwdiv", Unstable(sym::csky_target_feature), &[]),
581 ("mp", Unstable(sym::csky_target_feature), &["2e3"]),
582 ("mp1e2", Unstable(sym::csky_target_feature), &["3e7"]),
583 ("nvic", Unstable(sym::csky_target_feature), &[]),
584 ("trust", Unstable(sym::csky_target_feature), &[]),
585 ("vdsp2e60f", Unstable(sym::csky_target_feature), &[]),
586 ("vdspv1", Unstable(sym::csky_target_feature), &[]),
587 ("vdspv2", Unstable(sym::csky_target_feature), &[]),
588 ("fdivdu", Unstable(sym::csky_target_feature), &[]),
592 ("fpuv2_df", Unstable(sym::csky_target_feature), &[]),
593 ("fpuv2_sf", Unstable(sym::csky_target_feature), &[]),
594 ("fpuv3_df", Unstable(sym::csky_target_feature), &[]),
595 ("fpuv3_hf", Unstable(sym::csky_target_feature), &[]),
596 ("fpuv3_hi", Unstable(sym::csky_target_feature), &[]),
597 ("fpuv3_sf", Unstable(sym::csky_target_feature), &[]),
598 ("hard-float", Unstable(sym::csky_target_feature), &[]),
599 ("hard-float-abi", Unstable(sym::csky_target_feature), &[]),
600 ];
602
603static LOONGARCH_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
604 ("d", Unstable(sym::loongarch_target_feature), &["f"]),
606 ("div32", Unstable(sym::loongarch_target_feature), &[]),
607 ("f", Unstable(sym::loongarch_target_feature), &[]),
608 ("frecipe", Unstable(sym::loongarch_target_feature), &[]),
609 ("lam-bh", Unstable(sym::loongarch_target_feature), &[]),
610 ("lamcas", Unstable(sym::loongarch_target_feature), &[]),
611 ("lasx", Unstable(sym::loongarch_target_feature), &["lsx"]),
612 ("lbt", Unstable(sym::loongarch_target_feature), &[]),
613 ("ld-seq-sa", Unstable(sym::loongarch_target_feature), &[]),
614 ("lsx", Unstable(sym::loongarch_target_feature), &["d"]),
615 ("lvz", Unstable(sym::loongarch_target_feature), &[]),
616 ("relax", Unstable(sym::loongarch_target_feature), &[]),
617 ("scq", Unstable(sym::loongarch_target_feature), &[]),
618 ("ual", Unstable(sym::loongarch_target_feature), &[]),
619 ];
621
622const IBMZ_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
623 ("backchain", Unstable(sym::s390x_target_feature), &[]),
625 ("deflate-conversion", Unstable(sym::s390x_target_feature), &[]),
626 ("enhanced-sort", Unstable(sym::s390x_target_feature), &[]),
627 ("guarded-storage", Unstable(sym::s390x_target_feature), &[]),
628 ("high-word", Unstable(sym::s390x_target_feature), &[]),
629 ("nnp-assist", Unstable(sym::s390x_target_feature), &["vector"]),
630 ("transactional-execution", Unstable(sym::s390x_target_feature), &[]),
631 ("vector", Unstable(sym::s390x_target_feature), &[]),
632 ("vector-enhancements-1", Unstable(sym::s390x_target_feature), &["vector"]),
633 ("vector-enhancements-2", Unstable(sym::s390x_target_feature), &["vector-enhancements-1"]),
634 ("vector-packed-decimal", Unstable(sym::s390x_target_feature), &["vector"]),
635 (
636 "vector-packed-decimal-enhancement",
637 Unstable(sym::s390x_target_feature),
638 &["vector-packed-decimal"],
639 ),
640 (
641 "vector-packed-decimal-enhancement-2",
642 Unstable(sym::s390x_target_feature),
643 &["vector-packed-decimal-enhancement"],
644 ),
645 ];
647
648const SPARC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
649 ("leoncasa", Unstable(sym::sparc_target_feature), &[]),
651 ("v8plus", Unstable(sym::sparc_target_feature), &[]),
652 ("v9", Unstable(sym::sparc_target_feature), &[]),
653 ];
655
656static M68K_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
657 ("isa-68000", Unstable(sym::m68k_target_feature), &[]),
659 ("isa-68010", Unstable(sym::m68k_target_feature), &["isa-68000"]),
660 ("isa-68020", Unstable(sym::m68k_target_feature), &["isa-68010"]),
661 ("isa-68030", Unstable(sym::m68k_target_feature), &["isa-68020"]),
662 ("isa-68040", Unstable(sym::m68k_target_feature), &["isa-68030", "isa-68882"]),
663 ("isa-68060", Unstable(sym::m68k_target_feature), &["isa-68040"]),
664 ("isa-68881", Unstable(sym::m68k_target_feature), &[]),
666 ("isa-68882", Unstable(sym::m68k_target_feature), &["isa-68881"]),
667 ];
669
670pub fn all_rust_features() -> impl Iterator<Item = (&'static str, Stability)> {
675 std::iter::empty()
676 .chain(ARM_FEATURES.iter())
677 .chain(AARCH64_FEATURES.iter())
678 .chain(X86_FEATURES.iter())
679 .chain(HEXAGON_FEATURES.iter())
680 .chain(POWERPC_FEATURES.iter())
681 .chain(MIPS_FEATURES.iter())
682 .chain(RISCV_FEATURES.iter())
683 .chain(WASM_FEATURES.iter())
684 .chain(BPF_FEATURES.iter())
685 .chain(CSKY_FEATURES)
686 .chain(LOONGARCH_FEATURES)
687 .chain(IBMZ_FEATURES)
688 .chain(SPARC_FEATURES)
689 .chain(M68K_FEATURES)
690 .cloned()
691 .map(|(f, s, _)| (f, s))
692}
693
694const X86_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
698 &[(128, "sse"), (256, "avx"), (512, "avx512f")]; const AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")];
700
701const ARM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")];
703
704const POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "altivec")];
705const WASM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "simd128")];
706const S390X_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vector")];
707const RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
708 &[(128, "v")];
709const SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[];
711
712const HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
713 &[(1024, "hvx-length128b")];
714const MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "msa")];
715const CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vdspv1")];
716const LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
717 &[(128, "lsx"), (256, "lasx")];
718
719#[derive(Copy, Clone, Debug)]
720pub struct FeatureConstraints {
721 pub required: &'static [&'static str],
723 pub incompatible: &'static [&'static str],
725}
726
727impl Target {
728 pub fn rust_target_features(&self) -> &'static [(&'static str, Stability, ImpliedFeatures)] {
729 match &*self.arch {
730 "arm" => ARM_FEATURES,
731 "aarch64" | "arm64ec" => AARCH64_FEATURES,
732 "x86" | "x86_64" => X86_FEATURES,
733 "hexagon" => HEXAGON_FEATURES,
734 "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_FEATURES,
735 "powerpc" | "powerpc64" => POWERPC_FEATURES,
736 "riscv32" | "riscv64" => RISCV_FEATURES,
737 "wasm32" | "wasm64" => WASM_FEATURES,
738 "bpf" => BPF_FEATURES,
739 "csky" => CSKY_FEATURES,
740 "loongarch64" => LOONGARCH_FEATURES,
741 "s390x" => IBMZ_FEATURES,
742 "sparc" | "sparc64" => SPARC_FEATURES,
743 "m68k" => M68K_FEATURES,
744 _ => &[],
745 }
746 }
747
748 pub fn features_for_correct_vector_abi(&self) -> &'static [(u64, &'static str)] {
749 match &*self.arch {
750 "x86" | "x86_64" => X86_FEATURES_FOR_CORRECT_VECTOR_ABI,
751 "aarch64" | "arm64ec" => AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI,
752 "arm" => ARM_FEATURES_FOR_CORRECT_VECTOR_ABI,
753 "powerpc" | "powerpc64" => POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI,
754 "loongarch64" => LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI,
755 "riscv32" | "riscv64" => RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI,
756 "wasm32" | "wasm64" => WASM_FEATURES_FOR_CORRECT_VECTOR_ABI,
757 "s390x" => S390X_FEATURES_FOR_CORRECT_VECTOR_ABI,
758 "sparc" | "sparc64" => SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI,
759 "hexagon" => HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI,
760 "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI,
761 "bpf" | "m68k" => &[], "csky" => CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI,
763 _ => &[],
766 }
767 }
768
769 pub fn tied_target_features(&self) -> &'static [&'static [&'static str]] {
770 match &*self.arch {
771 "aarch64" | "arm64ec" => AARCH64_TIED_FEATURES,
772 _ => &[],
773 }
774 }
775
776 pub fn implied_target_features<'a>(&self, base_feature: &'a str) -> FxHashSet<&'a str> {
778 let implied_features =
779 self.rust_target_features().iter().map(|(f, _, i)| (f, i)).collect::<FxHashMap<_, _>>();
780
781 let mut features = FxHashSet::default();
784 let mut new_features = vec![base_feature];
785 while let Some(new_feature) = new_features.pop() {
786 if features.insert(new_feature) {
787 if let Some(implied_features) = implied_features.get(&new_feature) {
788 new_features.extend(implied_features.iter().copied())
789 }
790 }
791 }
792 features
793 }
794
795 pub fn abi_required_features(&self) -> FeatureConstraints {
806 const NOTHING: FeatureConstraints = FeatureConstraints { required: &[], incompatible: &[] };
807 match &*self.arch {
812 "x86" => {
813 match self.rustc_abi {
816 None => {
817 FeatureConstraints { required: &["x87"], incompatible: &["soft-float"] }
820 }
821 Some(RustcAbi::X86Sse2) => {
822 FeatureConstraints {
824 required: &["x87", "sse2"],
825 incompatible: &["soft-float"],
826 }
827 }
828 Some(RustcAbi::X86Softfloat) => {
829 FeatureConstraints { required: &["soft-float"], incompatible: &[] }
834 }
835 }
836 }
837 "x86_64" => {
838 match self.rustc_abi {
841 None => {
842 FeatureConstraints {
844 required: &["x87", "sse2"],
845 incompatible: &["soft-float"],
846 }
847 }
848 Some(RustcAbi::X86Softfloat) => {
849 FeatureConstraints { required: &["soft-float"], incompatible: &[] }
854 }
855 Some(r) => panic!("invalid Rust ABI for x86_64: {r:?}"),
856 }
857 }
858 "arm" => {
859 match self.llvm_floatabi.unwrap() {
862 FloatAbi::Soft => {
863 NOTHING
868 }
869 FloatAbi::Hard => {
870 FeatureConstraints { required: &["fpregs"], incompatible: &["soft-float"] }
872 }
873 }
874 }
875 "aarch64" | "arm64ec" => {
876 match &*self.abi {
879 "softfloat" => {
880 NOTHING
884 }
885 _ => {
886 FeatureConstraints { required: &["neon"], incompatible: &[] }
889 }
890 }
891 }
892 "riscv32" | "riscv64" => {
893 match &*self.llvm_abiname {
896 "ilp32d" | "lp64d" => {
897 FeatureConstraints { required: &["d"], incompatible: &["e"] }
899 }
900 "ilp32f" | "lp64f" => {
901 FeatureConstraints { required: &["f"], incompatible: &["e"] }
903 }
904 "ilp32" | "lp64" => {
905 FeatureConstraints { required: &[], incompatible: &["e"] }
907 }
908 "ilp32e" => {
909 FeatureConstraints { required: &[], incompatible: &["d"] }
918 }
919 "lp64e" => {
920 NOTHING
922 }
923 _ => unreachable!(),
924 }
925 }
926 "loongarch64" => {
927 match &*self.llvm_abiname {
930 "ilp32d" | "lp64d" => {
931 FeatureConstraints { required: &["d"], incompatible: &[] }
933 }
934 "ilp32f" | "lp64f" => {
935 FeatureConstraints { required: &["f"], incompatible: &[] }
937 }
938 "ilp32s" | "lp64s" => {
939 NOTHING
944 }
945 _ => unreachable!(),
946 }
947 }
948 _ => NOTHING,
949 }
950 }
951}