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_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
915 &[(128, "sse"), (256, "avx"), (512, "avx512f")]; const AARCH64_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
917 &[(128, "neon")];
918
919const ARM_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
921 &[(128, "neon")];
922
923const AMDGPU_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
924 &[(1024, "")];
925const POWERPC_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
926 &[(128, "altivec")];
927const WASM_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
928 &[(128, "simd128")];
929const S390X_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
930 &[(128, "vector")];
931const RISCV_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] = &[
932 (32, "zvl32b"),
933 (64, "zvl64b"),
934 (128, "zvl128b"),
935 (256, "zvl256b"),
936 (512, "zvl512b"),
937 (1024, "zvl1024b"),
938 (2048, "zvl2048b"),
939 (4096, "zvl4096b"),
940 (8192, "zvl8192b"),
941 (16384, "zvl16384b"),
942 (32768, "zvl32768b"),
943 (65536, "zvl65536b"),
944];
945const SPARC_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
947 &[];
948
949const HEXAGON_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
950 &[(1024, "hvx-length128b")];
951const MIPS_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
952 &[(128, "msa")];
953const CSKY_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
954 &[(128, "vdspv1")];
955const LOONGARCH_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] =
956 &[(128, "lsx"), (256, "lasx")];
957
958#[derive(Copy, Clone, Debug)]
959pub struct FeatureConstraints {
960 pub required: &'static [&'static str],
962 pub incompatible: &'static [&'static str],
964}
965
966impl Target {
967 pub fn rust_target_features(&self) -> &'static [(&'static str, Stability, ImpliedFeatures)] {
968 match &self.arch {
969 Arch::Arm => ARM_FEATURES,
970 Arch::AArch64 | Arch::Arm64EC => AARCH64_FEATURES,
971 Arch::X86 | Arch::X86_64 => X86_FEATURES,
972 Arch::Hexagon => HEXAGON_FEATURES,
973 Arch::Mips | Arch::Mips32r6 | Arch::Mips64 | Arch::Mips64r6 => MIPS_FEATURES,
974 Arch::Nvptx64 => NVPTX_FEATURES,
975 Arch::PowerPC | Arch::PowerPC64 => POWERPC_FEATURES,
976 Arch::RiscV32 | Arch::RiscV64 => RISCV_FEATURES,
977 Arch::Wasm32 | Arch::Wasm64 => WASM_FEATURES,
978 Arch::Bpf => BPF_FEATURES,
979 Arch::CSky => CSKY_FEATURES,
980 Arch::LoongArch32 | Arch::LoongArch64 => LOONGARCH_FEATURES,
981 Arch::S390x => IBMZ_FEATURES,
982 Arch::Sparc | Arch::Sparc64 => SPARC_FEATURES,
983 Arch::M68k => M68K_FEATURES,
984 Arch::AmdGpu
985 | Arch::Avr
986 | Arch::Msp430
987 | Arch::PowerPC64LE
988 | Arch::SpirV
989 | Arch::Xtensa
990 | Arch::Other(_) => &[],
991 }
992 }
993
994 pub fn features_for_correct_fixed_length_vector_abi(&self) -> &'static [(u64, &'static str)] {
995 match &self.arch {
996 Arch::X86 | Arch::X86_64 => X86_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
997 Arch::AArch64 | Arch::Arm64EC => AARCH64_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
998 Arch::Arm => ARM_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
999 Arch::PowerPC | Arch::PowerPC64 => POWERPC_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1000 Arch::LoongArch32 | Arch::LoongArch64 => {
1001 LOONGARCH_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI
1002 }
1003 Arch::RiscV32 | Arch::RiscV64 => RISCV_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1004 Arch::Wasm32 | Arch::Wasm64 => WASM_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1005 Arch::S390x => S390X_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1006 Arch::Sparc | Arch::Sparc64 => SPARC_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1007 Arch::Hexagon => HEXAGON_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1008 Arch::Mips | Arch::Mips32r6 | Arch::Mips64 | Arch::Mips64r6 => {
1009 MIPS_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI
1010 }
1011 Arch::AmdGpu => AMDGPU_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1012 Arch::Nvptx64 | Arch::Bpf | Arch::M68k => &[], Arch::CSky => CSKY_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI,
1014 Arch::Avr
1017 | Arch::Msp430
1018 | Arch::PowerPC64LE
1019 | Arch::SpirV
1020 | Arch::Xtensa
1021 | Arch::Other(_) => &[],
1022 }
1023 }
1024
1025 pub fn features_for_correct_scalable_vector_abi(&self) -> Option<&'static str> {
1026 match &self.arch {
1027 Arch::AArch64 | Arch::Arm64EC => Some("sve"),
1028 _ => None,
1030 }
1031 }
1032
1033 pub fn tied_target_features(&self) -> &'static [&'static [&'static str]] {
1034 match &self.arch {
1035 Arch::AArch64 | Arch::Arm64EC => AARCH64_TIED_FEATURES,
1036 _ => &[],
1037 }
1038 }
1039
1040 pub fn implied_target_features<'a>(&self, base_feature: &'a str) -> FxHashSet<&'a str> {
1042 let implied_features =
1043 self.rust_target_features().iter().map(|(f, _, i)| (f, i)).collect::<FxHashMap<_, _>>();
1044
1045 let mut features = FxHashSet::default();
1048 let mut new_features = vec![base_feature];
1049 while let Some(new_feature) = new_features.pop() {
1050 if features.insert(new_feature) {
1051 if let Some(implied_features) = implied_features.get(&new_feature) {
1052 new_features.extend(implied_features.iter().copied())
1053 }
1054 }
1055 }
1056 features
1057 }
1058
1059 pub fn abi_required_features(&self) -> FeatureConstraints {
1070 const NOTHING: FeatureConstraints = FeatureConstraints { required: &[], incompatible: &[] };
1071 match &self.arch {
1076 Arch::X86 => {
1077 match self.rustc_abi {
1080 None => {
1081 FeatureConstraints { required: &["x87"], incompatible: &["soft-float"] }
1084 }
1085 Some(RustcAbi::X86Sse2) => {
1086 FeatureConstraints {
1088 required: &["x87", "sse2"],
1089 incompatible: &["soft-float"],
1090 }
1091 }
1092 Some(RustcAbi::X86Softfloat) => {
1093 FeatureConstraints { required: &["soft-float"], incompatible: &[] }
1098 }
1099 }
1100 }
1101 Arch::X86_64 => {
1102 match self.rustc_abi {
1105 None => {
1106 FeatureConstraints {
1108 required: &["x87", "sse2"],
1109 incompatible: &["soft-float"],
1110 }
1111 }
1112 Some(RustcAbi::X86Softfloat) => {
1113 FeatureConstraints { required: &["soft-float"], incompatible: &[] }
1118 }
1119 Some(r) => panic!("invalid Rust ABI for x86_64: {r:?}"),
1120 }
1121 }
1122 Arch::Arm => {
1123 match self.llvm_floatabi.unwrap() {
1126 FloatAbi::Soft => {
1127 NOTHING
1132 }
1133 FloatAbi::Hard => {
1134 FeatureConstraints { required: &["fpregs"], incompatible: &["soft-float"] }
1136 }
1137 }
1138 }
1139 Arch::AArch64 | Arch::Arm64EC => {
1140 if matches!(self.abi, Abi::SoftFloat) {
1143 FeatureConstraints { required: &[], incompatible: &["neon"] }
1149 } else {
1150 FeatureConstraints { required: &["neon"], incompatible: &[] }
1153 }
1154 }
1155 Arch::RiscV32 | Arch::RiscV64 => {
1156 match &*self.llvm_abiname {
1159 "ilp32d" | "lp64d" => {
1160 FeatureConstraints { required: &["d"], incompatible: &["e", "zfinx"] }
1162 }
1163 "ilp32f" | "lp64f" => {
1164 FeatureConstraints { required: &["f"], incompatible: &["e", "zfinx"] }
1166 }
1167 "ilp32" | "lp64" => {
1168 FeatureConstraints { required: &[], incompatible: &["e"] }
1170 }
1171 "ilp32e" => {
1172 FeatureConstraints { required: &[], incompatible: &["d"] }
1181 }
1182 "lp64e" => {
1183 NOTHING
1185 }
1186 _ => unreachable!(),
1187 }
1188 }
1189 Arch::LoongArch32 | Arch::LoongArch64 => {
1190 match &*self.llvm_abiname {
1193 "ilp32d" | "lp64d" => {
1194 FeatureConstraints { required: &["d"], incompatible: &[] }
1196 }
1197 "ilp32f" | "lp64f" => {
1198 FeatureConstraints { required: &["f"], incompatible: &[] }
1200 }
1201 "ilp32s" | "lp64s" => {
1202 NOTHING
1207 }
1208 _ => unreachable!(),
1209 }
1210 }
1211 Arch::S390x => {
1212 FeatureConstraints { required: &[], incompatible: &["soft-float"] }
1217 }
1218 _ => NOTHING,
1219 }
1220 }
1221}