vm: faster foo_to_bignum for common case of one bignum digit.

db4
John Benediktsson 2014-06-02 07:16:43 -07:00
parent 278fe4830f
commit cf287f4144
1 changed files with 15 additions and 14 deletions

View File

@ -270,8 +270,6 @@ bignum* factor_vm::bignum_remainder(bignum* numerator, bignum* denominator) {
#define FOO_TO_BIGNUM(name, type, stype, utype) \
bignum* factor_vm::name##_to_bignum(type n) { \
int negative_p; \
bignum_digit_type result_digits[BIGNUM_DIGITS_FOR(type)]; \
bignum_digit_type* end_digits = result_digits; \
/* Special cases win when these small constants are cached. */ \
if (n == 0) \
return (BIGNUM_ZERO()); \
@ -282,19 +280,22 @@ bignum* factor_vm::bignum_remainder(bignum* numerator, bignum* denominator) {
{ \
utype accumulator = \
((negative_p = (n < (type) 0)) ? ((type)(-(stype) n)) : n); \
do { \
(*end_digits++) = (accumulator & BIGNUM_DIGIT_MASK); \
accumulator >>= BIGNUM_DIGIT_LENGTH; \
} while (accumulator != 0); \
} \
if (accumulator < BIGNUM_RADIX) \
{ \
bignum* result = \
(allot_bignum((end_digits - result_digits), negative_p)); \
bignum_digit_type* scan_digits = result_digits; \
bignum_digit_type* scan_result = (BIGNUM_START_PTR(result)); \
while (scan_digits < end_digits) \
(*scan_result++) = (*scan_digits++); \
bignum* result = allot_bignum(1, negative_p); \
bignum_digit_type* scan = (BIGNUM_START_PTR(result)); \
*scan = (accumulator & BIGNUM_DIGIT_MASK); \
return (result); \
} else { \
BIGNUM_ASSERT(BIGNUM_DIGITS_FOR(type) == 2); \
bignum* result = allot_bignum(2, negative_p); \
bignum_digit_type* scan = (BIGNUM_START_PTR(result)); \
(*scan++) = (accumulator & BIGNUM_DIGIT_MASK); \
accumulator >>= BIGNUM_DIGIT_LENGTH; \
*scan = (accumulator & BIGNUM_DIGIT_MASK); \
BIGNUM_ASSERT((accumulator >> BIGNUM_DIGIT_LENGTH) == 0); \
return (result); \
} \
} \
}