Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/rustc_codegen_gcc/src/gcc_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ pub fn to_gcc_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]>
("x86", "avx512vbmi2") => smallvec!["avx512vbmi2", "avx512bw"],
// NOTE: seems like GCC requires 'avx512bw' for 'avx512bitalg'.
("x86", "avx512bitalg") => smallvec!["avx512bitalg", "avx512bw"],
("x86", "cpuid") => smallvec![],
("aarch64", "rcpc2") => smallvec!["rcpc-immo"],
("aarch64", "dpb") => smallvec!["ccpp"],
("aarch64", "dpb2") => smallvec!["ccdp"],
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,8 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
TargetFeatureFoldStrength::Both("zu"),
],
)),
// This is supposed to be detection-only, has no effect on codegen
("x86", "cpuid") => None,
(_, s) => Some(LLVMFeature::new(s)),
}
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,8 @@ declare_features! (
/// Allows function attribute `#[coverage(on/off)]`, to control coverage
/// instrumentation of that function.
(unstable, coverage_attribute, "1.74.0", Some(84605)),
/// Allows using the `cpuid` target feature
(unstable, cpuid_target_feature, "CURRENT_RUSTC_VERSION", Some(146558)),
/// Allows non-builtin attributes in inner attribute position.
(unstable, custom_inner_attributes, "1.30.0", Some(54726)),
/// Allows custom test frameworks with `#![test_runner]` and `#[test_case]`.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,7 @@ symbols! {
count,
coverage,
coverage_attribute,
cpuid_target_feature,
cr,
crate_in_paths,
crate_local,
Expand Down
43 changes: 22 additions & 21 deletions compiler/rustc_target/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ const AARCH64_TIED_FEATURES: &[&[&str]] = &[

static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
// tidy-alphabetical-start
("adx", Stable, &[]),
("adx", Stable, &["cpuid"]),
("aes", Stable, &["sse2"]),
("amx-avx512", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
("amx-bf16", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
Expand All @@ -385,9 +385,9 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
("amx-int8", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
("amx-movrs", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
("amx-tf32", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
("amx-tile", Unstable(sym::x86_amx_intrinsics), &[]),
("amx-tile", Unstable(sym::x86_amx_intrinsics), &["cpuid"]),
("amx-transpose", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
("apxf", Unstable(sym::apx_target_feature), &[]),
("apxf", Unstable(sym::apx_target_feature), &["cpuid"]),
("avx", Stable, &["sse4.2"]),
("avx2", Stable, &["avx"]),
(
Expand Down Expand Up @@ -429,24 +429,25 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
("avxvnni", Stable, &["avx2"]),
("avxvnniint8", Stable, &["avx2"]),
("avxvnniint16", Stable, &["avx2"]),
("bmi1", Stable, &[]),
("bmi2", Stable, &[]),
("cmpxchg16b", Stable, &[]),
("ermsb", Unstable(sym::ermsb_target_feature), &[]),
("bmi1", Stable, &["cpuid"]),
("bmi2", Stable, &["cpuid"]),
("cmpxchg16b", Stable, &["cpuid"]),
("cpuid", Unstable(sym::cpuid_target_feature), &[]),
("ermsb", Unstable(sym::ermsb_target_feature), &["cpuid"]),
("f16c", Stable, &["avx"]),
("fma", Stable, &["avx"]),
("fxsr", Stable, &[]),
("fxsr", Stable, &["cpuid"]),
("gfni", Stable, &["sse2"]),
("kl", Stable, &["sse2"]),
("lahfsahf", Unstable(sym::lahfsahf_target_feature), &[]),
("lzcnt", Stable, &[]),
("movbe", Stable, &[]),
("movrs", Unstable(sym::movrs_target_feature), &[]),
("lahfsahf", Unstable(sym::lahfsahf_target_feature), &["cpuid"]),
("lzcnt", Stable, &["cpuid"]),
("movbe", Stable, &["cpuid"]),
("movrs", Unstable(sym::movrs_target_feature), &["cpuid"]),
("pclmulqdq", Stable, &["sse2"]),
("popcnt", Stable, &[]),
("prfchw", Unstable(sym::prfchw_target_feature), &[]),
("rdrand", Stable, &[]),
("rdseed", Stable, &[]),
("popcnt", Stable, &["cpuid"]),
("prfchw", Unstable(sym::prfchw_target_feature), &["cpuid"]),
("rdrand", Stable, &["cpuid"]),
("rdseed", Stable, &["cpuid"]),
(
"retpoline-external-thunk",
Stability::Forbidden { reason: "use `-Zretpoline-external-thunk` compiler flag instead" },
Expand All @@ -462,28 +463,28 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
Stability::Forbidden { reason: "use `-Zretpoline` compiler flag instead" },
&[],
),
("rtm", Unstable(sym::rtm_target_feature), &[]),
("rtm", Unstable(sym::rtm_target_feature), &["cpuid"]),
("sha", Stable, &["sse2"]),
("sha512", Stable, &["avx2"]),
("sm3", Stable, &["avx"]),
("sm4", Stable, &["avx2"]),
// This cannot actually be toggled, the ABI always fixes it, so it'd make little sense to
// stabilize. It must be in this list for the ABI check to be able to use it.
("soft-float", Stability::Unstable(sym::x87_target_feature), &[]),
("sse", Stable, &[]),
("sse", Stable, &["cpuid"]),
("sse2", Stable, &["sse"]),
("sse3", Stable, &["sse2"]),
("sse4.1", Stable, &["ssse3"]),
("sse4.2", Stable, &["sse4.1"]),
("sse4a", Stable, &["sse3"]),
("ssse3", Stable, &["sse3"]),
("tbm", Stable, &[]),
("tbm", Stable, &["cpuid"]),
("vaes", Stable, &["avx2", "aes"]),
("vpclmulqdq", Stable, &["avx", "pclmulqdq"]),
("widekl", Stable, &["kl"]),
("x87", Unstable(sym::x87_target_feature), &[]),
("x87", Unstable(sym::x87_target_feature), &["cpuid"]),
("xop", Unstable(sym::xop_target_feature), &[/*"fma4", */ "avx", "sse4a"]),
("xsave", Stable, &[]),
("xsave", Stable, &["cpuid"]),
("xsavec", Stable, &["xsave"]),
("xsaveopt", Stable, &["xsave"]),
("xsaves", Stable, &["xsave"]),
Expand Down
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@
// tidy-alphabetical-start
#![feature(aarch64_unstable_target_feature)]
#![feature(arm_target_feature)]
#![feature(cpuid_target_feature)]
#![feature(hexagon_target_feature)]
#![feature(loongarch_target_feature)]
#![feature(mips_target_feature)]
Expand Down
2 changes: 2 additions & 0 deletions library/std_detect/src/detect/arch/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,4 +281,6 @@ features! {
/// ERMSB, Enhanced REP MOVSB and STOSB
@FEATURE: #[unstable(feature = "xop_target_feature", issue = "127208")] xop: "xop";
/// XOP: eXtended Operations (AMD)
@FEATURE: #[unstable(feature = "cpuid_target_feature", issue = "146558")] cpuid: "cpuid";
/// CPUID
}
2 changes: 2 additions & 0 deletions library/std_detect/src/detect/os/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ pub(crate) fn detect_features() -> cache::Initializer {
return value;
}

value.set(Feature::cpuid as u32);

// Calling `__cpuid`/`__cpuid_count` from here on is safe because the CPU
// has `cpuid` support.

Expand Down
3 changes: 2 additions & 1 deletion library/stdarch/crates/core_arch/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
f16,
aarch64_unstable_target_feature,
bigint_helper_methods,
funnel_shifts
funnel_shifts,
cpuid_target_feature
)]
#![cfg_attr(test, feature(test, abi_vectorcall, stdarch_internal))]
#![deny(clippy::missing_inline_in_public_items)]
Expand Down
43 changes: 27 additions & 16 deletions library/stdarch/crates/core_arch/src/x86/cpuid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,20 @@ pub struct CpuidResult {

/// Returns the result of the `cpuid` instruction for a given `leaf` (`EAX`)
/// and `sub_leaf` (`ECX`).
///
/// The highest-supported leaf value is returned by the first tuple argument of
/// [`__get_cpuid_max(0)`](fn.__get_cpuid_max.html). For leaves containing
/// sub-leaves, the second tuple argument returns the highest-supported
/// sub-leaf value.
///
/// There are 2 types of information leafs - basic leafs (with `leaf < 0x8000000`)
/// and extended leafs (with `leaf >= 0x80000000`). The highest supported basic and
/// extended leafs can be obtained by calling CPUID with `0` and `0x80000000`,
/// respectively, and reading the value in the `EAX` register. If the leaf supports
/// more than one sub-leafs, then the procedure of obtaining the highest supported
/// sub-leaf, as well as the behavior if a invalid sub-leaf value is passed, depends
/// on the specific leaf.
///
/// If the `leaf` value is higher than the maximum supported basic or extended leaf
/// for the processor, this returns the information for the highest supported basic
/// information leaf (with the passed `sub_leaf` value). If the `leaf` value is less
/// than or equal to the highest basic or extended leaf value, but the leaf is not
/// supported on the processor, all zeros are returned.
///
/// The [CPUID Wikipedia page][wiki_cpuid] contains how to query which
/// information using the `EAX` and `ECX` registers, and the interpretation of
Expand All @@ -48,8 +57,9 @@ pub struct CpuidResult {
/// [amd64_ref]: http://support.amd.com/TechDocs/24594.pdf
#[inline]
#[cfg_attr(test, assert_instr(cpuid))]
#[target_feature(enable = "cpuid")]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn __cpuid_count(leaf: u32, sub_leaf: u32) -> CpuidResult {
pub fn __cpuid_count(leaf: u32, sub_leaf: u32) -> CpuidResult {
let eax;
let ebx;
let ecx;
Expand All @@ -58,7 +68,7 @@ pub unsafe fn __cpuid_count(leaf: u32, sub_leaf: u32) -> CpuidResult {
// LLVM sometimes reserves `ebx` for its internal use, we so we need to use
// a scratch register for it instead.
#[cfg(target_arch = "x86")]
{
unsafe {
asm!(
"mov {0}, ebx",
"cpuid",
Expand All @@ -71,7 +81,7 @@ pub unsafe fn __cpuid_count(leaf: u32, sub_leaf: u32) -> CpuidResult {
);
}
#[cfg(target_arch = "x86_64")]
{
unsafe {
asm!(
"mov {0:r}, rbx",
"cpuid",
Expand All @@ -86,27 +96,28 @@ pub unsafe fn __cpuid_count(leaf: u32, sub_leaf: u32) -> CpuidResult {
CpuidResult { eax, ebx, ecx, edx }
}

/// Calls CPUID with the provided `leaf` value, with `sub_leaf` set to 0.
/// See [`__cpuid_count`](fn.__cpuid_count.html).
#[inline]
#[cfg_attr(test, assert_instr(cpuid))]
#[target_feature(enable = "cpuid")]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn __cpuid(leaf: u32) -> CpuidResult {
pub fn __cpuid(leaf: u32) -> CpuidResult {
__cpuid_count(leaf, 0)
}

/// Returns the highest-supported `leaf` (`EAX`) and sub-leaf (`ECX`) `cpuid`
/// values.
/// Returns the EAX and EBX register after calling CPUID with the provided `leaf`,
/// with `sub_leaf` set to 0.
///
/// If `cpuid` is supported, and `leaf` is zero, then the first tuple argument
/// contains the highest `leaf` value that `cpuid` supports. For `leaf`s
/// containing sub-leafs, the second tuple argument contains the
/// highest-supported sub-leaf value.
/// If `leaf` if 0 or `0x80000000`, the first tuple argument contains the maximum
/// supported basic or extended leaf, respectively.
///
/// See also [`__cpuid`](fn.__cpuid.html) and
/// [`__cpuid_count`](fn.__cpuid_count.html).
#[inline]
#[target_feature(enable = "cpuid")]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn __get_cpuid_max(leaf: u32) -> (u32, u32) {
pub fn __get_cpuid_max(leaf: u32) -> (u32, u32) {
let CpuidResult { eax, ebx, .. } = __cpuid(leaf);
(eax, ebx)
}
1 change: 1 addition & 0 deletions tests/ui/check-cfg/target_feature.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE");
`cache`
`cmpxchg16b`
`concurrent-functions`
`cpuid`
`crc`
`crt-static`
`cssc`
Expand Down
19 changes: 19 additions & 0 deletions tests/ui/feature-gates/feature-gate-cpuid_target_feature.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//@ only-x86_64

use std::arch::x86_64::*;

#[target_feature(enable = "cpuid")]
//~^ ERROR: currently unstable
fn annotation() {}

fn detection() -> bool {
is_x86_feature_detected!("cpuid")
//~^ ERROR: use of unstable library feature
}

fn intrinsic() -> CpuidResult {
__cpuid(0)
//~^ ERROR: requires unsafe function or block
}

fn main() {}
34 changes: 34 additions & 0 deletions tests/ui/feature-gates/feature-gate-cpuid_target_feature.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
error[E0658]: use of unstable library feature `cpuid_target_feature`
--> $DIR/feature-gate-cpuid_target_feature.rs:10:5
|
LL | is_x86_feature_detected!("cpuid")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #146558 <https://github.com/rust-lang/rust/issues/146558> for more information
= help: add `#![feature(cpuid_target_feature)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
= note: this error originates in the macro `$crate::detect_feature` which comes from the expansion of the macro `is_x86_feature_detected` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0658]: the target feature `cpuid` is currently unstable
--> $DIR/feature-gate-cpuid_target_feature.rs:5:18
|
LL | #[target_feature(enable = "cpuid")]
| ^^^^^^^^^^^^^^^^
|
= note: see issue #146558 <https://github.com/rust-lang/rust/issues/146558> for more information
= help: add `#![feature(cpuid_target_feature)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0133]: call to function `std::arch::x86_64::__cpuid` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/feature-gate-cpuid_target_feature.rs:15:5
|
LL | __cpuid(0)
| ^^^^^^^^^^ call to function with `#[target_feature]`
|
= help: in order for the call to be safe, the context requires the following additional target feature: cpuid
= note: the cpuid target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0133, E0658.
For more information about an error, try `rustc --explain E0133`.
Loading