forked from rust-lang/libc
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add RDTSC and RDTSCP intrinsics (rust-lang#264)
- Loading branch information
1 parent
bf6d801
commit af8d8f5
Showing
2 changed files
with
73 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#[cfg(test)] | ||
use stdsimd_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. | ||
#[inline(always)] | ||
#[cfg_attr(test, assert_instr(rdtsc))] | ||
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. | ||
#[inline(always)] | ||
#[cfg_attr(test, assert_instr(rdtscp))] | ||
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 stdsimd_test::simd_test; | ||
use x86::i586::rdtsc; | ||
|
||
#[simd_test = "sse2"] | ||
unsafe fn _rdtsc() { | ||
let r = rdtsc::_rdtsc(); | ||
assert_ne!(r, 0); // The chances of this being 0 are infinitesimal | ||
} | ||
|
||
#[simd_test = "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 | ||
} | ||
} |