#
core/stdarch/crates/core_arch/src/x86/
rdtsc.rs

    1//! RDTSC instructions.
    2
    3#[cfg(test)]
    4use stdarch_test::assert_instr;
    5
    6/// Reads the current value of the processor’s time-stamp counter.
    7///
    8/// The processor monotonically increments the time-stamp counter MSR
    9/// every clock cycle and resets it to 0 whenever the processor is
    10/// reset.
    11///
    12/// The RDTSC instruction is not a serializing instruction. It does
    13/// not necessarily wait until all previous instructions have been
    14/// executed before reading the counter. Similarly, subsequent
    15/// instructions may begin execution before the read operation is
    16/// performed.
    17///
    18/// On processors that support the Intel 64 architecture, the
    19/// high-order 32 bits of each of RAX and RDX are cleared.
    20///
    21/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_rdtsc)
    22#[inline]
    23#[cfg_attr(test, assert_instr(rdtsc))]
    24#[stable(feature = "simd_x86", since = "1.27.0")]
    25pub unsafe fn _rdtsc() -> u64 {
    26    rdtsc()
    27}
    28
    29/// Reads the current value of the processor’s time-stamp counter and
    30/// the `IA32_TSC_AUX MSR`.
    31///
    32/// The processor monotonically increments the time-stamp counter MSR
    33/// every clock cycle and resets it to 0 whenever the processor is
    34/// reset.
    35///
    36/// The RDTSCP instruction waits until all previous instructions have
    37/// been executed before reading the counter. However, subsequent
    38/// instructions may begin execution before the read operation is
    39/// performed.
    40///
    41/// On processors that support the Intel 64 architecture, the
    42/// high-order 32 bits of each of RAX, RDX, and RCX are cleared.
    43///
    44/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=__rdtscp)
    45#[inline]
    46#[cfg_attr(test, assert_instr(rdtscp))]
    47#[stable(feature = "simd_x86", since = "1.27.0")]
    48pub unsafe fn __rdtscp(aux: *mut u32) -> u64 {
    49    let (tsc, auxval) = rdtscp();
    50    *aux = auxval;
    51    tsc
    52}
    53
    54#[allow(improper_ctypes)]
    55unsafe extern "unadjusted" {
    56    #[link_name = "llvm.x86.rdtsc"]
    57    fn rdtsc() -> u64;
    58    #[link_name = "llvm.x86.rdtscp"]
    59    fn rdtscp() -> (u64, u32);
    60}
    61
    62#[cfg(test)]
    63mod tests {
    64    use crate::core_arch::x86::*;
    65    use stdarch_test::simd_test;
    66
    67    #[simd_test(enable = "sse2")]
    68    unsafe fn test_rdtsc() {
    69        let r = _rdtsc();
    70        assert_ne!(r, 0); // The chances of this being 0 are infinitesimal
    71    }
    72
    73    #[simd_test(enable = "sse2")]
    74    unsafe fn test_rdtscp() {
    75        let mut aux = 0;
    76        let r = __rdtscp(&mut aux);
    77        assert_ne!(r, 0); // The chances of this being 0 are infinitesimal
    78    }
    79}