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    ("outline-atomics", Unstable(sym::aarch64_unstable_target_feature), &[]),
255    ("paca", Stable, &[]),
257    ("pacg", Stable, &[]),
259    ("pan", Stable, &[]),
261    ("pauth-lr", Unstable(sym::aarch64_unstable_target_feature), &[]),
263    ("pmuv3", Stable, &[]),
265    ("rand", Stable, &[]),
267    ("ras", Stable, &[]),
269    ("rcpc", Stable, &[]),
271    ("rcpc2", Stable, &["rcpc"]),
273    ("rcpc3", Unstable(sym::aarch64_unstable_target_feature), &["rcpc2"]),
275    ("rdm", Stable, &["neon"]),
277    ("reserve-x18", Forbidden { reason: "use `-Zfixed-x18` compiler flag instead" }, &[]),
278    ("sb", Stable, &[]),
280    ("sha2", Stable, &["neon"]),
282    ("sha3", Stable, &["sha2"]),
284    ("sm4", Stable, &["neon"]),
286    ("sme", Unstable(sym::aarch64_unstable_target_feature), &["bf16"]),
288    ("sme-b16b16", Unstable(sym::aarch64_unstable_target_feature), &["bf16", "sme2", "sve-b16b16"]),
290    ("sme-f8f16", Unstable(sym::aarch64_unstable_target_feature), &["sme-f8f32"]),
292    ("sme-f8f32", Unstable(sym::aarch64_unstable_target_feature), &["sme2", "fp8"]),
294    ("sme-f16f16", Unstable(sym::aarch64_unstable_target_feature), &["sme2"]),
296    ("sme-f64f64", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
298    ("sme-fa64", Unstable(sym::aarch64_unstable_target_feature), &["sme", "sve2"]),
300    ("sme-i16i64", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
302    ("sme-lutv2", Unstable(sym::aarch64_unstable_target_feature), &[]),
304    ("sme2", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
306    ("sme2p1", Unstable(sym::aarch64_unstable_target_feature), &["sme2"]),
308    ("spe", Stable, &[]),
310    ("ssbs", Stable, &[]),
312    ("ssve-fp8dot2", Unstable(sym::aarch64_unstable_target_feature), &["ssve-fp8dot4"]),
314    ("ssve-fp8dot4", Unstable(sym::aarch64_unstable_target_feature), &["ssve-fp8fma"]),
316    ("ssve-fp8fma", Unstable(sym::aarch64_unstable_target_feature), &["sme2", "fp8"]),
318    ("sve", Stable, &["neon"]),
326    ("sve-b16b16", Unstable(sym::aarch64_unstable_target_feature), &["bf16"]),
328    ("sve2", Stable, &["sve"]),
330    ("sve2-aes", Stable, &["sve2", "aes"]),
332    ("sve2-bitperm", Stable, &["sve2"]),
334    ("sve2-sha3", Stable, &["sve2", "sha3"]),
336    ("sve2-sm4", Stable, &["sve2", "sm4"]),
338    ("sve2p1", Unstable(sym::aarch64_unstable_target_feature), &["sve2"]),
340    ("tme", Stable, &[]),
342    (
343        "v8.1a",
344        Unstable(sym::aarch64_ver_target_feature),
345        &["crc", "lse", "rdm", "pan", "lor", "vh"],
346    ),
347    ("v8.2a", Unstable(sym::aarch64_ver_target_feature), &["v8.1a", "ras", "dpb"]),
348    (
349        "v8.3a",
350        Unstable(sym::aarch64_ver_target_feature),
351        &["v8.2a", "rcpc", "paca", "pacg", "jsconv"],
352    ),
353    ("v8.4a", Unstable(sym::aarch64_ver_target_feature), &["v8.3a", "dotprod", "dit", "flagm"]),
354    ("v8.5a", Unstable(sym::aarch64_ver_target_feature), &["v8.4a", "ssbs", "sb", "dpb2", "bti"]),
355    ("v8.6a", Unstable(sym::aarch64_ver_target_feature), &["v8.5a", "bf16", "i8mm"]),
356    ("v8.7a", Unstable(sym::aarch64_ver_target_feature), &["v8.6a", "wfxt"]),
357    ("v8.8a", Unstable(sym::aarch64_ver_target_feature), &["v8.7a", "hbc", "mops"]),
358    ("v8.9a", Unstable(sym::aarch64_ver_target_feature), &["v8.8a", "cssc"]),
359    ("v9.1a", Unstable(sym::aarch64_ver_target_feature), &["v9a", "v8.6a"]),
360    ("v9.2a", Unstable(sym::aarch64_ver_target_feature), &["v9.1a", "v8.7a"]),
361    ("v9.3a", Unstable(sym::aarch64_ver_target_feature), &["v9.2a", "v8.8a"]),
362    ("v9.4a", Unstable(sym::aarch64_ver_target_feature), &["v9.3a", "v8.9a"]),
363    ("v9.5a", Unstable(sym::aarch64_ver_target_feature), &["v9.4a"]),
364    ("v9a", Unstable(sym::aarch64_ver_target_feature), &["v8.5a", "sve2"]),
365    ("vh", Stable, &[]),
367    ("wfxt", Unstable(sym::aarch64_unstable_target_feature), &[]),
369    ];
371
372const AARCH64_TIED_FEATURES: &[&[&str]] = &[
373    &["paca", "pacg"], ];
375
376static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
377    ("adx", Stable, &[]),
379    ("aes", Stable, &["sse2"]),
380    ("amx-avx512", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
381    ("amx-bf16", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
382    ("amx-complex", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
383    ("amx-fp8", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
384    ("amx-fp16", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
385    ("amx-int8", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
386    ("amx-movrs", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
387    ("amx-tf32", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
388    ("amx-tile", Unstable(sym::x86_amx_intrinsics), &[]),
389    ("amx-transpose", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
390    ("apxf", Unstable(sym::apx_target_feature), &[]),
391    ("avx", Stable, &["sse4.2"]),
392    ("avx2", Stable, &["avx"]),
393    (
394        "avx10.1",
395        Unstable(sym::avx10_target_feature),
396        &[
397            "avx512bf16",
398            "avx512bitalg",
399            "avx512bw",
400            "avx512cd",
401            "avx512dq",
402            "avx512f",
403            "avx512fp16",
404            "avx512ifma",
405            "avx512vbmi",
406            "avx512vbmi2",
407            "avx512vl",
408            "avx512vnni",
409            "avx512vpopcntdq",
410        ],
411    ),
412    ("avx10.2", Unstable(sym::avx10_target_feature), &["avx10.1"]),
413    ("avx512bf16", Stable, &["avx512bw"]),
414    ("avx512bitalg", Stable, &["avx512bw"]),
415    ("avx512bw", Stable, &["avx512f"]),
416    ("avx512cd", Stable, &["avx512f"]),
417    ("avx512dq", Stable, &["avx512f"]),
418    ("avx512f", Stable, &["avx2", "fma", "f16c"]),
419    ("avx512fp16", Stable, &["avx512bw"]),
420    ("avx512ifma", Stable, &["avx512f"]),
421    ("avx512vbmi", Stable, &["avx512bw"]),
422    ("avx512vbmi2", Stable, &["avx512bw"]),
423    ("avx512vl", Stable, &["avx512f"]),
424    ("avx512vnni", Stable, &["avx512f"]),
425    ("avx512vp2intersect", Stable, &["avx512f"]),
426    ("avx512vpopcntdq", Stable, &["avx512f"]),
427    ("avxifma", Stable, &["avx2"]),
428    ("avxneconvert", Stable, &["avx2"]),
429    ("avxvnni", Stable, &["avx2"]),
430    ("avxvnniint8", Stable, &["avx2"]),
431    ("avxvnniint16", Stable, &["avx2"]),
432    ("bmi1", Stable, &[]),
433    ("bmi2", Stable, &[]),
434    ("cmpxchg16b", Stable, &[]),
435    ("ermsb", Unstable(sym::ermsb_target_feature), &[]),
436    ("f16c", Stable, &["avx"]),
437    ("fma", Stable, &["avx"]),
438    ("fxsr", Stable, &[]),
439    ("gfni", Stable, &["sse2"]),
440    ("kl", Stable, &["sse2"]),
441    ("lahfsahf", Unstable(sym::lahfsahf_target_feature), &[]),
442    ("lzcnt", Stable, &[]),
443    ("movbe", Stable, &[]),
444    ("movrs", Unstable(sym::movrs_target_feature), &[]),
445    ("pclmulqdq", Stable, &["sse2"]),
446    ("popcnt", Stable, &[]),
447    ("prfchw", Unstable(sym::prfchw_target_feature), &[]),
448    ("rdrand", Stable, &[]),
449    ("rdseed", Stable, &[]),
450    (
451        "retpoline-external-thunk",
452        Stability::Forbidden { reason: "use `-Zretpoline-external-thunk` compiler flag instead" },
453        &[],
454    ),
455    (
456        "retpoline-indirect-branches",
457        Stability::Forbidden { reason: "use `-Zretpoline` compiler flag instead" },
458        &[],
459    ),
460    (
461        "retpoline-indirect-calls",
462        Stability::Forbidden { reason: "use `-Zretpoline` compiler flag instead" },
463        &[],
464    ),
465    ("rtm", Unstable(sym::rtm_target_feature), &[]),
466    ("sha", Stable, &["sse2"]),
467    ("sha512", Stable, &["avx2"]),
468    ("sm3", Stable, &["avx"]),
469    ("sm4", Stable, &["avx2"]),
470    ("soft-float", Stability::Unstable(sym::x87_target_feature), &[]),
473    ("sse", Stable, &[]),
474    ("sse2", Stable, &["sse"]),
475    ("sse3", Stable, &["sse2"]),
476    ("sse4.1", Stable, &["ssse3"]),
477    ("sse4.2", Stable, &["sse4.1"]),
478    ("sse4a", Stable, &["sse3"]),
479    ("ssse3", Stable, &["sse3"]),
480    ("tbm", Stable, &[]),
481    ("vaes", Stable, &["avx2", "aes"]),
482    ("vpclmulqdq", Stable, &["avx", "pclmulqdq"]),
483    ("widekl", Stable, &["kl"]),
484    ("x87", Unstable(sym::x87_target_feature), &[]),
485    ("xop", Unstable(sym::xop_target_feature), &["avx", "sse4a"]),
486    ("xsave", Stable, &[]),
487    ("xsavec", Stable, &["xsave"]),
488    ("xsaveopt", Stable, &["xsave"]),
489    ("xsaves", Stable, &["xsave"]),
490    ];
492
493const HEXAGON_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
494    ("hvx", Unstable(sym::hexagon_target_feature), &[]),
496    ("hvx-length128b", Unstable(sym::hexagon_target_feature), &["hvx"]),
497    ];
499
500static POWERPC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
501    ("altivec", Unstable(sym::powerpc_target_feature), &[]),
503    ("msync", Unstable(sym::powerpc_target_feature), &[]),
504    ("partword-atomics", Unstable(sym::powerpc_target_feature), &[]),
505    ("power8-altivec", Unstable(sym::powerpc_target_feature), &["altivec"]),
506    ("power8-crypto", Unstable(sym::powerpc_target_feature), &["power8-altivec"]),
507    ("power8-vector", Unstable(sym::powerpc_target_feature), &["vsx", "power8-altivec"]),
508    ("power9-altivec", Unstable(sym::powerpc_target_feature), &["power8-altivec"]),
509    ("power9-vector", Unstable(sym::powerpc_target_feature), &["power8-vector", "power9-altivec"]),
510    ("power10-vector", Unstable(sym::powerpc_target_feature), &["power9-vector"]),
511    ("quadword-atomics", Unstable(sym::powerpc_target_feature), &[]),
512    ("vsx", Unstable(sym::powerpc_target_feature), &["altivec"]),
513    ];
515
516const MIPS_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
517    ("fp64", Unstable(sym::mips_target_feature), &[]),
519    ("msa", Unstable(sym::mips_target_feature), &[]),
520    ("virt", Unstable(sym::mips_target_feature), &[]),
521    ];
523
524const NVPTX_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
525    ("sm_20", Unstable(sym::nvptx_target_feature), &[]),
527    ("sm_21", Unstable(sym::nvptx_target_feature), &["sm_20"]),
528    ("sm_30", Unstable(sym::nvptx_target_feature), &["sm_21"]),
529    ("sm_32", Unstable(sym::nvptx_target_feature), &["sm_30"]),
530    ("sm_35", Unstable(sym::nvptx_target_feature), &["sm_32"]),
531    ("sm_37", Unstable(sym::nvptx_target_feature), &["sm_35"]),
532    ("sm_50", Unstable(sym::nvptx_target_feature), &["sm_37"]),
533    ("sm_52", Unstable(sym::nvptx_target_feature), &["sm_50"]),
534    ("sm_53", Unstable(sym::nvptx_target_feature), &["sm_52"]),
535    ("sm_60", Unstable(sym::nvptx_target_feature), &["sm_53"]),
536    ("sm_61", Unstable(sym::nvptx_target_feature), &["sm_60"]),
537    ("sm_62", Unstable(sym::nvptx_target_feature), &["sm_61"]),
538    ("sm_70", Unstable(sym::nvptx_target_feature), &["sm_62"]),
539    ("sm_72", Unstable(sym::nvptx_target_feature), &["sm_70"]),
540    ("sm_75", Unstable(sym::nvptx_target_feature), &["sm_72"]),
541    ("sm_80", Unstable(sym::nvptx_target_feature), &["sm_75"]),
542    ("sm_86", Unstable(sym::nvptx_target_feature), &["sm_80"]),
543    ("sm_87", Unstable(sym::nvptx_target_feature), &["sm_86"]),
544    ("sm_89", Unstable(sym::nvptx_target_feature), &["sm_87"]),
545    ("sm_90", Unstable(sym::nvptx_target_feature), &["sm_89"]),
546    ("sm_90a", Unstable(sym::nvptx_target_feature), &["sm_90"]),
547    ("sm_100", Unstable(sym::nvptx_target_feature), &["sm_90"]),
550    ("sm_100a", Unstable(sym::nvptx_target_feature), &["sm_100"]),
551    ("sm_101", Unstable(sym::nvptx_target_feature), &["sm_100"]),
552    ("sm_101a", Unstable(sym::nvptx_target_feature), &["sm_101"]),
553    ("sm_120", Unstable(sym::nvptx_target_feature), &["sm_101"]),
554    ("sm_120a", Unstable(sym::nvptx_target_feature), &["sm_120"]),
555    ("ptx32", Unstable(sym::nvptx_target_feature), &[]),
558    ("ptx40", Unstable(sym::nvptx_target_feature), &["ptx32"]),
559    ("ptx41", Unstable(sym::nvptx_target_feature), &["ptx40"]),
560    ("ptx42", Unstable(sym::nvptx_target_feature), &["ptx41"]),
561    ("ptx43", Unstable(sym::nvptx_target_feature), &["ptx42"]),
562    ("ptx50", Unstable(sym::nvptx_target_feature), &["ptx43"]),
563    ("ptx60", Unstable(sym::nvptx_target_feature), &["ptx50"]),
564    ("ptx61", Unstable(sym::nvptx_target_feature), &["ptx60"]),
565    ("ptx62", Unstable(sym::nvptx_target_feature), &["ptx61"]),
566    ("ptx63", Unstable(sym::nvptx_target_feature), &["ptx62"]),
567    ("ptx64", Unstable(sym::nvptx_target_feature), &["ptx63"]),
568    ("ptx65", Unstable(sym::nvptx_target_feature), &["ptx64"]),
569    ("ptx70", Unstable(sym::nvptx_target_feature), &["ptx65"]),
570    ("ptx71", Unstable(sym::nvptx_target_feature), &["ptx70"]),
571    ("ptx72", Unstable(sym::nvptx_target_feature), &["ptx71"]),
572    ("ptx73", Unstable(sym::nvptx_target_feature), &["ptx72"]),
573    ("ptx74", Unstable(sym::nvptx_target_feature), &["ptx73"]),
574    ("ptx75", Unstable(sym::nvptx_target_feature), &["ptx74"]),
575    ("ptx76", Unstable(sym::nvptx_target_feature), &["ptx75"]),
576    ("ptx77", Unstable(sym::nvptx_target_feature), &["ptx76"]),
577    ("ptx78", Unstable(sym::nvptx_target_feature), &["ptx77"]),
578    ("ptx80", Unstable(sym::nvptx_target_feature), &["ptx78"]),
579    ("ptx81", Unstable(sym::nvptx_target_feature), &["ptx80"]),
580    ("ptx82", Unstable(sym::nvptx_target_feature), &["ptx81"]),
581    ("ptx83", Unstable(sym::nvptx_target_feature), &["ptx82"]),
582    ("ptx84", Unstable(sym::nvptx_target_feature), &["ptx83"]),
583    ("ptx85", Unstable(sym::nvptx_target_feature), &["ptx84"]),
584    ("ptx86", Unstable(sym::nvptx_target_feature), &["ptx85"]),
585    ("ptx87", Unstable(sym::nvptx_target_feature), &["ptx86"]),
586    ];
588
589static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
590    ("a", Stable, &["zaamo", "zalrsc"]),
592    ("b", Unstable(sym::riscv_target_feature), &["zba", "zbb", "zbs"]),
593    ("c", Stable, &["zca"]),
594    ("d", Unstable(sym::riscv_target_feature), &["f"]),
595    ("e", Unstable(sym::riscv_target_feature), &[]),
596    ("f", Unstable(sym::riscv_target_feature), &["zicsr"]),
597    (
598        "forced-atomics",
599        Stability::Forbidden { reason: "unsound because it changes the ABI of atomic operations" },
600        &[],
601    ),
602    ("m", Stable, &[]),
603    ("relax", Unstable(sym::riscv_target_feature), &[]),
604    (
605        "rva23u64",
606        Unstable(sym::riscv_target_feature),
607        &[
608            "m",
609            "a",
610            "f",
611            "d",
612            "c",
613            "b",
614            "v",
615            "zicsr",
616            "zicntr",
617            "zihpm",
618            "ziccif",
619            "ziccrse",
620            "ziccamoa",
621            "zicclsm",
622            "zic64b",
623            "za64rs",
624            "zihintpause",
625            "zba",
626            "zbb",
627            "zbs",
628            "zicbom",
629            "zicbop",
630            "zicboz",
631            "zfhmin",
632            "zkt",
633            "zvfhmin",
634            "zvbb",
635            "zvkt",
636            "zihintntl",
637            "zicond",
638            "zimop",
639            "zcmop",
640            "zcb",
641            "zfa",
642            "zawrs",
643            "supm",
644        ],
645    ),
646    ("supm", Unstable(sym::riscv_target_feature), &[]),
647    ("unaligned-scalar-mem", Unstable(sym::riscv_target_feature), &[]),
648    ("unaligned-vector-mem", Unstable(sym::riscv_target_feature), &[]),
649    ("v", Unstable(sym::riscv_target_feature), &["zvl128b", "zve64d"]),
650    ("za64rs", Unstable(sym::riscv_target_feature), &["za128rs"]), ("za128rs", Unstable(sym::riscv_target_feature), &[]),
652    ("zaamo", Unstable(sym::riscv_target_feature), &[]),
653    ("zabha", Unstable(sym::riscv_target_feature), &["zaamo"]),
654    ("zacas", Unstable(sym::riscv_target_feature), &["zaamo"]),
655    ("zalrsc", Unstable(sym::riscv_target_feature), &[]),
656    ("zama16b", Unstable(sym::riscv_target_feature), &[]),
657    ("zawrs", Unstable(sym::riscv_target_feature), &[]),
658    ("zba", Stable, &[]),
659    ("zbb", Stable, &[]),
660    ("zbc", Stable, &["zbkc"]), ("zbkb", Stable, &[]),
662    ("zbkc", Stable, &[]),
663    ("zbkx", Stable, &[]),
664    ("zbs", Stable, &[]),
665    ("zca", Unstable(sym::riscv_target_feature), &[]),
666    ("zcb", Unstable(sym::riscv_target_feature), &["zca"]),
667    ("zcmop", Unstable(sym::riscv_target_feature), &["zca"]),
668    ("zdinx", Unstable(sym::riscv_target_feature), &["zfinx"]),
669    ("zfa", Unstable(sym::riscv_target_feature), &["f"]),
670    ("zfbfmin", Unstable(sym::riscv_target_feature), &["f"]), ("zfh", Unstable(sym::riscv_target_feature), &["zfhmin"]),
672    ("zfhmin", Unstable(sym::riscv_target_feature), &["f"]),
673    ("zfinx", Unstable(sym::riscv_target_feature), &["zicsr"]),
674    ("zhinx", Unstable(sym::riscv_target_feature), &["zhinxmin"]),
675    ("zhinxmin", Unstable(sym::riscv_target_feature), &["zfinx"]),
676    ("zic64b", Unstable(sym::riscv_target_feature), &[]),
677    ("zicbom", Unstable(sym::riscv_target_feature), &[]),
678    ("zicbop", Unstable(sym::riscv_target_feature), &[]),
679    ("zicboz", Unstable(sym::riscv_target_feature), &[]),
680    ("ziccamoa", Unstable(sym::riscv_target_feature), &[]),
681    ("ziccif", Unstable(sym::riscv_target_feature), &[]),
682    ("zicclsm", Unstable(sym::riscv_target_feature), &[]),
683    ("ziccrse", Unstable(sym::riscv_target_feature), &[]),
684    ("zicntr", Unstable(sym::riscv_target_feature), &["zicsr"]),
685    ("zicond", Unstable(sym::riscv_target_feature), &[]),
686    ("zicsr", Unstable(sym::riscv_target_feature), &[]),
687    ("zifencei", Unstable(sym::riscv_target_feature), &[]),
688    ("zihintntl", Unstable(sym::riscv_target_feature), &[]),
689    ("zihintpause", Unstable(sym::riscv_target_feature), &[]),
690    ("zihpm", Unstable(sym::riscv_target_feature), &["zicsr"]),
691    ("zimop", Unstable(sym::riscv_target_feature), &[]),
692    ("zk", Stable, &["zkn", "zkr", "zkt"]),
693    ("zkn", Stable, &["zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"]),
694    ("zknd", Stable, &[]),
695    ("zkne", Stable, &[]),
696    ("zknh", Stable, &[]),
697    ("zkr", Stable, &[]),
698    ("zks", Stable, &["zbkb", "zbkc", "zbkx", "zksed", "zksh"]),
699    ("zksed", Stable, &[]),
700    ("zksh", Stable, &[]),
701    ("zkt", Stable, &[]),
702    ("ztso", Unstable(sym::riscv_target_feature), &[]),
703    ("zvbb", Unstable(sym::riscv_target_feature), &["zvkb"]), ("zvbc", Unstable(sym::riscv_target_feature), &["zve64x"]),
705    ("zve32f", Unstable(sym::riscv_target_feature), &["zve32x", "f"]),
706    ("zve32x", Unstable(sym::riscv_target_feature), &["zvl32b", "zicsr"]),
707    ("zve64d", Unstable(sym::riscv_target_feature), &["zve64f", "d"]),
708    ("zve64f", Unstable(sym::riscv_target_feature), &["zve32f", "zve64x"]),
709    ("zve64x", Unstable(sym::riscv_target_feature), &["zve32x", "zvl64b"]),
710    ("zvfbfmin", Unstable(sym::riscv_target_feature), &["zve32f"]),
711    ("zvfbfwma", Unstable(sym::riscv_target_feature), &["zfbfmin", "zvfbfmin"]),
712    ("zvfh", Unstable(sym::riscv_target_feature), &["zvfhmin", "zve32f", "zfhmin"]), ("zvfhmin", Unstable(sym::riscv_target_feature), &["zve32f"]),
714    ("zvkb", Unstable(sym::riscv_target_feature), &["zve32x"]),
715    ("zvkg", Unstable(sym::riscv_target_feature), &["zve32x"]),
716    ("zvkn", Unstable(sym::riscv_target_feature), &["zvkned", "zvknhb", "zvkb", "zvkt"]),
717    ("zvknc", Unstable(sym::riscv_target_feature), &["zvkn", "zvbc"]),
718    ("zvkned", Unstable(sym::riscv_target_feature), &["zve32x"]),
719    ("zvkng", Unstable(sym::riscv_target_feature), &["zvkn", "zvkg"]),
720    ("zvknha", Unstable(sym::riscv_target_feature), &["zve32x"]),
721    ("zvknhb", Unstable(sym::riscv_target_feature), &["zvknha", "zve64x"]), ("zvks", Unstable(sym::riscv_target_feature), &["zvksed", "zvksh", "zvkb", "zvkt"]),
723    ("zvksc", Unstable(sym::riscv_target_feature), &["zvks", "zvbc"]),
724    ("zvksed", Unstable(sym::riscv_target_feature), &["zve32x"]),
725    ("zvksg", Unstable(sym::riscv_target_feature), &["zvks", "zvkg"]),
726    ("zvksh", Unstable(sym::riscv_target_feature), &["zve32x"]),
727    ("zvkt", Unstable(sym::riscv_target_feature), &[]),
728    ("zvl32b", Unstable(sym::riscv_target_feature), &[]),
729    ("zvl64b", Unstable(sym::riscv_target_feature), &["zvl32b"]),
730    ("zvl128b", Unstable(sym::riscv_target_feature), &["zvl64b"]),
731    ("zvl256b", Unstable(sym::riscv_target_feature), &["zvl128b"]),
732    ("zvl512b", Unstable(sym::riscv_target_feature), &["zvl256b"]),
733    ("zvl1024b", Unstable(sym::riscv_target_feature), &["zvl512b"]),
734    ("zvl2048b", Unstable(sym::riscv_target_feature), &["zvl1024b"]),
735    ("zvl4096b", Unstable(sym::riscv_target_feature), &["zvl2048b"]),
736    ("zvl8192b", Unstable(sym::riscv_target_feature), &["zvl4096b"]),
737    ("zvl16384b", Unstable(sym::riscv_target_feature), &["zvl8192b"]),
738    ("zvl32768b", Unstable(sym::riscv_target_feature), &["zvl16384b"]),
739    ("zvl65536b", Unstable(sym::riscv_target_feature), &["zvl32768b"]),
740    ];
742
743static WASM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
744    ("atomics", Unstable(sym::wasm_target_feature), &[]),
746    ("bulk-memory", Stable, &[]),
747    ("exception-handling", Unstable(sym::wasm_target_feature), &[]),
748    ("extended-const", Stable, &[]),
749    ("multivalue", Stable, &[]),
750    ("mutable-globals", Stable, &[]),
751    ("nontrapping-fptoint", Stable, &[]),
752    ("reference-types", Stable, &[]),
753    ("relaxed-simd", Stable, &["simd128"]),
754    ("sign-ext", Stable, &[]),
755    ("simd128", Stable, &[]),
756    ("tail-call", Stable, &[]),
757    ("wide-arithmetic", Unstable(sym::wasm_target_feature), &[]),
758    ];
760
761const BPF_FEATURES: &[(&str, Stability, ImpliedFeatures)] =
762    &[("alu32", Unstable(sym::bpf_target_feature), &[])];
763
764static CSKY_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
765    ("2e3", Unstable(sym::csky_target_feature), &["e2"]),
767    ("3e3r1", Unstable(sym::csky_target_feature), &[]),
768    ("3e3r2", Unstable(sym::csky_target_feature), &["3e3r1", "doloop"]),
769    ("3e3r3", Unstable(sym::csky_target_feature), &["doloop"]),
770    ("3e7", Unstable(sym::csky_target_feature), &["2e3"]),
771    ("7e10", Unstable(sym::csky_target_feature), &["3e7"]),
772    ("10e60", Unstable(sym::csky_target_feature), &["7e10"]),
773    ("cache", Unstable(sym::csky_target_feature), &[]),
774    ("doloop", Unstable(sym::csky_target_feature), &[]),
775    ("dsp1e2", Unstable(sym::csky_target_feature), &[]),
776    ("dspe60", Unstable(sym::csky_target_feature), &[]),
777    ("e1", Unstable(sym::csky_target_feature), &["elrw"]),
778    ("e2", Unstable(sym::csky_target_feature), &["e2"]),
779    ("edsp", Unstable(sym::csky_target_feature), &[]),
780    ("elrw", Unstable(sym::csky_target_feature), &[]),
781    ("float1e2", Unstable(sym::csky_target_feature), &[]),
782    ("float1e3", Unstable(sym::csky_target_feature), &[]),
783    ("float3e4", Unstable(sym::csky_target_feature), &[]),
784    ("float7e60", Unstable(sym::csky_target_feature), &[]),
785    ("floate1", Unstable(sym::csky_target_feature), &[]),
786    ("hard-tp", Unstable(sym::csky_target_feature), &[]),
787    ("high-registers", Unstable(sym::csky_target_feature), &[]),
788    ("hwdiv", Unstable(sym::csky_target_feature), &[]),
789    ("mp", Unstable(sym::csky_target_feature), &["2e3"]),
790    ("mp1e2", Unstable(sym::csky_target_feature), &["3e7"]),
791    ("nvic", Unstable(sym::csky_target_feature), &[]),
792    ("trust", Unstable(sym::csky_target_feature), &[]),
793    ("vdsp2e60f", Unstable(sym::csky_target_feature), &[]),
794    ("vdspv1", Unstable(sym::csky_target_feature), &[]),
795    ("vdspv2", Unstable(sym::csky_target_feature), &[]),
796    ("fdivdu", Unstable(sym::csky_target_feature), &[]),
800    ("fpuv2_df", Unstable(sym::csky_target_feature), &[]),
801    ("fpuv2_sf", Unstable(sym::csky_target_feature), &[]),
802    ("fpuv3_df", Unstable(sym::csky_target_feature), &[]),
803    ("fpuv3_hf", Unstable(sym::csky_target_feature), &[]),
804    ("fpuv3_hi", Unstable(sym::csky_target_feature), &[]),
805    ("fpuv3_sf", Unstable(sym::csky_target_feature), &[]),
806    ("hard-float", Unstable(sym::csky_target_feature), &[]),
807    ("hard-float-abi", Unstable(sym::csky_target_feature), &[]),
808    ];
810
811static LOONGARCH_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
812    ("32s", Unstable(sym::loongarch_target_feature), &[]),
814    ("d", Stable, &["f"]),
815    ("div32", Unstable(sym::loongarch_target_feature), &[]),
816    ("f", Stable, &[]),
817    ("frecipe", Stable, &[]),
818    ("lam-bh", Unstable(sym::loongarch_target_feature), &[]),
819    ("lamcas", Unstable(sym::loongarch_target_feature), &[]),
820    ("lasx", Stable, &["lsx"]),
821    ("lbt", Stable, &[]),
822    ("ld-seq-sa", Unstable(sym::loongarch_target_feature), &[]),
823    ("lsx", Stable, &["d"]),
824    ("lvz", Stable, &[]),
825    ("relax", Unstable(sym::loongarch_target_feature), &[]),
826    ("scq", Unstable(sym::loongarch_target_feature), &[]),
827    ("ual", Unstable(sym::loongarch_target_feature), &[]),
828    ];
830
831#[rustfmt::skip]
832const IBMZ_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
833    ("backchain", Unstable(sym::s390x_target_feature), &[]),
836    ("concurrent-functions", Unstable(sym::s390x_target_feature), &[]),
837    ("deflate-conversion", Unstable(sym::s390x_target_feature), &[]),
838    ("enhanced-sort", Unstable(sym::s390x_target_feature), &[]),
839    ("guarded-storage", Unstable(sym::s390x_target_feature), &[]),
840    ("high-word", Unstable(sym::s390x_target_feature), &[]),
841    ("message-security-assist-extension3", Unstable(sym::s390x_target_feature), &[]),
843    ("message-security-assist-extension4", Unstable(sym::s390x_target_feature), &[]),
844    ("message-security-assist-extension5", Unstable(sym::s390x_target_feature), &[]),
845    ("message-security-assist-extension8", Unstable(sym::s390x_target_feature), &["message-security-assist-extension3"]),
846    ("message-security-assist-extension9", Unstable(sym::s390x_target_feature), &["message-security-assist-extension3", "message-security-assist-extension4"]),
847    ("message-security-assist-extension12", Unstable(sym::s390x_target_feature), &[]),
848    ("miscellaneous-extensions-2", Unstable(sym::s390x_target_feature), &[]),
849    ("miscellaneous-extensions-3", Unstable(sym::s390x_target_feature), &[]),
850    ("miscellaneous-extensions-4", Unstable(sym::s390x_target_feature), &[]),
851    ("nnp-assist", Unstable(sym::s390x_target_feature), &["vector"]),
852    ("soft-float", Forbidden { reason: "currently unsupported ABI-configuration feature" }, &[]),
853    ("transactional-execution", Unstable(sym::s390x_target_feature), &[]),
854    ("vector", Unstable(sym::s390x_target_feature), &[]),
855    ("vector-enhancements-1", Unstable(sym::s390x_target_feature), &["vector"]),
856    ("vector-enhancements-2", Unstable(sym::s390x_target_feature), &["vector-enhancements-1"]),
857    ("vector-enhancements-3", Unstable(sym::s390x_target_feature), &["vector-enhancements-2"]),
858    ("vector-packed-decimal", Unstable(sym::s390x_target_feature), &["vector"]),
859    ("vector-packed-decimal-enhancement", Unstable(sym::s390x_target_feature), &["vector-packed-decimal"]),
860    ("vector-packed-decimal-enhancement-2", Unstable(sym::s390x_target_feature), &["vector-packed-decimal-enhancement"]),
861    ("vector-packed-decimal-enhancement-3", Unstable(sym::s390x_target_feature), &["vector-packed-decimal-enhancement-2"]),
862    ];
864
865const SPARC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
866    ("leoncasa", Unstable(sym::sparc_target_feature), &[]),
868    ("v8plus", Unstable(sym::sparc_target_feature), &[]),
869    ("v9", Unstable(sym::sparc_target_feature), &[]),
870    ];
872
873static M68K_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
874    ("isa-68000", Unstable(sym::m68k_target_feature), &[]),
876    ("isa-68010", Unstable(sym::m68k_target_feature), &["isa-68000"]),
877    ("isa-68020", Unstable(sym::m68k_target_feature), &["isa-68010"]),
878    ("isa-68030", Unstable(sym::m68k_target_feature), &["isa-68020"]),
879    ("isa-68040", Unstable(sym::m68k_target_feature), &["isa-68030", "isa-68882"]),
880    ("isa-68060", Unstable(sym::m68k_target_feature), &["isa-68040"]),
881    ("isa-68881", Unstable(sym::m68k_target_feature), &[]),
883    ("isa-68882", Unstable(sym::m68k_target_feature), &["isa-68881"]),
884    ];
886
887pub fn all_rust_features() -> impl Iterator<Item = (&'static str, Stability)> {
892    std::iter::empty()
893        .chain(ARM_FEATURES.iter())
894        .chain(AARCH64_FEATURES.iter())
895        .chain(X86_FEATURES.iter())
896        .chain(HEXAGON_FEATURES.iter())
897        .chain(POWERPC_FEATURES.iter())
898        .chain(MIPS_FEATURES.iter())
899        .chain(NVPTX_FEATURES.iter())
900        .chain(RISCV_FEATURES.iter())
901        .chain(WASM_FEATURES.iter())
902        .chain(BPF_FEATURES.iter())
903        .chain(CSKY_FEATURES)
904        .chain(LOONGARCH_FEATURES)
905        .chain(IBMZ_FEATURES)
906        .chain(SPARC_FEATURES)
907        .chain(M68K_FEATURES)
908        .cloned()
909        .map(|(f, s, _)| (f, s))
910}
911
912const X86_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
916    &[(128, "sse"), (256, "avx"), (512, "avx512f")]; const AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")];
918
919const ARM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")];
921
922const POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "altivec")];
923const WASM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "simd128")];
924const S390X_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vector")];
925const RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[
926    (32, "zvl32b"),
927    (64, "zvl64b"),
928    (128, "zvl128b"),
929    (256, "zvl256b"),
930    (512, "zvl512b"),
931    (1024, "zvl1024b"),
932    (2048, "zvl2048b"),
933    (4096, "zvl4096b"),
934    (8192, "zvl8192b"),
935    (16384, "zvl16384b"),
936    (32768, "zvl32768b"),
937    (65536, "zvl65536b"),
938];
939const SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[];
941
942const HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
943    &[(1024, "hvx-length128b")];
944const MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "msa")];
945const CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vdspv1")];
946const LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
947    &[(128, "lsx"), (256, "lasx")];
948
949#[derive(Copy, Clone, Debug)]
950pub struct FeatureConstraints {
951    pub required: &'static [&'static str],
953    pub incompatible: &'static [&'static str],
955}
956
957impl Target {
958    pub fn rust_target_features(&self) -> &'static [(&'static str, Stability, ImpliedFeatures)] {
959        match &*self.arch {
960            "arm" => ARM_FEATURES,
961            "aarch64" | "arm64ec" => AARCH64_FEATURES,
962            "x86" | "x86_64" => X86_FEATURES,
963            "hexagon" => HEXAGON_FEATURES,
964            "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_FEATURES,
965            "nvptx64" => NVPTX_FEATURES,
966            "powerpc" | "powerpc64" => POWERPC_FEATURES,
967            "riscv32" | "riscv64" => RISCV_FEATURES,
968            "wasm32" | "wasm64" => WASM_FEATURES,
969            "bpf" => BPF_FEATURES,
970            "csky" => CSKY_FEATURES,
971            "loongarch32" | "loongarch64" => LOONGARCH_FEATURES,
972            "s390x" => IBMZ_FEATURES,
973            "sparc" | "sparc64" => SPARC_FEATURES,
974            "m68k" => M68K_FEATURES,
975            _ => &[],
976        }
977    }
978
979    pub fn features_for_correct_vector_abi(&self) -> &'static [(u64, &'static str)] {
980        match &*self.arch {
981            "x86" | "x86_64" => X86_FEATURES_FOR_CORRECT_VECTOR_ABI,
982            "aarch64" | "arm64ec" => AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI,
983            "arm" => ARM_FEATURES_FOR_CORRECT_VECTOR_ABI,
984            "powerpc" | "powerpc64" => POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI,
985            "loongarch32" | "loongarch64" => LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI,
986            "riscv32" | "riscv64" => RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI,
987            "wasm32" | "wasm64" => WASM_FEATURES_FOR_CORRECT_VECTOR_ABI,
988            "s390x" => S390X_FEATURES_FOR_CORRECT_VECTOR_ABI,
989            "sparc" | "sparc64" => SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI,
990            "hexagon" => HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI,
991            "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI,
992            "nvptx64" | "bpf" | "m68k" => &[], "csky" => CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI,
994            _ => &[],
997        }
998    }
999
1000    pub fn tied_target_features(&self) -> &'static [&'static [&'static str]] {
1001        match &*self.arch {
1002            "aarch64" | "arm64ec" => AARCH64_TIED_FEATURES,
1003            _ => &[],
1004        }
1005    }
1006
1007    pub fn implied_target_features<'a>(&self, base_feature: &'a str) -> FxHashSet<&'a str> {
1009        let implied_features =
1010            self.rust_target_features().iter().map(|(f, _, i)| (f, i)).collect::<FxHashMap<_, _>>();
1011
1012        let mut features = FxHashSet::default();
1015        let mut new_features = vec![base_feature];
1016        while let Some(new_feature) = new_features.pop() {
1017            if features.insert(new_feature) {
1018                if let Some(implied_features) = implied_features.get(&new_feature) {
1019                    new_features.extend(implied_features.iter().copied())
1020                }
1021            }
1022        }
1023        features
1024    }
1025
1026    pub fn abi_required_features(&self) -> FeatureConstraints {
1037        const NOTHING: FeatureConstraints = FeatureConstraints { required: &[], incompatible: &[] };
1038        match &*self.arch {
1043            "x86" => {
1044                match self.rustc_abi {
1047                    None => {
1048                        FeatureConstraints { required: &["x87"], incompatible: &["soft-float"] }
1051                    }
1052                    Some(RustcAbi::X86Sse2) => {
1053                        FeatureConstraints {
1055                            required: &["x87", "sse2"],
1056                            incompatible: &["soft-float"],
1057                        }
1058                    }
1059                    Some(RustcAbi::X86Softfloat) => {
1060                        FeatureConstraints { required: &["soft-float"], incompatible: &[] }
1065                    }
1066                }
1067            }
1068            "x86_64" => {
1069                match self.rustc_abi {
1072                    None => {
1073                        FeatureConstraints {
1075                            required: &["x87", "sse2"],
1076                            incompatible: &["soft-float"],
1077                        }
1078                    }
1079                    Some(RustcAbi::X86Softfloat) => {
1080                        FeatureConstraints { required: &["soft-float"], incompatible: &[] }
1085                    }
1086                    Some(r) => panic!("invalid Rust ABI for x86_64: {r:?}"),
1087                }
1088            }
1089            "arm" => {
1090                match self.llvm_floatabi.unwrap() {
1093                    FloatAbi::Soft => {
1094                        NOTHING
1099                    }
1100                    FloatAbi::Hard => {
1101                        FeatureConstraints { required: &["fpregs"], incompatible: &["soft-float"] }
1103                    }
1104                }
1105            }
1106            "aarch64" | "arm64ec" => {
1107                match &*self.abi {
1110                    "softfloat" => {
1111                        FeatureConstraints { required: &[], incompatible: &["neon"] }
1117                    }
1118                    _ => {
1119                        FeatureConstraints { required: &["neon"], incompatible: &[] }
1122                    }
1123                }
1124            }
1125            "riscv32" | "riscv64" => {
1126                match &*self.llvm_abiname {
1129                    "ilp32d" | "lp64d" => {
1130                        FeatureConstraints { required: &["d"], incompatible: &["e", "zfinx"] }
1132                    }
1133                    "ilp32f" | "lp64f" => {
1134                        FeatureConstraints { required: &["f"], incompatible: &["e", "zfinx"] }
1136                    }
1137                    "ilp32" | "lp64" => {
1138                        FeatureConstraints { required: &[], incompatible: &["e"] }
1140                    }
1141                    "ilp32e" => {
1142                        FeatureConstraints { required: &[], incompatible: &["d"] }
1151                    }
1152                    "lp64e" => {
1153                        NOTHING
1155                    }
1156                    _ => unreachable!(),
1157                }
1158            }
1159            "loongarch32" | "loongarch64" => {
1160                match &*self.llvm_abiname {
1163                    "ilp32d" | "lp64d" => {
1164                        FeatureConstraints { required: &["d"], incompatible: &[] }
1166                    }
1167                    "ilp32f" | "lp64f" => {
1168                        FeatureConstraints { required: &["f"], incompatible: &[] }
1170                    }
1171                    "ilp32s" | "lp64s" => {
1172                        NOTHING
1177                    }
1178                    _ => unreachable!(),
1179                }
1180            }
1181            "s390x" => {
1182                FeatureConstraints { required: &[], incompatible: &["soft-float"] }
1187            }
1188            _ => NOTHING,
1189        }
1190    }
1191}