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