summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Gasch <[email protected]>2026-10-25 11:20:24 -0700
committerScott Gasch <[email protected]>2026-10-25 11:20:41 -0700
commitc1e8cefc7bf0c4017dda24b0486806ce3304a7ae (patch)
treeda5cfe55fe0af85c615db8c68320d53d1f67cf5c
parent455accb4cbb1777cb553b6d75136521c6b8d1c01 (diff)
Remove the x86/x64 assembly backend; use compiler intrinsics insteadHEADmaster
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/GNUmakefile44
-rw-r--r--src/board.c2
-rwxr-xr-xsrc/chess.h68
-rw-r--r--src/data.c15
-rw-r--r--src/eval.c3
-rw-r--r--src/generate.c2
-rw-r--r--src/probe.c2
-rw-r--r--src/recogn.c2
-rw-r--r--src/x64.asm320
-rw-r--r--src/x86.asm422
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
diff --git a/src/data.c b/src/data.c
index 8fc72cb..500af94 100644
--- a/src/data.c
+++ b/src/data.c
@@ -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
diff --git a/src/eval.c b/src/eval.c
index 0f2a556..141b92f 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -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