19#if !defined(SC_VECTOR_UTILS_H)
20#define SC_VECTOR_UTILS_H
27#define VEC_MIN(A,B) ( (A) <= (B) ? A : B )
28#define VEC_MAX(A,B) ( (A) >= (B) ? A : B )
32template<
int W>
class sc_bigint;
33template<
int W>
class sc_biguint;
43template<
int WIDTH,
bool SIGNED>
76template<
int WL,
bool SL,
int WR,
bool SR>
146 WIDTH = ACTUAL_WIDTH,
154 for (
int digit_i = 1; digit_i < DIGITS_N; ++digit_i ) {
178 WIDTH = ACTUAL_WIDTH-1,
186 for (
int digit_i = 1; digit_i < DIGITS_N; ++digit_i ) {
207 ACTUAL_WIDTH = 8*
sizeof(long),
210 WIDTH = ACTUAL_WIDTH,
218 for (
int digit_i = 1; digit_i < DIGITS_N; ++digit_i ) {
239 ACTUAL_WIDTH = 8*
sizeof(
unsigned long)+1,
242 WIDTH = ACTUAL_WIDTH-1,
250 unsigned long long llinit = init;
251 for (
int digit_i = 1; digit_i < DIGITS_N; ++digit_i ) {
253 m_digits[digit_i] = (
sc_digit)llinit;
272 ACTUAL_WIDTH = 8*
sizeof(int),
275 WIDTH = ACTUAL_WIDTH,
300 ACTUAL_WIDTH = 8*
sizeof(
unsigned int)+1,
303 WIDTH = ACTUAL_WIDTH-1,
343 for ( digit_i = hod; (digit_i > 0) && (digits_p[digit_i] == ~0u); --digit_i )
367 for ( digit_i = hod; (digit_i > 0) && (digits_p[digit_i] == 0); --digit_i )
390 if ( (
int)digits[hod] < 0 ) {
392 if ( (
int)digits[result_hod] >= 0 ) { ++result_hod; }
396 if ( (
int)digits[result_hod] < 0 ) { ++result_hod; }
445 const int shorter_hod,
447 const int result_hod,
451 if ( result_hod == 0 ) {
452 *result_p = *longer_p + *shorter_p;
461 for ( digit_i = 0; digit_i < shorter_hod; ++digit_i ) {
462 carry += *shorter_p++;
463 carry += *longer_p++;
471 if ( longer_hod == shorter_hod ) {
472 carry += (
int64)(
int)*shorter_p++;
473 carry += (
int64)(
int)*longer_p++;
485 carry += (
int64)(
int)*shorter_p++;
486 carry += *longer_p++;
490 for ( digit_i = shorter_hod+1; digit_i < longer_hod; ++digit_i ) {
491 carry += *longer_p++;
496 carry += (
int64)(
int)*longer_p++;
505 if ( result_hod > longer_hod ) {
527template<
bool SL,
bool SS>
532 const int shorter_hod,
536 if ( 0 == longer_hod ) {
537 *result_p = *longer_p & *shorter_p;
545 for ( digit_i = 0; digit_i <= shorter_hod; ++digit_i ) {
546 *result_p++ = *longer_p++ & shorter_p[digit_i];
552 if ( longer_hod > shorter_hod ) {
553 if ( SS && 0 > (
int)shorter_p[shorter_hod] ) {
554 for ( ; digit_i <= longer_hod; ++digit_i ) {
555 *result_p++ = *longer_p++;
559 for ( ; digit_i <= longer_hod; ++digit_i ) {
587 for (
int digit_i = 0; digit_i < hod; ++digit_i ) {
588 if ( target_p[digit_i] != (
sc_digit)-1 ) {
595 const sc_digit mask = ~( (std::numeric_limits<sc_digit>::max()-1)
597 if ( ( target_p[hod] & mask ) != mask ) {
627 if ( left_hod == right_hod ) {
629 ~((std::numeric_limits<sc_digit>::max()-1) << (left_i-right_i) );
630 return ( ( target_p[right_hod] & mask ) != mask ) ?
false :
true;
640 (std::numeric_limits<sc_digit>::max() << (right_index-1) );
641 if ( ( target_p[right_hod] & mask ) != mask ) {
644 for (
int digit_i = right_hod+1; digit_i < left_hod; ++digit_i ) {
645 if ( target_p[digit_i] != (
sc_digit)-1 ) {
655 for (
int digit_i = right_hod; digit_i < left_hod; ++digit_i ) {
656 if ( target_p[digit_i] != (
sc_digit)-1 ) {
665 ~( (std::numeric_limits<sc_digit>::max()-1) <<
SC_BIT_INDEX(left_i) );
666 if ( ( target_p[left_hod] & mask ) != mask ) {
691template<
int SL,
int SR>
705 left_hod_value = (int)left_p[left_hod];
706 if ( SL ==
true && SR ==
false && ( 0 > left_hod_value ) ) {
712 right_hod_value = (int)right_p[right_hod];
713 if ( SL ==
false && SR ==
true && ( 0 > right_hod_value ) ) {
720 if ( SL ==
true && SR ==
true && (0 > left_hod_value) &&
721 (0 <= right_hod_value ) ) {
728 if ( SL ==
true && SR ==
true && (0 <= left_hod_value) &&
729 (0 > right_hod_value ) ) {
735 else if ( SL ==
true && SR ==
true && (0 > left_hod_value) ) {
736 if ( left_hod >= right_hod ) {
737 for ( digit_i = left_hod; digit_i > right_hod; --digit_i ) {
738 if ( left_p[digit_i] != (
sc_digit)-1 ) {
744 for ( digit_i = right_hod; digit_i > left_hod; --digit_i ) {
745 if ( right_p[digit_i] != (
sc_digit)-1 ) {
750 for ( ; digit_i >= 0; --digit_i ) {
751 if ( left_p[digit_i] != right_p[digit_i] ) {
752 return ( left_p[digit_i] < right_p[digit_i] ) ? -1 : 1;
761 if ( left_hod >= right_hod ) {
762 for ( digit_i = left_hod; digit_i > right_hod; --digit_i ) {
763 if ( left_p[digit_i] != 0 ) {
769 for ( digit_i = right_hod; digit_i > left_hod; --digit_i ) {
770 if ( right_p[digit_i] != 0 ) {
775 for ( ; digit_i >= 0; --digit_i ) {
776 if ( left_p[digit_i] != right_p[digit_i] ) {
777 return ( left_p[digit_i] < right_p[digit_i] ) ? -1 : 1;
806 if ( from_n < to_n ) {
807 for ( digit_i = 0; digit_i < from_n; ++digit_i ) {
808 to_p[digit_i] = from_p[digit_i];
810 sc_digit fill = 0 > (int)from_p[from_n-1] ? -1 : 0;
811 for ( ; digit_i < to_n; ++digit_i ) {
812 to_p[digit_i] = fill;
816 for ( digit_i = 0; digit_i < to_n; ++digit_i ) {
817 to_p[digit_i] = from_p[digit_i];
839 for (
int digit_i = 0; digit_i < digits_n; ++digit_i ) {
840 to_p[digit_i] = from_p[digit_i];
869 dst_hob = high_bit-low_bit;
876 if ( 0 == right_shift ) {
877 const sc_digit* src_p = &source_p[lod];
879 for (
int digit_i = lod; digit_i <= hod; ++digit_i ) {
886 else if ( hod == lod ) {
887 *destination_p = source_p[lod] >> right_shift;
895 const sc_digit* src_p = &source_p[lod];
896 sc_digit carry = *src_p++ >> right_shift;
898 for (
int digit_i = lod+1; digit_i <= hod; ++digit_i ) {
900 *dst_p++ = (
value << left_shift) | carry;
901 carry = (
value >> right_shift);
904 if ( dst_p == &destination_p[dst_hod] ) {
931 for (
int digit_i = 0; digit_i <= to_hod; ++digit_i ) {
932 to_p[digit_i] = fill;
963 target_p[lod] = ( target_p[lod] & ~mask ) | ( fill & mask );
973 target_p[lod] = (target_p[lod] & low_mask ) | (fill & low_mask);
974 for (
int digit_i = lod+1; digit_i < hod; ++digit_i ) {
975 target_p[digit_i] = fill;
978 target_p[hod] = (target_p[lod] & ~high_mask ) | (fill & high_mask);
997 for (
int digit_i = 0; digit_i <= target_hod; ++digit_i ) {
998 target_p[digit_i] = ~target_p[digit_i];
1019 for (
int digit_i = 0; digit_i <= source_hod; ++digit_i ) {
1020 *target_p++ = ~*source_p++;
1040 for ( ; high_i > low_i; --high_i, ++low_i ) {
1046 if ( hom & target_p[hod] ) {
1047 if ( !( lom & target_p[lod] ) ) {
1048 target_p[hod] &= ~hom;
1049 target_p[lod] |= lom;
1052 else if ( lom & target_p[lod] ) {
1053 target_p[hod] |= hom;
1054 target_p[lod] &= ~lom;
1079 const int high_bit_i,
1080 const int low_bit_i )
1092 if ( high_bit_i >= low_bit_i ) {
1110 from_hod = from_digits_n - 1;
1113 std::cout <<
"vector_insert_bits(" << from_hod <<
", from_p, to_p, "
1114 << high_bit_i <<
", " << low_bit_i <<
"):" << std::endl;
1115 std::cout <<
" to_lob = " << to_lob << std::endl;
1116 std::cout <<
" to_lod = " << to_lod << std::endl;
1117 std::cout <<
" to_hob = " << to_hob << std::endl;
1118 std::cout <<
" to_hod = " << to_hod << std::endl;
1127 if ( to_hod == to_lod ) {
1129 to_p[to_lod] = ( to_p[to_lod] & ~(mask << to_lob) ) |
1130 ( ( *from_p & mask ) << to_lob) ;
1143 const int full_hod = to_hod - to_lod;
1144 const int src_hod = full_hod > from_hod ? from_hod : full_hod;
1146 std::cout <<
" full_hod = " << full_hod << std::endl;
1147 std::cout <<
" src_hod = " << src_hod << std::endl;
1154 if ( 0 == to_lob ) {
1163 if ( full_hod > src_hod ) {
1164 for ( digit_i = 0; digit_i <= src_hod; ++digit_i ) {
1165 *dst_p++ = *src_p++;
1167 const sc_digit fill = 0 > (int)from_p[from_hod] ? -1 : 0;
1168 for ( ; digit_i < full_hod; ++digit_i ) {
1171 *dst_p = ( *dst_p & ~to_hob_mask ) | ( fill & to_hob_mask );
1174 for ( digit_i = 0; digit_i < src_hod; ++digit_i ) {
1175 *dst_p++ = *src_p++;
1177 *dst_p = ( *dst_p & ~to_hob_mask ) | ( *src_p & to_hob_mask );
1188 int left_shift = to_lob;
1193 sc_digit low_value = *dst_p & low_mask;
1194 if ( full_hod > src_hod ) {
1195 for ( digit_i = 0; digit_i <= src_hod; ++digit_i ) {
1197 *dst_p++ = (high_value << left_shift) | low_value;
1198 low_value = high_value >> right_shift;
1200 const sc_digit fill = 0 > (int)from_p[from_hod] ? -1 : 0;
1201 for ( ; digit_i < full_hod; ++digit_i ) {
1203 *dst_p++ = (high_value << left_shift) | low_value;
1204 low_value = high_value >> right_shift;
1206 sc_digit highest_value = (fill << left_shift) | low_value;
1208 *dst_p = (*dst_p & ~to_hob_mask) | (highest_value & to_hob_mask);
1211 for ( digit_i = 0; digit_i < src_hod; ++digit_i ) {
1213 *dst_p++ = (high_value << left_shift) | low_value;
1214 low_value = high_value >> right_shift;
1217 highest_value = highest_value << left_shift | low_value;
1218 *dst_p = (*dst_p & ~to_hob_mask) | (highest_value & to_hob_mask);
1308 std::cout <<
" m_high_bits " <<
m_high_bits <<
" [0x" << std::hex
1310 std::cout <<
" m_low_bits " <<
m_low_bits <<
" [0x" << std::hex
1408 if ( left_hod >= right_hod ) {
1409 longer_hod = left_hod;
1411 shorter_hod = right_hod;
1412 shorter_p = right_p;
1415 longer_hod = right_hod;
1417 shorter_hod = left_hod;
1431 for (result_i=0; result_i < shorter_hod; ++result_i ) {
1432 for (
int other_i=0; other_i <= result_i; ++other_i ) {
1433 mac.
add_product( longer_p[result_i-other_i], shorter_p[other_i]);
1453 for ( result_i = shorter_hod; result_i < longer_hod; ++result_i ) {
1455 (
int)shorter_p[shorter_hod] );
1456 for(
int other_i=0; other_i < shorter_hod; ++other_i ) {
1457 mac.
add_product( longer_p[result_i-other_i], shorter_p[other_i] );
1469 for ( result_i=longer_hod; result_i < longer_hod+shorter_hod;
1472 (
int)shorter_p[shorter_hod] );
1473 for (
int other_i=result_i-(longer_hod-1); other_i < shorter_hod;
1476 shorter_p[other_i] );
1479 shorter_p[result_i-longer_hod] );
1482 mac.
add_product((
int)longer_p[longer_hod], (
int)shorter_p[shorter_hod]);
1483 result_p[longer_hod+shorter_hod] = mac.
shift_down();
1494 if ( (result_hod+1) >= longer_hod+shorter_hod+1) {
1495 if ( (result_hod) >= longer_hod+shorter_hod+1 ) {
1496 result_p[longer_hod+shorter_hod+1] = mac.
low_bits();
1497 sc_digit fill = 0 > (int)result_p[longer_hod+shorter_hod+1] ? -1:0;
1498 for ( result_i = longer_hod+shorter_hod+2; result_i <= result_hod;
1500 result_p[result_i] = fill;
1523template<
bool SL,
bool SS>
1528 const int shorter_hod,
1532 if ( 0 == longer_hod ) {
1533 *result_p = *longer_p | *shorter_p;
1541 for ( digit_i = 0; digit_i <= shorter_hod; ++digit_i ) {
1542 *result_p++ = *longer_p++ | shorter_p[digit_i];
1548 if ( longer_hod > shorter_hod ) {
1549 if ( SS && 0 > (
int)shorter_p[shorter_hod] ) {
1550 for ( ; digit_i <= longer_hod; ++digit_i ) {
1555 for ( ; digit_i <= longer_hod; ++digit_i ) {
1556 *result_p++ = *longer_p++;
1583 for (
int digit_i = 0; digit_i < hod; ++digit_i ) {
1584 if ( target_p[digit_i] != (
sc_digit)0 ) {
1591 ~( (std::numeric_limits<sc_digit>::max()-1) <<
SC_BIT_INDEX(bits_n-1) );
1592 if ( ( target_p[hod] & mask ) != 0 ) {
1622 if ( left_hod == right_hod ) {
1624 ~( (std::numeric_limits<sc_digit>::max()-1) << (left_i-right_i) );
1625 return ( ( target_p[right_hod] & mask ) != 0 ) ?
true :
false;
1633 if ( right_index ) {
1635 (std::numeric_limits<sc_digit>::max() << (right_index-1) );
1636 if ( ( target_p[right_hod] & mask ) != (
sc_digit)0 ) {
1639 for (
int digit_i = right_hod+1; digit_i < left_hod; ++digit_i ) {
1640 if ( target_p[digit_i] != (
sc_digit)0 ) {
1650 for (
int digit_i = right_hod; digit_i < left_hod; ++digit_i ) {
1651 if ( target_p[digit_i] != (
sc_digit)0 ) {
1660 ~( (std::numeric_limits<sc_digit>::max()-1) <<
SC_BIT_INDEX(left_i) );
1661 if ( ( target_p[left_hod] & mask ) != 0 ) {
1686 const int to_digits_n,
1692 if ( shift_n < 0 ) {
1706 from_hod = from_digits_n-1;
1708 carry_shift_n = 32-from_shift_n;
1709 to_hod = to_digits_n-1;
1711 to_end_hod =
VEC_MIN( to_hod, to_start_hod+from_hod );
1712 fill = 0 > (int)from_p[from_hod] ? ~0u : 0;
1715 std::cout <<
"from_hod = " << std::dec << from_hod << std::endl;
1716 std::cout <<
"to_hod = " << to_hod << std::endl;
1717 std::cout <<
"shift_n = " << shift_n << std::endl;
1718 std::cout <<
"carry_shift_n = " << carry_shift_n << std::endl;
1719 std::cout <<
"from_shift_n = " << from_shift_n << std::endl;
1720 std::cout <<
"to_start_hod = " << to_start_hod << std::endl;
1721 std::cout <<
"to_end_hod = " << to_end_hod << std::endl;
1722 std::cout <<
"fill = " << std::hex << fill << std::dec << std::endl;
1727 for ( to_i = 0; to_i < to_start_hod; ++to_i ) {
1733 if ( to_i > to_hod ) {
1734 std::cerr <<
"vector_shift_left: shift larger than target, word " << to_i <<
" > "
1735 << to_hod << std::endl;
1741 if ( 0 == from_shift_n ) {
1742 for ( from_i=0; to_i <= to_end_hod; ++from_i, ++to_i ) {
1743 to_p[to_i] = from_p[from_i];
1745 if ( to_i <= to_hod ) {
1746 fill = 0 > (int)from_p[from_hod] ? -1 : 0;
1747 for ( ; to_i <= to_hod; ++to_i ) {
1758 for ( ; to_i <= to_end_hod; ++from_i, ++to_i ) {
1759 sc_digit from_digit = from_p[from_i];
1760 to_p[to_i] = (from_digit << from_shift_n) | carry;
1761 carry = from_digit >> carry_shift_n;
1763 if ( to_i <= to_hod ) { to_p[to_i] = (fill << from_shift_n) | carry; }
1764 for ( to_i = to_i+1; to_i <= to_hod; ++to_i ) {
1794 std::cerr <<
"vector_shift_left: negative shift encountered " << shift_n << std::endl;
1799 int shift_remaining = shift_n;
1809 shift_remaining = 0;
1820 for (
int digit_i = target_n - 1; digit_i >= digits_n; --digit_i)
1821 target_p[digit_i] = target_p[digit_i - digits_n];
1823 const int clear_n =
VEC_MIN( digits_n, target_n );
1824 for (
int digit_i = 0; digit_i < clear_n; ++digit_i ) {
1825 target_p[digit_i] = 0;
1830 if (shift_remaining == 0)
1837 sc_digit* target_iter_p = target_p;
1838 sc_digit* target_end_p = target_iter_p + target_n;
1845 while (target_iter_p < target_end_p) {
1846 sc_digit target_value = (*target_iter_p);
1847 (*target_iter_p++) = (
sc_digit)(((target_value & mask) << shift_remaining) | carry);
1848 carry = target_value >> carry_shift;
1901 for (
int digit_i = 0; digit_i < (target_n - nd); ++digit_i) {
1902 target_p[digit_i] = target_p[digit_i + nd];
1905 for (
int digit_i = target_n -
VEC_MIN( nd, target_n );
1906 digit_i < target_n; ++digit_i) {
1907 target_p[digit_i] = fill;
1923 sc_digit carry = fill << other_shift_n;
1924 sc_digit *target_iter_p = (target_p + target_n );
1926 while (target_p < target_iter_p) {
1927 sc_digit target_val = *--target_iter_p;
1928 (*target_iter_p) = (target_val >> bits_n) | carry;
1929 carry = target_val << other_shift_n;
1974 const int shorter_hod,
1976 const int result_hod,
1979 if ( result_hod == 0 ) {
1980 *result_p = *shorter_p - *longer_p;
1989 for ( digit_i = 0; digit_i < shorter_hod; ++digit_i ) {
1990 borrow += *shorter_p++;
1991 borrow -= *longer_p++;
1999 if ( longer_hod == shorter_hod ) {
2000 borrow += (
int64)(
int)*shorter_p++;
2001 borrow -= (
int64)(
int)*longer_p++;
2013 borrow += (
int64)(
int)*shorter_p++;
2014 borrow -= *longer_p++;
2018 for ( ++digit_i; digit_i < longer_hod; ++digit_i ) {
2019 borrow -= *longer_p++;
2024 borrow -= (
int64)(
int)*longer_p++;
2032 if ( result_hod > longer_hod ) {
2079 const int shorter_hod,
2081 const int result_hod,
2084 if ( result_hod == 0 ) {
2085 *result_p = *longer_p - *shorter_p;
2094 for ( digit_i = 0; digit_i < shorter_hod; ++digit_i ) {
2095 borrow -= *shorter_p++;
2096 borrow += *longer_p++;
2104 if ( longer_hod == shorter_hod ) {
2105 borrow -= (
int64)(
int)*shorter_p++;
2106 borrow += (
int64)(
int)*longer_p++;
2118 borrow -= (
int64)(
int)*shorter_p++;
2119 borrow += *longer_p++;
2123 for ( ++digit_i; digit_i < longer_hod; ++digit_i ) {
2124 borrow += *longer_p++;
2129 borrow += (
int64)(
int)*longer_p++;
2137 if ( result_hod > longer_hod ) {
2156 long long carry = 0;
2157 for (
int digit_i = 0; digit_i < target_n; ++digit_i ) {
2158 carry -= target_p[digit_i];
2159 target_p[digit_i] = (
sc_digit)carry;
2181 long long carry = 0;
2182 for (
int digit_i = 0; digit_i <= source_hod; ++digit_i ) {
2183 carry -= *source_p++;
2254template<
bool SN,
bool SD>
2259 const int denominator_n,
2261 const int quotient_n,
2263 const int remainder_n,
2268 if ( 0 != quotient_n ) {
2269 for(
int quot_i=0; quot_i < quotient_n; ++quot_i) {
2270 quotient_p[quot_i] = 0;
2273 if ( 0 != remainder_n ) {
2274 for(
int remain_i=0; remain_i < remainder_n; ++remain_i) {
2275 remainder_p[remain_i] = numerator_p[remain_i];
2284 bool negative_numerator =
false;
2285 bool negative =
false;
2287 if ( SN && ( 0 > (
int)numerator_p[numerator_n-1] ) ) {
2290 numerator_complement_p );
2291 numerator_p = numerator_complement_p;
2293 negative_numerator =
true;
2296 if ( SD && (0 > (
int)denominator_p[denominator_n-1]) ) {
2299 denominator_complement_p );
2300 denominator_p = denominator_complement_p;
2301 negative = !negative;
2315 bool denom_16_hod_odd = (bool)(denominator_p[denom_32_hod] >> 16);
2316 int denom_16_hod= 2*denom_32_hod + denom_16_hod_odd;
2318 for ( numer_32_hod = numerator_n-1;
2319 numer_32_hod > 0 && !numerator_p[numer_32_hod];
2323 int numer_16_hod = 2*numer_32_hod + (bool)(numerator_p[numer_32_hod]>>16);
2327 if ( !denom_32_hod && !denominator_p[0]) {
2334 if ( numer_16_hod < denom_16_hod ) {
2345 uint64 denom_value = (
uint64)denominator_p[denom_32_hod] <<
2346 (16 << (
int)!denom_16_hod_odd);
2347 if ( denom_32_hod ) {
2348 denom_value |= denominator_p[denom_32_hod-1] >>
2349 (denom_16_hod_odd ? 16 : 0);
2357 for (
int remain_32_i = 0; remain_32_i <= numer_32_hod; ++remain_32_i ) {
2358 remain_work_p[remain_32_i] = numerator_p[remain_32_i];
2360 remain_work_p[numer_32_hod+1] = 0;
2376 for (
int quot_16_i = numer_16_hod - denom_16_hod; quot_16_i >= 0;
2381 bool quot_16_odd = quot_16_i & 1;
2382 int quot_32_i = quot_16_i >> 1;
2383 int remain_16_i = quot_16_i + denom_16_hod;
2384 int remain_32_i = remain_16_i >> 1;
2385 bool remain_16_odd = remain_16_i & 1;
2393 sc_digit low_order_bits = remain_32_i > 0 ? remain_work_p[remain_32_i-1] :
2396 if ( remain_16_odd ) {
2397 numer_value = ( (
uint64)remain_work_p[remain_32_i+1] << 48 ) |
2398 ( (
uint64)remain_work_p[remain_32_i] << 16 ) |
2399 ( low_order_bits >> 16 );
2402 numer_value = ( (
uint64)remain_work_p[remain_32_i] << 32 ) |
2407 if ( quot_guess >> 16 ) {
2416 uint64 quot_term = quot_guess << (quot_16_odd ? 16:0);
2418 for (
int denom_32_i = 0; denom_32_i <= denom_32_hod; ++denom_32_i) {
2419 carry += remain_work_p[quot_32_i + denom_32_i];
2420 bool carry_was_minus = carry < 0;
2421 product = denominator_p[denom_32_i] * quot_term;
2422 bool product_hob_one = (product < 0);
2424 remain_work_p[quot_32_i + denom_32_i] = (
sc_digit)carry;
2425 bool carry_is_minus = carry < 0;
2445 if ( !carry_is_minus && (product_hob_one || carry_was_minus ) ) {
2446 carry |= (std::numeric_limits<uint64_t>::max() << 32);
2448 else if ( carry_is_minus && product_hob_one && carry_was_minus ) {
2449 carry ^= (1LL << 32);
2457 if ( quot_16_odd || denom_16_hod_odd ) {
2458 carry += remain_work_p[quot_32_i + denom_32_hod + 1];
2459 remain_work_p[quot_32_i + denom_32_hod + 1] = (
sc_digit)carry;
2468 for(
int restore_i = 0; restore_i <= denom_32_hod; ++restore_i) {
2469 carry += (
int64)denominator_p[restore_i] <<
2470 (quot_16_odd ? 16:0);
2471 carry += remain_work_p[quot_32_i + restore_i];
2472 remain_work_p[quot_32_i + restore_i] = (
sc_digit)carry;
2475 if ( quot_16_odd | denom_16_hod_odd ) {
2476 remain_work_p[quot_32_i+denom_32_hod+1] += (
sc_digit)carry;
2483 if( quotient_n && quot_32_i < quotient_n ) {
2485 quotient_p[quot_32_i] = quot_guess << 16;
2488 quotient_p[quot_32_i] |= quot_guess;
2498 if ( (SN || SD) && negative && quotient_n ) {
2503 int remain_n =
VEC_MIN(remainder_n-1, numer_32_hod);
2504 for (
int remain_i = 0; remain_i <= remain_n; ++remain_i) {
2505 remainder_p[remain_i] = remain_work_p[remain_i];
2507 for (
int remain_i = remain_n+1; remain_i < remainder_n; ++remain_i) {
2508 remainder_p[remain_i] = 0;
2510 if ( SN && negative_numerator ) {
2534template<
int SL,
int SS>
2539 const int shorter_hod,
2543 if ( 0 == longer_hod ) {
2544 *result_p = *longer_p ^ *shorter_p;
2552 for ( digit_i = 0; digit_i <= shorter_hod; ++digit_i ) {
2553 *result_p++ = *longer_p++ ^ shorter_p[digit_i];
2559 if ( longer_hod > shorter_hod ) {
2560 if ( SS && 0 > (
int)shorter_p[shorter_hod] ) {
2561 for ( ; digit_i <= longer_hod; ++digit_i ) {
2562 *result_p++ = *longer_p++ ^ (
sc_digit)-1;
2566 for ( ; digit_i <= longer_hod; ++digit_i ) {
2567 *result_p++ = *longer_p++;
2590 const unsigned char* byte_p = (
const unsigned char*)target_p;
2596 for (
int byte_i = 0; byte_i < 4*hod; ++byte_i ) {
2603 ~((std::numeric_limits<sc_digit>::max()-1) <<
SC_BIT_INDEX(bits_n-1));
2604 const sc_digit high_order_bits = target_p[hod] & mask;
2605 byte_p = (
const unsigned char*)&high_order_bits;
2632 const unsigned char* byte_p = (
const unsigned char*)target_p;
2639 if ( left_hod == right_hod ) {
2641 ~((std::numeric_limits<sc_digit>::max()-1) << (left_i-right_i) );
2642 const sc_digit digit_bits = target_p[right_hod] & mask;
2643 byte_p = (
const unsigned char*)&digit_bits;
2656 if ( right_index ) {
2658 ( std::numeric_limits<sc_digit>::max() << (right_index-1) );
2659 const sc_digit digit_bits = target_p[right_hod] & mask;
2660 byte_p = (
const unsigned char*)&digit_bits;
2665 byte_p = (
const unsigned char*)target_p;
2666 for (
int byte_i = 4*(right_hod+1); byte_i < 4*left_hod; ++byte_i ) {
2675 byte_p = (
const unsigned char*)target_p;
2676 for (
int byte_i = 0; byte_i < 4*left_hod; ++byte_i ) {
2684 ~( (std::numeric_limits<sc_digit>::max()-1) <<
SC_BIT_INDEX(left_i) );
2686 const sc_digit high_order_bits = target_p[left_hod] & mask;
2687 byte_p = (
const unsigned char*)&high_order_bits;
2710 for (
int digit_i = from_i; digit_i < to_i; ++digit_i ) { target_p[digit_i] = 0; }
#define SC_DIGIT_INDEX(BIT_INDEX)
#define SC_BIT_INDEX(BIT)
#define SC_BIT_MASK1(BITS)
#define SC_DIGIT_COUNT(BIT_WIDTH)
#define SC_BIT_MASK(BITS)
int vector_compare(const int left_hod, const sc_digit *left_p, const int right_hod, const sc_digit *right_p)
void vector_fill(const sc_digit fill, const int to_hod, sc_digit *to_p)
void vector_subtract_shorter(const int longer_hod, const sc_digit *longer_p, const int shorter_hod, const sc_digit *shorter_p, const int result_hod, sc_digit *result_p)
int vector_skip_leading_zeros(const int hod, const sc_digit *digits_p)
void vector_xor(const int longer_hod, const sc_digit *longer_p, const int shorter_hod, const sc_digit *shorter_p, sc_digit *result_p)
void vector_fill_bits(sc_digit fill, sc_digit *target_p, const int high_bit, const int low_bit)
sc_digit_heap SC_API sc_temporary_digits
void vector_add(const int longer_hod, const sc_digit *longer_p, const int shorter_hod, const sc_digit *shorter_p, const int result_hod, sc_digit *result_p)
bool vector_and_reduce(const int bits_n, const sc_digit *target_p)
unsigned long long uint64
void vector_or(const int longer_hod, const sc_digit *longer_p, const int shorter_hod, const sc_digit *shorter_p, sc_digit *result_p)
void vector_extract(const sc_digit *source_p, sc_digit *destination_p, const int high_bit, const int low_bit)
void vector_ones_complement(const int target_hod, sc_digit *target_p)
int vector_skip_leading_ones(const int hod, const sc_digit *digits_p)
void vector_zero(int from_i, int to_i, sc_digit *target_p)
void vector_copy(const int from_n, const sc_digit *from_p, const int to_n, sc_digit *to_p)
constexpr int byte_one_bits[256]
sc_carry one_and_ones(int n)
void vector_twos_complement(const int target_n, sc_digit *target_p)
bool vector_xor_reduce(const int bits_n, const sc_digit *target_p)
bool vector_or_reduce(const int bits_n, const sc_digit *target_p)
sc_lv_base reverse(const sc_proxy< X > &x)
void vector_multiply(int left_hod, const sc_digit *left_p, int right_hod, const sc_digit *right_p, int result_hod, sc_digit *result_p)
bool vector_divide(const int numerator_n, const sc_digit *numerator_p, const int denominator_n, const sc_digit *denominator_p, const int quotient_n, sc_digit *quotient_p, const int remainder_n, sc_digit *remainder_p)
void vector_reverse_bits(sc_digit *target_p, int high_i, int low_i)
int vector_find_significant_hod(int hod, const sc_digit *digits)
void vector_insert_bits(const int from_digits_n, const sc_digit *from_p, sc_digit *to_p, const int high_bit_i, const int low_bit_i)
void vector_shift_left(const int from_digits_n, const sc_digit *from_p, const int to_digits_n, sc_digit *to_p, const int shift_n)
void vector_shift_right(const int target_n, sc_digit *target_p, int bits_n, const sc_digit fill)
void vector_and(const int longer_hod, const sc_digit *longer_p, const int shorter_hod, const sc_digit *shorter_p, sc_digit *result_p)
void vector_subtract_longer(const int longer_hod, const sc_digit *longer_p, const int shorter_hod, const sc_digit *shorter_p, const int result_hod, sc_digit *result_p)
sc_core::sc_signal_in_if< T > & value(const T &val)
sc_digit * allocate(size_t digits_n)
sc_bigint< WIDTH > top_type
sc_biguint< WIDTH > top_type
sc_big_op_type< sub_bits, signed_result >::top_type sub_result
sc_big_op_type< WL, SL >::top_type left_op
sc_big_op_type< mod_bits, signed_result >::top_type mod_result
sc_big_op_type< div_bits, signed_result >::top_type div_result
sc_big_op_type< WL, SL >::base_type left_base
sc_big_op_type< WR, SR >::base_type right_base
sc_big_op_type< add_bits, signed_result >::top_type add_result
sc_big_op_type< WR, SR >::top_type right_op
sc_big_op_type< mul_bits, signed_result >::top_type mul_result
sc_big_op_type< bit_bits, signed_result >::top_type bit_result
const sc_digit * get_digits() const
ScNativeDigits(int64 init)
int get_actual_length() const
int get_actual_length() const
const sc_digit * get_digits() const
ScNativeDigits(uint64 init)
ScNativeDigits(long init)
int get_actual_length() const
const sc_digit * get_digits() const
ScNativeDigits(unsigned long init)
int get_actual_length() const
const sc_digit * get_digits() const
const sc_digit * get_digits() const
int get_actual_length() const
const sc_digit * get_digits() const
ScNativeDigits(unsigned long init)
int get_actual_length() const
void add_product(unsigned int left, int right)
void add_product(unsigned int left, unsigned int right)
void add_product(int left, unsigned int right)
void add_product(int left, int right)