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 "systemc/ext/dt/int/sc_nbexterns.hh" 55#include "systemc/ext/utils/functions.hh" 56 57namespace sc_dt 58{ 59 60// ---------------------------------------------------------------------------- 61// SECTION: External functions for PLUS operators. 62// ---------------------------------------------------------------------------- 63 64// Handles the cases 3 and 4 and returns the result in u. 65void 66add_on_help(small_type &us, int /* unb */, int und, sc_digit *ud, 67 small_type vs, int /* vnb */, int vnd, const sc_digit *vd) 68{ 69 vnd = vec_skip_leading_zeros(vnd, vd); 70 71 if (us == vs) { // case 3 72 if (und >= vnd) 73 vec_add_on(und, ud, vnd, vd); 74 else 75 vec_add_on2(und, ud, vnd, vd); 76 77 } else { // case 4 78 // vec_cmp expects that und is the number of non-zero digits in ud. 79 int new_und = vec_skip_leading_zeros(und, ud); 80 int cmp_res = vec_cmp(new_und, ud, vnd, vd); 81 82 if (cmp_res == 0) { // u == v 83 us = SC_ZERO; 84 vec_zero(und, ud); 85 return; 86 } 87 88 if (cmp_res > 0) { // u > v 89 vec_sub_on(und, ud, vnd, vd); 90 } else { // u < v 91 us = -us; 92 vec_sub_on2(und, ud, vnd, vd); 93 } 94 } 95} 96 97 98// ---------------------------------------------------------------------------- 99 100/* 101 102mul_on_help_signed and mul_on_help_unsigned have the same body except 103that CONVERT_SM_to_2C_to_SM and COPY_DIGITS are defined for signed and 104unsigned, respectively. This comment also applies to the 105signed/unsigned versions of div_on_help and mod_on_help. It is 106possible to take COPY_DIGITS out of these functions and create a 107single version of each of these helper functions; however, this will 108impose an onverhead on performance. In the versions below, any change 109in the signed version of a helper function must be carried to a 110corresponding change in the unsigned verion of the same function or 111vice versa. 112 113*/ 114 115 116// ---------------------------------------------------------------------------- 117// SECTION: External functions of MULTIPLICATION operators. 118// ---------------------------------------------------------------------------- 119 120void 121mul_on_help_signed(small_type &us, int unb, int und, sc_digit *ud, 122 int vnb, int vnd, const sc_digit *vd) 123{ 124#define CONVERT_SM_to_2C_to_SM convert_signed_SM_to_2C_to_SM 125#define COPY_DIGITS copy_digits_signed 126 { // Body of mul_on_help 127 int old_und = und; 128 129 und = vec_skip_leading_zeros(und, ud); 130 vnd = vec_skip_leading_zeros(vnd, vd); 131 132 sc_digit ud0 = (*ud); 133 sc_digit vd0 = (*vd); 134 135 if ((vnd == 1) && (vd0 == 1)) { 136 us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud); 137 return; 138 } 139 140 if ((und == 1) && (ud0 == 1)) { 141 COPY_DIGITS(us, unb, old_und, ud, vnb, vnd, vd); 142 return; 143 } 144 145 if ((und == 1) && (vnd == 1) && 146 (ud0 < HALF_DIGIT_RADIX) && (vd0 < HALF_DIGIT_RADIX)) { 147 148 sc_digit d = ud0 * vd0; 149 COPY_DIGITS(us, unb, old_und, ud, unb + vnb, 1, &d); 150 return; 151 } 152 153 int nd = und + vnd; 154 155#ifdef SC_MAX_NBITS 156 sc_digit d[MAX_NDIGITS]; 157#else 158 sc_digit *d = new sc_digit[nd]; 159#endif 160 161 vec_zero(nd, d); 162 163 if ((und == 1) && (ud0 < HALF_DIGIT_RADIX)) 164 vec_mul_small(vnd, vd, ud0, d); 165 else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) 166 vec_mul_small(und, ud, vd0, d); 167 else if (vnd < und) 168 vec_mul(und, ud, vnd, vd, d); 169 else 170 vec_mul(vnd, vd, und, ud, d); 171 172 COPY_DIGITS(us, unb, old_und, ud, unb + vnb, nd, d); 173 174#ifndef SC_MAX_NBITS 175 delete [] d; 176#endif 177 } 178#undef COPY_DIGITS 179#undef CONVERT_SM_to_2C_to_SM 180} 181 182 183void 184mul_on_help_unsigned(small_type &us, int unb, int und, sc_digit *ud, 185 int vnb, int vnd, const sc_digit *vd) 186{ 187#define CONVERT_SM_to_2C_to_SM convert_unsigned_SM_to_2C_to_SM 188#define COPY_DIGITS copy_digits_unsigned 189 { // Body of mul_on_help 190 int old_und = und; 191 192 und = vec_skip_leading_zeros(und, ud); 193 vnd = vec_skip_leading_zeros(vnd, vd); 194 195 sc_digit ud0 = (*ud); 196 sc_digit vd0 = (*vd); 197 198 if ((vnd == 1) && (vd0 == 1)) { 199 us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud); 200 return; 201 } 202 203 if ((und == 1) && (ud0 == 1)) { 204 COPY_DIGITS(us, unb, old_und, ud, vnb, vnd, vd); 205 return; 206 } 207 208 if ((und == 1) && (vnd == 1) && 209 (ud0 < HALF_DIGIT_RADIX) && (vd0 < HALF_DIGIT_RADIX)) { 210 211 sc_digit d = ud0 * vd0; 212 COPY_DIGITS(us, unb, old_und, ud, unb + vnb, 1, &d); 213 return; 214 } 215 216 int nd = und + vnd; 217 218#ifdef SC_MAX_NBITS 219 sc_digit d[MAX_NDIGITS]; 220#else 221 sc_digit *d = new sc_digit[nd]; 222#endif 223 224 vec_zero(nd, d); 225 226 if ((und == 1) && (ud0 < HALF_DIGIT_RADIX)) 227 vec_mul_small(vnd, vd, ud0, d); 228 else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) 229 vec_mul_small(und, ud, vd0, d); 230 else if (vnd < und) 231 vec_mul(und, ud, vnd, vd, d); 232 else 233 vec_mul(vnd, vd, und, ud, d); 234 235 COPY_DIGITS(us, unb, old_und, ud, unb + vnb, nd, d); 236 237#ifndef SC_MAX_NBITS 238 delete [] d; 239#endif 240 } 241#undef COPY_DIGITS 242#undef CONVERT_SM_to_2C_to_SM 243} 244 245 246// ---------------------------------------------------------------------------- 247// SECTION: External functions for DIVISION operators. 248// ---------------------------------------------------------------------------- 249 250void 251div_on_help_signed(small_type &us, int unb, int und, sc_digit *ud, 252 int vnb, int vnd, const sc_digit *vd) 253{ 254#define CONVERT_SM_to_2C_to_SM convert_signed_SM_to_2C_to_SM 255#define COPY_DIGITS copy_digits_signed 256 { // Body of div_on_help 257 int old_und = und; 258 259 und = vec_skip_leading_zeros(und, ud); 260 vnd = vec_skip_leading_zeros(vnd, vd); 261 262 int cmp_res = vec_cmp(und, ud, vnd, vd); 263 264 if (cmp_res < 0) { // u < v => u / v = 0 - case 4 265 us = SC_ZERO; 266 vec_zero(old_und, ud); 267 return; 268 } 269 270 sc_digit vd0 = (*vd); 271 272 if ((cmp_res > 0) && (vnd == 1) && (vd0 == 1)) { 273 us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud); 274 return; 275 } 276 277 // One extra digit for d is allocated to simplify vec_div_*(). 278 int nd = sc_max(und, vnd) + 1; 279 280#ifdef SC_MAX_NBITS 281 sc_digit d[MAX_NDIGITS + 1]; 282#else 283 sc_digit *d = new sc_digit[nd]; 284#endif 285 286 vec_zero(nd, d); 287 288 // u = v => u / v = 1 - case 3 289 if (cmp_res == 0) 290 d[0] = 1; 291 else if ((vnd == 1) && (und == 1)) 292 d[0] = (*ud) / vd0; 293 else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) 294 vec_div_small(und, ud, vd0, d); 295 else 296 vec_div_large(und, ud, vnd, vd, d); 297 298 COPY_DIGITS(us, unb, old_und, ud, sc_max(unb, vnb), nd - 1, d); 299 300#ifndef SC_MAX_NBITS 301 delete [] d; 302#endif 303 } 304#undef COPY_DIGITS 305#undef CONVERT_SM_to_2C_to_SM 306} 307 308 309void 310div_on_help_unsigned(small_type &us, int unb, int und, sc_digit *ud, 311 int vnb, int vnd, const sc_digit *vd) 312{ 313#define CONVERT_SM_to_2C_to_SM convert_unsigned_SM_to_2C_to_SM 314#define COPY_DIGITS copy_digits_unsigned 315 { // Body of div_on_help 316 int old_und = und; 317 318 und = vec_skip_leading_zeros(und, ud); 319 vnd = vec_skip_leading_zeros(vnd, vd); 320 321 int cmp_res = vec_cmp(und, ud, vnd, vd); 322 323 if (cmp_res < 0) { // u < v => u / v = 0 - case 4 324 us = SC_ZERO; 325 vec_zero(old_und, ud); 326 return; 327 } 328 329 sc_digit vd0 = (*vd); 330 331 if ((cmp_res > 0) && (vnd == 1) && (vd0 == 1)) { 332 us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud); 333 return; 334 } 335 336 // One extra digit for d is allocated to simplify vec_div_*(). 337 int nd = sc_max(und, vnd) + 1; 338 339#ifdef SC_MAX_NBITS 340 sc_digit d[MAX_NDIGITS + 1]; 341#else 342 sc_digit *d = new sc_digit[nd]; 343#endif 344 345 vec_zero(nd, d); 346 347 // u = v => u / v = 1 - case 3 348 if (cmp_res == 0) 349 d[0] = 1; 350 else if ((vnd == 1) && (und == 1)) 351 d[0] = (*ud) / vd0; 352 else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) 353 vec_div_small(und, ud, vd0, d); 354 else 355 vec_div_large(und, ud, vnd, vd, d); 356 357 COPY_DIGITS(us, unb, old_und, ud, sc_max(unb, vnb), nd - 1, d); 358 359#ifndef SC_MAX_NBITS 360 delete [] d; 361#endif 362 } 363#undef COPY_DIGITS 364#undef CONVERT_SM_to_2C_to_SM 365} 366 367 368// ---------------------------------------------------------------------------- 369// SECTION: External functions for MOD operators. 370// ---------------------------------------------------------------------------- 371 372void 373mod_on_help_signed(small_type &us, int unb, int und, sc_digit *ud, 374 int /* vnb */, int vnd, const sc_digit *vd) 375{ 376#define COPY_DIGITS copy_digits_signed 377 { // Body of mod_on_help 378 int old_und = und; 379 380 und = vec_skip_leading_zeros(und, ud); 381 vnd = vec_skip_leading_zeros(vnd, vd); 382 383 int cmp_res = vec_cmp(und, ud, vnd, vd); 384 385 // u < v => u % v = u - case 4 386 if (cmp_res < 0) 387 return; 388 389 // u = v => u % v = 0 - case 3 390 if (cmp_res == 0) { 391 us = SC_ZERO; 392 vec_zero(old_und, ud); 393 return; 394 } 395 // else if u > v - case 5 396 397 sc_digit vd0 = (*vd); 398 399 if ((vnd == 1) && (vd0 == 1)) { 400 us = SC_ZERO; 401 vec_zero(old_und, ud); 402 return; 403 } 404 405 // One extra digit for d is allocated to simplify vec_div_*(). 406 int nd = sc_max(und, vnd) + 1; 407 408#ifdef SC_MAX_NBITS 409 sc_digit d[MAX_NDIGITS + 1]; 410#else 411 sc_digit *d = new sc_digit[nd]; 412#endif 413 414 vec_zero(nd, d); 415 416 if ((vnd == 1) && (und == 1)) 417 d[0] = (*ud) % vd0; 418 if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) 419 d[0] = vec_rem_small(und, ud, vd0); 420 else 421 vec_rem_large(und, ud, vnd, vd, d); 422 423 us = check_for_zero(us, nd - 1, d); 424 425 if (us == SC_ZERO) 426 vec_zero(old_und, ud); 427 else 428 COPY_DIGITS(us, unb, old_und, ud, sc_min(unb, vnd), nd - 1, d); 429 430#ifndef SC_MAX_NBITS 431 delete [] d; 432#endif 433 } 434#undef COPY_DIGITS 435} 436 437 438void 439mod_on_help_unsigned(small_type &us, int unb, int und, sc_digit *ud, 440 int /* vnb */, int vnd, const sc_digit *vd) 441{ 442#define COPY_DIGITS copy_digits_unsigned 443 { // Body of mod_on_help 444 int old_und = und; 445 446 und = vec_skip_leading_zeros(und, ud); 447 vnd = vec_skip_leading_zeros(vnd, vd); 448 449 int cmp_res = vec_cmp(und, ud, vnd, vd); 450 451 // u < v => u % v = u - case 4 452 if (cmp_res < 0) 453 return; 454 455 // u = v => u % v = 0 - case 3 456 if (cmp_res == 0) { 457 us = SC_ZERO; 458 vec_zero(old_und, ud); 459 return; 460 } 461 462 // else if u > v - case 5 463 464 sc_digit vd0 = (*vd); 465 466 if ((vnd == 1) && (vd0 == 1)) { 467 us = SC_ZERO; 468 vec_zero(old_und, ud); 469 return; 470 } 471 472 // One extra digit for d is allocated to simplify vec_div_*(). 473 int nd = sc_max(und, vnd) + 1; 474 475#ifdef SC_MAX_NBITS 476 sc_digit d[MAX_NDIGITS + 1]; 477#else 478 sc_digit *d = new sc_digit[nd]; 479#endif 480 481 vec_zero(nd, d); 482 483 if ((vnd == 1) && (und == 1)) 484 d[0] = (*ud) % vd0; 485 if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) 486 d[0] = vec_rem_small(und, ud, vd0); 487 else 488 vec_rem_large(und, ud, vnd, vd, d); 489 490 us = check_for_zero(us, nd - 1, d); 491 492 if (us == SC_ZERO) 493 vec_zero(old_und, ud); 494 else 495 COPY_DIGITS(us, unb, old_und, ud, sc_min(unb, vnd), nd - 1, d); 496 497#ifndef SC_MAX_NBITS 498 delete [] d; 499#endif 500 } 501#undef COPY_DIGITS 502} 503 504 505// ---------------------------------------------------------------------------- 506// SECTION: External functions for AND operators. 507// ---------------------------------------------------------------------------- 508 509// Handles the cases 2-5 and returns the result in u. 510void 511and_on_help(small_type us, int /* unb */, int und, sc_digit *ud, 512 small_type vs, int /* vnb */, int vnd, const sc_digit *vd) 513{ 514 sc_digit *x = ud; 515 const sc_digit *y = vd; 516 int xnd = und; 517 int ynd = vnd; 518 519 // Truncate y. 520 if (xnd < ynd) 521 ynd = xnd; 522 523 const sc_digit *xend = (x + xnd); 524 const sc_digit *yend = (y + ynd); 525 526 // x is longer than y. 527 small_type s = mul_signs(us, vs); 528 529 if (s > 0) { 530 if (us > 0) { // case 2 531 while (y < yend) 532 (*x++) &= (*y++); 533 while (x < xend) 534 (*x++) = 0; 535 } else { // case 3 536 sc_digit xcarry = 1; 537 sc_digit ycarry = 1; 538 while (y < yend) { 539 xcarry += (~(*x) & DIGIT_MASK); 540 ycarry += (~(*y++) & DIGIT_MASK); 541 (*x++) = (xcarry & ycarry) & DIGIT_MASK; 542 xcarry >>= BITS_PER_DIGIT; 543 ycarry >>= BITS_PER_DIGIT; 544 } 545 while (x < xend) { 546 xcarry += (~(*x) & DIGIT_MASK); 547 ycarry += DIGIT_MASK; 548 (*x++) = (xcarry & ycarry) & DIGIT_MASK; 549 xcarry >>= BITS_PER_DIGIT; 550 ycarry >>= BITS_PER_DIGIT; 551 } 552 553 } 554 } else { 555 if (us > 0) { // case 4 556 sc_digit ycarry = 1; 557 while (y < yend) { 558 ycarry += (~(*y++) & DIGIT_MASK); 559 (*x++) &= ycarry & DIGIT_MASK; 560 ycarry >>= BITS_PER_DIGIT; 561 } 562 while (x < xend) { 563 ycarry += DIGIT_MASK; 564 (*x++) &= ycarry & DIGIT_MASK; 565 ycarry >>= BITS_PER_DIGIT; 566 } 567 } else { // case 5 568 sc_digit xcarry = 1; 569 while (y < yend) { 570 xcarry += (~(*x) & DIGIT_MASK); 571 (*x++) = (xcarry & (*y++)) & DIGIT_MASK; 572 xcarry >>= BITS_PER_DIGIT; 573 } 574 while (x < xend) 575 (*x++) = 0; 576 } 577 } 578} 579 580 581// ---------------------------------------------------------------------------- 582// SECTION: External functions for OR operators. 583// ---------------------------------------------------------------------------- 584 585// Handles the cases 3-5 and returns the result in u. 586void 587or_on_help(small_type us, int /* unb */, int und, sc_digit *ud, 588 small_type vs, int /* vnb */, int vnd, const sc_digit *vd) 589{ 590 sc_digit *x = ud; 591 const sc_digit *y = vd; 592 int xnd = und; 593 int ynd = vnd; 594 595 if (xnd < ynd) 596 ynd = xnd; 597 598 const sc_digit *xend = (x + xnd); 599 const sc_digit *yend = (y + ynd); 600 601 // x is longer than y. 602 small_type s = mul_signs(us, vs); 603 604 if (s > 0) { 605 if (us > 0) { // case 3 606 while (y < yend) 607 (*x++) |= (*y++); 608 // No change for the rest of x. 609 } else { // case 4 610 sc_digit xcarry = 1; 611 sc_digit ycarry = 1; 612 while (y < yend) { 613 xcarry += (~(*x) & DIGIT_MASK); 614 ycarry += (~(*y++) & DIGIT_MASK); 615 (*x++) = (xcarry | ycarry) & DIGIT_MASK; 616 xcarry >>= BITS_PER_DIGIT; 617 ycarry >>= BITS_PER_DIGIT; 618 } 619 while (x < xend) { 620 xcarry += (~(*x) & DIGIT_MASK); 621 ycarry += DIGIT_MASK; 622 (*x++) = (xcarry | ycarry) & DIGIT_MASK; 623 xcarry >>= BITS_PER_DIGIT; 624 ycarry >>= BITS_PER_DIGIT; 625 } 626 } 627 } else { 628 if (us > 0) { // case 5 629 sc_digit ycarry = 1; 630 while (y < yend) { 631 ycarry += (~(*y++) & DIGIT_MASK); 632 (*x) = ((*x) | ycarry) & DIGIT_MASK; 633 x++; 634 ycarry >>= BITS_PER_DIGIT; 635 } 636 while (x < xend) { 637 ycarry += DIGIT_MASK; 638 (*x) = ((*x) | ycarry) & DIGIT_MASK; 639 x++; 640 ycarry >>= BITS_PER_DIGIT; 641 } 642 } else { // case 6 643 sc_digit xcarry = 1; 644 while (y < yend) { 645 xcarry += (~(*x) & DIGIT_MASK); 646 (*x++) = (xcarry | (*y++)) & DIGIT_MASK; 647 xcarry >>= BITS_PER_DIGIT; 648 } 649 while (x < xend) { 650 xcarry += (~(*x) & DIGIT_MASK); 651 (*x++) = xcarry & DIGIT_MASK; 652 xcarry >>= BITS_PER_DIGIT; 653 } 654 } 655 } 656} 657 658 659// ---------------------------------------------------------------------------- 660// SECTION: External functions for XOR operators. 661// ---------------------------------------------------------------------------- 662 663// Handles the cases 3-5 and returns the result in u. 664void 665xor_on_help(small_type us, int /* unb */, int und, sc_digit *ud, 666 small_type vs, int /* vnb */, int vnd, const sc_digit *vd) 667{ 668 sc_digit *x = ud; 669 const sc_digit *y = vd; 670 int xnd = und; 671 int ynd = vnd; 672 673 if (xnd < ynd) 674 ynd = xnd; 675 676 const sc_digit *xend = (x + xnd); 677 const sc_digit *yend = (y + ynd); 678 679 // x is longer than y. 680 small_type s = mul_signs(us, vs); 681 682 if (s > 0) { 683 if (us > 0) { // case 3 684 while (y < yend) { 685 (*x) = ((*x) ^ (*y)) & DIGIT_MASK; 686 x++; 687 y++; 688 } 689 // No change for the rest of x. 690 } else { // case 4 691 sc_digit xcarry = 1; 692 sc_digit ycarry = 1; 693 while (y < yend) { 694 xcarry += (~(*x) & DIGIT_MASK); 695 ycarry += (~(*y++) & DIGIT_MASK); 696 (*x++) = (xcarry ^ ycarry) & DIGIT_MASK; 697 xcarry >>= BITS_PER_DIGIT; 698 ycarry >>= BITS_PER_DIGIT; 699 } 700 while (x < xend) { 701 xcarry += (~(*x) & DIGIT_MASK); 702 ycarry += DIGIT_MASK; 703 (*x++) = (xcarry ^ ycarry) & DIGIT_MASK; 704 xcarry >>= BITS_PER_DIGIT; 705 ycarry >>= BITS_PER_DIGIT; 706 } 707 } 708 } else { 709 if (us > 0) { // case 5 710 sc_digit ycarry = 1; 711 while (y < yend) { 712 ycarry += (~(*y++) & DIGIT_MASK); 713 (*x) = ((*x) ^ ycarry) & DIGIT_MASK; 714 x++; 715 ycarry >>= BITS_PER_DIGIT; 716 } 717 while (x < xend) { 718 ycarry += DIGIT_MASK; 719 (*x) = ((*x) ^ ycarry) & DIGIT_MASK; 720 x++; 721 ycarry >>= BITS_PER_DIGIT; 722 } 723 } else { // case 6 724 sc_digit xcarry = 1; 725 while (y < yend) { 726 xcarry += (~(*x) & DIGIT_MASK); 727 (*x++) = (xcarry ^ (*y++)) & DIGIT_MASK; 728 xcarry >>= BITS_PER_DIGIT; 729 } 730 while (x < xend) { 731 xcarry += (~(*x) & DIGIT_MASK); 732 (*x++) = xcarry & DIGIT_MASK; 733 xcarry >>= BITS_PER_DIGIT; 734 } 735 } 736 } 737} 738 739} // namespace sc_dt 740