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