/*--------------------------------------------------------------------------
    Pawny 0.3, chess engine (source code).
    Copyright (C) 2009 - 2011 by Mincho Georgiev.
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
    contact: pawnychess@gmail.com 
    web: http://www.pawny.netii.net/
----------------------------------------------------------------------------*/

static __forceinline void bitset(unsigned __int64 *bb, int index) { *bb |= (1ULL << index); }
static __forceinline void bitclear(unsigned __int64 *bb, int index) {*bb &= ~(1ULL << index);}


#if defined(_M_IX86) && (defined(__INTEL_COMPILER) || defined(_MSC_VER))
static  __forceinline int bitscanf(unsigned __int64 bb)
{	__asm
	{	xor eax,eax
		bsf eax,dword ptr[bb]
		jne lret
		bsf eax,dword ptr[bb+4]
		je lret
		add eax,20h
		lret:
	}
}

static  __forceinline int bitscanr(unsigned __int64 bb)
{	__asm
	{	xor eax,eax
		bsr eax,dword ptr[bb+4]
		je l1
		add eax,20h
		jmp lret
		l1:
		bsr eax,dword ptr[bb]
		lret:
	}
}

static __forceinline int popcnt(unsigned __int64 w)
{	unsigned int w1,w2;
	w1 = (unsigned int)(w & 0xFFFFFFFF);
	w2 = (unsigned int)(w >> 32);
	w1 -= (w1 >> 1) & 0x55555555;
	w1 = (w1 & 0x33333333) + ((w1 >> 2) & 0x33333333);
	w1 = (w1 + (w1 >> 4)) & 0x0F0F0F0F;
	w2 -= (w2 >> 1) & 0x55555555;
	w2 = (w2 & 0x33333333) + ((w2 >> 2) & 0x33333333);
	w2 = (w2 + (w2 >> 4)) & 0x0F0F0F0F;
	return ((w1 * 0x01010101) >> 24)+((w2 * 0x01010101) >> 24);
}

#else if(defined(_M_IX64)) && (defined(__INTEL_COMPILER)))
static  __forceinline int bitscanf(unsigned __int64 bb)
{	__asm
	{	xor rax,rax
		bsf rax,qword ptr[bb]
	}
}


static  __forceinline int bitscanr(unsigned __int64 bb)
{	__asm
	{	xor rax,rax
		bsr rax,qword ptr[bb]
	}
}

static __forceinline int popcnt(unsigned __int64 w)
{	w -= ((w >> 1) & 0x5555555555555555ULL);
	w = (w & 0x3333333333333333ULL) + ((w >> 2) & 0x3333333333333333ULL);
	w = (w + (w >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
	return (int)((w * 0x0101010101010101ULL) >> 56);
}
#endif

