112027Sjungma@eit.uni-kl.de/*****************************************************************************
212027Sjungma@eit.uni-kl.de
312027Sjungma@eit.uni-kl.de  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
412027Sjungma@eit.uni-kl.de  more contributor license agreements.  See the NOTICE file distributed
512027Sjungma@eit.uni-kl.de  with this work for additional information regarding copyright ownership.
612027Sjungma@eit.uni-kl.de  Accellera licenses this file to you under the Apache License, Version 2.0
712027Sjungma@eit.uni-kl.de  (the "License"); you may not use this file except in compliance with the
812027Sjungma@eit.uni-kl.de  License.  You may obtain a copy of the License at
912027Sjungma@eit.uni-kl.de
1012027Sjungma@eit.uni-kl.de    http://www.apache.org/licenses/LICENSE-2.0
1112027Sjungma@eit.uni-kl.de
1212027Sjungma@eit.uni-kl.de  Unless required by applicable law or agreed to in writing, software
1312027Sjungma@eit.uni-kl.de  distributed under the License is distributed on an "AS IS" BASIS,
1412027Sjungma@eit.uni-kl.de  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1512027Sjungma@eit.uni-kl.de  implied.  See the License for the specific language governing
1612027Sjungma@eit.uni-kl.de  permissions and limitations under the License.
1712027Sjungma@eit.uni-kl.de
1812027Sjungma@eit.uni-kl.de *****************************************************************************/
1912027Sjungma@eit.uni-kl.de
2012027Sjungma@eit.uni-kl.de/*****************************************************************************
2112027Sjungma@eit.uni-kl.de
2212027Sjungma@eit.uni-kl.de  sc_nbutils.cpp -- External and friend functions for both sc_signed and
2312027Sjungma@eit.uni-kl.de                    sc_unsigned classes.
2412027Sjungma@eit.uni-kl.de
2512027Sjungma@eit.uni-kl.de  Original Author: Ali Dasdan, Synopsys, Inc.
2612027Sjungma@eit.uni-kl.de
2712027Sjungma@eit.uni-kl.de *****************************************************************************/
2812027Sjungma@eit.uni-kl.de
2912027Sjungma@eit.uni-kl.de/*****************************************************************************
3012027Sjungma@eit.uni-kl.de
3112027Sjungma@eit.uni-kl.de  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
3212027Sjungma@eit.uni-kl.de  changes you are making here.
3312027Sjungma@eit.uni-kl.de
3412027Sjungma@eit.uni-kl.de      Name, Affiliation, Date:
3512027Sjungma@eit.uni-kl.de  Description of Modification:
3612027Sjungma@eit.uni-kl.de
3712027Sjungma@eit.uni-kl.de *****************************************************************************/
3812027Sjungma@eit.uni-kl.de
3912027Sjungma@eit.uni-kl.de
4012027Sjungma@eit.uni-kl.de// $Log: sc_nbutils.cpp,v $
4112027Sjungma@eit.uni-kl.de// Revision 1.4  2011/08/24 22:05:46  acg
4212027Sjungma@eit.uni-kl.de//  Torsten Maehne: initialization changes to remove warnings.
4312027Sjungma@eit.uni-kl.de//
4412027Sjungma@eit.uni-kl.de// Revision 1.3  2011/02/18 20:19:15  acg
4512027Sjungma@eit.uni-kl.de//  Andy Goodrich: updating Copyright notice.
4612027Sjungma@eit.uni-kl.de//
4712027Sjungma@eit.uni-kl.de// Revision 1.2  2007/11/04 21:26:40  acg
4812027Sjungma@eit.uni-kl.de//  Andy Goodrich: added a buffer to the allocation of the q array to address
4912027Sjungma@eit.uni-kl.de//  an issue with references outside the array by 1 byte detected by valgrind.
5012027Sjungma@eit.uni-kl.de//
5112027Sjungma@eit.uni-kl.de// Revision 1.1.1.1  2006/12/15 20:20:05  acg
5212027Sjungma@eit.uni-kl.de// SystemC 2.3
5312027Sjungma@eit.uni-kl.de//
5412027Sjungma@eit.uni-kl.de// Revision 1.3  2006/01/13 18:49:32  acg
5512027Sjungma@eit.uni-kl.de// Added $Log command so that CVS check in comments are reproduced in the
5612027Sjungma@eit.uni-kl.de// source.
5712027Sjungma@eit.uni-kl.de//
5812027Sjungma@eit.uni-kl.de
5912027Sjungma@eit.uni-kl.de#include <ctype.h>
6012027Sjungma@eit.uni-kl.de#include <cstdio>
6112027Sjungma@eit.uni-kl.de#include <string.h>
6212027Sjungma@eit.uni-kl.de
6312027Sjungma@eit.uni-kl.de#include "sysc/datatypes/int/sc_int_ids.h"
6412027Sjungma@eit.uni-kl.de#include "sysc/datatypes/int/sc_nbutils.h"
6512027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_macros.h"
6612027Sjungma@eit.uni-kl.de
6712027Sjungma@eit.uni-kl.de
6812027Sjungma@eit.uni-kl.denamespace sc_dt
6912027Sjungma@eit.uni-kl.de{
7012027Sjungma@eit.uni-kl.de
7112027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
7212027Sjungma@eit.uni-kl.de//  ENUM : sc_numrep
7312027Sjungma@eit.uni-kl.de//
7412027Sjungma@eit.uni-kl.de//  Enumeration of number representations for character string conversion.
7512027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
7612027Sjungma@eit.uni-kl.de
7712027Sjungma@eit.uni-kl.deconst std::string
7812027Sjungma@eit.uni-kl.deto_string( sc_numrep numrep )
7912027Sjungma@eit.uni-kl.de{
8012027Sjungma@eit.uni-kl.de    switch( numrep )
8112027Sjungma@eit.uni-kl.de    {
8212027Sjungma@eit.uni-kl.de#   define CASE_ENUM2STR( Value ) \
8312027Sjungma@eit.uni-kl.de      case Value: return #Value
8412027Sjungma@eit.uni-kl.de
8512027Sjungma@eit.uni-kl.de      CASE_ENUM2STR(SC_DEC);
8612027Sjungma@eit.uni-kl.de
8712027Sjungma@eit.uni-kl.de      CASE_ENUM2STR(SC_BIN);
8812027Sjungma@eit.uni-kl.de      CASE_ENUM2STR(SC_BIN_US);
8912027Sjungma@eit.uni-kl.de      CASE_ENUM2STR(SC_BIN_SM);
9012027Sjungma@eit.uni-kl.de
9112027Sjungma@eit.uni-kl.de      CASE_ENUM2STR(SC_OCT);
9212027Sjungma@eit.uni-kl.de      CASE_ENUM2STR(SC_OCT_US);
9312027Sjungma@eit.uni-kl.de      CASE_ENUM2STR(SC_OCT_SM);
9412027Sjungma@eit.uni-kl.de
9512027Sjungma@eit.uni-kl.de      CASE_ENUM2STR(SC_HEX);
9612027Sjungma@eit.uni-kl.de      CASE_ENUM2STR(SC_HEX_US);
9712027Sjungma@eit.uni-kl.de      CASE_ENUM2STR(SC_HEX_SM);
9812027Sjungma@eit.uni-kl.de
9912027Sjungma@eit.uni-kl.de      CASE_ENUM2STR(SC_CSD);
10012027Sjungma@eit.uni-kl.de
10112027Sjungma@eit.uni-kl.de#   undef CASE_ENUM2STR
10212027Sjungma@eit.uni-kl.de
10312027Sjungma@eit.uni-kl.de    default:
10412027Sjungma@eit.uni-kl.de      return "unknown";
10512027Sjungma@eit.uni-kl.de    }
10612027Sjungma@eit.uni-kl.de}
10712027Sjungma@eit.uni-kl.de
10812027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
10912027Sjungma@eit.uni-kl.de//  SECTION: General utility functions.
11012027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
11112027Sjungma@eit.uni-kl.de
11212027Sjungma@eit.uni-kl.de// Return the number of characters to advance the source of c.  This
11312027Sjungma@eit.uni-kl.de// function implements one move of the FSM to parse the following
11412027Sjungma@eit.uni-kl.de// regular expressions. Error checking is done in the caller.
11512027Sjungma@eit.uni-kl.de
11612027Sjungma@eit.uni-kl.desmall_type
11712027Sjungma@eit.uni-kl.defsm_move(char c, small_type &b, small_type &s, small_type &state)
11812027Sjungma@eit.uni-kl.de{
11912027Sjungma@eit.uni-kl.de
12012027Sjungma@eit.uni-kl.de  // Possible regular expressions (REs):
12112027Sjungma@eit.uni-kl.de  // Let N = any digit depending on the base.
12212027Sjungma@eit.uni-kl.de  //    1. [0|1|..|9]N*
12312027Sjungma@eit.uni-kl.de  //    2. [+|-][0|1|..|9]N*
12412027Sjungma@eit.uni-kl.de  //    3. 0[b|B|d|D|o|O|x|X][0|1|..|F]N*
12512027Sjungma@eit.uni-kl.de  //    4. [+|-]?0[b|B|d|D|o|O|x|X][0|1|..|F]N*
12612027Sjungma@eit.uni-kl.de  //
12712027Sjungma@eit.uni-kl.de  // The finite state machine (FMS) to parse these regular expressions
12812027Sjungma@eit.uni-kl.de  // has 4 states, 0 to 3. 0 is the initial state and 3 is the final
12912027Sjungma@eit.uni-kl.de  // state.
13012027Sjungma@eit.uni-kl.de  //
13112027Sjungma@eit.uni-kl.de  // Default sign = SC_POS, default base = NB_DEFAULT_BASE.
13212027Sjungma@eit.uni-kl.de
13312027Sjungma@eit.uni-kl.de  switch (state) {
13412027Sjungma@eit.uni-kl.de
13512027Sjungma@eit.uni-kl.de  case 0: // The initial state.
13612027Sjungma@eit.uni-kl.de    switch (c) {
13712027Sjungma@eit.uni-kl.de    case '0': s = SC_POS; state = 1; return 0; // RE 1 or 3
13812027Sjungma@eit.uni-kl.de    case '+': s = SC_POS; state = 2; return 1; // RE 2
13912027Sjungma@eit.uni-kl.de    case '-': s = SC_NEG; state = 2; return 1; // RE 2
14012027Sjungma@eit.uni-kl.de    default:  s = SC_POS; b = NB_DEFAULT_BASE; state = 3; return 0; // RE 1
14112027Sjungma@eit.uni-kl.de    }
14212027Sjungma@eit.uni-kl.de    // break; //unreachable code
14312027Sjungma@eit.uni-kl.de  case 1: // 0...
14412027Sjungma@eit.uni-kl.de    switch (c) {
14512027Sjungma@eit.uni-kl.de    case 'x': case 'X': b = SC_HEX; state = 3; return 2; // RE 3 or 4
14612027Sjungma@eit.uni-kl.de    case 'd': case 'D': b = SC_DEC; state = 3; return 2; // RE 3 or 4
14712027Sjungma@eit.uni-kl.de    case 'o': case 'O': b = SC_OCT; state = 3; return 2; // RE 3 or 4
14812027Sjungma@eit.uni-kl.de    case 'b': case 'B': b = SC_BIN; state = 3; return 2; // RE 3 or 4
14912027Sjungma@eit.uni-kl.de    default:  b = NB_DEFAULT_BASE; state = 3; return 0; // RE 1
15012027Sjungma@eit.uni-kl.de    }
15112027Sjungma@eit.uni-kl.de    // break; //unreachable code
15212027Sjungma@eit.uni-kl.de  case 2: // +... or -...
15312027Sjungma@eit.uni-kl.de    switch (c) {
15412027Sjungma@eit.uni-kl.de    case '0': state = 1; return 0; // RE 2 or 4
15512027Sjungma@eit.uni-kl.de    default:  b = NB_DEFAULT_BASE; state = 3; return 0; // RE 2
15612027Sjungma@eit.uni-kl.de    }
15712027Sjungma@eit.uni-kl.de    // break; //unreachable code
15812027Sjungma@eit.uni-kl.de  case 3: // The final state.
15912027Sjungma@eit.uni-kl.de    break;
16012027Sjungma@eit.uni-kl.de
16112027Sjungma@eit.uni-kl.de  default:
16212027Sjungma@eit.uni-kl.de    // Any other state is not possible.
16312027Sjungma@eit.uni-kl.de    assert((0 <= state) && (state <= 3));
16412027Sjungma@eit.uni-kl.de
16512027Sjungma@eit.uni-kl.de  } // switch
16612027Sjungma@eit.uni-kl.de
16712027Sjungma@eit.uni-kl.de  return 0;
16812027Sjungma@eit.uni-kl.de
16912027Sjungma@eit.uni-kl.de}
17012027Sjungma@eit.uni-kl.de
17112027Sjungma@eit.uni-kl.de
17212027Sjungma@eit.uni-kl.de// Get base b and sign s of the number in the char string v. Return a
17312027Sjungma@eit.uni-kl.de// pointer to the first char after the point where b and s are
17412027Sjungma@eit.uni-kl.de// determined or where the end of v is reached. The input string v has
17512027Sjungma@eit.uni-kl.de// to be null terminated.
17612027Sjungma@eit.uni-kl.deconst char
17712027Sjungma@eit.uni-kl.de*get_base_and_sign(const char *v, small_type &b, small_type &s)
17812027Sjungma@eit.uni-kl.de{
17912027Sjungma@eit.uni-kl.de
18012027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
18112027Sjungma@eit.uni-kl.de  assert(v != NULL);
18212027Sjungma@eit.uni-kl.de#endif
18312027Sjungma@eit.uni-kl.de
18412027Sjungma@eit.uni-kl.de  const small_type STATE_START = 0;
18512027Sjungma@eit.uni-kl.de  const small_type STATE_FINISH = 3;
18612027Sjungma@eit.uni-kl.de
18712027Sjungma@eit.uni-kl.de  // Default sign = SC_POS, default base = 10.
18812027Sjungma@eit.uni-kl.de  s = SC_POS;
18912027Sjungma@eit.uni-kl.de  b = NB_DEFAULT_BASE;
19012027Sjungma@eit.uni-kl.de
19112027Sjungma@eit.uni-kl.de  small_type state = STATE_START;
19212027Sjungma@eit.uni-kl.de  small_type nskip = 0; // Skip that many chars.
19312027Sjungma@eit.uni-kl.de  const char *u = v;
19412027Sjungma@eit.uni-kl.de
19512027Sjungma@eit.uni-kl.de  while (*u) {
19612027Sjungma@eit.uni-kl.de    if (isspace(*u))  // Skip white space.
19712027Sjungma@eit.uni-kl.de      ++u;
19812027Sjungma@eit.uni-kl.de    else {
19912027Sjungma@eit.uni-kl.de      nskip += fsm_move(*u, b, s, state);
20012027Sjungma@eit.uni-kl.de      if (state == STATE_FINISH)
20112027Sjungma@eit.uni-kl.de        break;
20212027Sjungma@eit.uni-kl.de      else
20312027Sjungma@eit.uni-kl.de        ++u;
20412027Sjungma@eit.uni-kl.de    }
20512027Sjungma@eit.uni-kl.de  }
20612027Sjungma@eit.uni-kl.de
20712027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
20812027Sjungma@eit.uni-kl.de  // Test to see if the above loop executed more than it should
20912027Sjungma@eit.uni-kl.de  // have. The max number of skipped chars is equal to the length of
21012027Sjungma@eit.uni-kl.de  // the longest format specifier, e.g., "-0x".
21112027Sjungma@eit.uni-kl.de  assert(nskip <= 3);
21212027Sjungma@eit.uni-kl.de#endif
21312027Sjungma@eit.uni-kl.de
21412027Sjungma@eit.uni-kl.de  v += nskip;
21512027Sjungma@eit.uni-kl.de
21612027Sjungma@eit.uni-kl.de  // Handles empty strings or strings without any digits after the
21712027Sjungma@eit.uni-kl.de  // base or base and sign specifier.
21812027Sjungma@eit.uni-kl.de  if (*v == '\0') {
21912027Sjungma@eit.uni-kl.de      char msg[BUFSIZ];
22012027Sjungma@eit.uni-kl.de      std::sprintf( msg,
22112027Sjungma@eit.uni-kl.de	       "get_base_and_sign( const char* v, small_type&, small_type& ) : "
22212027Sjungma@eit.uni-kl.de	       "v = \"\" is not valid" );
22312027Sjungma@eit.uni-kl.de      SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
22412027Sjungma@eit.uni-kl.de  }
22512027Sjungma@eit.uni-kl.de
22612027Sjungma@eit.uni-kl.de  return v;
22712027Sjungma@eit.uni-kl.de
22812027Sjungma@eit.uni-kl.de}
22912027Sjungma@eit.uni-kl.de
23012027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------
23112027Sjungma@eit.uni-kl.de//"parse_binary_bits"
23212027Sjungma@eit.uni-kl.de//
23312027Sjungma@eit.uni-kl.de// This function parses the supplied string into the supplied vector as a
23412027Sjungma@eit.uni-kl.de// right justified bit value.
23512027Sjungma@eit.uni-kl.de//    src_p  -> character string representing the bits to be parsed.
23612027Sjungma@eit.uni-kl.de//    dst_n  =  number of words in data_p and ctrl_p.
23712027Sjungma@eit.uni-kl.de//    data_p -> words w/BITS_PER_DIGIT bits to receive the value's data bits.
23812027Sjungma@eit.uni-kl.de//    ctrl_p -> words w/BITS_PER_DIGIT bits to receive the value's control bits,
23912027Sjungma@eit.uni-kl.de//              or zero.
24012027Sjungma@eit.uni-kl.de// Result is true if value was non-zero.
24112027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------
24212027Sjungma@eit.uni-kl.devoid parse_binary_bits(
24312027Sjungma@eit.uni-kl.de    const char* src_p, int dst_n, sc_digit* data_p, sc_digit* ctrl_p )
24412027Sjungma@eit.uni-kl.de{
24512027Sjungma@eit.uni-kl.de    int      bit_i;    // Number of bit now processing.
24612027Sjungma@eit.uni-kl.de    sc_digit ctrl;     // Control word now assembling.
24712027Sjungma@eit.uni-kl.de    sc_digit data;     // Data word now assembling.
24812027Sjungma@eit.uni-kl.de    int      delta_n;  // src_n - dst_n*BITS_PER_DIGIT.
24912027Sjungma@eit.uni-kl.de    int      src_i;    // Index in src_p now accessing (left to right).
25012027Sjungma@eit.uni-kl.de    int      src_n;    // Length of source that is left in bits.
25112027Sjungma@eit.uni-kl.de    int      word_i;   // Bit within word now accessing (left to right).
25212027Sjungma@eit.uni-kl.de
25312027Sjungma@eit.uni-kl.de    // MAKE SURE WE HAVE A STRING TO PARSE:
25412027Sjungma@eit.uni-kl.de
25512027Sjungma@eit.uni-kl.de    if( src_p == 0 ) {
25612027Sjungma@eit.uni-kl.de        SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
25712027Sjungma@eit.uni-kl.de                         "character string is zero" );
25812027Sjungma@eit.uni-kl.de    }
25912027Sjungma@eit.uni-kl.de    if( *src_p == 0 ) {
26012027Sjungma@eit.uni-kl.de        SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
26112027Sjungma@eit.uni-kl.de                         "character string is empty" );
26212027Sjungma@eit.uni-kl.de    }
26312027Sjungma@eit.uni-kl.de
26412027Sjungma@eit.uni-kl.de
26512027Sjungma@eit.uni-kl.de    // INDEX INTO THE SOURCE TO A DEPTH THAT WILL ACCOMODATE OUR SIZE:
26612027Sjungma@eit.uni-kl.de    //
26712027Sjungma@eit.uni-kl.de    // If the source is smaller than our value initialize our value to zero.
26812027Sjungma@eit.uni-kl.de
26912027Sjungma@eit.uni-kl.de    src_n = strlen(src_p);
27012027Sjungma@eit.uni-kl.de    delta_n = src_n - (dst_n*BITS_PER_DIGIT);
27112027Sjungma@eit.uni-kl.de    if ( delta_n > 0 )
27212027Sjungma@eit.uni-kl.de    {
27312027Sjungma@eit.uni-kl.de        src_p = &src_p[delta_n];
27412027Sjungma@eit.uni-kl.de        src_n -= delta_n;
27512027Sjungma@eit.uni-kl.de    }
27612027Sjungma@eit.uni-kl.de    else
27712027Sjungma@eit.uni-kl.de    {
27812027Sjungma@eit.uni-kl.de        for ( word_i = 0; word_i < dst_n; word_i++ ) data_p[word_i] = 0;
27912027Sjungma@eit.uni-kl.de	    if ( ctrl_p )
28012027Sjungma@eit.uni-kl.de		for ( word_i = 0; word_i < dst_n; word_i++ ) ctrl_p[word_i] = 0;
28112027Sjungma@eit.uni-kl.de    }
28212027Sjungma@eit.uni-kl.de
28312027Sjungma@eit.uni-kl.de
28412027Sjungma@eit.uni-kl.de    // LOOP OVER THE SOURCE ASSEMBLING WORDS AND PLACING THEM IN OUR VALUE:
28512027Sjungma@eit.uni-kl.de    //
28612027Sjungma@eit.uni-kl.de    // We stride right to left through the source in BITS_PER_DIGIT chunks.
28712027Sjungma@eit.uni-kl.de    // Each of those chunks is processed from left to right a bit at a time.
28812027Sjungma@eit.uni-kl.de    // We process the high order word specially, since there are less bits.
28912027Sjungma@eit.uni-kl.de
29012027Sjungma@eit.uni-kl.de    src_n = src_n - BITS_PER_DIGIT;
29112027Sjungma@eit.uni-kl.de    for (word_i=0; word_i < dst_n; word_i++)
29212027Sjungma@eit.uni-kl.de    {
29312027Sjungma@eit.uni-kl.de        src_i = src_n;
29412027Sjungma@eit.uni-kl.de
29512027Sjungma@eit.uni-kl.de
29612027Sjungma@eit.uni-kl.de        // PARTIAL LAST WORD TO ASSEMBLE:
29712027Sjungma@eit.uni-kl.de
29812027Sjungma@eit.uni-kl.de        if ( src_i < 0 )
29912027Sjungma@eit.uni-kl.de        {
30012027Sjungma@eit.uni-kl.de            src_n += BITS_PER_DIGIT;
30112027Sjungma@eit.uni-kl.de            src_i = 0;
30212027Sjungma@eit.uni-kl.de            data = 0;
30312027Sjungma@eit.uni-kl.de            ctrl = 0;
30412027Sjungma@eit.uni-kl.de            for ( src_i = 0; src_i < src_n; src_i++ )
30512027Sjungma@eit.uni-kl.de            {
30612027Sjungma@eit.uni-kl.de                ctrl = ctrl << 1;
30712027Sjungma@eit.uni-kl.de                data = data << 1;
30812027Sjungma@eit.uni-kl.de                switch( src_p[src_i] )
30912027Sjungma@eit.uni-kl.de                {
31012027Sjungma@eit.uni-kl.de                  case 'X':
31112027Sjungma@eit.uni-kl.de                  case 'x': ctrl = ctrl | 1; data = data | 1; break;
31212027Sjungma@eit.uni-kl.de                  case '1': data = data | 1; break;
31312027Sjungma@eit.uni-kl.de                  case 'Z':
31412027Sjungma@eit.uni-kl.de                  case 'z': ctrl = ctrl | 1; break;
31512027Sjungma@eit.uni-kl.de                  case '0':                  break;
31612027Sjungma@eit.uni-kl.de                  default:
31712027Sjungma@eit.uni-kl.de                    {
31812027Sjungma@eit.uni-kl.de                        char msg[BUFSIZ];
31912027Sjungma@eit.uni-kl.de                        std::sprintf( msg, "character string '%s' is not valid",
32012027Sjungma@eit.uni-kl.de                        src_p );
32112027Sjungma@eit.uni-kl.de                        SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_, msg);
32212027Sjungma@eit.uni-kl.de                    }
32312027Sjungma@eit.uni-kl.de                    break;
32412027Sjungma@eit.uni-kl.de                }
32512027Sjungma@eit.uni-kl.de            }
32612027Sjungma@eit.uni-kl.de            if ( ctrl_p ) ctrl_p[word_i] = ctrl;
32712027Sjungma@eit.uni-kl.de            data_p[word_i] = data;
32812027Sjungma@eit.uni-kl.de            break;
32912027Sjungma@eit.uni-kl.de        }
33012027Sjungma@eit.uni-kl.de
33112027Sjungma@eit.uni-kl.de
33212027Sjungma@eit.uni-kl.de        // FULL WORD TO BE ASSEMBLED:
33312027Sjungma@eit.uni-kl.de
33412027Sjungma@eit.uni-kl.de        ctrl = 0;
33512027Sjungma@eit.uni-kl.de        data = 0;
33612027Sjungma@eit.uni-kl.de        for ( bit_i = 0; bit_i < BITS_PER_DIGIT; bit_i++ )
33712027Sjungma@eit.uni-kl.de        {
33812027Sjungma@eit.uni-kl.de            ctrl = ctrl << 1;
33912027Sjungma@eit.uni-kl.de            data = data << 1;
34012027Sjungma@eit.uni-kl.de            switch( src_p[src_i++] )
34112027Sjungma@eit.uni-kl.de            {
34212027Sjungma@eit.uni-kl.de              case 'X':
34312027Sjungma@eit.uni-kl.de              case 'x': ctrl = ctrl | 1; data = data | 1; break;
34412027Sjungma@eit.uni-kl.de              case '1': data = data | 1; break;
34512027Sjungma@eit.uni-kl.de              case 'Z':
34612027Sjungma@eit.uni-kl.de              case 'z': ctrl = ctrl | 1; break;
34712027Sjungma@eit.uni-kl.de              case '0':                  break;
34812027Sjungma@eit.uni-kl.de              default:
34912027Sjungma@eit.uni-kl.de                {
35012027Sjungma@eit.uni-kl.de                    char msg[BUFSIZ];
35112027Sjungma@eit.uni-kl.de                    std::sprintf( msg, "character string '%s' is not valid",
35212027Sjungma@eit.uni-kl.de                    src_p );
35312027Sjungma@eit.uni-kl.de                    SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
35412027Sjungma@eit.uni-kl.de                }
35512027Sjungma@eit.uni-kl.de                break;
35612027Sjungma@eit.uni-kl.de            }
35712027Sjungma@eit.uni-kl.de        }
35812027Sjungma@eit.uni-kl.de        if ( ctrl_p ) ctrl_p[word_i] = ctrl;
35912027Sjungma@eit.uni-kl.de        data_p[word_i] = data;
36012027Sjungma@eit.uni-kl.de        src_n = src_n - BITS_PER_DIGIT;
36112027Sjungma@eit.uni-kl.de    }
36212027Sjungma@eit.uni-kl.de}
36312027Sjungma@eit.uni-kl.de
36412027Sjungma@eit.uni-kl.de
36512027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------
36612027Sjungma@eit.uni-kl.de//"parse_hex_bits"
36712027Sjungma@eit.uni-kl.de//
36812027Sjungma@eit.uni-kl.de// This function parses the supplied string into the supplied vector as a
36912027Sjungma@eit.uni-kl.de// right justified bit value.
37012027Sjungma@eit.uni-kl.de//    src_p  -> character string representing the bits to be parsed.
37112027Sjungma@eit.uni-kl.de//    dst_n  =  number of words in data_p and ctrl_p.
37212027Sjungma@eit.uni-kl.de//    data_p -> words w/32 bits to receive the value's data bits.
37312027Sjungma@eit.uni-kl.de//    ctrl_p -> words w/32 bits to receive the value's control bits,
37412027Sjungma@eit.uni-kl.de//              or zero.
37512027Sjungma@eit.uni-kl.de// Result is true if value was non-zero.
37612027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------
37712027Sjungma@eit.uni-kl.devoid parse_hex_bits(
37812027Sjungma@eit.uni-kl.de	const char* src_p, int dst_n, sc_digit* data_p, sc_digit* ctrl_p )
37912027Sjungma@eit.uni-kl.de{
38012027Sjungma@eit.uni-kl.de    sc_digit ctrl;     // Control word now assembling.
38112027Sjungma@eit.uni-kl.de    sc_digit data;     // Data word now assembling.
38212027Sjungma@eit.uni-kl.de    int      delta_n;  // src_n - dst_n*BITS_PER_DIGIT.
38312027Sjungma@eit.uni-kl.de    int      digit_i;  // Number of digit now processing.
38412027Sjungma@eit.uni-kl.de    int      src_i;    // Index in src_p now accessing (left to right).
38512027Sjungma@eit.uni-kl.de    int      src_n;    // Length of source that is left in bits.
38612027Sjungma@eit.uni-kl.de    int      word_i;   // Bit within word now accessing (left to right).
38712027Sjungma@eit.uni-kl.de
38812027Sjungma@eit.uni-kl.de    // MAKE SURE WE HAVE A STRING TO PARSE:
38912027Sjungma@eit.uni-kl.de
39012027Sjungma@eit.uni-kl.de    if( src_p == 0 ) {
39112027Sjungma@eit.uni-kl.de        SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
39212027Sjungma@eit.uni-kl.de                         "character string is zero" );
39312027Sjungma@eit.uni-kl.de    }
39412027Sjungma@eit.uni-kl.de    if( *src_p == 0 ) {
39512027Sjungma@eit.uni-kl.de        SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
39612027Sjungma@eit.uni-kl.de                         "character string is empty" );
39712027Sjungma@eit.uni-kl.de    }
39812027Sjungma@eit.uni-kl.de
39912027Sjungma@eit.uni-kl.de
40012027Sjungma@eit.uni-kl.de    // INDEX INTO THE SOURCE TO A DEPTH THAT WILL ACCOMODATE OUR SIZE:
40112027Sjungma@eit.uni-kl.de    //
40212027Sjungma@eit.uni-kl.de    // If the source is smaller than our value initialize our value to zero.
40312027Sjungma@eit.uni-kl.de
40412027Sjungma@eit.uni-kl.de    src_n = strlen(src_p);
40512027Sjungma@eit.uni-kl.de    delta_n = src_n - (dst_n*8);
40612027Sjungma@eit.uni-kl.de    if ( delta_n > 0 )
40712027Sjungma@eit.uni-kl.de    {
40812027Sjungma@eit.uni-kl.de        src_p = &src_p[delta_n];
40912027Sjungma@eit.uni-kl.de        src_n -= delta_n;
41012027Sjungma@eit.uni-kl.de    }
41112027Sjungma@eit.uni-kl.de    else
41212027Sjungma@eit.uni-kl.de    {
41312027Sjungma@eit.uni-kl.de        for ( word_i = 0; word_i < dst_n; word_i++ ) data_p[word_i] = 0;
41412027Sjungma@eit.uni-kl.de		if ( ctrl_p )
41512027Sjungma@eit.uni-kl.de			for ( word_i = 0; word_i < dst_n; word_i++ ) ctrl_p[word_i] = 0;
41612027Sjungma@eit.uni-kl.de    }
41712027Sjungma@eit.uni-kl.de
41812027Sjungma@eit.uni-kl.de
41912027Sjungma@eit.uni-kl.de    // LOOP OVER THE SOURCE ASSEMBLING WORDS AND PLACING THEM IN OUR VALUE:
42012027Sjungma@eit.uni-kl.de    //
42112027Sjungma@eit.uni-kl.de    // We stride right to left through the source in BITS_PER_DIGIT chunks.
42212027Sjungma@eit.uni-kl.de    // Each of those chunks is processed from left to right a bit at a time.
42312027Sjungma@eit.uni-kl.de    // We process the high order word specially, since there are less bits.
42412027Sjungma@eit.uni-kl.de
42512027Sjungma@eit.uni-kl.de    src_n = src_n - 8;
42612027Sjungma@eit.uni-kl.de    for (word_i=0; word_i < dst_n; word_i++)
42712027Sjungma@eit.uni-kl.de    {
42812027Sjungma@eit.uni-kl.de        src_i = src_n;
42912027Sjungma@eit.uni-kl.de
43012027Sjungma@eit.uni-kl.de
43112027Sjungma@eit.uni-kl.de        // PARTIAL LAST WORD TO ASSEMBLE:
43212027Sjungma@eit.uni-kl.de
43312027Sjungma@eit.uni-kl.de        if ( src_i < 0 )
43412027Sjungma@eit.uni-kl.de        {
43512027Sjungma@eit.uni-kl.de            src_n += 8;
43612027Sjungma@eit.uni-kl.de            src_i = 0;
43712027Sjungma@eit.uni-kl.de            data = 0;
43812027Sjungma@eit.uni-kl.de            ctrl = 0;
43912027Sjungma@eit.uni-kl.de            for ( src_i = 0; src_i < src_n; src_i++ )
44012027Sjungma@eit.uni-kl.de            {
44112027Sjungma@eit.uni-kl.de                ctrl = ctrl << 4;
44212027Sjungma@eit.uni-kl.de                data = data << 4;
44312027Sjungma@eit.uni-kl.de                switch( src_p[src_i] )
44412027Sjungma@eit.uni-kl.de                {
44512027Sjungma@eit.uni-kl.de                  case 'X':
44612027Sjungma@eit.uni-kl.de                  case 'x': ctrl = ctrl | 15; data = data | 15; break;
44712027Sjungma@eit.uni-kl.de		  case 'F':
44812027Sjungma@eit.uni-kl.de                  case 'f': data = data | 15; break;
44912027Sjungma@eit.uni-kl.de		  case 'E':
45012027Sjungma@eit.uni-kl.de                  case 'e': data = data | 14; break;
45112027Sjungma@eit.uni-kl.de		  case 'D':
45212027Sjungma@eit.uni-kl.de                  case 'd': data = data | 13; break;
45312027Sjungma@eit.uni-kl.de		  case 'C':
45412027Sjungma@eit.uni-kl.de                  case 'c': data = data | 12; break;
45512027Sjungma@eit.uni-kl.de		  case 'B':
45612027Sjungma@eit.uni-kl.de                  case 'b': data = data | 11; break;
45712027Sjungma@eit.uni-kl.de		  case 'A':
45812027Sjungma@eit.uni-kl.de                  case 'a': data = data | 10; break;
45912027Sjungma@eit.uni-kl.de                  case '9': data = data |  9; break;
46012027Sjungma@eit.uni-kl.de                  case '8': data = data |  8; break;
46112027Sjungma@eit.uni-kl.de                  case '7': data = data |  7; break;
46212027Sjungma@eit.uni-kl.de                  case '6': data = data |  6; break;
46312027Sjungma@eit.uni-kl.de                  case '5': data = data |  5; break;
46412027Sjungma@eit.uni-kl.de                  case '4': data = data |  4; break;
46512027Sjungma@eit.uni-kl.de                  case '3': data = data |  3; break;
46612027Sjungma@eit.uni-kl.de                  case '2': data = data |  2; break;
46712027Sjungma@eit.uni-kl.de                  case '1': data = data |  1; break;
46812027Sjungma@eit.uni-kl.de                  case '0':                  break;
46912027Sjungma@eit.uni-kl.de                  case 'Z':
47012027Sjungma@eit.uni-kl.de                  case 'z': ctrl = ctrl | 15; break;
47112027Sjungma@eit.uni-kl.de                  default:
47212027Sjungma@eit.uni-kl.de                    {
47312027Sjungma@eit.uni-kl.de                        char msg[BUFSIZ];
47412027Sjungma@eit.uni-kl.de                        std::sprintf( msg, "character string '%s' is not valid",
47512027Sjungma@eit.uni-kl.de                        src_p );
47612027Sjungma@eit.uni-kl.de                        SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_, msg);
47712027Sjungma@eit.uni-kl.de                    }
47812027Sjungma@eit.uni-kl.de                    break;
47912027Sjungma@eit.uni-kl.de                }
48012027Sjungma@eit.uni-kl.de            }
48112027Sjungma@eit.uni-kl.de            if ( ctrl_p ) ctrl_p[word_i] = ctrl;
48212027Sjungma@eit.uni-kl.de            data_p[word_i] = data;
48312027Sjungma@eit.uni-kl.de            break;
48412027Sjungma@eit.uni-kl.de        }
48512027Sjungma@eit.uni-kl.de
48612027Sjungma@eit.uni-kl.de
48712027Sjungma@eit.uni-kl.de        // FULL WORD TO BE ASSEMBLED:
48812027Sjungma@eit.uni-kl.de
48912027Sjungma@eit.uni-kl.de        ctrl = 0;
49012027Sjungma@eit.uni-kl.de        data = 0;
49112027Sjungma@eit.uni-kl.de        for ( digit_i = 0; digit_i < 8; digit_i++ )
49212027Sjungma@eit.uni-kl.de        {
49312027Sjungma@eit.uni-kl.de            ctrl = ctrl << 4;
49412027Sjungma@eit.uni-kl.de            data = data << 4;
49512027Sjungma@eit.uni-kl.de            switch( src_p[src_i++] )
49612027Sjungma@eit.uni-kl.de            {
49712027Sjungma@eit.uni-kl.de	      case 'X':
49812027Sjungma@eit.uni-kl.de	      case 'x': ctrl = ctrl | 15; data = data | 15; break;
49912027Sjungma@eit.uni-kl.de	      case 'F':
50012027Sjungma@eit.uni-kl.de	      case 'f': data = data | 15; break;
50112027Sjungma@eit.uni-kl.de	      case 'E':
50212027Sjungma@eit.uni-kl.de	      case 'e': data = data | 14; break;
50312027Sjungma@eit.uni-kl.de	      case 'D':
50412027Sjungma@eit.uni-kl.de	      case 'd': data = data | 13; break;
50512027Sjungma@eit.uni-kl.de	      case 'C':
50612027Sjungma@eit.uni-kl.de	      case 'c': data = data | 12; break;
50712027Sjungma@eit.uni-kl.de	      case 'B':
50812027Sjungma@eit.uni-kl.de	      case 'b': data = data | 11; break;
50912027Sjungma@eit.uni-kl.de	      case 'A':
51012027Sjungma@eit.uni-kl.de	      case 'a': data = data | 10; break;
51112027Sjungma@eit.uni-kl.de	      case '9': data = data |  9; break;
51212027Sjungma@eit.uni-kl.de	      case '8': data = data |  8; break;
51312027Sjungma@eit.uni-kl.de	      case '7': data = data |  7; break;
51412027Sjungma@eit.uni-kl.de	      case '6': data = data |  6; break;
51512027Sjungma@eit.uni-kl.de	      case '5': data = data |  5; break;
51612027Sjungma@eit.uni-kl.de	      case '4': data = data |  4; break;
51712027Sjungma@eit.uni-kl.de	      case '3': data = data |  3; break;
51812027Sjungma@eit.uni-kl.de	      case '2': data = data |  2; break;
51912027Sjungma@eit.uni-kl.de	      case '1': data = data |  1; break;
52012027Sjungma@eit.uni-kl.de	      case '0':                  break;
52112027Sjungma@eit.uni-kl.de	      case 'Z':
52212027Sjungma@eit.uni-kl.de	      case 'z': ctrl = ctrl | 15; break;
52312027Sjungma@eit.uni-kl.de              default:
52412027Sjungma@eit.uni-kl.de                {
52512027Sjungma@eit.uni-kl.de                    char msg[BUFSIZ];
52612027Sjungma@eit.uni-kl.de                    std::sprintf( msg, "character string '%s' is not valid",
52712027Sjungma@eit.uni-kl.de                    src_p );
52812027Sjungma@eit.uni-kl.de                    SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
52912027Sjungma@eit.uni-kl.de                }
53012027Sjungma@eit.uni-kl.de                break;
53112027Sjungma@eit.uni-kl.de            }
53212027Sjungma@eit.uni-kl.de        }
53312027Sjungma@eit.uni-kl.de        if ( ctrl_p ) ctrl_p[word_i] = ctrl;
53412027Sjungma@eit.uni-kl.de        data_p[word_i] = data;
53512027Sjungma@eit.uni-kl.de        src_n = src_n - BITS_PER_DIGIT;
53612027Sjungma@eit.uni-kl.de    }
53712027Sjungma@eit.uni-kl.de}
53812027Sjungma@eit.uni-kl.de
53912027Sjungma@eit.uni-kl.de
54012027Sjungma@eit.uni-kl.de
54112027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
54212027Sjungma@eit.uni-kl.de//  SECTION: Utility functions involving unsigned vectors.
54312027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
54412027Sjungma@eit.uni-kl.de
54512027Sjungma@eit.uni-kl.de// Read u from a null terminated char string v. Note that operator>>
54612027Sjungma@eit.uni-kl.de// in sc_nbcommon.cpp is similar to this function.
54712027Sjungma@eit.uni-kl.desmall_type
54812027Sjungma@eit.uni-kl.devec_from_str(int unb, int und, sc_digit *u,
54912027Sjungma@eit.uni-kl.de             const char *v, sc_numrep base)
55012027Sjungma@eit.uni-kl.de{
55112027Sjungma@eit.uni-kl.de
55212027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
55312027Sjungma@eit.uni-kl.de  assert((unb > 0) && (und > 0) && (u != NULL));
55412027Sjungma@eit.uni-kl.de  assert(v != NULL);
55512027Sjungma@eit.uni-kl.de#endif
55612027Sjungma@eit.uni-kl.de
55712027Sjungma@eit.uni-kl.de  is_valid_base(base);
55812027Sjungma@eit.uni-kl.de
55912027Sjungma@eit.uni-kl.de  small_type b, s;  // base and sign.
56012027Sjungma@eit.uni-kl.de
56112027Sjungma@eit.uni-kl.de  v = get_base_and_sign(v, b, s);
56212027Sjungma@eit.uni-kl.de
56312027Sjungma@eit.uni-kl.de  if (base != SC_NOBASE) {
56412027Sjungma@eit.uni-kl.de    if (b == NB_DEFAULT_BASE)
56512027Sjungma@eit.uni-kl.de      b = base;
56612027Sjungma@eit.uni-kl.de    else {
56712027Sjungma@eit.uni-kl.de	char msg[BUFSIZ];
56812027Sjungma@eit.uni-kl.de	std::sprintf( msg,
56912027Sjungma@eit.uni-kl.de		 "vec_from_str( int, int, sc_digit*, const char*, sc_numrep base ) : "
57012027Sjungma@eit.uni-kl.de		 "base = %s does not match the default base",
57112027Sjungma@eit.uni-kl.de		 to_string( base ).c_str() );
57212027Sjungma@eit.uni-kl.de	SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
57312027Sjungma@eit.uni-kl.de    }
57412027Sjungma@eit.uni-kl.de  }
57512027Sjungma@eit.uni-kl.de
57612027Sjungma@eit.uni-kl.de  vec_zero(und, u);
57712027Sjungma@eit.uni-kl.de
57812027Sjungma@eit.uni-kl.de  char c;
57912027Sjungma@eit.uni-kl.de
58012027Sjungma@eit.uni-kl.de  for ( ; (c = *v); ++v) {
58112027Sjungma@eit.uni-kl.de
58212027Sjungma@eit.uni-kl.de    if (isalnum(c)) {
58312027Sjungma@eit.uni-kl.de
58412027Sjungma@eit.uni-kl.de      small_type val;  // Numeric value of a char.
58512027Sjungma@eit.uni-kl.de
58612027Sjungma@eit.uni-kl.de      if (isalpha(c)) // Hex digit.
58712027Sjungma@eit.uni-kl.de        val = toupper(c) - 'A' + 10;
58812027Sjungma@eit.uni-kl.de      else
58912027Sjungma@eit.uni-kl.de        val = c - '0';
59012027Sjungma@eit.uni-kl.de
59112027Sjungma@eit.uni-kl.de      if (val >= b) {
59212027Sjungma@eit.uni-kl.de	  char msg[BUFSIZ];
59312027Sjungma@eit.uni-kl.de	  std::sprintf( msg,
59412027Sjungma@eit.uni-kl.de		   "vec_from_str( int, int, sc_digit*, const char*, sc_numrep base ) : "
59512027Sjungma@eit.uni-kl.de		   "'%c' is not a valid digit in base %d",
59612027Sjungma@eit.uni-kl.de		   *v, b );
59712027Sjungma@eit.uni-kl.de	  SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
59812027Sjungma@eit.uni-kl.de      }
59912027Sjungma@eit.uni-kl.de
60012027Sjungma@eit.uni-kl.de      // digit = digit * b + val;
60112027Sjungma@eit.uni-kl.de      vec_mul_small_on(und, u, b);
60212027Sjungma@eit.uni-kl.de
60312027Sjungma@eit.uni-kl.de      if (val)
60412027Sjungma@eit.uni-kl.de        vec_add_small_on(und, u, val);
60512027Sjungma@eit.uni-kl.de
60612027Sjungma@eit.uni-kl.de    }
60712027Sjungma@eit.uni-kl.de    else {
60812027Sjungma@eit.uni-kl.de	char msg[BUFSIZ];
60912027Sjungma@eit.uni-kl.de	std::sprintf( msg,
61012027Sjungma@eit.uni-kl.de		 "vec_from_str( int, int, sc_digit*, const char*, sc_numrep base ) : "
61112027Sjungma@eit.uni-kl.de		 "'%c' is not a valid digit in base %d",
61212027Sjungma@eit.uni-kl.de		 *v, b );
61312027Sjungma@eit.uni-kl.de	SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
61412027Sjungma@eit.uni-kl.de    }
61512027Sjungma@eit.uni-kl.de  }
61612027Sjungma@eit.uni-kl.de
61712027Sjungma@eit.uni-kl.de  return convert_signed_SM_to_2C_to_SM(s, unb, und, u);
61812027Sjungma@eit.uni-kl.de}
61912027Sjungma@eit.uni-kl.de
62012027Sjungma@eit.uni-kl.de
62112027Sjungma@eit.uni-kl.de// All vec_ functions assume that the vector to hold the result,
62212027Sjungma@eit.uni-kl.de// called w, has sufficient length to hold the result. For efficiency
62312027Sjungma@eit.uni-kl.de// reasons, we do not test whether or not we are out of bounds.
62412027Sjungma@eit.uni-kl.de
62512027Sjungma@eit.uni-kl.de// Compute w = u + v, where w, u, and v are vectors.
62612027Sjungma@eit.uni-kl.de// - ulen >= vlen
62712027Sjungma@eit.uni-kl.de// - wlen >= sc_max(ulen, vlen) + 1
62812027Sjungma@eit.uni-kl.devoid
62912027Sjungma@eit.uni-kl.devec_add(int ulen, const sc_digit *u,
63012027Sjungma@eit.uni-kl.de        int vlen, const sc_digit *v,
63112027Sjungma@eit.uni-kl.de        sc_digit *w)
63212027Sjungma@eit.uni-kl.de{
63312027Sjungma@eit.uni-kl.de
63412027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
63512027Sjungma@eit.uni-kl.de  assert((ulen > 0) && (u != NULL));
63612027Sjungma@eit.uni-kl.de  assert((vlen > 0) && (v != NULL));
63712027Sjungma@eit.uni-kl.de  assert(w != NULL);
63812027Sjungma@eit.uni-kl.de  assert(ulen >= vlen);
63912027Sjungma@eit.uni-kl.de#endif
64012027Sjungma@eit.uni-kl.de
64112027Sjungma@eit.uni-kl.de  const sc_digit *uend = (u + ulen);
64212027Sjungma@eit.uni-kl.de  const sc_digit *vend = (v + vlen);
64312027Sjungma@eit.uni-kl.de
64412027Sjungma@eit.uni-kl.de  sc_digit carry = 0;   // Also used as sum to save space.
64512027Sjungma@eit.uni-kl.de
64612027Sjungma@eit.uni-kl.de  // Add along the shorter v.
64712027Sjungma@eit.uni-kl.de  while (v < vend) {
64812027Sjungma@eit.uni-kl.de    carry += (*u++) + (*v++);
64912027Sjungma@eit.uni-kl.de    (*w++) = carry & DIGIT_MASK;
65012027Sjungma@eit.uni-kl.de    carry >>= BITS_PER_DIGIT;
65112027Sjungma@eit.uni-kl.de  }
65212027Sjungma@eit.uni-kl.de
65312027Sjungma@eit.uni-kl.de  // Propagate the carry.
65412027Sjungma@eit.uni-kl.de  while (carry && (u < uend)) {
65512027Sjungma@eit.uni-kl.de    carry = (*u++) + 1;
65612027Sjungma@eit.uni-kl.de    (*w++) = carry & DIGIT_MASK;
65712027Sjungma@eit.uni-kl.de    carry >>= BITS_PER_DIGIT;
65812027Sjungma@eit.uni-kl.de  }
65912027Sjungma@eit.uni-kl.de
66012027Sjungma@eit.uni-kl.de  // Copy the rest of u to the result.
66112027Sjungma@eit.uni-kl.de  while (u < uend)
66212027Sjungma@eit.uni-kl.de    (*w++) = (*u++);
66312027Sjungma@eit.uni-kl.de
66412027Sjungma@eit.uni-kl.de  // Propagate the carry if it is still 1.
66512027Sjungma@eit.uni-kl.de  if (carry)
66612027Sjungma@eit.uni-kl.de    (*w) = 1;
66712027Sjungma@eit.uni-kl.de
66812027Sjungma@eit.uni-kl.de}
66912027Sjungma@eit.uni-kl.de
67012027Sjungma@eit.uni-kl.de
67112027Sjungma@eit.uni-kl.de// Compute u += v, where u and v are vectors.
67212027Sjungma@eit.uni-kl.de// - ulen >= vlen
67312027Sjungma@eit.uni-kl.devoid
67412027Sjungma@eit.uni-kl.devec_add_on(int ulen, sc_digit *ubegin,
67512027Sjungma@eit.uni-kl.de           int vlen, const sc_digit *v)
67612027Sjungma@eit.uni-kl.de{
67712027Sjungma@eit.uni-kl.de
67812027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
67912027Sjungma@eit.uni-kl.de  assert((ulen > 0) && (ubegin != NULL));
68012027Sjungma@eit.uni-kl.de  assert((vlen > 0) && (v != NULL));
68112027Sjungma@eit.uni-kl.de  assert(ulen >= vlen);
68212027Sjungma@eit.uni-kl.de#endif
68312027Sjungma@eit.uni-kl.de
68412027Sjungma@eit.uni-kl.de  sc_digit *u = ubegin;
68512027Sjungma@eit.uni-kl.de  const sc_digit *uend = (u + ulen);
68612027Sjungma@eit.uni-kl.de  const sc_digit *vend = (v + vlen);
68712027Sjungma@eit.uni-kl.de
68812027Sjungma@eit.uni-kl.de  sc_digit carry = 0;   // Also used as sum to save space.
68912027Sjungma@eit.uni-kl.de
69012027Sjungma@eit.uni-kl.de  // Add along the shorter v.
69112027Sjungma@eit.uni-kl.de  while (v < vend) {
69212027Sjungma@eit.uni-kl.de    carry += (*u) + (*v++);
69312027Sjungma@eit.uni-kl.de    (*u++) = carry & DIGIT_MASK;
69412027Sjungma@eit.uni-kl.de    carry >>= BITS_PER_DIGIT;
69512027Sjungma@eit.uni-kl.de  }
69612027Sjungma@eit.uni-kl.de
69712027Sjungma@eit.uni-kl.de  // Propagate the carry.
69812027Sjungma@eit.uni-kl.de  while (carry && (u < uend)) {
69912027Sjungma@eit.uni-kl.de    carry = (*u) + 1;
70012027Sjungma@eit.uni-kl.de    (*u++) = carry & DIGIT_MASK;
70112027Sjungma@eit.uni-kl.de    carry >>= BITS_PER_DIGIT;
70212027Sjungma@eit.uni-kl.de  }
70312027Sjungma@eit.uni-kl.de
70412027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
70512027Sjungma@eit.uni-kl.de  if( carry != 0 ) {
70612027Sjungma@eit.uni-kl.de      SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_,
70712027Sjungma@eit.uni-kl.de			 "vec_add_on( int, sc_digit*, int, const "
70812027Sjungma@eit.uni-kl.de			 "sc_digit* ) : "
70912027Sjungma@eit.uni-kl.de			 "result of addition is wrapped around" );
71012027Sjungma@eit.uni-kl.de  }
71112027Sjungma@eit.uni-kl.de#endif
71212027Sjungma@eit.uni-kl.de
71312027Sjungma@eit.uni-kl.de}
71412027Sjungma@eit.uni-kl.de
71512027Sjungma@eit.uni-kl.de
71612027Sjungma@eit.uni-kl.de// Compute u += v, where u and v are vectors.
71712027Sjungma@eit.uni-kl.de// - ulen < vlen
71812027Sjungma@eit.uni-kl.devoid
71912027Sjungma@eit.uni-kl.devec_add_on2(int ulen, sc_digit *ubegin,
72012027Sjungma@eit.uni-kl.de            int
72112027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
72212027Sjungma@eit.uni-kl.de            vlen
72312027Sjungma@eit.uni-kl.de#endif
72412027Sjungma@eit.uni-kl.de            , const sc_digit *v)
72512027Sjungma@eit.uni-kl.de{
72612027Sjungma@eit.uni-kl.de
72712027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
72812027Sjungma@eit.uni-kl.de  assert((ulen > 0) && (ubegin != NULL));
72912027Sjungma@eit.uni-kl.de  assert((vlen > 0) && (v != NULL));
73012027Sjungma@eit.uni-kl.de  assert(ulen < vlen);
73112027Sjungma@eit.uni-kl.de#endif
73212027Sjungma@eit.uni-kl.de
73312027Sjungma@eit.uni-kl.de  sc_digit *u = ubegin;
73412027Sjungma@eit.uni-kl.de  const sc_digit *uend = (u + ulen);
73512027Sjungma@eit.uni-kl.de
73612027Sjungma@eit.uni-kl.de  sc_digit carry = 0;   // Also used as sum to save space.
73712027Sjungma@eit.uni-kl.de
73812027Sjungma@eit.uni-kl.de  // Add along the shorter u.
73912027Sjungma@eit.uni-kl.de  while (u < uend) {
74012027Sjungma@eit.uni-kl.de    carry += (*u) + (*v++);
74112027Sjungma@eit.uni-kl.de    (*u++) = carry & DIGIT_MASK;
74212027Sjungma@eit.uni-kl.de    carry >>= BITS_PER_DIGIT;
74312027Sjungma@eit.uni-kl.de  }
74412027Sjungma@eit.uni-kl.de
74512027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
74612027Sjungma@eit.uni-kl.de  if( carry != 0 ) {
74712027Sjungma@eit.uni-kl.de      SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_,
74812027Sjungma@eit.uni-kl.de                         "vec_add_on2( int, sc_digit*, int, const "
74912027Sjungma@eit.uni-kl.de			 "sc_digit* ) : "
75012027Sjungma@eit.uni-kl.de			 "result of addition is wrapped around" );
75112027Sjungma@eit.uni-kl.de  }
75212027Sjungma@eit.uni-kl.de#endif
75312027Sjungma@eit.uni-kl.de}
75412027Sjungma@eit.uni-kl.de
75512027Sjungma@eit.uni-kl.de
75612027Sjungma@eit.uni-kl.de// Compute w = u + v, where w and u are vectors, and v is a scalar.
75712027Sjungma@eit.uni-kl.devoid
75812027Sjungma@eit.uni-kl.devec_add_small(int ulen, const sc_digit *u,
75912027Sjungma@eit.uni-kl.de              sc_digit v,
76012027Sjungma@eit.uni-kl.de              sc_digit *w)
76112027Sjungma@eit.uni-kl.de{
76212027Sjungma@eit.uni-kl.de
76312027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
76412027Sjungma@eit.uni-kl.de  assert((ulen > 0) && (u != NULL));
76512027Sjungma@eit.uni-kl.de  assert(w != NULL);
76612027Sjungma@eit.uni-kl.de#endif
76712027Sjungma@eit.uni-kl.de
76812027Sjungma@eit.uni-kl.de  const sc_digit *uend = (u + ulen);
76912027Sjungma@eit.uni-kl.de
77012027Sjungma@eit.uni-kl.de  // Add along the shorter v.
77112027Sjungma@eit.uni-kl.de  sc_digit carry = (*u++) + v;
77212027Sjungma@eit.uni-kl.de  (*w++) = carry & DIGIT_MASK;
77312027Sjungma@eit.uni-kl.de  carry >>= BITS_PER_DIGIT;
77412027Sjungma@eit.uni-kl.de
77512027Sjungma@eit.uni-kl.de  // Propagate the carry.
77612027Sjungma@eit.uni-kl.de  while (carry && (u < uend)) {
77712027Sjungma@eit.uni-kl.de    carry = (*u++) + 1;
77812027Sjungma@eit.uni-kl.de    (*w++) = carry & DIGIT_MASK;
77912027Sjungma@eit.uni-kl.de    carry >>= BITS_PER_DIGIT;
78012027Sjungma@eit.uni-kl.de  }
78112027Sjungma@eit.uni-kl.de
78212027Sjungma@eit.uni-kl.de  // Copy the rest of u to the result.
78312027Sjungma@eit.uni-kl.de  while (u < uend)
78412027Sjungma@eit.uni-kl.de    (*w++) = (*u++);
78512027Sjungma@eit.uni-kl.de
78612027Sjungma@eit.uni-kl.de  // Propagate the carry if it is still 1.
78712027Sjungma@eit.uni-kl.de  if (carry)
78812027Sjungma@eit.uni-kl.de    (*w) = 1;
78912027Sjungma@eit.uni-kl.de
79012027Sjungma@eit.uni-kl.de}
79112027Sjungma@eit.uni-kl.de
79212027Sjungma@eit.uni-kl.de// Compute u += v, where u is vectors, and v is a scalar.
79312027Sjungma@eit.uni-kl.devoid
79412027Sjungma@eit.uni-kl.devec_add_small_on(int ulen, sc_digit *u, sc_digit v)
79512027Sjungma@eit.uni-kl.de{
79612027Sjungma@eit.uni-kl.de
79712027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
79812027Sjungma@eit.uni-kl.de  assert((ulen > 0) && (u != NULL));
79912027Sjungma@eit.uni-kl.de#endif
80012027Sjungma@eit.uni-kl.de
80112027Sjungma@eit.uni-kl.de  int i = 0;
80212027Sjungma@eit.uni-kl.de
80312027Sjungma@eit.uni-kl.de  while (v && (i < ulen)) {
80412027Sjungma@eit.uni-kl.de    v += u[i];
80512027Sjungma@eit.uni-kl.de    u[i++] = v & DIGIT_MASK;
80612027Sjungma@eit.uni-kl.de    v >>= BITS_PER_DIGIT;
80712027Sjungma@eit.uni-kl.de  }
80812027Sjungma@eit.uni-kl.de
80912027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
81012027Sjungma@eit.uni-kl.de  if( v != 0 ) {
81112027Sjungma@eit.uni-kl.de      SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_,
81212027Sjungma@eit.uni-kl.de                         "vec_add_small_on( int, sc_digit*, unsigned "
81312027Sjungma@eit.uni-kl.de			 "long ) : "
81412027Sjungma@eit.uni-kl.de			 "result of addition is wrapped around" );
81512027Sjungma@eit.uni-kl.de  }
81612027Sjungma@eit.uni-kl.de#endif
81712027Sjungma@eit.uni-kl.de
81812027Sjungma@eit.uni-kl.de}
81912027Sjungma@eit.uni-kl.de
82012027Sjungma@eit.uni-kl.de// Compute w = u - v, where w, u, and v are vectors.
82112027Sjungma@eit.uni-kl.de// - ulen >= vlen
82212027Sjungma@eit.uni-kl.de// - wlen >= sc_max(ulen, vlen)
82312027Sjungma@eit.uni-kl.devoid
82412027Sjungma@eit.uni-kl.devec_sub(int ulen, const sc_digit *u,
82512027Sjungma@eit.uni-kl.de        int vlen, const sc_digit *v,
82612027Sjungma@eit.uni-kl.de        sc_digit *w)
82712027Sjungma@eit.uni-kl.de{
82812027Sjungma@eit.uni-kl.de
82912027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
83012027Sjungma@eit.uni-kl.de  assert((ulen > 0) && (u != NULL));
83112027Sjungma@eit.uni-kl.de  assert((vlen > 0) && (v != NULL));
83212027Sjungma@eit.uni-kl.de  assert(w != NULL);
83312027Sjungma@eit.uni-kl.de  assert(ulen >= vlen);
83412027Sjungma@eit.uni-kl.de#endif
83512027Sjungma@eit.uni-kl.de
83612027Sjungma@eit.uni-kl.de  const sc_digit *uend = (u + ulen);
83712027Sjungma@eit.uni-kl.de  const sc_digit *vend = (v + vlen);
83812027Sjungma@eit.uni-kl.de
83912027Sjungma@eit.uni-kl.de  sc_digit borrow = 0;   // Also used as diff to save space.
84012027Sjungma@eit.uni-kl.de
84112027Sjungma@eit.uni-kl.de  // Subtract along the shorter v.
84212027Sjungma@eit.uni-kl.de  while (v < vend) {
84312027Sjungma@eit.uni-kl.de    borrow = ((*u++) + DIGIT_RADIX) - (*v++) - borrow;
84412027Sjungma@eit.uni-kl.de    (*w++) = borrow & DIGIT_MASK;
84512027Sjungma@eit.uni-kl.de    borrow = 1 - (borrow >> BITS_PER_DIGIT);
84612027Sjungma@eit.uni-kl.de  }
84712027Sjungma@eit.uni-kl.de
84812027Sjungma@eit.uni-kl.de  // Propagate the borrow.
84912027Sjungma@eit.uni-kl.de  while (borrow && (u < uend)) {
85012027Sjungma@eit.uni-kl.de    borrow = ((*u++) + DIGIT_RADIX) - 1;
85112027Sjungma@eit.uni-kl.de    (*w++) = borrow & DIGIT_MASK;
85212027Sjungma@eit.uni-kl.de    borrow = 1 - (borrow >> BITS_PER_DIGIT);
85312027Sjungma@eit.uni-kl.de  }
85412027Sjungma@eit.uni-kl.de
85512027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
85612027Sjungma@eit.uni-kl.de  assert(borrow == 0);
85712027Sjungma@eit.uni-kl.de#endif
85812027Sjungma@eit.uni-kl.de
85912027Sjungma@eit.uni-kl.de  // Copy the rest of u to the result.
86012027Sjungma@eit.uni-kl.de  while (u < uend)
86112027Sjungma@eit.uni-kl.de    (*w++) = (*u++);
86212027Sjungma@eit.uni-kl.de
86312027Sjungma@eit.uni-kl.de}
86412027Sjungma@eit.uni-kl.de
86512027Sjungma@eit.uni-kl.de// Compute u = u - v, where u and v are vectors.
86612027Sjungma@eit.uni-kl.de// - u > v
86712027Sjungma@eit.uni-kl.de// - ulen >= vlen
86812027Sjungma@eit.uni-kl.devoid
86912027Sjungma@eit.uni-kl.devec_sub_on(int ulen, sc_digit *ubegin,
87012027Sjungma@eit.uni-kl.de           int vlen, const sc_digit *v)
87112027Sjungma@eit.uni-kl.de{
87212027Sjungma@eit.uni-kl.de
87312027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
87412027Sjungma@eit.uni-kl.de  assert((ulen > 0) && (ubegin != NULL));
87512027Sjungma@eit.uni-kl.de  assert((vlen > 0) && (v != NULL));
87612027Sjungma@eit.uni-kl.de  assert(ulen >= vlen);
87712027Sjungma@eit.uni-kl.de#endif
87812027Sjungma@eit.uni-kl.de
87912027Sjungma@eit.uni-kl.de  sc_digit *u = ubegin;
88012027Sjungma@eit.uni-kl.de  const sc_digit *uend = (u + ulen);
88112027Sjungma@eit.uni-kl.de  const sc_digit *vend = (v + vlen);
88212027Sjungma@eit.uni-kl.de
88312027Sjungma@eit.uni-kl.de  sc_digit borrow = 0;   // Also used as diff to save space.
88412027Sjungma@eit.uni-kl.de
88512027Sjungma@eit.uni-kl.de  // Subtract along the shorter v.
88612027Sjungma@eit.uni-kl.de  while (v < vend) {
88712027Sjungma@eit.uni-kl.de    borrow = ((*u) + DIGIT_RADIX) - (*v++) - borrow;
88812027Sjungma@eit.uni-kl.de    (*u++) = borrow & DIGIT_MASK;
88912027Sjungma@eit.uni-kl.de    borrow = 1 - (borrow >> BITS_PER_DIGIT);
89012027Sjungma@eit.uni-kl.de  }
89112027Sjungma@eit.uni-kl.de
89212027Sjungma@eit.uni-kl.de  // Propagate the borrow.
89312027Sjungma@eit.uni-kl.de  while (borrow && (u < uend)) {
89412027Sjungma@eit.uni-kl.de    borrow = ((*u) + DIGIT_RADIX) - 1;
89512027Sjungma@eit.uni-kl.de    (*u++) = borrow & DIGIT_MASK;
89612027Sjungma@eit.uni-kl.de    borrow = 1 - (borrow >> BITS_PER_DIGIT);
89712027Sjungma@eit.uni-kl.de  }
89812027Sjungma@eit.uni-kl.de
89912027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
90012027Sjungma@eit.uni-kl.de  assert(borrow == 0);
90112027Sjungma@eit.uni-kl.de#endif
90212027Sjungma@eit.uni-kl.de
90312027Sjungma@eit.uni-kl.de}
90412027Sjungma@eit.uni-kl.de
90512027Sjungma@eit.uni-kl.de// Compute u = v - u, where u and v are vectors.
90612027Sjungma@eit.uni-kl.de// - v > u
90712027Sjungma@eit.uni-kl.de// - ulen <= vlen or ulen > ulen
90812027Sjungma@eit.uni-kl.devoid
90912027Sjungma@eit.uni-kl.devec_sub_on2(int ulen, sc_digit *ubegin,
91012027Sjungma@eit.uni-kl.de            int vlen, const sc_digit *v)
91112027Sjungma@eit.uni-kl.de{
91212027Sjungma@eit.uni-kl.de
91312027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
91412027Sjungma@eit.uni-kl.de  assert((ulen > 0) && (ubegin != NULL));
91512027Sjungma@eit.uni-kl.de  assert((vlen > 0) && (v != NULL));
91612027Sjungma@eit.uni-kl.de#endif
91712027Sjungma@eit.uni-kl.de
91812027Sjungma@eit.uni-kl.de  sc_digit *u = ubegin;
91912027Sjungma@eit.uni-kl.de  const sc_digit *uend = (u + sc_min(ulen, vlen));
92012027Sjungma@eit.uni-kl.de
92112027Sjungma@eit.uni-kl.de  sc_digit borrow = 0;   // Also used as diff to save space.
92212027Sjungma@eit.uni-kl.de
92312027Sjungma@eit.uni-kl.de  // Subtract along the shorter u.
92412027Sjungma@eit.uni-kl.de  while (u < uend) {
92512027Sjungma@eit.uni-kl.de    borrow = ((*v++) + DIGIT_RADIX) - (*u) - borrow;
92612027Sjungma@eit.uni-kl.de    (*u++) = borrow & DIGIT_MASK;
92712027Sjungma@eit.uni-kl.de    borrow = 1 - (borrow >> BITS_PER_DIGIT);
92812027Sjungma@eit.uni-kl.de  }
92912027Sjungma@eit.uni-kl.de
93012027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
93112027Sjungma@eit.uni-kl.de  if( borrow != 0 ) {
93212027Sjungma@eit.uni-kl.de      SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_,
93312027Sjungma@eit.uni-kl.de                         "vec_sub_on2( int, sc_digit*, int, const "
93412027Sjungma@eit.uni-kl.de			 "sc_digit* ) : "
93512027Sjungma@eit.uni-kl.de			 "result of subtraction is wrapped around" );
93612027Sjungma@eit.uni-kl.de  }
93712027Sjungma@eit.uni-kl.de#endif
93812027Sjungma@eit.uni-kl.de}
93912027Sjungma@eit.uni-kl.de
94012027Sjungma@eit.uni-kl.de// Compute w = u - v, where w and u are vectors, and v is a scalar.
94112027Sjungma@eit.uni-kl.devoid
94212027Sjungma@eit.uni-kl.devec_sub_small(int ulen, const sc_digit *u,
94312027Sjungma@eit.uni-kl.de              sc_digit v,
94412027Sjungma@eit.uni-kl.de              sc_digit *w)
94512027Sjungma@eit.uni-kl.de{
94612027Sjungma@eit.uni-kl.de
94712027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
94812027Sjungma@eit.uni-kl.de  assert(ulen > 0);
94912027Sjungma@eit.uni-kl.de  assert(u != NULL);
95012027Sjungma@eit.uni-kl.de#endif
95112027Sjungma@eit.uni-kl.de
95212027Sjungma@eit.uni-kl.de  const sc_digit *uend = (u + ulen);
95312027Sjungma@eit.uni-kl.de
95412027Sjungma@eit.uni-kl.de  // Add along the shorter v.
95512027Sjungma@eit.uni-kl.de  sc_digit borrow = ((*u++) + DIGIT_RADIX) - v;
95612027Sjungma@eit.uni-kl.de  (*w++) = borrow & DIGIT_MASK;
95712027Sjungma@eit.uni-kl.de  borrow = 1 - (borrow >> BITS_PER_DIGIT);
95812027Sjungma@eit.uni-kl.de
95912027Sjungma@eit.uni-kl.de  // Propagate the borrow.
96012027Sjungma@eit.uni-kl.de  while (borrow && (u < uend)) {
96112027Sjungma@eit.uni-kl.de    borrow = ((*u++) + DIGIT_RADIX) - 1;
96212027Sjungma@eit.uni-kl.de    (*w++) = borrow & DIGIT_MASK;
96312027Sjungma@eit.uni-kl.de    borrow = 1 - (borrow >> BITS_PER_DIGIT);
96412027Sjungma@eit.uni-kl.de  }
96512027Sjungma@eit.uni-kl.de
96612027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
96712027Sjungma@eit.uni-kl.de  assert(borrow == 0);
96812027Sjungma@eit.uni-kl.de#endif
96912027Sjungma@eit.uni-kl.de
97012027Sjungma@eit.uni-kl.de  // Copy the rest of u to the result.
97112027Sjungma@eit.uni-kl.de  while (u < uend)
97212027Sjungma@eit.uni-kl.de    (*w++) = (*u++);
97312027Sjungma@eit.uni-kl.de
97412027Sjungma@eit.uni-kl.de}
97512027Sjungma@eit.uni-kl.de
97612027Sjungma@eit.uni-kl.de
97712027Sjungma@eit.uni-kl.de// Compute u -= v, where u is vectors, and v is a scalar.
97812027Sjungma@eit.uni-kl.devoid
97912027Sjungma@eit.uni-kl.devec_sub_small_on(int ulen, sc_digit *u, sc_digit v)
98012027Sjungma@eit.uni-kl.de{
98112027Sjungma@eit.uni-kl.de
98212027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
98312027Sjungma@eit.uni-kl.de  assert((ulen > 0) && (u != NULL));
98412027Sjungma@eit.uni-kl.de#endif
98512027Sjungma@eit.uni-kl.de
98612027Sjungma@eit.uni-kl.de  for (int i = 0; i < ulen; ++i) {
98712027Sjungma@eit.uni-kl.de    v = (u[i] + DIGIT_RADIX) - v;
98812027Sjungma@eit.uni-kl.de    u[i] = v & DIGIT_MASK;
98912027Sjungma@eit.uni-kl.de    v = 1 - (v >> BITS_PER_DIGIT);
99012027Sjungma@eit.uni-kl.de  }
99112027Sjungma@eit.uni-kl.de
99212027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
99312027Sjungma@eit.uni-kl.de  assert(v == 0);
99412027Sjungma@eit.uni-kl.de#endif
99512027Sjungma@eit.uni-kl.de
99612027Sjungma@eit.uni-kl.de}
99712027Sjungma@eit.uni-kl.de
99812027Sjungma@eit.uni-kl.de// Compute w = u * v, where w, u, and v are vectors.
99912027Sjungma@eit.uni-kl.devoid
100012027Sjungma@eit.uni-kl.devec_mul(int ulen, const sc_digit *u,
100112027Sjungma@eit.uni-kl.de        int vlen, const sc_digit *vbegin,
100212027Sjungma@eit.uni-kl.de        sc_digit *wbegin)
100312027Sjungma@eit.uni-kl.de{
100412027Sjungma@eit.uni-kl.de
100512027Sjungma@eit.uni-kl.de  /* Consider u = Ax + B and v = Cx + D where x is equal to
100612027Sjungma@eit.uni-kl.de     HALF_DIGIT_RADIX. In other words, A is the higher half of u and
100712027Sjungma@eit.uni-kl.de     B is the lower half of u. The interpretation for v is
100812027Sjungma@eit.uni-kl.de     similar. Then, we have the following picture:
100912027Sjungma@eit.uni-kl.de
101012027Sjungma@eit.uni-kl.de              u_h     u_l
101112027Sjungma@eit.uni-kl.de     u: -------- --------
101212027Sjungma@eit.uni-kl.de               A        B
101312027Sjungma@eit.uni-kl.de
101412027Sjungma@eit.uni-kl.de              v_h     v_l
101512027Sjungma@eit.uni-kl.de     v: -------- --------
101612027Sjungma@eit.uni-kl.de               C        D
101712027Sjungma@eit.uni-kl.de
101812027Sjungma@eit.uni-kl.de     result (d):
101912027Sjungma@eit.uni-kl.de     carry_before:                           -------- --------
102012027Sjungma@eit.uni-kl.de                                              carry_h  carry_l
102112027Sjungma@eit.uni-kl.de     result_before:        -------- -------- -------- --------
102212027Sjungma@eit.uni-kl.de                               R1_h     R1_l     R0_h     R0_l
102312027Sjungma@eit.uni-kl.de                                             -------- --------
102412027Sjungma@eit.uni-kl.de                                                 BD_h     BD_l
102512027Sjungma@eit.uni-kl.de                                    -------- --------
102612027Sjungma@eit.uni-kl.de                                        AD_h     AD_l
102712027Sjungma@eit.uni-kl.de                                    -------- --------
102812027Sjungma@eit.uni-kl.de                                        BC_h     BC_l
102912027Sjungma@eit.uni-kl.de                           -------- --------
103012027Sjungma@eit.uni-kl.de                               AC_h     AC_l
103112027Sjungma@eit.uni-kl.de     result_after:         -------- -------- -------- --------
103212027Sjungma@eit.uni-kl.de                              R1_h'    R1_l'    R0_h'    R0_l'
103312027Sjungma@eit.uni-kl.de
103412027Sjungma@eit.uni-kl.de     prod_l = R0_h|R0_l + B * D  + 0|carry_l
103512027Sjungma@eit.uni-kl.de            = R0_h|R0_l + BD_h|BD_l + 0|carry_l
103612027Sjungma@eit.uni-kl.de
103712027Sjungma@eit.uni-kl.de     prod_h = A * D + B * C + high_half(prod_l) + carry_h
103812027Sjungma@eit.uni-kl.de            = AD_h|AD_l + BC_h|BC_l + high_half(prod_l) + 0|carry_h
103912027Sjungma@eit.uni-kl.de
104012027Sjungma@eit.uni-kl.de     carry = A * C + high_half(prod_h)
104112027Sjungma@eit.uni-kl.de           = AC_h|AC_l + high_half(prod_h)
104212027Sjungma@eit.uni-kl.de
104312027Sjungma@eit.uni-kl.de     R0_l' = low_half(prod_l)
104412027Sjungma@eit.uni-kl.de
104512027Sjungma@eit.uni-kl.de     R0_h' = low_half(prod_h)
104612027Sjungma@eit.uni-kl.de
104712027Sjungma@eit.uni-kl.de     R0 = high_half(prod_h)|low_half(prod_l)
104812027Sjungma@eit.uni-kl.de
104912027Sjungma@eit.uni-kl.de     where '|' is the concatenation operation and the suffixes 0 and 1
105012027Sjungma@eit.uni-kl.de     show the iteration number, i.e., 0 is the current iteration and 1
105112027Sjungma@eit.uni-kl.de     is the next iteration.
105212027Sjungma@eit.uni-kl.de
105312027Sjungma@eit.uni-kl.de     NOTE: sc_max(prod_l, prod_h, carry) <= 2 * x^2 - 1, so any
105412027Sjungma@eit.uni-kl.de     of these numbers can be stored in a digit.
105512027Sjungma@eit.uni-kl.de
105612027Sjungma@eit.uni-kl.de     NOTE: low_half(u) returns the lower BITS_PER_HALF_DIGIT of u,
105712027Sjungma@eit.uni-kl.de     whereas high_half(u) returns the rest of the bits, which may
105812027Sjungma@eit.uni-kl.de     contain more bits than BITS_PER_HALF_DIGIT.
105912027Sjungma@eit.uni-kl.de  */
106012027Sjungma@eit.uni-kl.de
106112027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
106212027Sjungma@eit.uni-kl.de  assert((ulen > 0) && (u != NULL));
106312027Sjungma@eit.uni-kl.de  assert((vlen > 0) && (vbegin != NULL));
106412027Sjungma@eit.uni-kl.de  assert(wbegin != NULL);
106512027Sjungma@eit.uni-kl.de#endif
106612027Sjungma@eit.uni-kl.de
106712027Sjungma@eit.uni-kl.de#define prod_h carry
106812027Sjungma@eit.uni-kl.de
106912027Sjungma@eit.uni-kl.de  const sc_digit *uend = (u + ulen);
107012027Sjungma@eit.uni-kl.de  const sc_digit *vend = (vbegin + vlen);
107112027Sjungma@eit.uni-kl.de
107212027Sjungma@eit.uni-kl.de  while (u < uend) {
107312027Sjungma@eit.uni-kl.de
107412027Sjungma@eit.uni-kl.de    sc_digit u_h = (*u++);        // A|B
107512027Sjungma@eit.uni-kl.de    sc_digit u_l = low_half(u_h); // B
107612027Sjungma@eit.uni-kl.de    u_h = high_half(u_h);           // A
107712027Sjungma@eit.uni-kl.de
107812027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
107912027Sjungma@eit.uni-kl.de    // The overflow bits must be zero.
108012027Sjungma@eit.uni-kl.de    assert(u_h == (u_h & HALF_DIGIT_MASK));
108112027Sjungma@eit.uni-kl.de#endif
108212027Sjungma@eit.uni-kl.de
108312027Sjungma@eit.uni-kl.de    sc_digit carry = 0;
108412027Sjungma@eit.uni-kl.de
108512027Sjungma@eit.uni-kl.de    sc_digit *w = (wbegin++);
108612027Sjungma@eit.uni-kl.de
108712027Sjungma@eit.uni-kl.de    const sc_digit *v = vbegin;
108812027Sjungma@eit.uni-kl.de
108912027Sjungma@eit.uni-kl.de    while (v < vend) {
109012027Sjungma@eit.uni-kl.de
109112027Sjungma@eit.uni-kl.de      sc_digit v_h = (*v++);         // C|D
109212027Sjungma@eit.uni-kl.de      sc_digit v_l = low_half(v_h);  // D
109312027Sjungma@eit.uni-kl.de
109412027Sjungma@eit.uni-kl.de      v_h = high_half(v_h);            // C
109512027Sjungma@eit.uni-kl.de
109612027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
109712027Sjungma@eit.uni-kl.de      // The overflow bits must be zero.
109812027Sjungma@eit.uni-kl.de      assert(v_h == (v_h & HALF_DIGIT_MASK));
109912027Sjungma@eit.uni-kl.de#endif
110012027Sjungma@eit.uni-kl.de
110112027Sjungma@eit.uni-kl.de      sc_digit prod_l = (*w) + u_l * v_l + low_half(carry);
110212027Sjungma@eit.uni-kl.de
110312027Sjungma@eit.uni-kl.de      prod_h = u_h * v_l + u_l * v_h + high_half(prod_l) + high_half(carry);
110412027Sjungma@eit.uni-kl.de
110512027Sjungma@eit.uni-kl.de      (*w++) = concat(low_half(prod_h), low_half(prod_l));
110612027Sjungma@eit.uni-kl.de
110712027Sjungma@eit.uni-kl.de      carry = u_h * v_h + high_half(prod_h);
110812027Sjungma@eit.uni-kl.de
110912027Sjungma@eit.uni-kl.de    }
111012027Sjungma@eit.uni-kl.de
111112027Sjungma@eit.uni-kl.de    (*w) = carry;
111212027Sjungma@eit.uni-kl.de
111312027Sjungma@eit.uni-kl.de  }
111412027Sjungma@eit.uni-kl.de
111512027Sjungma@eit.uni-kl.de#undef prod_h
111612027Sjungma@eit.uni-kl.de
111712027Sjungma@eit.uni-kl.de}
111812027Sjungma@eit.uni-kl.de
111912027Sjungma@eit.uni-kl.de// Compute w = u * v, where w and u are vectors, and v is a scalar.
112012027Sjungma@eit.uni-kl.de// - 0 < v < HALF_DIGIT_RADIX.
112112027Sjungma@eit.uni-kl.devoid
112212027Sjungma@eit.uni-kl.devec_mul_small(int ulen, const sc_digit *u,
112312027Sjungma@eit.uni-kl.de              sc_digit v, sc_digit *w)
112412027Sjungma@eit.uni-kl.de{
112512027Sjungma@eit.uni-kl.de
112612027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
112712027Sjungma@eit.uni-kl.de  assert((ulen > 0) && (u != NULL));
112812027Sjungma@eit.uni-kl.de  assert(w != NULL);
112912027Sjungma@eit.uni-kl.de  assert((0 < v) && (v < HALF_DIGIT_RADIX));
113012027Sjungma@eit.uni-kl.de#endif
113112027Sjungma@eit.uni-kl.de
113212027Sjungma@eit.uni-kl.de#define prod_h carry
113312027Sjungma@eit.uni-kl.de
113412027Sjungma@eit.uni-kl.de  const sc_digit *uend = (u + ulen);
113512027Sjungma@eit.uni-kl.de
113612027Sjungma@eit.uni-kl.de  sc_digit carry = 0;
113712027Sjungma@eit.uni-kl.de
113812027Sjungma@eit.uni-kl.de  while (u < uend) {
113912027Sjungma@eit.uni-kl.de
114012027Sjungma@eit.uni-kl.de    sc_digit u_AB = (*u++);
114112027Sjungma@eit.uni-kl.de
114212027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
114312027Sjungma@eit.uni-kl.de    // The overflow bits must be zero.
114412027Sjungma@eit.uni-kl.de    assert(high_half(u_AB) == high_half_masked(u_AB));
114512027Sjungma@eit.uni-kl.de#endif
114612027Sjungma@eit.uni-kl.de
114712027Sjungma@eit.uni-kl.de    sc_digit prod_l = v * low_half(u_AB) + low_half(carry);
114812027Sjungma@eit.uni-kl.de
114912027Sjungma@eit.uni-kl.de    prod_h = v * high_half(u_AB) + high_half(prod_l) + high_half(carry);
115012027Sjungma@eit.uni-kl.de
115112027Sjungma@eit.uni-kl.de    (*w++) = concat(low_half(prod_h), low_half(prod_l));
115212027Sjungma@eit.uni-kl.de
115312027Sjungma@eit.uni-kl.de    carry = high_half(prod_h);
115412027Sjungma@eit.uni-kl.de
115512027Sjungma@eit.uni-kl.de  }
115612027Sjungma@eit.uni-kl.de
115712027Sjungma@eit.uni-kl.de  (*w) = carry;
115812027Sjungma@eit.uni-kl.de
115912027Sjungma@eit.uni-kl.de#undef prod_h
116012027Sjungma@eit.uni-kl.de
116112027Sjungma@eit.uni-kl.de}
116212027Sjungma@eit.uni-kl.de
116312027Sjungma@eit.uni-kl.de// Compute u = u * v, where u is a vector, and v is a scalar.
116412027Sjungma@eit.uni-kl.de// - 0 < v < HALF_DIGIT_RADIX.
116512027Sjungma@eit.uni-kl.devoid
116612027Sjungma@eit.uni-kl.devec_mul_small_on(int ulen, sc_digit *u, sc_digit v)
116712027Sjungma@eit.uni-kl.de{
116812027Sjungma@eit.uni-kl.de
116912027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
117012027Sjungma@eit.uni-kl.de  assert((ulen > 0) && (u != NULL));
117112027Sjungma@eit.uni-kl.de  assert((0 < v) && (v < HALF_DIGIT_RADIX));
117212027Sjungma@eit.uni-kl.de#endif
117312027Sjungma@eit.uni-kl.de
117412027Sjungma@eit.uni-kl.de#define prod_h carry
117512027Sjungma@eit.uni-kl.de
117612027Sjungma@eit.uni-kl.de  sc_digit carry = 0;
117712027Sjungma@eit.uni-kl.de
117812027Sjungma@eit.uni-kl.de  for (int i = 0; i < ulen; ++i) {
117912027Sjungma@eit.uni-kl.de
118012027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
118112027Sjungma@eit.uni-kl.de    // The overflow bits must be zero.
118212027Sjungma@eit.uni-kl.de    assert(high_half(u[i]) == high_half_masked(u[i]));
118312027Sjungma@eit.uni-kl.de#endif
118412027Sjungma@eit.uni-kl.de
118512027Sjungma@eit.uni-kl.de    sc_digit prod_l = v * low_half(u[i]) + low_half(carry);
118612027Sjungma@eit.uni-kl.de
118712027Sjungma@eit.uni-kl.de    prod_h = v * high_half(u[i]) + high_half(prod_l) + high_half(carry);
118812027Sjungma@eit.uni-kl.de
118912027Sjungma@eit.uni-kl.de    u[i] = concat(low_half(prod_h), low_half(prod_l));
119012027Sjungma@eit.uni-kl.de
119112027Sjungma@eit.uni-kl.de    carry = high_half(prod_h);
119212027Sjungma@eit.uni-kl.de
119312027Sjungma@eit.uni-kl.de  }
119412027Sjungma@eit.uni-kl.de
119512027Sjungma@eit.uni-kl.de#undef prod_h
119612027Sjungma@eit.uni-kl.de
119712027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
119812027Sjungma@eit.uni-kl.de  if( carry != 0 ) {
119912027Sjungma@eit.uni-kl.de      SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_,
120012027Sjungma@eit.uni-kl.de                         "vec_mul_small_on( int, sc_digit*, unsigned "
120112027Sjungma@eit.uni-kl.de			 "long ) : "
120212027Sjungma@eit.uni-kl.de			 "result of multiplication is wrapped around" );
120312027Sjungma@eit.uni-kl.de  }
120412027Sjungma@eit.uni-kl.de#endif
120512027Sjungma@eit.uni-kl.de}
120612027Sjungma@eit.uni-kl.de
120712027Sjungma@eit.uni-kl.de// Compute w = u / v, where w, u, and v are vectors.
120812027Sjungma@eit.uni-kl.de// - u and v are assumed to have at least two digits as uchars.
120912027Sjungma@eit.uni-kl.devoid
121012027Sjungma@eit.uni-kl.devec_div_large(int ulen, const sc_digit *u,
121112027Sjungma@eit.uni-kl.de              int vlen, const sc_digit *v,
121212027Sjungma@eit.uni-kl.de              sc_digit *w)
121312027Sjungma@eit.uni-kl.de{
121412027Sjungma@eit.uni-kl.de
121512027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
121612027Sjungma@eit.uni-kl.de  assert((ulen > 0) && (u != NULL));
121712027Sjungma@eit.uni-kl.de  assert((vlen > 0) && (v != NULL));
121812027Sjungma@eit.uni-kl.de  assert(w != NULL);
121912027Sjungma@eit.uni-kl.de  assert(BITS_PER_DIGIT >= 3 * BITS_PER_BYTE);
122012027Sjungma@eit.uni-kl.de#endif
122112027Sjungma@eit.uni-kl.de
122212027Sjungma@eit.uni-kl.de  // We will compute q = x / y where x = u and y = v. The reason for
122312027Sjungma@eit.uni-kl.de  // using x and y is that x and y are BYTE_RADIX copies of u and v,
122412027Sjungma@eit.uni-kl.de  // respectively. The use of BYTE_RADIX radix greatly simplifies the
122512027Sjungma@eit.uni-kl.de  // complexity of the division operation. These copies are also
122612027Sjungma@eit.uni-kl.de  // needed even when we use DIGIT_RADIX representation.
122712027Sjungma@eit.uni-kl.de
122812027Sjungma@eit.uni-kl.de  int xlen = BYTES_PER_DIGIT * ulen + 1;
122912027Sjungma@eit.uni-kl.de  int ylen = BYTES_PER_DIGIT * vlen;
123012027Sjungma@eit.uni-kl.de
123112027Sjungma@eit.uni-kl.de#ifdef SC_MAX_NBITS
123212027Sjungma@eit.uni-kl.de  uchar x[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
123312027Sjungma@eit.uni-kl.de  uchar y[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
123412027Sjungma@eit.uni-kl.de  uchar q[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
123512027Sjungma@eit.uni-kl.de#else
123612027Sjungma@eit.uni-kl.de  uchar *x = new uchar[xlen];
123712027Sjungma@eit.uni-kl.de  uchar *y = new uchar[ylen];
123812027Sjungma@eit.uni-kl.de  // valgrind complains about us accessing too far to so leave a buffer.
123912027Sjungma@eit.uni-kl.de  uchar *q = new uchar[(xlen - ylen) + 10];
124012027Sjungma@eit.uni-kl.de#endif
124112027Sjungma@eit.uni-kl.de
124212027Sjungma@eit.uni-kl.de  // q corresponds to w.
124312027Sjungma@eit.uni-kl.de
124412027Sjungma@eit.uni-kl.de  // Set (uchar) x = (sc_digit) u.
124512027Sjungma@eit.uni-kl.de  xlen = vec_to_char(ulen, u, xlen, x);
124612027Sjungma@eit.uni-kl.de
124712027Sjungma@eit.uni-kl.de  // Skip all the leading zeros in x.
124812027Sjungma@eit.uni-kl.de  while ((--xlen >= 0) && (! x[xlen])) continue;
124912027Sjungma@eit.uni-kl.de  xlen++;
125012027Sjungma@eit.uni-kl.de
125112027Sjungma@eit.uni-kl.de  // Set (uchar) y = (sc_digit) v.
125212027Sjungma@eit.uni-kl.de  ylen = vec_to_char(vlen, v, ylen, y);
125312027Sjungma@eit.uni-kl.de
125412027Sjungma@eit.uni-kl.de  // Skip all the leading zeros in y.
125512027Sjungma@eit.uni-kl.de  while ((--ylen >= 0) && (! y[ylen])) continue;
125612027Sjungma@eit.uni-kl.de  ylen++;
125712027Sjungma@eit.uni-kl.de
125812027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
125912027Sjungma@eit.uni-kl.de  assert(xlen > 1);
126012027Sjungma@eit.uni-kl.de  assert(ylen > 1);
126112027Sjungma@eit.uni-kl.de#endif
126212027Sjungma@eit.uni-kl.de
126312027Sjungma@eit.uni-kl.de  // At this point, all the leading zeros are eliminated from x and y.
126412027Sjungma@eit.uni-kl.de
126512027Sjungma@eit.uni-kl.de  // Zero the last digit of x.
126612027Sjungma@eit.uni-kl.de  x[xlen] = 0;
126712027Sjungma@eit.uni-kl.de
126812027Sjungma@eit.uni-kl.de  // The first two digits of y.
126912027Sjungma@eit.uni-kl.de  sc_digit y2 = (y[ylen - 1] << BITS_PER_BYTE) + y[ylen - 2];
127012027Sjungma@eit.uni-kl.de
127112027Sjungma@eit.uni-kl.de  const sc_digit DOUBLE_BITS_PER_BYTE = 2 * BITS_PER_BYTE;
127212027Sjungma@eit.uni-kl.de
127312027Sjungma@eit.uni-kl.de  // Find each q[k].
127412027Sjungma@eit.uni-kl.de  for (int k = (xlen - ylen); k >= 0; --k) {
127512027Sjungma@eit.uni-kl.de
127612027Sjungma@eit.uni-kl.de    // qk is a guess for q[k] such that q[k] = qk or qk - 1.
127712027Sjungma@eit.uni-kl.de    sc_digit qk;
127812027Sjungma@eit.uni-kl.de
127912027Sjungma@eit.uni-kl.de    // Find qk by just using 2 digits of y and 3 digits of x. The
128012027Sjungma@eit.uni-kl.de    // following code assumes that sizeof(sc_digit) >= 3 BYTEs.
128112027Sjungma@eit.uni-kl.de    int k2 = k + ylen;
128212027Sjungma@eit.uni-kl.de
128312027Sjungma@eit.uni-kl.de    qk = ((x[k2] << DOUBLE_BITS_PER_BYTE) +
128412027Sjungma@eit.uni-kl.de          (x[k2 - 1] << BITS_PER_BYTE) + x[k2 - 2]) / y2;
128512027Sjungma@eit.uni-kl.de
128612027Sjungma@eit.uni-kl.de    if (qk >= BYTE_RADIX)     // qk cannot be larger than the largest
128712027Sjungma@eit.uni-kl.de      qk = BYTE_RADIX - 1;    // digit in BYTE_RADIX.
128812027Sjungma@eit.uni-kl.de
128912027Sjungma@eit.uni-kl.de    // q[k] = qk or qk - 1. The following if-statement determines which:
129012027Sjungma@eit.uni-kl.de    if (qk) {
129112027Sjungma@eit.uni-kl.de
129212027Sjungma@eit.uni-kl.de      uchar *xk = (x + k);  // A shortcut for x[k].
129312027Sjungma@eit.uni-kl.de
129412027Sjungma@eit.uni-kl.de      // x = x - y * qk :
129512027Sjungma@eit.uni-kl.de      sc_digit carry = 0;
129612027Sjungma@eit.uni-kl.de
129712027Sjungma@eit.uni-kl.de      for (int i = 0; i < ylen; ++i) {
129812027Sjungma@eit.uni-kl.de        carry += y[i] * qk;
129912027Sjungma@eit.uni-kl.de        sc_digit diff = (xk[i] + BYTE_RADIX) - (carry & BYTE_MASK);
130012027Sjungma@eit.uni-kl.de        xk[i] = (uchar)(diff & BYTE_MASK);
130112027Sjungma@eit.uni-kl.de        carry = (carry >> BITS_PER_BYTE) + (1 - (diff >> BITS_PER_BYTE));
130212027Sjungma@eit.uni-kl.de      }
130312027Sjungma@eit.uni-kl.de
130412027Sjungma@eit.uni-kl.de      // If carry, qk may be one too large.
130512027Sjungma@eit.uni-kl.de      if (carry) {
130612027Sjungma@eit.uni-kl.de
130712027Sjungma@eit.uni-kl.de        // 2's complement the last digit.
130812027Sjungma@eit.uni-kl.de        carry = (xk[ylen] + BYTE_RADIX) - carry;
130912027Sjungma@eit.uni-kl.de        xk[ylen] = (uchar)(carry & BYTE_MASK);
131012027Sjungma@eit.uni-kl.de        carry = 1 - (carry >> BITS_PER_BYTE);
131112027Sjungma@eit.uni-kl.de
131212027Sjungma@eit.uni-kl.de        if (carry) {
131312027Sjungma@eit.uni-kl.de
131412027Sjungma@eit.uni-kl.de          // qk was one too large, so decrement it.
131512027Sjungma@eit.uni-kl.de          --qk;
131612027Sjungma@eit.uni-kl.de
131712027Sjungma@eit.uni-kl.de          // Since qk was decreased by one, y must be added to x:
131812027Sjungma@eit.uni-kl.de          // That is, x = x - y * (qk - 1) = x - y * qk + y = x_above + y.
131912027Sjungma@eit.uni-kl.de          carry = 0;
132012027Sjungma@eit.uni-kl.de
132112027Sjungma@eit.uni-kl.de          for (int i = 0; i < ylen; ++i) {
132212027Sjungma@eit.uni-kl.de            carry += xk[i] + y[i];
132312027Sjungma@eit.uni-kl.de            xk[i] = (uchar)(carry & BYTE_MASK);
132412027Sjungma@eit.uni-kl.de            carry >>= BITS_PER_BYTE;
132512027Sjungma@eit.uni-kl.de          }
132612027Sjungma@eit.uni-kl.de
132712027Sjungma@eit.uni-kl.de          if (carry)
132812027Sjungma@eit.uni-kl.de            xk[ylen] = (uchar)((xk[ylen] + 1) & BYTE_MASK);
132912027Sjungma@eit.uni-kl.de
133012027Sjungma@eit.uni-kl.de        }  // second if carry
133112027Sjungma@eit.uni-kl.de      }  // first if carry
133212027Sjungma@eit.uni-kl.de    }  // if qk
133312027Sjungma@eit.uni-kl.de
133412027Sjungma@eit.uni-kl.de    q[k] = (uchar)qk;
133512027Sjungma@eit.uni-kl.de
133612027Sjungma@eit.uni-kl.de  }  // for k
133712027Sjungma@eit.uni-kl.de
133812027Sjungma@eit.uni-kl.de  // Set (sc_digit) w = (uchar) q.
133912027Sjungma@eit.uni-kl.de  vec_from_char(xlen - ylen + 1, q, ulen, w);
134012027Sjungma@eit.uni-kl.de
134112027Sjungma@eit.uni-kl.de#ifndef SC_MAX_NBITS
134212027Sjungma@eit.uni-kl.de  delete [] x;
134312027Sjungma@eit.uni-kl.de  delete [] y;
134412027Sjungma@eit.uni-kl.de  delete [] q;
134512027Sjungma@eit.uni-kl.de#endif
134612027Sjungma@eit.uni-kl.de
134712027Sjungma@eit.uni-kl.de}
134812027Sjungma@eit.uni-kl.de
134912027Sjungma@eit.uni-kl.de// Compute w = u / v, where u and w are vectors, and v is a scalar.
135012027Sjungma@eit.uni-kl.de// - 0 < v < HALF_DIGIT_RADIX. Below, we rename w to q.
135112027Sjungma@eit.uni-kl.devoid
135212027Sjungma@eit.uni-kl.devec_div_small(int ulen, const sc_digit *u,
135312027Sjungma@eit.uni-kl.de              sc_digit v, sc_digit *q)
135412027Sjungma@eit.uni-kl.de{
135512027Sjungma@eit.uni-kl.de
135612027Sjungma@eit.uni-kl.de  // Given (u = u_1u_2...u_n)_b = (q = q_1q_2...q_n) * v + r, where b
135712027Sjungma@eit.uni-kl.de  // is the base, and 0 <= r < v. Then, the algorithm is as follows:
135812027Sjungma@eit.uni-kl.de  //
135912027Sjungma@eit.uni-kl.de  // r = 0;
136012027Sjungma@eit.uni-kl.de  // for (j = 1; j <= n; j++) {
136112027Sjungma@eit.uni-kl.de  //   q_j = (r * b + u_j) / v;
136212027Sjungma@eit.uni-kl.de  //   r = (r * b + u_j) % v;
136312027Sjungma@eit.uni-kl.de  // }
136412027Sjungma@eit.uni-kl.de  //
136512027Sjungma@eit.uni-kl.de  // In our case, b = DIGIT_RADIX, and u = Ax + B and q = Cx + D where
136612027Sjungma@eit.uni-kl.de  // x = HALF_DIGIT_RADIX. Note that r < v < x and b = x^2. Then, a
136712027Sjungma@eit.uni-kl.de  // typical situation is as follows:
136812027Sjungma@eit.uni-kl.de  //
136912027Sjungma@eit.uni-kl.de  // ---- ----
137012027Sjungma@eit.uni-kl.de  // 0    r
137112027Sjungma@eit.uni-kl.de  //           ---- ----
137212027Sjungma@eit.uni-kl.de  //           A    B
137312027Sjungma@eit.uni-kl.de  //      ---- ---- ----
137412027Sjungma@eit.uni-kl.de  //      r    A    B     = r * b + u
137512027Sjungma@eit.uni-kl.de  //
137612027Sjungma@eit.uni-kl.de  // Hence, C = (r|A) / v.
137712027Sjungma@eit.uni-kl.de  //        D = (((r|A) % v)|B) / v
137812027Sjungma@eit.uni-kl.de  //        r = (((r|A) % v)|B) % v
137912027Sjungma@eit.uni-kl.de
138012027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
138112027Sjungma@eit.uni-kl.de  assert((ulen > 0) && (u != NULL));
138212027Sjungma@eit.uni-kl.de  assert(q != NULL);
138312027Sjungma@eit.uni-kl.de  assert((0 < v) && (v < HALF_DIGIT_RADIX));
138412027Sjungma@eit.uni-kl.de#endif
138512027Sjungma@eit.uni-kl.de
138612027Sjungma@eit.uni-kl.de#define q_h r
138712027Sjungma@eit.uni-kl.de
138812027Sjungma@eit.uni-kl.de  sc_digit r = 0;
138912027Sjungma@eit.uni-kl.de  const sc_digit *ubegin = u;
139012027Sjungma@eit.uni-kl.de
139112027Sjungma@eit.uni-kl.de  u += ulen;
139212027Sjungma@eit.uni-kl.de  q += ulen;
139312027Sjungma@eit.uni-kl.de
139412027Sjungma@eit.uni-kl.de  while (ubegin < u) {
139512027Sjungma@eit.uni-kl.de
139612027Sjungma@eit.uni-kl.de    sc_digit u_AB = (*--u);       // A|B
139712027Sjungma@eit.uni-kl.de
139812027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
139912027Sjungma@eit.uni-kl.de    // The overflow bits must be zero.
140012027Sjungma@eit.uni-kl.de    assert(high_half(u_AB) == high_half_masked(u_AB));
140112027Sjungma@eit.uni-kl.de#endif
140212027Sjungma@eit.uni-kl.de
140312027Sjungma@eit.uni-kl.de    sc_digit num = concat(r, high_half(u_AB));  // num = r|A
140412027Sjungma@eit.uni-kl.de    q_h = num / v;                           // C
140512027Sjungma@eit.uni-kl.de    num = concat((num % v), low_half(u_AB)); // num = (((r|A) % v)|B)
140612027Sjungma@eit.uni-kl.de    (*--q) = concat(q_h, num / v);           // q = C|D
140712027Sjungma@eit.uni-kl.de    r = num % v;
140812027Sjungma@eit.uni-kl.de
140912027Sjungma@eit.uni-kl.de  }
141012027Sjungma@eit.uni-kl.de
141112027Sjungma@eit.uni-kl.de#undef q_h
141212027Sjungma@eit.uni-kl.de
141312027Sjungma@eit.uni-kl.de}
141412027Sjungma@eit.uni-kl.de
141512027Sjungma@eit.uni-kl.de// Compute w = u % v, where w, u, and v are vectors.
141612027Sjungma@eit.uni-kl.de// - u and v are assumed to have at least two digits as uchars.
141712027Sjungma@eit.uni-kl.devoid
141812027Sjungma@eit.uni-kl.devec_rem_large(int ulen, const sc_digit *u,
141912027Sjungma@eit.uni-kl.de              int vlen, const sc_digit *v,
142012027Sjungma@eit.uni-kl.de              sc_digit *w)
142112027Sjungma@eit.uni-kl.de{
142212027Sjungma@eit.uni-kl.de
142312027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
142412027Sjungma@eit.uni-kl.de  assert((ulen > 0) && (u != NULL));
142512027Sjungma@eit.uni-kl.de  assert((vlen > 0) && (v != NULL));
142612027Sjungma@eit.uni-kl.de  assert(w != NULL);
142712027Sjungma@eit.uni-kl.de  assert(BITS_PER_DIGIT >= 3 * BITS_PER_BYTE);
142812027Sjungma@eit.uni-kl.de#endif
142912027Sjungma@eit.uni-kl.de
143012027Sjungma@eit.uni-kl.de  // This function is adapted from vec_div_large.
143112027Sjungma@eit.uni-kl.de
143212027Sjungma@eit.uni-kl.de  int xlen = BYTES_PER_DIGIT * ulen + 1;
143312027Sjungma@eit.uni-kl.de  int ylen = BYTES_PER_DIGIT * vlen;
143412027Sjungma@eit.uni-kl.de
143512027Sjungma@eit.uni-kl.de#ifdef SC_MAX_NBITS
143612027Sjungma@eit.uni-kl.de  uchar x[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
143712027Sjungma@eit.uni-kl.de  uchar y[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
143812027Sjungma@eit.uni-kl.de#else
143912027Sjungma@eit.uni-kl.de  uchar *x = new uchar[xlen];
144012027Sjungma@eit.uni-kl.de  uchar *y = new uchar[ylen];
144112027Sjungma@eit.uni-kl.de#endif
144212027Sjungma@eit.uni-kl.de
144312027Sjungma@eit.uni-kl.de  // r corresponds to w.
144412027Sjungma@eit.uni-kl.de
144512027Sjungma@eit.uni-kl.de  // Set (uchar) x = (sc_digit) u.
144612027Sjungma@eit.uni-kl.de  xlen = vec_to_char(ulen, u, xlen, x);
144712027Sjungma@eit.uni-kl.de
144812027Sjungma@eit.uni-kl.de  // Skip all the leading zeros in x.
144912027Sjungma@eit.uni-kl.de  while ((--xlen >= 0) && (! x[xlen])) continue;
145012027Sjungma@eit.uni-kl.de  xlen++;
145112027Sjungma@eit.uni-kl.de
145212027Sjungma@eit.uni-kl.de  // Set (uchar) y = (sc_digit) v.
145312027Sjungma@eit.uni-kl.de  ylen = vec_to_char(vlen, v, ylen, y);
145412027Sjungma@eit.uni-kl.de
145512027Sjungma@eit.uni-kl.de  // Skip all the leading zeros in y.
145612027Sjungma@eit.uni-kl.de  while ((--ylen >= 0) && (! y[ylen])) continue;
145712027Sjungma@eit.uni-kl.de  ylen++;
145812027Sjungma@eit.uni-kl.de
145912027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
146012027Sjungma@eit.uni-kl.de  assert(xlen > 1);
146112027Sjungma@eit.uni-kl.de  assert(ylen > 1);
146212027Sjungma@eit.uni-kl.de#endif
146312027Sjungma@eit.uni-kl.de
146412027Sjungma@eit.uni-kl.de  // At this point, all the leading zeros are eliminated from x and y.
146512027Sjungma@eit.uni-kl.de
146612027Sjungma@eit.uni-kl.de  // Zero the last digit of x.
146712027Sjungma@eit.uni-kl.de  x[xlen] = 0;
146812027Sjungma@eit.uni-kl.de
146912027Sjungma@eit.uni-kl.de  // The first two digits of y.
147012027Sjungma@eit.uni-kl.de  sc_digit y2 = (y[ylen - 1] << BITS_PER_BYTE) + y[ylen - 2];
147112027Sjungma@eit.uni-kl.de
147212027Sjungma@eit.uni-kl.de  const sc_digit DOUBLE_BITS_PER_BYTE = 2 * BITS_PER_BYTE;
147312027Sjungma@eit.uni-kl.de
147412027Sjungma@eit.uni-kl.de  // Find each q[k].
147512027Sjungma@eit.uni-kl.de  for (int k = xlen - ylen; k >= 0; --k) {
147612027Sjungma@eit.uni-kl.de
147712027Sjungma@eit.uni-kl.de    // qk is a guess for q[k] such that q[k] = qk or qk - 1.
147812027Sjungma@eit.uni-kl.de    sc_digit qk;
147912027Sjungma@eit.uni-kl.de
148012027Sjungma@eit.uni-kl.de    // Find qk by just using 2 digits of y and 3 digits of x. The
148112027Sjungma@eit.uni-kl.de    // following code assumes that sizeof(sc_digit) >= 3 BYTEs.
148212027Sjungma@eit.uni-kl.de    int k2 = k + ylen;
148312027Sjungma@eit.uni-kl.de
148412027Sjungma@eit.uni-kl.de    qk = ((x[k2] << DOUBLE_BITS_PER_BYTE) +
148512027Sjungma@eit.uni-kl.de      (x[k2 - 1] << BITS_PER_BYTE) + x[k2 - 2]) / y2;
148612027Sjungma@eit.uni-kl.de
148712027Sjungma@eit.uni-kl.de    if (qk >= BYTE_RADIX)     // qk cannot be larger than the largest
148812027Sjungma@eit.uni-kl.de      qk = BYTE_RADIX - 1;    // digit in BYTE_RADIX.
148912027Sjungma@eit.uni-kl.de
149012027Sjungma@eit.uni-kl.de    // q[k] = qk or qk - 1. The following if-statement determines which.
149112027Sjungma@eit.uni-kl.de    if (qk) {
149212027Sjungma@eit.uni-kl.de
149312027Sjungma@eit.uni-kl.de      uchar *xk = (x + k);  // A shortcut for x[k].
149412027Sjungma@eit.uni-kl.de
149512027Sjungma@eit.uni-kl.de      // x = x - y * qk;
149612027Sjungma@eit.uni-kl.de      sc_digit carry = 0;
149712027Sjungma@eit.uni-kl.de
149812027Sjungma@eit.uni-kl.de      for (int i = 0; i < ylen; ++i) {
149912027Sjungma@eit.uni-kl.de        carry += y[i] * qk;
150012027Sjungma@eit.uni-kl.de        sc_digit diff = (xk[i] + BYTE_RADIX) - (carry & BYTE_MASK);
150112027Sjungma@eit.uni-kl.de        xk[i] = (uchar)(diff & BYTE_MASK);
150212027Sjungma@eit.uni-kl.de        carry = (carry >> BITS_PER_BYTE) + (1 - (diff >> BITS_PER_BYTE));
150312027Sjungma@eit.uni-kl.de      }
150412027Sjungma@eit.uni-kl.de
150512027Sjungma@eit.uni-kl.de      if (carry) {
150612027Sjungma@eit.uni-kl.de
150712027Sjungma@eit.uni-kl.de        // 2's complement the last digit.
150812027Sjungma@eit.uni-kl.de        carry = (xk[ylen] + BYTE_RADIX) - carry;
150912027Sjungma@eit.uni-kl.de        xk[ylen] = (uchar)(carry & BYTE_MASK);
151012027Sjungma@eit.uni-kl.de        carry = 1 - (carry >> BITS_PER_BYTE);
151112027Sjungma@eit.uni-kl.de
151212027Sjungma@eit.uni-kl.de        if (carry) {
151312027Sjungma@eit.uni-kl.de
151412027Sjungma@eit.uni-kl.de          // qk was one too large, so decrement it.
151512027Sjungma@eit.uni-kl.de          // --qk;
151612027Sjungma@eit.uni-kl.de
151712027Sjungma@eit.uni-kl.de          // x = x - y * (qk - 1) = x - y * qk + y = x_above + y.
151812027Sjungma@eit.uni-kl.de          carry = 0;
151912027Sjungma@eit.uni-kl.de
152012027Sjungma@eit.uni-kl.de          for (int i = 0; i < ylen; ++i) {
152112027Sjungma@eit.uni-kl.de            carry += xk[i] + y[i];
152212027Sjungma@eit.uni-kl.de            xk[i] = (uchar)(carry & BYTE_MASK);
152312027Sjungma@eit.uni-kl.de            carry >>= BITS_PER_BYTE;
152412027Sjungma@eit.uni-kl.de          }
152512027Sjungma@eit.uni-kl.de
152612027Sjungma@eit.uni-kl.de          if (carry)
152712027Sjungma@eit.uni-kl.de            xk[ylen] = (uchar)((xk[ylen] + 1) & BYTE_MASK);
152812027Sjungma@eit.uni-kl.de
152912027Sjungma@eit.uni-kl.de        }  // second if carry
153012027Sjungma@eit.uni-kl.de      } // first if carry
153112027Sjungma@eit.uni-kl.de    }  // if qk
153212027Sjungma@eit.uni-kl.de  }  // for k
153312027Sjungma@eit.uni-kl.de
153412027Sjungma@eit.uni-kl.de  // Set (sc_digit) w = (uchar) x for the remainder.
153512027Sjungma@eit.uni-kl.de  vec_from_char(ylen, x, ulen, w);
153612027Sjungma@eit.uni-kl.de
153712027Sjungma@eit.uni-kl.de#ifndef SC_MAX_NBITS
153812027Sjungma@eit.uni-kl.de  delete [] x;
153912027Sjungma@eit.uni-kl.de  delete [] y;
154012027Sjungma@eit.uni-kl.de#endif
154112027Sjungma@eit.uni-kl.de
154212027Sjungma@eit.uni-kl.de}
154312027Sjungma@eit.uni-kl.de
154412027Sjungma@eit.uni-kl.de// Compute r = u % v, where u is a vector, and r and v are scalars.
154512027Sjungma@eit.uni-kl.de// - 0 < v < HALF_DIGIT_RADIX.
154612027Sjungma@eit.uni-kl.de// - The remainder r is returned.
154712027Sjungma@eit.uni-kl.desc_digit
154812027Sjungma@eit.uni-kl.devec_rem_small(int ulen, const sc_digit *u, sc_digit v)
154912027Sjungma@eit.uni-kl.de{
155012027Sjungma@eit.uni-kl.de
155112027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
155212027Sjungma@eit.uni-kl.de  assert((ulen > 0) && (u != NULL));
155312027Sjungma@eit.uni-kl.de  assert((0 < v) && (v < HALF_DIGIT_RADIX));
155412027Sjungma@eit.uni-kl.de#endif
155512027Sjungma@eit.uni-kl.de
155612027Sjungma@eit.uni-kl.de  // This function is adapted from vec_div_small().
155712027Sjungma@eit.uni-kl.de
155812027Sjungma@eit.uni-kl.de  sc_digit r = 0;
155912027Sjungma@eit.uni-kl.de  const sc_digit *ubegin = u;
156012027Sjungma@eit.uni-kl.de
156112027Sjungma@eit.uni-kl.de  u += ulen;
156212027Sjungma@eit.uni-kl.de
156312027Sjungma@eit.uni-kl.de  while (ubegin < u) {
156412027Sjungma@eit.uni-kl.de    sc_digit u_AB = (*--u);  // A|B
156512027Sjungma@eit.uni-kl.de
156612027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
156712027Sjungma@eit.uni-kl.de    // The overflow bits must be zero.
156812027Sjungma@eit.uni-kl.de    assert(high_half(u_AB) == high_half_masked(u_AB));
156912027Sjungma@eit.uni-kl.de#endif
157012027Sjungma@eit.uni-kl.de
157112027Sjungma@eit.uni-kl.de    // r = (((r|A) % v)|B) % v
157212027Sjungma@eit.uni-kl.de    r = (concat(((concat(r, high_half(u_AB))) % v), low_half(u_AB))) % v;
157312027Sjungma@eit.uni-kl.de  }
157412027Sjungma@eit.uni-kl.de
157512027Sjungma@eit.uni-kl.de  return r;
157612027Sjungma@eit.uni-kl.de
157712027Sjungma@eit.uni-kl.de}
157812027Sjungma@eit.uni-kl.de
157912027Sjungma@eit.uni-kl.de// u = u / v, r = u % v.
158012027Sjungma@eit.uni-kl.desc_digit
158112027Sjungma@eit.uni-kl.devec_rem_on_small(int ulen, sc_digit *u, sc_digit v)
158212027Sjungma@eit.uni-kl.de{
158312027Sjungma@eit.uni-kl.de
158412027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
158512027Sjungma@eit.uni-kl.de  assert((ulen > 0) && (u != NULL));
158612027Sjungma@eit.uni-kl.de  assert(v > 0);
158712027Sjungma@eit.uni-kl.de#endif
158812027Sjungma@eit.uni-kl.de
158912027Sjungma@eit.uni-kl.de#define q_h r
159012027Sjungma@eit.uni-kl.de
159112027Sjungma@eit.uni-kl.de  sc_digit r = 0;
159212027Sjungma@eit.uni-kl.de  const sc_digit *ubegin = u;
159312027Sjungma@eit.uni-kl.de
159412027Sjungma@eit.uni-kl.de  u += ulen;
159512027Sjungma@eit.uni-kl.de
159612027Sjungma@eit.uni-kl.de  while (ubegin < u) {
159712027Sjungma@eit.uni-kl.de
159812027Sjungma@eit.uni-kl.de    sc_digit u_AB = (*--u);       // A|B
159912027Sjungma@eit.uni-kl.de
160012027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
160112027Sjungma@eit.uni-kl.de    // The overflow bits must be zero.
160212027Sjungma@eit.uni-kl.de    assert(high_half(u_AB) == high_half_masked(u_AB));
160312027Sjungma@eit.uni-kl.de#endif
160412027Sjungma@eit.uni-kl.de
160512027Sjungma@eit.uni-kl.de    sc_digit num = concat(r, high_half(u_AB));  // num = r|A
160612027Sjungma@eit.uni-kl.de    q_h = num / v;                           // C
160712027Sjungma@eit.uni-kl.de    num = concat((num % v), low_half(u_AB)); // num = (((r|A) % v)|B)
160812027Sjungma@eit.uni-kl.de    (*u) = concat(q_h, num / v);             // q = C|D
160912027Sjungma@eit.uni-kl.de    r = num % v;
161012027Sjungma@eit.uni-kl.de
161112027Sjungma@eit.uni-kl.de  }
161212027Sjungma@eit.uni-kl.de
161312027Sjungma@eit.uni-kl.de#undef q_h
161412027Sjungma@eit.uni-kl.de
161512027Sjungma@eit.uni-kl.de  return r;
161612027Sjungma@eit.uni-kl.de
161712027Sjungma@eit.uni-kl.de}
161812027Sjungma@eit.uni-kl.de
161912027Sjungma@eit.uni-kl.de// Set (uchar) v = (sc_digit) u. Return the new vlen.
162012027Sjungma@eit.uni-kl.deint
162112027Sjungma@eit.uni-kl.devec_to_char(int ulen, const sc_digit *u,
162212027Sjungma@eit.uni-kl.de            int vlen, uchar *v)
162312027Sjungma@eit.uni-kl.de{
162412027Sjungma@eit.uni-kl.de
162512027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
162612027Sjungma@eit.uni-kl.de  assert((ulen > 0) && (u != NULL));
162712027Sjungma@eit.uni-kl.de  assert((vlen > 0) && (v != NULL));
162812027Sjungma@eit.uni-kl.de#endif
162912027Sjungma@eit.uni-kl.de
163012027Sjungma@eit.uni-kl.de  int nbits = ulen * BITS_PER_DIGIT;
163112027Sjungma@eit.uni-kl.de
163212027Sjungma@eit.uni-kl.de  int right = 0;
163312027Sjungma@eit.uni-kl.de  int left = right + BITS_PER_BYTE - 1;
163412027Sjungma@eit.uni-kl.de
163512027Sjungma@eit.uni-kl.de  vlen = 0;
163612027Sjungma@eit.uni-kl.de
163712027Sjungma@eit.uni-kl.de  while (nbits > 0) {
163812027Sjungma@eit.uni-kl.de
163912027Sjungma@eit.uni-kl.de    int left_digit = left / BITS_PER_DIGIT;
164012027Sjungma@eit.uni-kl.de    int right_digit = right / BITS_PER_DIGIT;
164112027Sjungma@eit.uni-kl.de
164212027Sjungma@eit.uni-kl.de    int nsr = ((vlen << LOG2_BITS_PER_BYTE) % BITS_PER_DIGIT);
164312027Sjungma@eit.uni-kl.de
164412027Sjungma@eit.uni-kl.de    int d = u[right_digit] >> nsr;
164512027Sjungma@eit.uni-kl.de
164612027Sjungma@eit.uni-kl.de    if (left_digit != right_digit) {
164712027Sjungma@eit.uni-kl.de
164812027Sjungma@eit.uni-kl.de      if (left_digit < ulen)
164912027Sjungma@eit.uni-kl.de        d |= u[left_digit] << (BITS_PER_DIGIT - nsr);
165012027Sjungma@eit.uni-kl.de
165112027Sjungma@eit.uni-kl.de    }
165212027Sjungma@eit.uni-kl.de
165312027Sjungma@eit.uni-kl.de    v[vlen++] = (uchar)(d & BYTE_MASK);
165412027Sjungma@eit.uni-kl.de
165512027Sjungma@eit.uni-kl.de    left += BITS_PER_BYTE;
165612027Sjungma@eit.uni-kl.de    right += BITS_PER_BYTE;
165712027Sjungma@eit.uni-kl.de    nbits -= BITS_PER_BYTE;
165812027Sjungma@eit.uni-kl.de
165912027Sjungma@eit.uni-kl.de  }
166012027Sjungma@eit.uni-kl.de
166112027Sjungma@eit.uni-kl.de  return vlen;
166212027Sjungma@eit.uni-kl.de
166312027Sjungma@eit.uni-kl.de}
166412027Sjungma@eit.uni-kl.de
166512027Sjungma@eit.uni-kl.de// Set (sc_digit) v = (uchar) u.
166612027Sjungma@eit.uni-kl.de// - sizeof(uchar) <= sizeof(sc_digit),
166712027Sjungma@eit.uni-kl.devoid
166812027Sjungma@eit.uni-kl.devec_from_char(int ulen, const uchar *u,
166912027Sjungma@eit.uni-kl.de              int vlen, sc_digit *v)
167012027Sjungma@eit.uni-kl.de{
167112027Sjungma@eit.uni-kl.de
167212027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
167312027Sjungma@eit.uni-kl.de  assert((ulen > 0) && (u != NULL));
167412027Sjungma@eit.uni-kl.de  assert((vlen > 0) && (v != NULL));
167512027Sjungma@eit.uni-kl.de  assert(sizeof(uchar) <= sizeof(sc_digit));
167612027Sjungma@eit.uni-kl.de#endif
167712027Sjungma@eit.uni-kl.de
167812027Sjungma@eit.uni-kl.de  sc_digit *vend = (v + vlen);
167912027Sjungma@eit.uni-kl.de
168012027Sjungma@eit.uni-kl.de  const int nsr = BITS_PER_DIGIT - BITS_PER_BYTE;
168112027Sjungma@eit.uni-kl.de  const sc_digit mask = one_and_ones(nsr);
168212027Sjungma@eit.uni-kl.de
168312027Sjungma@eit.uni-kl.de  (*v) = (sc_digit) u[ulen - 1];
168412027Sjungma@eit.uni-kl.de
168512027Sjungma@eit.uni-kl.de  for (int i = ulen - 2; i >= 0; --i) {
168612027Sjungma@eit.uni-kl.de
168712027Sjungma@eit.uni-kl.de    // Manual inlining of vec_shift_left().
168812027Sjungma@eit.uni-kl.de
168912027Sjungma@eit.uni-kl.de    sc_digit *viter = v;
169012027Sjungma@eit.uni-kl.de
169112027Sjungma@eit.uni-kl.de    sc_digit carry = 0;
169212027Sjungma@eit.uni-kl.de
169312027Sjungma@eit.uni-kl.de    while (viter < vend) {
169412027Sjungma@eit.uni-kl.de      sc_digit vval = (*viter);
169512027Sjungma@eit.uni-kl.de      (*viter++) = (((vval & mask) << BITS_PER_BYTE) | carry);
169612027Sjungma@eit.uni-kl.de      carry = vval >> nsr;
169712027Sjungma@eit.uni-kl.de    }
169812027Sjungma@eit.uni-kl.de
169912027Sjungma@eit.uni-kl.de    if (viter < vend)
170012027Sjungma@eit.uni-kl.de      (*viter) = carry;
170112027Sjungma@eit.uni-kl.de
170212027Sjungma@eit.uni-kl.de    (*v) |= (sc_digit) u[i];
170312027Sjungma@eit.uni-kl.de
170412027Sjungma@eit.uni-kl.de  }
170512027Sjungma@eit.uni-kl.de
170612027Sjungma@eit.uni-kl.de}
170712027Sjungma@eit.uni-kl.de
170812027Sjungma@eit.uni-kl.de// Set u <<= nsl.
170912027Sjungma@eit.uni-kl.de// If nsl is negative, it is ignored.
171012027Sjungma@eit.uni-kl.devoid
171112027Sjungma@eit.uni-kl.devec_shift_left(int ulen, sc_digit *u, int nsl)
171212027Sjungma@eit.uni-kl.de{
171312027Sjungma@eit.uni-kl.de
171412027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
171512027Sjungma@eit.uni-kl.de  assert((ulen > 0) && (u != NULL));
171612027Sjungma@eit.uni-kl.de#endif
171712027Sjungma@eit.uni-kl.de
171812027Sjungma@eit.uni-kl.de  if (nsl <= 0)
171912027Sjungma@eit.uni-kl.de    return;
172012027Sjungma@eit.uni-kl.de
172112027Sjungma@eit.uni-kl.de  // Shift left whole digits if nsl is large enough.
172212027Sjungma@eit.uni-kl.de  if (nsl >= (int) BITS_PER_DIGIT) {
172312027Sjungma@eit.uni-kl.de
172412027Sjungma@eit.uni-kl.de    int nd;
172512027Sjungma@eit.uni-kl.de
172612027Sjungma@eit.uni-kl.de    if (nsl % BITS_PER_DIGIT == 0) {
172712027Sjungma@eit.uni-kl.de      nd = nsl / BITS_PER_DIGIT;  // No need to use DIV_CEIL(nsl).
172812027Sjungma@eit.uni-kl.de      nsl = 0;
172912027Sjungma@eit.uni-kl.de    }
173012027Sjungma@eit.uni-kl.de    else {
173112027Sjungma@eit.uni-kl.de      nd = DIV_CEIL(nsl) - 1;
173212027Sjungma@eit.uni-kl.de      nsl -= nd * BITS_PER_DIGIT;
173312027Sjungma@eit.uni-kl.de    }
173412027Sjungma@eit.uni-kl.de
173512027Sjungma@eit.uni-kl.de    if (nd) {
173612027Sjungma@eit.uni-kl.de
173712027Sjungma@eit.uni-kl.de      // Shift left for nd digits.
173812027Sjungma@eit.uni-kl.de      for (int j = ulen - 1; j >= nd; --j)
173912027Sjungma@eit.uni-kl.de        u[j] = u[j - nd];
174012027Sjungma@eit.uni-kl.de
174112027Sjungma@eit.uni-kl.de      vec_zero( sc_min( nd, ulen ), u );
174212027Sjungma@eit.uni-kl.de
174312027Sjungma@eit.uni-kl.de    }
174412027Sjungma@eit.uni-kl.de
174512027Sjungma@eit.uni-kl.de    if (nsl == 0)
174612027Sjungma@eit.uni-kl.de      return;
174712027Sjungma@eit.uni-kl.de
174812027Sjungma@eit.uni-kl.de  }
174912027Sjungma@eit.uni-kl.de
175012027Sjungma@eit.uni-kl.de  // Shift left if nsl < BITS_PER_DIGIT.
175112027Sjungma@eit.uni-kl.de  sc_digit *uiter = u;
175212027Sjungma@eit.uni-kl.de  sc_digit *uend = uiter + ulen;
175312027Sjungma@eit.uni-kl.de
175412027Sjungma@eit.uni-kl.de  int nsr = BITS_PER_DIGIT - nsl;
175512027Sjungma@eit.uni-kl.de  sc_digit mask = one_and_ones(nsr);
175612027Sjungma@eit.uni-kl.de
175712027Sjungma@eit.uni-kl.de  sc_digit carry = 0;
175812027Sjungma@eit.uni-kl.de
175912027Sjungma@eit.uni-kl.de  while (uiter < uend) {
176012027Sjungma@eit.uni-kl.de    sc_digit uval = (*uiter);
176112027Sjungma@eit.uni-kl.de    (*uiter++) = (((uval & mask) << nsl) | carry);
176212027Sjungma@eit.uni-kl.de    carry = uval >> nsr;
176312027Sjungma@eit.uni-kl.de  }
176412027Sjungma@eit.uni-kl.de
176512027Sjungma@eit.uni-kl.de  if (uiter < uend)
176612027Sjungma@eit.uni-kl.de    (*uiter) = carry;
176712027Sjungma@eit.uni-kl.de
176812027Sjungma@eit.uni-kl.de}
176912027Sjungma@eit.uni-kl.de
177012027Sjungma@eit.uni-kl.de// Set u >>= nsr.
177112027Sjungma@eit.uni-kl.de// If nsr is negative, it is ignored.
177212027Sjungma@eit.uni-kl.devoid
177312027Sjungma@eit.uni-kl.devec_shift_right(int ulen, sc_digit *u, int nsr, sc_digit fill)
177412027Sjungma@eit.uni-kl.de{
177512027Sjungma@eit.uni-kl.de
177612027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
177712027Sjungma@eit.uni-kl.de  assert((ulen > 0) && (u != NULL));
177812027Sjungma@eit.uni-kl.de#endif
177912027Sjungma@eit.uni-kl.de
178012027Sjungma@eit.uni-kl.de  // fill is usually either 0 or DIGIT_MASK; it can be any value.
178112027Sjungma@eit.uni-kl.de
178212027Sjungma@eit.uni-kl.de  if (nsr <= 0)
178312027Sjungma@eit.uni-kl.de    return;
178412027Sjungma@eit.uni-kl.de
178512027Sjungma@eit.uni-kl.de  // Shift right whole digits if nsr is large enough.
178612027Sjungma@eit.uni-kl.de  if (nsr >= (int) BITS_PER_DIGIT) {
178712027Sjungma@eit.uni-kl.de
178812027Sjungma@eit.uni-kl.de    int nd;
178912027Sjungma@eit.uni-kl.de
179012027Sjungma@eit.uni-kl.de    if (nsr % BITS_PER_DIGIT == 0) {
179112027Sjungma@eit.uni-kl.de      nd = nsr / BITS_PER_DIGIT;
179212027Sjungma@eit.uni-kl.de      nsr = 0;
179312027Sjungma@eit.uni-kl.de    }
179412027Sjungma@eit.uni-kl.de    else {
179512027Sjungma@eit.uni-kl.de      nd = DIV_CEIL(nsr) - 1;
179612027Sjungma@eit.uni-kl.de      nsr -= nd * BITS_PER_DIGIT;
179712027Sjungma@eit.uni-kl.de    }
179812027Sjungma@eit.uni-kl.de
179912027Sjungma@eit.uni-kl.de    if (nd) {
180012027Sjungma@eit.uni-kl.de
180112027Sjungma@eit.uni-kl.de      // Shift right for nd digits.
180212027Sjungma@eit.uni-kl.de      for (int j = 0; j < (ulen - nd); ++j)
180312027Sjungma@eit.uni-kl.de        u[j] = u[j + nd];
180412027Sjungma@eit.uni-kl.de
180512027Sjungma@eit.uni-kl.de      if (fill) {
180612027Sjungma@eit.uni-kl.de        for (int j = ulen - sc_min( nd, ulen ); j < ulen; ++j)
180712027Sjungma@eit.uni-kl.de          u[j] = fill;
180812027Sjungma@eit.uni-kl.de      }
180912027Sjungma@eit.uni-kl.de      else
181012027Sjungma@eit.uni-kl.de        vec_zero(ulen - sc_min( nd, ulen ), ulen, u);
181112027Sjungma@eit.uni-kl.de
181212027Sjungma@eit.uni-kl.de    }
181312027Sjungma@eit.uni-kl.de
181412027Sjungma@eit.uni-kl.de    if (nsr == 0)
181512027Sjungma@eit.uni-kl.de      return;
181612027Sjungma@eit.uni-kl.de
181712027Sjungma@eit.uni-kl.de  }
181812027Sjungma@eit.uni-kl.de
181912027Sjungma@eit.uni-kl.de  // Shift right if nsr < BITS_PER_DIGIT.
182012027Sjungma@eit.uni-kl.de  sc_digit *ubegin = u;
182112027Sjungma@eit.uni-kl.de  sc_digit *uiter = (ubegin + ulen);
182212027Sjungma@eit.uni-kl.de
182312027Sjungma@eit.uni-kl.de  int nsl = BITS_PER_DIGIT - nsr;
182412027Sjungma@eit.uni-kl.de  sc_digit mask = one_and_ones(nsr);
182512027Sjungma@eit.uni-kl.de
182612027Sjungma@eit.uni-kl.de  sc_digit carry = (fill & mask) << nsl;
182712027Sjungma@eit.uni-kl.de
182812027Sjungma@eit.uni-kl.de  while (ubegin < uiter) {
182912027Sjungma@eit.uni-kl.de    sc_digit uval = (*--uiter);
183012027Sjungma@eit.uni-kl.de    (*uiter) = (uval >> nsr) | carry;
183112027Sjungma@eit.uni-kl.de    carry = (uval & mask) << nsl;
183212027Sjungma@eit.uni-kl.de  }
183312027Sjungma@eit.uni-kl.de
183412027Sjungma@eit.uni-kl.de}
183512027Sjungma@eit.uni-kl.de
183612027Sjungma@eit.uni-kl.de
183712027Sjungma@eit.uni-kl.de// Let u[l..r], where l and r are left and right bit positions
183812027Sjungma@eit.uni-kl.de// respectively, be equal to its mirror image.
183912027Sjungma@eit.uni-kl.devoid
184012027Sjungma@eit.uni-kl.devec_reverse(int unb, int und, sc_digit *ud,
184112027Sjungma@eit.uni-kl.de            int l, int r)
184212027Sjungma@eit.uni-kl.de{
184312027Sjungma@eit.uni-kl.de
184412027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
184512027Sjungma@eit.uni-kl.de  assert((unb > 0) && (und > 0) && (ud != NULL));
184612027Sjungma@eit.uni-kl.de  assert((0 <= r) && (r <= l) && (l < unb));
184712027Sjungma@eit.uni-kl.de#endif
184812027Sjungma@eit.uni-kl.de
184912027Sjungma@eit.uni-kl.de  if (l < r) {
185012027Sjungma@eit.uni-kl.de      char msg[BUFSIZ];
185112027Sjungma@eit.uni-kl.de      std::sprintf( msg, "vec_reverse( int, int, sc_digit*, int l, int r ) : "
185212027Sjungma@eit.uni-kl.de	       "l = %d < r = %d is not valid",
185312027Sjungma@eit.uni-kl.de	       l, r );
185412027Sjungma@eit.uni-kl.de      SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
185512027Sjungma@eit.uni-kl.de  }
185612027Sjungma@eit.uni-kl.de
185712027Sjungma@eit.uni-kl.de  // Make sure that l and r are within bounds.
185812027Sjungma@eit.uni-kl.de  r = sc_max(r, 0);
185912027Sjungma@eit.uni-kl.de  l = sc_min(l, unb - 1);
186012027Sjungma@eit.uni-kl.de
186112027Sjungma@eit.uni-kl.de  // Allocate memory for processing.
186212027Sjungma@eit.uni-kl.de#ifdef SC_MAX_NBITS
186312027Sjungma@eit.uni-kl.de  sc_digit d[MAX_NDIGITS];
186412027Sjungma@eit.uni-kl.de#else
186512027Sjungma@eit.uni-kl.de  sc_digit *d = new sc_digit[und];
186612027Sjungma@eit.uni-kl.de#endif
186712027Sjungma@eit.uni-kl.de
186812027Sjungma@eit.uni-kl.de  // d is a copy of ud.
186912027Sjungma@eit.uni-kl.de  vec_copy(und, d, ud);
187012027Sjungma@eit.uni-kl.de
187112027Sjungma@eit.uni-kl.de  // Based on the value of the ith in d, find the value of the jth bit
187212027Sjungma@eit.uni-kl.de  // in ud.
187312027Sjungma@eit.uni-kl.de
187412027Sjungma@eit.uni-kl.de  for (int i = l, j = r; i >= r; --i, ++j) {
187512027Sjungma@eit.uni-kl.de
187612027Sjungma@eit.uni-kl.de    if ((d[digit_ord(i)] & one_and_zeros(bit_ord(i))) != 0) // Test.
187712027Sjungma@eit.uni-kl.de      ud[digit_ord(j)] |= one_and_zeros(bit_ord(j));     // Set.
187812027Sjungma@eit.uni-kl.de    else
187912027Sjungma@eit.uni-kl.de      ud[digit_ord(j)] &= ~(one_and_zeros(bit_ord(j)));  // Clear.
188012027Sjungma@eit.uni-kl.de
188112027Sjungma@eit.uni-kl.de  }
188212027Sjungma@eit.uni-kl.de
188312027Sjungma@eit.uni-kl.de#ifndef SC_MAX_NBITS
188412027Sjungma@eit.uni-kl.de  delete [] d;
188512027Sjungma@eit.uni-kl.de#endif
188612027Sjungma@eit.uni-kl.de
188712027Sjungma@eit.uni-kl.de}
188812027Sjungma@eit.uni-kl.de
188912027Sjungma@eit.uni-kl.de} // namespace sc_dt
189012027Sjungma@eit.uni-kl.de
189112027Sjungma@eit.uni-kl.de
189212027Sjungma@eit.uni-kl.de// End of file.
1893