1use rustc_data_structures::fx::{FxHashMap, FxHashSet};
5use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
6use rustc_span::{Symbol, sym};
7
8use crate::spec::{Abi, Arch, 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 ("apxf", Unstable(sym::apx_target_feature), &[]),
390 ("avx", Stable, &["sse4.2"]),
391 ("avx2", Stable, &["avx"]),
392 (
393 "avx10.1",
394 Unstable(sym::avx10_target_feature),
395 &[
396 "avx512bf16",
397 "avx512bitalg",
398 "avx512bw",
399 "avx512cd",
400 "avx512dq",
401 "avx512f",
402 "avx512fp16",
403 "avx512ifma",
404 "avx512vbmi",
405 "avx512vbmi2",
406 "avx512vl",
407 "avx512vnni",
408 "avx512vpopcntdq",
409 ],
410 ),
411 ("avx10.2", Unstable(sym::avx10_target_feature), &["avx10.1"]),
412 ("avx512bf16", Stable, &["avx512bw"]),
413 ("avx512bitalg", Stable, &["avx512bw"]),
414 ("avx512bw", Stable, &["avx512f"]),
415 ("avx512cd", Stable, &["avx512f"]),
416 ("avx512dq", Stable, &["avx512f"]),
417 ("avx512f", Stable, &["avx2", "fma", "f16c"]),
418 ("avx512fp16", Stable, &["avx512bw"]),
419 ("avx512ifma", Stable, &["avx512f"]),
420 ("avx512vbmi", Stable, &["avx512bw"]),
421 ("avx512vbmi2", Stable, &["avx512bw"]),
422 ("avx512vl", Stable, &["avx512f"]),
423 ("avx512vnni", Stable, &["avx512f"]),
424 ("avx512vp2intersect", Stable, &["avx512f"]),
425 ("avx512vpopcntdq", Stable, &["avx512f"]),
426 ("avxifma", Stable, &["avx2"]),
427 ("avxneconvert", Stable, &["avx2"]),
428 ("avxvnni", Stable, &["avx2"]),
429 ("avxvnniint8", Stable, &["avx2"]),
430 ("avxvnniint16", Stable, &["avx2"]),
431 ("bmi1", Stable, &[]),
432 ("bmi2", Stable, &[]),
433 ("cmpxchg16b", Stable, &[]),
434 ("ermsb", Unstable(sym::ermsb_target_feature), &[]),
435 ("f16c", Stable, &["avx"]),
436 ("fma", Stable, &["avx"]),
437 ("fxsr", Stable, &[]),
438 ("gfni", Stable, &["sse2"]),
439 ("kl", Stable, &["sse2"]),
440 ("lahfsahf", Unstable(sym::lahfsahf_target_feature), &[]),
441 ("lzcnt", Stable, &[]),
442 ("movbe", Stable, &[]),
443 ("movrs", Unstable(sym::movrs_target_feature), &[]),
444 ("pclmulqdq", Stable, &["sse2"]),
445 ("popcnt", Stable, &[]),
446 ("prfchw", Unstable(sym::prfchw_target_feature), &[]),
447 ("rdrand", Stable, &[]),
448 ("rdseed", Stable, &[]),
449 (
450 "retpoline-external-thunk",
451 Stability::Forbidden { reason: "use `-Zretpoline-external-thunk` compiler flag instead" },
452 &[],
453 ),
454 (
455 "retpoline-indirect-branches",
456 Stability::Forbidden { reason: "use `-Zretpoline` compiler flag instead" },
457 &[],
458 ),
459 (
460 "retpoline-indirect-calls",
461 Stability::Forbidden { reason: "use `-Zretpoline` compiler flag instead" },
462 &[],
463 ),
464 ("rtm", Unstable(sym::rtm_target_feature), &[]),
465 ("sha", Stable, &["sse2"]),
466 ("sha512", Stable, &["avx2"]),
467 ("sm3", Stable, &["avx"]),
468 ("sm4", Stable, &["avx2"]),
469 ("soft-float", Stability::Unstable(sym::x87_target_feature), &[]),
472 ("sse", Stable, &[]),
473 ("sse2", Stable, &["sse"]),
474 ("sse3", Stable, &["sse2"]),
475 ("sse4.1", Stable, &["ssse3"]),
476 ("sse4.2", Stable, &["sse4.1"]),
477 ("sse4a", Stable, &["sse3"]),
478 ("ssse3", Stable, &["sse3"]),
479 ("tbm", Stable, &[]),
480 ("vaes", Stable, &["avx2", "aes"]),
481 ("vpclmulqdq", Stable, &["avx", "pclmulqdq"]),
482 ("widekl", Stable, &["kl"]),
483 ("x87", Unstable(sym::x87_target_feature), &[]),
484 ("xop", Unstable(sym::xop_target_feature), &["avx", "sse4a"]),
485 ("xsave", Stable, &[]),
486 ("xsavec", Stable, &["xsave"]),
487 ("xsaveopt", Stable, &["xsave"]),
488 ("xsaves", Stable, &["xsave"]),
489 ];
491
492const HEXAGON_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
493 ("hvx", Unstable(sym::hexagon_target_feature), &[]),
495 ("hvx-length128b", Unstable(sym::hexagon_target_feature), &["hvx"]),
496 ];
498
499static POWERPC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
500 ("altivec", Unstable(sym::powerpc_target_feature), &[]),
502 ("msync", Unstable(sym::powerpc_target_feature), &[]),
503 ("partword-atomics", Unstable(sym::powerpc_target_feature), &[]),
504 ("power8-altivec", Unstable(sym::powerpc_target_feature), &["altivec"]),
505 ("power8-crypto", Unstable(sym::powerpc_target_feature), &["power8-altivec"]),
506 ("power8-vector", Unstable(sym::powerpc_target_feature), &["vsx", "power8-altivec"]),
507 ("power9-altivec", Unstable(sym::powerpc_target_feature), &["power8-altivec"]),
508 ("power9-vector", Unstable(sym::powerpc_target_feature), &["power8-vector", "power9-altivec"]),
509 ("power10-vector", Unstable(sym::powerpc_target_feature), &["power9-vector"]),
510 ("quadword-atomics", Unstable(sym::powerpc_target_feature), &[]),
511 ("vsx", Unstable(sym::powerpc_target_feature), &["altivec"]),
512 ];
514
515const MIPS_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
516 ("fp64", Unstable(sym::mips_target_feature), &[]),
518 ("msa", Unstable(sym::mips_target_feature), &[]),
519 ("virt", Unstable(sym::mips_target_feature), &[]),
520 ];
522
523const NVPTX_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
524 ("sm_20", Unstable(sym::nvptx_target_feature), &[]),
526 ("sm_21", Unstable(sym::nvptx_target_feature), &["sm_20"]),
527 ("sm_30", Unstable(sym::nvptx_target_feature), &["sm_21"]),
528 ("sm_32", Unstable(sym::nvptx_target_feature), &["sm_30"]),
529 ("sm_35", Unstable(sym::nvptx_target_feature), &["sm_32"]),
530 ("sm_37", Unstable(sym::nvptx_target_feature), &["sm_35"]),
531 ("sm_50", Unstable(sym::nvptx_target_feature), &["sm_37"]),
532 ("sm_52", Unstable(sym::nvptx_target_feature), &["sm_50"]),
533 ("sm_53", Unstable(sym::nvptx_target_feature), &["sm_52"]),
534 ("sm_60", Unstable(sym::nvptx_target_feature), &["sm_53"]),
535 ("sm_61", Unstable(sym::nvptx_target_feature), &["sm_60"]),
536 ("sm_62", Unstable(sym::nvptx_target_feature), &["sm_61"]),
537 ("sm_70", Unstable(sym::nvptx_target_feature), &["sm_62"]),
538 ("sm_72", Unstable(sym::nvptx_target_feature), &["sm_70"]),
539 ("sm_75", Unstable(sym::nvptx_target_feature), &["sm_72"]),
540 ("sm_80", Unstable(sym::nvptx_target_feature), &["sm_75"]),
541 ("sm_86", Unstable(sym::nvptx_target_feature), &["sm_80"]),
542 ("sm_87", Unstable(sym::nvptx_target_feature), &["sm_86"]),
543 ("sm_89", Unstable(sym::nvptx_target_feature), &["sm_87"]),
544 ("sm_90", Unstable(sym::nvptx_target_feature), &["sm_89"]),
545 ("sm_90a", Unstable(sym::nvptx_target_feature), &["sm_90"]),
546 ("sm_100", Unstable(sym::nvptx_target_feature), &["sm_90"]),
549 ("sm_100a", Unstable(sym::nvptx_target_feature), &["sm_100"]),
550 ("sm_101", Unstable(sym::nvptx_target_feature), &["sm_100"]),
551 ("sm_101a", Unstable(sym::nvptx_target_feature), &["sm_101"]),
552 ("sm_120", Unstable(sym::nvptx_target_feature), &["sm_101"]),
553 ("sm_120a", Unstable(sym::nvptx_target_feature), &["sm_120"]),
554 ("ptx32", Unstable(sym::nvptx_target_feature), &[]),
557 ("ptx40", Unstable(sym::nvptx_target_feature), &["ptx32"]),
558 ("ptx41", Unstable(sym::nvptx_target_feature), &["ptx40"]),
559 ("ptx42", Unstable(sym::nvptx_target_feature), &["ptx41"]),
560 ("ptx43", Unstable(sym::nvptx_target_feature), &["ptx42"]),
561 ("ptx50", Unstable(sym::nvptx_target_feature), &["ptx43"]),
562 ("ptx60", Unstable(sym::nvptx_target_feature), &["ptx50"]),
563 ("ptx61", Unstable(sym::nvptx_target_feature), &["ptx60"]),
564 ("ptx62", Unstable(sym::nvptx_target_feature), &["ptx61"]),
565 ("ptx63", Unstable(sym::nvptx_target_feature), &["ptx62"]),
566 ("ptx64", Unstable(sym::nvptx_target_feature), &["ptx63"]),
567 ("ptx65", Unstable(sym::nvptx_target_feature), &["ptx64"]),
568 ("ptx70", Unstable(sym::nvptx_target_feature), &["ptx65"]),
569 ("ptx71", Unstable(sym::nvptx_target_feature), &["ptx70"]),
570 ("ptx72", Unstable(sym::nvptx_target_feature), &["ptx71"]),
571 ("ptx73", Unstable(sym::nvptx_target_feature), &["ptx72"]),
572 ("ptx74", Unstable(sym::nvptx_target_feature), &["ptx73"]),
573 ("ptx75", Unstable(sym::nvptx_target_feature), &["ptx74"]),
574 ("ptx76", Unstable(sym::nvptx_target_feature), &["ptx75"]),
575 ("ptx77", Unstable(sym::nvptx_target_feature), &["ptx76"]),
576 ("ptx78", Unstable(sym::nvptx_target_feature), &["ptx77"]),
577 ("ptx80", Unstable(sym::nvptx_target_feature), &["ptx78"]),
578 ("ptx81", Unstable(sym::nvptx_target_feature), &["ptx80"]),
579 ("ptx82", Unstable(sym::nvptx_target_feature), &["ptx81"]),
580 ("ptx83", Unstable(sym::nvptx_target_feature), &["ptx82"]),
581 ("ptx84", Unstable(sym::nvptx_target_feature), &["ptx83"]),
582 ("ptx85", Unstable(sym::nvptx_target_feature), &["ptx84"]),
583 ("ptx86", Unstable(sym::nvptx_target_feature), &["ptx85"]),
584 ("ptx87", Unstable(sym::nvptx_target_feature), &["ptx86"]),
585 ];
587
588static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
589 ("a", Stable, &["zaamo", "zalrsc"]),
591 ("b", Unstable(sym::riscv_target_feature), &["zba", "zbb", "zbs"]),
592 ("c", Stable, &["zca"]),
593 ("d", Unstable(sym::riscv_target_feature), &["f"]),
594 ("e", Unstable(sym::riscv_target_feature), &[]),
595 ("f", Unstable(sym::riscv_target_feature), &["zicsr"]),
596 (
597 "forced-atomics",
598 Stability::Forbidden { reason: "unsound because it changes the ABI of atomic operations" },
599 &[],
600 ),
601 ("m", Stable, &[]),
602 ("relax", Unstable(sym::riscv_target_feature), &[]),
603 (
604 "rva23u64",
605 Unstable(sym::riscv_target_feature),
606 &[
607 "m",
608 "a",
609 "f",
610 "d",
611 "c",
612 "b",
613 "v",
614 "zicsr",
615 "zicntr",
616 "zihpm",
617 "ziccif",
618 "ziccrse",
619 "ziccamoa",
620 "zicclsm",
621 "zic64b",
622 "za64rs",
623 "zihintpause",
624 "zba",
625 "zbb",
626 "zbs",
627 "zicbom",
628 "zicbop",
629 "zicboz",
630 "zfhmin",
631 "zkt",
632 "zvfhmin",
633 "zvbb",
634 "zvkt",
635 "zihintntl",
636 "zicond",
637 "zimop",
638 "zcmop",
639 "zcb",
640 "zfa",
641 "zawrs",
642 "supm",
643 ],
644 ),
645 ("supm", Unstable(sym::riscv_target_feature), &[]),
646 ("unaligned-scalar-mem", Unstable(sym::riscv_target_feature), &[]),
647 ("unaligned-vector-mem", Unstable(sym::riscv_target_feature), &[]),
648 ("v", Unstable(sym::riscv_target_feature), &["zvl128b", "zve64d"]),
649 ("za64rs", Unstable(sym::riscv_target_feature), &["za128rs"]), ("za128rs", Unstable(sym::riscv_target_feature), &[]),
651 ("zaamo", Unstable(sym::riscv_target_feature), &[]),
652 ("zabha", Unstable(sym::riscv_target_feature), &["zaamo"]),
653 ("zacas", Unstable(sym::riscv_target_feature), &["zaamo"]),
654 ("zalrsc", Unstable(sym::riscv_target_feature), &[]),
655 ("zama16b", Unstable(sym::riscv_target_feature), &[]),
656 ("zawrs", Unstable(sym::riscv_target_feature), &[]),
657 ("zba", Stable, &[]),
658 ("zbb", Stable, &[]),
659 ("zbc", Stable, &["zbkc"]), ("zbkb", Stable, &[]),
661 ("zbkc", Stable, &[]),
662 ("zbkx", Stable, &[]),
663 ("zbs", Stable, &[]),
664 ("zca", Unstable(sym::riscv_target_feature), &[]),
665 ("zcb", Unstable(sym::riscv_target_feature), &["zca"]),
666 ("zcmop", Unstable(sym::riscv_target_feature), &["zca"]),
667 ("zdinx", Unstable(sym::riscv_target_feature), &["zfinx"]),
668 ("zfa", Unstable(sym::riscv_target_feature), &["f"]),
669 ("zfbfmin", Unstable(sym::riscv_target_feature), &["f"]), ("zfh", Unstable(sym::riscv_target_feature), &["zfhmin"]),
671 ("zfhmin", Unstable(sym::riscv_target_feature), &["f"]),
672 ("zfinx", Unstable(sym::riscv_target_feature), &["zicsr"]),
673 ("zhinx", Unstable(sym::riscv_target_feature), &["zhinxmin"]),
674 ("zhinxmin", Unstable(sym::riscv_target_feature), &["zfinx"]),
675 ("zic64b", Unstable(sym::riscv_target_feature), &[]),
676 ("zicbom", Unstable(sym::riscv_target_feature), &[]),
677 ("zicbop", Unstable(sym::riscv_target_feature), &[]),
678 ("zicboz", Unstable(sym::riscv_target_feature), &[]),
679 ("ziccamoa", Unstable(sym::riscv_target_feature), &[]),
680 ("ziccif", Unstable(sym::riscv_target_feature), &[]),
681 ("zicclsm", Unstable(sym::riscv_target_feature), &[]),
682 ("ziccrse", Unstable(sym::riscv_target_feature), &[]),
683 ("zicntr", Unstable(sym::riscv_target_feature), &["zicsr"]),
684 ("zicond", Unstable(sym::riscv_target_feature), &[]),
685 ("zicsr", Unstable(sym::riscv_target_feature), &[]),
686 ("zifencei", Unstable(sym::riscv_target_feature), &[]),
687 ("zihintntl", Unstable(sym::riscv_target_feature), &[]),
688 ("zihintpause", Unstable(sym::riscv_target_feature), &[]),
689 ("zihpm", Unstable(sym::riscv_target_feature), &["zicsr"]),
690 ("zimop", Unstable(sym::riscv_target_feature), &[]),
691 ("zk", Stable, &["zkn", "zkr", "zkt"]),
692 ("zkn", Stable, &["zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"]),
693 ("zknd", Stable, &[]),
694 ("zkne", Stable, &[]),
695 ("zknh", Stable, &[]),
696 ("zkr", Stable, &[]),
697 ("zks", Stable, &["zbkb", "zbkc", "zbkx", "zksed", "zksh"]),
698 ("zksed", Stable, &[]),
699 ("zksh", Stable, &[]),
700 ("zkt", Stable, &[]),
701 ("ztso", Unstable(sym::riscv_target_feature), &[]),
702 ("zvbb", Unstable(sym::riscv_target_feature), &["zvkb"]), ("zvbc", Unstable(sym::riscv_target_feature), &["zve64x"]),
704 ("zve32f", Unstable(sym::riscv_target_feature), &["zve32x", "f"]),
705 ("zve32x", Unstable(sym::riscv_target_feature), &["zvl32b", "zicsr"]),
706 ("zve64d", Unstable(sym::riscv_target_feature), &["zve64f", "d"]),
707 ("zve64f", Unstable(sym::riscv_target_feature), &["zve32f", "zve64x"]),
708 ("zve64x", Unstable(sym::riscv_target_feature), &["zve32x", "zvl64b"]),
709 ("zvfbfmin", Unstable(sym::riscv_target_feature), &["zve32f"]),
710 ("zvfbfwma", Unstable(sym::riscv_target_feature), &["zfbfmin", "zvfbfmin"]),
711 ("zvfh", Unstable(sym::riscv_target_feature), &["zvfhmin", "zve32f", "zfhmin"]), ("zvfhmin", Unstable(sym::riscv_target_feature), &["zve32f"]),
713 ("zvkb", Unstable(sym::riscv_target_feature), &["zve32x"]),
714 ("zvkg", Unstable(sym::riscv_target_feature), &["zve32x"]),
715 ("zvkn", Unstable(sym::riscv_target_feature), &["zvkned", "zvknhb", "zvkb", "zvkt"]),
716 ("zvknc", Unstable(sym::riscv_target_feature), &["zvkn", "zvbc"]),
717 ("zvkned", Unstable(sym::riscv_target_feature), &["zve32x"]),
718 ("zvkng", Unstable(sym::riscv_target_feature), &["zvkn", "zvkg"]),
719 ("zvknha", Unstable(sym::riscv_target_feature), &["zve32x"]),
720 ("zvknhb", Unstable(sym::riscv_target_feature), &["zvknha", "zve64x"]), ("zvks", Unstable(sym::riscv_target_feature), &["zvksed", "zvksh", "zvkb", "zvkt"]),
722 ("zvksc", Unstable(sym::riscv_target_feature), &["zvks", "zvbc"]),
723 ("zvksed", Unstable(sym::riscv_target_feature), &["zve32x"]),
724 ("zvksg", Unstable(sym::riscv_target_feature), &["zvks", "zvkg"]),
725 ("zvksh", Unstable(sym::riscv_target_feature), &["zve32x"]),
726 ("zvkt", Unstable(sym::riscv_target_feature), &[]),
727 ("zvl32b", Unstable(sym::riscv_target_feature), &[]),
728 ("zvl64b", Unstable(sym::riscv_target_feature), &["zvl32b"]),
729 ("zvl128b", Unstable(sym::riscv_target_feature), &["zvl64b"]),
730 ("zvl256b", Unstable(sym::riscv_target_feature), &["zvl128b"]),
731 ("zvl512b", Unstable(sym::riscv_target_feature), &["zvl256b"]),
732 ("zvl1024b", Unstable(sym::riscv_target_feature), &["zvl512b"]),
733 ("zvl2048b", Unstable(sym::riscv_target_feature), &["zvl1024b"]),
734 ("zvl4096b", Unstable(sym::riscv_target_feature), &["zvl2048b"]),
735 ("zvl8192b", Unstable(sym::riscv_target_feature), &["zvl4096b"]),
736 ("zvl16384b", Unstable(sym::riscv_target_feature), &["zvl8192b"]),
737 ("zvl32768b", Unstable(sym::riscv_target_feature), &["zvl16384b"]),
738 ("zvl65536b", Unstable(sym::riscv_target_feature), &["zvl32768b"]),
739 ];
741
742static WASM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
743 ("atomics", Unstable(sym::wasm_target_feature), &[]),
745 ("bulk-memory", Stable, &[]),
746 ("exception-handling", Unstable(sym::wasm_target_feature), &[]),
747 ("extended-const", Stable, &[]),
748 ("multivalue", Stable, &[]),
749 ("mutable-globals", Stable, &[]),
750 ("nontrapping-fptoint", Stable, &[]),
751 ("reference-types", Stable, &[]),
752 ("relaxed-simd", Stable, &["simd128"]),
753 ("sign-ext", Stable, &[]),
754 ("simd128", Stable, &[]),
755 ("tail-call", Stable, &[]),
756 ("wide-arithmetic", Unstable(sym::wasm_target_feature), &[]),
757 ];
759
760const BPF_FEATURES: &[(&str, Stability, ImpliedFeatures)] =
761 &[("alu32", Unstable(sym::bpf_target_feature), &[])];
762
763static CSKY_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
764 ("2e3", Unstable(sym::csky_target_feature), &["e2"]),
766 ("3e3r1", Unstable(sym::csky_target_feature), &[]),
767 ("3e3r2", Unstable(sym::csky_target_feature), &["3e3r1", "doloop"]),
768 ("3e3r3", Unstable(sym::csky_target_feature), &["doloop"]),
769 ("3e7", Unstable(sym::csky_target_feature), &["2e3"]),
770 ("7e10", Unstable(sym::csky_target_feature), &["3e7"]),
771 ("10e60", Unstable(sym::csky_target_feature), &["7e10"]),
772 ("cache", Unstable(sym::csky_target_feature), &[]),
773 ("doloop", Unstable(sym::csky_target_feature), &[]),
774 ("dsp1e2", Unstable(sym::csky_target_feature), &[]),
775 ("dspe60", Unstable(sym::csky_target_feature), &[]),
776 ("e1", Unstable(sym::csky_target_feature), &["elrw"]),
777 ("e2", Unstable(sym::csky_target_feature), &["e2"]),
778 ("edsp", Unstable(sym::csky_target_feature), &[]),
779 ("elrw", Unstable(sym::csky_target_feature), &[]),
780 ("float1e2", Unstable(sym::csky_target_feature), &[]),
781 ("float1e3", Unstable(sym::csky_target_feature), &[]),
782 ("float3e4", Unstable(sym::csky_target_feature), &[]),
783 ("float7e60", Unstable(sym::csky_target_feature), &[]),
784 ("floate1", Unstable(sym::csky_target_feature), &[]),
785 ("hard-tp", Unstable(sym::csky_target_feature), &[]),
786 ("high-registers", Unstable(sym::csky_target_feature), &[]),
787 ("hwdiv", Unstable(sym::csky_target_feature), &[]),
788 ("mp", Unstable(sym::csky_target_feature), &["2e3"]),
789 ("mp1e2", Unstable(sym::csky_target_feature), &["3e7"]),
790 ("nvic", Unstable(sym::csky_target_feature), &[]),
791 ("trust", Unstable(sym::csky_target_feature), &[]),
792 ("vdsp2e60f", Unstable(sym::csky_target_feature), &[]),
793 ("vdspv1", Unstable(sym::csky_target_feature), &[]),
794 ("vdspv2", Unstable(sym::csky_target_feature), &[]),
795 ("fdivdu", Unstable(sym::csky_target_feature), &[]),
799 ("fpuv2_df", Unstable(sym::csky_target_feature), &[]),
800 ("fpuv2_sf", Unstable(sym::csky_target_feature), &[]),
801 ("fpuv3_df", Unstable(sym::csky_target_feature), &[]),
802 ("fpuv3_hf", Unstable(sym::csky_target_feature), &[]),
803 ("fpuv3_hi", Unstable(sym::csky_target_feature), &[]),
804 ("fpuv3_sf", Unstable(sym::csky_target_feature), &[]),
805 ("hard-float", Unstable(sym::csky_target_feature), &[]),
806 ("hard-float-abi", Unstable(sym::csky_target_feature), &[]),
807 ];
809
810static LOONGARCH_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
811 ("32s", Unstable(sym::loongarch_target_feature), &[]),
813 ("d", Stable, &["f"]),
814 ("div32", Unstable(sym::loongarch_target_feature), &[]),
815 ("f", Stable, &[]),
816 ("frecipe", Stable, &[]),
817 ("lam-bh", Unstable(sym::loongarch_target_feature), &[]),
818 ("lamcas", Unstable(sym::loongarch_target_feature), &[]),
819 ("lasx", Stable, &["lsx"]),
820 ("lbt", Stable, &[]),
821 ("ld-seq-sa", Unstable(sym::loongarch_target_feature), &[]),
822 ("lsx", Stable, &["d"]),
823 ("lvz", Stable, &[]),
824 ("relax", Unstable(sym::loongarch_target_feature), &[]),
825 ("scq", Unstable(sym::loongarch_target_feature), &[]),
826 ("ual", Unstable(sym::loongarch_target_feature), &[]),
827 ];
829
830#[rustfmt::skip]
831const IBMZ_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
832 ("backchain", Unstable(sym::s390x_target_feature), &[]),
835 ("concurrent-functions", Unstable(sym::s390x_target_feature), &[]),
836 ("deflate-conversion", Unstable(sym::s390x_target_feature), &[]),
837 ("enhanced-sort", Unstable(sym::s390x_target_feature), &[]),
838 ("guarded-storage", Unstable(sym::s390x_target_feature), &[]),
839 ("high-word", Unstable(sym::s390x_target_feature), &[]),
840 ("message-security-assist-extension3", Unstable(sym::s390x_target_feature), &[]),
842 ("message-security-assist-extension4", Unstable(sym::s390x_target_feature), &[]),
843 ("message-security-assist-extension5", Unstable(sym::s390x_target_feature), &[]),
844 ("message-security-assist-extension8", Unstable(sym::s390x_target_feature), &["message-security-assist-extension3"]),
845 ("message-security-assist-extension9", Unstable(sym::s390x_target_feature), &["message-security-assist-extension3", "message-security-assist-extension4"]),
846 ("message-security-assist-extension12", Unstable(sym::s390x_target_feature), &[]),
847 ("miscellaneous-extensions-2", Stable, &[]),
848 ("miscellaneous-extensions-3", Stable, &[]),
849 ("miscellaneous-extensions-4", Stable, &[]),
850 ("nnp-assist", Stable, &["vector"]),
851 ("soft-float", Forbidden { reason: "currently unsupported ABI-configuration feature" }, &[]),
852 ("transactional-execution", Unstable(sym::s390x_target_feature), &[]),
853 ("vector", Stable, &[]),
854 ("vector-enhancements-1", Stable, &["vector"]),
855 ("vector-enhancements-2", Stable, &["vector-enhancements-1"]),
856 ("vector-enhancements-3", Stable, &["vector-enhancements-2"]),
857 ("vector-packed-decimal", Stable, &["vector"]),
858 ("vector-packed-decimal-enhancement", Stable, &["vector-packed-decimal"]),
859 ("vector-packed-decimal-enhancement-2", Stable, &["vector-packed-decimal-enhancement"]),
860 ("vector-packed-decimal-enhancement-3", Stable, &["vector-packed-decimal-enhancement-2"]),
861 ];
863
864const SPARC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
865 ("leoncasa", Unstable(sym::sparc_target_feature), &[]),
867 ("v8plus", Unstable(sym::sparc_target_feature), &[]),
868 ("v9", Unstable(sym::sparc_target_feature), &[]),
869 ];
871
872static M68K_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
873 ("isa-68000", Unstable(sym::m68k_target_feature), &[]),
875 ("isa-68010", Unstable(sym::m68k_target_feature), &["isa-68000"]),
876 ("isa-68020", Unstable(sym::m68k_target_feature), &["isa-68010"]),
877 ("isa-68030", Unstable(sym::m68k_target_feature), &["isa-68020"]),
878 ("isa-68040", Unstable(sym::m68k_target_feature), &["isa-68030", "isa-68882"]),
879 ("isa-68060", Unstable(sym::m68k_target_feature), &["isa-68040"]),
880 ("isa-68881", Unstable(sym::m68k_target_feature), &[]),
882 ("isa-68882", Unstable(sym::m68k_target_feature), &["isa-68881"]),
883 ];
885
886pub fn all_rust_features() -> impl Iterator<Item = (&'static str, Stability)> {
891 std::iter::empty()
892 .chain(ARM_FEATURES.iter())
893 .chain(AARCH64_FEATURES.iter())
894 .chain(X86_FEATURES.iter())
895 .chain(HEXAGON_FEATURES.iter())
896 .chain(POWERPC_FEATURES.iter())
897 .chain(MIPS_FEATURES.iter())
898 .chain(NVPTX_FEATURES.iter())
899 .chain(RISCV_FEATURES.iter())
900 .chain(WASM_FEATURES.iter())
901 .chain(BPF_FEATURES.iter())
902 .chain(CSKY_FEATURES)
903 .chain(LOONGARCH_FEATURES)
904 .chain(IBMZ_FEATURES)
905 .chain(SPARC_FEATURES)
906 .chain(M68K_FEATURES)
907 .cloned()
908 .map(|(f, s, _)| (f, s))
909}
910
911const X86_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
915 &[(128, "sse"), (256, "avx"), (512, "avx512f")]; const AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")];
917
918const ARM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")];
920
921const POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "altivec")];
922const WASM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "simd128")];
923const S390X_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vector")];
924const RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[
925 (32, "zvl32b"),
926 (64, "zvl64b"),
927 (128, "zvl128b"),
928 (256, "zvl256b"),
929 (512, "zvl512b"),
930 (1024, "zvl1024b"),
931 (2048, "zvl2048b"),
932 (4096, "zvl4096b"),
933 (8192, "zvl8192b"),
934 (16384, "zvl16384b"),
935 (32768, "zvl32768b"),
936 (65536, "zvl65536b"),
937];
938const SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[];
940
941const HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
942 &[(1024, "hvx-length128b")];
943const MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "msa")];
944const CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vdspv1")];
945const LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
946 &[(128, "lsx"), (256, "lasx")];
947
948#[derive(Copy, Clone, Debug)]
949pub struct FeatureConstraints {
950 pub required: &'static [&'static str],
952 pub incompatible: &'static [&'static str],
954}
955
956impl Target {
957 pub fn rust_target_features(&self) -> &'static [(&'static str, Stability, ImpliedFeatures)] {
958 match &self.arch {
959 Arch::Arm => ARM_FEATURES,
960 Arch::AArch64 | Arch::Arm64EC => AARCH64_FEATURES,
961 Arch::X86 | Arch::X86_64 => X86_FEATURES,
962 Arch::Hexagon => HEXAGON_FEATURES,
963 Arch::Mips | Arch::Mips32r6 | Arch::Mips64 | Arch::Mips64r6 => MIPS_FEATURES,
964 Arch::Nvptx64 => NVPTX_FEATURES,
965 Arch::PowerPC | Arch::PowerPC64 => POWERPC_FEATURES,
966 Arch::RiscV32 | Arch::RiscV64 => RISCV_FEATURES,
967 Arch::Wasm32 | Arch::Wasm64 => WASM_FEATURES,
968 Arch::Bpf => BPF_FEATURES,
969 Arch::CSky => CSKY_FEATURES,
970 Arch::LoongArch32 | Arch::LoongArch64 => LOONGARCH_FEATURES,
971 Arch::S390x => IBMZ_FEATURES,
972 Arch::Sparc | Arch::Sparc64 => SPARC_FEATURES,
973 Arch::M68k => M68K_FEATURES,
974 Arch::AmdGpu
975 | Arch::Avr
976 | Arch::Msp430
977 | Arch::PowerPC64LE
978 | Arch::SpirV
979 | Arch::Xtensa
980 | Arch::Other(_) => &[],
981 }
982 }
983
984 pub fn features_for_correct_vector_abi(&self) -> &'static [(u64, &'static str)] {
985 match &self.arch {
986 Arch::X86 | Arch::X86_64 => X86_FEATURES_FOR_CORRECT_VECTOR_ABI,
987 Arch::AArch64 | Arch::Arm64EC => AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI,
988 Arch::Arm => ARM_FEATURES_FOR_CORRECT_VECTOR_ABI,
989 Arch::PowerPC | Arch::PowerPC64 => POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI,
990 Arch::LoongArch32 | Arch::LoongArch64 => LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI,
991 Arch::RiscV32 | Arch::RiscV64 => RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI,
992 Arch::Wasm32 | Arch::Wasm64 => WASM_FEATURES_FOR_CORRECT_VECTOR_ABI,
993 Arch::S390x => S390X_FEATURES_FOR_CORRECT_VECTOR_ABI,
994 Arch::Sparc | Arch::Sparc64 => SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI,
995 Arch::Hexagon => HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI,
996 Arch::Mips | Arch::Mips32r6 | Arch::Mips64 | Arch::Mips64r6 => {
997 MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI
998 }
999 Arch::Nvptx64 | Arch::Bpf | Arch::M68k => &[], Arch::CSky => CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI,
1001 Arch::AmdGpu
1004 | Arch::Avr
1005 | Arch::Msp430
1006 | Arch::PowerPC64LE
1007 | Arch::SpirV
1008 | Arch::Xtensa
1009 | Arch::Other(_) => &[],
1010 }
1011 }
1012
1013 pub fn tied_target_features(&self) -> &'static [&'static [&'static str]] {
1014 match &self.arch {
1015 Arch::AArch64 | Arch::Arm64EC => AARCH64_TIED_FEATURES,
1016 _ => &[],
1017 }
1018 }
1019
1020 pub fn implied_target_features<'a>(&self, base_feature: &'a str) -> FxHashSet<&'a str> {
1022 let implied_features =
1023 self.rust_target_features().iter().map(|(f, _, i)| (f, i)).collect::<FxHashMap<_, _>>();
1024
1025 let mut features = FxHashSet::default();
1028 let mut new_features = vec![base_feature];
1029 while let Some(new_feature) = new_features.pop() {
1030 if features.insert(new_feature) {
1031 if let Some(implied_features) = implied_features.get(&new_feature) {
1032 new_features.extend(implied_features.iter().copied())
1033 }
1034 }
1035 }
1036 features
1037 }
1038
1039 pub fn abi_required_features(&self) -> FeatureConstraints {
1050 const NOTHING: FeatureConstraints = FeatureConstraints { required: &[], incompatible: &[] };
1051 match &self.arch {
1056 Arch::X86 => {
1057 match self.rustc_abi {
1060 None => {
1061 FeatureConstraints { required: &["x87"], incompatible: &["soft-float"] }
1064 }
1065 Some(RustcAbi::X86Sse2) => {
1066 FeatureConstraints {
1068 required: &["x87", "sse2"],
1069 incompatible: &["soft-float"],
1070 }
1071 }
1072 Some(RustcAbi::X86Softfloat) => {
1073 FeatureConstraints { required: &["soft-float"], incompatible: &[] }
1078 }
1079 }
1080 }
1081 Arch::X86_64 => {
1082 match self.rustc_abi {
1085 None => {
1086 FeatureConstraints {
1088 required: &["x87", "sse2"],
1089 incompatible: &["soft-float"],
1090 }
1091 }
1092 Some(RustcAbi::X86Softfloat) => {
1093 FeatureConstraints { required: &["soft-float"], incompatible: &[] }
1098 }
1099 Some(r) => panic!("invalid Rust ABI for x86_64: {r:?}"),
1100 }
1101 }
1102 Arch::Arm => {
1103 match self.llvm_floatabi.unwrap() {
1106 FloatAbi::Soft => {
1107 NOTHING
1112 }
1113 FloatAbi::Hard => {
1114 FeatureConstraints { required: &["fpregs"], incompatible: &["soft-float"] }
1116 }
1117 }
1118 }
1119 Arch::AArch64 | Arch::Arm64EC => {
1120 if matches!(self.abi, Abi::SoftFloat) {
1123 FeatureConstraints { required: &[], incompatible: &["neon"] }
1129 } else {
1130 FeatureConstraints { required: &["neon"], incompatible: &[] }
1133 }
1134 }
1135 Arch::RiscV32 | Arch::RiscV64 => {
1136 match &*self.llvm_abiname {
1139 "ilp32d" | "lp64d" => {
1140 FeatureConstraints { required: &["d"], incompatible: &["e", "zfinx"] }
1142 }
1143 "ilp32f" | "lp64f" => {
1144 FeatureConstraints { required: &["f"], incompatible: &["e", "zfinx"] }
1146 }
1147 "ilp32" | "lp64" => {
1148 FeatureConstraints { required: &[], incompatible: &["e"] }
1150 }
1151 "ilp32e" => {
1152 FeatureConstraints { required: &[], incompatible: &["d"] }
1161 }
1162 "lp64e" => {
1163 NOTHING
1165 }
1166 _ => unreachable!(),
1167 }
1168 }
1169 Arch::LoongArch32 | Arch::LoongArch64 => {
1170 match &*self.llvm_abiname {
1173 "ilp32d" | "lp64d" => {
1174 FeatureConstraints { required: &["d"], incompatible: &[] }
1176 }
1177 "ilp32f" | "lp64f" => {
1178 FeatureConstraints { required: &["f"], incompatible: &[] }
1180 }
1181 "ilp32s" | "lp64s" => {
1182 NOTHING
1187 }
1188 _ => unreachable!(),
1189 }
1190 }
1191 Arch::S390x => {
1192 FeatureConstraints { required: &[], incompatible: &["soft-float"] }
1197 }
1198 _ => NOTHING,
1199 }
1200 }
1201}