sc_nbexterns.cpp

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-2006 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.4 (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_nbexterns.cpp -- External functions for both sc_signed and sc_unsigned
00021                       classes. These functions work on two parameters u and
00022                       v, and copy the result to the first parameter u. This
00023                       is also the reason that they are suffixed with _on_help.
00024  
00025   Original Author: Ali Dasdan, Synopsys, Inc.
00026 
00027  *****************************************************************************/
00028 
00029 /*****************************************************************************
00030 
00031   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
00032   changes you are making here.
00033 
00034       Name, Affiliation, Date:
00035   Description of Modification:
00036 
00037  *****************************************************************************/
00038 
00039 
00040 // $Log: sc_nbexterns.cpp,v $
00041 // Revision 1.1.1.1  2006/12/15 20:31:36  acg
00042 // SystemC 2.2
00043 //
00044 // Revision 1.3  2006/01/13 18:49:32  acg
00045 // Added $Log command so that CVS check in comments are reproduced in the
00046 // source.
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 //  SECTION: External functions for PLUS operators.
00058 // ----------------------------------------------------------------------------
00059 
00060 // Handles the cases 3 and 4 and returns the result in u.
00061 void
00062 add_on_help(small_type &us, int /* unb */, int und,
00063             sc_digit *ud, 
00064             small_type vs, int /* vnb */, int vnd,
00065             const sc_digit *vd)
00066 {
00067 
00068   vnd = vec_skip_leading_zeros(vnd, vd);
00069 
00070   if (us == vs) {  // case 3
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 {  // case 4
00079 
00080     // vec_cmp expects that und is the number of non-zero digits in ud.
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)  { // u == v
00085       us = SC_ZERO;
00086       vec_zero(und, ud);
00087       return;
00088     }
00089 
00090     if (cmp_res > 0) // u > v
00091       vec_sub_on(und, ud, vnd, vd);
00092 
00093     else { // u < v
00094       us = -us;
00095       vec_sub_on2(und, ud, vnd, vd);
00096     }
00097 
00098   }
00099 }
00100 
00101 
00102 // ----------------------------------------------------------------------------
00103 
00104 /* 
00105 
00106 mul_on_help_signed and mul_on_help_unsigned have the same body except
00107 that CONVERT_SM_to_2C_to_SM and COPY_DIGITS are defined for signed and
00108 unsigned, respectively.  This comment also applies to the
00109 signed/unsigned versions of div_on_help and mod_on_help. It is
00110 possible to take COPY_DIGITS out of these functions and create a
00111 single version of each of these helper functions; however, this will
00112 impose an onverhead on performance. In the versions below, any change
00113 in the signed version of a helper function must be carried to a
00114 corresponding change in the unsigned verion of the same function or
00115 vice versa.
00116 
00117 */
00118 
00119 
00120 // ----------------------------------------------------------------------------
00121 //  SECTION: External functions of MULTIPLICATION operators.
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   {  // Body of mul_on_help
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   {  // Body of mul_on_help
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 //  SECTION: External functions for DIVISION operators.
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   {  // Body of div_on_help
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) { // u < v => u / v = 0 - case 4
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     // One extra digit for d is allocated to simplify vec_div_*().
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     // u = v => u / v = 1 - case 3
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   {  // Body of div_on_help
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) { // u < v => u / v = 0 - case 4
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     // One extra digit for d is allocated to simplify vec_div_*().
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     // u = v => u / v = 1 - case 3
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 //  SECTION: External functions for MOD operators.
00420 // ----------------------------------------------------------------------------
00421 
00422 void
00423 mod_on_help_signed(small_type &us, 
00424                    int unb, int und, 
00425                    sc_digit *ud, 
00426                    int /* vnb */, int vnd,
00427                    const sc_digit *vd)
00428 {
00429 
00430 #define COPY_DIGITS copy_digits_signed
00431 
00432   { // Body of mod_on_help
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     // u < v => u % v = u - case 4
00442     if (cmp_res < 0) 
00443       return;
00444     
00445     // u = v => u % v = 0 - case 3
00446     if (cmp_res == 0) { 
00447       us = SC_ZERO;
00448       vec_zero(old_und, ud);
00449       return;
00450     }
00451     
00452     // else if u > v - case 5
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     // One extra digit for d is allocated to simplify vec_div_*().
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 /* vnb */, int vnd,
00505                      const sc_digit *vd)
00506 {
00507 
00508 #define COPY_DIGITS copy_digits_unsigned
00509 
00510   { // Body of mod_on_help
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     // u < v => u % v = u - case 4
00520     if (cmp_res < 0) 
00521       return;
00522     
00523     // u = v => u % v = 0 - case 3
00524     if (cmp_res == 0) { 
00525       us = SC_ZERO;
00526       vec_zero(old_und, ud);
00527       return;
00528     }
00529     
00530     // else if u > v - case 5
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     // One extra digit for d is allocated to simplify vec_div_*().
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 //  SECTION: External functions for AND operators.
00580 // ----------------------------------------------------------------------------
00581 
00582 // Handles the cases 2-5 and returns the result in u.
00583 void
00584 and_on_help(small_type us, 
00585             int /* unb */, int und, 
00586             sc_digit *ud, 
00587             small_type vs,
00588             int /* vnb */, 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   // Truncate y.
00598   if (xnd < ynd)
00599     ynd = xnd;
00600 
00601   const sc_digit *xend = (x + xnd);
00602   const sc_digit *yend = (y + ynd);
00603 
00604   // x is longer than y.
00605 
00606   small_type s = mul_signs(us, vs);
00607 
00608   if (s > 0) {
00609 
00610     if (us > 0) { // case 2
00611 
00612       while (y < yend)
00613         (*x++) &= (*y++);
00614 
00615       while (x < xend)
00616         (*x++) = 0;
00617 
00618     }
00619     else {  // case 3
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) { // case 4
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 {  // case 5
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 //  SECTION: External functions for OR operators.
00681 // ----------------------------------------------------------------------------
00682 
00683 // Handles the cases 3-5 and returns the result in u.
00684 void
00685 or_on_help(small_type us, 
00686            int /* unb */, int und, 
00687            sc_digit *ud, 
00688            small_type vs,
00689            int /* vnb */, 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   // x is longer than y.
00705 
00706   small_type s = mul_signs(us, vs);
00707 
00708   if (s > 0) {
00709 
00710     if (us > 0) { // case 3
00711 
00712       while (y < yend)
00713         (*x++) |= (*y++);
00714 
00715       // No change for the rest of x.
00716 
00717     }
00718     else {  // case 4
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) { // case 5
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 {  // case 6
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 //  SECTION: External functions for XOR operators.
00784 // ----------------------------------------------------------------------------
00785 
00786 // Handles the cases 3-5 and returns the result in u.
00787 void
00788 xor_on_help(small_type us, 
00789             int /* unb */, int und, 
00790             sc_digit *ud, 
00791             small_type vs,
00792             int /* vnb */, 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   // x is longer than y.
00808 
00809   small_type s = mul_signs(us, vs);
00810 
00811   if (s > 0) {
00812 
00813     if (us > 0) { // case 3
00814 
00815       while (y < yend) {
00816         (*x) = ((*x) ^ (*y)) & DIGIT_MASK;
00817         x++;
00818         y++;
00819       }
00820 
00821       // No change for the rest of x.
00822 
00823     }
00824     else {  // case 4
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) { // case 5
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 {  // case 6
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 } // namespace sc_dt
00887 
00888 
00889 // End of file

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