core/stdarch/crates/core_arch/src/x86/
cpuid.rs

1//! `cpuid` intrinsics
2#![allow(clippy::module_name_repetitions)]
3
4use crate::arch::asm;
5#[cfg(test)]
6use stdarch_test::assert_instr;
7
8/// Result of the `cpuid` instruction.
9#[allow(clippy::missing_inline_in_public_items)]
10// ^^ the derived impl of Debug for CpuidResult is not #[inline] and that's OK.
11#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
12#[stable(feature = "simd_x86", since = "1.27.0")]
13pub struct CpuidResult {
14    /// EAX register.
15    #[stable(feature = "simd_x86", since = "1.27.0")]
16    pub eax: u32,
17    /// EBX register.
18    #[stable(feature = "simd_x86", since = "1.27.0")]
19    pub ebx: u32,
20    /// ECX register.
21    #[stable(feature = "simd_x86", since = "1.27.0")]
22    pub ecx: u32,
23    /// EDX register.
24    #[stable(feature = "simd_x86", since = "1.27.0")]
25    pub edx: u32,
26}
27
28/// Returns the result of the `cpuid` instruction for a given `leaf` (`EAX`)
29/// and `sub_leaf` (`ECX`).
30///
31/// The highest-supported leaf value is returned by the first tuple argument of
32/// [`__get_cpuid_max(0)`](fn.__get_cpuid_max.html). For leaves containing
33/// sub-leaves, the second tuple argument returns the highest-supported
34/// sub-leaf value.
35///
36/// The [CPUID Wikipedia page][wiki_cpuid] contains how to query which
37/// information using the `EAX` and `ECX` registers, and the interpretation of
38/// the results returned in `EAX`, `EBX`, `ECX`, and `EDX`.
39///
40/// The references are:
41/// - [Intel 64 and IA-32 Architectures Software Developer's Manual Volume 2:
42///   Instruction Set Reference, A-Z][intel64_ref].
43/// - [AMD64 Architecture Programmer's Manual, Volume 3: General-Purpose and
44///   System Instructions][amd64_ref].
45///
46/// [wiki_cpuid]: https://en.wikipedia.org/wiki/CPUID
47/// [intel64_ref]: https://cdrdv2-public.intel.com/671110/325383-sdm-vol-2abcd.pdf
48/// [amd64_ref]: http://support.amd.com/TechDocs/24594.pdf
49#[inline]
50#[cfg_attr(test, assert_instr(cpuid))]
51#[stable(feature = "simd_x86", since = "1.27.0")]
52pub unsafe fn __cpuid_count(leaf: u32, sub_leaf: u32) -> CpuidResult {
53    let eax;
54    let ebx;
55    let ecx;
56    let edx;
57
58    // LLVM sometimes reserves `ebx` for its internal use, we so we need to use
59    // a scratch register for it instead.
60    #[cfg(target_arch = "x86")]
61    {
62        asm!(
63            "mov {0}, ebx",
64            "cpuid",
65            "xchg {0}, ebx",
66            out(reg) ebx,
67            inout("eax") leaf => eax,
68            inout("ecx") sub_leaf => ecx,
69            out("edx") edx,
70            options(nostack, preserves_flags),
71        );
72    }
73    #[cfg(target_arch = "x86_64")]
74    {
75        asm!(
76            "mov {0:r}, rbx",
77            "cpuid",
78            "xchg {0:r}, rbx",
79            out(reg) ebx,
80            inout("eax") leaf => eax,
81            inout("ecx") sub_leaf => ecx,
82            out("edx") edx,
83            options(nostack, preserves_flags),
84        );
85    }
86    CpuidResult { eax, ebx, ecx, edx }
87}
88
89/// See [`__cpuid_count`](fn.__cpuid_count.html).
90#[inline]
91#[cfg_attr(test, assert_instr(cpuid))]
92#[stable(feature = "simd_x86", since = "1.27.0")]
93pub unsafe fn __cpuid(leaf: u32) -> CpuidResult {
94    __cpuid_count(leaf, 0)
95}
96
97/// Returns the highest-supported `leaf` (`EAX`) and sub-leaf (`ECX`) `cpuid`
98/// values.
99///
100/// If `cpuid` is supported, and `leaf` is zero, then the first tuple argument
101/// contains the highest `leaf` value that `cpuid` supports. For `leaf`s
102/// containing sub-leafs, the second tuple argument contains the
103/// highest-supported sub-leaf value.
104///
105/// See also [`__cpuid`](fn.__cpuid.html) and
106/// [`__cpuid_count`](fn.__cpuid_count.html).
107#[inline]
108#[stable(feature = "simd_x86", since = "1.27.0")]
109pub unsafe fn __get_cpuid_max(leaf: u32) -> (u32, u32) {
110    let CpuidResult { eax, ebx, .. } = __cpuid(leaf);
111    (eax, ebx)
112}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy