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 ("gc", Unstable(sym::wasm_target_feature), &["reference-types"]),
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", Stable, &[]),
849 ("miscellaneous-extensions-3", Stable, &[]),
850 ("miscellaneous-extensions-4", Stable, &[]),
851 ("nnp-assist", Stable, &["vector"]),
852 ("soft-float", Forbidden { reason: "currently unsupported ABI-configuration feature" }, &[]),
853 ("transactional-execution", Unstable(sym::s390x_target_feature), &[]),
854 ("vector", Stable, &[]),
855 ("vector-enhancements-1", Stable, &["vector"]),
856 ("vector-enhancements-2", Stable, &["vector-enhancements-1"]),
857 ("vector-enhancements-3", Stable, &["vector-enhancements-2"]),
858 ("vector-packed-decimal", Stable, &["vector"]),
859 ("vector-packed-decimal-enhancement", Stable, &["vector-packed-decimal"]),
860 ("vector-packed-decimal-enhancement-2", Stable, &["vector-packed-decimal-enhancement"]),
861 ("vector-packed-decimal-enhancement-3", Stable, &["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_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
916 &[(128, "sse"), (256, "avx"), (512, "avx512f")]; const AARCH64_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
918 &[(128, "neon")];
919
920const ARM_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
922 &[(128, "neon")];
923
924const AMDGPU_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
925 &[(1024, "")];
926const POWERPC_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
927 &[(128, "altivec")];
928const WASM_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
929 &[(128, "simd128")];
930const S390X_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
931 &[(128, "vector")];
932const RISCV_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] = &[
933 (32, "zvl32b"),
934 (64, "zvl64b"),
935 (128, "zvl128b"),
936 (256, "zvl256b"),
937 (512, "zvl512b"),
938 (1024, "zvl1024b"),
939 (2048, "zvl2048b"),
940 (4096, "zvl4096b"),
941 (8192, "zvl8192b"),
942 (16384, "zvl16384b"),
943 (32768, "zvl32768b"),
944 (65536, "zvl65536b"),
945];
946const SPARC_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
948 &[];
949
950const HEXAGON_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
951 &[(1024, "hvx-length128b")];
952const MIPS_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
953 &[(128, "msa")];
954const CSKY_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
955 &[(128, "vdspv1")];
956const LOONGARCH_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
957 &[(128, "lsx"), (256, "lasx")];
958
959#[derive(Copy, Clone, Debug)]
960pub struct FeatureConstraints {
961 pub required: &'static [&'static str],
963 pub incompatible: &'static [&'static str],
965}
966
967impl Target {
968 pub fn rust_target_features(&self) -> &'static [(&'static str, Stability, ImpliedFeatures)] {
969 match &self.arch {
970 Arch::Arm => ARM_FEATURES,
971 Arch::AArch64 | Arch::Arm64EC => AARCH64_FEATURES,
972 Arch::X86 | Arch::X86_64 => X86_FEATURES,
973 Arch::Hexagon => HEXAGON_FEATURES,
974 Arch::Mips | Arch::Mips32r6 | Arch::Mips64 | Arch::Mips64r6 => MIPS_FEATURES,
975 Arch::Nvptx64 => NVPTX_FEATURES,
976 Arch::PowerPC | Arch::PowerPC64 => POWERPC_FEATURES,
977 Arch::RiscV32 | Arch::RiscV64 => RISCV_FEATURES,
978 Arch::Wasm32 | Arch::Wasm64 => WASM_FEATURES,
979 Arch::Bpf => BPF_FEATURES,
980 Arch::CSky => CSKY_FEATURES,
981 Arch::LoongArch32 | Arch::LoongArch64 => LOONGARCH_FEATURES,
982 Arch::S390x => IBMZ_FEATURES,
983 Arch::Sparc | Arch::Sparc64 => SPARC_FEATURES,
984 Arch::M68k => M68K_FEATURES,
985 Arch::AmdGpu
986 | Arch::Avr
987 | Arch::Msp430
988 | Arch::PowerPC64LE
989 | Arch::SpirV
990 | Arch::Xtensa
991 | Arch::Other(_) => &[],
992 }
993 }
994
995 pub fn features_for_correct_fixed_length_vector_abi(&self) -> &'static [(u64, &'static str)] {
996 match &self.arch {
997 Arch::X86 | Arch::X86_64 => X86_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
998 Arch::AArch64 | Arch::Arm64EC => AARCH64_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
999 Arch::Arm => ARM_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1000 Arch::PowerPC | Arch::PowerPC64 => POWERPC_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1001 Arch::LoongArch32 | Arch::LoongArch64 => {
1002 LOONGARCH_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI
1003 }
1004 Arch::RiscV32 | Arch::RiscV64 => RISCV_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1005 Arch::Wasm32 | Arch::Wasm64 => WASM_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1006 Arch::S390x => S390X_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1007 Arch::Sparc | Arch::Sparc64 => SPARC_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1008 Arch::Hexagon => HEXAGON_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1009 Arch::Mips | Arch::Mips32r6 | Arch::Mips64 | Arch::Mips64r6 => {
1010 MIPS_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI
1011 }
1012 Arch::AmdGpu => AMDGPU_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1013 Arch::Nvptx64 | Arch::Bpf | Arch::M68k => &[], Arch::CSky => CSKY_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1015 Arch::Avr
1018 | Arch::Msp430
1019 | Arch::PowerPC64LE
1020 | Arch::SpirV
1021 | Arch::Xtensa
1022 | Arch::Other(_) => &[],
1023 }
1024 }
1025
1026 pub fn features_for_correct_scalable_vector_abi(&self) -> Option<&'static str> {
1027 match &self.arch {
1028 Arch::AArch64 | Arch::Arm64EC => Some("sve"),
1029 _ => None,
1031 }
1032 }
1033
1034 pub fn tied_target_features(&self) -> &'static [&'static [&'static str]] {
1035 match &self.arch {
1036 Arch::AArch64 | Arch::Arm64EC => AARCH64_TIED_FEATURES,
1037 _ => &[],
1038 }
1039 }
1040
1041 pub fn implied_target_features<'a>(&self, base_feature: &'a str) -> FxHashSet<&'a str> {
1043 let implied_features =
1044 self.rust_target_features().iter().map(|(f, _, i)| (f, i)).collect::<FxHashMap<_, _>>();
1045
1046 let mut features = FxHashSet::default();
1049 let mut new_features = vec![base_feature];
1050 while let Some(new_feature) = new_features.pop() {
1051 if features.insert(new_feature) {
1052 if let Some(implied_features) = implied_features.get(&new_feature) {
1053 new_features.extend(implied_features.iter().copied())
1054 }
1055 }
1056 }
1057 features
1058 }
1059
1060 pub fn abi_required_features(&self) -> FeatureConstraints {
1071 const NOTHING: FeatureConstraints = FeatureConstraints { required: &[], incompatible: &[] };
1072 match &self.arch {
1077 Arch::X86 => {
1078 match self.rustc_abi {
1081 None => {
1082 FeatureConstraints { required: &["x87"], incompatible: &["soft-float"] }
1085 }
1086 Some(RustcAbi::X86Sse2) => {
1087 FeatureConstraints {
1089 required: &["x87", "sse2"],
1090 incompatible: &["soft-float"],
1091 }
1092 }
1093 Some(RustcAbi::X86Softfloat) => {
1094 FeatureConstraints { required: &["soft-float"], incompatible: &[] }
1099 }
1100 }
1101 }
1102 Arch::X86_64 => {
1103 match self.rustc_abi {
1106 None => {
1107 FeatureConstraints {
1109 required: &["x87", "sse2"],
1110 incompatible: &["soft-float"],
1111 }
1112 }
1113 Some(RustcAbi::X86Softfloat) => {
1114 FeatureConstraints { required: &["soft-float"], incompatible: &[] }
1119 }
1120 Some(r) => panic!("invalid Rust ABI for x86_64: {r:?}"),
1121 }
1122 }
1123 Arch::Arm => {
1124 match self.llvm_floatabi.unwrap() {
1127 FloatAbi::Soft => {
1128 NOTHING
1133 }
1134 FloatAbi::Hard => {
1135 FeatureConstraints { required: &["fpregs"], incompatible: &["soft-float"] }
1137 }
1138 }
1139 }
1140 Arch::AArch64 | Arch::Arm64EC => {
1141 if matches!(self.abi, Abi::SoftFloat) {
1144 FeatureConstraints { required: &[], incompatible: &["neon"] }
1150 } else {
1151 FeatureConstraints { required: &["neon"], incompatible: &[] }
1154 }
1155 }
1156 Arch::RiscV32 | Arch::RiscV64 => {
1157 match &*self.llvm_abiname {
1160 "ilp32d" | "lp64d" => {
1161 FeatureConstraints { required: &["d"], incompatible: &["e", "zfinx"] }
1163 }
1164 "ilp32f" | "lp64f" => {
1165 FeatureConstraints { required: &["f"], incompatible: &["e", "zfinx"] }
1167 }
1168 "ilp32" | "lp64" => {
1169 FeatureConstraints { required: &[], incompatible: &["e"] }
1171 }
1172 "ilp32e" => {
1173 FeatureConstraints { required: &[], incompatible: &["d"] }
1182 }
1183 "lp64e" => {
1184 NOTHING
1186 }
1187 _ => unreachable!(),
1188 }
1189 }
1190 Arch::LoongArch32 | Arch::LoongArch64 => {
1191 match &*self.llvm_abiname {
1194 "ilp32d" | "lp64d" => {
1195 FeatureConstraints { required: &["d"], incompatible: &[] }
1197 }
1198 "ilp32f" | "lp64f" => {
1199 FeatureConstraints { required: &["f"], incompatible: &[] }
1201 }
1202 "ilp32s" | "lp64s" => {
1203 NOTHING
1208 }
1209 _ => unreachable!(),
1210 }
1211 }
1212 Arch::S390x => {
1213 FeatureConstraints { required: &[], incompatible: &["soft-float"] }
1218 }
1219 _ => NOTHING,
1220 }
1221 }
1222}