sc_nbfriends.inc

Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003   The following code is derived, directly or indirectly, from the SystemC
00004   source code Copyright (c) 1996-2005 by all Contributors.
00005   All Rights reserved.
00006 
00007   The contents of this file are subject to the restrictions and limitations
00008   set forth in the SystemC Open Source License Version 2.3 (the "License");
00009   You may not use this file except in compliance with such restrictions and
00010   limitations. You may obtain instructions on how to receive a copy of the
00011   License at http://www.systemc.org/. Software distributed by Contributors
00012   under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
00013   ANY KIND, either express or implied. See the License for the specific
00014   language governing rights and limitations under the License.
00015 
00016  *****************************************************************************/
00017 
00018 /*****************************************************************************
00019 
00020   sc_nbfriends.cpp -- Friend functions for both sc_signed and sc_unsigned
00021                       classes. The vec_* functions are called through either
00022                       these functions or those in sc_nbexterns.cpp. These
00023                       functions perform their work on two inputs u and v, and
00024                       return the result object. The functions in
00025                       sc_nbexterns.cpp perform their work on one of their
00026                       inputs.
00027 
00028                       The functions here try to use faster algorithms in case
00029                       the input numbers are small. The bitwise functions (and,
00030                       or, and xor) need the 2's complement representations of
00031                       their inputs. Instead of complementing their inputs
00032                       first and then processing, they complement their inputs
00033                       while processing without allocating extra temporary
00034                       memory.
00035 
00036   Original Author: Ali Dasdan, Synopsys, Inc.
00037 
00038  *****************************************************************************/
00039 
00040 /*****************************************************************************
00041 
00042   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
00043   changes you are making here.
00044 
00045       Name, Affiliation, Date:
00046   Description of Modification:
00047 
00048  *****************************************************************************/
00049 
00050 
00051 // ----------------------------------------------------------------------------
00052 //  Naming conventions:
00053 //  For sc_signed or sc_unsigned number u:
00054 //    us : u's sign, unb : u's number of bits, 
00055 //    und : u's number of digits, ud : u's digits array.
00056 // ----------------------------------------------------------------------------
00057 
00058 // ----------------------------------------------------------------------------
00059 //  SECTION: Friend functions for PLUS operators.
00060 // ----------------------------------------------------------------------------
00061 
00062 // Handles cases 3 and 4 and returns the result.
00063 CLASS_TYPE
00064 ADD_HELPER(small_type us, int unb, int und,
00065            const sc_digit *ud, 
00066            small_type vs, int vnb, int vnd,
00067            const sc_digit *vd)
00068 {
00069 
00070   und = vec_skip_leading_zeros(und, ud);
00071   vnd = vec_skip_leading_zeros(vnd, vd);
00072 
00073   int nb = sc_max(unb, vnb);
00074   int nd = sc_max(und, vnd) + 1;
00075 
00076 #ifdef SC_MAX_NBITS
00077   test_bound(nb);
00078   sc_digit d[MAX_NDIGITS];
00079 #else
00080   sc_digit *d = new sc_digit[nd];
00081 #endif
00082   
00083   d[nd - 1] = d[nd - 2] = 0;
00084 
00085   // case 3
00086   if (us == vs) {
00087 
00088     ++nb;
00089 
00090     if ((und == 1) && (vnd == 1)) {
00091       sc_digit carry = (*ud) + (*vd);
00092       d[0] = carry & DIGIT_MASK;
00093       d[1] = carry >> BITS_PER_DIGIT;
00094     }
00095 
00096     else if (und >= vnd)
00097       vec_add(und, ud, vnd, vd, d);
00098 
00099     else
00100       vec_add(vnd, vd, und, ud, d);
00101 
00102   }
00103 
00104   // case 4
00105   else {
00106 
00107     int cmp_res = vec_cmp(und, ud, vnd, vd);
00108     
00109     if (cmp_res == 0) // u == v
00110       return CLASS_TYPE();
00111     
00112     if (cmp_res > 0)  { // u > v
00113 
00114       if ((und == 1) && (vnd == 1))
00115         d[0] = (*ud) - (*vd);
00116       else
00117         vec_sub(und, ud, vnd, vd, d);
00118 
00119     }
00120     else { // u < v
00121 
00122       us = -us;
00123 
00124       if ((und == 1) && (vnd == 1))
00125         d[0] = (*vd) - (*ud);
00126       else
00127         vec_sub(vnd, vd, und, ud, d);
00128 
00129     }
00130   }
00131   
00132   return CLASS_TYPE(us, nb, nd, d);
00133   
00134 }
00135 
00136 
00137 // ----------------------------------------------------------------------------
00138 //  SECTION: Friend functions of MULTIPLICATION operators.
00139 // ----------------------------------------------------------------------------
00140 
00141 // Handles the case 4 and returns the result.
00142 CLASS_TYPE 
00143 MUL_HELPER(small_type s, 
00144            int unb, int und, 
00145            const sc_digit *ud, 
00146            int vnb, int vnd,
00147            const sc_digit *vd)
00148 {
00149 
00150   und = vec_skip_leading_zeros(und, ud);
00151   vnd = vec_skip_leading_zeros(vnd, vd);
00152 
00153   int nb = unb + vnb;
00154   int nd = und + vnd;
00155   
00156 #ifdef SC_MAX_NBITS
00157   test_bound(nb);
00158   sc_digit d[MAX_NDIGITS];
00159 #else
00160   sc_digit *d = new sc_digit[nd];
00161 #endif
00162 
00163   vec_zero(nd, d);
00164     
00165   sc_digit ud0 = (*ud);
00166   sc_digit vd0 = (*vd);
00167 
00168   if ((vnd == 1) && (vd0 == 1))
00169     vec_copy(und, d, ud);
00170 
00171   else if ((und == 1) && (ud0 == 1))
00172     vec_copy(vnd, d, vd);
00173 
00174   else if ((und == 1) && (vnd == 1) && 
00175       (ud0 < HALF_DIGIT_RADIX) && (vd0 < HALF_DIGIT_RADIX))
00176     d[0] = ud0 * vd0;
00177   
00178   else if ((und == 1) && (ud0 < HALF_DIGIT_RADIX))
00179     vec_mul_small(vnd, vd, ud0, d);
00180 
00181   else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
00182     vec_mul_small(und, ud, vd0, d);
00183 
00184   else if (vnd < und)
00185     vec_mul(und, ud, vnd, vd, d);
00186 
00187   else
00188     vec_mul(vnd, vd, und, ud, d);
00189   
00190   return CLASS_TYPE(s, nb, nd, d);
00191 
00192 }
00193 
00194 
00195 // ----------------------------------------------------------------------------
00196 //  SECTION: Friend functions for DIVISION operators.
00197 // ----------------------------------------------------------------------------
00198 
00199 // Handles the cases 3-4 and returns the result.
00200 CLASS_TYPE 
00201 DIV_HELPER(small_type s, 
00202            int unb, int und, 
00203            const sc_digit *ud, 
00204            int vnb, int vnd,
00205            const sc_digit *vd)
00206 {
00207 
00208   und = vec_skip_leading_zeros(und, ud);
00209   vnd = vec_skip_leading_zeros(vnd, vd);
00210 
00211   int cmp_res = vec_cmp(und, ud, vnd, vd);
00212 
00213   // u < v => u / v = 0 - case 4
00214   if (cmp_res < 0) 
00215     return CLASS_TYPE();
00216 
00217   // One extra digit for d is allocated to simplify vec_div_*().
00218   int nd = sc_max(und, vnd) + 1;
00219 
00220 #ifdef SC_MAX_NBITS
00221   sc_digit d[MAX_NDIGITS + 1];
00222 #else
00223   sc_digit *d = new sc_digit[nd];
00224 #endif
00225 
00226   vec_zero(nd, d);
00227 
00228   sc_digit vd0 = (*vd);
00229 
00230   // u = v => u / v = 1 - case 3
00231   if (cmp_res == 0)
00232     d[0] = 1;
00233 
00234   // else if u > v - case 5
00235 
00236   else if ((vnd == 1) && (vd0 == 1))
00237     vec_copy(und, d, ud);
00238 
00239   else if ((vnd == 1) && (und == 1))
00240     d[0] = (*ud) / vd0;
00241  
00242   else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
00243     vec_div_small(und, ud, vd0, d);
00244 
00245   else
00246     vec_div_large(und, ud, vnd, vd, d);
00247 
00248   return CLASS_TYPE(s, sc_max(unb, vnb), nd - 1, d);
00249   
00250 }
00251 
00252 
00253 // ----------------------------------------------------------------------------
00254 //  SECTION: Friend functions for MOD operators.
00255 // ----------------------------------------------------------------------------
00256 
00257 // Handles the cases 3-4 and returns the result.
00258 CLASS_TYPE 
00259 MOD_HELPER(small_type us, 
00260            int unb, int und, 
00261            const sc_digit *ud, 
00262            int vnb, int vnd,
00263            const sc_digit *vd)
00264 {
00265 
00266   und = vec_skip_leading_zeros(und, ud);
00267   vnd = vec_skip_leading_zeros(vnd, vd);
00268 
00269   int cmp_res = vec_cmp(und, ud, vnd, vd);
00270 
00271   // u = v => u % v = 0 - case 3
00272   if (cmp_res == 0) 
00273     return CLASS_TYPE();
00274 
00275   sc_digit vd0 = (*vd);
00276 
00277   if ((cmp_res > 0) && (vnd == 1) && (vd0 == 1))
00278     return CLASS_TYPE();
00279 
00280   // One extra digit for d is allocated to simplify vec_div_*().
00281   int nd = sc_max(und, vnd) + 1;
00282 
00283 #ifdef SC_MAX_NBITS
00284   sc_digit d[MAX_NDIGITS + 1];
00285 #else
00286   sc_digit *d = new sc_digit[nd];
00287 #endif
00288 
00289   vec_zero(nd, d);
00290 
00291   // u < v => u % v = u - case 4
00292   if (cmp_res < 0) 
00293     vec_copy(und, d, ud);
00294 
00295   // else if u > v - case 5
00296 
00297   else if ((vnd == 1) && (und == 1))
00298     d[0] = (*ud) % vd0;
00299 
00300   else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
00301     d[0] = vec_rem_small(und, ud, vd0);
00302 
00303   else
00304     vec_rem_large(und, ud, vnd, vd, d);
00305 
00306   us = check_for_zero(us, nd - 1, d);
00307 
00308   if (us == SC_ZERO)
00309     return CLASS_TYPE();
00310   else
00311     return CLASS_TYPE(us, sc_min(unb, vnb), nd - 1, d);
00312 
00313 }
00314 
00315 
00316 // ----------------------------------------------------------------------------
00317 //  SECTION: Friend functions for AND operators.
00318 // ----------------------------------------------------------------------------
00319 
00320 // Handles the cases 2-5 and returns the result.
00321 CLASS_TYPE 
00322 AND_HELPER(small_type us, 
00323            int unb, int und, 
00324            const sc_digit *ud, 
00325            small_type vs,
00326            int vnb, int vnd,
00327            const sc_digit *vd)
00328 {
00329 
00330   int nb = sc_max(unb, vnb);
00331   int nd = sc_max(und, vnd);
00332 
00333 #ifdef SC_MAX_NBITS
00334   sc_digit dbegin[MAX_NDIGITS];
00335 #else
00336   sc_digit *dbegin = new sc_digit[nd];
00337 #endif
00338 
00339   sc_digit *d = dbegin;
00340 
00341   register const sc_digit *x;
00342   register const sc_digit *y;
00343   int xnd;
00344   int ynd;
00345   small_type xs;
00346   small_type ys;
00347 
00348   if (und >= vnd) {
00349     x = ud;
00350     y = vd;
00351     xnd = und;
00352     ynd = vnd;
00353     xs = us;
00354     ys = vs;
00355   }
00356   else {
00357     y = ud;
00358     x = vd;
00359     ynd = und;
00360     xnd = vnd;
00361     ys = us;
00362     xs = vs;
00363   }
00364 
00365   const sc_digit *xend = (x + xnd);
00366   const sc_digit *yend = (y + ynd);
00367 
00368   // x is longer than y.
00369 
00370   small_type s = mul_signs(xs, ys);
00371 
00372   if (s > 0) {
00373 
00374     if (xs > 0) { // case 2
00375 
00376       while (y < yend)
00377         (*d++) = (*x++) & (*y++);
00378 
00379       while (x++ < xend) 
00380         (*d++) = 0;
00381 
00382     }
00383     else {  // case 3
00384 
00385       register sc_digit xcarry = 1;
00386       register sc_digit ycarry = 1;
00387 
00388       while (y < yend) {
00389         xcarry += (~(*x++) & DIGIT_MASK);
00390         ycarry += (~(*y++) & DIGIT_MASK);
00391         (*d++) = (xcarry & ycarry) & DIGIT_MASK;
00392         xcarry >>= BITS_PER_DIGIT;
00393         ycarry >>= BITS_PER_DIGIT;
00394       }
00395 
00396       while (x < xend) {
00397         xcarry += (~(*x++) & DIGIT_MASK);
00398         ycarry += DIGIT_MASK;
00399         (*d++) = (xcarry & ycarry) & DIGIT_MASK;
00400         xcarry >>= BITS_PER_DIGIT;
00401         ycarry >>= BITS_PER_DIGIT;
00402       }
00403 
00404     }
00405   }
00406   else {
00407 
00408     if (xs > 0) { // case 4
00409 
00410       register sc_digit ycarry = 1;
00411 
00412       while (y < yend) {
00413         ycarry += (~(*y++) & DIGIT_MASK);
00414         (*d++) = ((*x++) & ycarry) & DIGIT_MASK;
00415         ycarry >>= BITS_PER_DIGIT;
00416       }
00417 
00418       while (x < xend) {
00419         ycarry += DIGIT_MASK;
00420         (*d++) = ((*x++) & ycarry) & DIGIT_MASK;
00421         ycarry >>= BITS_PER_DIGIT;
00422       }
00423 
00424     }
00425     else {  // case 5
00426 
00427       register sc_digit xcarry = 1;
00428 
00429       while (y < yend) {
00430         xcarry += (~(*x++) & DIGIT_MASK);
00431         (*d++) = (xcarry & (*y++)) & DIGIT_MASK;
00432         xcarry >>= BITS_PER_DIGIT;
00433       }
00434 
00435       while (x++ < xend)
00436         (*d++) = 0;
00437 
00438     }
00439   }
00440 
00441   s = convert_signed_2C_to_SM(nb, nd, dbegin);
00442 
00443   return CLASS_TYPE(s, nb, nd, dbegin);  
00444 
00445 }
00446 
00447 
00448 // ----------------------------------------------------------------------------
00449 //  SECTION: Friend functions for OR operators.
00450 // ----------------------------------------------------------------------------
00451 
00452 // Handles the cases 3-5 and returns the result.
00453 CLASS_TYPE 
00454 OR_HELPER(small_type us, 
00455           int unb, int und, 
00456           const sc_digit *ud, 
00457           small_type vs,
00458           int vnb, int vnd,
00459           const sc_digit *vd)
00460 {
00461   
00462   int nb = sc_max(unb, vnb);
00463   int nd = sc_max(und, vnd);
00464 
00465 #ifdef SC_MAX_NBITS
00466   sc_digit dbegin[MAX_NDIGITS];
00467 #else
00468   sc_digit *dbegin = new sc_digit[nd];
00469 #endif
00470 
00471   sc_digit *d = dbegin;
00472 
00473   register const sc_digit *x;
00474   register const sc_digit *y;
00475   int xnd;
00476   int ynd;
00477   small_type xs;
00478   small_type ys;
00479 
00480   if (und >= vnd) {
00481     x = ud;
00482     y = vd;
00483     xnd = und;
00484     ynd = vnd;
00485     xs = us;
00486     ys = vs;
00487   }
00488   else {
00489     y = ud;
00490     x = vd;
00491     ynd = und;
00492     xnd = vnd;
00493     ys = us;
00494     xs = vs;
00495   }
00496 
00497   const sc_digit *xend = (x + xnd);
00498   const sc_digit *yend = (y + ynd);
00499 
00500   // x is longer than y.
00501 
00502   small_type s = mul_signs(xs, ys);
00503 
00504   if (s > 0) {
00505 
00506     if (xs > 0) { // case 3
00507 
00508       while (y < yend)
00509         (*d++) = (*x++) | (*y++);
00510 
00511       while (x < xend)
00512         (*d++) = (*x++);
00513 
00514     }
00515     else {  // case 4
00516 
00517       register sc_digit xcarry = 1;
00518       register sc_digit ycarry = 1;
00519 
00520       while (y < yend) {
00521         xcarry += (~(*x++) & DIGIT_MASK);
00522         ycarry += (~(*y++) & DIGIT_MASK);
00523         (*d++) = (xcarry | ycarry) & DIGIT_MASK;
00524         xcarry >>= BITS_PER_DIGIT;
00525         ycarry >>= BITS_PER_DIGIT;
00526       }
00527 
00528       while (x < xend) {
00529         xcarry += (~(*x++) & DIGIT_MASK);
00530         ycarry += DIGIT_MASK;
00531         (*d++) = (xcarry | ycarry) & DIGIT_MASK;
00532         xcarry >>= BITS_PER_DIGIT;
00533         ycarry >>= BITS_PER_DIGIT;
00534       }
00535 
00536     }
00537 
00538   }
00539   else {
00540 
00541     if (xs > 0) { // case 5
00542 
00543       register sc_digit ycarry = 1;
00544 
00545       while (y < yend) {
00546         ycarry += (~(*y++) & DIGIT_MASK);
00547         (*d++) = ((*x++) | ycarry) & DIGIT_MASK;
00548         ycarry >>= BITS_PER_DIGIT;
00549       }
00550 
00551       while (x < xend) {
00552         ycarry += DIGIT_MASK;
00553         (*d++) = ((*x++) | ycarry) & DIGIT_MASK;
00554         ycarry >>= BITS_PER_DIGIT;
00555       }
00556 
00557     }
00558     else {  // case 6
00559 
00560       register sc_digit xcarry = 1;
00561 
00562       while (y < yend) {
00563         xcarry += (~(*x++) & DIGIT_MASK);
00564         (*d++) = (xcarry | (*y++)) & DIGIT_MASK;
00565         xcarry >>= BITS_PER_DIGIT;
00566       }
00567 
00568       while (x < xend) {
00569         xcarry += (~(*x++) & DIGIT_MASK);
00570         (*d++) = xcarry & DIGIT_MASK;
00571         xcarry >>= BITS_PER_DIGIT;
00572       }
00573     }
00574 
00575   }
00576 
00577   s = convert_signed_2C_to_SM(nb, nd, dbegin);
00578 
00579   return CLASS_TYPE(s, nb, nd, dbegin);
00580 
00581 }
00582 
00583 
00584 // ----------------------------------------------------------------------------
00585 //  SECTION: Friend functions for XOR operators.
00586 // ----------------------------------------------------------------------------
00587 
00588 // Handles the cases 3-5 and returns the result.
00589 CLASS_TYPE 
00590 XOR_HELPER(small_type us, 
00591            int unb, int und, 
00592            const sc_digit *ud, 
00593            small_type vs,
00594            int vnb, int vnd,
00595            const sc_digit *vd)
00596 {
00597   
00598   int nb = sc_max(unb, vnb);
00599   int nd = sc_max(und, vnd);
00600 
00601 #ifdef SC_MAX_NBITS
00602   sc_digit dbegin[MAX_NDIGITS];
00603 #else
00604   sc_digit *dbegin = new sc_digit[nd];
00605 #endif
00606 
00607   sc_digit *d = dbegin;
00608 
00609   register const sc_digit *x;
00610   register const sc_digit *y;
00611   int xnd;
00612   int ynd;
00613   small_type xs;
00614   small_type ys;
00615 
00616   if (und >= vnd) {
00617     x = ud;
00618     y = vd;
00619     xnd = und;
00620     ynd = vnd;
00621     xs = us;
00622     ys = vs;
00623   }
00624   else {
00625     y = ud;
00626     x = vd;
00627     ynd = und;
00628     xnd = vnd;
00629     ys = us;
00630     xs = vs;
00631   }
00632 
00633   const sc_digit *xend = (x + xnd);
00634   const sc_digit *yend = (y + ynd);
00635 
00636   // x is longer than y.
00637 
00638   small_type s = mul_signs(xs, ys);
00639 
00640   if (s > 0) {
00641 
00642     if (xs > 0) { // case 3
00643 
00644       while (y < yend)
00645         (*d++) = ((*x++) ^ (*y++)) & DIGIT_MASK;
00646 
00647       while (x < xend)
00648         (*d++) = (*x++);
00649 
00650     }
00651     else {  // case 4
00652 
00653       register sc_digit xcarry = 1;
00654       register sc_digit ycarry = 1;
00655 
00656       while (y < yend) {
00657         xcarry += (~(*x++) & DIGIT_MASK);
00658         ycarry += (~(*y++) & DIGIT_MASK);
00659         (*d++) = (xcarry ^ ycarry) & DIGIT_MASK;
00660         xcarry >>= BITS_PER_DIGIT;
00661         ycarry >>= BITS_PER_DIGIT;
00662       }
00663 
00664       while (x < xend) {
00665         xcarry += (~(*x++) & DIGIT_MASK);
00666         ycarry += DIGIT_MASK;
00667         (*d++) = (xcarry ^ ycarry) & DIGIT_MASK;
00668         xcarry >>= BITS_PER_DIGIT;
00669         ycarry >>= BITS_PER_DIGIT;
00670       }
00671 
00672     }
00673   }
00674   else {
00675 
00676     if (xs > 0) { // case 5
00677 
00678       register sc_digit ycarry = 1;
00679 
00680       while (y < yend) {
00681         ycarry += (~(*y++) & DIGIT_MASK);
00682         (*d++) = ((*x++) ^ ycarry) & DIGIT_MASK;
00683         ycarry >>= BITS_PER_DIGIT;
00684       }
00685 
00686       while (x < xend) {
00687         ycarry += DIGIT_MASK;
00688         (*d++) = ((*x++) ^ ycarry) & DIGIT_MASK;
00689         ycarry >>= BITS_PER_DIGIT;
00690       }
00691 
00692     }
00693     else {  // case 6
00694 
00695       register sc_digit xcarry = 1;
00696 
00697       while (y < yend) {
00698         xcarry += (~(*x++) & DIGIT_MASK);
00699         (*d++) = (xcarry ^ (*y++)) & DIGIT_MASK;
00700         xcarry >>= BITS_PER_DIGIT;
00701       }
00702 
00703       while (x < xend) {
00704         xcarry += (~(*x++) & DIGIT_MASK);
00705         (*d++) = xcarry & DIGIT_MASK;
00706         xcarry >>= BITS_PER_DIGIT;
00707       }
00708     }
00709   }
00710 
00711   s = convert_signed_2C_to_SM(nb, nd, dbegin);
00712 
00713   return CLASS_TYPE(s, nb, nd, dbegin);
00714 
00715 }
00716 
00717 // End of file.
00718 

Generated on Wed Jan 21 15:32:08 2009 for SystemC by  doxygen 1.5.5