added: doxygen.cfg for generating a documentation from the doxygen
changed: UInt::Rcl(uint c=0) and UInt::Rcr(uint c=0) into UInt::Rcl2(uint bits, uint c) and UInt::Rcr2(uint bits, uint c) now they can move more than one bit and they are only private fixed: UInt::Rcl(uint bits, uint c) and UInt::Rcr(uint bits, uint c) didn't correctly return a carry if the 'bits' were equal to 'value_size*TTMATH_BITS_PER_UINT' changed: UInt::Rcl(uint bits, uint c) and UInt::Rcr(uint bits, uint c) into UInt::Rcl(uint bits, uint c=0) and UInt::Rcr(uint bits, uint c=0) they are faster now when the bits is greater than a half of the TTMATH_BITS_PER_UINT changed: UInt::CompensationToLeft() it's faster now changed: more small changes where there were UInt::Rcl(uint c=0) and UInt::Rcr(uint c=0) used git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@34 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
e40ed603c6
commit
0170572f84
File diff suppressed because it is too large
Load Diff
|
@ -561,7 +561,7 @@ public:
|
|||
// values have the same signs
|
||||
if( mantissa.Add(ss2.mantissa) )
|
||||
{
|
||||
mantissa.Rcr(1);
|
||||
mantissa.Rcr(1,1);
|
||||
c = exponent.AddOne();
|
||||
}
|
||||
}
|
||||
|
@ -570,7 +570,7 @@ public:
|
|||
// values have different signs
|
||||
if( mantissa.Sub(ss2.mantissa) )
|
||||
{
|
||||
mantissa.Rcl(1);
|
||||
mantissa.Rcl(1,1); // maybe without this rcl and subone()? !!!!
|
||||
c = exponent.SubOne();
|
||||
}
|
||||
}
|
||||
|
@ -814,7 +814,7 @@ public:
|
|||
if( start.Mul(start) )
|
||||
return 1;
|
||||
|
||||
pow.Rcr();
|
||||
pow.Rcr(1);
|
||||
}
|
||||
|
||||
*this = result;
|
||||
|
|
|
@ -819,7 +819,7 @@ public:
|
|||
|
||||
"leal (%%ebx,%%edx,4), %%ebx \n"
|
||||
|
||||
"movl %%esi, %%edx \n"
|
||||
"movl %%esi, %%edx \n"
|
||||
"clc \n"
|
||||
"1: \n"
|
||||
|
||||
|
@ -878,18 +878,31 @@ public:
|
|||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
#ifdef TTMATH_PLATFORM32
|
||||
|
||||
|
||||
/*!
|
||||
this method moving once all bits into the left side
|
||||
return value <- this <- C
|
||||
this method moves all bits into the left hand side
|
||||
return value <- this <- c
|
||||
|
||||
the lowest bit will hold value of 'c' and
|
||||
function returns the highest bit
|
||||
the lowest *bits* will be held the 'c' and
|
||||
the state of one additional bit (on the left hand side)
|
||||
will be returned
|
||||
|
||||
for example:
|
||||
let this is 001010000
|
||||
after Rcl2(3, 1) there'll be 010000111 and Rcl2 returns 1
|
||||
*/
|
||||
uint Rcl(uint c=0)
|
||||
uint Rcl2(uint bits, uint c)
|
||||
{
|
||||
if( bits == 0 )
|
||||
return 0;
|
||||
|
||||
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
||||
|
||||
register sint b = value_size;
|
||||
register uint * p1 = table;
|
||||
|
||||
|
@ -900,12 +913,16 @@ public:
|
|||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
|
||||
mov ecx,[b]
|
||||
mov ebx,[p1]
|
||||
mov edx, [bits]
|
||||
|
||||
a:
|
||||
xor eax, eax
|
||||
sub eax, [c]
|
||||
|
||||
mov eax,0
|
||||
sub eax,[c]
|
||||
mov ecx, [b]
|
||||
mov ebx, [p1]
|
||||
|
||||
p:
|
||||
rcl dword ptr[ebx],1
|
||||
|
@ -917,10 +934,15 @@ public:
|
|||
|
||||
loop p
|
||||
|
||||
dec edx
|
||||
|
||||
jnz a
|
||||
|
||||
mov eax,0
|
||||
adc eax,eax
|
||||
mov [c],eax
|
||||
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
|
@ -931,12 +953,16 @@ public:
|
|||
#ifdef __GNUC__
|
||||
__asm__ __volatile__(
|
||||
|
||||
"push %%esi \n"
|
||||
|
||||
"2: \n"
|
||||
|
||||
"xorl %%eax,%%eax \n"
|
||||
"subl %%edx,%%eax \n"
|
||||
|
||||
"push %%ebx \n"
|
||||
"push %%ecx \n"
|
||||
|
||||
"movl $0,%%eax \n"
|
||||
"subl %%edx,%%eax \n"
|
||||
|
||||
|
||||
"1: \n"
|
||||
"rcll $1,(%%ebx) \n"
|
||||
|
||||
|
@ -947,14 +973,20 @@ public:
|
|||
|
||||
"loop 1b \n"
|
||||
|
||||
"movl $0, %%edx \n"
|
||||
"adcl %%edx,%%edx \n"
|
||||
|
||||
"pop %%ecx \n"
|
||||
"pop %%ebx \n"
|
||||
|
||||
"decl %%esi \n"
|
||||
|
||||
"jnz 2b \n"
|
||||
|
||||
"movl $0, %%edx \n"
|
||||
"adcl %%edx, %%edx \n"
|
||||
|
||||
"pop %%esi \n"
|
||||
|
||||
: "=d" (c)
|
||||
: "0" (c), "c" (b), "b" (p1)
|
||||
: "0" (c), "c" (b), "b" (p1), "S" (bits)
|
||||
: "%eax", "cc", "memory" );
|
||||
|
||||
#endif
|
||||
|
@ -965,14 +997,24 @@ public:
|
|||
|
||||
|
||||
/*!
|
||||
this method moving once all bits into the right side
|
||||
C -> *this -> return value
|
||||
this method moves all bits into the right hand side
|
||||
C -> this -> return value
|
||||
|
||||
the highest bit will be held value of 'c' and
|
||||
function returns the lowest bit
|
||||
the highest *bits* will be held the 'c' and
|
||||
the state of one additional bit (on the right hand side)
|
||||
will be returned
|
||||
|
||||
for example:
|
||||
let this is 000000010
|
||||
after Rcr2(2, 1) there'll be 110000000 and Rcr2 returns 1
|
||||
*/
|
||||
uint Rcr(uint c=0)
|
||||
uint Rcr2(uint bits, uint c)
|
||||
{
|
||||
if( bits == 0 )
|
||||
return 0;
|
||||
|
||||
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
||||
|
||||
register sint b = value_size;
|
||||
register uint * p1 = table;
|
||||
|
||||
|
@ -983,15 +1025,19 @@ public:
|
|||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
|
||||
mov edx,[bits]
|
||||
|
||||
a:
|
||||
|
||||
xor eax,eax
|
||||
sub eax,[c]
|
||||
|
||||
mov ebx,[p1]
|
||||
mov ecx,[b]
|
||||
|
||||
lea ebx,[ebx+4*ecx]
|
||||
|
||||
mov eax,0
|
||||
sub eax,[c]
|
||||
|
||||
p:
|
||||
dec ebx
|
||||
dec ebx
|
||||
|
@ -1001,11 +1047,16 @@ public:
|
|||
rcr dword ptr [ebx],1
|
||||
|
||||
loop p
|
||||
|
||||
dec edx
|
||||
|
||||
jnz a
|
||||
|
||||
mov eax,0
|
||||
adc eax,eax
|
||||
mov [c],eax
|
||||
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
|
@ -1016,12 +1067,17 @@ public:
|
|||
#ifdef __GNUC__
|
||||
__asm__ __volatile__(
|
||||
|
||||
"push %%esi \n"
|
||||
|
||||
|
||||
"2: \n"
|
||||
|
||||
"push %%ebx \n"
|
||||
"push %%ecx \n"
|
||||
|
||||
"leal (%%ebx,%%ecx,4),%%ebx \n"
|
||||
|
||||
"movl $0, %%eax \n"
|
||||
"xorl %%eax, %%eax \n"
|
||||
"subl %%edx, %%eax \n"
|
||||
|
||||
"1: \n"
|
||||
|
@ -1034,14 +1090,20 @@ public:
|
|||
|
||||
"loop 1b \n"
|
||||
|
||||
"movl $0, %%edx \n"
|
||||
"adcl %%edx,%%edx \n"
|
||||
|
||||
"pop %%ecx \n"
|
||||
"pop %%ebx \n"
|
||||
|
||||
"decl %%esi \n"
|
||||
|
||||
"jnz 2b \n"
|
||||
|
||||
"movl $0, %%edx \n"
|
||||
"adcl %%edx, %%edx \n"
|
||||
|
||||
"pop %%esi \n"
|
||||
|
||||
: "=d" (c)
|
||||
: "0" (c), "c" (b), "b" (p1)
|
||||
: "0" (c), "c" (b), "b" (p1), "S" (bits)
|
||||
: "%eax", "cc", "memory" );
|
||||
|
||||
#endif
|
||||
|
@ -1052,6 +1114,47 @@ public:
|
|||
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
an auxiliary method for moving bits into the left hand side
|
||||
|
||||
this method moves only words
|
||||
*/
|
||||
void RclMoveAllWords( sint & all_words, uint & rest_bits, uint & last_c,
|
||||
uint bits, uint c)
|
||||
{
|
||||
rest_bits = sint(bits % TTMATH_BITS_PER_UINT);
|
||||
all_words = sint(bits / TTMATH_BITS_PER_UINT);
|
||||
|
||||
if( all_words >= sint(value_size) )
|
||||
{
|
||||
if( all_words==value_size && rest_bits==0 )
|
||||
last_c = table[0] & 1;
|
||||
|
||||
all_words = value_size; // not value_size - 1
|
||||
rest_bits = 0;
|
||||
}
|
||||
|
||||
if( all_words > 0 )
|
||||
{
|
||||
sint first;
|
||||
sint second;
|
||||
|
||||
last_c = table[value_size - all_words] & 1; // all_words is greater than 0
|
||||
|
||||
// copying the first part of the value
|
||||
for(first = value_size-1, second=first-all_words ; second>=0 ; --first, --second)
|
||||
table[first] = table[second];
|
||||
|
||||
// sets the rest bits of value into 'c'
|
||||
uint mask = c ? TTMATH_UINT_MAX_VALUE : 0;
|
||||
for( ; first>=0 ; --first )
|
||||
table[first] = mask;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
this method moving all bits into the left side 'bits' times
|
||||
return value <- this <- C
|
||||
|
@ -1062,39 +1165,92 @@ public:
|
|||
the value c will be set into the lowest bits
|
||||
and the method returns state of the last moved bit
|
||||
*/
|
||||
uint Rcl(uint bits, uint c)
|
||||
uint Rcl(uint bits, uint c=0)
|
||||
{
|
||||
sint first;
|
||||
sint second;
|
||||
uint last_c = 0;
|
||||
|
||||
if( bits > value_size*TTMATH_BITS_PER_UINT )
|
||||
bits = value_size*TTMATH_BITS_PER_UINT;
|
||||
sint all_words = 0;
|
||||
uint rest_bits = bits;
|
||||
|
||||
sint all_words = sint(bits) / sint(TTMATH_BITS_PER_UINT);
|
||||
if( bits >= TTMATH_BITS_PER_UINT )
|
||||
RclMoveAllWords(all_words, rest_bits, last_c, bits, c);
|
||||
|
||||
if( all_words > 0 )
|
||||
|
||||
// rest_bits is from 0 to TTMATH_BITS_PER_UINT-1 now
|
||||
if( rest_bits > 0 )
|
||||
{
|
||||
// copying the first part of the value
|
||||
for(first = value_size-1, second=first-all_words ; second>=0 ; --first, --second)
|
||||
// if rest_bits is greater than a half of TTMATH_BITS_PER_UINT
|
||||
// we're moving bits into the right hand side
|
||||
// (TTMATH_BITS_PER_UINT-rest_bits) times
|
||||
// and then we're moving one word into left
|
||||
if( rest_bits > TTMATH_BITS_PER_UINT/2 + 1 )
|
||||
{
|
||||
last_c = table[first] & 1;
|
||||
table[first] = table[second];
|
||||
uint temp = table[0];
|
||||
Rcr2(TTMATH_BITS_PER_UINT-rest_bits,0);
|
||||
last_c = table[value_size-1] & 1;
|
||||
|
||||
for(uint i=value_size-1 ; i>0 ; --i)
|
||||
table[i] = table[i-1];
|
||||
|
||||
table[0] = temp << rest_bits;
|
||||
|
||||
if( c )
|
||||
{
|
||||
uint mask = TTMATH_UINT_MAX_VALUE << rest_bits;
|
||||
table[0] |= ~mask;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
last_c = Rcl2(rest_bits, c);
|
||||
}
|
||||
|
||||
// sets the rest bits of value into 'c'
|
||||
uint mask = (c!=0)? TTMATH_UINT_MAX_VALUE : 0;
|
||||
for( ; first>=0 ; --first )
|
||||
table[first] = mask;
|
||||
}
|
||||
|
||||
sint rest_bits = sint(bits) % sint(TTMATH_BITS_PER_UINT);
|
||||
for( ; rest_bits > 0 ; --rest_bits )
|
||||
last_c = Rcl(c);
|
||||
|
||||
return last_c;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/*!
|
||||
an auxiliary method for moving bits into the right hand side
|
||||
|
||||
this method moves only words
|
||||
*/
|
||||
void RcrMoveAllWords( sint & all_words, uint & rest_bits, uint & last_c,
|
||||
uint bits, uint c)
|
||||
{
|
||||
rest_bits = sint(bits % TTMATH_BITS_PER_UINT);
|
||||
all_words = sint(bits / TTMATH_BITS_PER_UINT);
|
||||
|
||||
if( all_words >= sint(value_size) )
|
||||
{
|
||||
if( all_words==value_size && rest_bits==0 )
|
||||
last_c = (table[value_size-1] & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
|
||||
|
||||
all_words = value_size; // not value_size - 1
|
||||
rest_bits = 0;
|
||||
}
|
||||
|
||||
|
||||
if( all_words > 0 )
|
||||
{
|
||||
uint first;
|
||||
uint second;
|
||||
|
||||
last_c = (table[all_words - 1] & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0; // all_words is > 0
|
||||
|
||||
// copying the first part of the value
|
||||
for(first=0, second=all_words ; second<value_size ; ++first, ++second)
|
||||
table[first] = table[second];
|
||||
|
||||
// sets the rest bits of value into 'c'
|
||||
uint mask = c ? TTMATH_UINT_MAX_VALUE : 0;
|
||||
for( ; first<value_size ; ++first )
|
||||
table[first] = mask;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
this method moving all bits into the right side 'bits' times
|
||||
|
@ -1106,39 +1262,42 @@ public:
|
|||
the value c will be set into the highest bits
|
||||
and the method returns state of the last moved bit
|
||||
*/
|
||||
uint Rcr(uint bits, uint c)
|
||||
uint Rcr(uint bits, uint c=0)
|
||||
{
|
||||
sint first;
|
||||
sint second;
|
||||
sint last_c = 0;
|
||||
uint last_c = 0;
|
||||
sint all_words = 0;
|
||||
uint rest_bits = bits;
|
||||
|
||||
if( bits > value_size*TTMATH_BITS_PER_UINT )
|
||||
bits = value_size*TTMATH_BITS_PER_UINT;
|
||||
if( bits >= TTMATH_BITS_PER_UINT )
|
||||
RcrMoveAllWords(all_words, rest_bits, last_c, bits, c);
|
||||
|
||||
sint all_words = sint(bits) / sint(TTMATH_BITS_PER_UINT);
|
||||
|
||||
if( all_words > 0 )
|
||||
// rest_bits is from 0 to TTMATH_BITS_PER_UINT-1 now
|
||||
if( rest_bits > 0 )
|
||||
{
|
||||
// copying the first part of the value
|
||||
for(first=0, second=all_words ; second<sint(value_size) ; ++first, ++second)
|
||||
if( rest_bits > TTMATH_BITS_PER_UINT/2 + 1 )
|
||||
{
|
||||
last_c = table[first] & TTMATH_UINT_HIGHEST_BIT;
|
||||
table[first] = table[second];
|
||||
uint temp = table[value_size-1];
|
||||
Rcl2(TTMATH_BITS_PER_UINT-rest_bits,0);
|
||||
last_c = (table[0] & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
|
||||
|
||||
for(uint i=0 ; i<value_size-1 ; ++i)
|
||||
table[i] = table[i+1];
|
||||
|
||||
table[value_size-1] = temp >> rest_bits;
|
||||
|
||||
if( c )
|
||||
{
|
||||
uint mask = TTMATH_UINT_MAX_VALUE >> rest_bits;
|
||||
table[value_size-1] |= ~mask;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
last_c = Rcr2(rest_bits, c);
|
||||
}
|
||||
|
||||
if( last_c )
|
||||
last_c = 1;
|
||||
|
||||
// sets the rest bits of value into 'c'
|
||||
uint mask = (c!=0)? TTMATH_UINT_MAX_VALUE : 0;
|
||||
for( ; first<sint(value_size) ; ++first )
|
||||
table[first] = mask;
|
||||
}
|
||||
|
||||
sint rest_bits = sint(bits) % sint(TTMATH_BITS_PER_UINT);
|
||||
for( ; rest_bits > 0 ; --rest_bits )
|
||||
last_c = Rcr(c);
|
||||
|
||||
return last_c;
|
||||
}
|
||||
|
||||
|
@ -1175,14 +1334,14 @@ public:
|
|||
table[i] = 0;
|
||||
}
|
||||
|
||||
// moving the rest bits (max TTMATH_BITS_PER_UINT -- only one word)
|
||||
while( !IsTheHighestBitSet() )
|
||||
{
|
||||
Rcl();
|
||||
++moving;
|
||||
}
|
||||
uint moving2 = FindLeadingBitInWord( table[value_size-1] );
|
||||
// moving2 is different from -1 because the value table[value_size-1]
|
||||
// is not zero
|
||||
|
||||
return moving;
|
||||
moving2 = TTMATH_BITS_PER_UINT - moving2 - 1;
|
||||
Rcl(moving2);
|
||||
|
||||
return moving + moving2;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1545,7 +1704,7 @@ public:
|
|||
if( Add(*this) )
|
||||
return 1;
|
||||
|
||||
if( ss1.Rcl() )
|
||||
if( ss1.Rcl(1) )
|
||||
if( Add(ss2) )
|
||||
return 1;
|
||||
}
|
||||
|
@ -1934,7 +2093,7 @@ private:
|
|||
|
||||
|
||||
div_a:
|
||||
c = Rcl(c);
|
||||
c = Rcl(1, c);
|
||||
c = rest.Add(rest,c);
|
||||
c = rest.Sub(divisor,c);
|
||||
|
||||
|
@ -1949,12 +2108,12 @@ private:
|
|||
if(loop)
|
||||
goto div_a;
|
||||
|
||||
c = Rcl(c);
|
||||
c = Rcl(1, c);
|
||||
return 0;
|
||||
|
||||
|
||||
div_c:
|
||||
c = Rcl(c);
|
||||
c = Rcl(1, c);
|
||||
c = rest.Add(rest,c);
|
||||
c = rest.Add(divisor);
|
||||
|
||||
|
@ -1967,7 +2126,7 @@ private:
|
|||
if(loop)
|
||||
goto div_c;
|
||||
|
||||
c = Rcl(c);
|
||||
c = Rcl(1, c);
|
||||
c = rest.Add(divisor);
|
||||
|
||||
return 0;
|
||||
|
@ -2048,7 +2207,7 @@ private:
|
|||
|
||||
if( CmpSmaller(divisor_copy, table_id) )
|
||||
{
|
||||
divisor_copy.Rcr();
|
||||
divisor_copy.Rcr(1);
|
||||
--bits_diff;
|
||||
}
|
||||
|
||||
|
@ -2324,16 +2483,17 @@ private:
|
|||
{
|
||||
uint c = 0;
|
||||
|
||||
// !!!!!!!!! change
|
||||
for( d = 0 ; (v.table[n-1] & TTMATH_UINT_HIGHEST_BIT) == 0 ; ++d )
|
||||
{
|
||||
// we can move the bits only to the 'n-1' index but at the moment
|
||||
// we don't have such method
|
||||
// maybe it's time to write it now?
|
||||
v.Rcl(0);
|
||||
v.Rcl(1, 0);
|
||||
|
||||
c <<= 1;
|
||||
|
||||
if( Rcl(0) )
|
||||
if( Rcl(1, 0) )
|
||||
c += 1;
|
||||
}
|
||||
|
||||
|
@ -3224,6 +3384,11 @@ public:
|
|||
|
||||
#ifdef TTMATH_PLATFORM64
|
||||
|
||||
private:
|
||||
uint Rcl2(uint bits, uint c);
|
||||
uint Rcr2(uint bits, uint c);
|
||||
|
||||
public:
|
||||
// these methods are for 64bit processors and are defined in 'ttmathuint64.h'
|
||||
UInt<value_size> & operator=(unsigned int i);
|
||||
UInt(unsigned int i);
|
||||
|
@ -3235,8 +3400,6 @@ public:
|
|||
uint AddTwoInts(uint x2, uint x1, uint index);
|
||||
uint Sub(const UInt<value_size> & ss2, uint c=0);
|
||||
uint SubInt(uint value, uint index = 0);
|
||||
uint Rcl(uint c=0);
|
||||
uint Rcr(uint c=0);
|
||||
static sint FindLeadingBitInWord(uint x);
|
||||
static uint SetBitInWord(uint value, uint bit);
|
||||
static void MulTwoWords(uint a, uint b, uint * result2, uint * result1);
|
||||
|
|
|
@ -416,7 +416,7 @@ namespace ttmath
|
|||
"movq $0, %%rdx \n"
|
||||
|
||||
"movq (%%rbx), %%rax \n"
|
||||
"addq %%rsi, %%rax \n"
|
||||
"addq %%rsi, %%rax \n"
|
||||
"movq %%rax, (%%rbx) \n"
|
||||
|
||||
"inc %%rbx \n"
|
||||
|
@ -429,7 +429,7 @@ namespace ttmath
|
|||
"inc %%rbx \n"
|
||||
|
||||
"movq (%%rbx), %%rax \n"
|
||||
"adcq %%rdi, %%rax \n"
|
||||
"adcq %%rdi, %%rax \n"
|
||||
"movq %%rax, (%%rbx) \n"
|
||||
"jnc 2f \n"
|
||||
|
||||
|
@ -638,17 +638,27 @@ namespace ttmath
|
|||
|
||||
|
||||
/*!
|
||||
this method moving once all bits into the left side
|
||||
return value <- this <- C
|
||||
this method moves all bits into the left hand side
|
||||
return value <- this <- c
|
||||
|
||||
the lowest *bits* will be held the 'c' and
|
||||
the state of one additional bit (on the left hand side)
|
||||
will be returned
|
||||
|
||||
for example:
|
||||
let this is 001010000
|
||||
after Rcl2(3, 1) there'll be 010000111 and Rcl2 returns 1
|
||||
|
||||
***this method is created only on a 64bit platform***
|
||||
|
||||
the lowest bit will hold value of 'c' and
|
||||
function returns the highest bit
|
||||
*/
|
||||
template<uint value_size>
|
||||
uint UInt<value_size>::Rcl(uint c)
|
||||
uint UInt<value_size>::Rcl2(uint bits, uint c)
|
||||
{
|
||||
if( bits == 0 )
|
||||
return 0;
|
||||
|
||||
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
||||
|
||||
register sint b = value_size;
|
||||
register uint * p1 = table;
|
||||
|
||||
|
@ -659,12 +669,17 @@ namespace ttmath
|
|||
#ifdef __GNUC__
|
||||
__asm__ __volatile__(
|
||||
|
||||
"push %%rsi \n"
|
||||
|
||||
|
||||
"2: \n"
|
||||
|
||||
"xorq %%rax,%%rax \n"
|
||||
"subq %%rdx,%%rax \n"
|
||||
|
||||
"push %%rbx \n"
|
||||
"push %%rcx \n"
|
||||
|
||||
"movq $0,%%rax \n"
|
||||
"subq %%rdx,%%rax \n"
|
||||
|
||||
|
||||
"1: \n"
|
||||
"rclq $1,(%%rbx) \n"
|
||||
|
||||
|
@ -679,14 +694,20 @@ namespace ttmath
|
|||
|
||||
"loop 1b \n"
|
||||
|
||||
"movq $0, %%rdx \n"
|
||||
"adcq %%rdx,%%rdx \n"
|
||||
|
||||
"pop %%rcx \n"
|
||||
"pop %%rbx \n"
|
||||
|
||||
"decq %%rsi \n"
|
||||
|
||||
"jnz 2b \n"
|
||||
|
||||
"movq $0, %%rdx \n"
|
||||
"adcq %%rdx, %%rdx \n"
|
||||
|
||||
"pop %%rsi \n"
|
||||
|
||||
: "=d" (c)
|
||||
: "0" (c), "c" (b), "b" (p1)
|
||||
: "0" (c), "c" (b), "b" (p1), "S" (bits)
|
||||
: "%rax", "cc", "memory" );
|
||||
|
||||
#endif
|
||||
|
@ -697,17 +718,27 @@ namespace ttmath
|
|||
|
||||
|
||||
/*!
|
||||
this method moving once all bits into the right side
|
||||
C -> *this -> return value
|
||||
this method moves all bits into the right hand side
|
||||
C -> this -> return value
|
||||
|
||||
the highest *bits* will be held the 'c' and
|
||||
the state of one additional bit (on the right hand side)
|
||||
will be returned
|
||||
|
||||
for example:
|
||||
let this is 000000010
|
||||
after Rcr2(2, 1) there'll be 110000000 and Rcr2 returns 1
|
||||
|
||||
***this method is created only on a 64bit platform***
|
||||
|
||||
the highest bit will be held value of 'c' and
|
||||
function returns the lowest bit
|
||||
*/
|
||||
template<uint value_size>
|
||||
uint UInt<value_size>::Rcr(uint c)
|
||||
uint UInt<value_size>::Rcr2(uint bits, uint c)
|
||||
{
|
||||
if( bits == 0 )
|
||||
return 0;
|
||||
|
||||
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
||||
|
||||
register sint b = value_size;
|
||||
register uint * p1 = table;
|
||||
|
||||
|
@ -720,12 +751,18 @@ namespace ttmath
|
|||
#ifdef __GNUC__
|
||||
__asm__ __volatile__(
|
||||
|
||||
"push %%rsi \n"
|
||||
|
||||
|
||||
"2: \n"
|
||||
|
||||
|
||||
"push %%rbx \n"
|
||||
"push %%rcx \n"
|
||||
|
||||
"leaq (%%rbx,%%rcx,8),%%rbx \n"
|
||||
|
||||
"movq $0, %%rax \n"
|
||||
|
||||
"xorq %%rax, %%rax \n"
|
||||
"subq %%rdx, %%rax \n"
|
||||
|
||||
"1: \n"
|
||||
|
@ -742,14 +779,20 @@ namespace ttmath
|
|||
|
||||
"loop 1b \n"
|
||||
|
||||
"movq $0, %%rdx \n"
|
||||
"adcq %%rdx,%%rdx \n"
|
||||
|
||||
"pop %%rcx \n"
|
||||
"pop %%rbx \n"
|
||||
|
||||
"decq %%rsi \n"
|
||||
|
||||
"jnz 2b \n"
|
||||
|
||||
"movq $0, %%rdx \n"
|
||||
"adcq %%rdx,%%rdx \n"
|
||||
|
||||
"pop %%rsi \n"
|
||||
|
||||
: "=d" (c)
|
||||
: "0" (c), "c" (b), "b" (p1)
|
||||
: "0" (c), "c" (b), "b" (p1), "S" (bits)
|
||||
: "%rax", "cc", "memory" );
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue