From ed9a919db6069b8ecf4823e74916a0a6db6abed9 Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Thu, 21 Dec 2023 08:17:17 -0800 Subject: [PATCH] [board] Add a "count leading zeros" implementation for ARM machines Call the `clz` instruction on the bitboard via `asm!`. --- board/src/bitboard.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/board/src/bitboard.rs b/board/src/bitboard.rs index 4579e47..f799e4c 100644 --- a/board/src/bitboard.rs +++ b/board/src/bitboard.rs @@ -1,6 +1,7 @@ // Eryn Wells use crate::square::Square; +use std::arch::asm; #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct BitBoard(pub u64); @@ -17,6 +18,20 @@ impl BitBoard { fn place_piece_at(&mut self, sq: &Square) { self.0 |= 1 << sq.index } + + #[cfg(target_arch = "arm")] + fn _arm_count_leading_zeros(&self) -> u8 { + let mut number_of_leading_zeros: u8 = 0; + unsafe { + asm!( + "clz {count}, {bitfield}", + count = out(reg) number_of_leading_zeros, + bitfield = in(reg) self.0, + ); + } + + number_of_leading_zeros + } } #[cfg(test)] @@ -47,4 +62,13 @@ mod tests { bb.place_piece_at(&Square::from_index(34).expect("Invalid square index")); assert!(bb.has_piece_at(&Square::from_index(34).expect("Invalid square index"))); } + + #[cfg(target_arch = "arm")] + #[test] + fn arm_count_leading_zeros() { + assert_eq!(BitBoard(0)._arm_count_leading_zeros(), 0); + assert_eq!(BitBoard(0b10)._arm_count_leading_zeros(), 62); + assert_eq!(BitBoard(0b1010)._arm_count_leading_zeros(), 60); + assert_eq!(BitBoard(0x80000000)._arm_count_leading_zeros(), 0); + } }