1/***************************************************************************** 2 3 Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 more contributor license agreements. See the NOTICE file distributed 5 with this work for additional information regarding copyright ownership. 6 Accellera licenses this file to you under the Apache License, Version 2.0 7 (the "License"); you may not use this file except in compliance with the 8 License. You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12 Unless required by applicable law or agreed to in writing, software 13 distributed under the License is distributed on an "AS IS" BASIS, 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 implied. See the License for the specific language governing 16 permissions and limitations under the License. 17 18 *****************************************************************************/ 19 20/***************************************************************************** 21 22 sc_nbexterns.cpp -- External functions for both sc_signed and sc_unsigned 23 classes. These functions work on two parameters u and 24 v, and copy the result to the first parameter u. This 25 is also the reason that they are suffixed with _on_help. 26 27 Original Author: Ali Dasdan, Synopsys, Inc. 28 29 *****************************************************************************/ 30 31/***************************************************************************** 32 33 MODIFICATION LOG - modifiers, enter your name, affiliation, date and 34 changes you are making here. 35 36 Name, Affiliation, Date: 37 Description of Modification: 38 39 *****************************************************************************/ 40 41 42// $Log: sc_nbexterns.cpp,v $ 43// Revision 1.2 2011/02/18 20:19:15 acg 44// Andy Goodrich: updating Copyright notice. 45// 46// Revision 1.1.1.1 2006/12/15 20:20:05 acg 47// SystemC 2.3 48// 49// Revision 1.3 2006/01/13 18:49:32 acg 50// Added $Log command so that CVS check in comments are reproduced in the 51// source. 52// 53 54#include "sysc/datatypes/int/sc_nbexterns.h" 55#include "sysc/kernel/sc_macros.h" 56 57 58namespace sc_dt 59{ 60 61// ---------------------------------------------------------------------------- 62// SECTION: External functions for PLUS operators. 63// ---------------------------------------------------------------------------- 64 65// Handles the cases 3 and 4 and returns the result in u. 66void 67add_on_help(small_type &us, int /* unb */, int und, 68 sc_digit *ud, 69 small_type vs, int /* vnb */, int vnd, 70 const sc_digit *vd) 71{ 72 73 vnd = vec_skip_leading_zeros(vnd, vd); 74 75 if (us == vs) { // case 3 76 77 if (und >= vnd) 78 vec_add_on(und, ud, vnd, vd); 79 else 80 vec_add_on2(und, ud, vnd, vd); 81 82 } 83 else { // case 4 84 85 // vec_cmp expects that und is the number of non-zero digits in ud. 86 int new_und = vec_skip_leading_zeros(und, ud); 87 int cmp_res = vec_cmp(new_und, ud, vnd, vd); 88 89 if (cmp_res == 0) { // u == v 90 us = SC_ZERO; 91 vec_zero(und, ud); 92 return; 93 } 94 95 if (cmp_res > 0) // u > v 96 vec_sub_on(und, ud, vnd, vd); 97 98 else { // u < v 99 us = -us; 100 vec_sub_on2(und, ud, vnd, vd); 101 } 102 103 } 104} 105 106 107// ---------------------------------------------------------------------------- 108 109/* 110 111mul_on_help_signed and mul_on_help_unsigned have the same body except 112that CONVERT_SM_to_2C_to_SM and COPY_DIGITS are defined for signed and 113unsigned, respectively. This comment also applies to the 114signed/unsigned versions of div_on_help and mod_on_help. It is 115possible to take COPY_DIGITS out of these functions and create a 116single version of each of these helper functions; however, this will 117impose an onverhead on performance. In the versions below, any change 118in the signed version of a helper function must be carried to a 119corresponding change in the unsigned verion of the same function or 120vice versa. 121 122*/ 123 124 125// ---------------------------------------------------------------------------- 126// SECTION: External functions of MULTIPLICATION operators. 127// ---------------------------------------------------------------------------- 128 129void 130mul_on_help_signed(small_type &us, 131 int unb, int und, 132 sc_digit *ud, 133 int vnb, int vnd, 134 const sc_digit *vd) 135{ 136#define CONVERT_SM_to_2C_to_SM convert_signed_SM_to_2C_to_SM 137#define COPY_DIGITS copy_digits_signed 138 139 { // Body of mul_on_help 140 141 int old_und = und; 142 143 und = vec_skip_leading_zeros(und, ud); 144 vnd = vec_skip_leading_zeros(vnd, vd); 145 146 sc_digit ud0 = (*ud); 147 sc_digit vd0 = (*vd); 148 149 if ((vnd == 1) && (vd0 == 1)) { 150 us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud); 151 return; 152 } 153 154 if ((und == 1) && (ud0 == 1)) { 155 COPY_DIGITS(us, unb, old_und, ud, vnb, vnd, vd); 156 return; 157 } 158 159 if ((und == 1) && (vnd == 1) && 160 (ud0 < HALF_DIGIT_RADIX) && (vd0 < HALF_DIGIT_RADIX)) { 161 162 sc_digit d = ud0 * vd0; 163 COPY_DIGITS(us, unb, old_und, ud, unb + vnb, 1, &d); 164 return; 165 166 } 167 168 int nd = und + vnd; 169 170#ifdef SC_MAX_NBITS 171 sc_digit d[MAX_NDIGITS]; 172#else 173 sc_digit *d = new sc_digit[nd]; 174#endif 175 176 vec_zero(nd, d); 177 178 if ((und == 1) && (ud0 < HALF_DIGIT_RADIX)) 179 vec_mul_small(vnd, vd, ud0, d); 180 181 else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) 182 vec_mul_small(und, ud, vd0, d); 183 184 else if (vnd < und) 185 vec_mul(und, ud, vnd, vd, d); 186 187 else 188 vec_mul(vnd, vd, und, ud, d); 189 190 COPY_DIGITS(us, unb, old_und, ud, unb + vnb, nd, d); 191 192#ifndef SC_MAX_NBITS 193 delete [] d; 194#endif 195 196 } 197 198#undef COPY_DIGITS 199#undef CONVERT_SM_to_2C_to_SM 200 201} 202 203 204void 205mul_on_help_unsigned(small_type &us, 206 int unb, int und, 207 sc_digit *ud, 208 int vnb, int vnd, 209 const sc_digit *vd) 210{ 211#define CONVERT_SM_to_2C_to_SM convert_unsigned_SM_to_2C_to_SM 212#define COPY_DIGITS copy_digits_unsigned 213 214 { // Body of mul_on_help 215 216 int old_und = und; 217 218 und = vec_skip_leading_zeros(und, ud); 219 vnd = vec_skip_leading_zeros(vnd, vd); 220 221 sc_digit ud0 = (*ud); 222 sc_digit vd0 = (*vd); 223 224 if ((vnd == 1) && (vd0 == 1)) { 225 us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud); 226 return; 227 } 228 229 if ((und == 1) && (ud0 == 1)) { 230 COPY_DIGITS(us, unb, old_und, ud, vnb, vnd, vd); 231 return; 232 } 233 234 if ((und == 1) && (vnd == 1) && 235 (ud0 < HALF_DIGIT_RADIX) && (vd0 < HALF_DIGIT_RADIX)) { 236 237 sc_digit d = ud0 * vd0; 238 COPY_DIGITS(us, unb, old_und, ud, unb + vnb, 1, &d); 239 return; 240 241 } 242 243 int nd = und + vnd; 244 245#ifdef SC_MAX_NBITS 246 sc_digit d[MAX_NDIGITS]; 247#else 248 sc_digit *d = new sc_digit[nd]; 249#endif 250 251 vec_zero(nd, d); 252 253 if ((und == 1) && (ud0 < HALF_DIGIT_RADIX)) 254 vec_mul_small(vnd, vd, ud0, d); 255 256 else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) 257 vec_mul_small(und, ud, vd0, d); 258 259 else if (vnd < und) 260 vec_mul(und, ud, vnd, vd, d); 261 262 else 263 vec_mul(vnd, vd, und, ud, d); 264 265 COPY_DIGITS(us, unb, old_und, ud, unb + vnb, nd, d); 266 267#ifndef SC_MAX_NBITS 268 delete [] d; 269#endif 270 271 } 272 273#undef COPY_DIGITS 274#undef CONVERT_SM_to_2C_to_SM 275 276} 277 278 279// ---------------------------------------------------------------------------- 280// SECTION: External functions for DIVISION operators. 281// ---------------------------------------------------------------------------- 282 283void 284div_on_help_signed(small_type &us, 285 int unb, int und, 286 sc_digit *ud, 287 int vnb, int vnd, 288 const sc_digit *vd) 289{ 290#define CONVERT_SM_to_2C_to_SM convert_signed_SM_to_2C_to_SM 291#define COPY_DIGITS copy_digits_signed 292 293 { // Body of div_on_help 294 295 int old_und = und; 296 297 und = vec_skip_leading_zeros(und, ud); 298 vnd = vec_skip_leading_zeros(vnd, vd); 299 300 int cmp_res = vec_cmp(und, ud, vnd, vd); 301 302 if (cmp_res < 0) { // u < v => u / v = 0 - case 4 303 us = SC_ZERO; 304 vec_zero(old_und, ud); 305 return; 306 } 307 308 sc_digit vd0 = (*vd); 309 310 if ((cmp_res > 0) && (vnd == 1) && (vd0 == 1)) { 311 us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud); 312 return; 313 } 314 315 // One extra digit for d is allocated to simplify vec_div_*(). 316 int nd = sc_max(und, vnd) + 1; 317 318#ifdef SC_MAX_NBITS 319 sc_digit d[MAX_NDIGITS + 1]; 320#else 321 sc_digit *d = new sc_digit[nd]; 322#endif 323 324 vec_zero(nd, d); 325 326 // u = v => u / v = 1 - case 3 327 if (cmp_res == 0) 328 d[0] = 1; 329 330 else if ((vnd == 1) && (und == 1)) 331 d[0] = (*ud) / vd0; 332 333 else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) 334 vec_div_small(und, ud, vd0, d); 335 336 else 337 vec_div_large(und, ud, vnd, vd, d); 338 339 COPY_DIGITS(us, unb, old_und, ud, sc_max(unb, vnb), nd - 1, d); 340 341#ifndef SC_MAX_NBITS 342 delete [] d; 343#endif 344 345 } 346 347#undef COPY_DIGITS 348#undef CONVERT_SM_to_2C_to_SM 349 350} 351 352 353void 354div_on_help_unsigned(small_type &us, 355 int unb, int und, 356 sc_digit *ud, 357 int vnb, int vnd, 358 const sc_digit *vd) 359{ 360#define CONVERT_SM_to_2C_to_SM convert_unsigned_SM_to_2C_to_SM 361#define COPY_DIGITS copy_digits_unsigned 362 363 { // Body of div_on_help 364 365 int old_und = und; 366 367 und = vec_skip_leading_zeros(und, ud); 368 vnd = vec_skip_leading_zeros(vnd, vd); 369 370 int cmp_res = vec_cmp(und, ud, vnd, vd); 371 372 if (cmp_res < 0) { // u < v => u / v = 0 - case 4 373 us = SC_ZERO; 374 vec_zero(old_und, ud); 375 return; 376 } 377 378 sc_digit vd0 = (*vd); 379 380 if ((cmp_res > 0) && (vnd == 1) && (vd0 == 1)) { 381 us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud); 382 return; 383 } 384 385 // One extra digit for d is allocated to simplify vec_div_*(). 386 int nd = sc_max(und, vnd) + 1; 387 388#ifdef SC_MAX_NBITS 389 sc_digit d[MAX_NDIGITS + 1]; 390#else 391 sc_digit *d = new sc_digit[nd]; 392#endif 393 394 vec_zero(nd, d); 395 396 // u = v => u / v = 1 - case 3 397 if (cmp_res == 0) 398 d[0] = 1; 399 400 else if ((vnd == 1) && (und == 1)) 401 d[0] = (*ud) / vd0; 402 403 else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) 404 vec_div_small(und, ud, vd0, d); 405 406 else 407 vec_div_large(und, ud, vnd, vd, d); 408 409 COPY_DIGITS(us, unb, old_und, ud, sc_max(unb, vnb), nd - 1, d); 410 411#ifndef SC_MAX_NBITS 412 delete [] d; 413#endif 414 415 } 416 417#undef COPY_DIGITS 418#undef CONVERT_SM_to_2C_to_SM 419 420} 421 422 423// ---------------------------------------------------------------------------- 424// SECTION: External functions for MOD operators. 425// ---------------------------------------------------------------------------- 426 427void 428mod_on_help_signed(small_type &us, 429 int unb, int und, 430 sc_digit *ud, 431 int /* vnb */, int vnd, 432 const sc_digit *vd) 433{ 434 435#define COPY_DIGITS copy_digits_signed 436 437 { // Body of mod_on_help 438 439 int old_und = und; 440 441 und = vec_skip_leading_zeros(und, ud); 442 vnd = vec_skip_leading_zeros(vnd, vd); 443 444 int cmp_res = vec_cmp(und, ud, vnd, vd); 445 446 // u < v => u % v = u - case 4 447 if (cmp_res < 0) 448 return; 449 450 // u = v => u % v = 0 - case 3 451 if (cmp_res == 0) { 452 us = SC_ZERO; 453 vec_zero(old_und, ud); 454 return; 455 } 456 457 // else if u > v - case 5 458 459 sc_digit vd0 = (*vd); 460 461 if ((vnd == 1) && (vd0 == 1)) { 462 us = SC_ZERO; 463 vec_zero(old_und, ud); 464 return; 465 } 466 467 // One extra digit for d is allocated to simplify vec_div_*(). 468 int nd = sc_max(und, vnd) + 1; 469 470#ifdef SC_MAX_NBITS 471 sc_digit d[MAX_NDIGITS + 1]; 472#else 473 sc_digit *d = new sc_digit[nd]; 474#endif 475 476 vec_zero(nd, d); 477 478 if ((vnd == 1) && (und == 1)) 479 d[0] = (*ud) % vd0; 480 481 if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) 482 d[0] = vec_rem_small(und, ud, vd0); 483 484 else 485 vec_rem_large(und, ud, vnd, vd, d); 486 487 us = check_for_zero(us, nd - 1, d); 488 489 if (us == SC_ZERO) 490 vec_zero(old_und, ud); 491 else 492 COPY_DIGITS(us, unb, old_und, ud, sc_min(unb, vnd), nd - 1, d); 493 494#ifndef SC_MAX_NBITS 495 delete [] d; 496#endif 497 498 } 499 500#undef COPY_DIGITS 501 502} 503 504 505void 506mod_on_help_unsigned(small_type &us, 507 int unb, int und, 508 sc_digit *ud, 509 int /* vnb */, int vnd, 510 const sc_digit *vd) 511{ 512 513#define COPY_DIGITS copy_digits_unsigned 514 515 { // Body of mod_on_help 516 517 int old_und = und; 518 519 und = vec_skip_leading_zeros(und, ud); 520 vnd = vec_skip_leading_zeros(vnd, vd); 521 522 int cmp_res = vec_cmp(und, ud, vnd, vd); 523 524 // u < v => u % v = u - case 4 525 if (cmp_res < 0) 526 return; 527 528 // u = v => u % v = 0 - case 3 529 if (cmp_res == 0) { 530 us = SC_ZERO; 531 vec_zero(old_und, ud); 532 return; 533 } 534 535 // else if u > v - case 5 536 537 sc_digit vd0 = (*vd); 538 539 if ((vnd == 1) && (vd0 == 1)) { 540 us = SC_ZERO; 541 vec_zero(old_und, ud); 542 return; 543 } 544 545 // One extra digit for d is allocated to simplify vec_div_*(). 546 int nd = sc_max(und, vnd) + 1; 547 548#ifdef SC_MAX_NBITS 549 sc_digit d[MAX_NDIGITS + 1]; 550#else 551 sc_digit *d = new sc_digit[nd]; 552#endif 553 554 vec_zero(nd, d); 555 556 if ((vnd == 1) && (und == 1)) 557 d[0] = (*ud) % vd0; 558 559 if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) 560 d[0] = vec_rem_small(und, ud, vd0); 561 562 else 563 vec_rem_large(und, ud, vnd, vd, d); 564 565 us = check_for_zero(us, nd - 1, d); 566 567 if (us == SC_ZERO) 568 vec_zero(old_und, ud); 569 else 570 COPY_DIGITS(us, unb, old_und, ud, sc_min(unb, vnd), nd - 1, d); 571 572#ifndef SC_MAX_NBITS 573 delete [] d; 574#endif 575 576 } 577 578#undef COPY_DIGITS 579 580} 581 582 583// ---------------------------------------------------------------------------- 584// SECTION: External functions for AND operators. 585// ---------------------------------------------------------------------------- 586 587// Handles the cases 2-5 and returns the result in u. 588void 589and_on_help(small_type us, 590 int /* unb */, int und, 591 sc_digit *ud, 592 small_type vs, 593 int /* vnb */, int vnd, 594 const sc_digit *vd) 595{ 596 597 sc_digit *x = ud; 598 const sc_digit *y = vd; 599 int xnd = und; 600 int ynd = vnd; 601 602 // Truncate y. 603 if (xnd < ynd) 604 ynd = xnd; 605 606 const sc_digit *xend = (x + xnd); 607 const sc_digit *yend = (y + ynd); 608 609 // x is longer than y. 610 611 small_type s = mul_signs(us, vs); 612 613 if (s > 0) { 614 615 if (us > 0) { // case 2 616 617 while (y < yend) 618 (*x++) &= (*y++); 619 620 while (x < xend) 621 (*x++) = 0; 622 623 } 624 else { // case 3 625 626 sc_digit xcarry = 1; 627 sc_digit ycarry = 1; 628 629 while (y < yend) { 630 xcarry += (~(*x) & DIGIT_MASK); 631 ycarry += (~(*y++) & DIGIT_MASK); 632 (*x++) = (xcarry & ycarry) & DIGIT_MASK; 633 xcarry >>= BITS_PER_DIGIT; 634 ycarry >>= BITS_PER_DIGIT; 635 } 636 637 while (x < xend) { 638 xcarry += (~(*x) & DIGIT_MASK); 639 ycarry += DIGIT_MASK; 640 (*x++) = (xcarry & ycarry) & DIGIT_MASK; 641 xcarry >>= BITS_PER_DIGIT; 642 ycarry >>= BITS_PER_DIGIT; 643 } 644 645 } 646 } 647 else { 648 649 if (us > 0) { // case 4 650 651 sc_digit ycarry = 1; 652 653 while (y < yend) { 654 ycarry += (~(*y++) & DIGIT_MASK); 655 (*x++) &= ycarry & DIGIT_MASK; 656 ycarry >>= BITS_PER_DIGIT; 657 } 658 659 while (x < xend) { 660 ycarry += DIGIT_MASK; 661 (*x++) &= ycarry & DIGIT_MASK; 662 ycarry >>= BITS_PER_DIGIT; 663 } 664 665 } 666 else { // case 5 667 668 sc_digit xcarry = 1; 669 670 while (y < yend) { 671 xcarry += (~(*x) & DIGIT_MASK); 672 (*x++) = (xcarry & (*y++)) & DIGIT_MASK; 673 xcarry >>= BITS_PER_DIGIT; 674 } 675 676 while (x < xend) 677 (*x++) = 0; 678 679 } 680 } 681} 682 683 684// ---------------------------------------------------------------------------- 685// SECTION: External functions for OR operators. 686// ---------------------------------------------------------------------------- 687 688// Handles the cases 3-5 and returns the result in u. 689void 690or_on_help(small_type us, 691 int /* unb */, int und, 692 sc_digit *ud, 693 small_type vs, 694 int /* vnb */, int vnd, 695 const sc_digit *vd) 696{ 697 698 sc_digit *x = ud; 699 const sc_digit *y = vd; 700 int xnd = und; 701 int ynd = vnd; 702 703 if (xnd < ynd) 704 ynd = xnd; 705 706 const sc_digit *xend = (x + xnd); 707 const sc_digit *yend = (y + ynd); 708 709 // x is longer than y. 710 711 small_type s = mul_signs(us, vs); 712 713 if (s > 0) { 714 715 if (us > 0) { // case 3 716 717 while (y < yend) 718 (*x++) |= (*y++); 719 720 // No change for the rest of x. 721 722 } 723 else { // case 4 724 725 sc_digit xcarry = 1; 726 sc_digit ycarry = 1; 727 728 while (y < yend) { 729 xcarry += (~(*x) & DIGIT_MASK); 730 ycarry += (~(*y++) & DIGIT_MASK); 731 (*x++) = (xcarry | ycarry) & DIGIT_MASK; 732 xcarry >>= BITS_PER_DIGIT; 733 ycarry >>= BITS_PER_DIGIT; 734 } 735 736 while (x < xend) { 737 xcarry += (~(*x) & DIGIT_MASK); 738 ycarry += DIGIT_MASK; 739 (*x++) = (xcarry | ycarry) & DIGIT_MASK; 740 xcarry >>= BITS_PER_DIGIT; 741 ycarry >>= BITS_PER_DIGIT; 742 } 743 } 744 745 } 746 else { 747 748 if (us > 0) { // case 5 749 750 sc_digit ycarry = 1; 751 752 while (y < yend) { 753 ycarry += (~(*y++) & DIGIT_MASK); 754 (*x) = ((*x) | ycarry) & DIGIT_MASK; 755 x++; 756 ycarry >>= BITS_PER_DIGIT; 757 } 758 759 while (x < xend) { 760 ycarry += DIGIT_MASK; 761 (*x) = ((*x) | ycarry) & DIGIT_MASK; 762 x++; 763 ycarry >>= BITS_PER_DIGIT; 764 } 765 766 } 767 else { // case 6 768 769 sc_digit xcarry = 1; 770 771 while (y < yend) { 772 xcarry += (~(*x) & DIGIT_MASK); 773 (*x++) = (xcarry | (*y++)) & DIGIT_MASK; 774 xcarry >>= BITS_PER_DIGIT; 775 } 776 777 while (x < xend) { 778 xcarry += (~(*x) & DIGIT_MASK); 779 (*x++) = xcarry & DIGIT_MASK; 780 xcarry >>= BITS_PER_DIGIT; 781 } 782 } 783 } 784} 785 786 787// ---------------------------------------------------------------------------- 788// SECTION: External functions for XOR operators. 789// ---------------------------------------------------------------------------- 790 791// Handles the cases 3-5 and returns the result in u. 792void 793xor_on_help(small_type us, 794 int /* unb */, int und, 795 sc_digit *ud, 796 small_type vs, 797 int /* vnb */, int vnd, 798 const sc_digit *vd) 799{ 800 801 sc_digit *x = ud; 802 const sc_digit *y = vd; 803 int xnd = und; 804 int ynd = vnd; 805 806 if (xnd < ynd) 807 ynd = xnd; 808 809 const sc_digit *xend = (x + xnd); 810 const sc_digit *yend = (y + ynd); 811 812 // x is longer than y. 813 814 small_type s = mul_signs(us, vs); 815 816 if (s > 0) { 817 818 if (us > 0) { // case 3 819 820 while (y < yend) { 821 (*x) = ((*x) ^ (*y)) & DIGIT_MASK; 822 x++; 823 y++; 824 } 825 826 // No change for the rest of x. 827 828 } 829 else { // case 4 830 831 sc_digit xcarry = 1; 832 sc_digit ycarry = 1; 833 834 while (y < yend) { 835 xcarry += (~(*x) & DIGIT_MASK); 836 ycarry += (~(*y++) & DIGIT_MASK); 837 (*x++) = (xcarry ^ ycarry) & DIGIT_MASK; 838 xcarry >>= BITS_PER_DIGIT; 839 ycarry >>= BITS_PER_DIGIT; 840 } 841 842 while (x < xend) { 843 xcarry += (~(*x) & DIGIT_MASK); 844 ycarry += DIGIT_MASK; 845 (*x++) = (xcarry ^ ycarry) & DIGIT_MASK; 846 xcarry >>= BITS_PER_DIGIT; 847 ycarry >>= BITS_PER_DIGIT; 848 } 849 } 850 } 851 else { 852 853 if (us > 0) { // case 5 854 855 sc_digit ycarry = 1; 856 857 while (y < yend) { 858 ycarry += (~(*y++) & DIGIT_MASK); 859 (*x) = ((*x) ^ ycarry) & DIGIT_MASK; 860 x++; 861 ycarry >>= BITS_PER_DIGIT; 862 } 863 864 while (x < xend) { 865 ycarry += DIGIT_MASK; 866 (*x) = ((*x) ^ ycarry) & DIGIT_MASK; 867 x++; 868 ycarry >>= BITS_PER_DIGIT; 869 } 870 871 } 872 else { // case 6 873 874 sc_digit xcarry = 1; 875 876 while (y < yend) { 877 xcarry += (~(*x) & DIGIT_MASK); 878 (*x++) = (xcarry ^ (*y++)) & DIGIT_MASK; 879 xcarry >>= BITS_PER_DIGIT; 880 } 881 882 while (x < xend) { 883 xcarry += (~(*x) & DIGIT_MASK); 884 (*x++) = xcarry & DIGIT_MASK; 885 xcarry >>= BITS_PER_DIGIT; 886 } 887 } 888 } 889} 890 891} // namespace sc_dt 892 893 894// End of file 895