diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 73c34818446..a633ea5e5a9 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -349,17 +349,15 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty:: } pub fn provide(providers: &mut Providers) { + use rustc_codegen_ssa::target_features::{all_known_features, supported_target_features}; providers.supported_target_features = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); if tcx.sess.opts.actually_rustdoc { // rustdoc needs to be able to document functions that use all the features, so // provide them all. - llvm_util::all_known_features().map(|(a, b)| (a.to_string(), b)).collect() + all_known_features().map(|(a, b)| (a.to_string(), b)).collect() } else { - llvm_util::supported_target_features(tcx.sess) - .iter() - .map(|&(a, b)| (a.to_string(), b)) - .collect() + supported_target_features(tcx.sess).iter().map(|&(a, b)| (a.to_string(), b)).collect() } }; diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 900f2df383a..d42020047fd 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -1,12 +1,12 @@ use crate::back::write::create_informational_target_machine; use crate::llvm; use libc::c_int; +use rustc_codegen_ssa::target_features::supported_target_features; use rustc_data_structures::fx::FxHashSet; use rustc_feature::UnstableFeatures; use rustc_middle::bug; use rustc_session::config::PrintRequest; use rustc_session::Session; -use rustc_span::symbol::sym; use rustc_span::symbol::Symbol; use rustc_target::spec::{MergeFunctions, PanicStrategy}; use std::ffi::CString; @@ -139,140 +139,6 @@ pub fn time_trace_profiler_finish(file_name: &str) { // WARNING: the features after applying `to_llvm_feature` must be known // to LLVM or the feature detection code will walk past the end of the feature // array, leading to crashes. - -const ARM_ALLOWED_FEATURES: &[(&str, Option)] = &[ - ("aclass", Some(sym::arm_target_feature)), - ("mclass", Some(sym::arm_target_feature)), - ("rclass", Some(sym::arm_target_feature)), - ("dsp", Some(sym::arm_target_feature)), - ("neon", Some(sym::arm_target_feature)), - ("crc", Some(sym::arm_target_feature)), - ("crypto", Some(sym::arm_target_feature)), - ("v5te", Some(sym::arm_target_feature)), - ("v6", Some(sym::arm_target_feature)), - ("v6k", Some(sym::arm_target_feature)), - ("v6t2", Some(sym::arm_target_feature)), - ("v7", Some(sym::arm_target_feature)), - ("v8", Some(sym::arm_target_feature)), - ("vfp2", Some(sym::arm_target_feature)), - ("vfp3", Some(sym::arm_target_feature)), - ("vfp4", Some(sym::arm_target_feature)), - // This is needed for inline assembly, but shouldn't be stabilized as-is - // since it should be enabled per-function using #[instruction_set], not - // #[target_feature]. - ("thumb-mode", Some(sym::arm_target_feature)), -]; - -const AARCH64_ALLOWED_FEATURES: &[(&str, Option)] = &[ - ("fp", Some(sym::aarch64_target_feature)), - ("neon", Some(sym::aarch64_target_feature)), - ("sve", Some(sym::aarch64_target_feature)), - ("crc", Some(sym::aarch64_target_feature)), - ("crypto", Some(sym::aarch64_target_feature)), - ("ras", Some(sym::aarch64_target_feature)), - ("lse", Some(sym::aarch64_target_feature)), - ("rdm", Some(sym::aarch64_target_feature)), - ("fp16", Some(sym::aarch64_target_feature)), - ("rcpc", Some(sym::aarch64_target_feature)), - ("dotprod", Some(sym::aarch64_target_feature)), - ("tme", Some(sym::aarch64_target_feature)), - ("v8.1a", Some(sym::aarch64_target_feature)), - ("v8.2a", Some(sym::aarch64_target_feature)), - ("v8.3a", Some(sym::aarch64_target_feature)), -]; - -const X86_ALLOWED_FEATURES: &[(&str, Option)] = &[ - ("adx", Some(sym::adx_target_feature)), - ("aes", None), - ("avx", None), - ("avx2", None), - ("avx512bw", Some(sym::avx512_target_feature)), - ("avx512cd", Some(sym::avx512_target_feature)), - ("avx512dq", Some(sym::avx512_target_feature)), - ("avx512er", Some(sym::avx512_target_feature)), - ("avx512f", Some(sym::avx512_target_feature)), - ("avx512ifma", Some(sym::avx512_target_feature)), - ("avx512pf", Some(sym::avx512_target_feature)), - ("avx512vbmi", Some(sym::avx512_target_feature)), - ("avx512vl", Some(sym::avx512_target_feature)), - ("avx512vpopcntdq", Some(sym::avx512_target_feature)), - ("bmi1", None), - ("bmi2", None), - ("cmpxchg16b", Some(sym::cmpxchg16b_target_feature)), - ("f16c", Some(sym::f16c_target_feature)), - ("fma", None), - ("fxsr", None), - ("lzcnt", None), - ("movbe", Some(sym::movbe_target_feature)), - ("pclmulqdq", None), - ("popcnt", None), - ("rdrand", None), - ("rdseed", None), - ("rtm", Some(sym::rtm_target_feature)), - ("sha", None), - ("sse", None), - ("sse2", None), - ("sse3", None), - ("sse4.1", None), - ("sse4.2", None), - ("sse4a", Some(sym::sse4a_target_feature)), - ("ssse3", None), - ("tbm", Some(sym::tbm_target_feature)), - ("xsave", None), - ("xsavec", None), - ("xsaveopt", None), - ("xsaves", None), -]; - -const HEXAGON_ALLOWED_FEATURES: &[(&str, Option)] = &[ - ("hvx", Some(sym::hexagon_target_feature)), - ("hvx-length128b", Some(sym::hexagon_target_feature)), -]; - -const POWERPC_ALLOWED_FEATURES: &[(&str, Option)] = &[ - ("altivec", Some(sym::powerpc_target_feature)), - ("power8-altivec", Some(sym::powerpc_target_feature)), - ("power9-altivec", Some(sym::powerpc_target_feature)), - ("power8-vector", Some(sym::powerpc_target_feature)), - ("power9-vector", Some(sym::powerpc_target_feature)), - ("vsx", Some(sym::powerpc_target_feature)), -]; - -const MIPS_ALLOWED_FEATURES: &[(&str, Option)] = - &[("fp64", Some(sym::mips_target_feature)), ("msa", Some(sym::mips_target_feature))]; - -const RISCV_ALLOWED_FEATURES: &[(&str, Option)] = &[ - ("m", Some(sym::riscv_target_feature)), - ("a", Some(sym::riscv_target_feature)), - ("c", Some(sym::riscv_target_feature)), - ("f", Some(sym::riscv_target_feature)), - ("d", Some(sym::riscv_target_feature)), - ("e", Some(sym::riscv_target_feature)), -]; - -const WASM_ALLOWED_FEATURES: &[(&str, Option)] = &[ - ("simd128", Some(sym::wasm_target_feature)), - ("atomics", Some(sym::wasm_target_feature)), - ("nontrapping-fptoint", Some(sym::wasm_target_feature)), -]; - -/// When rustdoc is running, provide a list of all known features so that all their respective -/// primitives may be documented. -/// -/// IMPORTANT: If you're adding another feature list above, make sure to add it to this iterator! -pub fn all_known_features() -> impl Iterator)> { - std::iter::empty() - .chain(ARM_ALLOWED_FEATURES.iter()) - .chain(AARCH64_ALLOWED_FEATURES.iter()) - .chain(X86_ALLOWED_FEATURES.iter()) - .chain(HEXAGON_ALLOWED_FEATURES.iter()) - .chain(POWERPC_ALLOWED_FEATURES.iter()) - .chain(MIPS_ALLOWED_FEATURES.iter()) - .chain(RISCV_ALLOWED_FEATURES.iter()) - .chain(WASM_ALLOWED_FEATURES.iter()) - .cloned() -} - pub fn to_llvm_feature<'a>(sess: &Session, s: &'a str) -> &'a str { let arch = if sess.target.target.arch == "x86_64" { "x86" } else { &*sess.target.target.arch }; match (arch, s) { @@ -306,20 +172,6 @@ pub fn target_features(sess: &Session) -> Vec { .collect() } -pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Option)] { - match &*sess.target.target.arch { - "arm" => ARM_ALLOWED_FEATURES, - "aarch64" => AARCH64_ALLOWED_FEATURES, - "x86" | "x86_64" => X86_ALLOWED_FEATURES, - "hexagon" => HEXAGON_ALLOWED_FEATURES, - "mips" | "mips64" => MIPS_ALLOWED_FEATURES, - "powerpc" | "powerpc64" => POWERPC_ALLOWED_FEATURES, - "riscv32" | "riscv64" => RISCV_ALLOWED_FEATURES, - "wasm32" => WASM_ALLOWED_FEATURES, - _ => &[], - } -} - pub fn print_version() { // Can be called without initializing LLVM unsafe { diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index d4f3bf37797..e34371ef59a 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -42,6 +42,7 @@ pub mod glue; pub mod meth; pub mod mir; pub mod mono_item; +pub mod target_features; pub mod traits; pub struct ModuleCodegen { diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs new file mode 100644 index 00000000000..4c61e21901b --- /dev/null +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -0,0 +1,150 @@ +use rustc_session::Session; +use rustc_span::symbol::sym; +use rustc_span::symbol::Symbol; + +const ARM_ALLOWED_FEATURES: &[(&str, Option)] = &[ + ("aclass", Some(sym::arm_target_feature)), + ("mclass", Some(sym::arm_target_feature)), + ("rclass", Some(sym::arm_target_feature)), + ("dsp", Some(sym::arm_target_feature)), + ("neon", Some(sym::arm_target_feature)), + ("crc", Some(sym::arm_target_feature)), + ("crypto", Some(sym::arm_target_feature)), + ("v5te", Some(sym::arm_target_feature)), + ("v6", Some(sym::arm_target_feature)), + ("v6k", Some(sym::arm_target_feature)), + ("v6t2", Some(sym::arm_target_feature)), + ("v7", Some(sym::arm_target_feature)), + ("v8", Some(sym::arm_target_feature)), + ("vfp2", Some(sym::arm_target_feature)), + ("vfp3", Some(sym::arm_target_feature)), + ("vfp4", Some(sym::arm_target_feature)), + // This is needed for inline assembly, but shouldn't be stabilized as-is + // since it should be enabled per-function using #[instruction_set], not + // #[target_feature]. + ("thumb-mode", Some(sym::arm_target_feature)), +]; + +const AARCH64_ALLOWED_FEATURES: &[(&str, Option)] = &[ + ("fp", Some(sym::aarch64_target_feature)), + ("neon", Some(sym::aarch64_target_feature)), + ("sve", Some(sym::aarch64_target_feature)), + ("crc", Some(sym::aarch64_target_feature)), + ("crypto", Some(sym::aarch64_target_feature)), + ("ras", Some(sym::aarch64_target_feature)), + ("lse", Some(sym::aarch64_target_feature)), + ("rdm", Some(sym::aarch64_target_feature)), + ("fp16", Some(sym::aarch64_target_feature)), + ("rcpc", Some(sym::aarch64_target_feature)), + ("dotprod", Some(sym::aarch64_target_feature)), + ("tme", Some(sym::aarch64_target_feature)), + ("v8.1a", Some(sym::aarch64_target_feature)), + ("v8.2a", Some(sym::aarch64_target_feature)), + ("v8.3a", Some(sym::aarch64_target_feature)), +]; + +const X86_ALLOWED_FEATURES: &[(&str, Option)] = &[ + ("adx", Some(sym::adx_target_feature)), + ("aes", None), + ("avx", None), + ("avx2", None), + ("avx512bw", Some(sym::avx512_target_feature)), + ("avx512cd", Some(sym::avx512_target_feature)), + ("avx512dq", Some(sym::avx512_target_feature)), + ("avx512er", Some(sym::avx512_target_feature)), + ("avx512f", Some(sym::avx512_target_feature)), + ("avx512ifma", Some(sym::avx512_target_feature)), + ("avx512pf", Some(sym::avx512_target_feature)), + ("avx512vbmi", Some(sym::avx512_target_feature)), + ("avx512vl", Some(sym::avx512_target_feature)), + ("avx512vpopcntdq", Some(sym::avx512_target_feature)), + ("bmi1", None), + ("bmi2", None), + ("cmpxchg16b", Some(sym::cmpxchg16b_target_feature)), + ("f16c", Some(sym::f16c_target_feature)), + ("fma", None), + ("fxsr", None), + ("lzcnt", None), + ("movbe", Some(sym::movbe_target_feature)), + ("pclmulqdq", None), + ("popcnt", None), + ("rdrand", None), + ("rdseed", None), + ("rtm", Some(sym::rtm_target_feature)), + ("sha", None), + ("sse", None), + ("sse2", None), + ("sse3", None), + ("sse4.1", None), + ("sse4.2", None), + ("sse4a", Some(sym::sse4a_target_feature)), + ("ssse3", None), + ("tbm", Some(sym::tbm_target_feature)), + ("xsave", None), + ("xsavec", None), + ("xsaveopt", None), + ("xsaves", None), +]; + +const HEXAGON_ALLOWED_FEATURES: &[(&str, Option)] = &[ + ("hvx", Some(sym::hexagon_target_feature)), + ("hvx-length128b", Some(sym::hexagon_target_feature)), +]; + +const POWERPC_ALLOWED_FEATURES: &[(&str, Option)] = &[ + ("altivec", Some(sym::powerpc_target_feature)), + ("power8-altivec", Some(sym::powerpc_target_feature)), + ("power9-altivec", Some(sym::powerpc_target_feature)), + ("power8-vector", Some(sym::powerpc_target_feature)), + ("power9-vector", Some(sym::powerpc_target_feature)), + ("vsx", Some(sym::powerpc_target_feature)), +]; + +const MIPS_ALLOWED_FEATURES: &[(&str, Option)] = + &[("fp64", Some(sym::mips_target_feature)), ("msa", Some(sym::mips_target_feature))]; + +const RISCV_ALLOWED_FEATURES: &[(&str, Option)] = &[ + ("m", Some(sym::riscv_target_feature)), + ("a", Some(sym::riscv_target_feature)), + ("c", Some(sym::riscv_target_feature)), + ("f", Some(sym::riscv_target_feature)), + ("d", Some(sym::riscv_target_feature)), + ("e", Some(sym::riscv_target_feature)), +]; + +const WASM_ALLOWED_FEATURES: &[(&str, Option)] = &[ + ("simd128", Some(sym::wasm_target_feature)), + ("atomics", Some(sym::wasm_target_feature)), + ("nontrapping-fptoint", Some(sym::wasm_target_feature)), +]; + +/// When rustdoc is running, provide a list of all known features so that all their respective +/// primitives may be documented. +/// +/// IMPORTANT: If you're adding another feature list above, make sure to add it to this iterator! +pub fn all_known_features() -> impl Iterator)> { + std::iter::empty() + .chain(ARM_ALLOWED_FEATURES.iter()) + .chain(AARCH64_ALLOWED_FEATURES.iter()) + .chain(X86_ALLOWED_FEATURES.iter()) + .chain(HEXAGON_ALLOWED_FEATURES.iter()) + .chain(POWERPC_ALLOWED_FEATURES.iter()) + .chain(MIPS_ALLOWED_FEATURES.iter()) + .chain(RISCV_ALLOWED_FEATURES.iter()) + .chain(WASM_ALLOWED_FEATURES.iter()) + .cloned() +} + +pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Option)] { + match &*sess.target.target.arch { + "arm" => ARM_ALLOWED_FEATURES, + "aarch64" => AARCH64_ALLOWED_FEATURES, + "x86" | "x86_64" => X86_ALLOWED_FEATURES, + "hexagon" => HEXAGON_ALLOWED_FEATURES, + "mips" | "mips64" => MIPS_ALLOWED_FEATURES, + "powerpc" | "powerpc64" => POWERPC_ALLOWED_FEATURES, + "riscv32" | "riscv64" => RISCV_ALLOWED_FEATURES, + "wasm32" => WASM_ALLOWED_FEATURES, + _ => &[], + } +}