diff options
| author | Scott Gasch <[email protected]> | 2026-10-25 11:20:24 -0700 |
|---|---|---|
| committer | Scott Gasch <[email protected]> | 2026-10-25 11:20:41 -0700 |
| commit | c1e8cefc7bf0c4017dda24b0486806ce3304a7ae (patch) | |
| tree | da5cfe55fe0af85c615db8c68320d53d1f67cf5c | |
| parent | 455accb4cbb1777cb553b6d75136521c6b8d1c01 (diff) | |
x86.asm/x64.asm were already mostly dead weight -- GetAttacks's real
asm body was retired 2026-09-06 (section 7 of
board_representation/MIGRATION.md), and LockDecrement/
CanUseParallelOpcodes/ParallelCompareUlong/ParallelCompareVector had
zero remaining callers (confirmed by grep before deleting anything).
What was still real and load-bearing:
- CountBits/FirstBit/LastBit: popcount/bsf/bsr CDECL calls. Already
had faster, compiler-intrinsic replacements sitting right next to
them in chess.h (FastCountBits/FastFirstBit/FastLastBit, via
__builtin_popcountll/__builtin_ctzll/__builtin_clzll with -mpopcnt)
that per-file #ifndef CROUTINES blocks in board.c/eval.c/generate.c/
probe.c/recogn.c were already redirecting individual call sites to.
Promoted that redirect to the plain names unconditionally
(#define CountBits FastCountBits etc. in chess.h) and dropped the
now-always-true CROUTINES guards in those five files -- CountBits'
real asm body was a Kernighan bit-clearing loop (~23 cycles/op per
gmake TEST=1's own benchmark), not even O(1), so this is strictly
faster as well as removing the toolchain dependency.
- LockCompareExchange/LockIncrement: real atomics backing
AcquireSpinLock/TryAcquireSpinLock/ReleaseSpinLock (util.c) and the
move-pool allocator (gamelist.c). Replaced with static inline
wrappers over __sync_val_compare_and_swap/__sync_add_and_fetch --
same CAS/atomic-add semantics as the retired `lock cmpxchg`/
`lock xadd` instructions.
Removes the yasm/nasm build dependency entirely: GNUmakefile's
NASM/NASMFLAGS variables, the CROUTINES flag, the .asm->.o build rule,
and x86.o/x64.o from every OBJS list. x86.asm/x64.asm deleted outright
(git history keeps them if ever needed again). The ASM=1 debug mode
(-S -fverbose-asm, a C-compiler assembly-listing dump, unrelated to
the deleted files despite the similar name) is untouched.
Verified: clean build with no yasm/nasm invocation anywhere in the
log, a clean DEBUG=1 TEST=1 self-test run, and node-count parity
against the previous commit on all three curated suites at sd10
(4,003,856 / 22,308,015 / 26,868,016 on both sides) -- confirms this
is a pure substitution with zero behavioral change, not just "doesn't
crash."
Co-Authored-By: Claude Sonnet 5 <[email protected]>
| -rw-r--r-- | src/GNUmakefile | 44 | ||||
| -rw-r--r-- | src/board.c | 2 | ||||
| -rwxr-xr-x | src/chess.h | 68 | ||||
| -rw-r--r-- | src/data.c | 15 | ||||
| -rw-r--r-- | src/eval.c | 3 | ||||
| -rw-r--r-- | src/generate.c | 2 | ||||
| -rw-r--r-- | src/probe.c | 2 | ||||
| -rw-r--r-- | src/recogn.c | 2 | ||||
| -rw-r--r-- | src/x64.asm | 320 | ||||
| -rw-r--r-- | src/x86.asm | 422 |
10 files changed, 38 insertions, 842 deletions
diff --git a/src/GNUmakefile b/src/GNUmakefile index 717006b..6970b45 100644 --- a/src/GNUmakefile +++ b/src/GNUmakefile @@ -18,21 +18,9 @@ # TREEDUMP=1: dump a flat MOVE/RESULT search-tree trace to # treedump.log (see TREEDUMP_FORMAT.md) # OSX=1: build for an Intel-based Apple Mac (omit this for FreeBSD/Linux) -# USE_READLINE=1: link against the GNU readline library +# DISABLE_READLINE=1: opt out of linking the GNU readline library +# (default on; see GNUmakefile's own comment at that block) # SIXTYFOUR=1: make an X64 binary -# CROUTINES=1: use the C versions of the asm routines [slower] -# GETATTACKS_BITBOARD=1: use the bbPieces/bbPawns-backed _GetAttacksBB -# instead of the asm/CROUTINES GetAttacks -- see -# board_representation/MIGRATION.md section 6 -# DISABLE_BITBOARD_MOVEGEN=1: opt back into the mailbox move -# generator/escapes/ExposesCheck/IsAttacked implementations -- the -# nine GENERATE_*_BITBOARD/EXPOSESCHECK_BITBOARD/ISATTACKED_BITBOARD -# toggles (board_representation/MOVEGEN_MIGRATION.md) are on by -# default as of the 2026-09-04 correctness/no-regression sweep -# (perft, move-set comparison harness, sd10 curated-suite parity, -# match_play.py). The mailbox code is still fully present and -# compiled either way -- this flag only flips which side of each -# macro-swap wins, it doesn't remove anything. # GPROF=1: instrument with -pg for gprof(1)-based profiling (see # PROFILE.md) -- root-free on both FreeBSD and Linux, unlike # hardware-counter-based profiling (pmcstat/perf). Requires a @@ -44,7 +32,6 @@ # CC = clang CXX = clang++ -NASM = yasm # Default to a 64-bit build -- 32-bit clang isn't available in this # environment anyway (see CLAUDE.md). Still overridable in principle @@ -54,19 +41,8 @@ NASM = yasm SIXTYFOUR ?= 1 ifdef OSX LIBRARIES = -pthread -lc - ifdef SIXTYFOUR - $(warning you will need to use yasm for now to get x64 on OSX) - NASMFLAGS = -f macho64 -dOSX -d_X64_ - else - NASMFLAGS = -f macho -dOSX - endif else - LIBRARIES = -pthread -lc -lstdc++ - ifdef SIXTYFOUR - NASMFLAGS = -f elf64 -d__GNUC__ - else - NASMFLAGS = -f elf -d__GNUC__ - endif + LIBRARIES = -pthread -lc -lstdc++ endif RM = /bin/rm @@ -144,14 +120,8 @@ ifdef SIXTYFOUR # than the old CDECL-call CountBits, but not the ~1-3 cycle single # instruction the "fast" eval.c wrappers were assumed to get). PROFILE += -m64 -mpopcnt - NASMFLAGS += -d_X64_ else PROFILE += -m32 - NASMFLAGS += -d_X86_ -endif - -ifdef CROUTINES - PROFILE += -DCROUTINES endif # 2026-10-25: bitboard move generation is no longer optional -- this @@ -397,11 +367,11 @@ FATHOM_CFLAGS = -std=gnu99 -O2 -Ifathom $(filter -m32 -m64,$(PROFILE)) # ---> .o, not .c! <--- # OBJS = main.o root.o search.o searchsup.o draw.o dynamic.o \ - hash.o eval.o x86.o pawnhash.o bitboard.o \ + hash.o eval.o pawnhash.o bitboard.o \ generate.o see.o move.o movesup.o command.o script.o \ input.o vars.o util.o unix.o gamelist.o mersenne.o \ sig.o piece.o ics.o san.o fen.o book.o bench.o board.o \ - data.o probe.o fathom.o recogn.o list.o x64.o \ + data.o probe.o fathom.o recogn.o list.o \ nnuefeatures.o nnueaccum.o nnueeval.o fhmodel.o ifdef TEST @@ -429,7 +399,6 @@ endif .SUFFIXES: .c .o .SUFFIXES: .cpp .o -.SUFFIXES: .asm .o .PHONY: all all: $(BINARY) @@ -447,9 +416,6 @@ fathom.o: fathom/tbprobe.c fathom/tbchess.c fathom/tbconfig.h fathom/tbprobe.h f %.o: %.cpp $(HEADERS) $(CXX) $(CFLAGS) -c -w $< -o $@ -%.o: %.asm $(HEADERS) - $(NASM) $(NASMFLAGS) -o $@ $< - .PHONY: release release: $(MAKE) -j5 MP=1 GENETIC=1 diff --git a/src/board.c b/src/board.c index d2d6c28..083bbae 100644 --- a/src/board.c +++ b/src/board.c @@ -26,9 +26,7 @@ Revision History: // check bitboard-scan loops (added retiring cNonPawns/cPawns/ // uPawnCount/uNonPawnCount) to the inlined FastCoorFromBitBoardRank8ToRank1 // (chess.h) instead of the real out-of-line extern call. -#ifndef CROUTINES #define CoorFromBitBoardRank8ToRank1 FastCoorFromBitBoardRank8ToRank1 -#endif void SetRootToInitialPosition(void) diff --git a/src/chess.h b/src/chess.h index 2942f0a..97c877c 100755 --- a/src/chess.h +++ b/src/chess.h @@ -5214,11 +5214,18 @@ FastCoorFromBitBoardRank1ToRank8(IN OUT BITBOARD *pbb) return c; } -#ifdef CROUTINES -#define CountBits SlowCountBits -#define FirstBit SlowFirstBit -#define LastBit SlowLastBit -#endif +// 2026-10-25: CountBits/FirstBit/LastBit used to be real extern CDECL +// calls into x86.asm/x64.asm (retired -- see FastCountBits/ +// FastFirstBit/FastLastBit above, the compiler-intrinsic replacements +// that made the asm versions' only remaining edge, "CROUTINES=1 is +// slower," meaningless: the intrinsics are both correct AND faster). +// Every plain-name call site now just resolves to the fast inline +// version directly; Slow*/DeBruijnFirstBit above remain as the +// cross-check reference implementations FastCountBits's own ASSERT +// and testbitboard.c's benchmarks compare against. +#define CountBits FastCountBits +#define FirstBit FastFirstBit +#define LastBit FastLastBit COOR CoorFromBitBoardRank8ToRank1(BITBOARD *pbb); @@ -5302,37 +5309,28 @@ PawnMaterial(IN POSITION *pos, IN ULONG color) return FastCountBits(pos->bbPawns[color]) * VALUE_PAWN; } -// -// x86.asm -// -ULONG CDECL -CountBits(BITBOARD bb); - -ULONG CDECL -FirstBit(BITBOARD bb); - -ULONG CDECL -LastBit(BITBOARD bb); - -ULONG CDECL -LockCompareExchange(volatile void *pDest, - ULONG uExch, - ULONG uComp); - -ULONG CDECL -LockIncrement(volatile void *pDest); - -ULONG CDECL -LockDecrement(volatile void *pDest); - -FLAG CDECL -CanUseParallelOpcodes(); - -ULONG CDECL -ParallelCompareUlong(ULONG uComparand, void *pComparators); +// 2026-10-25: were extern CDECL calls into x86.asm/x64.asm (retired). +// CountBits/FirstBit/LastBit are handled above (macros onto +// FastCountBits/FastFirstBit/FastLastBit). LockDecrement/ +// CanUseParallelOpcodes/ParallelCompareUlong/ParallelCompareVector had +// zero real callers (confirmed by grep before deleting the asm) -- +// gone outright, nothing to replace. LockCompareExchange/LockIncrement +// are real (AcquireSpinLock/TryAcquireSpinLock/ReleaseSpinLock in +// util.c; gamelist.c's move-pool allocator) -- same CAS/atomic-add +// semantics as the retired `lock cmpxchg`/`lock xadd` asm, via +// compiler builtins instead. +static ULONG INLINE +LockCompareExchange(volatile void *pDest, ULONG uExch, ULONG uComp) +{ + return (ULONG)__sync_val_compare_and_swap((volatile ULONG *)pDest, + uComp, uExch); +} -ULONG CDECL -ParallelCompareVector(void *pComparand, void *pComparators); +static ULONG INLINE +LockIncrement(volatile void *pDest) +{ + return (ULONG)__sync_add_and_fetch((volatile ULONG *)pDest, 1); +} // board_representation/MIGRATION.md sections 3/6/7: bbPieces/bbPawns- // backed GetAttacks primitive. Verified correct (20,000-position @@ -332,21 +332,6 @@ InitializeVectorDeltaTable(void) } (void)VerifyVectorDelta(); -#ifdef OSX - // - // nasm under OSX/macho has a nasty bug that causes the addresses - // of extern symbols to be screwed up. I only use two extern data - // structs in the x86.asm code: the vector delta table and the - // piece data table. My workaround to the nasm bug is to copy - // these tables into a symbol in the asm module and access them - // locally on OSX. - // - extern VECTOR_DELTA *g_NasmVectorDelta; - extern PIECE_DATA *g_NasmPieceData; - - memcpy(&g_NasmVectorDelta, &g_VectorDelta, sizeof(g_VectorDelta)); - memcpy(&g_NasmPieceData, &g_PieceData, sizeof(g_PieceData)); -#endif } void @@ -44,11 +44,8 @@ Revision History: // CROUTINES debug/comparison build still gets the real (slow, // cross-checked) implementations. // -#ifndef CROUTINES -#define CountBits FastCountBits #define CoorFromBitBoardRank8ToRank1 FastCoorFromBitBoardRank8ToRank1 #define CoorFromBitBoardRank1ToRank8 FastCoorFromBitBoardRank1ToRank8 -#endif // !CROUTINES // Bishop/knight/rook mobility computed during their own eval pass only // knows about enemy PAWN attacks (bishop/knight) or enemy PAWN+MINOR diff --git a/src/generate.c b/src/generate.c index 3411474..5435e04 100644 --- a/src/generate.c +++ b/src/generate.c @@ -46,9 +46,7 @@ Revision History: // (dead mailbox-fallback paths under this build's *_BITBOARD toggles, // but still worth keeping fast for other toggle combinations) to the // inlined FastCoorFromBitBoardRank8ToRank1 (chess.h) instead. -#ifndef CROUTINES #define CoorFromBitBoardRank8ToRank1 FastCoorFromBitBoardRank8ToRank1 -#endif // // Note: this order is important because of how EvalQueen works diff --git a/src/probe.c b/src/probe.c index 33dd602..c930f2d 100644 --- a/src/probe.c +++ b/src/probe.c @@ -37,9 +37,7 @@ Revision History: // builder bitboard-scan loops to the inlined // FastCoorFromBitBoardRank8ToRank1 (chess.h) instead of the real // out-of-line extern call. -#ifndef CROUTINES #define CoorFromBitBoardRank8ToRank1 FastCoorFromBitBoardRank8ToRank1 -#endif ULONG g_uEgtbLock = 0; diff --git a/src/recogn.c b/src/recogn.c index 3263908..67ed0c8 100644 --- a/src/recogn.c +++ b/src/recogn.c @@ -28,9 +28,7 @@ Revision History: // RecognLookup in search.c) to the inlined // FastCoorFromBitBoardRank8ToRank1 (chess.h) instead of the real // out-of-line extern call. -#ifndef CROUTINES #define CoorFromBitBoardRank8ToRank1 FastCoorFromBitBoardRank8ToRank1 -#endif extern ULONG g_uIterateDepth; static COOR QUEENING_SQUARE_BY_COLOR_FILE[2][8] = diff --git a/src/x64.asm b/src/x64.asm deleted file mode 100644 index fb42ff3..0000000 --- a/src/x64.asm +++ /dev/null @@ -1,320 +0,0 @@ -%ifdef _X64_ -[BITS 64] - -[SEGMENT .data] - -[EXTERN g_VectorDelta] -[EXTERN g_PieceData] - -%ifdef OSX -;;; Note: The reason for this OSX stuff is that there is a bug in the mac -;;; version of nasm. See comments in data.c for more details. - -[GLOBAL g_NasmVectorDelta] -[GLOBAL _g_NasmVectorDelta] -g_NasmVectorDelta: -_g_NasmVectorDelta: - alignb 32, db 0 - times 256 * 4 db 0 - -[GLOBAL g_NasmPieceData] -[GLOBAL _g_NasmPieceData] -g_NasmPieceData: -_g_NasmPieceData: - alignb 32, db 0 - times 4 * 4 * 8 db 0 -%else -[EXTERN g_VectorDelta] -[EXTERN g_PieceData] -%endif - -[SEGMENT .text] - -%ifndef CROUTINES -[GLOBAL LastBit] -[GLOBAL _LastBit] - ;; - ;; ULONGLONG CDECL - ;; LastBit(BITBOARD bb) - ;; -LastBit: -_LastBit: - bsr rax, rdi - jnz .found - xor rax, rax - ret -.found: add rax, 1 - ret - int 3 - -[GLOBAL FirstBit] -[GLOBAL _FirstBit] - ;; - ;; ULONGLONG CDECL - ;; FirstBit(BITBOARD bb) - ;; -FirstBit: -_FirstBit: - bsf rax, rdi - jnz .found - xor rax, rax - ret -.found: add rax, 1 - ret - int 3 - -[GLOBAL CountBits] -[GLOBAL _CountBits] - ;; - ;; ULONGLONG CDECL - ;; CountBits(BITBOARD bb) - ;; -CountBits: -_CountBits: - xor rax, rax - mov rcx, rdi - test rcx, rcx - jz .done -.again: add rax, 1 - mov rdx, rcx - sub rdx, 1 - and rcx, rdx - jnz .again -.done: ret - int 3 - -%if 0 -;; Retired 2026-09-06 (board_representation/MIGRATION.md section 7): -;; _GetAttacksBB (see.c) is now the only GetAttacks implementation -- -;; all retirement criteria (correctness sweep, isolated + whole-engine -;; benchmarks, match_play.py gate) cleared. Left assembled-out rather -;; than deleted. -[GLOBAL GetAttacks] -[GLOBAL _GetAttacks] - - db 43h,30h,50h,56h,72h,31h,47h,34h,54h,20h,32h,30h,30h - db 36h,20h,53h,63h,30h,74h,74h,20h,47h,61h,73h,63h,34h - -iDelta dd -17 - dd +15 - -;; [rbp-0x8] is the saved rbx from the "push rbx" in the prologue below; -;; locals must start below that, not alias it. -%define pOldList qword [rbp-0x10] -%define c dword [rbp-0x14] -%define x dword [rbp-0x18] -%define cSquareSave dword [rbp-0x1C] -%define uSideSave dword [rbp-0x20] - -%define _cNonPawns 0x478 -%define _uNonPawnCount 0x500 -%define _rgSquare 0x0 - - ;; - ;; void CDECL (SysV AMD64 ABI) - ;; GetAttacks(SEE_LIST *pList, ; rdi - ;; POSITION *pos, ; rsi - ;; COOR cSquare, ; edx - ;; ULONG uSide) ; ecx - ;; - ;; NOTE: a square (COOR) is always >= 0, but a square-minus- - ;; square delta is not. Any such delta must be sign-extended - ;; into a 64-bit register (movsxd) before being used as a - ;; scaled memory index: using the raw 32-bit register zero- - ;; extends it into a huge positive 64-bit value instead of the - ;; intended negative offset. This is the same bug that turned - ;; up in the C DISTANCE macro -- see chess.h. - ;; -GetAttacks: -_GetAttacks: - push rbp - mov rbp, rsp - push rbx - sub rsp, 0x20 - - mov cSquareSave, edx - mov uSideSave, ecx - - mov pOldList, rdi ; pOldList = pList - mov dword [rdi], 0 ; pList->uCount = 0 - add rdi, 4 ; rdi = &pList->data[0] - - ;; ebx = c = cSquare + iDelta[uSide] - movsxd rax, uSideSave - mov ebx, [iDelta+rax*4] - add ebx, cSquareSave - - ;; ecx = pPawn = BLACK_PAWN | uColor - mov ecx, uSideSave - or ecx, 2 - - ;; - ;; Check the pawns - ;; - test ebx, 0x88 - jnz .try_other_pawn - movsxd rax, ebx - mov eax, dword [rsi+rax*8+_rgSquare] - cmp eax, ecx - jne .try_other_pawn - mov rax, pOldList - mov dword [rax], 1 - mov dword [rdi], ecx - mov dword [rdi+4], ebx - mov dword [rdi+8], 100 - add rdi, 12 - -.try_other_pawn: - add ebx, 2 - test ebx, 0x88 - jnz .done_pawns - movsxd rax, ebx - mov eax, dword [rsi+rax*8+_rgSquare] - cmp eax, ecx - jne .done_pawns - mov dword [rdi], ecx - mov dword [rdi+4], ebx - mov dword [rdi+8], 100 - mov rax, pOldList - add rdi, 12 - add dword [rax], 1 - -.done_pawns: - ;; - ;; Do pieces - ;; - ;; x = pos->uNonPawnCount[uSide][0] - mov eax, uSideSave - shl eax, 5 ; uSide * 32 - movsxd rax, eax - mov ecx, dword [rsi+rax+_uNonPawnCount] - mov x, ecx - -.loop_continue: - mov ecx, x - sub ecx, 1 - cmp ecx, 0 - jl near .done - mov x, ecx - - ;; eax = c = pos->cNonPawns[uSide][x] - mov eax, uSideSave - shl eax, 4 - add eax, ecx ; eax = uSide*16 + x - movsxd rax, eax - mov eax, dword [rsi+rax*4+_cNonPawns] - mov c, eax - - ;; ecx = p = pos->pSquare[c] - movsxd rax, eax - mov ecx, dword [rsi+rax*8+_rgSquare] - - ;; r8 = iIndex = c - cSquare (must stay signed) - sub eax, cSquareSave - movsxd r8, eax - - ;; - ;; If there is no way for that kind of piece to get to this - ;; square then keep looking. - ;; - mov ebx, 1 - mov r9d, ecx ; r9 = p, survives to .nothing_blocks - shr ecx, 1 - shl ebx, cl - test byte [g_VectorDelta+r8*4+512], bl - jz .loop_continue - - ;; if (IS_KNIGHT_OR_KING(p)) goto nothing_blocks - and ecx, 3 - cmp ecx, 2 - mov ecx, c - je .nothing_blocks - - ;; - ;; Not a knight or king. Check to see if there is a piece in - ;; the path from cSquare to c that blocks the attack. - ;; - movsx ebx, byte [g_VectorDelta+r8*4+515] - mov eax, cSquareSave -.block_loop: - add eax, ebx - cmp eax, ecx - je .nothing_blocks - movsxd rdx, eax - cmp dword [rsi+rdx*8], 0 - jne .loop_continue - jmp .block_loop - -.nothing_blocks: - mov dword [rdi], r9d - mov dword [rdi+4], ecx - - ;; index into g_PieceData: sizeof(PIECE_DATA) is 24 on x64 (not - ;; 16, as on x86) because its trailing "CHAR *szName" widens - ;; from 4 to 8 bytes and pads the struct to 8-byte alignment. - mov ecx, r9d - shr ecx, 1 - imul ecx, ecx, 24 - movsxd rcx, ecx - mov ebx, dword [g_PieceData+rcx] - mov dword [rdi+8], ebx - - mov rax, pOldList - add rdi, 12 - add dword [rax], 1 - jmp .loop_continue - -.done: add rsp, 0x20 - pop rbx - pop rbp - ret -%endif ; 0 (retired GetAttacks) -%endif ; !CROUTINES - -[GLOBAL LockCompareExchange] -[GLOBAL _LockCompareExchange] - ;; - ;; ULONG CDECL - ;; LockCompareExchange(void *dest, ; rdi (SysV AMD64 ABI) - ;; ULONG exch, ; esi - ;; ULONG comp) ; edx - ;; -LockCompareExchange: -_LockCompareExchange: - mov eax, edx ; comp -> eax (cmpxchg's implicit compare reg) - mov rcx, rdi ; dest pointer -> rcx - lock cmpxchg dword [rcx], esi - ret - int 3 - -[GLOBAL LockIncrement] -[GLOBAL _LockIncrement] - ;; - ;; ULONG CDECL - ;; LockIncrement(ULONG *pDest) ; rdi (SysV AMD64 ABI) - ;; -LockIncrement: -_LockIncrement: - mov rcx, rdi - mov eax, 1 - lock xadd [rcx], eax - add eax, 1 - ret - int 3 - -[GLOBAL LockDecrement] -[GLOBAL _LockDecrement] - ;; - ;; ULONG CDECL - ;; LockDecrement(ULONG *pDest) ; rdi (SysV AMD64 ABI) - ;; -LockDecrement: -_LockDecrement: - mov rcx, rdi - mov eax, -1 - lock xadd [rcx], eax - add eax, -1 - ret - int 3 - -%endif ; X64 diff --git a/src/x86.asm b/src/x86.asm deleted file mode 100644 index 8a3f51a..0000000 --- a/src/x86.asm +++ /dev/null @@ -1,422 +0,0 @@ -%ifdef _X86_ -[BITS 32] - -;;; -;;; For some reason MSVC like to put an extra underscore in front of -;;; global identifer names. If this is gcc, compensate. -;;; -%ifdef __GNUC__ -%define _g_VectorDelta g_VectorDelta -%define _g_PieceData g_PieceData -%endif - -[SEGMENT .data] -ParallelScratch: -_ParallelScratch: - db 43h,30h,50h,56h, 72h,31h,47h,34h, 54h,20h,32h,30h - db 30h,36h,20h,53h, 63h,30h,74h,74h, 20h,47h,61h,73h - db 63h,34h,00h,01h, 22h,15h,48h,35h, 31h,21h,55h,46h - -%ifdef OSX -;;; Note: The reason for this OSX stuff is that there is a bug in the mac -;;; version of nasm. See comments in data.c for more details. - -[GLOBAL g_NasmVectorDelta] -[GLOBAL _g_NasmVectorDelta] -g_NasmVectorDelta: -_g_NasmVectorDelta: - alignb 32, db 0 - times 256 * 4 db 0 - -[GLOBAL g_NasmPieceData] -[GLOBAL _g_NasmPieceData] -g_NasmPieceData: -_g_NasmPieceData: - alignb 32, db 0 - times 4 * 4 * 8 db 0 -%else -[EXTERN _g_VectorDelta] -[EXTERN _g_PieceData] -%endif - -[SEGMENT .text] - -%ifndef CROUTINES -[GLOBAL LastBit] -[GLOBAL _LastBit] - ;; - ;; ULONG CDECL - ;; LastBit(BITBOARD bb) - ;; -LastBit: -_LastBit: - mov ecx, [esp+8] - mov edx, [esp+4] - bsr eax, ecx - jnz .lone - bsr eax, edx - jnz .ltwo - xor eax, eax - jmp .ldone -.lone: add eax, 32 -.ltwo: add eax, 1 -.ldone: ret - - int 3 - -[GLOBAL FirstBit] -[GLOBAL _FirstBit] - ;; - ;; ULONG CDECL - ;; FirstBit(BITBOARD bb) - ;; -FirstBit: -_FirstBit: - mov ecx, [esp+8] ; half of bb - mov edx, [esp+4] ; the other half - bsf eax, edx - jnz .low - bsf eax, ecx - jnz .hi - xor eax, eax - ret -.hi: add eax, 32 -.low: add eax, 1 - ret - - int 3 - -[GLOBAL CountBits] -[GLOBAL _CountBits] - ;; - ;; ULONG CDECL - ;; CountBits(BITBOARD bb) - ;; -CountBits: -_CountBits: - xor eax, eax ; eax is the count - mov ecx, [esp+4] ; half of bb - test ecx, ecx - jz .c2 ; skip first loop? -.c1: add eax, 1 - mov edx, ecx - sub edx, 1 - and ecx, edx - jnz .c1 -.c2: mov ecx, [esp+8] ; the other half of bb - test ecx, ecx - jz .cdone ; skip second loop? -.c3: add eax, 1 - mov edx, ecx - sub edx, 1 - and ecx, edx - jnz .c3 -.cdone: ret - - int 3 -%endif - -[GLOBAL LockCompareExchange] -[GLOBAL _LockCompareExchange] - -%define uComp esp+0xC -%define uExch esp+8 -%define pDest esp+4 - - ;; - ;; ULONG CDECL - ;; LockCompareExchange(void *dest, ; esp + 4 - ;; ULONG exch, ; esp + 8 - ;; ULONG comp) ; esp + C - ;; -LockCompareExchange: -_LockCompareExchange: - mov ecx, [pDest] - mov edx, [uExch] - mov eax, [uComp] - lock cmpxchg dword [ecx], edx - ret - - int 3 - -[GLOBAL LockIncrement] -[GLOBAL _LockIncrement] - ;; - ;; ULONG CDECL - ;; LockIncrement(ULONG *pDest) - ;; -LockIncrement: -_LockIncrement: - mov ecx, [pDest] - mov eax, 1 - lock xadd [ecx], eax - add eax, 1 - ret - - int 3 - -[GLOBAL LockDecrement] -[GLOBAL _LockDecrement] - ;; - ;; ULONG CDECL - ;; LockDecrement(ULONG *pDest) - ;; -LockDecrement: -_LockDecrement: - mov ecx, [pDest] - mov eax, -1 - lock xadd [ecx], eax - add eax, -1 - ret - - int 3 - -%ifndef CROUTINES -[GLOBAL GetAttacks] -[GLOBAL _GetAttacks] - - db 43h,30h,50h,56h,72h,31h,47h,34h,54h,20h,32h,30h,30h - db 36h,20h,53h,63h,30h,74h,74h,20h,47h,61h,73h,63h,34h - -iDelta dd -17 - dd +15 - -%define uSide ebp+0x14 -%define cSquare ebp+0x10 -%define pos ebp+0xC -%define pList ebp+8 -;; retaddr ebp+4 -;; old ebp ebp -;; old ebx ebp-4 -;; old esi ebp-8 -;; old edi ebp-0xC -%define pOldList ebp-0x10 -%define c ebp-0x14 -%define x ebp-0x18 - -%define _cNonPawns 0x478 -%define _uNonPawnCount 0x500 -%define _rgSquare 0x0 - - ;; - ;; void CDECL - ;; GetAttacks(SEE_LIST *pList, ; ebp + 8 - ;; POSITION *pos, ; ebp + 0xC - ;; COOR cSquare, ; ebp + 0x10 - ;; ULONG uSide) ; ebp + 0x14 - ;; -GetAttacks: -_GetAttacks: - push ebp - mov ebp, esp - push ebx - push esi - push edi - - ;; SEE_LIST *pOldList - ;; COOR c - ;; int x - sub esp, 0xC - - mov ecx, [pList] - mov edx, [pos] - - ;; pOldList = pList; - mov dword [pOldList], ecx - - ;; pList.uCount = 0; - mov dword [ecx], 0 - - ;; pList = &(pList.data[0]); - add ecx, 4 - mov edi, ecx - - ;; c = cSquare + iDelta[uColor] - mov esi, dword [uSide] - mov ebx, dword [cSquare] - mov eax, dword [iDelta+esi*4] - add ebx, eax - - ;; pPawn = BLACK_PAWN | uColor - mov ecx, esi - or ecx, 2 - - ;; - ;; Check the pawns - ;; - - ;; if (!IS_ON_BOARD(c)) goto try other pawn - test ebx, 0x88 - jnz .try_other_pawn - - ;; p = pos->pSquare[c]; - mov eax, dword [edx+ebx*8+_rgSquare] - - ;; if (p != pPawn) then goto try other pawn - cmp eax, ecx - jne .try_other_pawn - - ;; pOldList->uCount = 1 - mov dword [edi-4], 1 - - ;; pList->pPiece = p; - mov dword [edi], ecx - - ;; pList->cLoc = c; - mov dword [edi+4], ebx - - ;; pList->iVal = VALUE_PAWN; - mov dword [edi+8], 100 - - ;; pList++ - add edi, 12 - -.try_other_pawn: - ;; c = c + 2 - add ebx, 2 - - ;; if (!IS_ON_BOARD(c)) goto done pawns - test ebx, 0x88 - jnz .done_pawns - - ;; p = pos->pSquare[c]; - mov eax, dword [edx+ebx*8+_rgSquare] - - ;; if (p != pPawn) then goto done pawns - cmp eax, ecx - jne .done_pawns - - ;; pList->pPiece = p; - mov dword [edi], ecx - - ;; pList->cLoc = c; - mov dword [edi+4], ebx - - ;; pList->iVal = VALUE_PAWN; - mov dword [edi+8], 100 - - ;; pOldList->uCount++ - ;; pList++ - mov eax, [pOldList] - add edi, 12 - add dword [eax], 1 - -.done_pawns: - - ;; - ;; Do pieces - ;; - - ;; for (x = pos->uNonPawnCount[uSide][0] - 1; - ;; x >= 0; - ;; x--) - ;; { - lea eax, [esi*8] - mov ecx, dword [edx+eax*4+_uNonPawnCount] - mov dword [x], ecx - -.loop_continue: - mov ecx, dword [x] - sub ecx, 1 - cmp ecx, 0 - jl near .done - mov esi, dword [uSide] - mov dword [x], ecx - - ;; c = pos->cNonPawns[uSide][x]; - mov eax, esi - shl eax, 4 - add eax, ecx - mov eax, dword [edx+eax*4+_cNonPawns] - mov dword [c], eax - - ;; p = pos->pSquare[c]; - mov ecx, dword [edx+eax*8+_rgSquare] - - ;; iIndex = c - cSquare; - sub eax, dword [cSquare] - - ;; - ;; If there is no way for that kind of piece to get to this - ;; square then keep looking. - ;; - ;; if (0 == (g_VectorDeltaTable[iIndex].iVector[iSide] & - ;; (1 << (PIECE_PIECE(p) >> 1)))) continue; - mov ebx, 1 - mov esi, ecx - shr ecx, 1 - shl ebx, cl -%ifdef OSX - test byte [_g_NasmVectorDelta+eax*4+512], bl -%else - test byte [_g_VectorDelta+eax*4+512], bl -%endif - jz .loop_continue - - ;; if (IS_KNIGHT_OR_KING(p)) goto nothing_blocks - and ecx, 3 - cmp ecx, 2 - mov ecx, dword [c] - je .nothing_blocks - - ;; - ;; Not a knight or king. Check to see if there is a piece in - ;; the path from cSquare to c that blocks the attack. - ;; - ;; iDelta = g_VectorDeltaTable[iIndex].iNegDelta; -%ifdef OSX - movsx ebx, byte [_g_NasmVectorDelta+eax*4+515] -%else - movsx ebx, byte [_g_VectorDelta+eax*4+515] -%endif - - ;; cBlockIndex = cSquare + iDelta - mov eax, dword [cSquare] -.block_loop: - add eax, ebx - - ;; if (cBlockIndex != c) - ;; { - cmp eax, ecx - je .nothing_blocks - - ;; if (IS_EMPTY(pos->pSquare[cBlockIndex])) - ;; { - cmp dword [edx+eax*8], 0 - jne .loop_continue - - ;; goto cond - jmp .block_loop - -.nothing_blocks: - ;; pList->pPiece[pList->iCount] = p; - mov dword [edi], esi - - ;; pList->cLoc[pList->iCount] = c; - mov dword [edi+4], ecx - - ;; pList->iVal[pList->iCount] = PIECE_VALUE(p) - mov ecx, esi - shr ecx, 1 - shl ecx, 4 -%ifdef OSX - mov ebx, dword [_g_NasmPieceData+ecx] -%else - mov ebx, dword [_g_PieceData+ecx] -%endif - mov dword [edi+8], ebx - - ;; uCount++ - mov eax, dword [pOldList] - add edi, 12 - add dword [eax], 1 - jmp .loop_continue - -.done: add esp, 0xC - pop edi ; restore saved registers - pop esi - pop ebx - leave - ret -%endif ; CROUTINES -%endif ; X86 |
