From 63dcb526a753eb48b7c6bd757d60360e9c908c28 Mon Sep 17 00:00:00 2001 From: Elias Kauppi Date: Thu, 14 Mar 2024 23:02:11 +0200 Subject: [PATCH] non-x86_64 support fixes --- src/deinterleave.rs | 4 ++++ src/interleave.rs | 4 ++++ src/lib.rs | 30 +++++++++++++++++++++++++----- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/deinterleave.rs b/src/deinterleave.rs index a67831c..49e0cb3 100644 --- a/src/deinterleave.rs +++ b/src/deinterleave.rs @@ -98,6 +98,7 @@ pub trait DeinterleaveBMI2: Deinterleave { unsafe fn deinterleave_bmi2(self, lsb: usize) -> >::Output; } +#[cfg(target_arch = "x86_64")] macro_rules! impl_deinterleave_bmi2_32 { ($($impl_type:ty => $dim:expr);*) => { $( @@ -114,6 +115,7 @@ macro_rules! impl_deinterleave_bmi2_32 { }; } +#[cfg(target_arch = "x86_64")] macro_rules! impl_deinterleave_bmi2_64 { ($($impl_type:ty => $dim:expr);*) => { $( @@ -130,6 +132,7 @@ macro_rules! impl_deinterleave_bmi2_64 { }; } +#[cfg(target_arch = "x86_64")] impl_deinterleave_bmi2_32! { u16 => 2; u32 => 2; @@ -137,6 +140,7 @@ impl_deinterleave_bmi2_32! { u32 => 4 } +#[cfg(target_arch = "x86_64")] impl_deinterleave_bmi2_64! { u64 => 2; u64 => 3; diff --git a/src/interleave.rs b/src/interleave.rs index bc4c0ed..4862eb8 100644 --- a/src/interleave.rs +++ b/src/interleave.rs @@ -100,6 +100,7 @@ pub trait InterleaveBMI2: Interleave { unsafe fn interleave_bmi2(self) -> >::Output; } +#[cfg(target_arch = "x86_64")] macro_rules! impl_interleave_bmi2_32 { ($($dim:expr, $impl_type:ty);*) => { $( @@ -113,6 +114,7 @@ macro_rules! impl_interleave_bmi2_32 { }; } +#[cfg(target_arch = "x86_64")] macro_rules! impl_interleave_bmi2_64 { ($($dim:expr, $impl_type:ty);*) => { $( @@ -126,6 +128,7 @@ macro_rules! impl_interleave_bmi2_64 { }; } +#[cfg(target_arch = "x86_64")] impl_interleave_bmi2_32! { 2, u8; 3, u8; @@ -133,6 +136,7 @@ impl_interleave_bmi2_32! { 2, u16 } +#[cfg(target_arch = "x86_64")] impl_interleave_bmi2_64! { 5, u8; 6, u8; diff --git a/src/lib.rs b/src/lib.rs index 7a94e41..8d6b3b5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -111,6 +111,8 @@ where /// Optionally, you can acquire a [`HardwareSupportToken`](crate::bmi2::HardwareSupportToken), and then call /// [`index_of`](crate::bmi2::index_of) and [`coord_of`](crate::bmi2::coord_of) without unsafe. /// +/// Note that the bmi2 instruction set is supported only on modern x86_64 CPUs. +/// /// # Examples /// /// ``` @@ -128,7 +130,7 @@ where /// ``` pub mod bmi2 { use crate::{ - deinterleave::DeinterleaveBMI2, interleave::InterleaveBMI2, util, Deinterleave, Interleave, + deinterleave::DeinterleaveBMI2, interleave::InterleaveBMI2, Deinterleave, Interleave, }; /// Returns true if the CPU supports the bmi2 instruction set. @@ -180,7 +182,15 @@ pub mod bmi2 { // SAFETY: Having an instance of `HardwareSupportToken` guarantees that // the `bmi2` instruction set is supported by the CPU and that it is safe // to call `index_of_unchecked`. - unsafe { index_of_unchecked(array) } + #[cfg(target_arch = "x86_64")] + unsafe { + index_of_unchecked(array) + } + #[cfg(not(target_arch = "x86_64"))] + { + let _ = array; + unreachable!("HardwareSupportToken cannot be created on non-x86_64 platforms") + } } /// Calculates Z-order curve index for given sequence of coordinates. @@ -212,13 +222,14 @@ pub mod bmi2 { /// ``` #[inline] #[target_feature(enable = "bmi2")] + #[cfg(target_arch = "x86_64")] pub unsafe fn index_of_unchecked( array: [I; N], ) -> >::Output where I: InterleaveBMI2, { - util::generic_index_of(array, |idx| idx.interleave_bmi2()) + crate::util::generic_index_of(array, |idx| idx.interleave_bmi2()) } /// Safe wrapper around [`coord_of_unchecked`] that requires a @@ -235,7 +246,15 @@ pub mod bmi2 { // SAFETY: Having an instance of `HardwareSupportToken` guarantees that // the `bmi2` instruction set is supported by the CPU and that it is safe // to call `coord_of_unchecked`. - unsafe { coord_of_unchecked(index) } + #[cfg(target_arch = "x86_64")] + unsafe { + coord_of_unchecked(index) + } + #[cfg(not(target_arch = "x86_64"))] + { + let _ = index; + unreachable!("HardwareSupportToken cannot be created on non-x86_64 platforms") + } } /// Returns the 2D coordinates of the given Z-order curve index. @@ -269,13 +288,14 @@ pub mod bmi2 { /// ``` #[inline] #[target_feature(enable = "bmi2")] + #[cfg(target_arch = "x86_64")] pub unsafe fn coord_of_unchecked( index: I, ) -> [>::Output; N] where I: DeinterleaveBMI2 + Copy, { - util::generic_coord_of(index, |idx, i| idx.deinterleave_bmi2(i)) + crate::util::generic_coord_of(index, |idx, i| idx.deinterleave_bmi2(i)) } }