switch to non-branching code in AlmostInverse()

pull/2/head
weidai 2010-06-28 22:42:31 +00:00
parent a8b398e042
commit 1435784dee
1 changed files with 23 additions and 35 deletions

View File

@ -2633,7 +2633,8 @@ unsigned int AlmostInverse(word *R, word *T, const word *A, size_t NA, const wor
word *f = T+2*N; word *f = T+2*N;
word *g = T+3*N; word *g = T+3*N;
size_t bcLen=2, fgLen=EvenWordCount(M, N); size_t bcLen=2, fgLen=EvenWordCount(M, N);
unsigned int k=0, s=0; unsigned int k=0;
bool s=false;
SetWords(T, 0, 3*N); SetWords(T, 0, 3*N);
b[0]=1; b[0]=1;
@ -2652,57 +2653,44 @@ unsigned int AlmostInverse(word *R, word *T, const word *A, size_t NA, const wor
} }
ShiftWordsRightByWords(f, fgLen, 1); ShiftWordsRightByWords(f, fgLen, 1);
if (c[bcLen-1]) bcLen+=2; bcLen += 2 * (c[bcLen-1] != 0);
assert(bcLen <= N); assert(bcLen <= N);
ShiftWordsLeftByWords(c, bcLen, 1); ShiftWordsLeftByWords(c, bcLen, 1);
k+=WORD_BITS; k+=WORD_BITS;
t=f[0]; t=f[0];
} }
unsigned int i=0; unsigned int i = TrailingZeros(t);
while (t%2 == 0) t >>= i;
{ k += i;
t>>=1;
i++;
}
k+=i;
if (t==1 && f[1]==0 && EvenWordCount(f, fgLen)==2) if (t==1 && f[1]==0 && EvenWordCount(f+2, fgLen-2)==0)
{ {
if (s%2==0) if (s)
CopyWords(R, b, N);
else
Subtract(R, M, b, N); Subtract(R, M, b, N);
else
CopyWords(R, b, N);
return k; return k;
} }
ShiftWordsRightByBits(f, fgLen, i); ShiftWordsRightByBits(f, fgLen, i);
t=ShiftWordsLeftByBits(c, bcLen, i); t = ShiftWordsLeftByBits(c, bcLen, i);
if (t) c[bcLen] += t;
{ bcLen += 2 * (t!=0);
c[bcLen] = t; assert(bcLen <= N);
bcLen+=2;
assert(bcLen <= N);
}
if (f[fgLen-2]==0 && g[fgLen-2]==0 && f[fgLen-1]==0 && g[fgLen-1]==0) bool swap = Compare(f, g, fgLen)==-1;
fgLen-=2; ConditionalSwapPointers(swap, f, g);
ConditionalSwapPointers(swap, b, c);
s ^= swap;
if (Compare(f, g, fgLen)==-1) fgLen -= 2 * !(f[fgLen-2] | f[fgLen-1]);
{
std::swap(f, g);
std::swap(b, c);
s++;
}
Subtract(f, f, g, fgLen); Subtract(f, f, g, fgLen);
t = Add(b, b, c, bcLen);
if (Add(b, b, c, bcLen)) b[bcLen] += t;
{ bcLen += 2*t;
b[bcLen] = 1; assert(bcLen <= N);
bcLen+=2;
assert(bcLen <= N);
}
} }
} }