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
14#[derive(Debug, Copy, Clone)]
16pub enum Stability {
17 Stable,
20 Unstable(
23 Symbol,
26 ),
27 Forbidden { reason: &'static str },
32}
33use Stability::*;
34
35impl<CTX> HashStable<CTX> for Stability {
36 #[inline]
37 fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
38 std::mem::discriminant(self).hash_stable(hcx, hasher);
39 match self {
40 Stability::Stable => {}
41 Stability::Unstable(nightly_feature) => {
42 nightly_feature.hash_stable(hcx, hasher);
43 }
44 Stability::Forbidden { reason } => {
45 reason.hash_stable(hcx, hasher);
46 }
47 }
48 }
49}
50
51impl Stability {
52 pub fn in_cfg(&self) -> bool {
56 matches!(self, Stability::Stable | Stability::Unstable { .. })
57 }
58
59 pub fn requires_nightly(&self) -> Option<Symbol> {
68 match *self {
69 Stability::Unstable(nightly_feature) => Some(nightly_feature),
70 Stability::Stable { .. } => None,
71 Stability::Forbidden { .. } => panic!("forbidden features should not reach this far"),
72 }
73 }
74
75 pub fn toggle_allowed(&self) -> Result<(), &'static str> {
79 match self {
80 Stability::Unstable(_) | Stability::Stable { .. } => Ok(()),
81 Stability::Forbidden { reason } => Err(reason),
82 }
83 }
84}
85
86type ImpliedFeatures = &'static [&'static str];
131
132static ARM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
133 ("aclass", Unstable(sym::arm_target_feature), &[]),
135 ("aes", Unstable(sym::arm_target_feature), &["neon"]),
136 (
137 "atomics-32",
138 Stability::Forbidden { reason: "unsound because it changes the ABI of atomic operations" },
139 &[],
140 ),
141 ("crc", Unstable(sym::arm_target_feature), &[]),
142 ("d32", Unstable(sym::arm_target_feature), &[]),
143 ("dotprod", Unstable(sym::arm_target_feature), &["neon"]),
144 ("dsp", Unstable(sym::arm_target_feature), &[]),
145 ("fp-armv8", Unstable(sym::arm_target_feature), &["vfp4"]),
146 ("fp16", Unstable(sym::arm_target_feature), &["neon"]),
147 ("fpregs", Unstable(sym::arm_target_feature), &[]),
148 ("i8mm", Unstable(sym::arm_target_feature), &["neon"]),
149 ("mclass", Unstable(sym::arm_target_feature), &[]),
150 ("neon", Unstable(sym::arm_target_feature), &["vfp3"]),
151 ("rclass", Unstable(sym::arm_target_feature), &[]),
152 ("sha2", Unstable(sym::arm_target_feature), &["neon"]),
153 ("soft-float", Unstable(sym::arm_target_feature), &[]),
158 ("thumb-mode", Unstable(sym::arm_target_feature), &[]),
162 ("thumb2", Unstable(sym::arm_target_feature), &[]),
163 ("trustzone", Unstable(sym::arm_target_feature), &[]),
164 ("v5te", Unstable(sym::arm_target_feature), &[]),
165 ("v6", Unstable(sym::arm_target_feature), &["v5te"]),
166 ("v6k", Unstable(sym::arm_target_feature), &["v6"]),
167 ("v6t2", Unstable(sym::arm_target_feature), &["v6k", "thumb2"]),
168 ("v7", Unstable(sym::arm_target_feature), &["v6t2"]),
169 ("v8", Unstable(sym::arm_target_feature), &["v7"]),
170 ("vfp2", Unstable(sym::arm_target_feature), &[]),
171 ("vfp3", Unstable(sym::arm_target_feature), &["vfp2", "d32"]),
172 ("vfp4", Unstable(sym::arm_target_feature), &["vfp3"]),
173 ("virtualization", Unstable(sym::arm_target_feature), &[]),
174 ];
176
177static AARCH64_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
178 ("aes", Stable, &["neon"]),
181 ("bf16", Stable, &[]),
183 ("bti", Stable, &[]),
185 ("crc", Stable, &[]),
187 ("cssc", Unstable(sym::aarch64_unstable_target_feature), &[]),
189 ("dit", Stable, &[]),
191 ("dotprod", Stable, &["neon"]),
193 ("dpb", Stable, &[]),
195 ("dpb2", Stable, &["dpb"]),
197 ("ecv", Unstable(sym::aarch64_unstable_target_feature), &[]),
199 ("f32mm", Stable, &["sve"]),
201 ("f64mm", Stable, &["sve"]),
203 ("faminmax", Unstable(sym::aarch64_unstable_target_feature), &[]),
205 ("fcma", Stable, &["neon"]),
207 ("fhm", Stable, &["fp16"]),
209 ("flagm", Stable, &[]),
211 ("flagm2", Unstable(sym::aarch64_unstable_target_feature), &[]),
213 ("fp-armv8", Stability::Forbidden { reason: "Rust ties `fp-armv8` to `neon`" }, &[]),
215 ("fp8", Unstable(sym::aarch64_unstable_target_feature), &["faminmax", "lut", "bf16"]),
217 ("fp8dot2", Unstable(sym::aarch64_unstable_target_feature), &["fp8dot4"]),
219 ("fp8dot4", Unstable(sym::aarch64_unstable_target_feature), &["fp8fma"]),
221 ("fp8fma", Unstable(sym::aarch64_unstable_target_feature), &["fp8"]),
223 ("fp16", Stable, &["neon"]),
226 ("frintts", Stable, &[]),
228 ("hbc", Unstable(sym::aarch64_unstable_target_feature), &[]),
230 ("i8mm", Stable, &[]),
232 ("jsconv", Stable, &["neon"]),
235 ("lor", Stable, &[]),
237 ("lse", Stable, &[]),
239 ("lse2", Unstable(sym::aarch64_unstable_target_feature), &[]),
241 ("lse128", Unstable(sym::aarch64_unstable_target_feature), &["lse"]),
243 ("lut", Unstable(sym::aarch64_unstable_target_feature), &[]),
245 ("mops", Unstable(sym::aarch64_unstable_target_feature), &[]),
247 ("mte", Stable, &[]),
249 ("neon", Stable, &[]),
251 ("paca", Stable, &[]),
253 ("pacg", Stable, &[]),
255 ("pan", Stable, &[]),
257 ("pauth-lr", Unstable(sym::aarch64_unstable_target_feature), &[]),
259 ("pmuv3", Stable, &[]),
261 ("rand", Stable, &[]),
263 ("ras", Stable, &[]),
265 ("rcpc", Stable, &[]),
267 ("rcpc2", Stable, &["rcpc"]),
269 ("rcpc3", Unstable(sym::aarch64_unstable_target_feature), &["rcpc2"]),
271 ("rdm", Stable, &["neon"]),
273 ("reserve-x18", Forbidden { reason: "use `-Zfixed-x18` compiler flag instead" }, &[]),
274 ("sb", Stable, &[]),
276 ("sha2", Stable, &["neon"]),
278 ("sha3", Stable, &["sha2"]),
280 ("sm4", Stable, &["neon"]),
282 ("sme", Unstable(sym::aarch64_unstable_target_feature), &["bf16"]),
284 ("sme-b16b16", Unstable(sym::aarch64_unstable_target_feature), &["bf16", "sme2", "sve-b16b16"]),
286 ("sme-f8f16", Unstable(sym::aarch64_unstable_target_feature), &["sme-f8f32"]),
288 ("sme-f8f32", Unstable(sym::aarch64_unstable_target_feature), &["sme2", "fp8"]),
290 ("sme-f16f16", Unstable(sym::aarch64_unstable_target_feature), &["sme2"]),
292 ("sme-f64f64", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
294 ("sme-fa64", Unstable(sym::aarch64_unstable_target_feature), &["sme", "sve2"]),
296 ("sme-i16i64", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
298 ("sme-lutv2", Unstable(sym::aarch64_unstable_target_feature), &[]),
300 ("sme2", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
302 ("sme2p1", Unstable(sym::aarch64_unstable_target_feature), &["sme2"]),
304 ("spe", Stable, &[]),
306 ("ssbs", Stable, &[]),
308 ("ssve-fp8dot2", Unstable(sym::aarch64_unstable_target_feature), &["ssve-fp8dot4"]),
310 ("ssve-fp8dot4", Unstable(sym::aarch64_unstable_target_feature), &["ssve-fp8fma"]),
312 ("ssve-fp8fma", Unstable(sym::aarch64_unstable_target_feature), &["sme2", "fp8"]),
314 ("sve", Stable, &["neon"]),
322 ("sve-b16b16", Unstable(sym::aarch64_unstable_target_feature), &["bf16"]),
324 ("sve2", Stable, &["sve"]),
326 ("sve2-aes", Stable, &["sve2", "aes"]),
328 ("sve2-bitperm", Stable, &["sve2"]),
330 ("sve2-sha3", Stable, &["sve2", "sha3"]),
332 ("sve2-sm4", Stable, &["sve2", "sm4"]),
334 ("sve2p1", Unstable(sym::aarch64_unstable_target_feature), &["sve2"]),
336 ("tme", Stable, &[]),
338 (
339 "v8.1a",
340 Unstable(sym::aarch64_ver_target_feature),
341 &["crc", "lse", "rdm", "pan", "lor", "vh"],
342 ),
343 ("v8.2a", Unstable(sym::aarch64_ver_target_feature), &["v8.1a", "ras", "dpb"]),
344 (
345 "v8.3a",
346 Unstable(sym::aarch64_ver_target_feature),
347 &["v8.2a", "rcpc", "paca", "pacg", "jsconv"],
348 ),
349 ("v8.4a", Unstable(sym::aarch64_ver_target_feature), &["v8.3a", "dotprod", "dit", "flagm"]),
350 ("v8.5a", Unstable(sym::aarch64_ver_target_feature), &["v8.4a", "ssbs", "sb", "dpb2", "bti"]),
351 ("v8.6a", Unstable(sym::aarch64_ver_target_feature), &["v8.5a", "bf16", "i8mm"]),
352 ("v8.7a", Unstable(sym::aarch64_ver_target_feature), &["v8.6a", "wfxt"]),
353 ("v8.8a", Unstable(sym::aarch64_ver_target_feature), &["v8.7a", "hbc", "mops"]),
354 ("v8.9a", Unstable(sym::aarch64_ver_target_feature), &["v8.8a", "cssc"]),
355 ("v9.1a", Unstable(sym::aarch64_ver_target_feature), &["v9a", "v8.6a"]),
356 ("v9.2a", Unstable(sym::aarch64_ver_target_feature), &["v9.1a", "v8.7a"]),
357 ("v9.3a", Unstable(sym::aarch64_ver_target_feature), &["v9.2a", "v8.8a"]),
358 ("v9.4a", Unstable(sym::aarch64_ver_target_feature), &["v9.3a", "v8.9a"]),
359 ("v9.5a", Unstable(sym::aarch64_ver_target_feature), &["v9.4a"]),
360 ("v9a", Unstable(sym::aarch64_ver_target_feature), &["v8.5a", "sve2"]),
361 ("vh", Stable, &[]),
363 ("wfxt", Unstable(sym::aarch64_unstable_target_feature), &[]),
365 ];
367
368const AARCH64_TIED_FEATURES: &[&[&str]] = &[
369 &["paca", "pacg"], ];
371
372static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
373 ("adx", Stable, &[]),
375 ("aes", Stable, &["sse2"]),
376 ("amx-avx512", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
377 ("amx-bf16", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
378 ("amx-complex", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
379 ("amx-fp8", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
380 ("amx-fp16", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
381 ("amx-int8", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
382 ("amx-movrs", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
383 ("amx-tf32", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
384 ("amx-tile", Unstable(sym::x86_amx_intrinsics), &[]),
385 ("amx-transpose", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
386 ("apxf", Unstable(sym::apx_target_feature), &[]),
387 ("avx", Stable, &["sse4.2"]),
388 ("avx2", Stable, &["avx"]),
389 (
390 "avx10.1",
391 Unstable(sym::avx10_target_feature),
392 &[
393 "avx512bf16",
394 "avx512bitalg",
395 "avx512bw",
396 "avx512cd",
397 "avx512dq",
398 "avx512f",
399 "avx512fp16",
400 "avx512ifma",
401 "avx512vbmi",
402 "avx512vbmi2",
403 "avx512vl",
404 "avx512vnni",
405 "avx512vpopcntdq",
406 ],
407 ),
408 ("avx10.2", Unstable(sym::avx10_target_feature), &["avx10.1"]),
409 ("avx512bf16", Stable, &["avx512bw"]),
410 ("avx512bitalg", Stable, &["avx512bw"]),
411 ("avx512bw", Stable, &["avx512f"]),
412 ("avx512cd", Stable, &["avx512f"]),
413 ("avx512dq", Stable, &["avx512f"]),
414 ("avx512f", Stable, &["avx2", "fma", "f16c"]),
415 ("avx512fp16", Stable, &["avx512bw"]),
416 ("avx512ifma", Stable, &["avx512f"]),
417 ("avx512vbmi", Stable, &["avx512bw"]),
418 ("avx512vbmi2", Stable, &["avx512bw"]),
419 ("avx512vl", Stable, &["avx512f"]),
420 ("avx512vnni", Stable, &["avx512f"]),
421 ("avx512vp2intersect", Stable, &["avx512f"]),
422 ("avx512vpopcntdq", Stable, &["avx512f"]),
423 ("avxifma", Stable, &["avx2"]),
424 ("avxneconvert", Stable, &["avx2"]),
425 ("avxvnni", Stable, &["avx2"]),
426 ("avxvnniint8", Stable, &["avx2"]),
427 ("avxvnniint16", Stable, &["avx2"]),
428 ("bmi1", Stable, &[]),
429 ("bmi2", Stable, &[]),
430 ("cmpxchg16b", Stable, &[]),
431 ("ermsb", Unstable(sym::ermsb_target_feature), &[]),
432 ("f16c", Stable, &["avx"]),
433 ("fma", Stable, &["avx"]),
434 ("fxsr", Stable, &[]),
435 ("gfni", Stable, &["sse2"]),
436 ("kl", Stable, &["sse2"]),
437 ("lahfsahf", Unstable(sym::lahfsahf_target_feature), &[]),
438 ("lzcnt", Stable, &[]),
439 ("movbe", Stable, &[]),
440 ("movrs", Unstable(sym::movrs_target_feature), &[]),
441 ("pclmulqdq", Stable, &["sse2"]),
442 ("popcnt", Stable, &[]),
443 ("prfchw", Unstable(sym::prfchw_target_feature), &[]),
444 ("rdrand", Stable, &[]),
445 ("rdseed", Stable, &[]),
446 (
447 "retpoline-external-thunk",
448 Stability::Forbidden { reason: "use `-Zretpoline-external-thunk` compiler flag instead" },
449 &[],
450 ),
451 (
452 "retpoline-indirect-branches",
453 Stability::Forbidden { reason: "use `-Zretpoline` compiler flag instead" },
454 &[],
455 ),
456 (
457 "retpoline-indirect-calls",
458 Stability::Forbidden { reason: "use `-Zretpoline` compiler flag instead" },
459 &[],
460 ),
461 ("rtm", Unstable(sym::rtm_target_feature), &[]),
462 ("sha", Stable, &["sse2"]),
463 ("sha512", Stable, &["avx2"]),
464 ("sm3", Stable, &["avx"]),
465 ("sm4", Stable, &["avx2"]),
466 ("soft-float", Stability::Unstable(sym::x87_target_feature), &[]),
469 ("sse", Stable, &[]),
470 ("sse2", Stable, &["sse"]),
471 ("sse3", Stable, &["sse2"]),
472 ("sse4.1", Stable, &["ssse3"]),
473 ("sse4.2", Stable, &["sse4.1"]),
474 ("sse4a", Unstable(sym::sse4a_target_feature), &["sse3"]),
475 ("ssse3", Stable, &["sse3"]),
476 ("tbm", Unstable(sym::tbm_target_feature), &[]),
477 ("vaes", Stable, &["avx2", "aes"]),
478 ("vpclmulqdq", Stable, &["avx", "pclmulqdq"]),
479 ("widekl", Stable, &["kl"]),
480 ("x87", Unstable(sym::x87_target_feature), &[]),
481 ("xop", Unstable(sym::xop_target_feature), &["avx", "sse4a"]),
482 ("xsave", Stable, &[]),
483 ("xsavec", Stable, &["xsave"]),
484 ("xsaveopt", Stable, &["xsave"]),
485 ("xsaves", Stable, &["xsave"]),
486 ];
488
489const HEXAGON_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
490 ("hvx", Unstable(sym::hexagon_target_feature), &[]),
492 ("hvx-length128b", Unstable(sym::hexagon_target_feature), &["hvx"]),
493 ];
495
496static POWERPC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
497 ("altivec", Unstable(sym::powerpc_target_feature), &[]),
499 ("msync", Unstable(sym::powerpc_target_feature), &[]),
500 ("partword-atomics", Unstable(sym::powerpc_target_feature), &[]),
501 ("power8-altivec", Unstable(sym::powerpc_target_feature), &["altivec"]),
502 ("power8-crypto", Unstable(sym::powerpc_target_feature), &["power8-altivec"]),
503 ("power8-vector", Unstable(sym::powerpc_target_feature), &["vsx", "power8-altivec"]),
504 ("power9-altivec", Unstable(sym::powerpc_target_feature), &["power8-altivec"]),
505 ("power9-vector", Unstable(sym::powerpc_target_feature), &["power8-vector", "power9-altivec"]),
506 ("power10-vector", Unstable(sym::powerpc_target_feature), &["power9-vector"]),
507 ("quadword-atomics", Unstable(sym::powerpc_target_feature), &[]),
508 ("vsx", Unstable(sym::powerpc_target_feature), &["altivec"]),
509 ];
511
512const MIPS_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
513 ("fp64", Unstable(sym::mips_target_feature), &[]),
515 ("msa", Unstable(sym::mips_target_feature), &[]),
516 ("virt", Unstable(sym::mips_target_feature), &[]),
517 ];
519
520static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
521 ("a", Stable, &["zaamo", "zalrsc"]),
523 ("b", Unstable(sym::riscv_target_feature), &["zba", "zbb", "zbs"]),
524 ("c", Stable, &["zca"]),
525 ("d", Unstable(sym::riscv_target_feature), &["f"]),
526 ("e", Unstable(sym::riscv_target_feature), &[]),
527 ("f", Unstable(sym::riscv_target_feature), &["zicsr"]),
528 (
529 "forced-atomics",
530 Stability::Forbidden { reason: "unsound because it changes the ABI of atomic operations" },
531 &[],
532 ),
533 ("m", Stable, &[]),
534 ("relax", Unstable(sym::riscv_target_feature), &[]),
535 ("unaligned-scalar-mem", Unstable(sym::riscv_target_feature), &[]),
536 ("unaligned-vector-mem", Unstable(sym::riscv_target_feature), &[]),
537 ("v", Unstable(sym::riscv_target_feature), &["zvl128b", "zve64d"]),
538 ("za64rs", Unstable(sym::riscv_target_feature), &["za128rs"]), ("za128rs", Unstable(sym::riscv_target_feature), &[]),
540 ("zaamo", Unstable(sym::riscv_target_feature), &[]),
541 ("zabha", Unstable(sym::riscv_target_feature), &["zaamo"]),
542 ("zacas", Unstable(sym::riscv_target_feature), &["zaamo"]),
543 ("zalrsc", Unstable(sym::riscv_target_feature), &[]),
544 ("zama16b", Unstable(sym::riscv_target_feature), &[]),
545 ("zawrs", Unstable(sym::riscv_target_feature), &[]),
546 ("zba", Stable, &[]),
547 ("zbb", Stable, &[]),
548 ("zbc", Stable, &["zbkc"]), ("zbkb", Stable, &[]),
550 ("zbkc", Stable, &[]),
551 ("zbkx", Stable, &[]),
552 ("zbs", Stable, &[]),
553 ("zca", Unstable(sym::riscv_target_feature), &[]),
554 ("zcb", Unstable(sym::riscv_target_feature), &["zca"]),
555 ("zcmop", Unstable(sym::riscv_target_feature), &["zca"]),
556 ("zdinx", Unstable(sym::riscv_target_feature), &["zfinx"]),
557 ("zfa", Unstable(sym::riscv_target_feature), &["f"]),
558 ("zfbfmin", Unstable(sym::riscv_target_feature), &["f"]), ("zfh", Unstable(sym::riscv_target_feature), &["zfhmin"]),
560 ("zfhmin", Unstable(sym::riscv_target_feature), &["f"]),
561 ("zfinx", Unstable(sym::riscv_target_feature), &["zicsr"]),
562 ("zhinx", Unstable(sym::riscv_target_feature), &["zhinxmin"]),
563 ("zhinxmin", Unstable(sym::riscv_target_feature), &["zfinx"]),
564 ("zic64b", Unstable(sym::riscv_target_feature), &[]),
565 ("zicbom", Unstable(sym::riscv_target_feature), &[]),
566 ("zicbop", Unstable(sym::riscv_target_feature), &[]),
567 ("zicboz", Unstable(sym::riscv_target_feature), &[]),
568 ("ziccamoa", Unstable(sym::riscv_target_feature), &[]),
569 ("ziccif", Unstable(sym::riscv_target_feature), &[]),
570 ("zicclsm", Unstable(sym::riscv_target_feature), &[]),
571 ("ziccrse", Unstable(sym::riscv_target_feature), &[]),
572 ("zicntr", Unstable(sym::riscv_target_feature), &["zicsr"]),
573 ("zicond", Unstable(sym::riscv_target_feature), &[]),
574 ("zicsr", Unstable(sym::riscv_target_feature), &[]),
575 ("zifencei", Unstable(sym::riscv_target_feature), &[]),
576 ("zihintntl", Unstable(sym::riscv_target_feature), &[]),
577 ("zihintpause", Unstable(sym::riscv_target_feature), &[]),
578 ("zihpm", Unstable(sym::riscv_target_feature), &["zicsr"]),
579 ("zimop", Unstable(sym::riscv_target_feature), &[]),
580 ("zk", Stable, &["zkn", "zkr", "zkt"]),
581 ("zkn", Stable, &["zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"]),
582 ("zknd", Stable, &[]),
583 ("zkne", Stable, &[]),
584 ("zknh", Stable, &[]),
585 ("zkr", Stable, &[]),
586 ("zks", Stable, &["zbkb", "zbkc", "zbkx", "zksed", "zksh"]),
587 ("zksed", Stable, &[]),
588 ("zksh", Stable, &[]),
589 ("zkt", Stable, &[]),
590 ("ztso", Unstable(sym::riscv_target_feature), &[]),
591 ("zvbb", Unstable(sym::riscv_target_feature), &["zvkb"]), ("zvbc", Unstable(sym::riscv_target_feature), &["zve64x"]),
593 ("zve32f", Unstable(sym::riscv_target_feature), &["zve32x", "f"]),
594 ("zve32x", Unstable(sym::riscv_target_feature), &["zvl32b", "zicsr"]),
595 ("zve64d", Unstable(sym::riscv_target_feature), &["zve64f", "d"]),
596 ("zve64f", Unstable(sym::riscv_target_feature), &["zve32f", "zve64x"]),
597 ("zve64x", Unstable(sym::riscv_target_feature), &["zve32x", "zvl64b"]),
598 ("zvfbfmin", Unstable(sym::riscv_target_feature), &["zve32f"]),
599 ("zvfbfwma", Unstable(sym::riscv_target_feature), &["zfbfmin", "zvfbfmin"]),
600 ("zvfh", Unstable(sym::riscv_target_feature), &["zvfhmin", "zve32f", "zfhmin"]), ("zvfhmin", Unstable(sym::riscv_target_feature), &["zve32f"]),
602 ("zvkb", Unstable(sym::riscv_target_feature), &["zve32x"]),
603 ("zvkg", Unstable(sym::riscv_target_feature), &["zve32x"]),
604 ("zvkn", Unstable(sym::riscv_target_feature), &["zvkned", "zvknhb", "zvkb", "zvkt"]),
605 ("zvknc", Unstable(sym::riscv_target_feature), &["zvkn", "zvbc"]),
606 ("zvkned", Unstable(sym::riscv_target_feature), &["zve32x"]),
607 ("zvkng", Unstable(sym::riscv_target_feature), &["zvkn", "zvkg"]),
608 ("zvknha", Unstable(sym::riscv_target_feature), &["zve32x"]),
609 ("zvknhb", Unstable(sym::riscv_target_feature), &["zvknha", "zve64x"]), ("zvks", Unstable(sym::riscv_target_feature), &["zvksed", "zvksh", "zvkb", "zvkt"]),
611 ("zvksc", Unstable(sym::riscv_target_feature), &["zvks", "zvbc"]),
612 ("zvksed", Unstable(sym::riscv_target_feature), &["zve32x"]),
613 ("zvksg", Unstable(sym::riscv_target_feature), &["zvks", "zvkg"]),
614 ("zvksh", Unstable(sym::riscv_target_feature), &["zve32x"]),
615 ("zvkt", Unstable(sym::riscv_target_feature), &[]),
616 ("zvl32b", Unstable(sym::riscv_target_feature), &[]),
617 ("zvl64b", Unstable(sym::riscv_target_feature), &["zvl32b"]),
618 ("zvl128b", Unstable(sym::riscv_target_feature), &["zvl64b"]),
619 ("zvl256b", Unstable(sym::riscv_target_feature), &["zvl128b"]),
620 ("zvl512b", Unstable(sym::riscv_target_feature), &["zvl256b"]),
621 ("zvl1024b", Unstable(sym::riscv_target_feature), &["zvl512b"]),
622 ("zvl2048b", Unstable(sym::riscv_target_feature), &["zvl1024b"]),
623 ("zvl4096b", Unstable(sym::riscv_target_feature), &["zvl2048b"]),
624 ("zvl8192b", Unstable(sym::riscv_target_feature), &["zvl4096b"]),
625 ("zvl16384b", Unstable(sym::riscv_target_feature), &["zvl8192b"]),
626 ("zvl32768b", Unstable(sym::riscv_target_feature), &["zvl16384b"]),
627 ("zvl65536b", Unstable(sym::riscv_target_feature), &["zvl32768b"]),
628 ];
630
631static WASM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
632 ("atomics", Unstable(sym::wasm_target_feature), &[]),
634 ("bulk-memory", Stable, &[]),
635 ("exception-handling", Unstable(sym::wasm_target_feature), &[]),
636 ("extended-const", Stable, &[]),
637 ("multivalue", Stable, &[]),
638 ("mutable-globals", Stable, &[]),
639 ("nontrapping-fptoint", Stable, &[]),
640 ("reference-types", Stable, &[]),
641 ("relaxed-simd", Stable, &["simd128"]),
642 ("sign-ext", Stable, &[]),
643 ("simd128", Stable, &[]),
644 ("tail-call", Stable, &[]),
645 ("wide-arithmetic", Unstable(sym::wasm_target_feature), &[]),
646 ];
648
649const BPF_FEATURES: &[(&str, Stability, ImpliedFeatures)] =
650 &[("alu32", Unstable(sym::bpf_target_feature), &[])];
651
652static CSKY_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
653 ("2e3", Unstable(sym::csky_target_feature), &["e2"]),
655 ("3e3r1", Unstable(sym::csky_target_feature), &[]),
656 ("3e3r2", Unstable(sym::csky_target_feature), &["3e3r1", "doloop"]),
657 ("3e3r3", Unstable(sym::csky_target_feature), &["doloop"]),
658 ("3e7", Unstable(sym::csky_target_feature), &["2e3"]),
659 ("7e10", Unstable(sym::csky_target_feature), &["3e7"]),
660 ("10e60", Unstable(sym::csky_target_feature), &["7e10"]),
661 ("cache", Unstable(sym::csky_target_feature), &[]),
662 ("doloop", Unstable(sym::csky_target_feature), &[]),
663 ("dsp1e2", Unstable(sym::csky_target_feature), &[]),
664 ("dspe60", Unstable(sym::csky_target_feature), &[]),
665 ("e1", Unstable(sym::csky_target_feature), &["elrw"]),
666 ("e2", Unstable(sym::csky_target_feature), &["e2"]),
667 ("edsp", Unstable(sym::csky_target_feature), &[]),
668 ("elrw", Unstable(sym::csky_target_feature), &[]),
669 ("float1e2", Unstable(sym::csky_target_feature), &[]),
670 ("float1e3", Unstable(sym::csky_target_feature), &[]),
671 ("float3e4", Unstable(sym::csky_target_feature), &[]),
672 ("float7e60", Unstable(sym::csky_target_feature), &[]),
673 ("floate1", Unstable(sym::csky_target_feature), &[]),
674 ("hard-tp", Unstable(sym::csky_target_feature), &[]),
675 ("high-registers", Unstable(sym::csky_target_feature), &[]),
676 ("hwdiv", Unstable(sym::csky_target_feature), &[]),
677 ("mp", Unstable(sym::csky_target_feature), &["2e3"]),
678 ("mp1e2", Unstable(sym::csky_target_feature), &["3e7"]),
679 ("nvic", Unstable(sym::csky_target_feature), &[]),
680 ("trust", Unstable(sym::csky_target_feature), &[]),
681 ("vdsp2e60f", Unstable(sym::csky_target_feature), &[]),
682 ("vdspv1", Unstable(sym::csky_target_feature), &[]),
683 ("vdspv2", Unstable(sym::csky_target_feature), &[]),
684 ("fdivdu", Unstable(sym::csky_target_feature), &[]),
688 ("fpuv2_df", Unstable(sym::csky_target_feature), &[]),
689 ("fpuv2_sf", Unstable(sym::csky_target_feature), &[]),
690 ("fpuv3_df", Unstable(sym::csky_target_feature), &[]),
691 ("fpuv3_hf", Unstable(sym::csky_target_feature), &[]),
692 ("fpuv3_hi", Unstable(sym::csky_target_feature), &[]),
693 ("fpuv3_sf", Unstable(sym::csky_target_feature), &[]),
694 ("hard-float", Unstable(sym::csky_target_feature), &[]),
695 ("hard-float-abi", Unstable(sym::csky_target_feature), &[]),
696 ];
698
699static LOONGARCH_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
700 ("d", Stable, &["f"]),
702 ("div32", Unstable(sym::loongarch_target_feature), &[]),
703 ("f", Stable, &[]),
704 ("frecipe", Stable, &[]),
705 ("lam-bh", Unstable(sym::loongarch_target_feature), &[]),
706 ("lamcas", Unstable(sym::loongarch_target_feature), &[]),
707 ("lasx", Stable, &["lsx"]),
708 ("lbt", Stable, &[]),
709 ("ld-seq-sa", Unstable(sym::loongarch_target_feature), &[]),
710 ("lsx", Stable, &["d"]),
711 ("lvz", Stable, &[]),
712 ("relax", Unstable(sym::loongarch_target_feature), &[]),
713 ("scq", Unstable(sym::loongarch_target_feature), &[]),
714 ("ual", Unstable(sym::loongarch_target_feature), &[]),
715 ];
717
718#[rustfmt::skip]
719const IBMZ_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
720 ("backchain", Unstable(sym::s390x_target_feature), &[]),
723 ("concurrent-functions", Unstable(sym::s390x_target_feature), &[]),
724 ("deflate-conversion", Unstable(sym::s390x_target_feature), &[]),
725 ("enhanced-sort", Unstable(sym::s390x_target_feature), &[]),
726 ("guarded-storage", Unstable(sym::s390x_target_feature), &[]),
727 ("high-word", Unstable(sym::s390x_target_feature), &[]),
728 ("message-security-assist-extension3", Unstable(sym::s390x_target_feature), &[]),
730 ("message-security-assist-extension4", Unstable(sym::s390x_target_feature), &[]),
731 ("message-security-assist-extension5", Unstable(sym::s390x_target_feature), &[]),
732 ("message-security-assist-extension8", Unstable(sym::s390x_target_feature), &["message-security-assist-extension3"]),
733 ("message-security-assist-extension9", Unstable(sym::s390x_target_feature), &["message-security-assist-extension3", "message-security-assist-extension4"]),
734 ("message-security-assist-extension12", Unstable(sym::s390x_target_feature), &[]),
735 ("miscellaneous-extensions-2", Unstable(sym::s390x_target_feature), &[]),
736 ("miscellaneous-extensions-3", Unstable(sym::s390x_target_feature), &[]),
737 ("miscellaneous-extensions-4", Unstable(sym::s390x_target_feature), &[]),
738 ("nnp-assist", Unstable(sym::s390x_target_feature), &["vector"]),
739 ("transactional-execution", Unstable(sym::s390x_target_feature), &[]),
740 ("vector", Unstable(sym::s390x_target_feature), &[]),
741 ("vector-enhancements-1", Unstable(sym::s390x_target_feature), &["vector"]),
742 ("vector-enhancements-2", Unstable(sym::s390x_target_feature), &["vector-enhancements-1"]),
743 ("vector-enhancements-3", Unstable(sym::s390x_target_feature), &["vector-enhancements-2"]),
744 ("vector-packed-decimal", Unstable(sym::s390x_target_feature), &["vector"]),
745 ("vector-packed-decimal-enhancement", Unstable(sym::s390x_target_feature), &["vector-packed-decimal"]),
746 ("vector-packed-decimal-enhancement-2", Unstable(sym::s390x_target_feature), &["vector-packed-decimal-enhancement"]),
747 ("vector-packed-decimal-enhancement-3", Unstable(sym::s390x_target_feature), &["vector-packed-decimal-enhancement-2"]),
748 ];
750
751const SPARC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
752 ("leoncasa", Unstable(sym::sparc_target_feature), &[]),
754 ("v8plus", Unstable(sym::sparc_target_feature), &[]),
755 ("v9", Unstable(sym::sparc_target_feature), &[]),
756 ];
758
759static M68K_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
760 ("isa-68000", Unstable(sym::m68k_target_feature), &[]),
762 ("isa-68010", Unstable(sym::m68k_target_feature), &["isa-68000"]),
763 ("isa-68020", Unstable(sym::m68k_target_feature), &["isa-68010"]),
764 ("isa-68030", Unstable(sym::m68k_target_feature), &["isa-68020"]),
765 ("isa-68040", Unstable(sym::m68k_target_feature), &["isa-68030", "isa-68882"]),
766 ("isa-68060", Unstable(sym::m68k_target_feature), &["isa-68040"]),
767 ("isa-68881", Unstable(sym::m68k_target_feature), &[]),
769 ("isa-68882", Unstable(sym::m68k_target_feature), &["isa-68881"]),
770 ];
772
773pub fn all_rust_features() -> impl Iterator<Item = (&'static str, Stability)> {
778 std::iter::empty()
779 .chain(ARM_FEATURES.iter())
780 .chain(AARCH64_FEATURES.iter())
781 .chain(X86_FEATURES.iter())
782 .chain(HEXAGON_FEATURES.iter())
783 .chain(POWERPC_FEATURES.iter())
784 .chain(MIPS_FEATURES.iter())
785 .chain(RISCV_FEATURES.iter())
786 .chain(WASM_FEATURES.iter())
787 .chain(BPF_FEATURES.iter())
788 .chain(CSKY_FEATURES)
789 .chain(LOONGARCH_FEATURES)
790 .chain(IBMZ_FEATURES)
791 .chain(SPARC_FEATURES)
792 .chain(M68K_FEATURES)
793 .cloned()
794 .map(|(f, s, _)| (f, s))
795}
796
797const X86_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
801 &[(128, "sse"), (256, "avx"), (512, "avx512f")]; const AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")];
803
804const ARM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")];
806
807const POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "altivec")];
808const WASM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "simd128")];
809const S390X_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vector")];
810const RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[
811 (32, "zvl32b"),
812 (64, "zvl64b"),
813 (128, "zvl128b"),
814 (256, "zvl256b"),
815 (512, "zvl512b"),
816 (1024, "zvl1024b"),
817 (2048, "zvl2048b"),
818 (4096, "zvl4096b"),
819 (8192, "zvl8192b"),
820 (16384, "zvl16384b"),
821 (32768, "zvl32768b"),
822 (65536, "zvl65536b"),
823];
824const SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[];
826
827const HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
828 &[(1024, "hvx-length128b")];
829const MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "msa")];
830const CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vdspv1")];
831const LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
832 &[(128, "lsx"), (256, "lasx")];
833
834#[derive(Copy, Clone, Debug)]
835pub struct FeatureConstraints {
836 pub required: &'static [&'static str],
838 pub incompatible: &'static [&'static str],
840}
841
842impl Target {
843 pub fn rust_target_features(&self) -> &'static [(&'static str, Stability, ImpliedFeatures)] {
844 match &*self.arch {
845 "arm" => ARM_FEATURES,
846 "aarch64" | "arm64ec" => AARCH64_FEATURES,
847 "x86" | "x86_64" => X86_FEATURES,
848 "hexagon" => HEXAGON_FEATURES,
849 "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_FEATURES,
850 "powerpc" | "powerpc64" => POWERPC_FEATURES,
851 "riscv32" | "riscv64" => RISCV_FEATURES,
852 "wasm32" | "wasm64" => WASM_FEATURES,
853 "bpf" => BPF_FEATURES,
854 "csky" => CSKY_FEATURES,
855 "loongarch32" | "loongarch64" => LOONGARCH_FEATURES,
856 "s390x" => IBMZ_FEATURES,
857 "sparc" | "sparc64" => SPARC_FEATURES,
858 "m68k" => M68K_FEATURES,
859 _ => &[],
860 }
861 }
862
863 pub fn features_for_correct_vector_abi(&self) -> &'static [(u64, &'static str)] {
864 match &*self.arch {
865 "x86" | "x86_64" => X86_FEATURES_FOR_CORRECT_VECTOR_ABI,
866 "aarch64" | "arm64ec" => AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI,
867 "arm" => ARM_FEATURES_FOR_CORRECT_VECTOR_ABI,
868 "powerpc" | "powerpc64" => POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI,
869 "loongarch32" | "loongarch64" => LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI,
870 "riscv32" | "riscv64" => RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI,
871 "wasm32" | "wasm64" => WASM_FEATURES_FOR_CORRECT_VECTOR_ABI,
872 "s390x" => S390X_FEATURES_FOR_CORRECT_VECTOR_ABI,
873 "sparc" | "sparc64" => SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI,
874 "hexagon" => HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI,
875 "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI,
876 "bpf" | "m68k" => &[], "csky" => CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI,
878 _ => &[],
881 }
882 }
883
884 pub fn tied_target_features(&self) -> &'static [&'static [&'static str]] {
885 match &*self.arch {
886 "aarch64" | "arm64ec" => AARCH64_TIED_FEATURES,
887 _ => &[],
888 }
889 }
890
891 pub fn implied_target_features<'a>(&self, base_feature: &'a str) -> FxHashSet<&'a str> {
893 let implied_features =
894 self.rust_target_features().iter().map(|(f, _, i)| (f, i)).collect::<FxHashMap<_, _>>();
895
896 let mut features = FxHashSet::default();
899 let mut new_features = vec![base_feature];
900 while let Some(new_feature) = new_features.pop() {
901 if features.insert(new_feature) {
902 if let Some(implied_features) = implied_features.get(&new_feature) {
903 new_features.extend(implied_features.iter().copied())
904 }
905 }
906 }
907 features
908 }
909
910 pub fn abi_required_features(&self) -> FeatureConstraints {
921 const NOTHING: FeatureConstraints = FeatureConstraints { required: &[], incompatible: &[] };
922 match &*self.arch {
927 "x86" => {
928 match self.rustc_abi {
931 None => {
932 FeatureConstraints { required: &["x87"], incompatible: &["soft-float"] }
935 }
936 Some(RustcAbi::X86Sse2) => {
937 FeatureConstraints {
939 required: &["x87", "sse2"],
940 incompatible: &["soft-float"],
941 }
942 }
943 Some(RustcAbi::X86Softfloat) => {
944 FeatureConstraints { required: &["soft-float"], incompatible: &[] }
949 }
950 }
951 }
952 "x86_64" => {
953 match self.rustc_abi {
956 None => {
957 FeatureConstraints {
959 required: &["x87", "sse2"],
960 incompatible: &["soft-float"],
961 }
962 }
963 Some(RustcAbi::X86Softfloat) => {
964 FeatureConstraints { required: &["soft-float"], incompatible: &[] }
969 }
970 Some(r) => panic!("invalid Rust ABI for x86_64: {r:?}"),
971 }
972 }
973 "arm" => {
974 match self.llvm_floatabi.unwrap() {
977 FloatAbi::Soft => {
978 NOTHING
983 }
984 FloatAbi::Hard => {
985 FeatureConstraints { required: &["fpregs"], incompatible: &["soft-float"] }
987 }
988 }
989 }
990 "aarch64" | "arm64ec" => {
991 match &*self.abi {
994 "softfloat" => {
995 FeatureConstraints { required: &[], incompatible: &["neon"] }
1001 }
1002 _ => {
1003 FeatureConstraints { required: &["neon"], incompatible: &[] }
1006 }
1007 }
1008 }
1009 "riscv32" | "riscv64" => {
1010 match &*self.llvm_abiname {
1013 "ilp32d" | "lp64d" => {
1014 FeatureConstraints { required: &["d"], incompatible: &["e", "zfinx"] }
1016 }
1017 "ilp32f" | "lp64f" => {
1018 FeatureConstraints { required: &["f"], incompatible: &["e", "zfinx"] }
1020 }
1021 "ilp32" | "lp64" => {
1022 FeatureConstraints { required: &[], incompatible: &["e"] }
1024 }
1025 "ilp32e" => {
1026 FeatureConstraints { required: &[], incompatible: &["d"] }
1035 }
1036 "lp64e" => {
1037 NOTHING
1039 }
1040 _ => unreachable!(),
1041 }
1042 }
1043 "loongarch32" | "loongarch64" => {
1044 match &*self.llvm_abiname {
1047 "ilp32d" | "lp64d" => {
1048 FeatureConstraints { required: &["d"], incompatible: &[] }
1050 }
1051 "ilp32f" | "lp64f" => {
1052 FeatureConstraints { required: &["f"], incompatible: &[] }
1054 }
1055 "ilp32s" | "lp64s" => {
1056 NOTHING
1061 }
1062 _ => unreachable!(),
1063 }
1064 }
1065 _ => NOTHING,
1066 }
1067 }
1068}