00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include "sysc/datatypes/int/sc_nbexterns.h"
00050 #include "sysc/kernel/sc_macros.h"
00051
00052
00053 namespace sc_dt
00054 {
00055
00056
00057
00058
00059
00060
00061 void
00062 add_on_help(small_type &us, int , int und,
00063 sc_digit *ud,
00064 small_type vs, int , int vnd,
00065 const sc_digit *vd)
00066 {
00067
00068 vnd = vec_skip_leading_zeros(vnd, vd);
00069
00070 if (us == vs) {
00071
00072 if (und >= vnd)
00073 vec_add_on(und, ud, vnd, vd);
00074 else
00075 vec_add_on2(und, ud, vnd, vd);
00076
00077 }
00078 else {
00079
00080
00081 int new_und = vec_skip_leading_zeros(und, ud);
00082 int cmp_res = vec_cmp(new_und, ud, vnd, vd);
00083
00084 if (cmp_res == 0) {
00085 us = SC_ZERO;
00086 vec_zero(und, ud);
00087 return;
00088 }
00089
00090 if (cmp_res > 0)
00091 vec_sub_on(und, ud, vnd, vd);
00092
00093 else {
00094 us = -us;
00095 vec_sub_on2(und, ud, vnd, vd);
00096 }
00097
00098 }
00099 }
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 void
00125 mul_on_help_signed(small_type &us,
00126 int unb, int und,
00127 sc_digit *ud,
00128 int vnb, int vnd,
00129 const sc_digit *vd)
00130 {
00131 #define CONVERT_SM_to_2C_to_SM convert_signed_SM_to_2C_to_SM
00132 #define COPY_DIGITS copy_digits_signed
00133
00134 {
00135
00136 int old_und = und;
00137
00138 und = vec_skip_leading_zeros(und, ud);
00139 vnd = vec_skip_leading_zeros(vnd, vd);
00140
00141 sc_digit ud0 = (*ud);
00142 sc_digit vd0 = (*vd);
00143
00144 if ((vnd == 1) && (vd0 == 1)) {
00145 us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud);
00146 return;
00147 }
00148
00149 if ((und == 1) && (ud0 == 1)) {
00150 COPY_DIGITS(us, unb, old_und, ud, vnb, vnd, vd);
00151 return;
00152 }
00153
00154 if ((und == 1) && (vnd == 1) &&
00155 (ud0 < HALF_DIGIT_RADIX) && (vd0 < HALF_DIGIT_RADIX)) {
00156
00157 sc_digit d = ud0 * vd0;
00158 COPY_DIGITS(us, unb, old_und, ud, unb + vnb, 1, &d);
00159 return;
00160
00161 }
00162
00163 int nd = und + vnd;
00164
00165 #ifdef SC_MAX_NBITS
00166 sc_digit d[MAX_NDIGITS];
00167 #else
00168 sc_digit *d = new sc_digit[nd];
00169 #endif
00170
00171 vec_zero(nd, d);
00172
00173 if ((und == 1) && (ud0 < HALF_DIGIT_RADIX))
00174 vec_mul_small(vnd, vd, ud0, d);
00175
00176 else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
00177 vec_mul_small(und, ud, vd0, d);
00178
00179 else if (vnd < und)
00180 vec_mul(und, ud, vnd, vd, d);
00181
00182 else
00183 vec_mul(vnd, vd, und, ud, d);
00184
00185 COPY_DIGITS(us, unb, old_und, ud, unb + vnb, nd, d);
00186
00187 #ifndef SC_MAX_NBITS
00188 delete [] d;
00189 #endif
00190
00191 }
00192
00193 #undef COPY_DIGITS
00194 #undef CONVERT_SM_to_2C_to_SM
00195
00196 }
00197
00198
00199 void
00200 mul_on_help_unsigned(small_type &us,
00201 int unb, int und,
00202 sc_digit *ud,
00203 int vnb, int vnd,
00204 const sc_digit *vd)
00205 {
00206 #define CONVERT_SM_to_2C_to_SM convert_unsigned_SM_to_2C_to_SM
00207 #define COPY_DIGITS copy_digits_unsigned
00208
00209 {
00210
00211 int old_und = und;
00212
00213 und = vec_skip_leading_zeros(und, ud);
00214 vnd = vec_skip_leading_zeros(vnd, vd);
00215
00216 sc_digit ud0 = (*ud);
00217 sc_digit vd0 = (*vd);
00218
00219 if ((vnd == 1) && (vd0 == 1)) {
00220 us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud);
00221 return;
00222 }
00223
00224 if ((und == 1) && (ud0 == 1)) {
00225 COPY_DIGITS(us, unb, old_und, ud, vnb, vnd, vd);
00226 return;
00227 }
00228
00229 if ((und == 1) && (vnd == 1) &&
00230 (ud0 < HALF_DIGIT_RADIX) && (vd0 < HALF_DIGIT_RADIX)) {
00231
00232 sc_digit d = ud0 * vd0;
00233 COPY_DIGITS(us, unb, old_und, ud, unb + vnb, 1, &d);
00234 return;
00235
00236 }
00237
00238 int nd = und + vnd;
00239
00240 #ifdef SC_MAX_NBITS
00241 sc_digit d[MAX_NDIGITS];
00242 #else
00243 sc_digit *d = new sc_digit[nd];
00244 #endif
00245
00246 vec_zero(nd, d);
00247
00248 if ((und == 1) && (ud0 < HALF_DIGIT_RADIX))
00249 vec_mul_small(vnd, vd, ud0, d);
00250
00251 else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
00252 vec_mul_small(und, ud, vd0, d);
00253
00254 else if (vnd < und)
00255 vec_mul(und, ud, vnd, vd, d);
00256
00257 else
00258 vec_mul(vnd, vd, und, ud, d);
00259
00260 COPY_DIGITS(us, unb, old_und, ud, unb + vnb, nd, d);
00261
00262 #ifndef SC_MAX_NBITS
00263 delete [] d;
00264 #endif
00265
00266 }
00267
00268 #undef COPY_DIGITS
00269 #undef CONVERT_SM_to_2C_to_SM
00270
00271 }
00272
00273
00274
00275
00276
00277
00278 void
00279 div_on_help_signed(small_type &us,
00280 int unb, int und,
00281 sc_digit *ud,
00282 int vnb, int vnd,
00283 const sc_digit *vd)
00284 {
00285 #define CONVERT_SM_to_2C_to_SM convert_signed_SM_to_2C_to_SM
00286 #define COPY_DIGITS copy_digits_signed
00287
00288 {
00289
00290 int old_und = und;
00291
00292 und = vec_skip_leading_zeros(und, ud);
00293 vnd = vec_skip_leading_zeros(vnd, vd);
00294
00295 int cmp_res = vec_cmp(und, ud, vnd, vd);
00296
00297 if (cmp_res < 0) {
00298 us = SC_ZERO;
00299 vec_zero(old_und, ud);
00300 return;
00301 }
00302
00303 sc_digit vd0 = (*vd);
00304
00305 if ((cmp_res > 0) && (vnd == 1) && (vd0 == 1)) {
00306 us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud);
00307 return;
00308 }
00309
00310
00311 int nd = sc_max(und, vnd) + 1;
00312
00313 #ifdef SC_MAX_NBITS
00314 sc_digit d[MAX_NDIGITS + 1];
00315 #else
00316 sc_digit *d = new sc_digit[nd];
00317 #endif
00318
00319 vec_zero(nd, d);
00320
00321
00322 if (cmp_res == 0)
00323 d[0] = 1;
00324
00325 else if ((vnd == 1) && (und == 1))
00326 d[0] = (*ud) / vd0;
00327
00328 else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
00329 vec_div_small(und, ud, vd0, d);
00330
00331 else
00332 vec_div_large(und, ud, vnd, vd, d);
00333
00334 COPY_DIGITS(us, unb, old_und, ud, sc_max(unb, vnb), nd - 1, d);
00335
00336 #ifndef SC_MAX_NBITS
00337 delete [] d;
00338 #endif
00339
00340 }
00341
00342 #undef COPY_DIGITS
00343 #undef CONVERT_SM_to_2C_to_SM
00344
00345 }
00346
00347
00348 void
00349 div_on_help_unsigned(small_type &us,
00350 int unb, int und,
00351 sc_digit *ud,
00352 int vnb, int vnd,
00353 const sc_digit *vd)
00354 {
00355 #define CONVERT_SM_to_2C_to_SM convert_unsigned_SM_to_2C_to_SM
00356 #define COPY_DIGITS copy_digits_unsigned
00357
00358 {
00359
00360 int old_und = und;
00361
00362 und = vec_skip_leading_zeros(und, ud);
00363 vnd = vec_skip_leading_zeros(vnd, vd);
00364
00365 int cmp_res = vec_cmp(und, ud, vnd, vd);
00366
00367 if (cmp_res < 0) {
00368 us = SC_ZERO;
00369 vec_zero(old_und, ud);
00370 return;
00371 }
00372
00373 sc_digit vd0 = (*vd);
00374
00375 if ((cmp_res > 0) && (vnd == 1) && (vd0 == 1)) {
00376 us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud);
00377 return;
00378 }
00379
00380
00381 int nd = sc_max(und, vnd) + 1;
00382
00383 #ifdef SC_MAX_NBITS
00384 sc_digit d[MAX_NDIGITS + 1];
00385 #else
00386 sc_digit *d = new sc_digit[nd];
00387 #endif
00388
00389 vec_zero(nd, d);
00390
00391
00392 if (cmp_res == 0)
00393 d[0] = 1;
00394
00395 else if ((vnd == 1) && (und == 1))
00396 d[0] = (*ud) / vd0;
00397
00398 else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
00399 vec_div_small(und, ud, vd0, d);
00400
00401 else
00402 vec_div_large(und, ud, vnd, vd, d);
00403
00404 COPY_DIGITS(us, unb, old_und, ud, sc_max(unb, vnb), nd - 1, d);
00405
00406 #ifndef SC_MAX_NBITS
00407 delete [] d;
00408 #endif
00409
00410 }
00411
00412 #undef COPY_DIGITS
00413 #undef CONVERT_SM_to_2C_to_SM
00414
00415 }
00416
00417
00418
00419
00420
00421
00422 void
00423 mod_on_help_signed(small_type &us,
00424 int unb, int und,
00425 sc_digit *ud,
00426 int , int vnd,
00427 const sc_digit *vd)
00428 {
00429
00430 #define COPY_DIGITS copy_digits_signed
00431
00432 {
00433
00434 int old_und = und;
00435
00436 und = vec_skip_leading_zeros(und, ud);
00437 vnd = vec_skip_leading_zeros(vnd, vd);
00438
00439 int cmp_res = vec_cmp(und, ud, vnd, vd);
00440
00441
00442 if (cmp_res < 0)
00443 return;
00444
00445
00446 if (cmp_res == 0) {
00447 us = SC_ZERO;
00448 vec_zero(old_und, ud);
00449 return;
00450 }
00451
00452
00453
00454 sc_digit vd0 = (*vd);
00455
00456 if ((vnd == 1) && (vd0 == 1)) {
00457 us = SC_ZERO;
00458 vec_zero(old_und, ud);
00459 return;
00460 }
00461
00462
00463 int nd = sc_max(und, vnd) + 1;
00464
00465 #ifdef SC_MAX_NBITS
00466 sc_digit d[MAX_NDIGITS + 1];
00467 #else
00468 sc_digit *d = new sc_digit[nd];
00469 #endif
00470
00471 vec_zero(nd, d);
00472
00473 if ((vnd == 1) && (und == 1))
00474 d[0] = (*ud) % vd0;
00475
00476 if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
00477 d[0] = vec_rem_small(und, ud, vd0);
00478
00479 else
00480 vec_rem_large(und, ud, vnd, vd, d);
00481
00482 us = check_for_zero(us, nd - 1, d);
00483
00484 if (us == SC_ZERO)
00485 vec_zero(old_und, ud);
00486 else
00487 COPY_DIGITS(us, unb, old_und, ud, sc_min(unb, vnd), nd - 1, d);
00488
00489 #ifndef SC_MAX_NBITS
00490 delete [] d;
00491 #endif
00492
00493 }
00494
00495 #undef COPY_DIGITS
00496
00497 }
00498
00499
00500 void
00501 mod_on_help_unsigned(small_type &us,
00502 int unb, int und,
00503 sc_digit *ud,
00504 int , int vnd,
00505 const sc_digit *vd)
00506 {
00507
00508 #define COPY_DIGITS copy_digits_unsigned
00509
00510 {
00511
00512 int old_und = und;
00513
00514 und = vec_skip_leading_zeros(und, ud);
00515 vnd = vec_skip_leading_zeros(vnd, vd);
00516
00517 int cmp_res = vec_cmp(und, ud, vnd, vd);
00518
00519
00520 if (cmp_res < 0)
00521 return;
00522
00523
00524 if (cmp_res == 0) {
00525 us = SC_ZERO;
00526 vec_zero(old_und, ud);
00527 return;
00528 }
00529
00530
00531
00532 sc_digit vd0 = (*vd);
00533
00534 if ((vnd == 1) && (vd0 == 1)) {
00535 us = SC_ZERO;
00536 vec_zero(old_und, ud);
00537 return;
00538 }
00539
00540
00541 int nd = sc_max(und, vnd) + 1;
00542
00543 #ifdef SC_MAX_NBITS
00544 sc_digit d[MAX_NDIGITS + 1];
00545 #else
00546 sc_digit *d = new sc_digit[nd];
00547 #endif
00548
00549 vec_zero(nd, d);
00550
00551 if ((vnd == 1) && (und == 1))
00552 d[0] = (*ud) % vd0;
00553
00554 if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
00555 d[0] = vec_rem_small(und, ud, vd0);
00556
00557 else
00558 vec_rem_large(und, ud, vnd, vd, d);
00559
00560 us = check_for_zero(us, nd - 1, d);
00561
00562 if (us == SC_ZERO)
00563 vec_zero(old_und, ud);
00564 else
00565 COPY_DIGITS(us, unb, old_und, ud, sc_min(unb, vnd), nd - 1, d);
00566
00567 #ifndef SC_MAX_NBITS
00568 delete [] d;
00569 #endif
00570
00571 }
00572
00573 #undef COPY_DIGITS
00574
00575 }
00576
00577
00578
00579
00580
00581
00582
00583 void
00584 and_on_help(small_type us,
00585 int , int und,
00586 sc_digit *ud,
00587 small_type vs,
00588 int , int vnd,
00589 const sc_digit *vd)
00590 {
00591
00592 register sc_digit *x = ud;
00593 register const sc_digit *y = vd;
00594 int xnd = und;
00595 int ynd = vnd;
00596
00597
00598 if (xnd < ynd)
00599 ynd = xnd;
00600
00601 const sc_digit *xend = (x + xnd);
00602 const sc_digit *yend = (y + ynd);
00603
00604
00605
00606 small_type s = mul_signs(us, vs);
00607
00608 if (s > 0) {
00609
00610 if (us > 0) {
00611
00612 while (y < yend)
00613 (*x++) &= (*y++);
00614
00615 while (x < xend)
00616 (*x++) = 0;
00617
00618 }
00619 else {
00620
00621 register sc_digit xcarry = 1;
00622 register sc_digit ycarry = 1;
00623
00624 while (y < yend) {
00625 xcarry += (~(*x) & DIGIT_MASK);
00626 ycarry += (~(*y++) & DIGIT_MASK);
00627 (*x++) = (xcarry & ycarry) & DIGIT_MASK;
00628 xcarry >>= BITS_PER_DIGIT;
00629 ycarry >>= BITS_PER_DIGIT;
00630 }
00631
00632 while (x < xend) {
00633 xcarry += (~(*x) & DIGIT_MASK);
00634 ycarry += DIGIT_MASK;
00635 (*x++) = (xcarry & ycarry) & DIGIT_MASK;
00636 xcarry >>= BITS_PER_DIGIT;
00637 ycarry >>= BITS_PER_DIGIT;
00638 }
00639
00640 }
00641 }
00642 else {
00643
00644 if (us > 0) {
00645
00646 register sc_digit ycarry = 1;
00647
00648 while (y < yend) {
00649 ycarry += (~(*y++) & DIGIT_MASK);
00650 (*x++) &= ycarry & DIGIT_MASK;
00651 ycarry >>= BITS_PER_DIGIT;
00652 }
00653
00654 while (x < xend) {
00655 ycarry += DIGIT_MASK;
00656 (*x++) &= ycarry & DIGIT_MASK;
00657 ycarry >>= BITS_PER_DIGIT;
00658 }
00659
00660 }
00661 else {
00662
00663 register sc_digit xcarry = 1;
00664
00665 while (y < yend) {
00666 xcarry += (~(*x) & DIGIT_MASK);
00667 (*x++) = (xcarry & (*y++)) & DIGIT_MASK;
00668 xcarry >>= BITS_PER_DIGIT;
00669 }
00670
00671 while (x < xend)
00672 (*x++) = 0;
00673
00674 }
00675 }
00676 }
00677
00678
00679
00680
00681
00682
00683
00684 void
00685 or_on_help(small_type us,
00686 int , int und,
00687 sc_digit *ud,
00688 small_type vs,
00689 int , int vnd,
00690 const sc_digit *vd)
00691 {
00692
00693 register sc_digit *x = ud;
00694 register const sc_digit *y = vd;
00695 int xnd = und;
00696 int ynd = vnd;
00697
00698 if (xnd < ynd)
00699 ynd = xnd;
00700
00701 const sc_digit *xend = (x + xnd);
00702 const sc_digit *yend = (y + ynd);
00703
00704
00705
00706 small_type s = mul_signs(us, vs);
00707
00708 if (s > 0) {
00709
00710 if (us > 0) {
00711
00712 while (y < yend)
00713 (*x++) |= (*y++);
00714
00715
00716
00717 }
00718 else {
00719
00720 register sc_digit xcarry = 1;
00721 register sc_digit ycarry = 1;
00722
00723 while (y < yend) {
00724 xcarry += (~(*x) & DIGIT_MASK);
00725 ycarry += (~(*y++) & DIGIT_MASK);
00726 (*x++) = (xcarry | ycarry) & DIGIT_MASK;
00727 xcarry >>= BITS_PER_DIGIT;
00728 ycarry >>= BITS_PER_DIGIT;
00729 }
00730
00731 while (x < xend) {
00732 xcarry += (~(*x) & DIGIT_MASK);
00733 ycarry += DIGIT_MASK;
00734 (*x++) = (xcarry | ycarry) & DIGIT_MASK;
00735 xcarry >>= BITS_PER_DIGIT;
00736 ycarry >>= BITS_PER_DIGIT;
00737 }
00738 }
00739
00740 }
00741 else {
00742
00743 if (us > 0) {
00744
00745 register sc_digit ycarry = 1;
00746
00747 while (y < yend) {
00748 ycarry += (~(*y++) & DIGIT_MASK);
00749 (*x) = ((*x) | ycarry) & DIGIT_MASK;
00750 x++;
00751 ycarry >>= BITS_PER_DIGIT;
00752 }
00753
00754 while (x < xend) {
00755 ycarry += DIGIT_MASK;
00756 (*x) = ((*x) | ycarry) & DIGIT_MASK;
00757 x++;
00758 ycarry >>= BITS_PER_DIGIT;
00759 }
00760
00761 }
00762 else {
00763
00764 register sc_digit xcarry = 1;
00765
00766 while (y < yend) {
00767 xcarry += (~(*x) & DIGIT_MASK);
00768 (*x++) = (xcarry | (*y++)) & DIGIT_MASK;
00769 xcarry >>= BITS_PER_DIGIT;
00770 }
00771
00772 while (x < xend) {
00773 xcarry += (~(*x) & DIGIT_MASK);
00774 (*x++) = xcarry & DIGIT_MASK;
00775 xcarry >>= BITS_PER_DIGIT;
00776 }
00777 }
00778 }
00779 }
00780
00781
00782
00783
00784
00785
00786
00787 void
00788 xor_on_help(small_type us,
00789 int , int und,
00790 sc_digit *ud,
00791 small_type vs,
00792 int , int vnd,
00793 const sc_digit *vd)
00794 {
00795
00796 register sc_digit *x = ud;
00797 register const sc_digit *y = vd;
00798 int xnd = und;
00799 int ynd = vnd;
00800
00801 if (xnd < ynd)
00802 ynd = xnd;
00803
00804 const sc_digit *xend = (x + xnd);
00805 const sc_digit *yend = (y + ynd);
00806
00807
00808
00809 small_type s = mul_signs(us, vs);
00810
00811 if (s > 0) {
00812
00813 if (us > 0) {
00814
00815 while (y < yend) {
00816 (*x) = ((*x) ^ (*y)) & DIGIT_MASK;
00817 x++;
00818 y++;
00819 }
00820
00821
00822
00823 }
00824 else {
00825
00826 register sc_digit xcarry = 1;
00827 register sc_digit ycarry = 1;
00828
00829 while (y < yend) {
00830 xcarry += (~(*x) & DIGIT_MASK);
00831 ycarry += (~(*y++) & DIGIT_MASK);
00832 (*x++) = (xcarry ^ ycarry) & DIGIT_MASK;
00833 xcarry >>= BITS_PER_DIGIT;
00834 ycarry >>= BITS_PER_DIGIT;
00835 }
00836
00837 while (x < xend) {
00838 xcarry += (~(*x) & DIGIT_MASK);
00839 ycarry += DIGIT_MASK;
00840 (*x++) = (xcarry ^ ycarry) & DIGIT_MASK;
00841 xcarry >>= BITS_PER_DIGIT;
00842 ycarry >>= BITS_PER_DIGIT;
00843 }
00844 }
00845 }
00846 else {
00847
00848 if (us > 0) {
00849
00850 register sc_digit ycarry = 1;
00851
00852 while (y < yend) {
00853 ycarry += (~(*y++) & DIGIT_MASK);
00854 (*x) = ((*x) ^ ycarry) & DIGIT_MASK;
00855 x++;
00856 ycarry >>= BITS_PER_DIGIT;
00857 }
00858
00859 while (x < xend) {
00860 ycarry += DIGIT_MASK;
00861 (*x) = ((*x) ^ ycarry) & DIGIT_MASK;
00862 x++;
00863 ycarry >>= BITS_PER_DIGIT;
00864 }
00865
00866 }
00867 else {
00868
00869 register sc_digit xcarry = 1;
00870
00871 while (y < yend) {
00872 xcarry += (~(*x) & DIGIT_MASK);
00873 (*x++) = (xcarry ^ (*y++)) & DIGIT_MASK;
00874 xcarry >>= BITS_PER_DIGIT;
00875 }
00876
00877 while (x < xend) {
00878 xcarry += (~(*x) & DIGIT_MASK);
00879 (*x++) = xcarry & DIGIT_MASK;
00880 xcarry >>= BITS_PER_DIGIT;
00881 }
00882 }
00883 }
00884 }
00885
00886 }
00887
00888
00889