Update codebase to remove clang warnings (and a couple of legit errors
[typhoon.git] / src / x86.asm
1 %ifdef _X86_
2 [BITS 32]
3
4 ;;; 
5 ;;; For some reason MSVC like to put an extra underscore in front of
6 ;;; global identifer names.  If this is gcc, compensate.
7 ;;; 
8 %ifdef __GNUC__
9 %define _g_VectorDelta g_VectorDelta
10 %define _g_PieceData g_PieceData
11 %endif
12
13 [SEGMENT .data]
14 ParallelScratch:
15 _ParallelScratch:
16     db 43h,30h,50h,56h, 72h,31h,47h,34h, 54h,20h,32h,30h 
17     db 30h,36h,20h,53h, 63h,30h,74h,74h, 20h,47h,61h,73h
18     db 63h,34h,00h,01h, 22h,15h,48h,35h, 31h,21h,55h,46h
19
20 %ifdef OSX
21 ;;; Note: The reason for this OSX stuff is that there is a bug in the mac
22 ;;; version of nasm.  See comments in data.c for more details.
23        
24 [GLOBAL g_NasmVectorDelta]
25 [GLOBAL _g_NasmVectorDelta]
26 g_NasmVectorDelta:
27 _g_NasmVectorDelta: 
28     alignb 32, db 0
29     times 256 * 4 db 0
30
31 [GLOBAL g_NasmPieceData]
32 [GLOBAL _g_NasmPieceData]
33 g_NasmPieceData:
34 _g_NasmPieceData:               
35     alignb 32, db 0
36     times 4 * 4 * 8 db 0
37 %else
38 [EXTERN _g_VectorDelta]
39 [EXTERN _g_PieceData]
40 %endif
41
42 [SEGMENT .text]
43
44 %ifndef CROUTINES        
45 [GLOBAL LastBit]
46 [GLOBAL _LastBit]
47         ;; 
48         ;; ULONG CDECL
49         ;; LastBit(BITBOARD bb)
50         ;; 
51 LastBit:
52 _LastBit:
53         mov ecx, [esp+8]
54         mov edx, [esp+4]
55         bsr eax, ecx
56         jnz .lone
57         bsr eax, edx
58         jnz .ltwo
59         xor eax, eax
60         jmp .ldone
61 .lone:  add eax, 32
62 .ltwo:  add eax, 1
63 .ldone: ret
64
65         int 3
66
67 [GLOBAL FirstBit]
68 [GLOBAL _FirstBit]
69         ;; 
70         ;; ULONG CDECL
71         ;; FirstBit(BITBOARD bb)
72         ;; 
73 FirstBit:      
74 _FirstBit:      
75         mov ecx, [esp+8]        ; half of bb
76         mov edx, [esp+4]        ; the other half
77         bsf eax, edx
78         jnz .low
79         bsf eax, ecx
80         jnz .hi
81         xor eax, eax
82         ret
83 .hi:    add eax, 32
84 .low:   add eax, 1
85         ret
86
87         int 3
88
89 [GLOBAL CountBits]
90 [GLOBAL _CountBits]
91         ;; 
92         ;; ULONG CDECL
93         ;; CountBits(BITBOARD bb)
94         ;; 
95 CountBits:     
96 _CountBits:
97         xor eax, eax            ; eax is the count
98         mov ecx, [esp+4]        ; half of bb
99         test ecx, ecx
100         jz .c2                  ; skip first loop?
101 .c1:    add eax, 1
102         mov edx, ecx
103         sub edx, 1
104         and ecx, edx
105         jnz .c1
106 .c2:    mov ecx, [esp+8]        ; the other half of bb
107         test ecx, ecx
108         jz .cdone               ; skip second loop?
109 .c3:    add eax, 1
110         mov edx, ecx
111         sub edx, 1
112         and ecx, edx
113         jnz .c3
114 .cdone: ret
115
116         int 3
117 %endif
118
119 [GLOBAL LockCompareExchange]
120 [GLOBAL _LockCompareExchange]
121
122 %define uComp esp+0xC
123 %define uExch esp+8
124 %define pDest esp+4
125         
126         ;; 
127         ;; ULONG CDECL
128         ;; LockCompareExchange(void *dest, ; esp + 4
129         ;;                     ULONG exch, ; esp + 8
130         ;;                     ULONG comp) ; esp + C
131         ;; 
132 LockCompareExchange:
133 _LockCompareExchange:
134         mov ecx, [pDest]
135         mov edx, [uExch]
136         mov eax, [uComp]
137         lock cmpxchg dword [ecx], edx
138         ret
139
140         int 3
141
142 [GLOBAL LockIncrement]
143 [GLOBAL _LockIncrement]
144         ;;
145         ;; ULONG CDECL
146         ;; LockIncrement(ULONG *pDest)
147         ;; 
148 LockIncrement:
149 _LockIncrement:
150         mov ecx, [pDest]
151         mov eax, 1
152         lock xadd [ecx], eax
153         add eax, 1
154         ret
155
156         int 3
157
158 [GLOBAL LockDecrement]
159 [GLOBAL _LockDecrement]
160         ;;
161         ;; ULONG CDECL
162         ;; LockDecrement(ULONG *pDest)
163         ;; 
164 LockDecrement:
165 _LockDecrement:
166         mov ecx, [pDest]
167         mov eax, -1
168         lock xadd [ecx], eax
169         add eax, -1
170         ret
171
172         int 3
173
174 %ifndef CROUTINES
175 [GLOBAL GetAttacks]
176 [GLOBAL _GetAttacks]
177
178         db 43h,30h,50h,56h,72h,31h,47h,34h,54h,20h,32h,30h,30h
179         db 36h,20h,53h,63h,30h,74h,74h,20h,47h,61h,73h,63h,34h
180         
181 iDelta  dd -17
182         dd +15
183
184 %define uSide    ebp+0x14
185 %define cSquare  ebp+0x10
186 %define pos      ebp+0xC
187 %define pList    ebp+8
188 ;;      retaddr  ebp+4
189 ;;      old ebp  ebp
190 ;;      old ebx  ebp-4
191 ;;      old esi  ebp-8
192 ;;      old edi  ebp-0xC
193 %define pOldList ebp-0x10
194 %define c        ebp-0x14
195 %define x        ebp-0x18
196
197 %define _cNonPawns     0x478
198 %define _uNonPawnCount 0x500
199 %define _rgSquare      0x0
200                         
201         ;; 
202         ;; void CDECL
203         ;; GetAttacks(SEE_LIST *pList,  ; ebp + 8
204         ;;            POSITION *pos,    ; ebp + 0xC
205         ;;            COOR cSquare,     ; ebp + 0x10
206         ;;            ULONG uSide)      ; ebp + 0x14
207         ;; 
208 GetAttacks:
209 _GetAttacks:
210         push ebp
211         mov ebp, esp
212         push ebx
213         push esi
214         push edi
215         
216         ;; SEE_LIST *pOldList
217         ;; COOR c
218         ;; int x
219         sub esp, 0xC
220
221         mov ecx, [pList]
222         mov edx, [pos]
223
224         ;; pOldList = pList;
225         mov dword [pOldList], ecx
226
227         ;; pList.uCount = 0;
228         mov dword [ecx], 0
229
230         ;; pList = &(pList.data[0]);
231         add ecx, 4
232         mov edi, ecx
233
234         ;; c = cSquare + iDelta[uColor]
235         mov esi, dword [uSide]
236         mov ebx, dword [cSquare]
237         mov eax, dword [iDelta+esi*4] 
238         add ebx, eax
239
240         ;; pPawn = BLACK_PAWN | uColor
241         mov ecx, esi
242         or ecx, 2
243
244         ;;
245         ;; Check the pawns
246         ;;
247         
248         ;; if (!IS_ON_BOARD(c)) goto try other pawn
249         test ebx, 0x88
250         jnz .try_other_pawn
251
252         ;; p = pos->pSquare[c];
253         mov eax, dword [edx+ebx*8+_rgSquare]
254
255         ;; if (p != pPawn) then goto try other pawn
256         cmp eax, ecx
257         jne .try_other_pawn
258
259         ;; pOldList->uCount = 1
260         mov dword [edi-4], 1
261
262         ;; pList->pPiece = p;
263         mov dword [edi], ecx
264
265         ;; pList->cLoc = c;
266         mov dword [edi+4], ebx
267
268         ;; pList->iVal = VALUE_PAWN;
269         mov dword [edi+8], 100
270
271         ;; pList++
272         add edi, 12
273
274 .try_other_pawn:
275         ;; c = c + 2
276         add ebx, 2
277
278         ;; if (!IS_ON_BOARD(c)) goto done pawns
279         test ebx, 0x88
280         jnz .done_pawns
281
282         ;; p = pos->pSquare[c];
283         mov eax, dword [edx+ebx*8+_rgSquare]
284
285         ;; if (p != pPawn) then goto done pawns
286         cmp eax, ecx
287         jne .done_pawns
288
289         ;; pList->pPiece = p;
290         mov dword [edi], ecx
291
292         ;; pList->cLoc = c;
293         mov dword [edi+4], ebx
294
295         ;; pList->iVal = VALUE_PAWN;
296         mov dword [edi+8], 100
297
298         ;; pOldList->uCount++
299         ;; pList++
300         mov eax, [pOldList]
301         add edi, 12
302         add dword [eax], 1
303
304 .done_pawns:
305
306         ;;
307         ;; Do pieces
308         ;;
309         
310         ;; for (x = pos->uNonPawnCount[uSide][0] - 1;
311         ;;      x >= 0;
312         ;;      x--)
313         ;; {
314         lea eax, [esi*8]
315         mov ecx, dword [edx+eax*4+_uNonPawnCount]
316         mov dword [x], ecx
317
318 .loop_continue:
319         mov ecx, dword [x]
320         sub ecx, 1
321         cmp ecx, 0
322         jl near .done
323         mov esi, dword [uSide]
324         mov dword [x], ecx
325
326         ;; c = pos->cNonPawns[uSide][x];
327         mov eax, esi
328         shl eax, 4
329         add eax, ecx
330         mov eax, dword [edx+eax*4+_cNonPawns]
331         mov dword [c], eax
332
333         ;; p = pos->pSquare[c];
334         mov ecx, dword [edx+eax*8+_rgSquare]
335
336         ;; iIndex = c - cSquare;
337         sub eax, dword [cSquare]
338
339         ;;
340         ;; If there is no way for that kind of piece to get to this
341         ;; square then keep looking.
342         ;;
343         ;; if (0 == (g_VectorDeltaTable[iIndex].iVector[iSide] &
344         ;;          (1 << (PIECE_PIECE(p) >> 1)))) continue;
345         mov ebx, 1
346         mov esi, ecx
347         shr ecx, 1
348         shl ebx, cl
349 %ifdef OSX
350         test byte [_g_NasmVectorDelta+eax*4+512], bl
351 %else
352         test byte [_g_VectorDelta+eax*4+512], bl
353 %endif
354         jz .loop_continue
355
356         ;; if (IS_KNIGHT_OR_KING(p)) goto nothing_blocks
357         and ecx, 3
358         cmp ecx, 2
359         mov ecx, dword [c]
360         je .nothing_blocks
361
362         ;;
363         ;; Not a knight or king.  Check to see if there is a piece in 
364         ;; the path from cSquare to c that blocks the attack.
365         ;;
366         ;; iDelta = g_VectorDeltaTable[iIndex].iNegDelta;
367 %ifdef OSX
368         movsx ebx, byte [_g_NasmVectorDelta+eax*4+515]
369 %else
370         movsx ebx, byte [_g_VectorDelta+eax*4+515]
371 %endif
372
373         ;; cBlockIndex = cSquare + iDelta
374         mov eax, dword [cSquare]
375 .block_loop:
376         add eax, ebx
377
378         ;; if (cBlockIndex != c)
379         ;; {
380         cmp eax, ecx
381         je .nothing_blocks
382
383         ;;     if (IS_EMPTY(pos->pSquare[cBlockIndex]))
384         ;;     {
385         cmp dword [edx+eax*8], 0
386         jne .loop_continue
387
388         ;; goto cond
389         jmp .block_loop
390
391 .nothing_blocks:
392         ;; pList->pPiece[pList->iCount] = p;
393         mov dword [edi], esi
394
395         ;; pList->cLoc[pList->iCount] = c;
396         mov dword [edi+4], ecx
397
398         ;; pList->iVal[pList->iCount] = PIECE_VALUE(p)
399         mov ecx, esi
400         shr ecx, 1
401         shl ecx, 4
402 %ifdef OSX
403         mov ebx, dword [_g_NasmPieceData+ecx]
404 %else
405         mov ebx, dword [_g_PieceData+ecx]
406 %endif
407         mov dword [edi+8], ebx
408
409         ;; uCount++
410         mov eax, dword [pOldList]
411         add edi, 12
412         add dword [eax], 1
413         jmp .loop_continue
414
415 .done:  add esp, 0xC
416         pop edi                         ; restore saved registers
417         pop esi
418         pop ebx
419         leave
420         ret
421 %endif ; CROUTINES
422 %endif ; X86