Skip to content

Commit af8d8f5

Browse files
shepmasteralexcrichton
authored andcommitted
Add RDTSC and RDTSCP intrinsics (rust-lang#264)
1 parent bf6d801 commit af8d8f5

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

coresimd/src/x86/i586/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ pub use self::xsave::*;
55

66
pub use self::bswap::*;
77

8+
pub use self::rdtsc::*;
9+
810
pub use self::sse::*;
911
pub use self::sse2::*;
1012
pub use self::sse3::*;
@@ -26,6 +28,8 @@ mod xsave;
2628

2729
mod bswap;
2830

31+
mod rdtsc;
32+
2933
mod sse;
3034
mod sse2;
3135
mod sse3;

coresimd/src/x86/i586/rdtsc.rs

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

0 commit comments

Comments
 (0)