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-avx512", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
384 ("amx-bf16", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
385 ("amx-complex", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
386 ("amx-fp16", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
387 ("amx-fp8", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
388 ("amx-int8", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
389 ("amx-movrs", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
390 ("amx-tf32", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
391 ("amx-tile", Unstable(sym::x86_amx_intrinsics), &[]),
392 ("amx-transpose", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
393 ("avx", Stable, &["sse4.2"]),
394 ("avx2", Stable, &["avx"]),
395 ("avx512bf16", Unstable(sym::avx512_target_feature), &["avx512bw"]),
396 ("avx512bitalg", Unstable(sym::avx512_target_feature), &["avx512bw"]),
397 ("avx512bw", Unstable(sym::avx512_target_feature), &["avx512f"]),
398 ("avx512cd", Unstable(sym::avx512_target_feature), &["avx512f"]),
399 ("avx512dq", Unstable(sym::avx512_target_feature), &["avx512f"]),
400 ("avx512f", Unstable(sym::avx512_target_feature), &["avx2", "fma", "f16c"]),
401 ("avx512fp16", Unstable(sym::avx512_target_feature), &["avx512bw", "avx512vl", "avx512dq"]),
402 ("avx512ifma", Unstable(sym::avx512_target_feature), &["avx512f"]),
403 ("avx512vbmi", Unstable(sym::avx512_target_feature), &["avx512bw"]),
404 ("avx512vbmi2", Unstable(sym::avx512_target_feature), &["avx512bw"]),
405 ("avx512vl", Unstable(sym::avx512_target_feature), &["avx512f"]),
406 ("avx512vnni", Unstable(sym::avx512_target_feature), &["avx512f"]),
407 ("avx512vp2intersect", Unstable(sym::avx512_target_feature), &["avx512f"]),
408 ("avx512vpopcntdq", Unstable(sym::avx512_target_feature), &["avx512f"]),
409 ("avxifma", Unstable(sym::avx512_target_feature), &["avx2"]),
410 ("avxneconvert", Unstable(sym::avx512_target_feature), &["avx2"]),
411 ("avxvnni", Unstable(sym::avx512_target_feature), &["avx2"]),
412 ("avxvnniint16", Unstable(sym::avx512_target_feature), &["avx2"]),
413 ("avxvnniint8", Unstable(sym::avx512_target_feature), &["avx2"]),
414 ("bmi1", Stable, &[]),
415 ("bmi2", Stable, &[]),
416 ("cmpxchg16b", Stable, &[]),
417 ("ermsb", Unstable(sym::ermsb_target_feature), &[]),
418 ("f16c", Stable, &["avx"]),
419 ("fma", Stable, &["avx"]),
420 ("fxsr", Stable, &[]),
421 ("gfni", Unstable(sym::avx512_target_feature), &["sse2"]),
422 ("kl", Unstable(sym::keylocker_x86), &["sse2"]),
423 ("lahfsahf", Unstable(sym::lahfsahf_target_feature), &[]),
424 ("lzcnt", Stable, &[]),
425 ("movbe", Stable, &[]),
426 ("movrs", Unstable(sym::movrs_target_feature), &[]),
427 ("pclmulqdq", Stable, &["sse2"]),
428 ("popcnt", Stable, &[]),
429 ("prfchw", Unstable(sym::prfchw_target_feature), &[]),
430 ("rdrand", Stable, &[]),
431 ("rdseed", Stable, &[]),
432 ("rtm", Unstable(sym::rtm_target_feature), &[]),
433 ("sha", Stable, &["sse2"]),
434 ("sha512", Unstable(sym::sha512_sm_x86), &["avx2"]),
435 ("sm3", Unstable(sym::sha512_sm_x86), &["avx"]),
436 ("sm4", Unstable(sym::sha512_sm_x86), &["avx2"]),
437 ("soft-float", Stability::Unstable(sym::x87_target_feature), &[]),
440 ("sse", Stable, &[]),
441 ("sse2", Stable, &["sse"]),
442 ("sse3", Stable, &["sse2"]),
443 ("sse4.1", Stable, &["ssse3"]),
444 ("sse4.2", Stable, &["sse4.1"]),
445 ("sse4a", Unstable(sym::sse4a_target_feature), &["sse3"]),
446 ("ssse3", Stable, &["sse3"]),
447 ("tbm", Unstable(sym::tbm_target_feature), &[]),
448 ("vaes", Unstable(sym::avx512_target_feature), &["avx2", "aes"]),
449 ("vpclmulqdq", Unstable(sym::avx512_target_feature), &["avx", "pclmulqdq"]),
450 ("widekl", Unstable(sym::keylocker_x86), &["kl"]),
451 ("x87", Unstable(sym::x87_target_feature), &[]),
452 ("xop", Unstable(sym::xop_target_feature), &["avx", "sse4a"]),
453 ("xsave", Stable, &[]),
454 ("xsavec", Stable, &["xsave"]),
455 ("xsaveopt", Stable, &["xsave"]),
456 ("xsaves", Stable, &["xsave"]),
457 ];
459
460const HEXAGON_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
461 ("hvx", Unstable(sym::hexagon_target_feature), &[]),
463 ("hvx-length128b", Unstable(sym::hexagon_target_feature), &["hvx"]),
464 ];
466
467static POWERPC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
468 ("altivec", Unstable(sym::powerpc_target_feature), &[]),
470 ("msync", Unstable(sym::powerpc_target_feature), &[]),
471 ("partword-atomics", Unstable(sym::powerpc_target_feature), &[]),
472 ("power10-vector", Unstable(sym::powerpc_target_feature), &["power9-vector"]),
473 ("power8-altivec", Unstable(sym::powerpc_target_feature), &["altivec"]),
474 ("power8-crypto", Unstable(sym::powerpc_target_feature), &["power8-altivec"]),
475 ("power8-vector", Unstable(sym::powerpc_target_feature), &["vsx", "power8-altivec"]),
476 ("power9-altivec", Unstable(sym::powerpc_target_feature), &["power8-altivec"]),
477 ("power9-vector", Unstable(sym::powerpc_target_feature), &["power8-vector", "power9-altivec"]),
478 ("quadword-atomics", Unstable(sym::powerpc_target_feature), &[]),
479 ("vsx", Unstable(sym::powerpc_target_feature), &["altivec"]),
480 ];
482
483const MIPS_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
484 ("fp64", Unstable(sym::mips_target_feature), &[]),
486 ("msa", Unstable(sym::mips_target_feature), &[]),
487 ("virt", Unstable(sym::mips_target_feature), &[]),
488 ];
490
491static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
492 ("a", Stable, &["zaamo", "zalrsc"]),
494 ("c", Stable, &[]),
495 ("d", Unstable(sym::riscv_target_feature), &["f"]),
496 ("e", Unstable(sym::riscv_target_feature), &[]),
497 ("f", Unstable(sym::riscv_target_feature), &["zicsr"]),
498 (
499 "forced-atomics",
500 Stability::Forbidden { reason: "unsound because it changes the ABI of atomic operations" },
501 &[],
502 ),
503 ("m", Stable, &[]),
504 ("relax", Unstable(sym::riscv_target_feature), &[]),
505 ("unaligned-scalar-mem", Unstable(sym::riscv_target_feature), &[]),
506 ("unaligned-vector-mem", Unstable(sym::riscv_target_feature), &[]),
507 ("v", Unstable(sym::riscv_target_feature), &["zvl128b", "zve64d"]),
508 ("za128rs", Unstable(sym::riscv_target_feature), &[]),
509 ("za64rs", Unstable(sym::riscv_target_feature), &[]),
510 ("zaamo", Unstable(sym::riscv_target_feature), &[]),
511 ("zabha", Unstable(sym::riscv_target_feature), &["zaamo"]),
512 ("zacas", Unstable(sym::riscv_target_feature), &["zaamo"]),
513 ("zalrsc", Unstable(sym::riscv_target_feature), &[]),
514 ("zama16b", Unstable(sym::riscv_target_feature), &[]),
515 ("zawrs", Unstable(sym::riscv_target_feature), &[]),
516 ("zba", Stable, &[]),
517 ("zbb", Stable, &[]),
518 ("zbc", Stable, &[]),
519 ("zbkb", Stable, &[]),
520 ("zbkc", Stable, &[]),
521 ("zbkx", Stable, &[]),
522 ("zbs", Stable, &[]),
523 ("zdinx", Unstable(sym::riscv_target_feature), &["zfinx"]),
524 ("zfh", Unstable(sym::riscv_target_feature), &["zfhmin"]),
525 ("zfhmin", Unstable(sym::riscv_target_feature), &["f"]),
526 ("zfinx", Unstable(sym::riscv_target_feature), &["zicsr"]),
527 ("zhinx", Unstable(sym::riscv_target_feature), &["zhinxmin"]),
528 ("zhinxmin", Unstable(sym::riscv_target_feature), &["zfinx"]),
529 ("zicntr", Unstable(sym::riscv_target_feature), &["zicsr"]),
530 ("zicsr", Unstable(sym::riscv_target_feature), &[]),
531 ("zifencei", Unstable(sym::riscv_target_feature), &[]),
532 ("zihintpause", Unstable(sym::riscv_target_feature), &[]),
533 ("zihpm", Unstable(sym::riscv_target_feature), &["zicsr"]),
534 ("zk", Stable, &["zkn", "zkr", "zkt"]),
535 ("zkn", Stable, &["zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"]),
536 ("zknd", Stable, &[]),
537 ("zkne", Stable, &[]),
538 ("zknh", Stable, &[]),
539 ("zkr", Stable, &["zicsr"]),
540 ("zks", Stable, &["zbkb", "zbkc", "zbkx", "zksed", "zksh"]),
541 ("zksed", Stable, &[]),
542 ("zksh", Stable, &[]),
543 ("zkt", Stable, &[]),
544 ("zvbb", Unstable(sym::riscv_target_feature), &["zvkb"]),
545 ("zvbc", Unstable(sym::riscv_target_feature), &["zve64x"]),
546 ("zve32f", Unstable(sym::riscv_target_feature), &["zve32x", "f"]),
547 ("zve32x", Unstable(sym::riscv_target_feature), &["zvl32b", "zicsr"]),
548 ("zve64d", Unstable(sym::riscv_target_feature), &["zve64f", "d"]),
549 ("zve64f", Unstable(sym::riscv_target_feature), &["zve32f", "zve64x"]),
550 ("zve64x", Unstable(sym::riscv_target_feature), &["zve32x", "zvl64b"]),
551 ("zvfh", Unstable(sym::riscv_target_feature), &["zvfhmin", "zfhmin"]),
552 ("zvfhmin", Unstable(sym::riscv_target_feature), &["zve32f"]),
553 ("zvkb", Unstable(sym::riscv_target_feature), &["zve32x"]),
554 ("zvkg", Unstable(sym::riscv_target_feature), &["zve32x"]),
555 ("zvkn", Unstable(sym::riscv_target_feature), &["zvkned", "zvknhb", "zvkb", "zvkt"]),
556 ("zvknc", Unstable(sym::riscv_target_feature), &["zvkn", "zvbc"]),
557 ("zvkned", Unstable(sym::riscv_target_feature), &["zve32x"]),
558 ("zvkng", Unstable(sym::riscv_target_feature), &["zvkn", "zvkg"]),
559 ("zvknha", Unstable(sym::riscv_target_feature), &["zve32x"]),
560 ("zvknhb", Unstable(sym::riscv_target_feature), &["zve64x"]),
561 ("zvks", Unstable(sym::riscv_target_feature), &["zvksed", "zvksh", "zvkb", "zvkt"]),
562 ("zvksc", Unstable(sym::riscv_target_feature), &["zvks", "zvbc"]),
563 ("zvksed", Unstable(sym::riscv_target_feature), &["zve32x"]),
564 ("zvksg", Unstable(sym::riscv_target_feature), &["zvks", "zvkg"]),
565 ("zvksh", Unstable(sym::riscv_target_feature), &["zve32x"]),
566 ("zvkt", Unstable(sym::riscv_target_feature), &[]),
567 ("zvl1024b", Unstable(sym::riscv_target_feature), &["zvl512b"]),
568 ("zvl128b", Unstable(sym::riscv_target_feature), &["zvl64b"]),
569 ("zvl16384b", Unstable(sym::riscv_target_feature), &["zvl8192b"]),
570 ("zvl2048b", Unstable(sym::riscv_target_feature), &["zvl1024b"]),
571 ("zvl256b", Unstable(sym::riscv_target_feature), &["zvl128b"]),
572 ("zvl32768b", Unstable(sym::riscv_target_feature), &["zvl16384b"]),
573 ("zvl32b", Unstable(sym::riscv_target_feature), &[]),
574 ("zvl4096b", Unstable(sym::riscv_target_feature), &["zvl2048b"]),
575 ("zvl512b", Unstable(sym::riscv_target_feature), &["zvl256b"]),
576 ("zvl64b", Unstable(sym::riscv_target_feature), &["zvl32b"]),
577 ("zvl65536b", Unstable(sym::riscv_target_feature), &["zvl32768b"]),
578 ("zvl8192b", Unstable(sym::riscv_target_feature), &["zvl4096b"]),
579 ];
581
582static WASM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
583 ("atomics", Unstable(sym::wasm_target_feature), &[]),
585 ("bulk-memory", Stable, &[]),
586 ("exception-handling", Unstable(sym::wasm_target_feature), &[]),
587 ("extended-const", Stable, &[]),
588 ("multivalue", Stable, &[]),
589 ("mutable-globals", Stable, &[]),
590 ("nontrapping-fptoint", Stable, &[]),
591 ("reference-types", Stable, &[]),
592 ("relaxed-simd", Stable, &["simd128"]),
593 ("sign-ext", Stable, &[]),
594 ("simd128", Stable, &[]),
595 ("tail-call", Stable, &[]),
596 ("wide-arithmetic", Unstable(sym::wasm_target_feature), &[]),
597 ];
599
600const BPF_FEATURES: &[(&str, Stability, ImpliedFeatures)] =
601 &[("alu32", Unstable(sym::bpf_target_feature), &[])];
602
603static CSKY_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
604 ("10e60", Unstable(sym::csky_target_feature), &["7e10"]),
606 ("2e3", Unstable(sym::csky_target_feature), &["e2"]),
607 ("3e3r1", Unstable(sym::csky_target_feature), &[]),
608 ("3e3r2", Unstable(sym::csky_target_feature), &["3e3r1", "doloop"]),
609 ("3e3r3", Unstable(sym::csky_target_feature), &["doloop"]),
610 ("3e7", Unstable(sym::csky_target_feature), &["2e3"]),
611 ("7e10", Unstable(sym::csky_target_feature), &["3e7"]),
612 ("cache", Unstable(sym::csky_target_feature), &[]),
613 ("doloop", Unstable(sym::csky_target_feature), &[]),
614 ("dsp1e2", Unstable(sym::csky_target_feature), &[]),
615 ("dspe60", Unstable(sym::csky_target_feature), &[]),
616 ("e1", Unstable(sym::csky_target_feature), &["elrw"]),
617 ("e2", Unstable(sym::csky_target_feature), &["e2"]),
618 ("edsp", Unstable(sym::csky_target_feature), &[]),
619 ("elrw", Unstable(sym::csky_target_feature), &[]),
620 ("float1e2", Unstable(sym::csky_target_feature), &[]),
621 ("float1e3", Unstable(sym::csky_target_feature), &[]),
622 ("float3e4", Unstable(sym::csky_target_feature), &[]),
623 ("float7e60", Unstable(sym::csky_target_feature), &[]),
624 ("floate1", Unstable(sym::csky_target_feature), &[]),
625 ("hard-tp", Unstable(sym::csky_target_feature), &[]),
626 ("high-registers", Unstable(sym::csky_target_feature), &[]),
627 ("hwdiv", Unstable(sym::csky_target_feature), &[]),
628 ("mp", Unstable(sym::csky_target_feature), &["2e3"]),
629 ("mp1e2", Unstable(sym::csky_target_feature), &["3e7"]),
630 ("nvic", Unstable(sym::csky_target_feature), &[]),
631 ("trust", Unstable(sym::csky_target_feature), &[]),
632 ("vdsp2e60f", Unstable(sym::csky_target_feature), &[]),
633 ("vdspv1", Unstable(sym::csky_target_feature), &[]),
634 ("vdspv2", Unstable(sym::csky_target_feature), &[]),
635 ("fdivdu", Unstable(sym::csky_target_feature), &[]),
639 ("fpuv2_df", Unstable(sym::csky_target_feature), &[]),
640 ("fpuv2_sf", Unstable(sym::csky_target_feature), &[]),
641 ("fpuv3_df", Unstable(sym::csky_target_feature), &[]),
642 ("fpuv3_hf", Unstable(sym::csky_target_feature), &[]),
643 ("fpuv3_hi", Unstable(sym::csky_target_feature), &[]),
644 ("fpuv3_sf", Unstable(sym::csky_target_feature), &[]),
645 ("hard-float", Unstable(sym::csky_target_feature), &[]),
646 ("hard-float-abi", Unstable(sym::csky_target_feature), &[]),
647 ];
649
650static LOONGARCH_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
651 ("d", Unstable(sym::loongarch_target_feature), &["f"]),
653 ("div32", Unstable(sym::loongarch_target_feature), &[]),
654 ("f", Unstable(sym::loongarch_target_feature), &[]),
655 ("frecipe", Unstable(sym::loongarch_target_feature), &[]),
656 ("lam-bh", Unstable(sym::loongarch_target_feature), &[]),
657 ("lamcas", Unstable(sym::loongarch_target_feature), &[]),
658 ("lasx", Unstable(sym::loongarch_target_feature), &["lsx"]),
659 ("lbt", Unstable(sym::loongarch_target_feature), &[]),
660 ("ld-seq-sa", Unstable(sym::loongarch_target_feature), &[]),
661 ("lsx", Unstable(sym::loongarch_target_feature), &["d"]),
662 ("lvz", Unstable(sym::loongarch_target_feature), &[]),
663 ("relax", Unstable(sym::loongarch_target_feature), &[]),
664 ("scq", Unstable(sym::loongarch_target_feature), &[]),
665 ("ual", Unstable(sym::loongarch_target_feature), &[]),
666 ];
668
669const IBMZ_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
670 ("backchain", Unstable(sym::s390x_target_feature), &[]),
672 ("deflate-conversion", Unstable(sym::s390x_target_feature), &[]),
673 ("enhanced-sort", Unstable(sym::s390x_target_feature), &[]),
674 ("guarded-storage", Unstable(sym::s390x_target_feature), &[]),
675 ("high-word", Unstable(sym::s390x_target_feature), &[]),
676 ("nnp-assist", Unstable(sym::s390x_target_feature), &["vector"]),
677 ("transactional-execution", Unstable(sym::s390x_target_feature), &[]),
678 ("vector", Unstable(sym::s390x_target_feature), &[]),
679 ("vector-enhancements-1", Unstable(sym::s390x_target_feature), &["vector"]),
680 ("vector-enhancements-2", Unstable(sym::s390x_target_feature), &["vector-enhancements-1"]),
681 ("vector-packed-decimal", Unstable(sym::s390x_target_feature), &["vector"]),
682 (
683 "vector-packed-decimal-enhancement",
684 Unstable(sym::s390x_target_feature),
685 &["vector-packed-decimal"],
686 ),
687 (
688 "vector-packed-decimal-enhancement-2",
689 Unstable(sym::s390x_target_feature),
690 &["vector-packed-decimal-enhancement"],
691 ),
692 ];
694
695const SPARC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
696 ("leoncasa", Unstable(sym::sparc_target_feature), &[]),
698 ("v8plus", Unstable(sym::sparc_target_feature), &[]),
699 ("v9", Unstable(sym::sparc_target_feature), &[]),
700 ];
702
703static M68K_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
704 ("isa-68000", Unstable(sym::m68k_target_feature), &[]),
706 ("isa-68010", Unstable(sym::m68k_target_feature), &["isa-68000"]),
707 ("isa-68020", Unstable(sym::m68k_target_feature), &["isa-68010"]),
708 ("isa-68030", Unstable(sym::m68k_target_feature), &["isa-68020"]),
709 ("isa-68040", Unstable(sym::m68k_target_feature), &["isa-68030", "isa-68882"]),
710 ("isa-68060", Unstable(sym::m68k_target_feature), &["isa-68040"]),
711 ("isa-68881", Unstable(sym::m68k_target_feature), &[]),
713 ("isa-68882", Unstable(sym::m68k_target_feature), &["isa-68881"]),
714 ];
716
717pub fn all_rust_features() -> impl Iterator<Item = (&'static str, Stability)> {
722 std::iter::empty()
723 .chain(ARM_FEATURES.iter())
724 .chain(AARCH64_FEATURES.iter())
725 .chain(X86_FEATURES.iter())
726 .chain(HEXAGON_FEATURES.iter())
727 .chain(POWERPC_FEATURES.iter())
728 .chain(MIPS_FEATURES.iter())
729 .chain(RISCV_FEATURES.iter())
730 .chain(WASM_FEATURES.iter())
731 .chain(BPF_FEATURES.iter())
732 .chain(CSKY_FEATURES)
733 .chain(LOONGARCH_FEATURES)
734 .chain(IBMZ_FEATURES)
735 .chain(SPARC_FEATURES)
736 .chain(M68K_FEATURES)
737 .cloned()
738 .map(|(f, s, _)| (f, s))
739}
740
741const X86_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
745 &[(128, "sse"), (256, "avx"), (512, "avx512f")]; const AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")];
747
748const ARM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")];
750
751const POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "altivec")];
752const WASM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "simd128")];
753const S390X_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vector")];
754const RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[
755 (32, "zvl32b"),
756 (64, "zvl64b"),
757 (128, "zvl128b"),
758 (256, "zvl256b"),
759 (512, "zvl512b"),
760 (1024, "zvl1024b"),
761 (2048, "zvl2048b"),
762 (4096, "zvl4096b"),
763 (8192, "zvl8192b"),
764 (16384, "zvl16384b"),
765 (32768, "zvl32768b"),
766 (65536, "zvl65536b"),
767];
768const SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[];
770
771const HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
772 &[(1024, "hvx-length128b")];
773const MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "msa")];
774const CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vdspv1")];
775const LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
776 &[(128, "lsx"), (256, "lasx")];
777
778#[derive(Copy, Clone, Debug)]
779pub struct FeatureConstraints {
780 pub required: &'static [&'static str],
782 pub incompatible: &'static [&'static str],
784}
785
786impl Target {
787 pub fn rust_target_features(&self) -> &'static [(&'static str, Stability, ImpliedFeatures)] {
788 match &*self.arch {
789 "arm" => ARM_FEATURES,
790 "aarch64" | "arm64ec" => AARCH64_FEATURES,
791 "x86" | "x86_64" => X86_FEATURES,
792 "hexagon" => HEXAGON_FEATURES,
793 "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_FEATURES,
794 "powerpc" | "powerpc64" => POWERPC_FEATURES,
795 "riscv32" | "riscv64" => RISCV_FEATURES,
796 "wasm32" | "wasm64" => WASM_FEATURES,
797 "bpf" => BPF_FEATURES,
798 "csky" => CSKY_FEATURES,
799 "loongarch64" => LOONGARCH_FEATURES,
800 "s390x" => IBMZ_FEATURES,
801 "sparc" | "sparc64" => SPARC_FEATURES,
802 "m68k" => M68K_FEATURES,
803 _ => &[],
804 }
805 }
806
807 pub fn features_for_correct_vector_abi(&self) -> &'static [(u64, &'static str)] {
808 match &*self.arch {
809 "x86" | "x86_64" => X86_FEATURES_FOR_CORRECT_VECTOR_ABI,
810 "aarch64" | "arm64ec" => AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI,
811 "arm" => ARM_FEATURES_FOR_CORRECT_VECTOR_ABI,
812 "powerpc" | "powerpc64" => POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI,
813 "loongarch64" => LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI,
814 "riscv32" | "riscv64" => RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI,
815 "wasm32" | "wasm64" => WASM_FEATURES_FOR_CORRECT_VECTOR_ABI,
816 "s390x" => S390X_FEATURES_FOR_CORRECT_VECTOR_ABI,
817 "sparc" | "sparc64" => SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI,
818 "hexagon" => HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI,
819 "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI,
820 "bpf" | "m68k" => &[], "csky" => CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI,
822 _ => &[],
825 }
826 }
827
828 pub fn tied_target_features(&self) -> &'static [&'static [&'static str]] {
829 match &*self.arch {
830 "aarch64" | "arm64ec" => AARCH64_TIED_FEATURES,
831 _ => &[],
832 }
833 }
834
835 pub fn implied_target_features<'a>(&self, base_feature: &'a str) -> FxHashSet<&'a str> {
837 let implied_features =
838 self.rust_target_features().iter().map(|(f, _, i)| (f, i)).collect::<FxHashMap<_, _>>();
839
840 let mut features = FxHashSet::default();
843 let mut new_features = vec![base_feature];
844 while let Some(new_feature) = new_features.pop() {
845 if features.insert(new_feature) {
846 if let Some(implied_features) = implied_features.get(&new_feature) {
847 new_features.extend(implied_features.iter().copied())
848 }
849 }
850 }
851 features
852 }
853
854 pub fn abi_required_features(&self) -> FeatureConstraints {
865 const NOTHING: FeatureConstraints = FeatureConstraints { required: &[], incompatible: &[] };
866 match &*self.arch {
871 "x86" => {
872 match self.rustc_abi {
875 None => {
876 FeatureConstraints { required: &["x87"], incompatible: &["soft-float"] }
879 }
880 Some(RustcAbi::X86Sse2) => {
881 FeatureConstraints {
883 required: &["x87", "sse2"],
884 incompatible: &["soft-float"],
885 }
886 }
887 Some(RustcAbi::X86Softfloat) => {
888 FeatureConstraints { required: &["soft-float"], incompatible: &[] }
893 }
894 }
895 }
896 "x86_64" => {
897 match self.rustc_abi {
900 None => {
901 FeatureConstraints {
903 required: &["x87", "sse2"],
904 incompatible: &["soft-float"],
905 }
906 }
907 Some(RustcAbi::X86Softfloat) => {
908 FeatureConstraints { required: &["soft-float"], incompatible: &[] }
913 }
914 Some(r) => panic!("invalid Rust ABI for x86_64: {r:?}"),
915 }
916 }
917 "arm" => {
918 match self.llvm_floatabi.unwrap() {
921 FloatAbi::Soft => {
922 NOTHING
927 }
928 FloatAbi::Hard => {
929 FeatureConstraints { required: &["fpregs"], incompatible: &["soft-float"] }
931 }
932 }
933 }
934 "aarch64" | "arm64ec" => {
935 match &*self.abi {
938 "softfloat" => {
939 NOTHING
943 }
944 _ => {
945 FeatureConstraints { required: &["neon"], incompatible: &[] }
948 }
949 }
950 }
951 "riscv32" | "riscv64" => {
952 match &*self.llvm_abiname {
955 "ilp32d" | "lp64d" => {
956 FeatureConstraints { required: &["d"], incompatible: &["e"] }
958 }
959 "ilp32f" | "lp64f" => {
960 FeatureConstraints { required: &["f"], incompatible: &["e"] }
962 }
963 "ilp32" | "lp64" => {
964 FeatureConstraints { required: &[], incompatible: &["e"] }
966 }
967 "ilp32e" => {
968 FeatureConstraints { required: &[], incompatible: &["d"] }
977 }
978 "lp64e" => {
979 NOTHING
981 }
982 _ => unreachable!(),
983 }
984 }
985 "loongarch64" => {
986 match &*self.llvm_abiname {
989 "ilp32d" | "lp64d" => {
990 FeatureConstraints { required: &["d"], incompatible: &[] }
992 }
993 "ilp32f" | "lp64f" => {
994 FeatureConstraints { required: &["f"], incompatible: &[] }
996 }
997 "ilp32s" | "lp64s" => {
998 NOTHING
1003 }
1004 _ => unreachable!(),
1005 }
1006 }
1007 _ => NOTHING,
1008 }
1009 }
1010}