sc_nbutils.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_nbutils.cpp -- External and friend functions for both sc_signed and
00021                     sc_unsigned classes.
00022  
00023   Original Author: Ali Dasdan, Synopsys, Inc.
00024 
00025  *****************************************************************************/
00026 
00027 /*****************************************************************************
00028 
00029   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
00030   changes you are making here.
00031 
00032       Name, Affiliation, Date:
00033   Description of Modification:
00034 
00035  *****************************************************************************/
00036 
00037 
00038 // $Log: sc_nbutils.cpp,v $
00039 // Revision 1.1.1.1  2006/12/15 20:31:36  acg
00040 // SystemC 2.2
00041 //
00042 // Revision 1.3  2006/01/13 18:49:32  acg
00043 // Added $Log command so that CVS check in comments are reproduced in the
00044 // source.
00045 //
00046 
00047 #include <ctype.h>
00048 #include "sysc/datatypes/int/sc_int_ids.h"
00049 #include "sysc/datatypes/int/sc_nbutils.h"
00050 #include "sysc/kernel/sc_macros.h"
00051 
00052 
00053 namespace sc_dt
00054 {
00055 
00056 // ----------------------------------------------------------------------------
00057 //  SECTION: General utility functions.
00058 // ----------------------------------------------------------------------------
00059 
00060 // Return the number of characters to advance the source of c.  This
00061 // function implements one move of the FSM to parse the following
00062 // regular expressions. Error checking is done in the caller.
00063 
00064 small_type
00065 fsm_move(char c, small_type &b, small_type &s, small_type &state)
00066 {
00067 
00068   // Possible regular expressions (REs):
00069   // Let N = any digit depending on the base.
00070   //    1. [0|1|..|9]N*
00071   //    2. [+|-][0|1|..|9]N*
00072   //    3. 0[b|B|d|D|o|O|x|X][0|1|..|F]N*
00073   //    4. [+|-]?0[b|B|d|D|o|O|x|X][0|1|..|F]N*
00074   //
00075   // The finite state machine (FMS) to parse these regular expressions
00076   // has 4 states, 0 to 3. 0 is the initial state and 3 is the final
00077   // state.
00078   //
00079   // Default sign = SC_POS, default base = NB_DEFAULT_BASE.
00080 
00081   switch (state) {
00082 
00083   case 0: // The initial state.
00084     switch (c) { 
00085     case '0': s = SC_POS; state = 1; return 0; // RE 1 or 3
00086     case '+': s = SC_POS; state = 2; return 1; // RE 2
00087     case '-': s = SC_NEG; state = 2; return 1; // RE 2
00088     default:  s = SC_POS; b = NB_DEFAULT_BASE; state = 3; return 0; // RE 1
00089     }
00090     // break; //unreachable code
00091   case 1: // 0...
00092     switch (c) {
00093     case 'x': case 'X': b = SC_HEX; state = 3; return 2; // RE 3 or 4
00094     case 'd': case 'D': b = SC_DEC; state = 3; return 2; // RE 3 or 4
00095     case 'o': case 'O': b = SC_OCT; state = 3; return 2; // RE 3 or 4
00096     case 'b': case 'B': b = SC_BIN; state = 3; return 2; // RE 3 or 4
00097     default:  b = NB_DEFAULT_BASE; state = 3; return 0; // RE 1
00098     }
00099     // break; //unreachable code
00100   case 2: // +... or -...
00101     switch (c) {
00102     case '0': state = 1; return 0; // RE 2 or 4
00103     default:  b = NB_DEFAULT_BASE; state = 3; return 0; // RE 2
00104     }
00105     // break; //unreachable code
00106   case 3: // The final state.
00107     break;
00108 
00109   default:
00110     // Any other state is not possible.
00111     assert((0 <= state) && (state <= 3));
00112 
00113   } // switch
00114 
00115   return 0;
00116 
00117 }  
00118 
00119 
00120 // Get base b and sign s of the number in the char string v. Return a
00121 // pointer to the first char after the point where b and s are
00122 // determined or where the end of v is reached. The input string v has
00123 // to be null terminated.
00124 const char 
00125 *get_base_and_sign(const char *v, small_type &b, small_type &s)
00126 {
00127 
00128 #ifdef DEBUG_SYSTEMC
00129   assert(v != NULL);
00130 #endif
00131 
00132   const small_type STATE_START = 0;
00133   const small_type STATE_FINISH = 3;
00134 
00135   // Default sign = SC_POS, default base = 10.
00136   s = SC_POS;
00137   b = NB_DEFAULT_BASE;
00138 
00139   small_type state = STATE_START;
00140   small_type nskip = 0; // Skip that many chars.
00141   const char *u = v;
00142 
00143   while (*u) {
00144     if (isspace(*u))  // Skip white space.
00145       ++u;
00146     else {
00147       nskip += fsm_move(*u, b, s, state);
00148       if (state == STATE_FINISH)
00149         break;
00150       else
00151         ++u;
00152     }
00153   }
00154 
00155 #ifdef DEBUG_SYSTEMC
00156   // Test to see if the above loop executed more than it should
00157   // have. The max number of skipped chars is equal to the length of
00158   // the longest format specifier, e.g., "-0x".
00159   assert(nskip <= 3);
00160 #endif
00161 
00162   v += nskip;
00163 
00164   // Handles empty strings or strings without any digits after the
00165   // base or base and sign specifier.
00166   if (*v == '\0') { 
00167       char msg[BUFSIZ];
00168       std::sprintf( msg,
00169            "get_base_and_sign( const char* v, small_type&, small_type& ) : "
00170            "v = \"\" is not valid" );
00171       SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
00172   }
00173 
00174   return v;
00175 
00176 }
00177 
00178 //------------------------------------------------------------------------------
00179 //"parse_binary_bits"
00180 //
00181 // This function parses the supplied string into the supplied vector as a
00182 // right justified bit value.
00183 //    src_p  -> character string representing the bits to be parsed.
00184 //    dst_n  =  number of words in data_p and ctrl_p.
00185 //    data_p -> words w/BITS_PER_DIGIT bits to receive the value's data bits.
00186 //    ctrl_p -> words w/BITS_PER_DIGIT bits to receive the value's control bits,
00187 //              or zero.
00188 // Result is true if value was non-zero.
00189 //------------------------------------------------------------------------------
00190 void parse_binary_bits( 
00191     const char* src_p, int dst_n, sc_digit* data_p, sc_digit* ctrl_p )
00192 {
00193     int      bit_i;    // Number of bit now processing.
00194     sc_digit ctrl;     // Control word now assembling.
00195     sc_digit data;     // Data word now assembling.
00196     int      delta_n;  // src_n - dst_n*BITS_PER_DIGIT.
00197     int      src_i;    // Index in src_p now accessing (left to right).
00198     int      src_n;    // Length of source that is left in bits.
00199     int      word_i;   // Bit within word now accessing (left to right).
00200 
00201     // MAKE SURE WE HAVE A STRING TO PARSE:
00202 
00203     if( src_p == 0 ) {
00204         SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
00205                          "character string is zero" );
00206     }
00207     if( *src_p == 0 ) {
00208         SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
00209                          "character string is empty" );
00210     }
00211 
00212 
00213     // INDEX INTO THE SOURCE TO A DEPTH THAT WILL ACCOMODATE OUR SIZE:
00214     //
00215     // If the source is smaller than our value initialize our value to zero.
00216 
00217     src_n = strlen(src_p);
00218     delta_n = src_n - (dst_n*BITS_PER_DIGIT);
00219     if ( delta_n > 0 ) 
00220     {
00221         src_p = &src_p[delta_n];
00222         src_n -= delta_n;
00223     }
00224     else
00225     {
00226         for ( word_i = 0; word_i < dst_n; word_i++ ) data_p[word_i] = 0;
00227         if ( ctrl_p ) 
00228         for ( word_i = 0; word_i < dst_n; word_i++ ) ctrl_p[word_i] = 0;
00229     }
00230 
00231 
00232     // LOOP OVER THE SOURCE ASSEMBLING WORDS AND PLACING THEM IN OUR VALUE:
00233     //
00234     // We stride right to left through the source in BITS_PER_DIGIT chunks.
00235     // Each of those chunks is processed from left to right a bit at a time.
00236     // We process the high order word specially, since there are less bits.
00237 
00238     src_n = src_n - BITS_PER_DIGIT;
00239     for (word_i=0; word_i < dst_n; word_i++)
00240     {
00241         src_i = src_n;
00242 
00243 
00244         // PARTIAL LAST WORD TO ASSEMBLE:
00245 
00246         if ( src_i < 0 ) 
00247         {
00248             src_n += BITS_PER_DIGIT;
00249             src_i = 0;
00250             data = 0;
00251             ctrl = 0;
00252             for ( src_i = 0; src_i < src_n; src_i++ )
00253             {
00254                 ctrl = ctrl << 1;
00255                 data = data << 1;
00256                 switch( src_p[src_i] )
00257                 {
00258                   case 'X':
00259                   case 'x': ctrl = ctrl | 1; data = data | 1; break;
00260                   case '1': data = data | 1; break;
00261                   case 'Z':
00262                   case 'z': ctrl = ctrl | 1; break;
00263                   case '0':                  break;
00264                   default:
00265                     {
00266                         char msg[BUFSIZ];
00267                         std::sprintf( msg, "character string '%s' is not valid", 
00268                         src_p );
00269                         SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_, msg);
00270                     }
00271                     break;
00272                 }
00273             }
00274             if ( ctrl_p ) ctrl_p[word_i] = ctrl;
00275             data_p[word_i] = data;
00276             break;
00277         }
00278 
00279 
00280         // FULL WORD TO BE ASSEMBLED:
00281 
00282         ctrl = 0;
00283         data = 0;
00284         for ( bit_i = 0; bit_i < BITS_PER_DIGIT; bit_i++ )
00285         {
00286             ctrl = ctrl << 1;
00287             data = data << 1;
00288             switch( src_p[src_i++] )
00289             {
00290               case 'X':
00291               case 'x': ctrl = ctrl | 1; data = data | 1; break;
00292               case '1': data = data | 1; break;
00293               case 'Z':
00294               case 'z': ctrl = ctrl | 1; break;
00295               case '0':                  break;
00296               default:
00297                 {
00298                     char msg[BUFSIZ];
00299                     std::sprintf( msg, "character string '%s' is not valid", 
00300                     src_p );
00301                     SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
00302                 }
00303                 break;
00304             }
00305         }
00306         if ( ctrl_p ) ctrl_p[word_i] = ctrl;
00307         data_p[word_i] = data;
00308         src_n = src_n - BITS_PER_DIGIT;
00309     }
00310 }
00311         
00312 
00313 //------------------------------------------------------------------------------
00314 //"parse_hex_bits"
00315 //
00316 // This function parses the supplied string into the supplied vector as a
00317 // right justified bit value.
00318 //    src_p  -> character string representing the bits to be parsed.
00319 //    dst_n  =  number of words in data_p and ctrl_p.
00320 //    data_p -> words w/32 bits to receive the value's data bits.
00321 //    ctrl_p -> words w/32 bits to receive the value's control bits,
00322 //              or zero.
00323 // Result is true if value was non-zero.
00324 //------------------------------------------------------------------------------
00325 void parse_hex_bits( 
00326     const char* src_p, int dst_n, sc_digit* data_p, sc_digit* ctrl_p )
00327 {
00328     sc_digit ctrl;     // Control word now assembling.
00329     sc_digit data;     // Data word now assembling.
00330     int      delta_n;  // src_n - dst_n*BITS_PER_DIGIT.
00331     int      digit_i;  // Number of digit now processing.
00332     int      src_i;    // Index in src_p now accessing (left to right).
00333     int      src_n;    // Length of source that is left in bits.
00334     int      word_i;   // Bit within word now accessing (left to right).
00335 
00336     // MAKE SURE WE HAVE A STRING TO PARSE:
00337 
00338     if( src_p == 0 ) {
00339         SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
00340                          "character string is zero" );
00341     }
00342     if( *src_p == 0 ) {
00343         SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
00344                          "character string is empty" );
00345     }
00346 
00347 
00348     // INDEX INTO THE SOURCE TO A DEPTH THAT WILL ACCOMODATE OUR SIZE:
00349     //
00350     // If the source is smaller than our value initialize our value to zero.
00351 
00352     src_n = strlen(src_p);
00353     delta_n = src_n - (dst_n*8);
00354     if ( delta_n > 0 ) 
00355     {
00356         src_p = &src_p[delta_n];
00357         src_n -= delta_n;
00358     }
00359     else
00360     {
00361         for ( word_i = 0; word_i < dst_n; word_i++ ) data_p[word_i] = 0;
00362         if ( ctrl_p ) 
00363             for ( word_i = 0; word_i < dst_n; word_i++ ) ctrl_p[word_i] = 0;
00364     }
00365 
00366 
00367     // LOOP OVER THE SOURCE ASSEMBLING WORDS AND PLACING THEM IN OUR VALUE:
00368     //
00369     // We stride right to left through the source in BITS_PER_DIGIT chunks.
00370     // Each of those chunks is processed from left to right a bit at a time.
00371     // We process the high order word specially, since there are less bits.
00372 
00373     src_n = src_n - 8;
00374     for (word_i=0; word_i < dst_n; word_i++)
00375     {
00376         src_i = src_n;
00377 
00378 
00379         // PARTIAL LAST WORD TO ASSEMBLE:
00380 
00381         if ( src_i < 0 ) 
00382         {
00383             src_n += 8;
00384             src_i = 0;
00385             data = 0;
00386             ctrl = 0;
00387             for ( src_i = 0; src_i < src_n; src_i++ )
00388             {
00389                 ctrl = ctrl << 4;
00390                 data = data << 4;
00391                 switch( src_p[src_i] )
00392                 {
00393                   case 'X':
00394                   case 'x': ctrl = ctrl | 15; data = data | 15; break;
00395           case 'F':
00396                   case 'f': data = data | 15; break;
00397           case 'E':
00398                   case 'e': data = data | 14; break;
00399           case 'D':
00400                   case 'd': data = data | 13; break;
00401           case 'C':
00402                   case 'c': data = data | 12; break;
00403           case 'B':
00404                   case 'b': data = data | 11; break;
00405           case 'A':
00406                   case 'a': data = data | 10; break;
00407                   case '9': data = data |  9; break;
00408                   case '8': data = data |  8; break;
00409                   case '7': data = data |  7; break;
00410                   case '6': data = data |  6; break;
00411                   case '5': data = data |  5; break;
00412                   case '4': data = data |  4; break;
00413                   case '3': data = data |  3; break;
00414                   case '2': data = data |  2; break;
00415                   case '1': data = data |  1; break;
00416                   case '0':                  break;
00417                   case 'Z':
00418                   case 'z': ctrl = ctrl | 15; break;
00419                   default:
00420                     {
00421                         char msg[BUFSIZ];
00422                         std::sprintf( msg, "character string '%s' is not valid", 
00423                         src_p );
00424                         SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_, msg);
00425                     }
00426                     break;
00427                 }
00428             }
00429             if ( ctrl_p ) ctrl_p[word_i] = ctrl;
00430             data_p[word_i] = data;
00431             break;
00432         }
00433 
00434 
00435         // FULL WORD TO BE ASSEMBLED:
00436 
00437         ctrl = 0;
00438         data = 0;
00439         for ( digit_i = 0; digit_i < 8; digit_i++ )
00440         {
00441             ctrl = ctrl << 4;
00442             data = data << 4;
00443             switch( src_p[src_i++] )
00444             {
00445           case 'X':
00446           case 'x': ctrl = ctrl | 15; data = data | 15; break;
00447           case 'F':
00448           case 'f': data = data | 15; break;
00449           case 'E':
00450           case 'e': data = data | 14; break;
00451           case 'D':
00452           case 'd': data = data | 13; break;
00453           case 'C':
00454           case 'c': data = data | 12; break;
00455           case 'B':
00456           case 'b': data = data | 11; break;
00457           case 'A':
00458           case 'a': data = data | 10; break;
00459           case '9': data = data |  9; break;
00460           case '8': data = data |  8; break;
00461           case '7': data = data |  7; break;
00462           case '6': data = data |  6; break;
00463           case '5': data = data |  5; break;
00464           case '4': data = data |  4; break;
00465           case '3': data = data |  3; break;
00466           case '2': data = data |  2; break;
00467           case '1': data = data |  1; break;
00468           case '0':                  break;
00469           case 'Z':
00470           case 'z': ctrl = ctrl | 15; break;
00471               default:
00472                 {
00473                     char msg[BUFSIZ];
00474                     std::sprintf( msg, "character string '%s' is not valid", 
00475                     src_p );
00476                     SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
00477                 }
00478                 break;
00479             }
00480         }
00481         if ( ctrl_p ) ctrl_p[word_i] = ctrl;
00482         data_p[word_i] = data;
00483         src_n = src_n - BITS_PER_DIGIT;
00484     }
00485 }
00486         
00487 
00488 
00489 // ----------------------------------------------------------------------------
00490 //  SECTION: Utility functions involving unsigned vectors.
00491 // ----------------------------------------------------------------------------
00492 
00493 // Read u from a null terminated char string v. Note that operator>>
00494 // in sc_nbcommon.cpp is similar to this function.
00495 small_type
00496 vec_from_str(int unb, int und, sc_digit *u, 
00497              const char *v, sc_numrep base) 
00498 {
00499 
00500 #ifdef DEBUG_SYSTEMC
00501   assert((unb > 0) && (und > 0) && (u != NULL));
00502   assert(v != NULL);
00503 #endif
00504 
00505   is_valid_base(base);
00506 
00507   small_type b, s;  // base and sign.
00508 
00509   v = get_base_and_sign(v, b, s);
00510 
00511   if (base != SC_NOBASE) {
00512     if (b == NB_DEFAULT_BASE)
00513       b = base;
00514     else {
00515     char msg[BUFSIZ];
00516     std::sprintf( msg,
00517          "vec_from_str( int, int, sc_digit*, const char*, sc_numrep base ) : "
00518          "base = %s does not match the default base",
00519          to_string( base ).c_str() );
00520     SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
00521     }
00522   }
00523 
00524   vec_zero(und, u);
00525 
00526   char c;
00527   
00528   for ( ; (c = *v); ++v) {
00529 
00530     if (isalnum(c)) {
00531       
00532       small_type val;  // Numeric value of a char.
00533     
00534       if (isalpha(c)) // Hex digit.
00535         val = toupper(c) - 'A' + 10;
00536       else
00537         val = c - '0';
00538       
00539       if (val >= b) {
00540       char msg[BUFSIZ];
00541       std::sprintf( msg,
00542            "vec_from_str( int, int, sc_digit*, const char*, sc_numrep base ) : "
00543            "'%c' is not a valid digit in base %d",
00544            *v, b );
00545       SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
00546       }
00547       
00548       // digit = digit * b + val;
00549       vec_mul_small_on(und, u, b);
00550       
00551       if (val)
00552         vec_add_small_on(und, u, val);
00553 
00554     }
00555     else {
00556     char msg[BUFSIZ];
00557     std::sprintf( msg,
00558          "vec_from_str( int, int, sc_digit*, const char*, sc_numrep base ) : "
00559          "'%c' is not a valid digit in base %d",
00560          *v, b );
00561     SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
00562     }
00563   }
00564 
00565   return convert_signed_SM_to_2C_to_SM(s, unb, und, u);
00566 }
00567 
00568 
00569 // All vec_ functions assume that the vector to hold the result,
00570 // called w, has sufficient length to hold the result. For efficiency
00571 // reasons, we do not test whether or not we are out of bounds.
00572 
00573 // Compute w = u + v, where w, u, and v are vectors. 
00574 // - ulen >= vlen
00575 // - wlen >= sc_max(ulen, vlen) + 1
00576 void
00577 vec_add(int ulen, const sc_digit *u,
00578         int vlen, const sc_digit *v,
00579         sc_digit *w)
00580 {
00581 
00582 #ifdef DEBUG_SYSTEMC
00583   assert((ulen > 0) && (u != NULL));
00584   assert((vlen > 0) && (v != NULL));
00585   assert(w != NULL);
00586   assert(ulen >= vlen);
00587 #endif
00588 
00589   const sc_digit *uend = (u + ulen);
00590   const sc_digit *vend = (v + vlen);
00591 
00592   register sc_digit carry = 0;   // Also used as sum to save space.
00593 
00594   // Add along the shorter v.
00595   while (v < vend) {
00596     carry += (*u++) + (*v++);
00597     (*w++) = carry & DIGIT_MASK;
00598     carry >>= BITS_PER_DIGIT;
00599   }
00600 
00601   // Propagate the carry.
00602   while (carry && (u < uend)) {
00603     carry = (*u++) + 1;
00604     (*w++) = carry & DIGIT_MASK;
00605     carry >>= BITS_PER_DIGIT;
00606   }
00607 
00608   // Copy the rest of u to the result.
00609   while (u < uend)
00610     (*w++) = (*u++);
00611 
00612   // Propagate the carry if it is still 1.
00613   if (carry)
00614     (*w) = 1;
00615 
00616 }
00617 
00618 
00619 // Compute u += v, where u and v are vectors.
00620 // - ulen >= vlen
00621 void
00622 vec_add_on(int ulen, sc_digit *ubegin, 
00623            int vlen, const sc_digit *v)
00624 {
00625 
00626 #ifdef DEBUG_SYSTEMC
00627   assert((ulen > 0) && (ubegin != NULL));
00628   assert((vlen > 0) && (v != NULL));
00629   assert(ulen >= vlen);
00630 #endif
00631 
00632   register sc_digit *u = ubegin;
00633   const sc_digit *uend = (u + ulen);
00634   const sc_digit *vend = (v + vlen);
00635 
00636   register sc_digit carry = 0;   // Also used as sum to save space.
00637 
00638   // Add along the shorter v.
00639   while (v < vend) {
00640     carry += (*u) + (*v++);
00641     (*u++) = carry & DIGIT_MASK;
00642     carry >>= BITS_PER_DIGIT;
00643   }
00644 
00645   // Propagate the carry.
00646   while (carry && (u < uend)) {
00647     carry = (*u) + 1;
00648     (*u++) = carry & DIGIT_MASK;
00649     carry >>= BITS_PER_DIGIT;
00650   }
00651 
00652 #ifdef DEBUG_SYSTEMC
00653   if( carry != 0 ) {
00654       SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_,
00655              "vec_add_on( int, sc_digit*, int, const "
00656              "sc_digit* ) : "
00657              "result of addition is wrapped around" );
00658   }
00659 #endif
00660 
00661 }
00662 
00663 
00664 // Compute u += v, where u and v are vectors.
00665 // - ulen < vlen
00666 void
00667 vec_add_on2(int ulen, sc_digit *ubegin, 
00668             int
00669 #ifdef DEBUG_SYSTEMC
00670             vlen
00671 #endif
00672             , const sc_digit *v)
00673 {
00674 
00675 #ifdef DEBUG_SYSTEMC
00676   assert((ulen > 0) && (ubegin != NULL));
00677   assert((vlen > 0) && (v != NULL));
00678   assert(ulen < vlen);
00679 #endif
00680 
00681   register sc_digit *u = ubegin;
00682   const sc_digit *uend = (u + ulen);
00683 
00684   register sc_digit carry = 0;   // Also used as sum to save space.
00685 
00686   // Add along the shorter u.
00687   while (u < uend) {
00688     carry += (*u) + (*v++);
00689     (*u++) = carry & DIGIT_MASK;
00690     carry >>= BITS_PER_DIGIT;
00691   }
00692 
00693 #ifdef DEBUG_SYSTEMC
00694   if( carry != 0 ) {
00695       SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_,
00696                          "vec_add_on2( int, sc_digit*, int, const "
00697              "sc_digit* ) : "
00698              "result of addition is wrapped around" );
00699   }
00700 #endif
00701 }
00702 
00703 
00704 // Compute w = u + v, where w and u are vectors, and v is a scalar.
00705 void
00706 vec_add_small(int ulen, const sc_digit *u,
00707               sc_digit v, 
00708               sc_digit *w)
00709 {
00710 
00711 #ifdef DEBUG_SYSTEMC
00712   assert((ulen > 0) && (u != NULL));
00713   assert(w != NULL);
00714 #endif
00715 
00716   const sc_digit *uend = (u + ulen);
00717 
00718   // Add along the shorter v.
00719   register sc_digit carry = (*u++) + v;
00720   (*w++) = carry & DIGIT_MASK;
00721   carry >>= BITS_PER_DIGIT;
00722 
00723   // Propagate the carry.
00724   while (carry && (u < uend)) {
00725     carry = (*u++) + 1;
00726     (*w++) = carry & DIGIT_MASK;
00727     carry >>= BITS_PER_DIGIT;
00728   }
00729 
00730   // Copy the rest of u to the result.
00731   while (u < uend)
00732     (*w++) = (*u++);
00733 
00734   // Propagate the carry if it is still 1.
00735   if (carry)
00736     (*w) = 1;
00737 
00738 }
00739 
00740 // Compute u += v, where u is vectors, and v is a scalar.
00741 void 
00742 vec_add_small_on(int ulen, sc_digit *u, sc_digit v)
00743 {
00744 
00745 #ifdef DEBUG_SYSTEMC
00746   assert((ulen > 0) && (u != NULL));
00747 #endif
00748 
00749   register int i = 0;
00750 
00751   while (v && (i < ulen)) {
00752     v += u[i];
00753     u[i++] = v & DIGIT_MASK;
00754     v >>= BITS_PER_DIGIT;
00755   }
00756 
00757 #ifdef DEBUG_SYSTEMC
00758   if( v != 0 ) {
00759       SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_,
00760                          "vec_add_small_on( int, sc_digit*, unsigned "
00761              "long ) : "
00762              "result of addition is wrapped around" );
00763   }
00764 #endif
00765 
00766 }
00767 
00768 // Compute w = u - v, where w, u, and v are vectors.
00769 // - ulen >= vlen
00770 // - wlen >= sc_max(ulen, vlen)
00771 void
00772 vec_sub(int ulen, const sc_digit *u,
00773         int vlen, const sc_digit *v,
00774         sc_digit *w)
00775 {
00776 
00777 #ifdef DEBUG_SYSTEMC
00778   assert((ulen > 0) && (u != NULL));
00779   assert((vlen > 0) && (v != NULL));
00780   assert(w != NULL);
00781   assert(ulen >= vlen);
00782 #endif
00783 
00784   const sc_digit *uend = (u + ulen);
00785   const sc_digit *vend = (v + vlen);
00786 
00787   register sc_digit borrow = 0;   // Also used as diff to save space.
00788 
00789   // Subtract along the shorter v.
00790   while (v < vend) {
00791     borrow = ((*u++) + DIGIT_RADIX) - (*v++) - borrow;
00792     (*w++) = borrow & DIGIT_MASK;
00793     borrow = 1 - (borrow >> BITS_PER_DIGIT);
00794   }
00795 
00796   // Propagate the borrow.
00797   while (borrow && (u < uend)) {
00798     borrow = ((*u++) + DIGIT_RADIX) - 1;
00799     (*w++) = borrow & DIGIT_MASK;
00800     borrow = 1 - (borrow >> BITS_PER_DIGIT);
00801   }
00802 
00803 #ifdef DEBUG_SYSTEMC
00804   assert(borrow == 0);
00805 #endif
00806 
00807   // Copy the rest of u to the result.
00808   while (u < uend)
00809     (*w++) = (*u++);
00810 
00811 }
00812 
00813 // Compute u = u - v, where u and v are vectors.
00814 // - u > v
00815 // - ulen >= vlen
00816 void
00817 vec_sub_on(int ulen, sc_digit *ubegin,
00818            int vlen, const sc_digit *v)
00819 {
00820 
00821 #ifdef DEBUG_SYSTEMC
00822   assert((ulen > 0) && (ubegin != NULL));
00823   assert((vlen > 0) && (v != NULL));
00824   assert(ulen >= vlen);
00825 #endif
00826 
00827   register sc_digit *u = ubegin;
00828   const sc_digit *uend = (u + ulen);
00829   const sc_digit *vend = (v + vlen);
00830 
00831   register sc_digit borrow = 0;   // Also used as diff to save space.
00832 
00833   // Subtract along the shorter v.
00834   while (v < vend) {
00835     borrow = ((*u) + DIGIT_RADIX) - (*v++) - borrow;
00836     (*u++) = borrow & DIGIT_MASK;
00837     borrow = 1 - (borrow >> BITS_PER_DIGIT);
00838   }
00839 
00840   // Propagate the borrow.
00841   while (borrow && (u < uend)) {
00842     borrow = ((*u) + DIGIT_RADIX) - 1;
00843     (*u++) = borrow & DIGIT_MASK;
00844     borrow = 1 - (borrow >> BITS_PER_DIGIT);
00845   }
00846 
00847 #ifdef DEBUG_SYSTEMC
00848   assert(borrow == 0);
00849 #endif
00850 
00851 }
00852 
00853 // Compute u = v - u, where u and v are vectors.
00854 // - v > u
00855 // - ulen <= vlen or ulen > ulen
00856 void
00857 vec_sub_on2(int ulen, sc_digit *ubegin,
00858             int vlen, const sc_digit *v)
00859 {
00860 
00861 #ifdef DEBUG_SYSTEMC
00862   assert((ulen > 0) && (ubegin != NULL));
00863   assert((vlen > 0) && (v != NULL));
00864 #endif
00865 
00866   register sc_digit *u = ubegin;
00867   const sc_digit *uend = (u + sc_min(ulen, vlen));
00868 
00869   register sc_digit borrow = 0;   // Also used as diff to save space.
00870 
00871   // Subtract along the shorter u.
00872   while (u < uend) {
00873     borrow = ((*v++) + DIGIT_RADIX) - (*u) - borrow;
00874     (*u++) = borrow & DIGIT_MASK;
00875     borrow = 1 - (borrow >> BITS_PER_DIGIT);
00876   }
00877 
00878 #ifdef DEBUG_SYSTEMC
00879   if( borrow != 0 ) {
00880       SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_,
00881                          "vec_sub_on2( int, sc_digit*, int, const "
00882              "sc_digit* ) : "
00883              "result of subtraction is wrapped around" );
00884   }
00885 #endif
00886 }
00887 
00888 // Compute w = u - v, where w and u are vectors, and v is a scalar.
00889 void
00890 vec_sub_small(int ulen, const sc_digit *u,
00891               sc_digit v, 
00892               sc_digit *w)
00893 {
00894 
00895 #ifdef DEBUG_SYSTEMC
00896   assert(ulen > 0);
00897   assert(u != NULL);
00898 #endif
00899 
00900   const sc_digit *uend = (u + ulen);
00901 
00902   // Add along the shorter v.
00903   register sc_digit borrow = ((*u++) + DIGIT_RADIX) - v;
00904   (*w++) = borrow & DIGIT_MASK;
00905   borrow = 1 - (borrow >> BITS_PER_DIGIT);
00906 
00907   // Propagate the borrow.
00908   while (borrow && (u < uend)) {
00909     borrow = ((*u++) + DIGIT_RADIX) - 1;
00910     (*w++) = borrow & DIGIT_MASK;
00911     borrow = 1 - (borrow >> BITS_PER_DIGIT);
00912   }
00913 
00914 #ifdef DEBUG_SYSTEMC
00915   assert(borrow == 0);
00916 #endif
00917 
00918   // Copy the rest of u to the result.
00919   while (u < uend)
00920     (*w++) = (*u++);
00921 
00922 }
00923 
00924 
00925 // Compute u -= v, where u is vectors, and v is a scalar.
00926 void 
00927 vec_sub_small_on(int ulen, sc_digit *u, sc_digit v)
00928 {
00929 
00930 #ifdef DEBUG_SYSTEMC
00931   assert((ulen > 0) && (u != NULL));
00932 #endif
00933 
00934   for (register int i = 0; i < ulen; ++i) {
00935     v = (u[i] + DIGIT_RADIX) - v;    
00936     u[i] = v & DIGIT_MASK;
00937     v = 1 - (v >> BITS_PER_DIGIT);
00938   }
00939 
00940 #ifdef DEBUG_SYSTEMC
00941   assert(v == 0);
00942 #endif
00943 
00944 }
00945 
00946 // Compute w = u * v, where w, u, and v are vectors.
00947 void
00948 vec_mul(int ulen, const sc_digit *u,
00949         int vlen, const sc_digit *vbegin, 
00950         sc_digit *wbegin)
00951 {
00952 
00953   /* Consider u = Ax + B and v = Cx + D where x is equal to
00954      HALF_DIGIT_RADIX. In other words, A is the higher half of u and
00955      B is the lower half of u. The interpretation for v is
00956      similar. Then, we have the following picture:
00957 
00958               u_h     u_l
00959      u: -------- --------
00960                A        B
00961 
00962               v_h     v_l
00963      v: -------- --------
00964                C        D
00965  
00966      result (d):                     
00967      carry_before:                           -------- --------
00968                                               carry_h  carry_l
00969      result_before:        -------- -------- -------- --------
00970                                R1_h     R1_l     R0_h     R0_l
00971                                              -------- --------
00972                                                  BD_h     BD_l
00973                                     -------- --------
00974                                         AD_h     AD_l
00975                                     -------- --------
00976                                         BC_h     BC_l
00977                            -------- --------
00978                                AC_h     AC_l
00979      result_after:         -------- -------- -------- --------
00980                               R1_h'    R1_l'    R0_h'    R0_l'
00981  
00982      prod_l = R0_h|R0_l + B * D  + 0|carry_l
00983             = R0_h|R0_l + BD_h|BD_l + 0|carry_l
00984  
00985      prod_h = A * D + B * C + high_half(prod_l) + carry_h
00986             = AD_h|AD_l + BC_h|BC_l + high_half(prod_l) + 0|carry_h
00987  
00988      carry = A * C + high_half(prod_h)
00989            = AC_h|AC_l + high_half(prod_h)
00990  
00991      R0_l' = low_half(prod_l)
00992  
00993      R0_h' = low_half(prod_h)
00994  
00995      R0 = high_half(prod_h)|low_half(prod_l)
00996  
00997      where '|' is the concatenation operation and the suffixes 0 and 1
00998      show the iteration number, i.e., 0 is the current iteration and 1
00999      is the next iteration.
01000  
01001      NOTE: sc_max(prod_l, prod_h, carry) <= 2 * x^2 - 1, so any
01002      of these numbers can be stored in a digit.
01003 
01004      NOTE: low_half(u) returns the lower BITS_PER_HALF_DIGIT of u,
01005      whereas high_half(u) returns the rest of the bits, which may
01006      contain more bits than BITS_PER_HALF_DIGIT.  
01007   */
01008 
01009 #ifdef DEBUG_SYSTEMC
01010   assert((ulen > 0) && (u != NULL));
01011   assert((vlen > 0) && (vbegin != NULL));
01012   assert(wbegin != NULL);
01013 #endif
01014 
01015 #define prod_h carry
01016 
01017   const sc_digit *uend = (u + ulen);
01018   const sc_digit *vend = (vbegin + vlen);
01019 
01020   while (u < uend) {
01021 
01022     sc_digit u_h = (*u++);        // A|B
01023     sc_digit u_l = low_half(u_h); // B
01024     u_h = high_half(u_h);           // A
01025 
01026 #ifdef DEBUG_SYSTEMC
01027     // The overflow bits must be zero.
01028     assert(u_h == (u_h & HALF_DIGIT_MASK));
01029 #endif
01030 
01031     register sc_digit carry = 0;
01032 
01033     register sc_digit *w = (wbegin++);
01034 
01035     register const sc_digit *v = vbegin;
01036 
01037     while (v < vend) {
01038 
01039       sc_digit v_h = (*v++);         // C|D
01040       sc_digit v_l = low_half(v_h);  // D
01041 
01042       v_h = high_half(v_h);            // C
01043 
01044 #ifdef DEBUG_SYSTEMC
01045       // The overflow bits must be zero.
01046       assert(v_h == (v_h & HALF_DIGIT_MASK));
01047 #endif
01048 
01049       sc_digit prod_l = (*w) + u_l * v_l + low_half(carry);
01050 
01051       prod_h = u_h * v_l + u_l * v_h + high_half(prod_l) + high_half(carry);
01052 
01053       (*w++) = concat(low_half(prod_h), low_half(prod_l));
01054 
01055       carry = u_h * v_h + high_half(prod_h);
01056 
01057     }
01058 
01059     (*w) = carry;
01060 
01061   }
01062 
01063 #undef prod_h
01064 
01065 }
01066 
01067 // Compute w = u * v, where w and u are vectors, and v is a scalar. 
01068 // - 0 < v < HALF_DIGIT_RADIX.
01069 void
01070 vec_mul_small(int ulen, const sc_digit *u,
01071               sc_digit v, sc_digit *w)
01072 {
01073 
01074 #ifdef DEBUG_SYSTEMC
01075   assert((ulen > 0) && (u != NULL));
01076   assert(w != NULL);
01077   assert((0 < v) && (v < HALF_DIGIT_RADIX));
01078 #endif
01079 
01080 #define prod_h carry
01081 
01082   const sc_digit *uend = (u + ulen);
01083 
01084   register sc_digit carry = 0;
01085 
01086   while (u < uend) {
01087 
01088     sc_digit u_AB = (*u++);
01089 
01090 #ifdef DEBUG_SYSTEMC
01091     // The overflow bits must be zero.
01092     assert(high_half(u_AB) == high_half_masked(u_AB));
01093 #endif
01094 
01095     sc_digit prod_l = v * low_half(u_AB) + low_half(carry);
01096 
01097     prod_h = v * high_half(u_AB) + high_half(prod_l) + high_half(carry);
01098 
01099     (*w++) = concat(low_half(prod_h), low_half(prod_l));
01100 
01101     carry = high_half(prod_h);
01102 
01103   }
01104 
01105   (*w) = carry;
01106 
01107 #undef prod_h
01108 
01109 }
01110 
01111 // Compute u = u * v, where u is a vector, and v is a scalar.
01112 // - 0 < v < HALF_DIGIT_RADIX. 
01113 void
01114 vec_mul_small_on(int ulen, sc_digit *u, sc_digit v)
01115 {
01116 
01117 #ifdef DEBUG_SYSTEMC
01118   assert((ulen > 0) && (u != NULL));
01119   assert((0 < v) && (v < HALF_DIGIT_RADIX));
01120 #endif
01121 
01122 #define prod_h carry
01123 
01124   register sc_digit carry = 0;
01125 
01126   for (register int i = 0; i < ulen; ++i) {
01127 
01128 #ifdef DEBUG_SYSTEMC
01129     // The overflow bits must be zero.
01130     assert(high_half(u[i]) == high_half_masked(u[i]));
01131 #endif
01132 
01133     sc_digit prod_l = v * low_half(u[i]) + low_half(carry);
01134 
01135     prod_h = v * high_half(u[i]) + high_half(prod_l) + high_half(carry);
01136 
01137     u[i] = concat(low_half(prod_h), low_half(prod_l));
01138 
01139     carry = high_half(prod_h);
01140 
01141   }
01142 
01143 #undef prod_h
01144 
01145 #ifdef DEBUG_SYSTEMC
01146   if( carry != 0 ) {
01147       SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_,
01148                          "vec_mul_small_on( int, sc_digit*, unsigned "
01149              "long ) : "
01150              "result of multiplication is wrapped around" );
01151   }
01152 #endif
01153 }
01154 
01155 // Compute w = u / v, where w, u, and v are vectors. 
01156 // - u and v are assumed to have at least two digits as uchars.
01157 void
01158 vec_div_large(int ulen, const sc_digit *u,
01159               int vlen, const sc_digit *v,
01160               sc_digit *w)
01161 {
01162 
01163 #ifdef DEBUG_SYSTEMC
01164   assert((ulen > 0) && (u != NULL));
01165   assert((vlen > 0) && (v != NULL));
01166   assert(w != NULL);
01167   assert(BITS_PER_DIGIT >= 3 * BITS_PER_BYTE);
01168 #endif
01169 
01170   // We will compute q = x / y where x = u and y = v. The reason for
01171   // using x and y is that x and y are BYTE_RADIX copies of u and v,
01172   // respectively. The use of BYTE_RADIX radix greatly simplifies the
01173   // complexity of the division operation. These copies are also
01174   // needed even when we use DIGIT_RADIX representation.
01175 
01176   int xlen = BYTES_PER_DIGIT * ulen + 1;
01177   int ylen = BYTES_PER_DIGIT * vlen;
01178 
01179 #ifdef SC_MAX_NBITS
01180   uchar x[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
01181   uchar y[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
01182   uchar q[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
01183 #else
01184   uchar *x = new uchar[xlen];
01185   uchar *y = new uchar[ylen];
01186   uchar *q = new uchar[xlen - ylen + 1];
01187 #endif
01188 
01189   // q corresponds to w.
01190 
01191   // Set (uchar) x = (sc_digit) u.
01192   xlen = vec_to_char(ulen, u, xlen, x);
01193 
01194   // Skip all the leading zeros in x.
01195   while ((--xlen >= 0) && (! x[xlen]));
01196   xlen++;
01197 
01198   // Set (uchar) y = (sc_digit) v.
01199   ylen = vec_to_char(vlen, v, ylen, y);
01200 
01201   // Skip all the leading zeros in y.
01202   while ((--ylen >= 0) && (! y[ylen]));
01203   ylen++;
01204 
01205 #ifdef DEBUG_SYSTEMC
01206   assert(xlen > 1);
01207   assert(ylen > 1);
01208 #endif
01209 
01210   // At this point, all the leading zeros are eliminated from x and y.
01211 
01212   // Zero the last digit of x.
01213   x[xlen] = 0;
01214 
01215   // The first two digits of y.
01216   register sc_digit y2 = (y[ylen - 1] << BITS_PER_BYTE) + y[ylen - 2];
01217 
01218   const sc_digit DOUBLE_BITS_PER_BYTE = 2 * BITS_PER_BYTE;
01219 
01220   // Find each q[k].
01221   for (register int k = xlen - ylen; k >= 0; --k) {
01222 
01223     // qk is a guess for q[k] such that q[k] = qk or qk - 1.
01224     register sc_digit qk;
01225 
01226     // Find qk by just using 2 digits of y and 3 digits of x. The
01227     // following code assumes that sizeof(sc_digit) >= 3 BYTEs.
01228     int k2 = k + ylen;
01229 
01230     qk = ((x[k2] << DOUBLE_BITS_PER_BYTE) + 
01231           (x[k2 - 1] << BITS_PER_BYTE) + x[k2 - 2]) / y2;
01232 
01233     if (qk >= BYTE_RADIX)     // qk cannot be larger than the largest
01234       qk = BYTE_RADIX - 1;    // digit in BYTE_RADIX.
01235 
01236     // q[k] = qk or qk - 1. The following if-statement determines which:
01237     if (qk) {
01238 
01239       register uchar *xk = (x + k);  // A shortcut for x[k].
01240 
01241       // x = x - y * qk :
01242       register sc_digit carry = 0;
01243 
01244       for (register int i = 0; i < ylen; ++i) {
01245         carry += y[i] * qk;
01246         sc_digit diff = (xk[i] + BYTE_RADIX) - (carry & BYTE_MASK);
01247         xk[i] = (uchar)(diff & BYTE_MASK);
01248         carry = (carry >> BITS_PER_BYTE) + (1 - (diff >> BITS_PER_BYTE));
01249       }
01250 
01251       // If carry, qk may be one too large.
01252       if (carry) {
01253 
01254         // 2's complement the last digit.
01255         carry = (xk[ylen] + BYTE_RADIX) - carry;
01256         xk[ylen] = (uchar)(carry & BYTE_MASK);
01257         carry = 1 - (carry >> BITS_PER_BYTE);
01258         
01259         if (carry) {
01260 
01261           // qk was one too large, so decrement it.
01262           --qk;
01263         
01264           // Since qk was decreased by one, y must be added to x:
01265           // That is, x = x - y * (qk - 1) = x - y * qk + y = x_above + y.
01266           carry = 0;
01267 
01268           for (register int i = 0; i < ylen; ++i) {
01269             carry += xk[i] + y[i];
01270             xk[i] = (uchar)(carry & BYTE_MASK);
01271             carry >>= BITS_PER_BYTE;
01272           }
01273 
01274           if (carry)
01275             xk[ylen] = (uchar)((xk[ylen] + 1) & BYTE_MASK);
01276 
01277         }  // second if carry
01278       }  // first if carry
01279     }  // if qk
01280 
01281     q[k] = (uchar)qk;
01282 
01283   }  // for k
01284 
01285   // Set (sc_digit) w = (uchar) q.
01286   vec_from_char(xlen - ylen + 1, q, ulen, w);
01287 
01288 #ifndef SC_MAX_NBITS
01289   delete [] x;
01290   delete [] y;
01291   delete [] q;
01292 #endif
01293 
01294 }
01295 
01296 // Compute w = u / v, where u and w are vectors, and v is a scalar.
01297 // - 0 < v < HALF_DIGIT_RADIX. Below, we rename w to q.
01298 void 
01299 vec_div_small(int ulen, const sc_digit *u,
01300               sc_digit v, sc_digit *q)
01301 {
01302 
01303   // Given (u = u_1u_2...u_n)_b = (q = q_1q_2...q_n) * v + r, where b
01304   // is the base, and 0 <= r < v. Then, the algorithm is as follows:
01305   //
01306   // r = 0; 
01307   // for (j = 1; j <= n; j++) {
01308   //   q_j = (r * b + u_j) / v;
01309   //   r = (r * b + u_j) % v;
01310   // }
01311   // 
01312   // In our case, b = DIGIT_RADIX, and u = Ax + B and q = Cx + D where
01313   // x = HALF_DIGIT_RADIX. Note that r < v < x and b = x^2. Then, a
01314   // typical situation is as follows:
01315   //
01316   // ---- ----
01317   // 0    r
01318   //           ---- ----
01319   //           A    B
01320   //      ---- ---- ----
01321   //      r    A    B     = r * b + u
01322   //
01323   // Hence, C = (r|A) / v.
01324   //        D = (((r|A) % v)|B) / v
01325   //        r = (((r|A) % v)|B) % v
01326 
01327 #ifdef DEBUG_SYSTEMC
01328   assert((ulen > 0) && (u != NULL));
01329   assert(q != NULL);
01330   assert((0 < v) && (v < HALF_DIGIT_RADIX));
01331 #endif
01332 
01333 #define q_h r
01334 
01335   register sc_digit r = 0;
01336   const sc_digit *ubegin = u;
01337 
01338   u += ulen;
01339   q += ulen;
01340 
01341   while (ubegin < u) {
01342 
01343     sc_digit u_AB = (*--u);       // A|B
01344 
01345 #ifdef DEBUG_SYSTEMC
01346     // The overflow bits must be zero.
01347     assert(high_half(u_AB) == high_half_masked(u_AB));
01348 #endif
01349 
01350     register sc_digit num = concat(r, high_half(u_AB));  // num = r|A
01351     q_h = num / v;                           // C
01352     num = concat((num % v), low_half(u_AB)); // num = (((r|A) % v)|B) 
01353     (*--q) = concat(q_h, num / v);           // q = C|D
01354     r = num % v;
01355 
01356   }
01357 
01358 #undef q_h
01359 
01360 }
01361 
01362 // Compute w = u % v, where w, u, and v are vectors. 
01363 // - u and v are assumed to have at least two digits as uchars.
01364 void
01365 vec_rem_large(int ulen, const sc_digit *u,
01366               int vlen, const sc_digit *v,
01367               sc_digit *w)
01368 {
01369 
01370 #ifdef DEBUG_SYSTEMC
01371   assert((ulen > 0) && (u != NULL));
01372   assert((vlen > 0) && (v != NULL));
01373   assert(w != NULL);
01374   assert(BITS_PER_DIGIT >= 3 * BITS_PER_BYTE);
01375 #endif
01376 
01377   // This function is adapted from vec_div_large.
01378 
01379   int xlen = BYTES_PER_DIGIT * ulen + 1;
01380   int ylen = BYTES_PER_DIGIT * vlen;
01381 
01382 #ifdef SC_MAX_NBITS
01383   uchar x[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
01384   uchar y[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
01385 #else
01386   uchar *x = new uchar[xlen];
01387   uchar *y = new uchar[ylen];
01388 #endif
01389 
01390   // r corresponds to w.
01391 
01392   // Set (uchar) x = (sc_digit) u.
01393   xlen = vec_to_char(ulen, u, xlen, x);
01394 
01395   // Skip all the leading zeros in x.
01396   while ((--xlen >= 0) && (! x[xlen]));
01397   xlen++;
01398 
01399   // Set (uchar) y = (sc_digit) v.
01400   ylen = vec_to_char(vlen, v, ylen, y);
01401 
01402   // Skip all the leading zeros in y.
01403   while ((--ylen >= 0) && (! y[ylen]));
01404   ylen++;
01405 
01406 #ifdef DEBUG_SYSTEMC
01407   assert(xlen > 1);
01408   assert(ylen > 1);
01409 #endif
01410 
01411   // At this point, all the leading zeros are eliminated from x and y.
01412 
01413   // Zero the last digit of x.
01414   x[xlen] = 0;
01415 
01416   // The first two digits of y.
01417   register sc_digit y2 = (y[ylen - 1] << BITS_PER_BYTE) + y[ylen - 2];
01418 
01419   const sc_digit DOUBLE_BITS_PER_BYTE = 2 * BITS_PER_BYTE;
01420 
01421   // Find each q[k].
01422   for (register int k = xlen - ylen; k >= 0; --k) {
01423 
01424     // qk is a guess for q[k] such that q[k] = qk or qk - 1.
01425     register sc_digit qk;
01426 
01427     // Find qk by just using 2 digits of y and 3 digits of x. The
01428     // following code assumes that sizeof(sc_digit) >= 3 BYTEs.
01429     int k2 = k + ylen;
01430 
01431     qk = ((x[k2] << DOUBLE_BITS_PER_BYTE) +
01432       (x[k2 - 1] << BITS_PER_BYTE) + x[k2 - 2]) / y2;
01433 
01434     if (qk >= BYTE_RADIX)     // qk cannot be larger than the largest
01435       qk = BYTE_RADIX - 1;    // digit in BYTE_RADIX.
01436 
01437     // q[k] = qk or qk - 1. The following if-statement determines which.
01438     if (qk) {
01439 
01440       register uchar *xk = (x + k);  // A shortcut for x[k].
01441 
01442       // x = x - y * qk;
01443       register sc_digit carry = 0;
01444 
01445       for (register int i = 0; i < ylen; ++i) {
01446         carry += y[i] * qk;
01447         sc_digit diff = (xk[i] + BYTE_RADIX) - (carry & BYTE_MASK);
01448         xk[i] = (uchar)(diff & BYTE_MASK);
01449         carry = (carry >> BITS_PER_BYTE) + (1 - (diff >> BITS_PER_BYTE));
01450       }
01451 
01452       if (carry) {
01453 
01454         // 2's complement the last digit.
01455         carry = (xk[ylen] + BYTE_RADIX) - carry;
01456         xk[ylen] = (uchar)(carry & BYTE_MASK);
01457         carry = 1 - (carry >> BITS_PER_BYTE);
01458         
01459         if (carry) {
01460 
01461           // qk was one too large, so decrement it.
01462           // --qk;
01463         
01464           // x = x - y * (qk - 1) = x - y * qk + y = x_above + y.
01465           carry = 0;
01466 
01467           for (register int i = 0; i < ylen; ++i) {
01468             carry += xk[i] + y[i];
01469             xk[i] = (uchar)(carry & BYTE_MASK);
01470             carry >>= BITS_PER_BYTE;
01471           }
01472 
01473           if (carry)
01474             xk[ylen] = (uchar)((xk[ylen] + 1) & BYTE_MASK);
01475 
01476         }  // second if carry
01477       } // first if carry
01478     }  // if qk
01479   }  // for k
01480 
01481   // Set (sc_digit) w = (uchar) x for the remainder.
01482   vec_from_char(ylen, x, ulen, w);
01483 
01484 #ifndef SC_MAX_NBITS
01485   delete [] x;
01486   delete [] y;
01487 #endif
01488 
01489 }
01490 
01491 // Compute r = u % v, where u is a vector, and r and v are scalars.
01492 // - 0 < v < HALF_DIGIT_RADIX. 
01493 // - The remainder r is returned.
01494 sc_digit
01495 vec_rem_small(int ulen, const sc_digit *u, sc_digit v)
01496 {
01497 
01498 #ifdef DEBUG_SYSTEMC
01499   assert((ulen > 0) && (u != NULL));
01500   assert((0 < v) && (v < HALF_DIGIT_RADIX));
01501 #endif
01502 
01503   // This function is adapted from vec_div_small().
01504 
01505   register sc_digit r = 0;
01506   const sc_digit *ubegin = u;
01507 
01508   u += ulen;
01509 
01510   while (ubegin < u) {
01511     register sc_digit u_AB = (*--u);  // A|B
01512 
01513 #ifdef DEBUG_SYSTEMC
01514     // The overflow bits must be zero.
01515     assert(high_half(u_AB) == high_half_masked(u_AB));
01516 #endif
01517 
01518     // r = (((r|A) % v)|B) % v
01519     r = (concat(((concat(r, high_half(u_AB))) % v), low_half(u_AB))) % v;
01520   }
01521 
01522   return r;
01523 
01524 }
01525 
01526 // u = u / v, r = u % v.
01527 sc_digit
01528 vec_rem_on_small(int ulen, sc_digit *u, sc_digit v)
01529 {
01530 
01531 #ifdef DEBUG_SYSTEMC
01532   assert((ulen > 0) && (u != NULL));
01533   assert(v > 0);
01534 #endif
01535 
01536 #define q_h r
01537 
01538   register sc_digit r = 0;
01539   const sc_digit *ubegin = u;
01540 
01541   u += ulen;
01542 
01543   while (ubegin < u) {
01544 
01545     sc_digit u_AB = (*--u);       // A|B
01546 
01547 #ifdef DEBUG_SYSTEMC
01548     // The overflow bits must be zero.
01549     assert(high_half(u_AB) == high_half_masked(u_AB));
01550 #endif
01551 
01552     register sc_digit num = concat(r, high_half(u_AB));  // num = r|A
01553     q_h = num / v;                           // C
01554     num = concat((num % v), low_half(u_AB)); // num = (((r|A) % v)|B) 
01555     (*u) = concat(q_h, num / v);             // q = C|D
01556     r = num % v;
01557 
01558   }
01559 
01560 #undef q_h
01561 
01562   return r;
01563 
01564 }
01565 
01566 // Set (uchar) v = (sc_digit) u. Return the new vlen.
01567 int
01568 vec_to_char(int ulen, const sc_digit *u,
01569             int vlen, uchar *v)
01570 {
01571 
01572 #ifdef DEBUG_SYSTEMC
01573   assert((ulen > 0) && (u != NULL));
01574   assert((vlen > 0) && (v != NULL));
01575 #endif
01576 
01577   register int nbits = ulen * BITS_PER_DIGIT;
01578 
01579   register int right = 0;
01580   register int left = right + BITS_PER_BYTE - 1;
01581 
01582   vlen = 0;
01583 
01584   while (nbits > 0) {
01585 
01586     int left_digit = left / BITS_PER_DIGIT;
01587     int right_digit = right / BITS_PER_DIGIT;
01588 
01589     register int nsr = ((vlen << LOG2_BITS_PER_BYTE) % BITS_PER_DIGIT);
01590 
01591     int d = u[right_digit] >> nsr;
01592 
01593     if (left_digit != right_digit) {
01594 
01595       if (left_digit < ulen)
01596         d |= u[left_digit] << (BITS_PER_DIGIT - nsr);
01597 
01598     }
01599 
01600     v[vlen++] = (uchar)(d & BYTE_MASK);
01601 
01602     left += BITS_PER_BYTE;
01603     right += BITS_PER_BYTE;
01604     nbits -= BITS_PER_BYTE;
01605 
01606   }
01607 
01608   return vlen;
01609 
01610 }
01611 
01612 // Set (sc_digit) v = (uchar) u. 
01613 // - sizeof(uchar) <= sizeof(sc_digit), 
01614 void 
01615 vec_from_char(int ulen, const uchar *u, 
01616               int vlen, sc_digit *v)
01617 {
01618 
01619 #ifdef DEBUG_SYSTEMC
01620   assert((ulen > 0) && (u != NULL));
01621   assert((vlen > 0) && (v != NULL));
01622   assert(sizeof(uchar) <= sizeof(sc_digit));
01623 #endif
01624 
01625   sc_digit *vend = (v + vlen);
01626 
01627   const int nsr = BITS_PER_DIGIT - BITS_PER_BYTE;
01628   const sc_digit mask = one_and_ones(nsr);
01629 
01630   (*v) = (sc_digit) u[ulen - 1];
01631 
01632   for (register int i = ulen - 2; i >= 0; --i) {
01633 
01634     // Manual inlining of vec_shift_left().
01635 
01636     register sc_digit *viter = v;
01637 
01638     register sc_digit carry = 0;
01639 
01640     while (viter < vend) {
01641       register sc_digit vval = (*viter);
01642       (*viter++) = (((vval & mask) << BITS_PER_BYTE) | carry);
01643       carry = vval >> nsr;
01644     }
01645 
01646     if (viter < vend)
01647       (*viter) = carry;
01648 
01649     (*v) |= (sc_digit) u[i];
01650 
01651   }
01652 
01653 }
01654 
01655 // Set u <<= nsl.
01656 // If nsl is negative, it is ignored.
01657 void 
01658 vec_shift_left(int ulen, sc_digit *u, int nsl)
01659 {
01660 
01661 #ifdef DEBUG_SYSTEMC
01662   assert((ulen > 0) && (u != NULL));
01663 #endif
01664 
01665   if (nsl <= 0)
01666     return;
01667 
01668   // Shift left whole digits if nsl is large enough.
01669   if (nsl >= (int) BITS_PER_DIGIT) {
01670 
01671     int nd;
01672 
01673     if (nsl % BITS_PER_DIGIT == 0) {
01674       nd = nsl / BITS_PER_DIGIT;  // No need to use DIV_CEIL(nsl).
01675       nsl = 0;
01676     }
01677     else {
01678       nd = DIV_CEIL(nsl) - 1;
01679       nsl -= nd * BITS_PER_DIGIT;
01680     }
01681 
01682     if (nd) {
01683 
01684       // Shift left for nd digits.
01685       for (register int j = ulen - 1; j >= nd; --j)
01686         u[j] = u[j - nd];
01687       
01688       vec_zero( sc_min( nd, ulen ), u );
01689       
01690     }
01691 
01692     if (nsl == 0)
01693       return;
01694 
01695   }
01696 
01697   // Shift left if nsl < BITS_PER_DIGIT.
01698   register sc_digit *uiter = u;
01699   sc_digit *uend = uiter + ulen;
01700 
01701   int nsr = BITS_PER_DIGIT - nsl;
01702   sc_digit mask = one_and_ones(nsr);
01703 
01704   register sc_digit carry = 0;
01705 
01706   while (uiter < uend) {
01707     register sc_digit uval = (*uiter);
01708     (*uiter++) = (((uval & mask) << nsl) | carry);
01709     carry = uval >> nsr;
01710   }
01711 
01712   if (uiter < uend)
01713     (*uiter) = carry;
01714 
01715 }
01716 
01717 // Set u >>= nsr.
01718 // If nsr is negative, it is ignored.
01719 void 
01720 vec_shift_right(int ulen, sc_digit *u, int nsr, sc_digit fill)
01721 {
01722 
01723 #ifdef DEBUG_SYSTEMC
01724   assert((ulen > 0) && (u != NULL));
01725 #endif
01726 
01727   // fill is usually either 0 or DIGIT_MASK; it can be any value.
01728 
01729   if (nsr <= 0)
01730     return;
01731 
01732   // Shift right whole digits if nsr is large enough.
01733   if (nsr >= (int) BITS_PER_DIGIT) {
01734 
01735     int nd;
01736 
01737     if (nsr % BITS_PER_DIGIT == 0) {
01738       nd = nsr / BITS_PER_DIGIT;
01739       nsr = 0;
01740     }
01741     else {
01742       nd = DIV_CEIL(nsr) - 1;
01743       nsr -= nd * BITS_PER_DIGIT;
01744     }
01745     
01746     if (nd) {
01747 
01748       // Shift right for nd digits.
01749       for (register int j = 0; j < (ulen - nd); ++j)
01750         u[j] = u[j + nd];
01751 
01752       if (fill) {
01753         for (register int j = ulen - sc_min( nd, ulen ); j < ulen; ++j)
01754           u[j] = fill;
01755       }
01756       else
01757         vec_zero(ulen - sc_min( nd, ulen ), ulen, u);
01758      
01759     }
01760 
01761     if (nsr == 0)
01762       return;
01763 
01764   }
01765 
01766   // Shift right if nsr < BITS_PER_DIGIT.
01767   sc_digit *ubegin = u;
01768   register sc_digit *uiter = (ubegin + ulen);
01769 
01770   int nsl = BITS_PER_DIGIT - nsr;
01771   sc_digit mask = one_and_ones(nsr);
01772 
01773   register sc_digit carry = (fill & mask) << nsl;
01774 
01775   while (ubegin < uiter) {
01776     register sc_digit uval = (*--uiter);
01777     (*uiter) = (uval >> nsr) | carry;
01778     carry = (uval & mask) << nsl;
01779   }
01780 
01781 }
01782 
01783 
01784 // Let u[l..r], where l and r are left and right bit positions
01785 // respectively, be equal to its mirror image.
01786 void
01787 vec_reverse(int unb, int und, sc_digit *ud, 
01788             int l, int r)
01789 {
01790 
01791 #ifdef DEBUG_SYSTEMC
01792   assert((unb > 0) && (und > 0) && (ud != NULL));
01793   assert((0 <= r) && (r <= l) && (l < unb));
01794 #endif
01795 
01796   if (l < r) {
01797       char msg[BUFSIZ];
01798       std::sprintf( msg, "vec_reverse( int, int, sc_digit*, int l, int r ) : "
01799            "l = %d < r = %d is not valid",
01800            l, r );
01801       SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
01802   }
01803 
01804   // Make sure that l and r are within bounds.
01805   r = sc_max(r, 0);
01806   l = sc_min(l, unb - 1);
01807 
01808   // Allocate memory for processing.
01809 #ifdef SC_MAX_NBITS
01810   sc_digit d[MAX_NDIGITS];
01811 #else
01812   sc_digit *d = new sc_digit[und];
01813 #endif
01814 
01815   // d is a copy of ud.
01816   vec_copy(und, d, ud);
01817 
01818   // Based on the value of the ith in d, find the value of the jth bit
01819   // in ud.
01820 
01821   for (register int i = l, j = r; i >= r; --i, ++j) {
01822 
01823     if ((d[digit_ord(i)] & one_and_zeros(bit_ord(i))) != 0) // Test.
01824       ud[digit_ord(j)] |= one_and_zeros(bit_ord(j));     // Set.
01825     else  
01826       ud[digit_ord(j)] &= ~(one_and_zeros(bit_ord(j)));  // Clear.
01827 
01828   }
01829 
01830 #ifndef SC_MAX_NBITS
01831   delete [] d;
01832 #endif
01833     
01834 }
01835 
01836 } // namespace sc_dt
01837 
01838 
01839 // End of file.

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