summaryrefslogtreecommitdiff
path: root/src/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/eval.c')
-rwxr-xr-xsrc/eval.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/eval.c b/src/eval.c
index 3e856f1..23f830c 100755
--- a/src/eval.c
+++ b/src/eval.c
@@ -21,6 +21,68 @@ Revision History:
#include "chess.h"
+//
+// CountBits and the CoorFromBitBoard{Rank8ToRank1,Rank1ToRank8}
+// wrappers (bitboard.c) are real out-of-line asm calls on every one of
+// eval.c's ~20 production call sites (passed-pawn detection, bishop-
+// pair logic, etc.), hit on every real Eval() call. CountBits' asm
+// body (x64.asm) isn't even O(1) popcnt, it's a Kernighan bit-clearing
+// loop -- O(popcount) iterations plus call overhead. Redirected via
+// #define, the same mechanism chess.h already uses for the OTHER
+// direction (#ifdef CROUTINES routes CountBits/FirstBit/LastBit to the
+// slow C fallbacks) -- this routes them to fast inline compiler
+// builtins instead, for every existing call site below with no further
+// edits. Gated on !CROUTINES so the CROUTINES debug/comparison build
+// still gets the real (slow, cross-checked) implementations.
+//
+// _FastCoorFromBitBoardRank1ToRank8 also bakes in the wrong-bit-clear
+// fix applied to bitboard.c's real CoorFromBitBoardRank1ToRank8 (that
+// function used to clear the LOWEST set bit via `*pbb &= (*pbb - 1)`
+// regardless of uLastBit, correct only when a single bit was set) --
+// this version clears the bit it actually just reported, via BBSQUARE.
+//
+#ifndef CROUTINES
+static ULONG INLINE
+_FastCountBits(IN BITBOARD bb)
+{
+ return (ULONG)__builtin_popcountll(bb);
+}
+
+static COOR INLINE
+_FastCoorFromBitBoardRank8ToRank1(IN OUT BITBOARD *pbb)
+{
+ COOR c = ILLEGAL_COOR;
+ ULONG uBitIndex;
+
+ if (*pbb)
+ {
+ uBitIndex = (ULONG)__builtin_ctzll(*pbb);
+ c = BIT_NUMBER_TO_COOR(uBitIndex);
+ *pbb &= (*pbb - 1);
+ }
+ return c;
+}
+
+static COOR INLINE
+_FastCoorFromBitBoardRank1ToRank8(IN OUT BITBOARD *pbb)
+{
+ COOR c = ILLEGAL_COOR;
+ ULONG uBitIndex;
+
+ if (*pbb)
+ {
+ uBitIndex = (ULONG)(63 - __builtin_clzll(*pbb));
+ c = BIT_NUMBER_TO_COOR(uBitIndex);
+ *pbb &= ~BBSQUARE[uBitIndex];
+ }
+ return c;
+}
+
+#define CountBits _FastCountBits
+#define CoorFromBitBoardRank8ToRank1 _FastCoorFromBitBoardRank8ToRank1
+#define CoorFromBitBoardRank1ToRank8 _FastCoorFromBitBoardRank1ToRank8
+#endif // !CROUTINES
+
//
// Bishop-mobility ray-walk outcome categories -- see BMobCaseTable in