summaryrefslogtreecommitdiffstats
path: root/library/stdarch/crates/core_arch/src/x86/rdtsc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/stdarch/crates/core_arch/src/x86/rdtsc.rs')
-rw-r--r--library/stdarch/crates/core_arch/src/x86/rdtsc.rs77
1 files changed, 77 insertions, 0 deletions
diff --git a/library/stdarch/crates/core_arch/src/x86/rdtsc.rs b/library/stdarch/crates/core_arch/src/x86/rdtsc.rs
new file mode 100644
index 000000000..67f6e48fa
--- /dev/null
+++ b/library/stdarch/crates/core_arch/src/x86/rdtsc.rs
@@ -0,0 +1,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
+ }
+}