Computer Chess Club Archives


Search

Terms

Messages

Subject: Assembly Programmers Challenge!

Author: David Rasmussen

Date: 04:39:42 01/19/03


Here

http://www.talkchess.com/forums/1/message.html?278161

you can read about the code generated by MSVC (6 or 7) and Intel C++ for simple
64-bit constructs. I am wondering how much could be gained on x86 by defining
this and other fundamental functions in assembly.

Below are some inlined functions from my bitboard.h file. For people who know
bitboards, most of it should be obvious. My orientation is a1=0 .. h8=63. My
question to assembly programmers is: Can you make (hopefully faster) x86
assembly equivalents of these functions, since it seems the compilers can't even
generate good code for these simple things? I know x86/IA32 means many different
things, but I am talking about newer processors. I don't care if it doesn't work
on the original Pentium or K6. On the other hand, I would like to have "clean"
x86 versions instead of versions that works only on P4 for example (I don't have
a P4). Stuff that works on all newer processors such as MMX is ok, if it help
etc. I have an Athlon XP 1800+ myself.
Will you help me (and others)?

(well these are some constants, but maybe they're intereting to some)
const BitBoard lightSquares = 0x55aa55aa | (BitBoard(0x55aa55aa) << 32);
const BitBoard darkSquares = ~lightSquares;
const BitBoard center = 0x18000000 | BitBoard(0x00000018) << 32;

//INLINE BitBoard Mask(Square square) { return BitBoard(1) << square; }
INLINE BitBoard Mask(Square square) { return mask[square]; }
INLINE BitBoard RankMask(Rank rank) { return rankMask[rank]; }
INLINE BitBoard FileMask(File file) { return fileMask[file]; }
INLINE void Set(BitBoard& bitboard, Square square)
{ bitboard |= Mask(square); }
INLINE void Clear(BitBoard& bitboard, Square square)
{ bitboard &= ~Mask(square); }
INLINE void Toggle(BitBoard& bitboard, BitBoard mask)
{ bitboard ^= mask; }

INLINE Square Rotate45Left(Square square) { return rotate45Left[square]; }
INLINE Square Rotate45Right(Square square) { return rotate45Right[square]; }
INLINE Square Rotate90Left(Square square) { return rotate90Left[square]; }
INLINE Square UnRotate45Left(Square square) { return unrotate45Left[square]; }
INLINE Square UnRotate45Right(Square square) { return unrotate45Right[square]; }
INLINE Square UnRotate90Left(Square square) { return unrotate90Left[square]; }

INLINE void SetOccupied(Position& pos, Square square, Color color)
{
	Set(pos.occupied[color],square);
	Set(pos.occupiedRotate90Left,Rotate90Left(square));
	Set(pos.occupiedRotate45Left,Rotate45Left(square));
	Set(pos.occupiedRotate45Right,Rotate45Right(square));
}

INLINE void ClearOccupied(Position &pos, Square square, Color color)
{
	Clear(pos.occupied[color],square);
	Clear(pos.occupiedRotate90Left,Rotate90Left(square));
	Clear(pos.occupiedRotate45Left,Rotate45Left(square));
	Clear(pos.occupiedRotate45Right,Rotate45Right(square));
}

INLINE int RankShift(Square square) { return rankShift[square]; }
INLINE int FileShift(Square square) { return fileShift[square]; }

INLINE int DiagonalShiftA1H8(Square square)
{ return diagonalShiftA1H8[square]; }
INLINE int DiagonalShiftH1A8(Square square)
{ return diagonalShiftH1A8[square]; }

INLINE BitBoard Occupied(const Position &pos)
{ return pos.occupied[WHITE] | pos.occupied[BLACK]; }

INLINE BitBoard FileAttack(const Position& pos, Square square)
{
	return fileAttack
		[square]
		[int((pos.occupiedRotate90Left >> FileShift(square)) & 0xFF)];
}

INLINE BitBoard RankAttack(const Position& pos, Square square)
{
	return rankAttack
		[square]
		[int((Occupied(pos) >> RankShift(square)) & 0xFF)];
}

INLINE BitBoard DiagonalAttackA1H8(const Position& pos, Square square)
{
	return diagonalAttackA1H8
		[square]
		[int((pos.occupiedRotate45Right
			>> DiagonalShiftA1H8(square)) & 0xFF)];
}

INLINE BitBoard DiagonalAttackH1A8(const Position& pos, Square square)
{
	return diagonalAttackH1A8
		[square]
		[int((pos.occupiedRotate45Left
			>> DiagonalShiftH1A8(square)) & 0xFF)];
}

INLINE BitBoard PawnAttack(Square square, Color color)
{ return pawnAttack[color][square]; }

INLINE BitBoard KnightAttack(Square square)
{ return knightAttack[square]; }

INLINE BitBoard BishopAttack(const Position &pos, Square square)
{ return DiagonalAttackA1H8(pos,square) | DiagonalAttackH1A8(pos,square); }

INLINE BitBoard RookAttack(const Position& pos, Square square)
{ return RankAttack(pos,square) | FileAttack(pos,square); }

INLINE BitBoard QueenAttack(const Position& pos, Square square)
{ return RookAttack(pos,square) | BishopAttack(pos,square); }

INLINE BitBoard KingAttack(Square square)
{ return kingAttack[square]; }

I don't remember where I got these, I probably stole them or copied them from
discussions on CCC. Maybe they can be even faster:

INLINE int FirstBit(const BitBoard bitboard)
{
	__asm
	{
		mov ecx,dword ptr [bitboard+4]
		mov ebx,dword ptr [bitboard]
		bsf eax,ecx
		add eax,32
		bsf eax,ebx
	}
}

INLINE int LastBit(const BitBoard bitboard)
{
	__asm
	{
		mov ecx,dword ptr [bitboard]
		mov ebx,dword ptr [bitboard+4]
		bsr eax,ecx
		sub eax,32
		bsr eax,ebx
		add eax,32
	}
}

INLINE int PopCount(BitBoard a) // MMX
{
    static const __int64 C55 = 0x5555555555555555;
    static const __int64 C33 = 0x3333333333333333;
    static const __int64 C0F = 0x0F0F0F0F0F0F0F0F;

    __asm {
        movd            mm0, word ptr a;
        punpckldq       mm0, word ptr a + 4;
        movq            mm1, mm0;
        psrld           mm0, 1;
        pand            mm0, [C55];
        psubd           mm1, mm0;
        movq            mm0, mm1;
        psrld           mm1, 2;
        pand            mm0, [C33];
        pand            mm1, [C33];
        paddd           mm0, mm1;
        movq            mm1, mm0;
        psrld           mm0, 4;
        paddd           mm0, mm1;
        pand            mm0, [C0F];
        pxor            mm1, mm1;
        psadbw mm0, mm1;
        movd            eax, mm0;
        emms;
    }
}





This page took 0.01 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.