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, &["zkne_or_zknd"]),
694 ("zkne", Stable, &["zkne_or_zknd"]),
695 ("zkne_or_zknd", Unstable(sym::riscv_target_feature), &[]), ("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 ("gc", Unstable(sym::wasm_target_feature), &["reference-types"]),
750 ("multivalue", Stable, &[]),
751 ("mutable-globals", Stable, &[]),
752 ("nontrapping-fptoint", Stable, &[]),
753 ("reference-types", Stable, &[]),
754 ("relaxed-simd", Stable, &["simd128"]),
755 ("sign-ext", Stable, &[]),
756 ("simd128", Stable, &[]),
757 ("tail-call", Stable, &[]),
758 ("wide-arithmetic", Unstable(sym::wasm_target_feature), &[]),
759 ];
761
762const BPF_FEATURES: &[(&str, Stability, ImpliedFeatures)] =
763 &[("alu32", Unstable(sym::bpf_target_feature), &[])];
764
765static CSKY_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
766 ("2e3", Unstable(sym::csky_target_feature), &["e2"]),
768 ("3e3r1", Unstable(sym::csky_target_feature), &[]),
769 ("3e3r2", Unstable(sym::csky_target_feature), &["3e3r1", "doloop"]),
770 ("3e3r3", Unstable(sym::csky_target_feature), &["doloop"]),
771 ("3e7", Unstable(sym::csky_target_feature), &["2e3"]),
772 ("7e10", Unstable(sym::csky_target_feature), &["3e7"]),
773 ("10e60", Unstable(sym::csky_target_feature), &["7e10"]),
774 ("cache", Unstable(sym::csky_target_feature), &[]),
775 ("doloop", Unstable(sym::csky_target_feature), &[]),
776 ("dsp1e2", Unstable(sym::csky_target_feature), &[]),
777 ("dspe60", Unstable(sym::csky_target_feature), &[]),
778 ("e1", Unstable(sym::csky_target_feature), &["elrw"]),
779 ("e2", Unstable(sym::csky_target_feature), &["e2"]),
780 ("edsp", Unstable(sym::csky_target_feature), &[]),
781 ("elrw", Unstable(sym::csky_target_feature), &[]),
782 ("float1e2", Unstable(sym::csky_target_feature), &[]),
783 ("float1e3", Unstable(sym::csky_target_feature), &[]),
784 ("float3e4", Unstable(sym::csky_target_feature), &[]),
785 ("float7e60", Unstable(sym::csky_target_feature), &[]),
786 ("floate1", Unstable(sym::csky_target_feature), &[]),
787 ("hard-tp", Unstable(sym::csky_target_feature), &[]),
788 ("high-registers", Unstable(sym::csky_target_feature), &[]),
789 ("hwdiv", Unstable(sym::csky_target_feature), &[]),
790 ("mp", Unstable(sym::csky_target_feature), &["2e3"]),
791 ("mp1e2", Unstable(sym::csky_target_feature), &["3e7"]),
792 ("nvic", Unstable(sym::csky_target_feature), &[]),
793 ("trust", Unstable(sym::csky_target_feature), &[]),
794 ("vdsp2e60f", Unstable(sym::csky_target_feature), &[]),
795 ("vdspv1", Unstable(sym::csky_target_feature), &[]),
796 ("vdspv2", Unstable(sym::csky_target_feature), &[]),
797 ("fdivdu", Unstable(sym::csky_target_feature), &[]),
801 ("fpuv2_df", Unstable(sym::csky_target_feature), &[]),
802 ("fpuv2_sf", Unstable(sym::csky_target_feature), &[]),
803 ("fpuv3_df", Unstable(sym::csky_target_feature), &[]),
804 ("fpuv3_hf", Unstable(sym::csky_target_feature), &[]),
805 ("fpuv3_hi", Unstable(sym::csky_target_feature), &[]),
806 ("fpuv3_sf", Unstable(sym::csky_target_feature), &[]),
807 ("hard-float", Unstable(sym::csky_target_feature), &[]),
808 ("hard-float-abi", Unstable(sym::csky_target_feature), &[]),
809 ];
811
812static LOONGARCH_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
813 ("32s", Unstable(sym::loongarch_target_feature), &[]),
815 ("d", Stable, &["f"]),
816 ("div32", Unstable(sym::loongarch_target_feature), &[]),
817 ("f", Stable, &[]),
818 ("frecipe", Stable, &[]),
819 ("lam-bh", Unstable(sym::loongarch_target_feature), &[]),
820 ("lamcas", Unstable(sym::loongarch_target_feature), &[]),
821 ("lasx", Stable, &["lsx"]),
822 ("lbt", Stable, &[]),
823 ("ld-seq-sa", Unstable(sym::loongarch_target_feature), &[]),
824 ("lsx", Stable, &["d"]),
825 ("lvz", Stable, &[]),
826 ("relax", Unstable(sym::loongarch_target_feature), &[]),
827 ("scq", Unstable(sym::loongarch_target_feature), &[]),
828 ("ual", Unstable(sym::loongarch_target_feature), &[]),
829 ];
831
832#[rustfmt::skip]
833const IBMZ_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
834 ("backchain", Unstable(sym::s390x_target_feature), &[]),
837 ("concurrent-functions", Unstable(sym::s390x_target_feature), &[]),
838 ("deflate-conversion", Unstable(sym::s390x_target_feature), &[]),
839 ("enhanced-sort", Unstable(sym::s390x_target_feature), &[]),
840 ("guarded-storage", Unstable(sym::s390x_target_feature), &[]),
841 ("high-word", Unstable(sym::s390x_target_feature), &[]),
842 ("message-security-assist-extension3", Unstable(sym::s390x_target_feature), &[]),
844 ("message-security-assist-extension4", Unstable(sym::s390x_target_feature), &[]),
845 ("message-security-assist-extension5", Unstable(sym::s390x_target_feature), &[]),
846 ("message-security-assist-extension8", Unstable(sym::s390x_target_feature), &["message-security-assist-extension3"]),
847 ("message-security-assist-extension9", Unstable(sym::s390x_target_feature), &["message-security-assist-extension3", "message-security-assist-extension4"]),
848 ("message-security-assist-extension12", Unstable(sym::s390x_target_feature), &[]),
849 ("miscellaneous-extensions-2", Stable, &[]),
850 ("miscellaneous-extensions-3", Stable, &[]),
851 ("miscellaneous-extensions-4", Stable, &[]),
852 ("nnp-assist", Stable, &["vector"]),
853 ("soft-float", Forbidden { reason: "currently unsupported ABI-configuration feature" }, &[]),
854 ("transactional-execution", Unstable(sym::s390x_target_feature), &[]),
855 ("vector", Stable, &[]),
856 ("vector-enhancements-1", Stable, &["vector"]),
857 ("vector-enhancements-2", Stable, &["vector-enhancements-1"]),
858 ("vector-enhancements-3", Stable, &["vector-enhancements-2"]),
859 ("vector-packed-decimal", Stable, &["vector"]),
860 ("vector-packed-decimal-enhancement", Stable, &["vector-packed-decimal"]),
861 ("vector-packed-decimal-enhancement-2", Stable, &["vector-packed-decimal-enhancement"]),
862 ("vector-packed-decimal-enhancement-3", Stable, &["vector-packed-decimal-enhancement-2"]),
863 ];
865
866const SPARC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
867 ("leoncasa", Unstable(sym::sparc_target_feature), &[]),
869 ("v8plus", Unstable(sym::sparc_target_feature), &[]),
870 ("v9", Unstable(sym::sparc_target_feature), &[]),
871 ];
873
874static M68K_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
875 ("isa-68000", Unstable(sym::m68k_target_feature), &[]),
877 ("isa-68010", Unstable(sym::m68k_target_feature), &["isa-68000"]),
878 ("isa-68020", Unstable(sym::m68k_target_feature), &["isa-68010"]),
879 ("isa-68030", Unstable(sym::m68k_target_feature), &["isa-68020"]),
880 ("isa-68040", Unstable(sym::m68k_target_feature), &["isa-68030", "isa-68882"]),
881 ("isa-68060", Unstable(sym::m68k_target_feature), &["isa-68040"]),
882 ("isa-68881", Unstable(sym::m68k_target_feature), &[]),
884 ("isa-68882", Unstable(sym::m68k_target_feature), &["isa-68881"]),
885 ];
887
888pub fn all_rust_features() -> impl Iterator<Item = (&'static str, Stability)> {
893 std::iter::empty()
894 .chain(ARM_FEATURES.iter())
895 .chain(AARCH64_FEATURES.iter())
896 .chain(X86_FEATURES.iter())
897 .chain(HEXAGON_FEATURES.iter())
898 .chain(POWERPC_FEATURES.iter())
899 .chain(MIPS_FEATURES.iter())
900 .chain(NVPTX_FEATURES.iter())
901 .chain(RISCV_FEATURES.iter())
902 .chain(WASM_FEATURES.iter())
903 .chain(BPF_FEATURES.iter())
904 .chain(CSKY_FEATURES)
905 .chain(LOONGARCH_FEATURES)
906 .chain(IBMZ_FEATURES)
907 .chain(SPARC_FEATURES)
908 .chain(M68K_FEATURES)
909 .cloned()
910 .map(|(f, s, _)| (f, s))
911}
912
913const X86_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
917 &[(128, "sse"), (256, "avx"), (512, "avx512f")]; const AARCH64_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
919 &[(128, "neon")];
920
921const ARM_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
923 &[(128, "neon")];
924
925const AMDGPU_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
926 &[(1024, "")];
927const POWERPC_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
928 &[(128, "altivec")];
929const WASM_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
930 &[(128, "simd128")];
931const S390X_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
932 &[(128, "vector")];
933const RISCV_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] = &[
934 (32, "zvl32b"),
935 (64, "zvl64b"),
936 (128, "zvl128b"),
937 (256, "zvl256b"),
938 (512, "zvl512b"),
939 (1024, "zvl1024b"),
940 (2048, "zvl2048b"),
941 (4096, "zvl4096b"),
942 (8192, "zvl8192b"),
943 (16384, "zvl16384b"),
944 (32768, "zvl32768b"),
945 (65536, "zvl65536b"),
946];
947const SPARC_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
949 &[];
950
951const HEXAGON_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
952 &[(1024, "hvx-length128b")];
953const MIPS_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
954 &[(128, "msa")];
955const CSKY_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
956 &[(128, "vdspv1")];
957const LOONGARCH_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
958 &[(128, "lsx"), (256, "lasx")];
959
960#[derive(Copy, Clone, Debug)]
961pub struct FeatureConstraints {
962 pub required: &'static [&'static str],
964 pub incompatible: &'static [&'static str],
966}
967
968impl Target {
969 pub fn rust_target_features(&self) -> &'static [(&'static str, Stability, ImpliedFeatures)] {
970 match &self.arch {
971 Arch::Arm => ARM_FEATURES,
972 Arch::AArch64 | Arch::Arm64EC => AARCH64_FEATURES,
973 Arch::X86 | Arch::X86_64 => X86_FEATURES,
974 Arch::Hexagon => HEXAGON_FEATURES,
975 Arch::Mips | Arch::Mips32r6 | Arch::Mips64 | Arch::Mips64r6 => MIPS_FEATURES,
976 Arch::Nvptx64 => NVPTX_FEATURES,
977 Arch::PowerPC | Arch::PowerPC64 => POWERPC_FEATURES,
978 Arch::RiscV32 | Arch::RiscV64 => RISCV_FEATURES,
979 Arch::Wasm32 | Arch::Wasm64 => WASM_FEATURES,
980 Arch::Bpf => BPF_FEATURES,
981 Arch::CSky => CSKY_FEATURES,
982 Arch::LoongArch32 | Arch::LoongArch64 => LOONGARCH_FEATURES,
983 Arch::S390x => IBMZ_FEATURES,
984 Arch::Sparc | Arch::Sparc64 => SPARC_FEATURES,
985 Arch::M68k => M68K_FEATURES,
986 Arch::AmdGpu
987 | Arch::Avr
988 | Arch::Msp430
989 | Arch::PowerPC64LE
990 | Arch::SpirV
991 | Arch::Xtensa
992 | Arch::Other(_) => &[],
993 }
994 }
995
996 pub fn features_for_correct_fixed_length_vector_abi(&self) -> &'static [(u64, &'static str)] {
997 match &self.arch {
998 Arch::X86 | Arch::X86_64 => X86_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
999 Arch::AArch64 | Arch::Arm64EC => AARCH64_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1000 Arch::Arm => ARM_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1001 Arch::PowerPC | Arch::PowerPC64 => POWERPC_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1002 Arch::LoongArch32 | Arch::LoongArch64 => {
1003 LOONGARCH_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI
1004 }
1005 Arch::RiscV32 | Arch::RiscV64 => RISCV_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1006 Arch::Wasm32 | Arch::Wasm64 => WASM_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1007 Arch::S390x => S390X_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1008 Arch::Sparc | Arch::Sparc64 => SPARC_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1009 Arch::Hexagon => HEXAGON_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1010 Arch::Mips | Arch::Mips32r6 | Arch::Mips64 | Arch::Mips64r6 => {
1011 MIPS_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI
1012 }
1013 Arch::AmdGpu => AMDGPU_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1014 Arch::Nvptx64 | Arch::Bpf | Arch::M68k => &[], Arch::CSky => CSKY_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1016 Arch::Avr
1019 | Arch::Msp430
1020 | Arch::PowerPC64LE
1021 | Arch::SpirV
1022 | Arch::Xtensa
1023 | Arch::Other(_) => &[],
1024 }
1025 }
1026
1027 pub fn features_for_correct_scalable_vector_abi(&self) -> Option<&'static str> {
1028 match &self.arch {
1029 Arch::AArch64 | Arch::Arm64EC => Some("sve"),
1030 _ => None,
1032 }
1033 }
1034
1035 pub fn tied_target_features(&self) -> &'static [&'static [&'static str]] {
1036 match &self.arch {
1037 Arch::AArch64 | Arch::Arm64EC => AARCH64_TIED_FEATURES,
1038 _ => &[],
1039 }
1040 }
1041
1042 pub fn implied_target_features<'a>(&self, base_feature: &'a str) -> FxHashSet<&'a str> {
1044 let implied_features =
1045 self.rust_target_features().iter().map(|(f, _, i)| (f, i)).collect::<FxHashMap<_, _>>();
1046
1047 let mut features = FxHashSet::default();
1050 let mut new_features = vec![base_feature];
1051 while let Some(new_feature) = new_features.pop() {
1052 if features.insert(new_feature) {
1053 if let Some(implied_features) = implied_features.get(&new_feature) {
1054 new_features.extend(implied_features.iter().copied())
1055 }
1056 }
1057 }
1058 features
1059 }
1060
1061 pub fn abi_required_features(&self) -> FeatureConstraints {
1072 const NOTHING: FeatureConstraints = FeatureConstraints { required: &[], incompatible: &[] };
1073 match &self.arch {
1078 Arch::X86 => {
1079 match self.rustc_abi {
1082 None => {
1083 FeatureConstraints { required: &["x87"], incompatible: &["soft-float"] }
1086 }
1087 Some(RustcAbi::X86Sse2) => {
1088 FeatureConstraints {
1090 required: &["x87", "sse2"],
1091 incompatible: &["soft-float"],
1092 }
1093 }
1094 Some(RustcAbi::X86Softfloat) => {
1095 FeatureConstraints { required: &["soft-float"], incompatible: &[] }
1100 }
1101 }
1102 }
1103 Arch::X86_64 => {
1104 match self.rustc_abi {
1107 None => {
1108 FeatureConstraints {
1110 required: &["x87", "sse2"],
1111 incompatible: &["soft-float"],
1112 }
1113 }
1114 Some(RustcAbi::X86Softfloat) => {
1115 FeatureConstraints { required: &["soft-float"], incompatible: &[] }
1120 }
1121 Some(r) => panic!("invalid Rust ABI for x86_64: {r:?}"),
1122 }
1123 }
1124 Arch::Arm => {
1125 match self.llvm_floatabi.unwrap() {
1128 FloatAbi::Soft => {
1129 NOTHING
1134 }
1135 FloatAbi::Hard => {
1136 FeatureConstraints { required: &["fpregs"], incompatible: &["soft-float"] }
1138 }
1139 }
1140 }
1141 Arch::AArch64 | Arch::Arm64EC => {
1142 if self.abi == Abi::SoftFloat {
1145 FeatureConstraints { required: &[], incompatible: &["neon"] }
1151 } else {
1152 FeatureConstraints { required: &["neon"], incompatible: &[] }
1155 }
1156 }
1157 Arch::RiscV32 | Arch::RiscV64 => {
1158 match &*self.llvm_abiname {
1161 "ilp32d" | "lp64d" => {
1162 FeatureConstraints { required: &["d"], incompatible: &["e", "zfinx"] }
1164 }
1165 "ilp32f" | "lp64f" => {
1166 FeatureConstraints { required: &["f"], incompatible: &["e", "zfinx"] }
1168 }
1169 "ilp32" | "lp64" => {
1170 FeatureConstraints { required: &[], incompatible: &["e"] }
1172 }
1173 "ilp32e" => {
1174 FeatureConstraints { required: &[], incompatible: &["d"] }
1183 }
1184 "lp64e" => {
1185 NOTHING
1187 }
1188 _ => unreachable!(),
1189 }
1190 }
1191 Arch::LoongArch32 | Arch::LoongArch64 => {
1192 match &*self.llvm_abiname {
1195 "ilp32d" | "lp64d" => {
1196 FeatureConstraints { required: &["d"], incompatible: &[] }
1198 }
1199 "ilp32f" | "lp64f" => {
1200 FeatureConstraints { required: &["f"], incompatible: &[] }
1202 }
1203 "ilp32s" | "lp64s" => {
1204 NOTHING
1209 }
1210 _ => unreachable!(),
1211 }
1212 }
1213 Arch::S390x => {
1214 FeatureConstraints { required: &[], incompatible: &["soft-float"] }
1219 }
1220 _ => NOTHING,
1221 }
1222 }
1223}