1use rustc_data_structures::fx::{FxHashMap, FxHashSet};
5use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
6use rustc_span::{Symbol, sym};
7
8use crate::spec::{FloatAbi, RustcAbi, Target};
9
10pub const RUSTC_SPECIFIC_FEATURES: &[&str] = &["crt-static"];
13
14pub const RUSTC_SPECIAL_FEATURES: &[&str] = &["backchain"];
18
19#[derive(Debug, Copy, Clone)]
21pub enum Stability {
22 Stable,
25 Unstable(
28 Symbol,
31 ),
32 Forbidden { reason: &'static str },
37}
38use Stability::*;
39
40impl<CTX> HashStable<CTX> for Stability {
41 #[inline]
42 fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
43 std::mem::discriminant(self).hash_stable(hcx, hasher);
44 match self {
45 Stability::Stable => {}
46 Stability::Unstable(nightly_feature) => {
47 nightly_feature.hash_stable(hcx, hasher);
48 }
49 Stability::Forbidden { reason } => {
50 reason.hash_stable(hcx, hasher);
51 }
52 }
53 }
54}
55
56impl Stability {
57 pub fn in_cfg(&self) -> bool {
61 !matches!(self, Stability::Forbidden { .. })
62 }
63
64 pub fn requires_nightly(&self) -> Option<Symbol> {
73 match *self {
74 Stability::Unstable(nightly_feature) => Some(nightly_feature),
75 Stability::Stable { .. } => None,
76 Stability::Forbidden { .. } => panic!("forbidden features should not reach this far"),
77 }
78 }
79
80 pub fn toggle_allowed(&self) -> Result<(), &'static str> {
84 match self {
85 Stability::Forbidden { reason } => Err(reason),
86 _ => Ok(()),
87 }
88 }
89}
90
91type ImpliedFeatures = &'static [&'static str];
133
134static ARM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
135 ("aclass", Unstable(sym::arm_target_feature), &[]),
137 ("aes", Unstable(sym::arm_target_feature), &["neon"]),
138 (
139 "atomics-32",
140 Stability::Forbidden { reason: "unsound because it changes the ABI of atomic operations" },
141 &[],
142 ),
143 ("crc", Unstable(sym::arm_target_feature), &[]),
144 ("d32", Unstable(sym::arm_target_feature), &[]),
145 ("dotprod", Unstable(sym::arm_target_feature), &["neon"]),
146 ("dsp", Unstable(sym::arm_target_feature), &[]),
147 ("fp-armv8", Unstable(sym::arm_target_feature), &["vfp4"]),
148 ("fp16", Unstable(sym::arm_target_feature), &["neon"]),
149 ("fpregs", Unstable(sym::arm_target_feature), &[]),
150 ("i8mm", Unstable(sym::arm_target_feature), &["neon"]),
151 ("mclass", Unstable(sym::arm_target_feature), &[]),
152 ("neon", Unstable(sym::arm_target_feature), &["vfp3"]),
153 ("rclass", Unstable(sym::arm_target_feature), &[]),
154 ("sha2", Unstable(sym::arm_target_feature), &["neon"]),
155 ("soft-float", Unstable(sym::arm_target_feature), &[]),
160 ("thumb-mode", Unstable(sym::arm_target_feature), &[]),
164 ("thumb2", Unstable(sym::arm_target_feature), &[]),
165 ("trustzone", Unstable(sym::arm_target_feature), &[]),
166 ("v5te", Unstable(sym::arm_target_feature), &[]),
167 ("v6", Unstable(sym::arm_target_feature), &["v5te"]),
168 ("v6k", Unstable(sym::arm_target_feature), &["v6"]),
169 ("v6t2", Unstable(sym::arm_target_feature), &["v6k", "thumb2"]),
170 ("v7", Unstable(sym::arm_target_feature), &["v6t2"]),
171 ("v8", Unstable(sym::arm_target_feature), &["v7"]),
172 ("vfp2", Unstable(sym::arm_target_feature), &[]),
173 ("vfp3", Unstable(sym::arm_target_feature), &["vfp2", "d32"]),
174 ("vfp4", Unstable(sym::arm_target_feature), &["vfp3"]),
175 ("virtualization", Unstable(sym::arm_target_feature), &[]),
176 ];
178
179static AARCH64_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
180 ("aes", Stable, &["neon"]),
183 ("bf16", Stable, &[]),
185 ("bti", Stable, &[]),
187 ("crc", Stable, &[]),
189 ("cssc", Unstable(sym::aarch64_unstable_target_feature), &[]),
191 ("dit", Stable, &[]),
193 ("dotprod", Stable, &["neon"]),
195 ("dpb", Stable, &[]),
197 ("dpb2", Stable, &["dpb"]),
199 ("ecv", Unstable(sym::aarch64_unstable_target_feature), &[]),
201 ("f32mm", Stable, &["sve"]),
203 ("f64mm", Stable, &["sve"]),
205 ("faminmax", Unstable(sym::aarch64_unstable_target_feature), &[]),
207 ("fcma", Stable, &["neon"]),
209 ("fhm", Stable, &["fp16"]),
211 ("flagm", Stable, &[]),
213 ("flagm2", Unstable(sym::aarch64_unstable_target_feature), &[]),
215 ("fp-armv8", Stability::Forbidden { reason: "Rust ties `fp-armv8` to `neon`" }, &[]),
217 ("fp16", Stable, &["neon"]),
220 ("fp8", Unstable(sym::aarch64_unstable_target_feature), &["faminmax", "lut", "bf16"]),
222 ("fp8dot2", Unstable(sym::aarch64_unstable_target_feature), &["fp8dot4"]),
224 ("fp8dot4", Unstable(sym::aarch64_unstable_target_feature), &["fp8fma"]),
226 ("fp8fma", Unstable(sym::aarch64_unstable_target_feature), &["fp8"]),
228 ("frintts", Stable, &[]),
230 ("hbc", Unstable(sym::aarch64_unstable_target_feature), &[]),
232 ("i8mm", Stable, &[]),
234 ("jsconv", Stable, &["neon"]),
237 ("lor", Stable, &[]),
239 ("lse", Stable, &[]),
241 ("lse128", Unstable(sym::aarch64_unstable_target_feature), &["lse"]),
243 ("lse2", Unstable(sym::aarch64_unstable_target_feature), &[]),
245 ("lut", Unstable(sym::aarch64_unstable_target_feature), &[]),
247 ("mops", Unstable(sym::aarch64_unstable_target_feature), &[]),
249 ("mte", Stable, &[]),
251 ("neon", Stable, &[]),
253 ("paca", Stable, &[]),
255 ("pacg", Stable, &[]),
257 ("pan", Stable, &[]),
259 ("pauth-lr", Unstable(sym::aarch64_unstable_target_feature), &[]),
261 ("pmuv3", Stable, &[]),
263 ("rand", Stable, &[]),
265 ("ras", Stable, &[]),
267 ("rcpc", Stable, &[]),
269 ("rcpc2", Stable, &["rcpc"]),
271 ("rcpc3", Unstable(sym::aarch64_unstable_target_feature), &["rcpc2"]),
273 ("rdm", Stable, &["neon"]),
275 ("reserve-x18", Unstable(sym::aarch64_unstable_target_feature), &[]),
281 ("sb", Stable, &[]),
283 ("sha2", Stable, &["neon"]),
285 ("sha3", Stable, &["sha2"]),
287 ("sm4", Stable, &["neon"]),
289 ("sme", Unstable(sym::aarch64_unstable_target_feature), &["bf16"]),
291 ("sme-b16b16", Unstable(sym::aarch64_unstable_target_feature), &["bf16", "sme2", "sve-b16b16"]),
293 ("sme-f16f16", Unstable(sym::aarch64_unstable_target_feature), &["sme2"]),
295 ("sme-f64f64", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
297 ("sme-f8f16", Unstable(sym::aarch64_unstable_target_feature), &["sme-f8f32"]),
299 ("sme-f8f32", Unstable(sym::aarch64_unstable_target_feature), &["sme2", "fp8"]),
301 ("sme-fa64", Unstable(sym::aarch64_unstable_target_feature), &["sme", "sve2"]),
303 ("sme-i16i64", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
305 ("sme-lutv2", Unstable(sym::aarch64_unstable_target_feature), &[]),
307 ("sme2", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
309 ("sme2p1", Unstable(sym::aarch64_unstable_target_feature), &["sme2"]),
311 ("spe", Stable, &[]),
313 ("ssbs", Stable, &[]),
315 ("ssve-fp8dot2", Unstable(sym::aarch64_unstable_target_feature), &["ssve-fp8dot4"]),
317 ("ssve-fp8dot4", Unstable(sym::aarch64_unstable_target_feature), &["ssve-fp8fma"]),
319 ("ssve-fp8fma", Unstable(sym::aarch64_unstable_target_feature), &["sme2", "fp8"]),
321 ("sve", Stable, &["neon"]),
329 ("sve-b16b16", Unstable(sym::aarch64_unstable_target_feature), &["bf16"]),
331 ("sve2", Stable, &["sve"]),
333 ("sve2-aes", Stable, &["sve2", "aes"]),
335 ("sve2-bitperm", Stable, &["sve2"]),
337 ("sve2-sha3", Stable, &["sve2", "sha3"]),
339 ("sve2-sm4", Stable, &["sve2", "sm4"]),
341 ("sve2p1", Unstable(sym::aarch64_unstable_target_feature), &["sve2"]),
343 ("tme", Stable, &[]),
345 (
346 "v8.1a",
347 Unstable(sym::aarch64_ver_target_feature),
348 &["crc", "lse", "rdm", "pan", "lor", "vh"],
349 ),
350 ("v8.2a", Unstable(sym::aarch64_ver_target_feature), &["v8.1a", "ras", "dpb"]),
351 (
352 "v8.3a",
353 Unstable(sym::aarch64_ver_target_feature),
354 &["v8.2a", "rcpc", "paca", "pacg", "jsconv"],
355 ),
356 ("v8.4a", Unstable(sym::aarch64_ver_target_feature), &["v8.3a", "dotprod", "dit", "flagm"]),
357 ("v8.5a", Unstable(sym::aarch64_ver_target_feature), &["v8.4a", "ssbs", "sb", "dpb2", "bti"]),
358 ("v8.6a", Unstable(sym::aarch64_ver_target_feature), &["v8.5a", "bf16", "i8mm"]),
359 ("v8.7a", Unstable(sym::aarch64_ver_target_feature), &["v8.6a", "wfxt"]),
360 ("v8.8a", Unstable(sym::aarch64_ver_target_feature), &["v8.7a", "hbc", "mops"]),
361 ("v8.9a", Unstable(sym::aarch64_ver_target_feature), &["v8.8a", "cssc"]),
362 ("v9.1a", Unstable(sym::aarch64_ver_target_feature), &["v9a", "v8.6a"]),
363 ("v9.2a", Unstable(sym::aarch64_ver_target_feature), &["v9.1a", "v8.7a"]),
364 ("v9.3a", Unstable(sym::aarch64_ver_target_feature), &["v9.2a", "v8.8a"]),
365 ("v9.4a", Unstable(sym::aarch64_ver_target_feature), &["v9.3a", "v8.9a"]),
366 ("v9.5a", Unstable(sym::aarch64_ver_target_feature), &["v9.4a"]),
367 ("v9a", Unstable(sym::aarch64_ver_target_feature), &["v8.5a", "sve2"]),
368 ("vh", Stable, &[]),
370 ("wfxt", Unstable(sym::aarch64_unstable_target_feature), &[]),
372 ];
374
375const AARCH64_TIED_FEATURES: &[&[&str]] = &[
376 &["paca", "pacg"], ];
378
379static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
380 ("adx", Stable, &[]),
382 ("aes", Stable, &["sse2"]),
383 ("amx-bf16", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
384 ("amx-complex", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
385 ("amx-fp16", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
386 ("amx-int8", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
387 ("amx-tile", Unstable(sym::x86_amx_intrinsics), &[]),
388 ("avx", Stable, &["sse4.2"]),
389 ("avx2", Stable, &["avx"]),
390 ("avx512bf16", Unstable(sym::avx512_target_feature), &["avx512bw"]),
391 ("avx512bitalg", Unstable(sym::avx512_target_feature), &["avx512bw"]),
392 ("avx512bw", Unstable(sym::avx512_target_feature), &["avx512f"]),
393 ("avx512cd", Unstable(sym::avx512_target_feature), &["avx512f"]),
394 ("avx512dq", Unstable(sym::avx512_target_feature), &["avx512f"]),
395 ("avx512f", Unstable(sym::avx512_target_feature), &["avx2", "fma", "f16c"]),
396 ("avx512fp16", Unstable(sym::avx512_target_feature), &["avx512bw", "avx512vl", "avx512dq"]),
397 ("avx512ifma", Unstable(sym::avx512_target_feature), &["avx512f"]),
398 ("avx512vbmi", Unstable(sym::avx512_target_feature), &["avx512bw"]),
399 ("avx512vbmi2", Unstable(sym::avx512_target_feature), &["avx512bw"]),
400 ("avx512vl", Unstable(sym::avx512_target_feature), &["avx512f"]),
401 ("avx512vnni", Unstable(sym::avx512_target_feature), &["avx512f"]),
402 ("avx512vp2intersect", Unstable(sym::avx512_target_feature), &["avx512f"]),
403 ("avx512vpopcntdq", Unstable(sym::avx512_target_feature), &["avx512f"]),
404 ("avxifma", Unstable(sym::avx512_target_feature), &["avx2"]),
405 ("avxneconvert", Unstable(sym::avx512_target_feature), &["avx2"]),
406 ("avxvnni", Unstable(sym::avx512_target_feature), &["avx2"]),
407 ("avxvnniint16", Unstable(sym::avx512_target_feature), &["avx2"]),
408 ("avxvnniint8", Unstable(sym::avx512_target_feature), &["avx2"]),
409 ("bmi1", Stable, &[]),
410 ("bmi2", Stable, &[]),
411 ("cmpxchg16b", Stable, &[]),
412 ("ermsb", Unstable(sym::ermsb_target_feature), &[]),
413 ("f16c", Stable, &["avx"]),
414 ("fma", Stable, &["avx"]),
415 ("fxsr", Stable, &[]),
416 ("gfni", Unstable(sym::avx512_target_feature), &["sse2"]),
417 ("kl", Unstable(sym::keylocker_x86), &["sse2"]),
418 ("lahfsahf", Unstable(sym::lahfsahf_target_feature), &[]),
419 ("lzcnt", Stable, &[]),
420 ("movbe", Stable, &[]),
421 ("pclmulqdq", Stable, &["sse2"]),
422 ("popcnt", Stable, &[]),
423 ("prfchw", Unstable(sym::prfchw_target_feature), &[]),
424 ("rdrand", Stable, &[]),
425 ("rdseed", Stable, &[]),
426 ("rtm", Unstable(sym::rtm_target_feature), &[]),
427 ("sha", Stable, &["sse2"]),
428 ("sha512", Unstable(sym::sha512_sm_x86), &["avx2"]),
429 ("sm3", Unstable(sym::sha512_sm_x86), &["avx"]),
430 ("sm4", Unstable(sym::sha512_sm_x86), &["avx2"]),
431 ("soft-float", Stability::Unstable(sym::x87_target_feature), &[]),
434 ("sse", Stable, &[]),
435 ("sse2", Stable, &["sse"]),
436 ("sse3", Stable, &["sse2"]),
437 ("sse4.1", Stable, &["ssse3"]),
438 ("sse4.2", Stable, &["sse4.1"]),
439 ("sse4a", Unstable(sym::sse4a_target_feature), &["sse3"]),
440 ("ssse3", Stable, &["sse3"]),
441 ("tbm", Unstable(sym::tbm_target_feature), &[]),
442 ("vaes", Unstable(sym::avx512_target_feature), &["avx2", "aes"]),
443 ("vpclmulqdq", Unstable(sym::avx512_target_feature), &["avx", "pclmulqdq"]),
444 ("widekl", Unstable(sym::keylocker_x86), &["kl"]),
445 ("x87", Unstable(sym::x87_target_feature), &[]),
446 ("xop", Unstable(sym::xop_target_feature), &["avx", "sse4a"]),
447 ("xsave", Stable, &[]),
448 ("xsavec", Stable, &["xsave"]),
449 ("xsaveopt", Stable, &["xsave"]),
450 ("xsaves", Stable, &["xsave"]),
451 ];
453
454const HEXAGON_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
455 ("hvx", Unstable(sym::hexagon_target_feature), &[]),
457 ("hvx-length128b", Unstable(sym::hexagon_target_feature), &["hvx"]),
458 ];
460
461static POWERPC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
462 ("altivec", Unstable(sym::powerpc_target_feature), &[]),
464 ("partword-atomics", Unstable(sym::powerpc_target_feature), &[]),
465 ("power10-vector", Unstable(sym::powerpc_target_feature), &["power9-vector"]),
466 ("power8-altivec", Unstable(sym::powerpc_target_feature), &["altivec"]),
467 ("power8-crypto", Unstable(sym::powerpc_target_feature), &["power8-altivec"]),
468 ("power8-vector", Unstable(sym::powerpc_target_feature), &["vsx", "power8-altivec"]),
469 ("power9-altivec", Unstable(sym::powerpc_target_feature), &["power8-altivec"]),
470 ("power9-vector", Unstable(sym::powerpc_target_feature), &["power8-vector", "power9-altivec"]),
471 ("quadword-atomics", Unstable(sym::powerpc_target_feature), &[]),
472 ("vsx", Unstable(sym::powerpc_target_feature), &["altivec"]),
473 ];
475
476const MIPS_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
477 ("fp64", Unstable(sym::mips_target_feature), &[]),
479 ("msa", Unstable(sym::mips_target_feature), &[]),
480 ("virt", Unstable(sym::mips_target_feature), &[]),
481 ];
483
484static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
485 ("a", Stable, &["zaamo", "zalrsc"]),
487 ("c", Stable, &[]),
488 ("d", Unstable(sym::riscv_target_feature), &["f"]),
489 ("e", Unstable(sym::riscv_target_feature), &[]),
490 ("f", Unstable(sym::riscv_target_feature), &[]),
491 (
492 "forced-atomics",
493 Stability::Forbidden { reason: "unsound because it changes the ABI of atomic operations" },
494 &[],
495 ),
496 ("m", Stable, &[]),
497 ("relax", Unstable(sym::riscv_target_feature), &[]),
498 ("unaligned-scalar-mem", Unstable(sym::riscv_target_feature), &[]),
499 ("v", Unstable(sym::riscv_target_feature), &[]),
500 ("zaamo", Unstable(sym::riscv_target_feature), &[]),
501 ("zabha", Unstable(sym::riscv_target_feature), &["zaamo"]),
502 ("zalrsc", Unstable(sym::riscv_target_feature), &[]),
503 ("zba", Stable, &[]),
504 ("zbb", Stable, &[]),
505 ("zbc", Stable, &[]),
506 ("zbkb", Stable, &[]),
507 ("zbkc", Stable, &[]),
508 ("zbkx", Stable, &[]),
509 ("zbs", Stable, &[]),
510 ("zdinx", Unstable(sym::riscv_target_feature), &["zfinx"]),
511 ("zfh", Unstable(sym::riscv_target_feature), &["zfhmin"]),
512 ("zfhmin", Unstable(sym::riscv_target_feature), &["f"]),
513 ("zfinx", Unstable(sym::riscv_target_feature), &[]),
514 ("zhinx", Unstable(sym::riscv_target_feature), &["zhinxmin"]),
515 ("zhinxmin", Unstable(sym::riscv_target_feature), &["zfinx"]),
516 ("zk", Stable, &["zkn", "zkr", "zkt"]),
517 ("zkn", Stable, &["zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"]),
518 ("zknd", Stable, &[]),
519 ("zkne", Stable, &[]),
520 ("zknh", Stable, &[]),
521 ("zkr", Stable, &[]),
522 ("zks", Stable, &["zbkb", "zbkc", "zbkx", "zksed", "zksh"]),
523 ("zksed", Stable, &[]),
524 ("zksh", Stable, &[]),
525 ("zkt", Stable, &[]),
526 ];
528
529static WASM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
530 ("atomics", Unstable(sym::wasm_target_feature), &[]),
532 ("bulk-memory", Stable, &[]),
533 ("exception-handling", Unstable(sym::wasm_target_feature), &[]),
534 ("extended-const", Stable, &[]),
535 ("multivalue", Stable, &[]),
536 ("mutable-globals", Stable, &[]),
537 ("nontrapping-fptoint", Stable, &[]),
538 ("reference-types", Stable, &[]),
539 ("relaxed-simd", Stable, &["simd128"]),
540 ("sign-ext", Stable, &[]),
541 ("simd128", Stable, &[]),
542 ("tail-call", Stable, &[]),
543 ("wide-arithmetic", Unstable(sym::wasm_target_feature), &[]),
544 ];
546
547const BPF_FEATURES: &[(&str, Stability, ImpliedFeatures)] =
548 &[("alu32", Unstable(sym::bpf_target_feature), &[])];
549
550static CSKY_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
551 ("10e60", Unstable(sym::csky_target_feature), &["7e10"]),
553 ("2e3", Unstable(sym::csky_target_feature), &["e2"]),
554 ("3e3r1", Unstable(sym::csky_target_feature), &[]),
555 ("3e3r2", Unstable(sym::csky_target_feature), &["3e3r1", "doloop"]),
556 ("3e3r3", Unstable(sym::csky_target_feature), &["doloop"]),
557 ("3e7", Unstable(sym::csky_target_feature), &["2e3"]),
558 ("7e10", Unstable(sym::csky_target_feature), &["3e7"]),
559 ("cache", Unstable(sym::csky_target_feature), &[]),
560 ("doloop", Unstable(sym::csky_target_feature), &[]),
561 ("dsp1e2", Unstable(sym::csky_target_feature), &[]),
562 ("dspe60", Unstable(sym::csky_target_feature), &[]),
563 ("e1", Unstable(sym::csky_target_feature), &["elrw"]),
564 ("e2", Unstable(sym::csky_target_feature), &["e2"]),
565 ("edsp", Unstable(sym::csky_target_feature), &[]),
566 ("elrw", Unstable(sym::csky_target_feature), &[]),
567 ("float1e2", Unstable(sym::csky_target_feature), &[]),
568 ("float1e3", Unstable(sym::csky_target_feature), &[]),
569 ("float3e4", Unstable(sym::csky_target_feature), &[]),
570 ("float7e60", Unstable(sym::csky_target_feature), &[]),
571 ("floate1", Unstable(sym::csky_target_feature), &[]),
572 ("hard-tp", Unstable(sym::csky_target_feature), &[]),
573 ("high-registers", Unstable(sym::csky_target_feature), &[]),
574 ("hwdiv", Unstable(sym::csky_target_feature), &[]),
575 ("mp", Unstable(sym::csky_target_feature), &["2e3"]),
576 ("mp1e2", Unstable(sym::csky_target_feature), &["3e7"]),
577 ("nvic", Unstable(sym::csky_target_feature), &[]),
578 ("trust", Unstable(sym::csky_target_feature), &[]),
579 ("vdsp2e60f", Unstable(sym::csky_target_feature), &[]),
580 ("vdspv1", Unstable(sym::csky_target_feature), &[]),
581 ("vdspv2", Unstable(sym::csky_target_feature), &[]),
582 ("fdivdu", Unstable(sym::csky_target_feature), &[]),
586 ("fpuv2_df", Unstable(sym::csky_target_feature), &[]),
587 ("fpuv2_sf", Unstable(sym::csky_target_feature), &[]),
588 ("fpuv3_df", Unstable(sym::csky_target_feature), &[]),
589 ("fpuv3_hf", Unstable(sym::csky_target_feature), &[]),
590 ("fpuv3_hi", Unstable(sym::csky_target_feature), &[]),
591 ("fpuv3_sf", Unstable(sym::csky_target_feature), &[]),
592 ("hard-float", Unstable(sym::csky_target_feature), &[]),
593 ("hard-float-abi", Unstable(sym::csky_target_feature), &[]),
594 ];
596
597static LOONGARCH_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
598 ("d", Unstable(sym::loongarch_target_feature), &["f"]),
600 ("f", Unstable(sym::loongarch_target_feature), &[]),
601 ("frecipe", Unstable(sym::loongarch_target_feature), &[]),
602 ("lasx", Unstable(sym::loongarch_target_feature), &["lsx"]),
603 ("lbt", Unstable(sym::loongarch_target_feature), &[]),
604 ("lsx", Unstable(sym::loongarch_target_feature), &["d"]),
605 ("lvz", Unstable(sym::loongarch_target_feature), &[]),
606 ("relax", Unstable(sym::loongarch_target_feature), &[]),
607 ("ual", Unstable(sym::loongarch_target_feature), &[]),
608 ];
610
611const IBMZ_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
612 ("backchain", Unstable(sym::s390x_target_feature), &[]),
614 ("vector", Unstable(sym::s390x_target_feature), &[]),
615 ];
617
618const SPARC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
619 ("leoncasa", Unstable(sym::sparc_target_feature), &[]),
621 ("v8plus", Unstable(sym::sparc_target_feature), &[]),
622 ("v9", Unstable(sym::sparc_target_feature), &[]),
623 ];
625
626static M68K_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
627 ("isa-68000", Unstable(sym::m68k_target_feature), &[]),
629 ("isa-68010", Unstable(sym::m68k_target_feature), &["isa-68000"]),
630 ("isa-68020", Unstable(sym::m68k_target_feature), &["isa-68010"]),
631 ("isa-68030", Unstable(sym::m68k_target_feature), &["isa-68020"]),
632 ("isa-68040", Unstable(sym::m68k_target_feature), &["isa-68030", "isa-68882"]),
633 ("isa-68060", Unstable(sym::m68k_target_feature), &["isa-68040"]),
634 ("isa-68881", Unstable(sym::m68k_target_feature), &[]),
636 ("isa-68882", Unstable(sym::m68k_target_feature), &["isa-68881"]),
637 ];
639
640pub fn all_rust_features() -> impl Iterator<Item = (&'static str, Stability)> {
645 std::iter::empty()
646 .chain(ARM_FEATURES.iter())
647 .chain(AARCH64_FEATURES.iter())
648 .chain(X86_FEATURES.iter())
649 .chain(HEXAGON_FEATURES.iter())
650 .chain(POWERPC_FEATURES.iter())
651 .chain(MIPS_FEATURES.iter())
652 .chain(RISCV_FEATURES.iter())
653 .chain(WASM_FEATURES.iter())
654 .chain(BPF_FEATURES.iter())
655 .chain(CSKY_FEATURES)
656 .chain(LOONGARCH_FEATURES)
657 .chain(IBMZ_FEATURES)
658 .chain(SPARC_FEATURES)
659 .chain(M68K_FEATURES)
660 .cloned()
661 .map(|(f, s, _)| (f, s))
662}
663
664const X86_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
668 &[(128, "sse"), (256, "avx"), (512, "avx512f")]; const AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")];
670
671const ARM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")];
673
674const POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "altivec")];
675const WASM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "simd128")];
676const S390X_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vector")];
677const RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
678 &[(128, "v")];
679const SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[];
681
682const HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
683 &[(1024, "hvx-length128b")];
684const MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "msa")];
685const CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vdspv1")];
686const LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
687 &[(128, "lsx"), (256, "lasx")];
688
689#[derive(Copy, Clone, Debug)]
690pub struct FeatureConstraints {
691 pub required: &'static [&'static str],
693 pub incompatible: &'static [&'static str],
695}
696
697impl Target {
698 pub fn rust_target_features(&self) -> &'static [(&'static str, Stability, ImpliedFeatures)] {
699 match &*self.arch {
700 "arm" => ARM_FEATURES,
701 "aarch64" | "arm64ec" => AARCH64_FEATURES,
702 "x86" | "x86_64" => X86_FEATURES,
703 "hexagon" => HEXAGON_FEATURES,
704 "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_FEATURES,
705 "powerpc" | "powerpc64" => POWERPC_FEATURES,
706 "riscv32" | "riscv64" => RISCV_FEATURES,
707 "wasm32" | "wasm64" => WASM_FEATURES,
708 "bpf" => BPF_FEATURES,
709 "csky" => CSKY_FEATURES,
710 "loongarch64" => LOONGARCH_FEATURES,
711 "s390x" => IBMZ_FEATURES,
712 "sparc" | "sparc64" => SPARC_FEATURES,
713 "m68k" => M68K_FEATURES,
714 _ => &[],
715 }
716 }
717
718 pub fn features_for_correct_vector_abi(&self) -> &'static [(u64, &'static str)] {
719 match &*self.arch {
720 "x86" | "x86_64" => X86_FEATURES_FOR_CORRECT_VECTOR_ABI,
721 "aarch64" | "arm64ec" => AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI,
722 "arm" => ARM_FEATURES_FOR_CORRECT_VECTOR_ABI,
723 "powerpc" | "powerpc64" => POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI,
724 "loongarch64" => LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI,
725 "riscv32" | "riscv64" => RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI,
726 "wasm32" | "wasm64" => WASM_FEATURES_FOR_CORRECT_VECTOR_ABI,
727 "s390x" => S390X_FEATURES_FOR_CORRECT_VECTOR_ABI,
728 "sparc" | "sparc64" => SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI,
729 "hexagon" => HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI,
730 "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI,
731 "bpf" | "m68k" => &[], "csky" => CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI,
733 _ => &[],
736 }
737 }
738
739 pub fn tied_target_features(&self) -> &'static [&'static [&'static str]] {
740 match &*self.arch {
741 "aarch64" | "arm64ec" => AARCH64_TIED_FEATURES,
742 _ => &[],
743 }
744 }
745
746 pub fn implied_target_features<'a>(
747 &self,
748 base_features: impl Iterator<Item = &'a str>,
749 ) -> FxHashSet<&'a str> {
750 let implied_features =
751 self.rust_target_features().iter().map(|(f, _, i)| (f, i)).collect::<FxHashMap<_, _>>();
752
753 let mut features = FxHashSet::default();
756 let mut new_features = base_features.collect::<Vec<&str>>();
757 while let Some(new_feature) = new_features.pop() {
758 if features.insert(new_feature) {
759 if let Some(implied_features) = implied_features.get(&new_feature) {
760 new_features.extend(implied_features.iter().copied())
761 }
762 }
763 }
764 features
765 }
766
767 pub fn abi_required_features(&self) -> FeatureConstraints {
778 const NOTHING: FeatureConstraints = FeatureConstraints { required: &[], incompatible: &[] };
779 match &*self.arch {
784 "x86" => {
785 match self.rustc_abi {
788 None => {
789 FeatureConstraints { required: &["x87"], incompatible: &["soft-float"] }
792 }
793 Some(RustcAbi::X86Sse2) => {
794 FeatureConstraints {
796 required: &["x87", "sse2"],
797 incompatible: &["soft-float"],
798 }
799 }
800 Some(RustcAbi::X86Softfloat) => {
801 FeatureConstraints { required: &["soft-float"], incompatible: &[] }
806 }
807 }
808 }
809 "x86_64" => {
810 match self.rustc_abi {
813 None => {
814 FeatureConstraints {
816 required: &["x87", "sse2"],
817 incompatible: &["soft-float"],
818 }
819 }
820 Some(RustcAbi::X86Softfloat) => {
821 FeatureConstraints { required: &["soft-float"], incompatible: &[] }
826 }
827 Some(r) => panic!("invalid Rust ABI for x86_64: {r:?}"),
828 }
829 }
830 "arm" => {
831 match self.llvm_floatabi.unwrap() {
834 FloatAbi::Soft => {
835 NOTHING
840 }
841 FloatAbi::Hard => {
842 FeatureConstraints { required: &["fpregs"], incompatible: &["soft-float"] }
844 }
845 }
846 }
847 "aarch64" | "arm64ec" => {
848 match &*self.abi {
851 "softfloat" => {
852 NOTHING
856 }
857 _ => {
858 FeatureConstraints { required: &["neon"], incompatible: &[] }
861 }
862 }
863 }
864 "riscv32" | "riscv64" => {
865 match &*self.llvm_abiname {
868 "ilp32d" | "lp64d" => {
869 FeatureConstraints { required: &["d"], incompatible: &["e"] }
871 }
872 "ilp32f" | "lp64f" => {
873 FeatureConstraints { required: &["f"], incompatible: &["e"] }
875 }
876 "ilp32" | "lp64" => {
877 FeatureConstraints { required: &[], incompatible: &["e"] }
879 }
880 "ilp32e" => {
881 FeatureConstraints { required: &[], incompatible: &["d"] }
890 }
891 "lp64e" => {
892 NOTHING
894 }
895 _ => unreachable!(),
896 }
897 }
898 _ => NOTHING,
899 }
900 }
901}