#[cfg(any(target_arch = "aarch64", target_arch = "arm"))]
use core::arch::asm;
#[cfg(not(any(
target_arch = "x86_64",
target_arch = "x86",
target_arch = "aarch64",
target_arch = "arm",
target_arch = "riscv64",
target_arch = "riscv32"
)))]
use crate::current_nanos;
#[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
#[must_use]
pub fn read_time_counter() -> u64 {
#[cfg(target_arch = "x86_64")]
unsafe {
core::arch::x86_64::_rdtsc()
}
#[cfg(target_arch = "x86")]
unsafe {
core::arch::x86::_rdtsc()
}
}
#[cfg(target_arch = "aarch64")]
#[must_use]
pub fn read_time_counter() -> u64 {
let mut v: u64;
unsafe {
asm!("mrs {v}, cntvct_el0", v = out(reg) v);
}
v
}
#[cfg(target_arch = "arm")]
#[must_use]
pub fn read_time_counter() -> u64 {
let mut v: u32;
unsafe {
asm!("mrc p15, 0, {v}, c9, c13, 0", v = out(reg) v);
}
u64::from(v)
}
#[cfg(target_arch = "riscv64")]
#[must_use]
pub fn read_time_counter() -> u64 {
let mut v: u64;
unsafe {
asm!("rdcycle {v}", v = out(reg) v);
}
v
}
#[cfg(target_arch = "riscv32")]
#[must_use]
pub fn read_time_counter() -> u64 {
let mut v: u64;
let mut hg: u32;
let mut lw: u32;
let mut cmp: u32;
unsafe {
asm!("jmp%=:",
"rdcycleh {hg}",
"rdcycle {lw}",
"rdcycleh {cmp}",
"bne {hg}, {cmp}, jmp%=",
hg = out(reg) hg,
lw = out(reg) lw,
cmp = out(reg) cmp);
v = ((hg as u64) << 32) | lw as u64;
}
v
}
#[cfg(not(any(
target_arch = "x86_64",
target_arch = "x86",
target_arch = "aarch64",
target_arch = "arm",
target_arch = "riscv64",
target_arch = "riscv32"
)))]
#[must_use]
pub fn read_time_counter() -> u64 {
current_nanos()
}