sc_nbutils.cc revision 13325
16145Snate@binkert.org/*****************************************************************************
26145Snate@binkert.org
36145Snate@binkert.org  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
46145Snate@binkert.org  more contributor license agreements.  See the NOTICE file distributed
56145Snate@binkert.org  with this work for additional information regarding copyright ownership.
66145Snate@binkert.org  Accellera licenses this file to you under the Apache License, Version 2.0
76145Snate@binkert.org  (the "License"); you may not use this file except in compliance with the
86145Snate@binkert.org  License.  You may obtain a copy of the License at
96145Snate@binkert.org
106145Snate@binkert.org    http://www.apache.org/licenses/LICENSE-2.0
116145Snate@binkert.org
126145Snate@binkert.org  Unless required by applicable law or agreed to in writing, software
136145Snate@binkert.org  distributed under the License is distributed on an "AS IS" BASIS,
146145Snate@binkert.org  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
156145Snate@binkert.org  implied.  See the License for the specific language governing
166145Snate@binkert.org  permissions and limitations under the License.
176145Snate@binkert.org
186145Snate@binkert.org *****************************************************************************/
196145Snate@binkert.org
206145Snate@binkert.org/*****************************************************************************
216145Snate@binkert.org
226145Snate@binkert.org  sc_nbutils.cpp -- External and friend functions for both sc_signed and
236145Snate@binkert.org                    sc_unsigned classes.
246145Snate@binkert.org
256145Snate@binkert.org  Original Author: Ali Dasdan, Synopsys, Inc.
266145Snate@binkert.org
276145Snate@binkert.org *****************************************************************************/
286145Snate@binkert.org
296145Snate@binkert.org/*****************************************************************************
306145Snate@binkert.org
316145Snate@binkert.org  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
326145Snate@binkert.org  changes you are making here.
336145Snate@binkert.org
346145Snate@binkert.org      Name, Affiliation, Date:
356145Snate@binkert.org  Description of Modification:
366145Snate@binkert.org
376145Snate@binkert.org *****************************************************************************/
386145Snate@binkert.org
396145Snate@binkert.org
406145Snate@binkert.org// $Log: sc_nbutils.cpp,v $
416145Snate@binkert.org// Revision 1.4  2011/08/24 22:05:46  acg
426145Snate@binkert.org//  Torsten Maehne: initialization changes to remove warnings.
436145Snate@binkert.org//
446145Snate@binkert.org// Revision 1.3  2011/02/18 20:19:15  acg
456145Snate@binkert.org//  Andy Goodrich: updating Copyright notice.
466145Snate@binkert.org//
476145Snate@binkert.org// Revision 1.2  2007/11/04 21:26:40  acg
486145Snate@binkert.org//  Andy Goodrich: added a buffer to the allocation of the q array to address
496145Snate@binkert.org//  an issue with references outside the array by 1 byte detected by valgrind.
506145Snate@binkert.org//
516145Snate@binkert.org// Revision 1.1.1.1  2006/12/15 20:20:05  acg
526145Snate@binkert.org// SystemC 2.3
536145Snate@binkert.org//
546145Snate@binkert.org// Revision 1.3  2006/01/13 18:49:32  acg
556145Snate@binkert.org// Added $Log command so that CVS check in comments are reproduced in the
566145Snate@binkert.org// source.
576145Snate@binkert.org//
586145Snate@binkert.org
596145Snate@binkert.org#include <cctype>
606145Snate@binkert.org#include <cstdio>
616145Snate@binkert.org#include <cstring>
626145Snate@binkert.org#include <sstream>
636145Snate@binkert.org
646145Snate@binkert.org#include "systemc/ext/dt/bit/messages.hh"
656145Snate@binkert.org#include "systemc/ext/dt/int/messages.hh"
666145Snate@binkert.org#include "systemc/ext/dt/int/sc_nbutils.hh"
676145Snate@binkert.org#include "systemc/ext/utils/functions.hh"
686145Snate@binkert.org
696145Snate@binkert.orgnamespace sc_dt
706145Snate@binkert.org{
716145Snate@binkert.org
726145Snate@binkert.org// only used within vec_from_str (non-standard, deprecated)
736145Snate@binkert.orgstatic inline void
746145Snate@binkert.orgis_valid_base(sc_numrep base)
756145Snate@binkert.org{
766145Snate@binkert.org    switch (base) {
776145Snate@binkert.org      case SC_NOBASE: case SC_BIN:
786145Snate@binkert.org      case SC_OCT: case SC_DEC:
796145Snate@binkert.org      case SC_HEX:
806145Snate@binkert.org        break;
816145Snate@binkert.org      case SC_BIN_US: case SC_BIN_SM:
826145Snate@binkert.org      case SC_OCT_US: case SC_OCT_SM:
836145Snate@binkert.org      case SC_HEX_US: case SC_HEX_SM:
846145Snate@binkert.org      case SC_CSD:
856145Snate@binkert.org        SC_REPORT_ERROR("not implemented",
866145Snate@binkert.org                        "is_valid_base( sc_numrep base ) : "
876145Snate@binkert.org                        "bases SC_CSD, or ending in _US and _SM are "
886145Snate@binkert.org                        "not supported");
896145Snate@binkert.org        break;
90      default:
91        std::stringstream msg;
92        msg << "is_valid_base( sc_numrep base ) : base = " << base <<
93               " is not valid";
94        SC_REPORT_ERROR(sc_core::SC_ID_VALUE_NOT_VALID_, msg.str().c_str());
95    }
96}
97
98// ----------------------------------------------------------------------------
99//  ENUM : sc_numrep
100//
101//  Enumeration of number representations for character string conversion.
102// ----------------------------------------------------------------------------
103
104const std::string
105to_string(sc_numrep numrep)
106{
107    switch (numrep) {
108#define CASE_ENUM2STR(Value) case Value: return #Value
109
110      CASE_ENUM2STR(SC_DEC);
111
112      CASE_ENUM2STR(SC_BIN);
113      CASE_ENUM2STR(SC_BIN_US);
114      CASE_ENUM2STR(SC_BIN_SM);
115
116      CASE_ENUM2STR(SC_OCT);
117      CASE_ENUM2STR(SC_OCT_US);
118      CASE_ENUM2STR(SC_OCT_SM);
119
120      CASE_ENUM2STR(SC_HEX);
121      CASE_ENUM2STR(SC_HEX_US);
122      CASE_ENUM2STR(SC_HEX_SM);
123
124      CASE_ENUM2STR(SC_CSD);
125
126#undef CASE_ENUM2STR
127
128      default:
129        return "unknown";
130    }
131}
132
133// ----------------------------------------------------------------------------
134//  SECTION: General utility functions.
135// ----------------------------------------------------------------------------
136
137// Return the number of characters to advance the source of c.  This
138// function implements one move of the FSM to parse the following
139// regular expressions. Error checking is done in the caller.
140
141small_type
142fsm_move(char c, small_type &b, small_type &s, small_type &state)
143{
144    // Possible regular expressions (REs):
145    // Let N = any digit depending on the base.
146    //    1. [0|1|..|9]N*
147    //    2. [+|-][0|1|..|9]N*
148    //    3. 0[b|B|d|D|o|O|x|X][0|1|..|F]N*
149    //    4. [+|-]?0[b|B|d|D|o|O|x|X][0|1|..|F]N*
150    //
151    // The finite state machine (FMS) to parse these regular expressions
152    // has 4 states, 0 to 3. 0 is the initial state and 3 is the final
153    // state.
154    //
155    // Default sign = SC_POS, default base = NB_DEFAULT_BASE.
156
157    switch (state) {
158      case 0: // The initial state.
159        switch (c) {
160          case '0': s = SC_POS; state = 1; return 0; // RE 1 or 3
161          case '+': s = SC_POS; state = 2; return 1; // RE 2
162          case '-': s = SC_NEG; state = 2; return 1; // RE 2
163          default:
164            s = SC_POS; b = NB_DEFAULT_BASE; state = 3; return 0; // RE 1
165        }
166        // break; //unreachable code
167      case 1: // 0...
168        switch (c) {
169          case 'x': case 'X': b = SC_HEX; state = 3; return 2; // RE 3 or 4
170          case 'd': case 'D': b = SC_DEC; state = 3; return 2; // RE 3 or 4
171          case 'o': case 'O': b = SC_OCT; state = 3; return 2; // RE 3 or 4
172          case 'b': case 'B': b = SC_BIN; state = 3; return 2; // RE 3 or 4
173          default: b = NB_DEFAULT_BASE; state = 3; return 0; // RE 1
174        }
175        // break; //unreachable code
176      case 2: // +... or -...
177        switch (c) {
178          case '0': state = 1; return 0; // RE 2 or 4
179          default: b = NB_DEFAULT_BASE; state = 3; return 0; // RE 2
180        }
181        // break; //unreachable code
182      case 3: // The final state.
183        break;
184      default:
185        // Any other state is not possible.
186        sc_assert((0 <= state) && (state <= 3));
187    } // switch
188    return 0;
189}
190
191
192// Get base b and sign s of the number in the char string v. Return a
193// pointer to the first char after the point where b and s are
194// determined or where the end of v is reached. The input string v has
195// to be null terminated.
196const char *
197get_base_and_sign(const char *v, small_type &b, small_type &s)
198{
199#ifdef DEBUG_SYSTEMC
200    sc_assert(v != NULL);
201#endif
202    const small_type STATE_START = 0;
203    const small_type STATE_FINISH = 3;
204
205    // Default sign = SC_POS, default base = 10.
206    s = SC_POS;
207    b = NB_DEFAULT_BASE;
208
209    small_type state = STATE_START;
210    small_type nskip = 0; // Skip that many chars.
211    const char *u = v;
212
213    while (*u) {
214        if (isspace(*u)) { // Skip white space.
215            ++u;
216        } else {
217            nskip += fsm_move(*u, b, s, state);
218            if (state == STATE_FINISH)
219              break;
220            else
221              ++u;
222        }
223    }
224
225    // Test to see if the above loop executed more than it should
226    // have. The max number of skipped chars is equal to the length of
227    // the longest format specifier, e.g., "-0x".
228    sc_assert(nskip <= 3);
229
230    v += nskip;
231
232    // Handles empty strings or strings without any digits after the
233    // base or base and sign specifier.
234    if (*v == '\0') {
235        static const char msg[] =
236            "get_base_and_sign( const char* v, small_type&, small_type& ) : "
237            "v = \"\" is not valid";
238        SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_, msg);
239    }
240    return v;
241}
242
243//-----------------------------------------------------------------------------
244//"parse_binary_bits"
245//
246// This function parses the supplied string into the supplied vector as a
247// right justified bit value.
248//    src_p  -> character string representing the bits to be parsed.
249//    dst_n  =  number of words in data_p and ctrl_p.
250//    data_p -> words w/BITS_PER_DIGIT bits to receive the value's data bits.
251//    ctrl_p -> words w/BITS_PER_DIGIT bits to receive the value's control
252//              bits, or zero.
253// Result is true if value was non-zero.
254//-----------------------------------------------------------------------------
255void
256parse_binary_bits(const char *src_p, int dst_n,
257                  sc_digit *data_p, sc_digit *ctrl_p)
258{
259    int bit_i; // Number of bit now processing.
260    sc_digit ctrl; // Control word now assembling.
261    sc_digit data; // Data word now assembling.
262    int delta_n; // src_n - dst_n*BITS_PER_DIGIT.
263    int src_i; // Index in src_p now accessing (left to right).
264    int src_n; // Length of source that is left in bits.
265    int word_i; // Bit within word now accessing (left to right).
266
267    // MAKE SURE WE HAVE A STRING TO PARSE:
268    if (src_p == 0) {
269        SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_,
270                        "character string is zero");
271        return;
272    }
273    if (*src_p == 0) {
274        SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_,
275                        "character string is empty");
276        return;
277    }
278
279
280    // INDEX INTO THE SOURCE TO A DEPTH THAT WILL ACCOMODATE OUR SIZE:
281    //
282    // If the source is smaller than our value initialize our value to zero.
283
284    src_n = strlen(src_p);
285    delta_n = src_n - (dst_n*BITS_PER_DIGIT);
286    if (delta_n > 0) {
287        src_p = &src_p[delta_n];
288        src_n -= delta_n;
289    } else {
290        for (word_i = 0; word_i < dst_n; word_i++)
291            data_p[word_i] = 0;
292        if (ctrl_p)
293            for (word_i = 0; word_i < dst_n; word_i++)
294                ctrl_p[word_i] = 0;
295    }
296
297    // LOOP OVER THE SOURCE ASSEMBLING WORDS AND PLACING THEM IN OUR VALUE:
298    //
299    // We stride right to left through the source in BITS_PER_DIGIT chunks.
300    // Each of those chunks is processed from left to right a bit at a time.
301    // We process the high order word specially, since there are less bits.
302    src_n = src_n - BITS_PER_DIGIT;
303    for (word_i=0; word_i < dst_n; word_i++) {
304        src_i = src_n;
305
306        // PARTIAL LAST WORD TO ASSEMBLE:
307        if (src_i < 0) {
308            src_n += BITS_PER_DIGIT;
309            data = 0;
310            ctrl = 0;
311            for (src_i = 0; src_i < src_n; src_i++) {
312                ctrl = ctrl << 1;
313                data = data << 1;
314                switch (src_p[src_i]) {
315                  case 'X':
316                  case 'x': ctrl = ctrl | 1; data = data | 1; break;
317                  case '1': data = data | 1; break;
318                  case 'Z':
319                  case 'z': ctrl = ctrl | 1; break;
320                  case '0': break;
321                  default:
322                    {
323                        std::stringstream msg;
324                        msg << "character string '" << src_p <<
325                               "' is not valid";
326                        SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_,
327                                        msg.str().c_str());
328                        return;
329                    }
330                    break;
331                }
332            }
333            if (ctrl_p)
334                ctrl_p[word_i] = ctrl;
335            data_p[word_i] = data;
336            break;
337        }
338
339        // FULL WORD TO BE ASSEMBLED:
340        ctrl = 0;
341        data = 0;
342        for (bit_i = 0; bit_i < BITS_PER_DIGIT; bit_i++) {
343            ctrl = ctrl << 1;
344            data = data << 1;
345            switch (src_p[src_i++]) {
346              case 'X':
347              case 'x': ctrl = ctrl | 1; data = data | 1; break;
348              case '1': data = data | 1; break;
349              case 'Z':
350              case 'z': ctrl = ctrl | 1; break;
351              case '0': break;
352              default:
353                {
354                    std::stringstream msg;
355                    msg << "character string '" << src_p <<
356                           "' is not valid";
357                    SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_,
358                                    msg.str().c_str());
359                    return;
360                }
361                break;
362            }
363        }
364        if (ctrl_p)
365            ctrl_p[word_i] = ctrl;
366        data_p[word_i] = data;
367        src_n = src_n - BITS_PER_DIGIT;
368    }
369}
370
371
372//-----------------------------------------------------------------------------
373//"parse_hex_bits"
374//
375// This function parses the supplied string into the supplied vector as a
376// right justified bit value.
377//    src_p  -> character string representing the bits to be parsed.
378//    dst_n  =  number of words in data_p and ctrl_p.
379//    data_p -> words w/32 bits to receive the value's data bits.
380//    ctrl_p -> words w/32 bits to receive the value's control bits,
381//              or zero.
382// Result is true if value was non-zero.
383//-----------------------------------------------------------------------------
384void
385parse_hex_bits(const char *src_p, int dst_n,
386               sc_digit *data_p, sc_digit *ctrl_p)
387{
388    sc_digit ctrl; // Control word now assembling.
389    sc_digit data; // Data word now assembling.
390    int delta_n; // src_n - dst_n*BITS_PER_DIGIT.
391    int digit_i; // Number of digit now processing.
392    int src_i; // Index in src_p now accessing (left to right).
393    int src_n; // Length of source that is left in bits.
394    int word_i; // Bit within word now accessing (left to right).
395
396    // MAKE SURE WE HAVE A STRING TO PARSE:
397    if (src_p == 0) {
398        SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_,
399                        "character string is zero");
400        return;
401    }
402    if (*src_p == 0) {
403        SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_,
404                        "character string is empty");
405        return;
406    }
407
408    // INDEX INTO THE SOURCE TO A DEPTH THAT WILL ACCOMODATE OUR SIZE:
409    //
410    // If the source is smaller than our value initialize our value to zero.
411    src_n = strlen(src_p);
412    delta_n = src_n - (dst_n*8);
413    if (delta_n > 0) {
414        src_p = &src_p[delta_n];
415        src_n -= delta_n;
416    } else {
417        for (word_i = 0; word_i < dst_n; word_i++)
418            data_p[word_i] = 0;
419        if (ctrl_p)
420            for (word_i = 0; word_i < dst_n; word_i++)
421                ctrl_p[word_i] = 0;
422    }
423
424    // LOOP OVER THE SOURCE ASSEMBLING WORDS AND PLACING THEM IN OUR VALUE:
425    //
426    // We stride right to left through the source in BITS_PER_DIGIT chunks.
427    // Each of those chunks is processed from left to right a bit at a time.
428    // We process the high order word specially, since there are less bits.
429    src_n = src_n - 8;
430    for (word_i = 0; word_i < dst_n; word_i++) {
431        src_i = src_n;
432
433        // PARTIAL LAST WORD TO ASSEMBLE:
434        if (src_i < 0) {
435            src_n += 8;
436            data = 0;
437            ctrl = 0;
438            for (src_i = 0; src_i < src_n; src_i++) {
439                ctrl = ctrl << 4;
440                data = data << 4;
441                switch (src_p[src_i]) {
442                  case 'X':
443                  case 'x': ctrl = ctrl | 15; data = data | 15; break;
444                  case 'F':
445                  case 'f': data = data | 15; break;
446                  case 'E':
447                  case 'e': data = data | 14; break;
448                  case 'D':
449                  case 'd': data = data | 13; break;
450                  case 'C':
451                  case 'c': data = data | 12; break;
452                  case 'B':
453                  case 'b': data = data | 11; break;
454                  case 'A':
455                  case 'a': data = data | 10; break;
456                  case '9': data = data |  9; break;
457                  case '8': data = data |  8; break;
458                  case '7': data = data |  7; break;
459                  case '6': data = data |  6; break;
460                  case '5': data = data |  5; break;
461                  case '4': data = data |  4; break;
462                  case '3': data = data |  3; break;
463                  case '2': data = data |  2; break;
464                  case '1': data = data |  1; break;
465                  case '0': break;
466                  case 'Z':
467                  case 'z': ctrl = ctrl | 15; break;
468                  default:
469                    {
470                        std::stringstream msg;
471                        msg << "character string '" << src_p <<
472                               "' is not valid";
473                        SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_,
474                                        msg.str().c_str());
475                        return;
476                    }
477                    break;
478                }
479            }
480            if (ctrl_p)
481                ctrl_p[word_i] = ctrl;
482            data_p[word_i] = data;
483            break;
484        }
485
486        // FULL WORD TO BE ASSEMBLED:
487        ctrl = 0;
488        data = 0;
489        for (digit_i = 0; digit_i < 8; digit_i++) {
490            ctrl = ctrl << 4;
491            data = data << 4;
492            switch (src_p[src_i++]) {
493              case 'X':
494              case 'x': ctrl = ctrl | 15; data = data | 15; break;
495              case 'F':
496              case 'f': data = data | 15; break;
497              case 'E':
498              case 'e': data = data | 14; break;
499              case 'D':
500              case 'd': data = data | 13; break;
501              case 'C':
502              case 'c': data = data | 12; break;
503              case 'B':
504              case 'b': data = data | 11; break;
505              case 'A':
506              case 'a': data = data | 10; break;
507              case '9': data = data |  9; break;
508              case '8': data = data |  8; break;
509              case '7': data = data |  7; break;
510              case '6': data = data |  6; break;
511              case '5': data = data |  5; break;
512              case '4': data = data |  4; break;
513              case '3': data = data |  3; break;
514              case '2': data = data |  2; break;
515              case '1': data = data |  1; break;
516              case '0': break;
517              case 'Z':
518              case 'z': ctrl = ctrl | 15; break;
519              default:
520                {
521                    std::stringstream msg;
522                    msg << "character string '" << src_p << "' is not valid";
523                    SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_,
524                                    msg.str().c_str() );
525                    return;
526                }
527                break;
528            }
529        }
530        if (ctrl_p)
531            ctrl_p[word_i] = ctrl;
532        data_p[word_i] = data;
533        src_n = src_n - BITS_PER_DIGIT;
534    }
535}
536
537
538// ----------------------------------------------------------------------------
539//  SECTION: Utility functions involving unsigned vectors.
540// ----------------------------------------------------------------------------
541
542// Read u from a null terminated char string v. Note that operator>>
543// in sc_nbcommon.cpp is similar to this function.
544small_type
545vec_from_str(int unb, int und, sc_digit *u, const char *v, sc_numrep base)
546{
547
548#ifdef DEBUG_SYSTEMC
549    sc_assert((unb > 0) && (und > 0) && (u != NULL));
550    sc_assert(v != NULL);
551#endif
552    is_valid_base(base);
553
554    small_type b, s; // base and sign.
555
556    v = get_base_and_sign(v, b, s);
557
558    if (base != SC_NOBASE) {
559        if (b == NB_DEFAULT_BASE) {
560            b = base;
561        } else {
562            std::stringstream msg;
563            msg << "vec_from_str( int, int, sc_digit*, const char*, " <<
564                   "sc_numrep base ) : base = " << base <<
565                   " does not match the default base";
566            SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_,
567                            msg.str().c_str());
568            return 0;
569        }
570    }
571
572    vec_zero(und, u);
573
574    char c;
575    for (; (c = *v); ++v) {
576        if (isalnum(c)) {
577            small_type val;  // Numeric value of a char.
578
579            if (isalpha(c)) // Hex digit.
580                val = toupper(c) - 'A' + 10;
581            else
582                val = c - '0';
583
584            if (val >= b) {
585                std::stringstream msg;
586                msg << "vec_from_str( int, int, sc_digit*, const char*, " <<
587                       "sc_numrep base ) : '" << *v << "' is not a valid " <<
588                       "digit in base " << b;
589                SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_,
590                                msg.str().c_str());
591                return 0;
592            }
593
594            // digit = digit * b + val;
595            vec_mul_small_on(und, u, b);
596
597            if (val)
598                vec_add_small_on(und, u, val);
599        } else {
600            std::stringstream msg;
601            msg << "vec_from_str( int, int, sc_digit*, const char*, " <<
602                   "sc_numrep base ) : '" << *v << "' is not a valid " <<
603                   "digit in base " << b;
604            SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_,
605                            msg.str().c_str());
606            return 0;
607        }
608    }
609
610    return convert_signed_SM_to_2C_to_SM(s, unb, und, u);
611}
612
613
614// All vec_ functions assume that the vector to hold the result,
615// called w, has sufficient length to hold the result. For efficiency
616// reasons, we do not test whether or not we are out of bounds.
617
618// Compute w = u + v, where w, u, and v are vectors.
619// - ulen >= vlen
620// - wlen >= sc_max(ulen, vlen) + 1
621void
622vec_add(int ulen, const sc_digit *u, int vlen, const sc_digit *v, sc_digit *w)
623{
624#ifdef DEBUG_SYSTEMC
625    sc_assert((ulen > 0) && (u != NULL));
626    sc_assert((vlen > 0) && (v != NULL));
627    sc_assert(w != NULL);
628    sc_assert(ulen >= vlen);
629#endif
630
631    const sc_digit *uend = (u + ulen);
632    const sc_digit *vend = (v + vlen);
633
634    sc_digit carry = 0; // Also used as sum to save space.
635
636    // Add along the shorter v.
637    while (v < vend) {
638        carry += (*u++) + (*v++);
639        (*w++) = carry & DIGIT_MASK;
640        carry >>= BITS_PER_DIGIT;
641    }
642
643    // Propagate the carry.
644    while (carry && (u < uend)) {
645        carry = (*u++) + 1;
646        (*w++) = carry & DIGIT_MASK;
647        carry >>= BITS_PER_DIGIT;
648    }
649
650    // Copy the rest of u to the result.
651    while (u < uend)
652        (*w++) = (*u++);
653
654    // Propagate the carry if it is still 1.
655    if (carry)
656        (*w) = 1;
657}
658
659
660// Compute u += v, where u and v are vectors.
661// - ulen >= vlen
662void
663vec_add_on(int ulen, sc_digit *ubegin, int vlen, const sc_digit *v)
664{
665#ifdef DEBUG_SYSTEMC
666    sc_assert((ulen > 0) && (ubegin != NULL));
667    sc_assert((vlen > 0) && (v != NULL));
668    sc_assert(ulen >= vlen);
669#endif
670
671    sc_digit *u = ubegin;
672    const sc_digit *uend = (u + ulen);
673    const sc_digit *vend = (v + vlen);
674
675    sc_digit carry = 0; // Also used as sum to save space.
676
677    // Add along the shorter v.
678    while (v < vend) {
679        carry += (*u) + (*v++);
680        (*u++) = carry & DIGIT_MASK;
681        carry >>= BITS_PER_DIGIT;
682    }
683
684    // Propagate the carry.
685    while (carry && (u < uend)) {
686        carry = (*u) + 1;
687        (*u++) = carry & DIGIT_MASK;
688        carry >>= BITS_PER_DIGIT;
689    }
690
691#ifdef   DEBUG_SYSTEMC
692    if (carry != 0) {
693        SC_REPORT_WARNING(sc_core::SC_ID_WITHOUT_MESSAGE_,
694                          "vec_add_on( int, sc_digit*, int, const "
695                          "sc_digit* ) : "
696                          "result of addition is wrapped around");
697    }
698#endif
699}
700
701
702// Compute u += v, where u and v are vectors.
703// - ulen < vlen
704void
705vec_add_on2(int ulen, sc_digit *ubegin, int,
706#ifdef DEBUG_SYSTEMC
707            vlen,
708#endif
709            const sc_digit *v)
710{
711#ifdef DEBUG_SYSTEMC
712    sc_assert((ulen > 0) && (ubegin != NULL));
713    sc_assert((vlen > 0) && (v != NULL));
714    sc_assert(ulen < vlen);
715#endif
716
717    sc_digit *u = ubegin;
718    const sc_digit *uend = (u + ulen);
719
720    sc_digit carry = 0; // Also used as sum to save space.
721
722    // Add along the shorter u.
723    while (u < uend) {
724        carry += (*u) + (*v++);
725        (*u++) = carry & DIGIT_MASK;
726        carry >>= BITS_PER_DIGIT;
727    }
728
729#ifdef   DEBUG_SYSTEMC
730    if (carry != 0) {
731        SC_REPORT_WARNING(sc_core::SC_ID_WITHOUT_MESSAGE_,
732                          "vec_add_on2( int, sc_digit*, int, const "
733                          "sc_digit* ) : "
734                          "result of addition is wrapped around");
735    }
736#endif
737}
738
739
740// Compute w = u + v, where w and u are vectors, and v is a scalar.
741void
742vec_add_small(int ulen, const sc_digit *u, sc_digit v, sc_digit *w)
743{
744#ifdef DEBUG_SYSTEMC
745    sc_assert((ulen > 0) && (u != NULL));
746    sc_assert(w != NULL);
747#endif
748
749    const sc_digit *uend = (u + ulen);
750
751    // Add along the shorter v.
752    sc_digit carry = (*u++) + v;
753    (*w++) = carry & DIGIT_MASK;
754    carry >>= BITS_PER_DIGIT;
755
756    // Propagate the carry.
757    while (carry && (u < uend)) {
758        carry = (*u++) + 1;
759        (*w++) = carry & DIGIT_MASK;
760        carry >>= BITS_PER_DIGIT;
761    }
762
763    // Copy the rest of u to the result.
764    while (u < uend)
765        (*w++) = (*u++);
766
767    // Propagate the carry if it is still 1.
768    if (carry)
769        (*w) = 1;
770}
771
772// Compute u += v, where u is vectors, and v is a scalar.
773void
774vec_add_small_on(int ulen, sc_digit *u, sc_digit v)
775{
776#ifdef DEBUG_SYSTEMC
777    sc_assert((ulen > 0) && (u != NULL));
778#endif
779
780    int i = 0;
781
782    while (v && (i < ulen)) {
783        v += u[i];
784        u[i++] = v & DIGIT_MASK;
785        v >>= BITS_PER_DIGIT;
786    }
787
788#ifdef   DEBUG_SYSTEMC
789    if (v != 0) {
790        SC_REPORT_WARNING(sc_core::SC_ID_WITHOUT_MESSAGE_,
791                          "vec_add_small_on( int, sc_digit*, unsigned "
792                          "long ) : "
793                          "result of addition is wrapped around");
794    }
795#endif
796}
797
798// Compute w = u - v, where w, u, and v are vectors.
799// - ulen >= vlen
800// - wlen >= sc_max(ulen, vlen)
801void
802vec_sub(int ulen, const sc_digit *u, int vlen, const sc_digit *v, sc_digit *w)
803{
804#ifdef DEBUG_SYSTEMC
805    sc_assert((ulen > 0) && (u != NULL));
806    sc_assert((vlen > 0) && (v != NULL));
807    sc_assert(w != NULL);
808    sc_assert(ulen >= vlen);
809#endif
810
811    const sc_digit *uend = (u + ulen);
812    const sc_digit *vend = (v + vlen);
813
814    sc_digit borrow = 0; // Also used as diff to save space.
815
816    // Subtract along the shorter v.
817    while (v < vend) {
818        borrow = ((*u++) + DIGIT_RADIX) - (*v++) - borrow;
819        (*w++) = borrow & DIGIT_MASK;
820        borrow = 1 - (borrow >> BITS_PER_DIGIT);
821    }
822
823    // Propagate the borrow.
824    while (borrow && (u < uend)) {
825        borrow = ((*u++) + DIGIT_RADIX) - 1;
826        (*w++) = borrow & DIGIT_MASK;
827        borrow = 1 - (borrow >> BITS_PER_DIGIT);
828    }
829
830#ifdef DEBUG_SYSTEMC
831    sc_assert(borrow == 0);
832#endif
833
834    // Copy the rest of u to the result.
835    while (u < uend)
836        (*w++) = (*u++);
837}
838
839// Compute u = u - v, where u and v are vectors.
840// - u > v
841// - ulen >= vlen
842void
843vec_sub_on(int ulen, sc_digit *ubegin, int vlen, const sc_digit *v)
844{
845#ifdef DEBUG_SYSTEMC
846    sc_assert((ulen > 0) && (ubegin != NULL));
847    sc_assert((vlen > 0) && (v != NULL));
848    sc_assert(ulen >= vlen);
849#endif
850
851    sc_digit *u = ubegin;
852    const sc_digit *uend = (u + ulen);
853    const sc_digit *vend = (v + vlen);
854
855    sc_digit borrow = 0;   // Also used as diff to save space.
856
857    // Subtract along the shorter v.
858    while (v < vend) {
859        borrow = ((*u) + DIGIT_RADIX) - (*v++) - borrow;
860        (*u++) = borrow & DIGIT_MASK;
861        borrow = 1 - (borrow >> BITS_PER_DIGIT);
862    }
863
864    // Propagate the borrow.
865    while (borrow && (u < uend)) {
866        borrow = ((*u) + DIGIT_RADIX) - 1;
867        (*u++) = borrow & DIGIT_MASK;
868        borrow = 1 - (borrow >> BITS_PER_DIGIT);
869    }
870
871#ifdef DEBUG_SYSTEMC
872    sc_assert(borrow == 0);
873#endif
874}
875
876// Compute u = v - u, where u and v are vectors.
877// - v > u
878// - ulen <= vlen or ulen > ulen
879void
880vec_sub_on2(int ulen, sc_digit *ubegin, int vlen, const sc_digit *v)
881{
882#ifdef DEBUG_SYSTEMC
883    sc_assert((ulen > 0) && (ubegin != NULL));
884    sc_assert((vlen > 0) && (v != NULL));
885#endif
886
887    sc_digit *u = ubegin;
888    const sc_digit *uend = (u + sc_min(ulen, vlen));
889
890    sc_digit borrow = 0;   // Also used as diff to save space.
891
892    // Subtract along the shorter u.
893    while (u < uend) {
894        borrow = ((*v++) + DIGIT_RADIX) - (*u) - borrow;
895        (*u++) = borrow & DIGIT_MASK;
896        borrow = 1 - (borrow >> BITS_PER_DIGIT);
897    }
898
899#ifdef DEBUG_SYSTEMC
900    if (borrow != 0) {
901        SC_REPORT_WARNING(sc_core::SC_ID_WITHOUT_MESSAGE_,
902                          "vec_sub_on2( int, sc_digit*, int, const "
903                          "sc_digit* ) : "
904                          "result of subtraction is wrapped around");
905    }
906#endif
907}
908
909// Compute w = u - v, where w and u are vectors, and v is a scalar.
910void
911vec_sub_small(int ulen, const sc_digit *u, sc_digit v, sc_digit *w)
912{
913#ifdef DEBUG_SYSTEMC
914    sc_assert(ulen > 0);
915    sc_assert(u != NULL);
916#endif
917
918    const sc_digit *uend = (u + ulen);
919
920    // Add along the shorter v.
921    sc_digit borrow = ((*u++) + DIGIT_RADIX) - v;
922    (*w++) = borrow & DIGIT_MASK;
923    borrow = 1 - (borrow >> BITS_PER_DIGIT);
924
925    // Propagate the borrow.
926    while (borrow && (u < uend)) {
927        borrow = ((*u++) + DIGIT_RADIX) - 1;
928        (*w++) = borrow & DIGIT_MASK;
929        borrow = 1 - (borrow >> BITS_PER_DIGIT);
930    }
931
932#ifdef   DEBUG_SYSTEMC
933    sc_assert(borrow == 0);
934#endif
935
936    // Copy the rest of u to the result.
937    while (u < uend)
938        (*w++) = (*u++);
939}
940
941
942// Compute u -= v, where u is vectors, and v is a scalar.
943void
944vec_sub_small_on(int ulen, sc_digit *u, sc_digit v)
945{
946#ifdef DEBUG_SYSTEMC
947    sc_assert((ulen > 0) && (u != NULL));
948#endif
949
950    for (int i = 0; i < ulen; ++i) {
951      v = (u[i] + DIGIT_RADIX) - v;
952      u[i] = v & DIGIT_MASK;
953      v = 1 - (v >> BITS_PER_DIGIT);
954    }
955
956#ifdef DEBUG_SYSTEMC
957    sc_assert(v == 0);
958#endif
959}
960
961// Compute w = u * v, where w, u, and v are vectors.
962void
963vec_mul(int ulen, const sc_digit *u, int vlen, const sc_digit *vbegin,
964        sc_digit *wbegin)
965{
966
967  /* Consider u = Ax + B and v = Cx + D where x is equal to
968     HALF_DIGIT_RADIX. In other words, A is the higher half of u and
969     B is the lower half of u. The interpretation for v is
970     similar. Then, we have the following picture:
971
972              u_h     u_l
973     u: -------- --------
974               A        B
975
976              v_h     v_l
977     v: -------- --------
978               C        D
979
980     result (d):
981     carry_before:                           -------- --------
982                                              carry_h  carry_l
983     result_before:        -------- -------- -------- --------
984                               R1_h     R1_l     R0_h     R0_l
985                                             -------- --------
986                                                 BD_h     BD_l
987                                    -------- --------
988                                        AD_h     AD_l
989                                    -------- --------
990                                        BC_h     BC_l
991                           -------- --------
992                               AC_h     AC_l
993     result_after:         -------- -------- -------- --------
994                              R1_h'    R1_l'    R0_h'    R0_l'
995
996     prod_l = R0_h|R0_l + B * D  + 0|carry_l
997            = R0_h|R0_l + BD_h|BD_l + 0|carry_l
998
999     prod_h = A * D + B * C + high_half(prod_l) + carry_h
1000            = AD_h|AD_l + BC_h|BC_l + high_half(prod_l) + 0|carry_h
1001
1002     carry = A * C + high_half(prod_h)
1003           = AC_h|AC_l + high_half(prod_h)
1004
1005     R0_l' = low_half(prod_l)
1006
1007     R0_h' = low_half(prod_h)
1008
1009     R0 = high_half(prod_h)|low_half(prod_l)
1010
1011     where '|' is the concatenation operation and the suffixes 0 and 1
1012     show the iteration number, i.e., 0 is the current iteration and 1
1013     is the next iteration.
1014
1015     NOTE: sc_max(prod_l, prod_h, carry) <= 2 * x^2 - 1, so any
1016     of these numbers can be stored in a digit.
1017
1018     NOTE: low_half(u) returns the lower BITS_PER_HALF_DIGIT of u,
1019     whereas high_half(u) returns the rest of the bits, which may
1020     contain more bits than BITS_PER_HALF_DIGIT.
1021  */
1022
1023#ifdef DEBUG_SYSTEMC
1024    sc_assert((ulen > 0) && (u != NULL));
1025    sc_assert((vlen > 0) && (vbegin != NULL));
1026    sc_assert(wbegin != NULL);
1027#endif
1028
1029#define prod_h carry
1030    const sc_digit *uend = (u + ulen);
1031    const sc_digit *vend = (vbegin + vlen);
1032
1033    while (u < uend) {
1034        sc_digit u_h = (*u++); // A|B
1035        sc_digit u_l = low_half(u_h); // B
1036        u_h = high_half(u_h); // A
1037
1038#ifdef DEBUG_SYSTEMC
1039        // The overflow bits must be zero.
1040        sc_assert(u_h == (u_h & HALF_DIGIT_MASK));
1041#endif
1042        sc_digit carry = 0;
1043        sc_digit *w = (wbegin++);
1044        const sc_digit *v = vbegin;
1045
1046        while (v < vend) {
1047            sc_digit v_h = (*v++); // C|D
1048            sc_digit v_l = low_half(v_h); // D
1049
1050            v_h = high_half(v_h); // C
1051
1052#ifdef   DEBUG_SYSTEMC
1053            // The overflow bits must be zero.
1054            sc_assert(v_h == (v_h & HALF_DIGIT_MASK));
1055#endif
1056
1057            sc_digit prod_l = (*w) + u_l * v_l + low_half(carry);
1058            prod_h = u_h * v_l + u_l * v_h +
1059                high_half(prod_l) + high_half(carry);
1060            (*w++) = concat(low_half(prod_h), low_half(prod_l));
1061            carry = u_h * v_h + high_half(prod_h);
1062        }
1063        (*w) = carry;
1064    }
1065#undef prod_h
1066}
1067
1068// Compute w = u * v, where w and u are vectors, and v is a scalar.
1069// - 0 < v < HALF_DIGIT_RADIX.
1070void
1071vec_mul_small(int ulen, const sc_digit *u, sc_digit v, sc_digit *w)
1072{
1073#ifdef DEBUG_SYSTEMC
1074    sc_assert((ulen > 0) && (u != NULL));
1075    sc_assert(w != NULL);
1076    sc_assert((0 < v) && (v < HALF_DIGIT_RADIX));
1077#endif
1078
1079#define prod_h carry
1080
1081    const sc_digit *uend = (u + ulen);
1082    sc_digit carry = 0;
1083    while (u < uend) {
1084        sc_digit u_AB = (*u++);
1085#ifdef DEBUG_SYSTEMC
1086        // The overflow bits must be zero.
1087        sc_assert(high_half(u_AB) == high_half_masked(u_AB));
1088#endif
1089        sc_digit prod_l = v * low_half(u_AB) + low_half(carry);
1090        prod_h = v * high_half(u_AB) + high_half(prod_l) + high_half(carry);
1091        (*w++) = concat(low_half(prod_h), low_half(prod_l));
1092        carry = high_half(prod_h);
1093    }
1094    (*w) = carry;
1095#undef prod_h
1096}
1097
1098// Compute u = u * v, where u is a vector, and v is a scalar.
1099// - 0 < v < HALF_DIGIT_RADIX.
1100void
1101vec_mul_small_on(int ulen, sc_digit *u, sc_digit v)
1102{
1103#ifdef DEBUG_SYSTEMC
1104    sc_assert((ulen > 0) && (u != NULL));
1105    sc_assert((0 < v) && (v < HALF_DIGIT_RADIX));
1106#endif
1107
1108#define   prod_h carry
1109    sc_digit carry = 0;
1110    for (int i = 0; i < ulen; ++i) {
1111#ifdef DEBUG_SYSTEMC
1112        // The overflow bits must be zero.
1113        sc_assert(high_half(u[i]) == high_half_masked(u[i]));
1114#endif
1115        sc_digit prod_l = v * low_half(u[i]) + low_half(carry);
1116        prod_h = v * high_half(u[i]) + high_half(prod_l) + high_half(carry);
1117        u[i] = concat(low_half(prod_h), low_half(prod_l));
1118        carry = high_half(prod_h);
1119    }
1120#undef   prod_h
1121
1122#ifdef   DEBUG_SYSTEMC
1123    if (carry != 0) {
1124        SC_REPORT_WARNING(sc_core::SC_ID_WITHOUT_MESSAGE_,
1125                          "vec_mul_small_on( int, sc_digit*, unsigned "
1126                          "long ) : "
1127                          "result of multiplication is wrapped around");
1128    }
1129#endif
1130}
1131
1132// Compute w = u / v, where w, u, and v are vectors.
1133// - u and v are assumed to have at least two digits as uchars.
1134void
1135vec_div_large(int ulen, const sc_digit *u, int vlen, const sc_digit *v,
1136              sc_digit *w)
1137{
1138#ifdef DEBUG_SYSTEMC
1139    sc_assert((ulen > 0) && (u != NULL));
1140    sc_assert((vlen > 0) && (v != NULL));
1141    sc_assert(w != NULL);
1142    sc_assert(BITS_PER_DIGIT >= 3 * BITS_PER_BYTE);
1143#endif
1144
1145    // We will compute q = x / y where x = u and y = v. The reason for
1146    // using x and y is that x and y are BYTE_RADIX copies of u and v,
1147    // respectively. The use of BYTE_RADIX radix greatly simplifies the
1148    // complexity of the division operation. These copies are also
1149    // needed even when we use DIGIT_RADIX representation.
1150
1151    int xlen = BYTES_PER_DIGIT * ulen + 1;
1152    int ylen = BYTES_PER_DIGIT * vlen;
1153
1154#ifdef SC_MAX_NBITS
1155    uchar x[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
1156    uchar y[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
1157    uchar q[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
1158#else
1159    uchar *x = new uchar[xlen];
1160    uchar *y = new uchar[ylen];
1161    // valgrind complains about us accessing too far to so leave a buffer.
1162    uchar *q = new uchar[(xlen - ylen) + 10];
1163#endif
1164
1165    // q corresponds to w.
1166
1167    // Set (uchar) x = (sc_digit) u.
1168    xlen = vec_to_char(ulen, u, xlen, x);
1169
1170    // Skip all the leading zeros in x.
1171    while ((--xlen >= 0) && (! x[xlen]))
1172        continue;
1173    xlen++;
1174
1175    // Set (uchar) y = (sc_digit) v.
1176    ylen = vec_to_char(vlen, v, ylen, y);
1177
1178    // Skip all the leading zeros in y.
1179    while ((--ylen >= 0) && (! y[ylen]))
1180        continue;
1181    ylen++;
1182
1183#ifdef DEBUG_SYSTEMC
1184    sc_assert(xlen > 1);
1185    sc_assert(ylen > 1);
1186#endif
1187
1188    // At this point, all the leading zeros are eliminated from x and y.
1189
1190    // Zero the last digit of x.
1191    x[xlen] = 0;
1192
1193    // The first two digits of y.
1194    sc_digit y2 = (y[ylen - 1] << BITS_PER_BYTE) + y[ylen - 2];
1195
1196    const sc_digit DOUBLE_BITS_PER_BYTE = 2 * BITS_PER_BYTE;
1197
1198    // Find each q[k].
1199    for (int k = (xlen - ylen); k >= 0; --k) {
1200        // qk is a guess for q[k] such that q[k] = qk or qk - 1.
1201        sc_digit qk;
1202
1203        // Find qk by just using 2 digits of y and 3 digits of x. The
1204        // following code assumes that sizeof(sc_digit) >= 3 BYTEs.
1205        int k2 = k + ylen;
1206
1207        qk = ((x[k2] << DOUBLE_BITS_PER_BYTE) +
1208              (x[k2 - 1] << BITS_PER_BYTE) + x[k2 - 2]) / y2;
1209
1210        if (qk >= BYTE_RADIX) // qk cannot be larger than the largest
1211            qk = BYTE_RADIX - 1; // digit in BYTE_RADIX.
1212
1213        // q[k] = qk or qk - 1. The following if-statement determines which:
1214        if (qk) {
1215            uchar *xk = (x + k);  // A shortcut for x[k].
1216
1217            // x = x - y * qk :
1218            sc_digit carry = 0;
1219
1220            for (int i = 0; i < ylen; ++i) {
1221                carry += y[i] * qk;
1222                sc_digit diff = (xk[i] + BYTE_RADIX) - (carry & BYTE_MASK);
1223                xk[i] = (uchar)(diff & BYTE_MASK);
1224                carry = (carry >> BITS_PER_BYTE) +
1225                    (1 - (diff >> BITS_PER_BYTE));
1226            }
1227
1228            // If carry, qk may be one too large.
1229            if (carry) {
1230                // 2's complement the last digit.
1231                carry = (xk[ylen] + BYTE_RADIX) - carry;
1232                xk[ylen] = (uchar)(carry & BYTE_MASK);
1233                carry = 1 - (carry >> BITS_PER_BYTE);
1234
1235                if (carry) {
1236
1237                  // qk was one too large, so decrement it.
1238                  --qk;
1239
1240                  // Since qk was decreased by one, y must be added to x:
1241                  // x = x - y * (qk - 1) = x - y * qk + y = x_above + y.
1242                  carry = 0;
1243
1244                  for (int i = 0; i < ylen; ++i) {
1245                      carry += xk[i] + y[i];
1246                      xk[i] = (uchar)(carry & BYTE_MASK);
1247                      carry >>= BITS_PER_BYTE;
1248                  }
1249
1250                  if (carry)
1251                      xk[ylen] = (uchar)((xk[ylen] + 1) & BYTE_MASK);
1252
1253                }  // second if carry
1254            }  // first if carry
1255        }  // if qk
1256        q[k] = (uchar)qk;
1257    }  // for k
1258
1259    // Set (sc_digit) w = (uchar) q.
1260    vec_from_char(xlen - ylen + 1, q, ulen, w);
1261
1262#ifndef SC_MAX_NBITS
1263    delete [] x;
1264    delete [] y;
1265    delete [] q;
1266#endif
1267
1268}
1269
1270// Compute w = u / v, where u and w are vectors, and v is a scalar.
1271// - 0 < v < HALF_DIGIT_RADIX. Below, we rename w to q.
1272void
1273vec_div_small(int ulen, const sc_digit *u, sc_digit v, sc_digit *q)
1274{
1275    // Given (u = u_1u_2...u_n)_b = (q = q_1q_2...q_n) * v + r, where b
1276    // is the base, and 0 <= r < v. Then, the algorithm is as follows:
1277    //
1278    // r = 0;
1279    // for (j = 1; j <= n; j++) {
1280    //   q_j = (r * b + u_j) / v;
1281    //   r = (r * b + u_j) % v;
1282    // }
1283    //
1284    // In our case, b = DIGIT_RADIX, and u = Ax + B and q = Cx + D where
1285    // x = HALF_DIGIT_RADIX. Note that r < v < x and b = x^2. Then, a
1286    // typical situation is as follows:
1287    //
1288    // ---- ----
1289    // 0    r
1290    //           ---- ----
1291    //           A    B
1292    //      ---- ---- ----
1293    //      r    A    B     = r * b + u
1294    //
1295    // Hence, C = (r|A) / v.
1296    //        D = (((r|A) % v)|B) / v
1297    //        r = (((r|A) % v)|B) % v
1298
1299#ifdef DEBUG_SYSTEMC
1300    sc_assert((ulen > 0) && (u != NULL));
1301    sc_assert(q != NULL);
1302    sc_assert((0 < v) && (v < HALF_DIGIT_RADIX));
1303#endif
1304
1305#define q_h r
1306    sc_digit r = 0;
1307    const sc_digit *ubegin = u;
1308
1309    u += ulen;
1310    q += ulen;
1311
1312    while (ubegin < u) {
1313        sc_digit u_AB = (*--u); // A|B
1314
1315#ifdef DEBUG_SYSTEMC
1316        // The overflow bits must be zero.
1317        sc_assert(high_half(u_AB) == high_half_masked(u_AB));
1318#endif
1319
1320        sc_digit num = concat(r, high_half(u_AB)); // num = r|A
1321        q_h = num / v; // C
1322        num = concat((num % v), low_half(u_AB)); // num = (((r|A) % v)|B)
1323        (*--q) = concat(q_h, num / v); // q = C|D
1324        r = num % v;
1325    }
1326#undef q_h
1327}
1328
1329// Compute w = u % v, where w, u, and v are vectors.
1330// - u and v are assumed to have at least two digits as uchars.
1331void
1332vec_rem_large(int ulen, const sc_digit *u, int vlen, const sc_digit *v,
1333              sc_digit *w)
1334{
1335#ifdef DEBUG_SYSTEMC
1336    sc_assert((ulen > 0) && (u != NULL));
1337    sc_assert((vlen > 0) && (v != NULL));
1338    sc_assert(w != NULL);
1339    sc_assert(BITS_PER_DIGIT >= 3 * BITS_PER_BYTE);
1340#endif
1341
1342    // This function is adapted from vec_div_large.
1343    int xlen = BYTES_PER_DIGIT * ulen + 1;
1344    int ylen = BYTES_PER_DIGIT * vlen;
1345
1346#ifdef SC_MAX_NBITS
1347    uchar x[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
1348    uchar y[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
1349#else
1350    uchar *x = new uchar[xlen];
1351    uchar *y = new uchar[ylen];
1352#endif
1353
1354    // r corresponds to w.
1355
1356    // Set (uchar) x = (sc_digit) u.
1357    xlen = vec_to_char(ulen, u, xlen, x);
1358
1359    // Skip all the leading zeros in x.
1360    while ((--xlen >= 0) && (!x[xlen]))
1361        continue;
1362    xlen++;
1363
1364    // Set (uchar) y = (sc_digit) v.
1365    ylen = vec_to_char(vlen, v, ylen, y);
1366
1367    // Skip all the leading zeros in y.
1368    while ((--ylen >= 0) && (!y[ylen]))
1369        continue;
1370    ylen++;
1371
1372#ifdef DEBUG_SYSTEMC
1373    sc_assert(xlen > 1);
1374    sc_assert(ylen > 1);
1375#endif
1376
1377    // At this point, all the leading zeros are eliminated from x and y.
1378
1379    // Zero the last digit of x.
1380    x[xlen] = 0;
1381
1382    // The first two digits of y.
1383    sc_digit y2 = (y[ylen - 1] << BITS_PER_BYTE) + y[ylen - 2];
1384
1385    const sc_digit DOUBLE_BITS_PER_BYTE = 2 * BITS_PER_BYTE;
1386
1387    // Find each q[k].
1388    for (int k = xlen - ylen; k >= 0; --k) {
1389        // qk is a guess for q[k] such that q[k] = qk or qk - 1.
1390        sc_digit qk;
1391
1392        // Find qk by just using 2 digits of y and 3 digits of x. The
1393        // following code assumes that sizeof(sc_digit) >= 3 BYTEs.
1394        int k2 = k + ylen;
1395
1396        qk = ((x[k2] << DOUBLE_BITS_PER_BYTE) +
1397            (x[k2 - 1] << BITS_PER_BYTE) + x[k2 - 2]) / y2;
1398
1399        if (qk >= BYTE_RADIX) // qk cannot be larger than the largest
1400            qk = BYTE_RADIX - 1; // digit in BYTE_RADIX.
1401
1402        // q[k] = qk or qk - 1. The following if-statement determines which.
1403        if (qk) {
1404            uchar *xk = (x + k);  // A shortcut for x[k].
1405
1406            // x = x - y * qk;
1407            sc_digit carry = 0;
1408
1409            for (int i = 0; i < ylen; ++i) {
1410                carry += y[i] * qk;
1411                sc_digit diff = (xk[i] + BYTE_RADIX) - (carry & BYTE_MASK);
1412                xk[i] = (uchar)(diff & BYTE_MASK);
1413                carry = (carry >> BITS_PER_BYTE) +
1414                    (1 - (diff >> BITS_PER_BYTE));
1415            }
1416
1417            if (carry) {
1418                // 2's complement the last digit.
1419                carry = (xk[ylen] + BYTE_RADIX) - carry;
1420                xk[ylen] = (uchar)(carry & BYTE_MASK);
1421                carry = 1 - (carry >> BITS_PER_BYTE);
1422
1423                if (carry) {
1424                  // qk was one too large, so decrement it.
1425                  // --qk;
1426
1427                  // x = x - y * (qk - 1) = x - y * qk + y = x_above + y.
1428                  carry = 0;
1429
1430                  for (int i = 0; i < ylen; ++i) {
1431                      carry += xk[i] + y[i];
1432                      xk[i] = (uchar)(carry & BYTE_MASK);
1433                      carry >>= BITS_PER_BYTE;
1434                  }
1435
1436                  if (carry)
1437                      xk[ylen] = (uchar)((xk[ylen] + 1) & BYTE_MASK);
1438                }  // second if carry
1439            } // first if carry
1440        }  // if qk
1441    }  // for k
1442
1443    // Set (sc_digit) w = (uchar) x for the remainder.
1444    vec_from_char(ylen, x, ulen, w);
1445
1446#ifndef SC_MAX_NBITS
1447    delete [] x;
1448    delete [] y;
1449#endif
1450
1451}
1452
1453// Compute r = u % v, where u is a vector, and r and v are scalars.
1454// - 0 < v < HALF_DIGIT_RADIX.
1455// - The remainder r is returned.
1456sc_digit
1457vec_rem_small(int ulen, const sc_digit *u, sc_digit v)
1458{
1459
1460#ifdef DEBUG_SYSTEMC
1461    sc_assert((ulen > 0) && (u != NULL));
1462    sc_assert((0 < v) && (v < HALF_DIGIT_RADIX));
1463#endif
1464
1465    // This function is adapted from vec_div_small().
1466
1467    sc_digit r = 0;
1468    const sc_digit *ubegin = u;
1469
1470    u += ulen;
1471
1472    while (ubegin < u) {
1473        sc_digit u_AB = (*--u); // A|B
1474#ifdef DEBUG_SYSTEMC
1475        // The overflow bits must be zero.
1476        sc_assert(high_half(u_AB) == high_half_masked(u_AB));
1477#endif
1478        // r = (((r|A) % v)|B) % v
1479        r = (concat(((concat(r, high_half(u_AB))) % v), low_half(u_AB))) % v;
1480    }
1481
1482    return r;
1483}
1484
1485// u = u / v, r = u % v.
1486sc_digit
1487vec_rem_on_small(int ulen, sc_digit *u, sc_digit v)
1488{
1489#ifdef DEBUG_SYSTEMC
1490    sc_assert((ulen > 0) && (u != NULL));
1491    sc_assert(v > 0);
1492#endif
1493
1494#define q_h r
1495    sc_digit r = 0;
1496    const sc_digit *ubegin = u;
1497
1498    u += ulen;
1499    while (ubegin < u) {
1500        sc_digit u_AB = (*--u); // A|B
1501#ifdef DEBUG_SYSTEMC
1502        // The overflow bits must be zero.
1503        sc_assert(high_half(u_AB) == high_half_masked(u_AB));
1504#endif
1505        sc_digit num = concat(r, high_half(u_AB)); // num = r|A
1506        q_h = num / v; // C
1507        num = concat((num % v), low_half(u_AB)); // num = (((r|A) % v)|B)
1508        (*u) = concat(q_h, num / v); // q = C|D
1509        r = num % v;
1510    }
1511#undef q_h
1512    return r;
1513}
1514
1515// Set (uchar) v = (sc_digit) u. Return the new vlen.
1516int
1517vec_to_char(int ulen, const sc_digit *u, int vlen, uchar *v)
1518{
1519#ifdef DEBUG_SYSTEMC
1520    sc_assert((ulen > 0) && (u != NULL));
1521    sc_assert((vlen > 0) && (v != NULL));
1522#endif
1523
1524    int nbits = ulen * BITS_PER_DIGIT;
1525    int right = 0;
1526    int left = right + BITS_PER_BYTE - 1;
1527
1528    vlen = 0;
1529    while (nbits > 0) {
1530        int left_digit = left / BITS_PER_DIGIT;
1531        int right_digit = right / BITS_PER_DIGIT;
1532        int nsr = ((vlen << LOG2_BITS_PER_BYTE) % BITS_PER_DIGIT);
1533        int d = u[right_digit] >> nsr;
1534
1535        if (left_digit != right_digit) {
1536            if (left_digit < ulen)
1537                d |= u[left_digit] << (BITS_PER_DIGIT - nsr);
1538        }
1539
1540        v[vlen++] = (uchar)(d & BYTE_MASK);
1541
1542        left += BITS_PER_BYTE;
1543        right += BITS_PER_BYTE;
1544        nbits -= BITS_PER_BYTE;
1545    }
1546    return vlen;
1547}
1548
1549// Set (sc_digit) v = (uchar) u.
1550// - sizeof(uchar) <= sizeof(sc_digit),
1551void
1552vec_from_char(int ulen, const uchar *u, int vlen, sc_digit *v)
1553{
1554#ifdef DEBUG_SYSTEMC
1555    sc_assert((ulen > 0) && (u != NULL));
1556    sc_assert((vlen > 0) && (v != NULL));
1557    sc_assert(sizeof(uchar) <= sizeof(sc_digit));
1558#endif
1559
1560    sc_digit *vend = (v + vlen);
1561
1562    const int nsr = BITS_PER_DIGIT - BITS_PER_BYTE;
1563    const sc_digit mask = one_and_ones(nsr);
1564
1565    (*v) = (sc_digit) u[ulen - 1];
1566
1567    for (int i = ulen - 2; i >= 0; --i) {
1568        // Manual inlining of vec_shift_left().
1569        sc_digit *viter = v;
1570        sc_digit carry = 0;
1571        while (viter < vend) {
1572            sc_digit vval = (*viter);
1573            (*viter++) = (((vval & mask) << BITS_PER_BYTE) | carry);
1574            carry = vval >> nsr;
1575        }
1576
1577        if (viter < vend)
1578            (*viter) = carry;
1579
1580        (*v) |= (sc_digit)u[i];
1581    }
1582}
1583
1584// Set u <<= nsl.
1585// If nsl is negative, it is ignored.
1586void
1587vec_shift_left(int ulen, sc_digit *u, int nsl)
1588{
1589#ifdef DEBUG_SYSTEMC
1590    sc_assert((ulen > 0) && (u != NULL));
1591#endif
1592
1593    if (nsl <= 0)
1594        return;
1595
1596    // Shift left whole digits if nsl is large enough.
1597    if (nsl >= (int) BITS_PER_DIGIT) {
1598        int nd;
1599        if (nsl % BITS_PER_DIGIT == 0) {
1600            nd = nsl / BITS_PER_DIGIT; // No need to use DIV_CEIL(nsl).
1601            nsl = 0;
1602        } else {
1603            nd = DIV_CEIL(nsl) - 1;
1604            nsl -= nd * BITS_PER_DIGIT;
1605        }
1606
1607        if (nd) {
1608            // Shift left for nd digits.
1609            for (int j = ulen - 1; j >= nd; --j)
1610                u[j] = u[j - nd];
1611
1612            vec_zero(sc_min(nd, ulen), u);
1613        }
1614        if (nsl == 0)
1615            return;
1616    }
1617
1618    // Shift left if nsl < BITS_PER_DIGIT.
1619    sc_digit *uiter = u;
1620    sc_digit *uend = uiter + ulen;
1621
1622    int nsr = BITS_PER_DIGIT - nsl;
1623    sc_digit mask = one_and_ones(nsr);
1624
1625    sc_digit carry = 0;
1626
1627    while (uiter < uend) {
1628        sc_digit uval = (*uiter);
1629        (*uiter++) = (((uval & mask) << nsl) | carry);
1630        carry = uval >> nsr;
1631    }
1632
1633    if (uiter < uend)
1634        (*uiter) = carry;
1635}
1636
1637// Set u >>= nsr.
1638// If nsr is negative, it is ignored.
1639void
1640vec_shift_right(int ulen, sc_digit *u, int nsr, sc_digit fill)
1641{
1642#ifdef DEBUG_SYSTEMC
1643    sc_assert((ulen > 0) && (u != NULL));
1644#endif
1645
1646    // fill is usually either 0 or DIGIT_MASK; it can be any value.
1647    if (nsr <= 0)
1648        return;
1649
1650    // Shift right whole digits if nsr is large enough.
1651    if (nsr >= (int) BITS_PER_DIGIT) {
1652        int nd;
1653        if (nsr % BITS_PER_DIGIT == 0) {
1654            nd = nsr / BITS_PER_DIGIT;
1655            nsr = 0;
1656        } else {
1657            nd = DIV_CEIL(nsr) - 1;
1658            nsr -= nd * BITS_PER_DIGIT;
1659        }
1660
1661        if (nd) {
1662            // Shift right for nd digits.
1663            for (int j = 0; j < (ulen - nd); ++j)
1664                u[j] = u[j + nd];
1665
1666            if (fill) {
1667                for (int j = ulen - sc_min( nd, ulen ); j < ulen; ++j)
1668                    u[j] = fill;
1669            } else {
1670                vec_zero(ulen - sc_min( nd, ulen ), ulen, u);
1671            }
1672        }
1673        if (nsr == 0)
1674          return;
1675    }
1676
1677    // Shift right if nsr < BITS_PER_DIGIT.
1678    sc_digit *ubegin = u;
1679    sc_digit *uiter = (ubegin + ulen);
1680
1681    int nsl = BITS_PER_DIGIT - nsr;
1682    sc_digit mask = one_and_ones(nsr);
1683
1684    sc_digit carry = (fill & mask) << nsl;
1685
1686    while (ubegin < uiter) {
1687        sc_digit uval = (*--uiter);
1688        (*uiter) = (uval >> nsr) | carry;
1689        carry = (uval & mask) << nsl;
1690    }
1691}
1692
1693
1694// Let u[l..r], where l and r are left and right bit positions
1695// respectively, be equal to its mirror image.
1696void
1697vec_reverse(int unb, int und, sc_digit *ud, int l, int r)
1698{
1699#ifdef DEBUG_SYSTEMC
1700    sc_assert((unb > 0) && (und > 0) && (ud != NULL));
1701    sc_assert((0 <= r) && (r <= l) && (l < unb));
1702#endif
1703
1704    if (l < r) {
1705        std::stringstream msg;
1706        msg << "vec_reverse( int, int, sc_digit*, int l, int r ) : " <<
1707               "l = " << l << " < r = " << r << " is not valid",
1708        SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_, msg.str().c_str());
1709        return;
1710    }
1711
1712    // Make sure that l and r are within bounds.
1713    r = sc_max(r, 0);
1714    l = sc_min(l, unb - 1);
1715
1716    // Allocate memory for processing.
1717#ifdef SC_MAX_NBITS
1718    sc_digit d[MAX_NDIGITS];
1719#else
1720    sc_digit *d = new sc_digit[und];
1721#endif
1722
1723    // d is a copy of ud.
1724    vec_copy(und, d, ud);
1725
1726    // Based on the value of the ith in d, find the value of the jth bit
1727    // in ud.
1728    for (int i = l, j = r; i >= r; --i, ++j) {
1729        if ((d[digit_ord(i)] & one_and_zeros(bit_ord(i))) != 0) // Test.
1730            ud[digit_ord(j)] |= one_and_zeros(bit_ord(j)); // Set.
1731        else
1732            ud[digit_ord(j)] &= ~(one_and_zeros(bit_ord(j))); // Clear.
1733    }
1734
1735#ifndef SC_MAX_NBITS
1736    delete [] d;
1737#endif
1738}
1739
1740#ifdef SC_MAX_NBITS
1741void test_bound_failed(int nb)
1742{
1743    std::stringstream msg;
1744    msg << "test_bound( int nb ) : "
1745           "nb = " << nb << " > SC_MAX_NBITS = " << SC_MAX_NBITS <<
1746           "  is not valid";
1747    SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, msg.str().c_str());
1748}
1749#endif // SC_MAX_NBITS
1750
1751} // namespace sc_dt
1752