+template<PieceType Pt>
+inline Bitboard attacks_bb(Square s, Bitboard occ) {
+ return (Pt == ROOK ? RAttacks : BAttacks)[s][magic_index<Pt>(s, occ)];
+}
+
+
+/// lsb()/msb() finds the least/most significant bit in a nonzero bitboard.
+/// pop_lsb() finds and clears the least significant bit in a nonzero bitboard.
+
+#if defined(USE_BSFQ)
+
+# if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
+
+FORCE_INLINE Square lsb(Bitboard b) {
+ unsigned long index;
+ _BitScanForward64(&index, b);
+ return (Square) index;
+}
+
+FORCE_INLINE Square msb(Bitboard b) {
+ unsigned long index;
+ _BitScanReverse64(&index, b);
+ return (Square) index;
+}
+
+# elif defined(__arm__)
+
+FORCE_INLINE int lsb32(uint32_t v) {
+ __asm__("rbit %0, %1" : "=r"(v) : "r"(v));
+ return __builtin_clz(v);
+}
+
+FORCE_INLINE Square msb(Bitboard b) {
+ return (Square) (63 - __builtin_clzll(b));
+}
+
+FORCE_INLINE Square lsb(Bitboard b) {
+ return (Square) (uint32_t(b) ? lsb32(uint32_t(b)) : 32 + lsb32(uint32_t(b >> 32)));
+}
+
+# else
+
+FORCE_INLINE Square lsb(Bitboard b) { // Assembly code by Heinz van Saanen
+ Bitboard index;
+ __asm__("bsfq %1, %0": "=r"(index): "rm"(b) );
+ return (Square) index;
+}
+
+FORCE_INLINE Square msb(Bitboard b) {
+ Bitboard index;
+ __asm__("bsrq %1, %0": "=r"(index): "rm"(b) );
+ return (Square) index;
+}
+
+# endif
+
+FORCE_INLINE Square pop_lsb(Bitboard* b) {
+ const Square s = lsb(*b);
+ *b &= ~(1ULL << s);