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_nbfriends.inc -- Friend functions for both sc_signed and sc_unsigned 23 classes. The vec_* functions are called through either 24 these functions or those in sc_nbexterns.cpp. These 25 functions perform their work on two inputs u and v, and 26 return the result object. The functions in 27 sc_nbexterns.cpp perform their work on one of their 28 inputs. 29 30 The functions here try to use faster algorithms in case 31 the input numbers are small. The bitwise functions (and, 32 or, and xor) need the 2's complement representations of 33 their inputs. Instead of complementing their inputs 34 first and then processing, they complement their inputs 35 while processing without allocating extra temporary 36 memory. 37 38 Original Author: Ali Dasdan, Synopsys, Inc. 39 40 *****************************************************************************/ 41 42/***************************************************************************** 43 44 MODIFICATION LOG - modifiers, enter your name, affiliation, date and 45 changes you are making here. 46 47 Name, Affiliation, Date: 48 Description of Modification: 49 50 *****************************************************************************/ 51 52 53// ---------------------------------------------------------------------------- 54// Naming conventions: 55// For sc_signed or sc_unsigned number u: 56// us : u's sign, unb : u's number of bits, 57// und : u's number of digits, ud : u's digits array. 58// ---------------------------------------------------------------------------- 59 60// ---------------------------------------------------------------------------- 61// SECTION: Friend functions for PLUS operators. 62// ---------------------------------------------------------------------------- 63 64// Handles cases 3 and 4 and returns the result. 65CLASS_TYPE 66ADD_HELPER(small_type us, int unb, int und, const sc_digit *ud, 67 small_type vs, int vnb, int vnd, const sc_digit *vd) 68{ 69 und = vec_skip_leading_zeros(und, ud); 70 vnd = vec_skip_leading_zeros(vnd, vd); 71 72 int nb = sc_max(unb, vnb); 73 int nd = sc_max(und, vnd) + 1; 74 75#ifdef SC_MAX_NBITS 76 test_bound(nb); 77 sc_digit d[MAX_NDIGITS]; 78#else 79 sc_digit *d = new sc_digit[nd]; 80#endif 81 82 d[nd - 1] = d[nd - 2] = 0; 83 84 // case 3 85 if (us == vs) { 86 87 ++nb; 88 89 if ((und == 1) && (vnd == 1)) { 90 sc_digit carry = (*ud) + (*vd); 91 d[0] = carry & DIGIT_MASK; 92 d[1] = carry >> BITS_PER_DIGIT; 93 } else if (und >= vnd) { 94 vec_add(und, ud, vnd, vd, d); 95 } else { 96 vec_add(vnd, vd, und, ud, d); 97 } 98 } else { 99 // case 4 100 int cmp_res = vec_cmp(und, ud, vnd, vd); 101 102 if (cmp_res == 0) { // u == v 103#ifndef SC_MAX_NBITS 104 delete[] d; 105#endif 106 return CLASS_TYPE(); 107 } 108 109 if (cmp_res > 0) { // u > v 110 if ((und == 1) && (vnd == 1)) 111 d[0] = (*ud) - (*vd); 112 else 113 vec_sub(und, ud, vnd, vd, d); 114 } else { // u < v 115 us = -us; 116 if ((und == 1) && (vnd == 1)) 117 d[0] = (*vd) - (*ud); 118 else 119 vec_sub(vnd, vd, und, ud, d); 120 } 121 } 122 return CLASS_TYPE(us, nb, nd, d); 123} 124 125 126// ---------------------------------------------------------------------------- 127// SECTION: Friend functions of MULTIPLICATION operators. 128// ---------------------------------------------------------------------------- 129 130// Handles the case 4 and returns the result. 131CLASS_TYPE 132MUL_HELPER(small_type s, int unb, int und, const sc_digit *ud, 133 int vnb, int vnd, const sc_digit *vd) 134{ 135 und = vec_skip_leading_zeros(und, ud); 136 vnd = vec_skip_leading_zeros(vnd, vd); 137 138 int nb = unb + vnb; 139 int nd = und + vnd; 140 141#ifdef SC_MAX_NBITS 142 test_bound(nb); 143 sc_digit d[MAX_NDIGITS]; 144#else 145 sc_digit *d = new sc_digit[nd]; 146#endif 147 148 vec_zero(nd, d); 149 150 sc_digit ud0 = (*ud); 151 sc_digit vd0 = (*vd); 152 153 if ((vnd == 1) && (vd0 == 1)) { 154 vec_copy(und, d, ud); 155 } else if ((und == 1) && (ud0 == 1)) { 156 vec_copy(vnd, d, vd); 157 } else if ((und == 1) && (vnd == 1) && 158 (ud0 < HALF_DIGIT_RADIX) && (vd0 < HALF_DIGIT_RADIX)) { 159 d[0] = ud0 * vd0; 160 } else if ((und == 1) && (ud0 < HALF_DIGIT_RADIX)) { 161 vec_mul_small(vnd, vd, ud0, d); 162 } else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) { 163 vec_mul_small(und, ud, vd0, d); 164 } else if (vnd < und) { 165 vec_mul(und, ud, vnd, vd, d); 166 } else { 167 vec_mul(vnd, vd, und, ud, d); 168 } 169 return CLASS_TYPE(s, nb, nd, d); 170} 171 172 173// ---------------------------------------------------------------------------- 174// SECTION: Friend functions for DIVISION operators. 175// ---------------------------------------------------------------------------- 176 177// Handles the cases 3-4 and returns the result. 178CLASS_TYPE 179DIV_HELPER(small_type s, int unb, int und, const sc_digit *ud, 180 int vnb, int vnd, const sc_digit *vd) 181{ 182 und = vec_skip_leading_zeros(und, ud); 183 vnd = vec_skip_leading_zeros(vnd, vd); 184 185 int cmp_res = vec_cmp(und, ud, vnd, vd); 186 187 // u < v => u / v = 0 - case 4 188 if (cmp_res < 0) 189 return CLASS_TYPE(); 190 191 // One extra digit for d is allocated to simplify vec_div_*(). 192 int nd = sc_max(und, vnd) + 1; 193 194#ifdef SC_MAX_NBITS 195 sc_digit d[MAX_NDIGITS + 1]; 196#else 197 sc_digit *d = new sc_digit[nd]; 198#endif 199 200 vec_zero(nd, d); 201 sc_digit vd0 = (*vd); 202 203 // u = v => u / v = 1 - case 3 204 if (cmp_res == 0) { 205 d[0] = 1; 206 // else if u > v - case 5 207 } else if ((vnd == 1) && (vd0 == 1)) { 208 vec_copy(und, d, ud); 209 } else if ((vnd == 1) && (und == 1)) { 210 d[0] = (*ud) / vd0; 211 } else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) { 212 vec_div_small(und, ud, vd0, d); 213 } else { 214 vec_div_large(und, ud, vnd, vd, d); 215 } 216 217 return CLASS_TYPE(s, sc_max(unb, vnb), nd - 1, d); 218} 219 220 221// ---------------------------------------------------------------------------- 222// SECTION: Friend functions for MOD operators. 223// ---------------------------------------------------------------------------- 224 225// Handles the cases 3-4 and returns the result. 226CLASS_TYPE 227MOD_HELPER(small_type us, int unb, int und, const sc_digit *ud, 228 int vnb, int vnd, const sc_digit *vd) 229{ 230 und = vec_skip_leading_zeros(und, ud); 231 vnd = vec_skip_leading_zeros(vnd, vd); 232 233 int cmp_res = vec_cmp(und, ud, vnd, vd); 234 // u = v => u % v = 0 - case 3 235 if (cmp_res == 0) 236 return CLASS_TYPE(); 237 238 sc_digit vd0 = (*vd); 239 if ((cmp_res > 0) && (vnd == 1) && (vd0 == 1)) 240 return CLASS_TYPE(); 241 242 // One extra digit for d is allocated to simplify vec_div_*(). 243 int nd = sc_max(und, vnd) + 1; 244 245#ifdef SC_MAX_NBITS 246 sc_digit d[MAX_NDIGITS + 1]; 247#else 248 sc_digit *d = new sc_digit[nd]; 249#endif 250 251 vec_zero(nd, d); 252 253 // u < v => u % v = u - case 4 254 if (cmp_res < 0) { 255 vec_copy(und, d, ud); 256 // else if u > v - case 5 257 } else if ((vnd == 1) && (und == 1)) { 258 d[0] = (*ud) % vd0; 259 } else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) { 260 d[0] = vec_rem_small(und, ud, vd0); 261 } else { 262 vec_rem_large(und, ud, vnd, vd, d); 263 } 264 265 us = check_for_zero(us, nd - 1, d); 266 267 if (us == SC_ZERO) { 268#ifndef SC_MAX_NBITS 269 delete[] d; 270#endif 271 return CLASS_TYPE(); 272 } else { 273 return CLASS_TYPE(us, sc_min(unb, vnb), nd - 1, d); 274 } 275} 276 277 278// ---------------------------------------------------------------------------- 279// SECTION: Friend functions for AND operators. 280// ---------------------------------------------------------------------------- 281 282// Handles the cases 2-5 and returns the result. 283CLASS_TYPE 284AND_HELPER(small_type us, int unb, int und, const sc_digit *ud, 285 small_type vs, int vnb, int vnd, const sc_digit *vd) 286{ 287 int nb = sc_max(unb, vnb); 288 int nd = sc_max(und, vnd); 289 290#ifdef SC_MAX_NBITS 291 sc_digit dbegin[MAX_NDIGITS]; 292#else 293 sc_digit *dbegin = new sc_digit[nd]; 294#endif 295 296 sc_digit *d = dbegin; 297 298 const sc_digit *x; 299 const sc_digit *y; 300 int xnd; 301 int ynd; 302 small_type xs; 303 small_type ys; 304 305 if (und >= vnd) { 306 x = ud; 307 y = vd; 308 xnd = und; 309 ynd = vnd; 310 xs = us; 311 ys = vs; 312 } else { 313 y = ud; 314 x = vd; 315 ynd = und; 316 xnd = vnd; 317 ys = us; 318 xs = vs; 319 } 320 321 const sc_digit *xend = (x + xnd); 322 const sc_digit *yend = (y + ynd); 323 324 // x is longer than y. 325 small_type s = mul_signs(xs, ys); 326 if (s > 0) { 327 if (xs > 0) { // case 2 328 while (y < yend) 329 (*d++) = (*x++) & (*y++); 330 while (x++ < xend) 331 (*d++) = 0; 332 } else { // case 3 333 sc_digit xcarry = 1; 334 sc_digit ycarry = 1; 335 while (y < yend) { 336 xcarry += (~(*x++) & DIGIT_MASK); 337 ycarry += (~(*y++) & DIGIT_MASK); 338 (*d++) = (xcarry & ycarry) & DIGIT_MASK; 339 xcarry >>= BITS_PER_DIGIT; 340 ycarry >>= BITS_PER_DIGIT; 341 } 342 while (x < xend) { 343 xcarry += (~(*x++) & DIGIT_MASK); 344 ycarry += DIGIT_MASK; 345 (*d++) = (xcarry & ycarry) & DIGIT_MASK; 346 xcarry >>= BITS_PER_DIGIT; 347 ycarry >>= BITS_PER_DIGIT; 348 } 349 } 350 } else { 351 if (xs > 0) { // case 4 352 sc_digit ycarry = 1; 353 while (y < yend) { 354 ycarry += (~(*y++) & DIGIT_MASK); 355 (*d++) = ((*x++) & ycarry) & DIGIT_MASK; 356 ycarry >>= BITS_PER_DIGIT; 357 } 358 while (x < xend) { 359 ycarry += DIGIT_MASK; 360 (*d++) = ((*x++) & ycarry) & DIGIT_MASK; 361 ycarry >>= BITS_PER_DIGIT; 362 } 363 } else { // case 5 364 sc_digit xcarry = 1; 365 while (y < yend) { 366 xcarry += (~(*x++) & DIGIT_MASK); 367 (*d++) = (xcarry & (*y++)) & DIGIT_MASK; 368 xcarry >>= BITS_PER_DIGIT; 369 } 370 while (x++ < xend) 371 (*d++) = 0; 372 } 373 } 374 s = convert_signed_2C_to_SM(nb, nd, dbegin); 375 return CLASS_TYPE(s, nb, nd, dbegin); 376} 377 378 379// ---------------------------------------------------------------------------- 380// SECTION: Friend functions for OR operators. 381// ---------------------------------------------------------------------------- 382 383// Handles the cases 3-5 and returns the result. 384CLASS_TYPE 385OR_HELPER(small_type us, int unb, int und, const sc_digit *ud, 386 small_type vs, int vnb, int vnd, const sc_digit *vd) 387{ 388 int nb = sc_max(unb, vnb); 389 int nd = sc_max(und, vnd); 390 391#ifdef SC_MAX_NBITS 392 sc_digit dbegin[MAX_NDIGITS]; 393#else 394 sc_digit *dbegin = new sc_digit[nd]; 395#endif 396 sc_digit *d = dbegin; 397 const sc_digit *x; 398 const sc_digit *y; 399 int xnd; 400 int ynd; 401 small_type xs; 402 small_type ys; 403 404 if (und >= vnd) { 405 x = ud; 406 y = vd; 407 xnd = und; 408 ynd = vnd; 409 xs = us; 410 ys = vs; 411 } else { 412 y = ud; 413 x = vd; 414 ynd = und; 415 xnd = vnd; 416 ys = us; 417 xs = vs; 418 } 419 420 const sc_digit *xend = (x + xnd); 421 const sc_digit *yend = (y + ynd); 422 423 // x is longer than y. 424 small_type s = mul_signs(xs, ys); 425 if (s > 0) { 426 if (xs > 0) { // case 3 427 while (y < yend) 428 (*d++) = (*x++) | (*y++); 429 while (x < xend) 430 (*d++) = (*x++); 431 } else { // case 4 432 sc_digit xcarry = 1; 433 sc_digit ycarry = 1; 434 while (y < yend) { 435 xcarry += (~(*x++) & DIGIT_MASK); 436 ycarry += (~(*y++) & DIGIT_MASK); 437 (*d++) = (xcarry | ycarry) & DIGIT_MASK; 438 xcarry >>= BITS_PER_DIGIT; 439 ycarry >>= BITS_PER_DIGIT; 440 } 441 while (x < xend) { 442 xcarry += (~(*x++) & DIGIT_MASK); 443 ycarry += DIGIT_MASK; 444 (*d++) = (xcarry | ycarry) & DIGIT_MASK; 445 xcarry >>= BITS_PER_DIGIT; 446 ycarry >>= BITS_PER_DIGIT; 447 } 448 } 449 } else { 450 if (xs > 0) { // case 5 451 sc_digit ycarry = 1; 452 while (y < yend) { 453 ycarry += (~(*y++) & DIGIT_MASK); 454 (*d++) = ((*x++) | ycarry) & DIGIT_MASK; 455 ycarry >>= BITS_PER_DIGIT; 456 } 457 while (x < xend) { 458 ycarry += DIGIT_MASK; 459 (*d++) = ((*x++) | ycarry) & DIGIT_MASK; 460 ycarry >>= BITS_PER_DIGIT; 461 } 462 } else { // case 6 463 sc_digit xcarry = 1; 464 while (y < yend) { 465 xcarry += (~(*x++) & DIGIT_MASK); 466 (*d++) = (xcarry | (*y++)) & DIGIT_MASK; 467 xcarry >>= BITS_PER_DIGIT; 468 } 469 while (x < xend) { 470 xcarry += (~(*x++) & DIGIT_MASK); 471 (*d++) = xcarry & DIGIT_MASK; 472 xcarry >>= BITS_PER_DIGIT; 473 } 474 } 475 } 476 s = convert_signed_2C_to_SM(nb, nd, dbegin); 477 return CLASS_TYPE(s, nb, nd, dbegin); 478} 479 480 481// ---------------------------------------------------------------------------- 482// SECTION: Friend functions for XOR operators. 483// ---------------------------------------------------------------------------- 484 485// Handles the cases 3-5 and returns the result. 486CLASS_TYPE 487XOR_HELPER(small_type us, int unb, int und, const sc_digit *ud, 488 small_type vs, int vnb, int vnd, const sc_digit *vd) 489{ 490 int nb = sc_max(unb, vnb); 491 int nd = sc_max(und, vnd); 492 493#ifdef SC_MAX_NBITS 494 sc_digit dbegin[MAX_NDIGITS]; 495#else 496 sc_digit *dbegin = new sc_digit[nd]; 497#endif 498 499 sc_digit *d = dbegin; 500 501 const sc_digit *x; 502 const sc_digit *y; 503 int xnd; 504 int ynd; 505 small_type xs; 506 small_type ys; 507 508 if (und >= vnd) { 509 x = ud; 510 y = vd; 511 xnd = und; 512 ynd = vnd; 513 xs = us; 514 ys = vs; 515 } else { 516 y = ud; 517 x = vd; 518 ynd = und; 519 xnd = vnd; 520 ys = us; 521 xs = vs; 522 } 523 524 const sc_digit *xend = (x + xnd); 525 const sc_digit *yend = (y + ynd); 526 527 // x is longer than y. 528 small_type s = mul_signs(xs, ys); 529 if (s > 0) { 530 if (xs > 0) { // case 3 531 while (y < yend) 532 (*d++) = ((*x++) ^ (*y++)) & DIGIT_MASK; 533 while (x < xend) 534 (*d++) = (*x++); 535 } else { // case 4 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 (*d++) = (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 (*d++) = (xcarry ^ ycarry) & DIGIT_MASK; 549 xcarry >>= BITS_PER_DIGIT; 550 ycarry >>= BITS_PER_DIGIT; 551 } 552 } 553 } else { 554 if (xs > 0) { // case 5 555 sc_digit ycarry = 1; 556 while (y < yend) { 557 ycarry += (~(*y++) & DIGIT_MASK); 558 (*d++) = ((*x++) ^ ycarry) & DIGIT_MASK; 559 ycarry >>= BITS_PER_DIGIT; 560 } 561 while (x < xend) { 562 ycarry += DIGIT_MASK; 563 (*d++) = ((*x++) ^ ycarry) & DIGIT_MASK; 564 ycarry >>= BITS_PER_DIGIT; 565 } 566 } else { // case 6 567 sc_digit xcarry = 1; 568 while (y < yend) { 569 xcarry += (~(*x++) & DIGIT_MASK); 570 (*d++) = (xcarry ^ (*y++)) & DIGIT_MASK; 571 xcarry >>= BITS_PER_DIGIT; 572 } 573 while (x < xend) { 574 xcarry += (~(*x++) & DIGIT_MASK); 575 (*d++) = xcarry & DIGIT_MASK; 576 xcarry >>= BITS_PER_DIGIT; 577 } 578 } 579 } 580 s = convert_signed_2C_to_SM(nb, nd, dbegin); 581 return CLASS_TYPE(s, nb, nd, dbegin); 582} 583