pub mod arm;
pub mod common;
pub mod esp32;
pub mod riscv;
pub trait TargetArch {
fn name(&self) -> &'static str;
fn pointer_size(&self) -> usize;
fn native_alignment(&self) -> usize;
fn supports_unaligned_access(&self) -> bool;
fn memory_barrier(&self);
fn cycle_count(&self) -> Option<u64>;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MemoryOrder {
Relaxed,
Acquire,
Release,
AcquireRelease,
SeqCst,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CacheOp {
Clean,
Invalidate,
CleanInvalidate,
}
#[derive(Debug, Clone, Copy)]
pub struct TargetCapabilities {
pub has_fpu: bool,
pub has_simd: bool,
pub has_aes: bool,
pub has_crc: bool,
pub cache_line_size: usize,
pub num_cores: usize,
}
impl Default for TargetCapabilities {
fn default() -> Self {
Self {
has_fpu: false,
has_simd: false,
has_aes: false,
has_crc: false,
cache_line_size: 64,
num_cores: 1,
}
}
}
pub fn get_capabilities() -> TargetCapabilities {
#[cfg(feature = "arm")]
{
arm::get_capabilities()
}
#[cfg(all(feature = "riscv", not(feature = "arm")))]
{
riscv::get_capabilities()
}
#[cfg(all(feature = "esp32", not(any(feature = "arm", feature = "riscv"))))]
{
esp32::get_capabilities()
}
#[cfg(not(any(feature = "arm", feature = "riscv", feature = "esp32")))]
{
TargetCapabilities::default()
}
}
#[inline]
pub fn memory_barrier() {
#[cfg(feature = "arm")]
arm::memory_barrier();
#[cfg(all(feature = "riscv", not(feature = "arm")))]
riscv::memory_barrier();
#[cfg(all(feature = "esp32", not(any(feature = "arm", feature = "riscv"))))]
esp32::memory_barrier();
#[cfg(not(any(feature = "arm", feature = "riscv", feature = "esp32")))]
core::sync::atomic::fence(core::sync::atomic::Ordering::SeqCst);
}
#[inline]
pub fn cycle_count() -> Option<u64> {
#[cfg(feature = "arm")]
{
arm::cycle_count()
}
#[cfg(all(feature = "riscv", not(feature = "arm")))]
{
riscv::cycle_count()
}
#[cfg(all(feature = "esp32", not(any(feature = "arm", feature = "riscv"))))]
{
esp32::cycle_count()
}
#[cfg(not(any(feature = "arm", feature = "riscv", feature = "esp32")))]
{
None
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_capabilities() {
let caps = get_capabilities();
assert!(caps.cache_line_size > 0);
assert!(caps.num_cores > 0);
}
#[test]
fn test_memory_barrier() {
memory_barrier();
}
}