Skip to content

Commit

Permalink
non-x86_64 support fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
kauppie committed Mar 14, 2024
1 parent fe72a3b commit 63dcb52
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 5 deletions.
4 changes: 4 additions & 0 deletions src/deinterleave.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ pub trait DeinterleaveBMI2<const N: usize>: Deinterleave<N> {
unsafe fn deinterleave_bmi2(self, lsb: usize) -> <Self as Deinterleave<N>>::Output;
}

#[cfg(target_arch = "x86_64")]
macro_rules! impl_deinterleave_bmi2_32 {
($($impl_type:ty => $dim:expr);*) => {
$(
Expand All @@ -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);*) => {
$(
Expand All @@ -130,13 +132,15 @@ macro_rules! impl_deinterleave_bmi2_64 {
};
}

#[cfg(target_arch = "x86_64")]
impl_deinterleave_bmi2_32! {
u16 => 2;
u32 => 2;
u32 => 3;
u32 => 4
}

#[cfg(target_arch = "x86_64")]
impl_deinterleave_bmi2_64! {
u64 => 2;
u64 => 3;
Expand Down
4 changes: 4 additions & 0 deletions src/interleave.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ pub trait InterleaveBMI2<const N: usize>: Interleave<N> {
unsafe fn interleave_bmi2(self) -> <Self as Interleave<N>>::Output;
}

#[cfg(target_arch = "x86_64")]
macro_rules! impl_interleave_bmi2_32 {
($($dim:expr, $impl_type:ty);*) => {
$(
Expand All @@ -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);*) => {
$(
Expand All @@ -126,13 +128,15 @@ macro_rules! impl_interleave_bmi2_64 {
};
}

#[cfg(target_arch = "x86_64")]
impl_interleave_bmi2_32! {
2, u8;
3, u8;
4, u8;
2, u16
}

#[cfg(target_arch = "x86_64")]
impl_interleave_bmi2_64! {
5, u8;
6, u8;
Expand Down
30 changes: 25 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
///
/// ```
Expand All @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -212,13 +222,14 @@ pub mod bmi2 {
/// ```
#[inline]
#[target_feature(enable = "bmi2")]
#[cfg(target_arch = "x86_64")]
pub unsafe fn index_of_unchecked<I, const N: usize>(
array: [I; N],
) -> <I as Interleave<N>>::Output
where
I: InterleaveBMI2<N>,
{
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
Expand All @@ -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.
Expand Down Expand Up @@ -269,13 +288,14 @@ pub mod bmi2 {
/// ```
#[inline]
#[target_feature(enable = "bmi2")]
#[cfg(target_arch = "x86_64")]
pub unsafe fn coord_of_unchecked<I, const N: usize>(
index: I,
) -> [<I as Deinterleave<N>>::Output; N]
where
I: DeinterleaveBMI2<N> + Copy,
{
util::generic_coord_of(index, |idx, i| idx.deinterleave_bmi2(i))
crate::util::generic_coord_of(index, |idx, i| idx.deinterleave_bmi2(i))
}
}

Expand Down

0 comments on commit 63dcb52

Please sign in to comment.