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];
136
137static ARM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
138 ("aclass", Unstable(sym::arm_target_feature), &[]),
140 ("aes", Unstable(sym::arm_target_feature), &["neon"]),
141 (
142 "atomics-32",
143 Stability::Forbidden { reason: "unsound because it changes the ABI of atomic operations" },
144 &[],
145 ),
146 ("crc", Unstable(sym::arm_target_feature), &[]),
147 ("d32", Unstable(sym::arm_target_feature), &[]),
148 ("dotprod", Unstable(sym::arm_target_feature), &["neon"]),
149 ("dsp", Unstable(sym::arm_target_feature), &[]),
150 ("fp-armv8", Unstable(sym::arm_target_feature), &["vfp4"]),
151 ("fp16", Unstable(sym::arm_target_feature), &["neon"]),
152 ("fpregs", Unstable(sym::arm_target_feature), &[]),
153 ("i8mm", Unstable(sym::arm_target_feature), &["neon"]),
154 ("mclass", Unstable(sym::arm_target_feature), &[]),
155 ("neon", Unstable(sym::arm_target_feature), &["vfp3"]),
156 ("rclass", Unstable(sym::arm_target_feature), &[]),
157 ("sha2", Unstable(sym::arm_target_feature), &["neon"]),
158 ("soft-float", Unstable(sym::arm_target_feature), &[]),
163 ("thumb-mode", Unstable(sym::arm_target_feature), &[]),
167 ("thumb2", Unstable(sym::arm_target_feature), &[]),
168 ("trustzone", Unstable(sym::arm_target_feature), &[]),
169 ("v5te", Unstable(sym::arm_target_feature), &[]),
170 ("v6", Unstable(sym::arm_target_feature), &["v5te"]),
171 ("v6k", Unstable(sym::arm_target_feature), &["v6"]),
172 ("v6t2", Unstable(sym::arm_target_feature), &["v6k", "thumb2"]),
173 ("v7", Unstable(sym::arm_target_feature), &["v6t2"]),
174 ("v8", Unstable(sym::arm_target_feature), &["v7"]),
175 ("vfp2", Unstable(sym::arm_target_feature), &[]),
176 ("vfp3", Unstable(sym::arm_target_feature), &["vfp2", "d32"]),
177 ("vfp4", Unstable(sym::arm_target_feature), &["vfp3"]),
178 ("virtualization", Unstable(sym::arm_target_feature), &[]),
179 ];
181
182static AARCH64_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
183 ("aes", Stable, &["neon"]),
186 ("bf16", Stable, &[]),
188 ("bti", Stable, &[]),
190 ("crc", Stable, &[]),
192 ("cssc", Unstable(sym::aarch64_unstable_target_feature), &[]),
194 ("dit", Stable, &[]),
196 ("dotprod", Stable, &["neon"]),
198 ("dpb", Stable, &[]),
200 ("dpb2", Stable, &["dpb"]),
202 ("ecv", Unstable(sym::aarch64_unstable_target_feature), &[]),
204 ("f32mm", Stable, &["sve"]),
206 ("f64mm", Stable, &["sve"]),
208 ("faminmax", Unstable(sym::aarch64_unstable_target_feature), &[]),
210 ("fcma", Stable, &["neon"]),
212 ("fhm", Stable, &["fp16"]),
214 ("flagm", Stable, &[]),
216 ("flagm2", Unstable(sym::aarch64_unstable_target_feature), &[]),
218 ("fp-armv8", Stability::Forbidden { reason: "Rust ties `fp-armv8` to `neon`" }, &[]),
220 ("fp16", Stable, &["neon"]),
223 ("fp8", Unstable(sym::aarch64_unstable_target_feature), &["faminmax", "lut", "bf16"]),
225 ("fp8dot2", Unstable(sym::aarch64_unstable_target_feature), &["fp8dot4"]),
227 ("fp8dot4", Unstable(sym::aarch64_unstable_target_feature), &["fp8fma"]),
229 ("fp8fma", Unstable(sym::aarch64_unstable_target_feature), &["fp8"]),
231 ("frintts", Stable, &[]),
233 ("hbc", Unstable(sym::aarch64_unstable_target_feature), &[]),
235 ("i8mm", Stable, &[]),
237 ("jsconv", Stable, &["neon"]),
240 ("lor", Stable, &[]),
242 ("lse", Stable, &[]),
244 ("lse128", Unstable(sym::aarch64_unstable_target_feature), &["lse"]),
246 ("lse2", Unstable(sym::aarch64_unstable_target_feature), &[]),
248 ("lut", Unstable(sym::aarch64_unstable_target_feature), &[]),
250 ("mops", Unstable(sym::aarch64_unstable_target_feature), &[]),
252 ("mte", Stable, &[]),
254 ("neon", Stable, &[]),
256 ("paca", Stable, &[]),
258 ("pacg", Stable, &[]),
260 ("pan", Stable, &[]),
262 ("pauth-lr", Unstable(sym::aarch64_unstable_target_feature), &[]),
264 ("pmuv3", Stable, &[]),
266 ("rand", Stable, &[]),
268 ("ras", Stable, &[]),
270 ("rcpc", Stable, &[]),
272 ("rcpc2", Stable, &["rcpc"]),
274 ("rcpc3", Unstable(sym::aarch64_unstable_target_feature), &["rcpc2"]),
276 ("rdm", Stable, &["neon"]),
278 ("reserve-x18", Unstable(sym::aarch64_unstable_target_feature), &[]),
284 ("sb", Stable, &[]),
286 ("sha2", Stable, &["neon"]),
288 ("sha3", Stable, &["sha2"]),
290 ("sm4", Stable, &["neon"]),
292 ("sme", Unstable(sym::aarch64_unstable_target_feature), &["bf16"]),
294 ("sme-b16b16", Unstable(sym::aarch64_unstable_target_feature), &["bf16", "sme2", "sve-b16b16"]),
296 ("sme-f16f16", Unstable(sym::aarch64_unstable_target_feature), &["sme2"]),
298 ("sme-f64f64", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
300 ("sme-f8f16", Unstable(sym::aarch64_unstable_target_feature), &["sme-f8f32"]),
302 ("sme-f8f32", Unstable(sym::aarch64_unstable_target_feature), &["sme2", "fp8"]),
304 ("sme-fa64", Unstable(sym::aarch64_unstable_target_feature), &["sme", "sve2"]),
306 ("sme-i16i64", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
308 ("sme-lutv2", Unstable(sym::aarch64_unstable_target_feature), &[]),
310 ("sme2", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
312 ("sme2p1", Unstable(sym::aarch64_unstable_target_feature), &["sme2"]),
314 ("spe", Stable, &[]),
316 ("ssbs", Stable, &[]),
318 ("ssve-fp8dot2", Unstable(sym::aarch64_unstable_target_feature), &["ssve-fp8dot4"]),
320 ("ssve-fp8dot4", Unstable(sym::aarch64_unstable_target_feature), &["ssve-fp8fma"]),
322 ("ssve-fp8fma", Unstable(sym::aarch64_unstable_target_feature), &["sme2", "fp8"]),
324 ("sve", Stable, &["neon"]),
332 ("sve-b16b16", Unstable(sym::aarch64_unstable_target_feature), &["bf16"]),
334 ("sve2", Stable, &["sve"]),
336 ("sve2-aes", Stable, &["sve2", "aes"]),
338 ("sve2-bitperm", Stable, &["sve2"]),
340 ("sve2-sha3", Stable, &["sve2", "sha3"]),
342 ("sve2-sm4", Stable, &["sve2", "sm4"]),
344 ("sve2p1", Unstable(sym::aarch64_unstable_target_feature), &["sve2"]),
346 ("tme", Stable, &[]),
348 (
349 "v8.1a",
350 Unstable(sym::aarch64_ver_target_feature),
351 &["crc", "lse", "rdm", "pan", "lor", "vh"],
352 ),
353 ("v8.2a", Unstable(sym::aarch64_ver_target_feature), &["v8.1a", "ras", "dpb"]),
354 (
355 "v8.3a",
356 Unstable(sym::aarch64_ver_target_feature),
357 &["v8.2a", "rcpc", "paca", "pacg", "jsconv"],
358 ),
359 ("v8.4a", Unstable(sym::aarch64_ver_target_feature), &["v8.3a", "dotprod", "dit", "flagm"]),
360 ("v8.5a", Unstable(sym::aarch64_ver_target_feature), &["v8.4a", "ssbs", "sb", "dpb2", "bti"]),
361 ("v8.6a", Unstable(sym::aarch64_ver_target_feature), &["v8.5a", "bf16", "i8mm"]),
362 ("v8.7a", Unstable(sym::aarch64_ver_target_feature), &["v8.6a", "wfxt"]),
363 ("v8.8a", Unstable(sym::aarch64_ver_target_feature), &["v8.7a", "hbc", "mops"]),
364 ("v8.9a", Unstable(sym::aarch64_ver_target_feature), &["v8.8a", "cssc"]),
365 ("v9.1a", Unstable(sym::aarch64_ver_target_feature), &["v9a", "v8.6a"]),
366 ("v9.2a", Unstable(sym::aarch64_ver_target_feature), &["v9.1a", "v8.7a"]),
367 ("v9.3a", Unstable(sym::aarch64_ver_target_feature), &["v9.2a", "v8.8a"]),
368 ("v9.4a", Unstable(sym::aarch64_ver_target_feature), &["v9.3a", "v8.9a"]),
369 ("v9.5a", Unstable(sym::aarch64_ver_target_feature), &["v9.4a"]),
370 ("v9a", Unstable(sym::aarch64_ver_target_feature), &["v8.5a", "sve2"]),
371 ("vh", Stable, &[]),
373 ("wfxt", Unstable(sym::aarch64_unstable_target_feature), &[]),
375 ];
377
378const AARCH64_TIED_FEATURES: &[&[&str]] = &[
379 &["paca", "pacg"], ];
381
382static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
383 ("adx", Stable, &[]),
385 ("aes", Stable, &["sse2"]),
386 ("amx-avx512", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
387 ("amx-bf16", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
388 ("amx-complex", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
389 ("amx-fp16", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
390 ("amx-fp8", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
391 ("amx-int8", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
392 ("amx-movrs", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
393 ("amx-tf32", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
394 ("amx-tile", Unstable(sym::x86_amx_intrinsics), &[]),
395 ("amx-transpose", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
396 ("apxf", Unstable(sym::apx_target_feature), &[]),
397 ("avx", Stable, &["sse4.2"]),
398 (
399 "avx10.1",
400 Unstable(sym::avx10_target_feature),
401 &[
402 "avx512bf16",
403 "avx512bitalg",
404 "avx512bw",
405 "avx512cd",
406 "avx512dq",
407 "avx512f",
408 "avx512fp16",
409 "avx512ifma",
410 "avx512vbmi",
411 "avx512vbmi2",
412 "avx512vl",
413 "avx512vnni",
414 "avx512vpopcntdq",
415 ],
416 ),
417 ("avx10.2", Unstable(sym::avx10_target_feature), &["avx10.1"]),
418 ("avx2", Stable, &["avx"]),
419 ("avx512bf16", Stable, &["avx512bw"]),
420 ("avx512bitalg", Stable, &["avx512bw"]),
421 ("avx512bw", Stable, &["avx512f"]),
422 ("avx512cd", Stable, &["avx512f"]),
423 ("avx512dq", Stable, &["avx512f"]),
424 ("avx512f", Stable, &["avx2", "fma", "f16c"]),
425 ("avx512fp16", Stable, &["avx512bw"]),
426 ("avx512ifma", Stable, &["avx512f"]),
427 ("avx512vbmi", Stable, &["avx512bw"]),
428 ("avx512vbmi2", Stable, &["avx512bw"]),
429 ("avx512vl", Stable, &["avx512f"]),
430 ("avx512vnni", Stable, &["avx512f"]),
431 ("avx512vp2intersect", Stable, &["avx512f"]),
432 ("avx512vpopcntdq", Stable, &["avx512f"]),
433 ("avxifma", Stable, &["avx2"]),
434 ("avxneconvert", Stable, &["avx2"]),
435 ("avxvnni", Stable, &["avx2"]),
436 ("avxvnniint16", Stable, &["avx2"]),
437 ("avxvnniint8", Stable, &["avx2"]),
438 ("bmi1", Stable, &[]),
439 ("bmi2", Stable, &[]),
440 ("cmpxchg16b", Stable, &[]),
441 ("ermsb", Unstable(sym::ermsb_target_feature), &[]),
442 ("f16c", Stable, &["avx"]),
443 ("fma", Stable, &["avx"]),
444 ("fxsr", Stable, &[]),
445 ("gfni", Stable, &["sse2"]),
446 ("kl", Unstable(sym::keylocker_x86), &["sse2"]),
447 ("lahfsahf", Unstable(sym::lahfsahf_target_feature), &[]),
448 ("lzcnt", Stable, &[]),
449 ("movbe", Stable, &[]),
450 ("movrs", Unstable(sym::movrs_target_feature), &[]),
451 ("pclmulqdq", Stable, &["sse2"]),
452 ("popcnt", Stable, &[]),
453 ("prfchw", Unstable(sym::prfchw_target_feature), &[]),
454 ("rdrand", Stable, &[]),
455 ("rdseed", Stable, &[]),
456 ("rtm", Unstable(sym::rtm_target_feature), &[]),
457 ("sha", Stable, &["sse2"]),
458 ("sha512", Unstable(sym::sha512_sm_x86), &["avx2"]),
459 ("sm3", Unstable(sym::sha512_sm_x86), &["avx"]),
460 ("sm4", Unstable(sym::sha512_sm_x86), &["avx2"]),
461 ("soft-float", Stability::Unstable(sym::x87_target_feature), &[]),
464 ("sse", Stable, &[]),
465 ("sse2", Stable, &["sse"]),
466 ("sse3", Stable, &["sse2"]),
467 ("sse4.1", Stable, &["ssse3"]),
468 ("sse4.2", Stable, &["sse4.1"]),
469 ("sse4a", Unstable(sym::sse4a_target_feature), &["sse3"]),
470 ("ssse3", Stable, &["sse3"]),
471 ("tbm", Unstable(sym::tbm_target_feature), &[]),
472 ("vaes", Stable, &["avx2", "aes"]),
473 ("vpclmulqdq", Stable, &["avx", "pclmulqdq"]),
474 ("widekl", Unstable(sym::keylocker_x86), &["kl"]),
475 ("x87", Unstable(sym::x87_target_feature), &[]),
476 ("xop", Unstable(sym::xop_target_feature), &["avx", "sse4a"]),
477 ("xsave", Stable, &[]),
478 ("xsavec", Stable, &["xsave"]),
479 ("xsaveopt", Stable, &["xsave"]),
480 ("xsaves", Stable, &["xsave"]),
481 ];
483
484const HEXAGON_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
485 ("hvx", Unstable(sym::hexagon_target_feature), &[]),
487 ("hvx-length128b", Unstable(sym::hexagon_target_feature), &["hvx"]),
488 ];
490
491static POWERPC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
492 ("altivec", Unstable(sym::powerpc_target_feature), &[]),
494 ("msync", Unstable(sym::powerpc_target_feature), &[]),
495 ("partword-atomics", Unstable(sym::powerpc_target_feature), &[]),
496 ("power10-vector", Unstable(sym::powerpc_target_feature), &["power9-vector"]),
497 ("power8-altivec", Unstable(sym::powerpc_target_feature), &["altivec"]),
498 ("power8-crypto", Unstable(sym::powerpc_target_feature), &["power8-altivec"]),
499 ("power8-vector", Unstable(sym::powerpc_target_feature), &["vsx", "power8-altivec"]),
500 ("power9-altivec", Unstable(sym::powerpc_target_feature), &["power8-altivec"]),
501 ("power9-vector", Unstable(sym::powerpc_target_feature), &["power8-vector", "power9-altivec"]),
502 ("quadword-atomics", Unstable(sym::powerpc_target_feature), &[]),
503 ("vsx", Unstable(sym::powerpc_target_feature), &["altivec"]),
504 ];
506
507const MIPS_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
508 ("fp64", Unstable(sym::mips_target_feature), &[]),
510 ("msa", Unstable(sym::mips_target_feature), &[]),
511 ("virt", Unstable(sym::mips_target_feature), &[]),
512 ];
514
515static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
516 ("a", Stable, &["zaamo", "zalrsc"]),
518 ("b", Unstable(sym::riscv_target_feature), &["zba", "zbb", "zbs"]),
519 ("c", Stable, &["zca"]),
520 ("d", Unstable(sym::riscv_target_feature), &["f"]),
521 ("e", Unstable(sym::riscv_target_feature), &[]),
522 ("f", Unstable(sym::riscv_target_feature), &["zicsr"]),
523 (
524 "forced-atomics",
525 Stability::Forbidden { reason: "unsound because it changes the ABI of atomic operations" },
526 &[],
527 ),
528 ("m", Stable, &[]),
529 ("relax", Unstable(sym::riscv_target_feature), &[]),
530 ("unaligned-scalar-mem", Unstable(sym::riscv_target_feature), &[]),
531 ("unaligned-vector-mem", Unstable(sym::riscv_target_feature), &[]),
532 ("v", Unstable(sym::riscv_target_feature), &["zvl128b", "zve64d"]),
533 ("za128rs", Unstable(sym::riscv_target_feature), &[]),
534 ("za64rs", Unstable(sym::riscv_target_feature), &["za128rs"]), ("zaamo", Unstable(sym::riscv_target_feature), &[]),
536 ("zabha", Unstable(sym::riscv_target_feature), &["zaamo"]),
537 ("zacas", Unstable(sym::riscv_target_feature), &["zaamo"]),
538 ("zalrsc", Unstable(sym::riscv_target_feature), &[]),
539 ("zama16b", Unstable(sym::riscv_target_feature), &[]),
540 ("zawrs", Unstable(sym::riscv_target_feature), &[]),
541 ("zba", Stable, &[]),
542 ("zbb", Stable, &[]),
543 ("zbc", Stable, &["zbkc"]), ("zbkb", Stable, &[]),
545 ("zbkc", Stable, &[]),
546 ("zbkx", Stable, &[]),
547 ("zbs", Stable, &[]),
548 ("zca", Unstable(sym::riscv_target_feature), &[]),
549 ("zcb", Unstable(sym::riscv_target_feature), &["zca"]),
550 ("zcmop", Unstable(sym::riscv_target_feature), &["zca"]),
551 ("zdinx", Unstable(sym::riscv_target_feature), &["zfinx"]),
552 ("zfa", Unstable(sym::riscv_target_feature), &["f"]),
553 ("zfbfmin", Unstable(sym::riscv_target_feature), &["f"]), ("zfh", Unstable(sym::riscv_target_feature), &["zfhmin"]),
555 ("zfhmin", Unstable(sym::riscv_target_feature), &["f"]),
556 ("zfinx", Unstable(sym::riscv_target_feature), &["zicsr"]),
557 ("zhinx", Unstable(sym::riscv_target_feature), &["zhinxmin"]),
558 ("zhinxmin", Unstable(sym::riscv_target_feature), &["zfinx"]),
559 ("zic64b", Unstable(sym::riscv_target_feature), &[]),
560 ("zicbom", Unstable(sym::riscv_target_feature), &[]),
561 ("zicbop", Unstable(sym::riscv_target_feature), &[]),
562 ("zicboz", Unstable(sym::riscv_target_feature), &[]),
563 ("ziccamoa", Unstable(sym::riscv_target_feature), &[]),
564 ("ziccif", Unstable(sym::riscv_target_feature), &[]),
565 ("zicclsm", Unstable(sym::riscv_target_feature), &[]),
566 ("ziccrse", Unstable(sym::riscv_target_feature), &[]),
567 ("zicntr", Unstable(sym::riscv_target_feature), &["zicsr"]),
568 ("zicond", Unstable(sym::riscv_target_feature), &[]),
569 ("zicsr", Unstable(sym::riscv_target_feature), &[]),
570 ("zifencei", Unstable(sym::riscv_target_feature), &[]),
571 ("zihintntl", Unstable(sym::riscv_target_feature), &[]),
572 ("zihintpause", Unstable(sym::riscv_target_feature), &[]),
573 ("zihpm", Unstable(sym::riscv_target_feature), &["zicsr"]),
574 ("zimop", Unstable(sym::riscv_target_feature), &[]),
575 ("zk", Stable, &["zkn", "zkr", "zkt"]),
576 ("zkn", Stable, &["zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"]),
577 ("zknd", Stable, &[]),
578 ("zkne", Stable, &[]),
579 ("zknh", Stable, &[]),
580 ("zkr", Stable, &[]),
581 ("zks", Stable, &["zbkb", "zbkc", "zbkx", "zksed", "zksh"]),
582 ("zksed", Stable, &[]),
583 ("zksh", Stable, &[]),
584 ("zkt", Stable, &[]),
585 ("ztso", Unstable(sym::riscv_target_feature), &[]),
586 ("zvbb", Unstable(sym::riscv_target_feature), &["zvkb"]), ("zvbc", Unstable(sym::riscv_target_feature), &["zve64x"]),
588 ("zve32f", Unstable(sym::riscv_target_feature), &["zve32x", "f"]),
589 ("zve32x", Unstable(sym::riscv_target_feature), &["zvl32b", "zicsr"]),
590 ("zve64d", Unstable(sym::riscv_target_feature), &["zve64f", "d"]),
591 ("zve64f", Unstable(sym::riscv_target_feature), &["zve32f", "zve64x"]),
592 ("zve64x", Unstable(sym::riscv_target_feature), &["zve32x", "zvl64b"]),
593 ("zvfbfmin", Unstable(sym::riscv_target_feature), &["zve32f"]),
594 ("zvfbfwma", Unstable(sym::riscv_target_feature), &["zfbfmin", "zvfbfmin"]),
595 ("zvfh", Unstable(sym::riscv_target_feature), &["zvfhmin", "zve32f", "zfhmin"]), ("zvfhmin", Unstable(sym::riscv_target_feature), &["zve32f"]),
597 ("zvkb", Unstable(sym::riscv_target_feature), &["zve32x"]),
598 ("zvkg", Unstable(sym::riscv_target_feature), &["zve32x"]),
599 ("zvkn", Unstable(sym::riscv_target_feature), &["zvkned", "zvknhb", "zvkb", "zvkt"]),
600 ("zvknc", Unstable(sym::riscv_target_feature), &["zvkn", "zvbc"]),
601 ("zvkned", Unstable(sym::riscv_target_feature), &["zve32x"]),
602 ("zvkng", Unstable(sym::riscv_target_feature), &["zvkn", "zvkg"]),
603 ("zvknha", Unstable(sym::riscv_target_feature), &["zve32x"]),
604 ("zvknhb", Unstable(sym::riscv_target_feature), &["zvknha", "zve64x"]), ("zvks", Unstable(sym::riscv_target_feature), &["zvksed", "zvksh", "zvkb", "zvkt"]),
606 ("zvksc", Unstable(sym::riscv_target_feature), &["zvks", "zvbc"]),
607 ("zvksed", Unstable(sym::riscv_target_feature), &["zve32x"]),
608 ("zvksg", Unstable(sym::riscv_target_feature), &["zvks", "zvkg"]),
609 ("zvksh", Unstable(sym::riscv_target_feature), &["zve32x"]),
610 ("zvkt", Unstable(sym::riscv_target_feature), &[]),
611 ("zvl1024b", Unstable(sym::riscv_target_feature), &["zvl512b"]),
612 ("zvl128b", Unstable(sym::riscv_target_feature), &["zvl64b"]),
613 ("zvl16384b", Unstable(sym::riscv_target_feature), &["zvl8192b"]),
614 ("zvl2048b", Unstable(sym::riscv_target_feature), &["zvl1024b"]),
615 ("zvl256b", Unstable(sym::riscv_target_feature), &["zvl128b"]),
616 ("zvl32768b", Unstable(sym::riscv_target_feature), &["zvl16384b"]),
617 ("zvl32b", Unstable(sym::riscv_target_feature), &[]),
618 ("zvl4096b", Unstable(sym::riscv_target_feature), &["zvl2048b"]),
619 ("zvl512b", Unstable(sym::riscv_target_feature), &["zvl256b"]),
620 ("zvl64b", Unstable(sym::riscv_target_feature), &["zvl32b"]),
621 ("zvl65536b", Unstable(sym::riscv_target_feature), &["zvl32768b"]),
622 ("zvl8192b", Unstable(sym::riscv_target_feature), &["zvl4096b"]),
623 ];
625
626static WASM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
627 ("atomics", Unstable(sym::wasm_target_feature), &[]),
629 ("bulk-memory", Stable, &[]),
630 ("exception-handling", Unstable(sym::wasm_target_feature), &[]),
631 ("extended-const", Stable, &[]),
632 ("multivalue", Stable, &[]),
633 ("mutable-globals", Stable, &[]),
634 ("nontrapping-fptoint", Stable, &[]),
635 ("reference-types", Stable, &[]),
636 ("relaxed-simd", Stable, &["simd128"]),
637 ("sign-ext", Stable, &[]),
638 ("simd128", Stable, &[]),
639 ("tail-call", Stable, &[]),
640 ("wide-arithmetic", Unstable(sym::wasm_target_feature), &[]),
641 ];
643
644const BPF_FEATURES: &[(&str, Stability, ImpliedFeatures)] =
645 &[("alu32", Unstable(sym::bpf_target_feature), &[])];
646
647static CSKY_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
648 ("10e60", Unstable(sym::csky_target_feature), &["7e10"]),
650 ("2e3", Unstable(sym::csky_target_feature), &["e2"]),
651 ("3e3r1", Unstable(sym::csky_target_feature), &[]),
652 ("3e3r2", Unstable(sym::csky_target_feature), &["3e3r1", "doloop"]),
653 ("3e3r3", Unstable(sym::csky_target_feature), &["doloop"]),
654 ("3e7", Unstable(sym::csky_target_feature), &["2e3"]),
655 ("7e10", Unstable(sym::csky_target_feature), &["3e7"]),
656 ("cache", Unstable(sym::csky_target_feature), &[]),
657 ("doloop", Unstable(sym::csky_target_feature), &[]),
658 ("dsp1e2", Unstable(sym::csky_target_feature), &[]),
659 ("dspe60", Unstable(sym::csky_target_feature), &[]),
660 ("e1", Unstable(sym::csky_target_feature), &["elrw"]),
661 ("e2", Unstable(sym::csky_target_feature), &["e2"]),
662 ("edsp", Unstable(sym::csky_target_feature), &[]),
663 ("elrw", Unstable(sym::csky_target_feature), &[]),
664 ("float1e2", Unstable(sym::csky_target_feature), &[]),
665 ("float1e3", Unstable(sym::csky_target_feature), &[]),
666 ("float3e4", Unstable(sym::csky_target_feature), &[]),
667 ("float7e60", Unstable(sym::csky_target_feature), &[]),
668 ("floate1", Unstable(sym::csky_target_feature), &[]),
669 ("hard-tp", Unstable(sym::csky_target_feature), &[]),
670 ("high-registers", Unstable(sym::csky_target_feature), &[]),
671 ("hwdiv", Unstable(sym::csky_target_feature), &[]),
672 ("mp", Unstable(sym::csky_target_feature), &["2e3"]),
673 ("mp1e2", Unstable(sym::csky_target_feature), &["3e7"]),
674 ("nvic", Unstable(sym::csky_target_feature), &[]),
675 ("trust", Unstable(sym::csky_target_feature), &[]),
676 ("vdsp2e60f", Unstable(sym::csky_target_feature), &[]),
677 ("vdspv1", Unstable(sym::csky_target_feature), &[]),
678 ("vdspv2", Unstable(sym::csky_target_feature), &[]),
679 ("fdivdu", Unstable(sym::csky_target_feature), &[]),
683 ("fpuv2_df", Unstable(sym::csky_target_feature), &[]),
684 ("fpuv2_sf", Unstable(sym::csky_target_feature), &[]),
685 ("fpuv3_df", Unstable(sym::csky_target_feature), &[]),
686 ("fpuv3_hf", Unstable(sym::csky_target_feature), &[]),
687 ("fpuv3_hi", Unstable(sym::csky_target_feature), &[]),
688 ("fpuv3_sf", Unstable(sym::csky_target_feature), &[]),
689 ("hard-float", Unstable(sym::csky_target_feature), &[]),
690 ("hard-float-abi", Unstable(sym::csky_target_feature), &[]),
691 ];
693
694static LOONGARCH_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
695 ("d", Stable, &["f"]),
697 ("div32", Unstable(sym::loongarch_target_feature), &[]),
698 ("f", Stable, &[]),
699 ("frecipe", Stable, &[]),
700 ("lam-bh", Unstable(sym::loongarch_target_feature), &[]),
701 ("lamcas", Unstable(sym::loongarch_target_feature), &[]),
702 ("lasx", Stable, &["lsx"]),
703 ("lbt", Stable, &[]),
704 ("ld-seq-sa", Unstable(sym::loongarch_target_feature), &[]),
705 ("lsx", Stable, &["d"]),
706 ("lvz", Stable, &[]),
707 ("relax", Unstable(sym::loongarch_target_feature), &[]),
708 ("scq", Unstable(sym::loongarch_target_feature), &[]),
709 ("ual", Unstable(sym::loongarch_target_feature), &[]),
710 ];
712
713const IBMZ_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
714 ("backchain", Unstable(sym::s390x_target_feature), &[]),
716 ("deflate-conversion", Unstable(sym::s390x_target_feature), &[]),
717 ("enhanced-sort", Unstable(sym::s390x_target_feature), &[]),
718 ("guarded-storage", Unstable(sym::s390x_target_feature), &[]),
719 ("high-word", Unstable(sym::s390x_target_feature), &[]),
720 ("nnp-assist", Unstable(sym::s390x_target_feature), &["vector"]),
721 ("transactional-execution", Unstable(sym::s390x_target_feature), &[]),
722 ("vector", Unstable(sym::s390x_target_feature), &[]),
723 ("vector-enhancements-1", Unstable(sym::s390x_target_feature), &["vector"]),
724 ("vector-enhancements-2", Unstable(sym::s390x_target_feature), &["vector-enhancements-1"]),
725 ("vector-packed-decimal", Unstable(sym::s390x_target_feature), &["vector"]),
726 (
727 "vector-packed-decimal-enhancement",
728 Unstable(sym::s390x_target_feature),
729 &["vector-packed-decimal"],
730 ),
731 (
732 "vector-packed-decimal-enhancement-2",
733 Unstable(sym::s390x_target_feature),
734 &["vector-packed-decimal-enhancement"],
735 ),
736 ];
738
739const SPARC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
740 ("leoncasa", Unstable(sym::sparc_target_feature), &[]),
742 ("v8plus", Unstable(sym::sparc_target_feature), &[]),
743 ("v9", Unstable(sym::sparc_target_feature), &[]),
744 ];
746
747static M68K_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
748 ("isa-68000", Unstable(sym::m68k_target_feature), &[]),
750 ("isa-68010", Unstable(sym::m68k_target_feature), &["isa-68000"]),
751 ("isa-68020", Unstable(sym::m68k_target_feature), &["isa-68010"]),
752 ("isa-68030", Unstable(sym::m68k_target_feature), &["isa-68020"]),
753 ("isa-68040", Unstable(sym::m68k_target_feature), &["isa-68030", "isa-68882"]),
754 ("isa-68060", Unstable(sym::m68k_target_feature), &["isa-68040"]),
755 ("isa-68881", Unstable(sym::m68k_target_feature), &[]),
757 ("isa-68882", Unstable(sym::m68k_target_feature), &["isa-68881"]),
758 ];
760
761pub fn all_rust_features() -> impl Iterator<Item = (&'static str, Stability)> {
766 std::iter::empty()
767 .chain(ARM_FEATURES.iter())
768 .chain(AARCH64_FEATURES.iter())
769 .chain(X86_FEATURES.iter())
770 .chain(HEXAGON_FEATURES.iter())
771 .chain(POWERPC_FEATURES.iter())
772 .chain(MIPS_FEATURES.iter())
773 .chain(RISCV_FEATURES.iter())
774 .chain(WASM_FEATURES.iter())
775 .chain(BPF_FEATURES.iter())
776 .chain(CSKY_FEATURES)
777 .chain(LOONGARCH_FEATURES)
778 .chain(IBMZ_FEATURES)
779 .chain(SPARC_FEATURES)
780 .chain(M68K_FEATURES)
781 .cloned()
782 .map(|(f, s, _)| (f, s))
783}
784
785const X86_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
789 &[(128, "sse"), (256, "avx"), (512, "avx512f")]; const AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")];
791
792const ARM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")];
794
795const POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "altivec")];
796const WASM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "simd128")];
797const S390X_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vector")];
798const RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[
799 (32, "zvl32b"),
800 (64, "zvl64b"),
801 (128, "zvl128b"),
802 (256, "zvl256b"),
803 (512, "zvl512b"),
804 (1024, "zvl1024b"),
805 (2048, "zvl2048b"),
806 (4096, "zvl4096b"),
807 (8192, "zvl8192b"),
808 (16384, "zvl16384b"),
809 (32768, "zvl32768b"),
810 (65536, "zvl65536b"),
811];
812const SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[];
814
815const HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
816 &[(1024, "hvx-length128b")];
817const MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "msa")];
818const CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vdspv1")];
819const LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
820 &[(128, "lsx"), (256, "lasx")];
821
822#[derive(Copy, Clone, Debug)]
823pub struct FeatureConstraints {
824 pub required: &'static [&'static str],
826 pub incompatible: &'static [&'static str],
828}
829
830impl Target {
831 pub fn rust_target_features(&self) -> &'static [(&'static str, Stability, ImpliedFeatures)] {
832 match &*self.arch {
833 "arm" => ARM_FEATURES,
834 "aarch64" | "arm64ec" => AARCH64_FEATURES,
835 "x86" | "x86_64" => X86_FEATURES,
836 "hexagon" => HEXAGON_FEATURES,
837 "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_FEATURES,
838 "powerpc" | "powerpc64" => POWERPC_FEATURES,
839 "riscv32" | "riscv64" => RISCV_FEATURES,
840 "wasm32" | "wasm64" => WASM_FEATURES,
841 "bpf" => BPF_FEATURES,
842 "csky" => CSKY_FEATURES,
843 "loongarch64" => LOONGARCH_FEATURES,
844 "s390x" => IBMZ_FEATURES,
845 "sparc" | "sparc64" => SPARC_FEATURES,
846 "m68k" => M68K_FEATURES,
847 _ => &[],
848 }
849 }
850
851 pub fn features_for_correct_vector_abi(&self) -> &'static [(u64, &'static str)] {
852 match &*self.arch {
853 "x86" | "x86_64" => X86_FEATURES_FOR_CORRECT_VECTOR_ABI,
854 "aarch64" | "arm64ec" => AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI,
855 "arm" => ARM_FEATURES_FOR_CORRECT_VECTOR_ABI,
856 "powerpc" | "powerpc64" => POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI,
857 "loongarch64" => LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI,
858 "riscv32" | "riscv64" => RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI,
859 "wasm32" | "wasm64" => WASM_FEATURES_FOR_CORRECT_VECTOR_ABI,
860 "s390x" => S390X_FEATURES_FOR_CORRECT_VECTOR_ABI,
861 "sparc" | "sparc64" => SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI,
862 "hexagon" => HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI,
863 "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI,
864 "bpf" | "m68k" => &[], "csky" => CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI,
866 _ => &[],
869 }
870 }
871
872 pub fn tied_target_features(&self) -> &'static [&'static [&'static str]] {
873 match &*self.arch {
874 "aarch64" | "arm64ec" => AARCH64_TIED_FEATURES,
875 _ => &[],
876 }
877 }
878
879 pub fn implied_target_features<'a>(&self, base_feature: &'a str) -> FxHashSet<&'a str> {
881 let implied_features =
882 self.rust_target_features().iter().map(|(f, _, i)| (f, i)).collect::<FxHashMap<_, _>>();
883
884 let mut features = FxHashSet::default();
887 let mut new_features = vec![base_feature];
888 while let Some(new_feature) = new_features.pop() {
889 if features.insert(new_feature) {
890 if let Some(implied_features) = implied_features.get(&new_feature) {
891 new_features.extend(implied_features.iter().copied())
892 }
893 }
894 }
895 features
896 }
897
898 pub fn abi_required_features(&self) -> FeatureConstraints {
909 const NOTHING: FeatureConstraints = FeatureConstraints { required: &[], incompatible: &[] };
910 match &*self.arch {
915 "x86" => {
916 match self.rustc_abi {
919 None => {
920 FeatureConstraints { required: &["x87"], incompatible: &["soft-float"] }
923 }
924 Some(RustcAbi::X86Sse2) => {
925 FeatureConstraints {
927 required: &["x87", "sse2"],
928 incompatible: &["soft-float"],
929 }
930 }
931 Some(RustcAbi::X86Softfloat) => {
932 FeatureConstraints { required: &["soft-float"], incompatible: &[] }
937 }
938 }
939 }
940 "x86_64" => {
941 match self.rustc_abi {
944 None => {
945 FeatureConstraints {
947 required: &["x87", "sse2"],
948 incompatible: &["soft-float"],
949 }
950 }
951 Some(RustcAbi::X86Softfloat) => {
952 FeatureConstraints { required: &["soft-float"], incompatible: &[] }
957 }
958 Some(r) => panic!("invalid Rust ABI for x86_64: {r:?}"),
959 }
960 }
961 "arm" => {
962 match self.llvm_floatabi.unwrap() {
965 FloatAbi::Soft => {
966 NOTHING
971 }
972 FloatAbi::Hard => {
973 FeatureConstraints { required: &["fpregs"], incompatible: &["soft-float"] }
975 }
976 }
977 }
978 "aarch64" | "arm64ec" => {
979 match &*self.abi {
982 "softfloat" => {
983 FeatureConstraints { required: &[], incompatible: &["neon"] }
989 }
990 _ => {
991 FeatureConstraints { required: &["neon"], incompatible: &[] }
994 }
995 }
996 }
997 "riscv32" | "riscv64" => {
998 match &*self.llvm_abiname {
1001 "ilp32d" | "lp64d" => {
1002 FeatureConstraints { required: &["d"], incompatible: &["e", "zfinx"] }
1004 }
1005 "ilp32f" | "lp64f" => {
1006 FeatureConstraints { required: &["f"], incompatible: &["e", "zfinx"] }
1008 }
1009 "ilp32" | "lp64" => {
1010 FeatureConstraints { required: &[], incompatible: &["e"] }
1012 }
1013 "ilp32e" => {
1014 FeatureConstraints { required: &[], incompatible: &["d"] }
1023 }
1024 "lp64e" => {
1025 NOTHING
1027 }
1028 _ => unreachable!(),
1029 }
1030 }
1031 "loongarch64" => {
1032 match &*self.llvm_abiname {
1035 "ilp32d" | "lp64d" => {
1036 FeatureConstraints { required: &["d"], incompatible: &[] }
1038 }
1039 "ilp32f" | "lp64f" => {
1040 FeatureConstraints { required: &["f"], incompatible: &[] }
1042 }
1043 "ilp32s" | "lp64s" => {
1044 NOTHING
1049 }
1050 _ => unreachable!(),
1051 }
1052 }
1053 _ => NOTHING,
1054 }
1055 }
1056}