sp_mod_word(): add unoptimized alternative if -U__GNUC__.

This commit is contained in:
Daniel Pouzzner
2020-09-05 01:18:19 -05:00
parent c8cd042bdd
commit a9cad51b65

View File

@ -1477,7 +1477,6 @@ int sp_mulmod(sp_int* a, sp_int* b, sp_int* m, sp_int* r)
*/ */
static WC_INLINE int sp_mod_word(sp_int_word *w, sp_int_digit d) { static WC_INLINE int sp_mod_word(sp_int_word *w, sp_int_digit d) {
sp_int_word x; sp_int_word x;
int x_shift;
if (*w == 0) if (*w == 0)
return 0; return 0;
if (d == 0) if (d == 0)
@ -1490,43 +1489,50 @@ static WC_INLINE int sp_mod_word(sp_int_word *w, sp_int_digit d) {
* shifting so that x has one less leading zero, and then doing a * shifting so that x has one less leading zero, and then doing a
* final comparison. * final comparison.
* *
* textbook logic:
*
* while (x <= w/2)
* x <<= 1;
*/ */
x_shift = ((int)__builtin_clzll(d) + (SP_WORD_SIZE - 1)); #ifdef __GNUC__
if ((*w >> SP_WORD_SIZE) == 0) {
x_shift -= int x_shift = ((int)__builtin_clzll(d) + (SP_WORD_SIZE - 1));
if ((*w >> SP_WORD_SIZE) == 0)
x_shift -=
#if SP_WORD_SIZE == 64 #if SP_WORD_SIZE == 64
(int)__builtin_clzll((uint64_t)*w) (int)__builtin_clzll((uint64_t)*w)
#elif SP_WORD_SIZE == 32 #elif SP_WORD_SIZE == 32
(int)__builtin_clz((uint32_t)*w) (int)__builtin_clz((uint32_t)*w)
#else #else
#error unexpected SP_WORD_SIZE #error unexpected SP_WORD_SIZE
#endif #endif
+ SP_WORD_SIZE; + SP_WORD_SIZE;
else else
x_shift -= x_shift -=
#if SP_WORD_SIZE == 64 #if SP_WORD_SIZE == 64
(int)__builtin_clzll((uint64_t)(*w >> SP_WORD_SIZE)) (int)__builtin_clzll((uint64_t)(*w >> SP_WORD_SIZE))
#elif SP_WORD_SIZE == 32 #elif SP_WORD_SIZE == 32
(int)__builtin_clz((uint32_t)(*w >> SP_WORD_SIZE)) (int)__builtin_clz((uint32_t)(*w >> SP_WORD_SIZE))
#else #else
#error unexpected SP_WORD_SIZE #error unexpected SP_WORD_SIZE
#endif #endif
; ;
if (x_shift < 0) if (x_shift < 0)
x_shift = 0; x_shift = 0;
x = (sp_int_word)d << x_shift; x = (sp_int_word)d << x_shift;
}
if (x <= (*w>>1)) if (x <= (*w>>1))
x <<= 1; x <<= 1;
#else /* ! __GNUC__ */
/* textbook logic */
x = (sp_int_word)d;
while (x <= (*w>>1))
x <<= 1;
#endif /* __GNUC__ */
while (*w >= (sp_int_word)d) { while (*w >= (sp_int_word)d) {
if (*w >= x) if (*w >= x)
*w -= x; *w -= x;
x >>= 1; x >>= 1;
} }
return MP_OKAY; return MP_OKAY;
} }
#endif /* WOLFSSL_SP_MOD_WORD_RP */ #endif /* WOLFSSL_SP_MOD_WORD_RP */