added: static sint UInt<value_size>::FindLowestBitInWord(uint x)

(asm_vc_32, asm_gcc_32, no_asm, and intrinsic for vc64)



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@275 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2010-01-03 01:10:37 +00:00
parent 39db6fc469
commit e727eacce0
5 changed files with 120 additions and 16 deletions

View File

@ -34,8 +34,10 @@ Version 0.9.1 prerelease (2009.12.28):
- and the exponent is smaller than about 2 times the number of bits from the mantissa
this helps to correctly calculate expressions such as: "0.80-3*0.34+0.22"
now the parser gives zero (previous there was a value very closed to zero)
* added: static sint UInt<value_size>::FindLowestBitInWord(uint x)
this method is looking for the lowest set bit in a word
* added: UInt::FindLowestBit(uint & table_id, uint & index)
/temporarily version - asm version is missing /
this method is looking for the lowest set bit
Version 0.9.0 (2009.11.25):

View File

@ -672,27 +672,14 @@ public:
if( table_id >= value_size )
{
// is zero
index = 0;
index = 0;
table_id = 0;
return false;
}
// table[table_id] is different from 0
// !! need asm version:
// index = FindSmallestBitInWord( table[table_id] );
index = 0;
uint temp = table[table_id];
while( (temp & 1) == 0 )
{
index += 1;
temp >>= 1;
}
// !!
index = FindLowestBitInWord( table[table_id] );
return true;
}
@ -3498,6 +3485,7 @@ public:
uint SubInt(uint value, uint index = 0);
static uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result);
static sint FindLeadingBitInWord(uint x);
static sint FindLowestBitInWord(uint x);
static uint SetBitInWord(uint & value, uint bit);
static void MulTwoWords(uint a, uint b, uint * result_high, uint * result_low);
static void DivTwoWords(uint a,uint b, uint c, uint * r, uint * rest);

View File

@ -588,6 +588,27 @@ namespace ttmath
/*!
this method returns the number of the highest set bit in x
if the 'x' is zero this method returns '-1'
*/
template<uint value_size>
sint UInt<value_size>::FindLowestBitInWord(uint x)
{
if( x == 0 )
return -1;
uint bit = 0;
while( (x & 1) == 0 )
{
x = x >> 1;
++bit;
}
return bit;
}
/*!

View File

@ -1353,6 +1353,50 @@ namespace ttmath
/*
this method returns the number of the smallest set bit in one 32-bit word
if the 'x' is zero this method returns '-1'
*/
template<uint value_size>
sint UInt<value_size>::FindLowestBitInWord(uint x)
{
sint result;
#ifndef __GNUC__
__asm
{
push eax
push edx
mov edx,-1
bsf eax,[x]
cmovz eax,edx
mov [result], eax
pop edx
pop eax
}
#endif
#ifdef __GNUC__
uint dummy;
__asm__ (
"movl $-1, %1 \n"
"bsfl %2, %0 \n"
"cmovz %1, %0 \n"
: "=r" (result), "=&r" (dummy)
: "r" (x)
: "cc" );
#endif
return result;
}
/*!

View File

@ -987,6 +987,55 @@ namespace ttmath
}
/*
this method returns the number of the highest set bit in one 64-bit word
if the 'x' is zero this method returns '-1'
***this method is created only on a 64bit platform***
*/
template<uint value_size>
sint UInt<value_size>::FindLowestBitInWord(uint x)
{
sint result;
#if !defined(__GNUC__) && !defined(_MSC_VER)
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
unsigned long nIndex = 0;
if( _BitScanForward64(&nIndex,x) == 0 )
result = -1;
else
result = nIndex;
#endif
#ifdef __GNUC__
uint dummy;
__asm__ (
"movq $-1, %1 \n"
"bsfq %2, %0 \n"
"cmovz %1, %0 \n"
: "=r" (result), "=&r" (dummy)
: "r" (x)
: "cc" );
#endif
return result;
}
/*!
this method sets a special bit in the 'value'
and returns the last state of the bit (zero or one)