//-----------------------------------------------------------------------------
// Copyright © 2003 - Philip Howard - All rights reserved
//
// 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 2
// 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, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//-----------------------------------------------------------------------------
// package	libh/bit
// homepage	http://libh.slashusr.org/
//-----------------------------------------------------------------------------
// author	Philip Howard
// email	libh at ipal dot org
// homepage	http://phil.ipal.org/
//-----------------------------------------------------------------------------
// This file is best viewed using a fixed spaced font such as Courier
// and in a display at least 120 columns wide.
//-----------------------------------------------------------------------------

#include "bit_lib.h"

__FMACRO_BEGIN__
//-----------------------------------------------------------------------------
// macro	bit_count_128
//
// purpose	Count the number of bits that are on in a 128 bit integer.
//
// arguments	(uint128_t) unsigned integer with bits to count
//
// returns	(int) <  0 : error
//		(int) >= 0 : number of bits that are on
//-----------------------------------------------------------------------------
#define bit_count_128_mask_1	UINT128_C( 0x55555555555555555555555555555555 )
#define bit_count_128_mask_2	UINT128_C( 0x33333333333333333333333333333333 )
#define bit_count_128_mask_3	UINT128_C( 0x07070707070707070707070707070707 )
#define bit_count_128_mask_4	UINT128_C( 0x000f000f000f000f000f000f000f000f )
#define bit_count_128_mask_5	UINT128_C( 0x0000001f0000001f0000001f0000001f )
#define bit_count_128_mask_6	UINT128_C( 0x000000000000003f000000000000003f )
#define bit_count_128_mask_7	( (int) 0x007f )
#define bit_count_128( b ) ({							\
	uint128_t d = ( b );							\
	d = ( d >>  1 & bit_count_128_mask_1 ) + ( d & bit_count_128_mask_1 );	\
	d = ( d >>  2 & bit_count_128_mask_2 ) + ( d & bit_count_128_mask_2 );	\
	d = ( d >>  4 & bit_count_128_mask_3 ) + ( d & bit_count_128_mask_3 );	\
	d = ( d >>  8 & bit_count_128_mask_4 ) + ( d & bit_count_128_mask_4 );	\
	d = ( d >> 16 & bit_count_128_mask_5 ) + ( d & bit_count_128_mask_5 );	\
	d = ( d >> 32 & bit_count_128_mask_6 ) + ( d & bit_count_128_mask_6 );	\
	( (int) ( d >> 64 ) & bit_count_128_mask_7 ) + ( (int) d & bit_count_128_mask_7 ); })

__FMACRO_END__

