sc_nbutils.hh revision 12853
112853Sgabeblack@google.com/***************************************************************************** 212853Sgabeblack@google.com 312853Sgabeblack@google.com Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 412853Sgabeblack@google.com more contributor license agreements. See the NOTICE file distributed 512853Sgabeblack@google.com with this work for additional information regarding copyright ownership. 612853Sgabeblack@google.com Accellera licenses this file to you under the Apache License, Version 2.0 712853Sgabeblack@google.com (the "License"); you may not use this file except in compliance with the 812853Sgabeblack@google.com License. You may obtain a copy of the License at 912853Sgabeblack@google.com 1012853Sgabeblack@google.com http://www.apache.org/licenses/LICENSE-2.0 1112853Sgabeblack@google.com 1212853Sgabeblack@google.com Unless required by applicable law or agreed to in writing, software 1312853Sgabeblack@google.com distributed under the License is distributed on an "AS IS" BASIS, 1412853Sgabeblack@google.com WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 1512853Sgabeblack@google.com implied. See the License for the specific language governing 1612853Sgabeblack@google.com permissions and limitations under the License. 1712853Sgabeblack@google.com 1812853Sgabeblack@google.com *****************************************************************************/ 1912853Sgabeblack@google.com 2012853Sgabeblack@google.com/***************************************************************************** 2112853Sgabeblack@google.com 2212853Sgabeblack@google.com sc_nbutils.h -- External and friend functions for both sc_signed and 2312853Sgabeblack@google.com sc_unsigned classes. 2412853Sgabeblack@google.com 2512853Sgabeblack@google.com Original Author: Ali Dasdan, Synopsys, Inc. 2612853Sgabeblack@google.com 2712853Sgabeblack@google.com *****************************************************************************/ 2812853Sgabeblack@google.com 2912853Sgabeblack@google.com/***************************************************************************** 3012853Sgabeblack@google.com 3112853Sgabeblack@google.com MODIFICATION LOG - modifiers, enter your name, affiliation, date and 3212853Sgabeblack@google.com changes you are making here. 3312853Sgabeblack@google.com 3412853Sgabeblack@google.com Name, Affiliation, Date: 3512853Sgabeblack@google.com Description of Modification: 3612853Sgabeblack@google.com 3712853Sgabeblack@google.com *****************************************************************************/ 3812853Sgabeblack@google.com 3912853Sgabeblack@google.com// $Log: sc_nbutils.h,v $ 4012853Sgabeblack@google.com// Revision 1.6 2011/09/08 16:12:15 acg 4112853Sgabeblack@google.com// Philipp A. Hartmann: fix issue with Sun machines wrt real math libraries. 4212853Sgabeblack@google.com// 4312853Sgabeblack@google.com// Revision 1.5 2011/08/26 23:00:01 acg 4412853Sgabeblack@google.com// Torsten Maehne: remove use of ieeefp.h. 4512853Sgabeblack@google.com// 4612853Sgabeblack@google.com// Revision 1.4 2011/08/15 16:43:24 acg 4712853Sgabeblack@google.com// Torsten Maehne: changes to remove unused argument warnings. 4812853Sgabeblack@google.com// 4912853Sgabeblack@google.com// Revision 1.3 2011/02/18 20:19:15 acg 5012853Sgabeblack@google.com// Andy Goodrich: updating Copyright notice. 5112853Sgabeblack@google.com// 5212853Sgabeblack@google.com// Revision 1.2 2010/09/06 16:35:48 acg 5312853Sgabeblack@google.com// Andy Goodrich: changed i386 to __i386__ in ifdef's. 5412853Sgabeblack@google.com// 5512853Sgabeblack@google.com// Revision 1.1.1.1 2006/12/15 20:20:05 acg 5612853Sgabeblack@google.com// SystemC 2.3 5712853Sgabeblack@google.com// 5812853Sgabeblack@google.com// Revision 1.3 2006/01/13 18:49:32 acg 5912853Sgabeblack@google.com// Added $Log command so that CVS check in comments are reproduced in the 6012853Sgabeblack@google.com// source. 6112853Sgabeblack@google.com// 6212853Sgabeblack@google.com 6312853Sgabeblack@google.com#ifndef __SYSTEMC_EXT_DT_INT_SC_NBUTILS_HH__ 6412853Sgabeblack@google.com#define __SYSTEMC_EXT_DT_INT_SC_NBUTILS_HH__ 6512853Sgabeblack@google.com 6612853Sgabeblack@google.com#include <cmath> 6712853Sgabeblack@google.com#include <ios> 6812853Sgabeblack@google.com#include <limits> 6912853Sgabeblack@google.com#include <ostream> 7012853Sgabeblack@google.com 7112853Sgabeblack@google.com#include "../../utils/sc_report_handler.hh" 7212853Sgabeblack@google.com#include "sc_nbdefs.hh" 7312853Sgabeblack@google.com 7412853Sgabeblack@google.comnamespace sc_dt 7512853Sgabeblack@google.com{ 7612853Sgabeblack@google.com 7712853Sgabeblack@google.com//----------------------------------------------------------------------------- 7812853Sgabeblack@google.com//"sc_io_base" 7912853Sgabeblack@google.com// 8012853Sgabeblack@google.com// This inline function returns the type of an i/o stream's base as a SystemC 8112853Sgabeblack@google.com// base designator. 8212853Sgabeblack@google.com// stream_object = reference to the i/o stream whose base is to be returned. 8312853Sgabeblack@google.com// 8412853Sgabeblack@google.com//"sc_io_show_base" 8512853Sgabeblack@google.com// 8612853Sgabeblack@google.com// This inline function returns true if the base should be shown when a SystemC 8712853Sgabeblack@google.com// value is displayed via the supplied stream operator. 8812853Sgabeblack@google.com// stream_object = reference to the i/o stream to return showbase value for. 8912853Sgabeblack@google.com//----------------------------------------------------------------------------- 9012853Sgabeblack@google.cominline sc_numrep 9112853Sgabeblack@google.comsc_io_base(::std::ostream &os, sc_numrep def_base) 9212853Sgabeblack@google.com{ 9312853Sgabeblack@google.com std::ios::fmtflags flags = os.flags() & std::ios::basefield; 9412853Sgabeblack@google.com if (flags & ::std::ios::dec) return SC_DEC; 9512853Sgabeblack@google.com if (flags & ::std::ios::hex) return SC_HEX; 9612853Sgabeblack@google.com if (flags & ::std::ios::oct) return SC_OCT; 9712853Sgabeblack@google.com return def_base; 9812853Sgabeblack@google.com} 9912853Sgabeblack@google.com 10012853Sgabeblack@google.cominline bool 10112853Sgabeblack@google.comsc_io_show_base(::std::ostream &os) 10212853Sgabeblack@google.com{ 10312853Sgabeblack@google.com return (os.flags() & ::std::ios::showbase) != 0; 10412853Sgabeblack@google.com} 10512853Sgabeblack@google.com 10612853Sgabeblack@google.comconst std::string to_string(sc_numrep); 10712853Sgabeblack@google.com 10812853Sgabeblack@google.cominline ::std::ostream & 10912853Sgabeblack@google.comoperator << (::std::ostream &os, sc_numrep numrep) 11012853Sgabeblack@google.com{ 11112853Sgabeblack@google.com os << to_string(numrep); 11212853Sgabeblack@google.com return os; 11312853Sgabeblack@google.com} 11412853Sgabeblack@google.com 11512853Sgabeblack@google.com// ---------------------------------------------------------------------------- 11612853Sgabeblack@google.com 11712853Sgabeblack@google.com// One transition of the FSM to find base and sign of a number. 11812853Sgabeblack@google.comextern small_type fsm_move( 11912853Sgabeblack@google.com char c, small_type &b, small_type &s, small_type &state); 12012853Sgabeblack@google.com 12112853Sgabeblack@google.com// Parse a character string into its equivalent binary bits. 12212853Sgabeblack@google.comextern void parse_binary_bits( 12312853Sgabeblack@google.com const char *src_p, int dst_n, sc_digit *data_p, sc_digit *ctrl_p=0); 12412853Sgabeblack@google.com 12512853Sgabeblack@google.com// Parse a character string into its equivalent hexadecimal bits. 12612853Sgabeblack@google.comextern void parse_hex_bits( 12712853Sgabeblack@google.com const char *src_p, int dst_n, sc_digit *data_p, sc_digit *ctrl_p=0); 12812853Sgabeblack@google.com 12912853Sgabeblack@google.com// Find the base and sign of a number in v. 13012853Sgabeblack@google.comextern const char *get_base_and_sign( 13112853Sgabeblack@google.com const char *v, small_type &base, small_type &sign); 13212853Sgabeblack@google.com 13312853Sgabeblack@google.com// Create a number out of v in base. 13412853Sgabeblack@google.comextern small_type 13512853Sgabeblack@google.comvec_from_str(int unb, int und, sc_digit *u, 13612853Sgabeblack@google.com const char *v, sc_numrep base=SC_NOBASE); 13712853Sgabeblack@google.com 13812853Sgabeblack@google.com 13912853Sgabeblack@google.com// ---------------------------------------------------------------------------- 14012853Sgabeblack@google.com// Naming convention for the vec_ functions below: 14112853Sgabeblack@google.com// vec_OP(u, v, w) : computes w = u OP v. 14212853Sgabeblack@google.com// vec_OP_on(u, v) : computes u = u OP v if u has more digits than v. 14312853Sgabeblack@google.com// vec_OP_on2(u, v) : computes u = u OP v if u has fewer digits than v. 14412853Sgabeblack@google.com// _large : parameters are vectors. 14512853Sgabeblack@google.com// _small : one of the parameters is a single digit. 14612853Sgabeblack@google.com// Xlen : the number of digits in X. 14712853Sgabeblack@google.com// ---------------------------------------------------------------------------- 14812853Sgabeblack@google.com 14912853Sgabeblack@google.com// ---------------------------------------------------------------------------- 15012853Sgabeblack@google.com// Functions for vector addition: w = u + v or u += v. 15112853Sgabeblack@google.com// ---------------------------------------------------------------------------- 15212853Sgabeblack@google.com 15312853Sgabeblack@google.comextern void vec_add(int ulen, const sc_digit *u, 15412853Sgabeblack@google.com int vlen, const sc_digit *v, sc_digit *w); 15512853Sgabeblack@google.comextern void vec_add_on(int ulen, sc_digit *u, int vlen, const sc_digit *v); 15612853Sgabeblack@google.comextern void vec_add_on2(int ulen, sc_digit *u, int vlen, const sc_digit *v); 15712853Sgabeblack@google.comextern void vec_add_small(int ulen, const sc_digit *u, 15812853Sgabeblack@google.com sc_digit v, sc_digit *w); 15912853Sgabeblack@google.comextern void vec_add_small_on(int ulen, sc_digit *u, sc_digit v); 16012853Sgabeblack@google.com 16112853Sgabeblack@google.com// ---------------------------------------------------------------------------- 16212853Sgabeblack@google.com// Functions for vector subtraction: w = u - v, u -= v, or u = v - u. 16312853Sgabeblack@google.com// ---------------------------------------------------------------------------- 16412853Sgabeblack@google.com 16512853Sgabeblack@google.comextern void vec_sub(int ulen, const sc_digit *u, 16612853Sgabeblack@google.com int vlen, const sc_digit *v, sc_digit *w); 16712853Sgabeblack@google.comextern void vec_sub_on(int ulen, sc_digit *u, int vlen, const sc_digit *v); 16812853Sgabeblack@google.comextern void vec_sub_on2(int ulen, sc_digit *u, int vlen, const sc_digit *v); 16912853Sgabeblack@google.comextern void vec_sub_small(int ulen, const sc_digit *u, 17012853Sgabeblack@google.com sc_digit v, sc_digit *w); 17112853Sgabeblack@google.comextern void vec_sub_small_on(int ulen, sc_digit *u, sc_digit v); 17212853Sgabeblack@google.com 17312853Sgabeblack@google.com 17412853Sgabeblack@google.com// ---------------------------------------------------------------------------- 17512853Sgabeblack@google.com// Functions for vector multiplication: w = u * v or u *= v. 17612853Sgabeblack@google.com// ---------------------------------------------------------------------------- 17712853Sgabeblack@google.com 17812853Sgabeblack@google.comextern void vec_mul(int ulen, const sc_digit *u, 17912853Sgabeblack@google.com int vlen, const sc_digit *v, sc_digit *w); 18012853Sgabeblack@google.comextern void vec_mul_small(int ulen, const sc_digit *u, 18112853Sgabeblack@google.com sc_digit v, sc_digit *w); 18212853Sgabeblack@google.comextern void vec_mul_small_on(int ulen, sc_digit *u, sc_digit v); 18312853Sgabeblack@google.com 18412853Sgabeblack@google.com 18512853Sgabeblack@google.com// ---------------------------------------------------------------------------- 18612853Sgabeblack@google.com// Functions for vector division: w = u / v. 18712853Sgabeblack@google.com// ---------------------------------------------------------------------------- 18812853Sgabeblack@google.com 18912853Sgabeblack@google.comextern void vec_div_large(int ulen, const sc_digit *u, 19012853Sgabeblack@google.com int vlen, const sc_digit *v, sc_digit *w); 19112853Sgabeblack@google.comextern void vec_div_small(int ulen, const sc_digit *u, 19212853Sgabeblack@google.com sc_digit v, sc_digit *w); 19312853Sgabeblack@google.com 19412853Sgabeblack@google.com 19512853Sgabeblack@google.com// ---------------------------------------------------------------------------- 19612853Sgabeblack@google.com// Functions for vector remainder: w = u % v or u %= v. 19712853Sgabeblack@google.com// ---------------------------------------------------------------------------- 19812853Sgabeblack@google.com 19912853Sgabeblack@google.comextern void vec_rem_large(int ulen, const sc_digit *u, 20012853Sgabeblack@google.com int vlen, const sc_digit *v, sc_digit *w); 20112853Sgabeblack@google.comextern sc_digit vec_rem_small(int ulen, const sc_digit *u, sc_digit v); 20212853Sgabeblack@google.comextern sc_digit vec_rem_on_small(int ulen, sc_digit *u, sc_digit v); 20312853Sgabeblack@google.com 20412853Sgabeblack@google.com 20512853Sgabeblack@google.com// ---------------------------------------------------------------------------- 20612853Sgabeblack@google.com// Functions to convert between vectors of char and sc_digit. 20712853Sgabeblack@google.com// ---------------------------------------------------------------------------- 20812853Sgabeblack@google.com 20912853Sgabeblack@google.comextern int vec_to_char(int ulen, const sc_digit *u, int vlen, uchar *v); 21012853Sgabeblack@google.comextern void vec_from_char(int ulen, const uchar *u, int vlen, sc_digit *v); 21112853Sgabeblack@google.com 21212853Sgabeblack@google.com 21312853Sgabeblack@google.com// ---------------------------------------------------------------------------- 21412853Sgabeblack@google.com// Functions to shift left or right, or to create a mirror image of vectors. 21512853Sgabeblack@google.com// ---------------------------------------------------------------------------- 21612853Sgabeblack@google.com 21712853Sgabeblack@google.comextern void vec_shift_left(int ulen, sc_digit *u, int nsl); 21812853Sgabeblack@google.comextern void vec_shift_right(int vlen, sc_digit *u, int nsr, sc_digit fill=0); 21912853Sgabeblack@google.comextern void vec_reverse(int unb, int und, sc_digit *ud, int l, int r=0); 22012853Sgabeblack@google.com 22112853Sgabeblack@google.com 22212853Sgabeblack@google.com// ---------------------------------------------------------------------------- 22312853Sgabeblack@google.com// Various utility functions. 22412853Sgabeblack@google.com// ---------------------------------------------------------------------------- 22512853Sgabeblack@google.com 22612853Sgabeblack@google.com// Return the low half part of d. 22712853Sgabeblack@google.cominline sc_digit low_half(sc_digit d) { return (d & HALF_DIGIT_MASK); } 22812853Sgabeblack@google.com 22912853Sgabeblack@google.com// Return the high half part of d. The high part of the digit may have 23012853Sgabeblack@google.com// more bits than BITS_PER_HALF_DIGIT due to, e.g., overflow in the 23112853Sgabeblack@google.com// multiplication. Hence, in other functions that use high_half(), 23212853Sgabeblack@google.com// make sure that the result contains BITS_PER_HALF_DIGIT if 23312853Sgabeblack@google.com// necessary. This is done by high_half_masked(). 23412853Sgabeblack@google.cominline sc_digit high_half(sc_digit d) { return (d >> BITS_PER_HALF_DIGIT); } 23512853Sgabeblack@google.cominline sc_digit 23612853Sgabeblack@google.comhigh_half_masked(sc_digit d) 23712853Sgabeblack@google.com{ 23812853Sgabeblack@google.com return (high_half(d) & HALF_DIGIT_MASK); 23912853Sgabeblack@google.com} 24012853Sgabeblack@google.com 24112853Sgabeblack@google.com// Concatenate the high part h and low part l. Assumes that h and l 24212853Sgabeblack@google.com// are less than or equal to HALF_DIGIT_MASK; 24312853Sgabeblack@google.cominline sc_digit 24412853Sgabeblack@google.comconcat(sc_digit h, sc_digit l) 24512853Sgabeblack@google.com{ 24612853Sgabeblack@google.com return ((h << BITS_PER_HALF_DIGIT) | l); 24712853Sgabeblack@google.com} 24812853Sgabeblack@google.com 24912853Sgabeblack@google.com// Create a number with n 1's. 25012853Sgabeblack@google.cominline sc_digit 25112853Sgabeblack@google.comone_and_ones(int n) 25212853Sgabeblack@google.com{ 25312853Sgabeblack@google.com return (((sc_digit) 1 << n) - 1); 25412853Sgabeblack@google.com} 25512853Sgabeblack@google.com 25612853Sgabeblack@google.com// Create a number with one 1 and n 0's. 25712853Sgabeblack@google.cominline sc_digit one_and_zeros(int n) { return ((sc_digit) 1 << n); } 25812853Sgabeblack@google.com 25912853Sgabeblack@google.com 26012853Sgabeblack@google.com// ---------------------------------------------------------------------------- 26112853Sgabeblack@google.com 26212853Sgabeblack@google.com// Find the digit that bit i is in. 26312853Sgabeblack@google.cominline int digit_ord(int i) { return (i / BITS_PER_DIGIT); } 26412853Sgabeblack@google.com 26512853Sgabeblack@google.com// Find the bit in digit_ord(i) that bit i corressponds to. 26612853Sgabeblack@google.cominline int bit_ord(int i) { return (i % BITS_PER_DIGIT); } 26712853Sgabeblack@google.com 26812853Sgabeblack@google.com 26912853Sgabeblack@google.com// ---------------------------------------------------------------------------- 27012853Sgabeblack@google.com// Functions to compare, zero, complement vector(s). 27112853Sgabeblack@google.com// ---------------------------------------------------------------------------- 27212853Sgabeblack@google.com 27312853Sgabeblack@google.com// Compare u and v and return r 27412853Sgabeblack@google.com// r = 0 if u == v 27512853Sgabeblack@google.com// r < 0 if u < v 27612853Sgabeblack@google.com// r > 0 if u > v 27712853Sgabeblack@google.com// - Assume that all the leading zero digits are already skipped. 27812853Sgabeblack@google.com// - ulen and/or vlen can be zero. 27912853Sgabeblack@google.com// - Every digit is less than or equal to DIGIT_MASK; 28012853Sgabeblack@google.cominline int 28112853Sgabeblack@google.comvec_cmp(int ulen, const sc_digit *u, 28212853Sgabeblack@google.com int vlen, const sc_digit *v) 28312853Sgabeblack@google.com{ 28412853Sgabeblack@google.com 28512853Sgabeblack@google.com#ifdef DEBUG_SYSTEMC 28612853Sgabeblack@google.com // sc_assert((ulen <= 0) || (u != NULL)); 28712853Sgabeblack@google.com // sc_assert((vlen <= 0) || (v != NULL)); 28812853Sgabeblack@google.com 28912853Sgabeblack@google.com // ulen and vlen can be equal to 0 because vec_cmp can be called 29012853Sgabeblack@google.com // after vec_skip_leading_zeros. 29112853Sgabeblack@google.com sc_assert((ulen >= 0) && (u != NULL)); 29212853Sgabeblack@google.com sc_assert((vlen >= 0) && (v != NULL)); 29312853Sgabeblack@google.com // If ulen > 0, then the leading digit of u must be non-zero. 29412853Sgabeblack@google.com sc_assert((ulen <= 0) || (u[ulen - 1] != 0)); 29512853Sgabeblack@google.com sc_assert((vlen <= 0) || (v[vlen - 1] != 0)); 29612853Sgabeblack@google.com#endif 29712853Sgabeblack@google.com 29812853Sgabeblack@google.com if (ulen != vlen) 29912853Sgabeblack@google.com return (ulen - vlen); 30012853Sgabeblack@google.com 30112853Sgabeblack@google.com // ulen == vlen >= 1 30212853Sgabeblack@google.com while ((--ulen >= 0) && (u[ulen] == v[ulen])) 30312853Sgabeblack@google.com {} 30412853Sgabeblack@google.com 30512853Sgabeblack@google.com if (ulen < 0) 30612853Sgabeblack@google.com return 0; 30712853Sgabeblack@google.com 30812853Sgabeblack@google.com#ifdef DEBUG_SYSTEMC 30912853Sgabeblack@google.com // Test to see if the result is wrong due to the presence of 31012853Sgabeblack@google.com // overflow bits. 31112853Sgabeblack@google.com sc_assert((u[ulen] & DIGIT_MASK) != (v[ulen] & DIGIT_MASK)); 31212853Sgabeblack@google.com#endif 31312853Sgabeblack@google.com 31412853Sgabeblack@google.com return (int)(u[ulen] - v[ulen]); 31512853Sgabeblack@google.com} 31612853Sgabeblack@google.com 31712853Sgabeblack@google.com// Find the index of the first non-zero digit. 31812853Sgabeblack@google.com// - ulen (before) = the number of digits in u. 31912853Sgabeblack@google.com// - the returned value = the index of the first non-zero digit. 32012853Sgabeblack@google.com// A negative value of -1 indicates that every digit in u is zero. 32112853Sgabeblack@google.cominline int 32212853Sgabeblack@google.comvec_find_first_nonzero(int ulen, const sc_digit *u) 32312853Sgabeblack@google.com{ 32412853Sgabeblack@google.com 32512853Sgabeblack@google.com#ifdef DEBUG_SYSTEMC 32612853Sgabeblack@google.com // sc_assert((ulen <= 0) || (u != NULL)); 32712853Sgabeblack@google.com sc_assert((ulen > 0) && (u != NULL)); 32812853Sgabeblack@google.com#endif 32912853Sgabeblack@google.com 33012853Sgabeblack@google.com while ((--ulen >= 0) && (! u[ulen])) 33112853Sgabeblack@google.com {} 33212853Sgabeblack@google.com 33312853Sgabeblack@google.com return ulen; 33412853Sgabeblack@google.com} 33512853Sgabeblack@google.com 33612853Sgabeblack@google.com// Skip all the leading zero digits. 33712853Sgabeblack@google.com// - ulen (before) = the number of digits in u. 33812853Sgabeblack@google.com// - the returned value = the number of non-zero digits in u. 33912853Sgabeblack@google.com// - the returned value is non-negative. 34012853Sgabeblack@google.cominline int 34112853Sgabeblack@google.comvec_skip_leading_zeros(int ulen, const sc_digit *u) 34212853Sgabeblack@google.com{ 34312853Sgabeblack@google.com#ifdef DEBUG_SYSTEMC 34412853Sgabeblack@google.com // sc_assert((ulen <= 0) || (u != NULL)); 34512853Sgabeblack@google.com sc_assert((ulen > 0) && (u != NULL)); 34612853Sgabeblack@google.com#endif 34712853Sgabeblack@google.com 34812853Sgabeblack@google.com return (1 + vec_find_first_nonzero(ulen, u)); 34912853Sgabeblack@google.com} 35012853Sgabeblack@google.com 35112853Sgabeblack@google.com// Compare u and v and return r 35212853Sgabeblack@google.com// r = 0 if u == v 35312853Sgabeblack@google.com// r < 0 if u < v 35412853Sgabeblack@google.com// r > 0 if u > v 35512853Sgabeblack@google.cominline int 35612853Sgabeblack@google.comvec_skip_and_cmp(int ulen, const sc_digit *u, int vlen, const sc_digit *v) 35712853Sgabeblack@google.com{ 35812853Sgabeblack@google.com#ifdef DEBUG_SYSTEMC 35912853Sgabeblack@google.com sc_assert((ulen > 0) && (u != NULL)); 36012853Sgabeblack@google.com sc_assert((vlen > 0) && (v != NULL)); 36112853Sgabeblack@google.com#endif 36212853Sgabeblack@google.com 36312853Sgabeblack@google.com ulen = vec_skip_leading_zeros(ulen, u); 36412853Sgabeblack@google.com vlen = vec_skip_leading_zeros(vlen, v); 36512853Sgabeblack@google.com // ulen and/or vlen can be equal to zero here. 36612853Sgabeblack@google.com return vec_cmp(ulen, u, vlen, v); 36712853Sgabeblack@google.com} 36812853Sgabeblack@google.com 36912853Sgabeblack@google.com// Set u[i] = 0 where i = from ... (ulen - 1). 37012853Sgabeblack@google.cominline void 37112853Sgabeblack@google.comvec_zero(int from, int ulen, sc_digit *u) 37212853Sgabeblack@google.com{ 37312853Sgabeblack@google.com#ifdef DEBUG_SYSTEMC 37412853Sgabeblack@google.com sc_assert((ulen > 0) && (u != NULL)); 37512853Sgabeblack@google.com#endif 37612853Sgabeblack@google.com for (int i = from; i < ulen; i++) 37712853Sgabeblack@google.com u[i] = 0; 37812853Sgabeblack@google.com} 37912853Sgabeblack@google.com 38012853Sgabeblack@google.com// Set u[i] = 0 where i = 0 .. (ulen - 1). 38112853Sgabeblack@google.cominline void vec_zero(int ulen, sc_digit *u) { vec_zero(0, ulen, u); } 38212853Sgabeblack@google.com 38312853Sgabeblack@google.com// Copy n digits from v to u. 38412853Sgabeblack@google.cominline void 38512853Sgabeblack@google.comvec_copy(int n, sc_digit *u, const sc_digit *v) 38612853Sgabeblack@google.com{ 38712853Sgabeblack@google.com#ifdef DEBUG_SYSTEMC 38812853Sgabeblack@google.com sc_assert((n > 0) && (u != NULL) && (v != NULL)); 38912853Sgabeblack@google.com#endif 39012853Sgabeblack@google.com for (int i = 0; i < n; ++i) 39112853Sgabeblack@google.com u[i] = v[i]; 39212853Sgabeblack@google.com} 39312853Sgabeblack@google.com 39412853Sgabeblack@google.com// Copy v to u, where ulen >= vlen, and zero the rest of the digits in u. 39512853Sgabeblack@google.cominline void 39612853Sgabeblack@google.comvec_copy_and_zero(int ulen, sc_digit *u, int vlen, const sc_digit *v) 39712853Sgabeblack@google.com{ 39812853Sgabeblack@google.com 39912853Sgabeblack@google.com#ifdef DEBUG_SYSTEMC 40012853Sgabeblack@google.com sc_assert((ulen > 0) && (u != NULL)); 40112853Sgabeblack@google.com sc_assert((vlen > 0) && (v != NULL)); 40212853Sgabeblack@google.com sc_assert(ulen >= vlen); 40312853Sgabeblack@google.com#endif 40412853Sgabeblack@google.com vec_copy(vlen, u, v); 40512853Sgabeblack@google.com vec_zero(vlen, ulen, u); 40612853Sgabeblack@google.com 40712853Sgabeblack@google.com} 40812853Sgabeblack@google.com 40912853Sgabeblack@google.com// 2's-complement the digits in u. 41012853Sgabeblack@google.cominline void 41112853Sgabeblack@google.comvec_complement(int ulen, sc_digit *u) 41212853Sgabeblack@google.com{ 41312853Sgabeblack@google.com 41412853Sgabeblack@google.com#ifdef DEBUG_SYSTEMC 41512853Sgabeblack@google.com sc_assert((ulen > 0) && (u != NULL)); 41612853Sgabeblack@google.com#endif 41712853Sgabeblack@google.com 41812853Sgabeblack@google.com sc_digit carry = 1; 41912853Sgabeblack@google.com 42012853Sgabeblack@google.com for (int i = 0; i < ulen; ++i) { 42112853Sgabeblack@google.com carry += (~u[i] & DIGIT_MASK); 42212853Sgabeblack@google.com u[i] = carry & DIGIT_MASK; 42312853Sgabeblack@google.com carry >>= BITS_PER_DIGIT; 42412853Sgabeblack@google.com } 42512853Sgabeblack@google.com} 42612853Sgabeblack@google.com 42712853Sgabeblack@google.com 42812853Sgabeblack@google.com// ---------------------------------------------------------------------------- 42912853Sgabeblack@google.com// Functions to handle built-in types or signs. 43012853Sgabeblack@google.com// ---------------------------------------------------------------------------- 43112853Sgabeblack@google.com 43212853Sgabeblack@google.com// u = v 43312853Sgabeblack@google.com// - v is an unsigned long or uint64, and positive integer. 43412853Sgabeblack@google.comtemplate<class Type> 43512853Sgabeblack@google.cominline void 43612853Sgabeblack@google.comfrom_uint(int ulen, sc_digit *u, Type v) 43712853Sgabeblack@google.com{ 43812853Sgabeblack@google.com#ifdef DEBUG_SYSTEMC 43912853Sgabeblack@google.com // sc_assert((ulen <= 0) || (u != NULL)); 44012853Sgabeblack@google.com sc_assert((ulen > 0) && (u != NULL)); 44112853Sgabeblack@google.com sc_assert(v >= 0); 44212853Sgabeblack@google.com#endif 44312853Sgabeblack@google.com 44412853Sgabeblack@google.com int i = 0; 44512853Sgabeblack@google.com 44612853Sgabeblack@google.com while (v && (i < ulen)) { 44712853Sgabeblack@google.com u[i++] = static_cast<sc_digit>(v & DIGIT_MASK); 44812853Sgabeblack@google.com v >>= BITS_PER_DIGIT; 44912853Sgabeblack@google.com } 45012853Sgabeblack@google.com vec_zero(i, ulen, u); 45112853Sgabeblack@google.com} 45212853Sgabeblack@google.com 45312853Sgabeblack@google.com#ifndef __GNUC__ 45412853Sgabeblack@google.com# define SC_LIKELY_(x) !!(x) 45512853Sgabeblack@google.com#else 45612853Sgabeblack@google.com# define SC_LIKELY_(x) __builtin_expect(!!(x), 1) 45712853Sgabeblack@google.com#endif 45812853Sgabeblack@google.com 45912853Sgabeblack@google.com// Get u's sign and return its absolute value. 46012853Sgabeblack@google.com// u can be long, unsigned long, int64, or uint64. 46112853Sgabeblack@google.comtemplate<class Type> 46212853Sgabeblack@google.cominline small_type 46312853Sgabeblack@google.comget_sign(Type &u) 46412853Sgabeblack@google.com{ 46512853Sgabeblack@google.com if (u > 0) 46612853Sgabeblack@google.com return SC_POS; 46712853Sgabeblack@google.com 46812853Sgabeblack@google.com if (u == 0) 46912853Sgabeblack@google.com return SC_ZERO; 47012853Sgabeblack@google.com 47112853Sgabeblack@google.com // no positive number representable for minimum value, 47212853Sgabeblack@google.com // leave as is to avoid Undefined Behaviour 47312853Sgabeblack@google.com if (SC_LIKELY_(u > (std::numeric_limits<Type>::min)())) 47412853Sgabeblack@google.com u = -u; 47512853Sgabeblack@google.com 47612853Sgabeblack@google.com return SC_NEG; 47712853Sgabeblack@google.com} 47812853Sgabeblack@google.com 47912853Sgabeblack@google.com#undef SC_LIKELY_ 48012853Sgabeblack@google.com 48112853Sgabeblack@google.com 48212853Sgabeblack@google.com// Return us * vs: 48312853Sgabeblack@google.com// - Return SC_ZERO if either sign is SC_ZERO. 48412853Sgabeblack@google.com// - Return SC_POS if us == vs 48512853Sgabeblack@google.com// - Return SC_NEG if us != vs. 48612853Sgabeblack@google.cominline small_type 48712853Sgabeblack@google.commul_signs(small_type us, small_type vs) 48812853Sgabeblack@google.com{ 48912853Sgabeblack@google.com if ((us == SC_ZERO) || (vs == SC_ZERO)) 49012853Sgabeblack@google.com return SC_ZERO; 49112853Sgabeblack@google.com 49212853Sgabeblack@google.com if (us == vs) 49312853Sgabeblack@google.com return SC_POS; 49412853Sgabeblack@google.com 49512853Sgabeblack@google.com return SC_NEG; 49612853Sgabeblack@google.com} 49712853Sgabeblack@google.com 49812853Sgabeblack@google.com 49912853Sgabeblack@google.com// ---------------------------------------------------------------------------- 50012853Sgabeblack@google.com// Functions to test for errors and print out error messages. 50112853Sgabeblack@google.com// ---------------------------------------------------------------------------- 50212853Sgabeblack@google.com 50312853Sgabeblack@google.com#ifdef SC_MAX_NBITS 50412853Sgabeblack@google.com 50512853Sgabeblack@google.comvoid test_bound_failed(int nb); 50612853Sgabeblack@google.com 50712853Sgabeblack@google.cominline void 50812853Sgabeblack@google.comtest_bound(int nb) 50912853Sgabeblack@google.com{ 51012853Sgabeblack@google.com if (nb > SC_MAX_NBITS) { 51112853Sgabeblack@google.com test_bound_failed(nb); 51212853Sgabeblack@google.com sc_core::sc_abort(); // can't recover from here 51312853Sgabeblack@google.com } 51412853Sgabeblack@google.com} 51512853Sgabeblack@google.com 51612853Sgabeblack@google.com#endif 51712853Sgabeblack@google.com 51812853Sgabeblack@google.comtemplate<class Type> 51912853Sgabeblack@google.cominline void 52012853Sgabeblack@google.comdiv_by_zero(Type s) 52112853Sgabeblack@google.com{ 52212853Sgabeblack@google.com if (s == 0) { 52312853Sgabeblack@google.com SC_REPORT_ERROR("operation failed", 52412853Sgabeblack@google.com "div_by_zero<Type>(Type) : division by zero"); 52512853Sgabeblack@google.com sc_core::sc_abort(); // can't recover from here 52612853Sgabeblack@google.com } 52712853Sgabeblack@google.com} 52812853Sgabeblack@google.com 52912853Sgabeblack@google.com 53012853Sgabeblack@google.com// ---------------------------------------------------------------------------- 53112853Sgabeblack@google.com// Functions to check if a given vector is zero or make one. 53212853Sgabeblack@google.com// ---------------------------------------------------------------------------- 53312853Sgabeblack@google.com 53412853Sgabeblack@google.com// If u[i] is zero for every i = 0,..., ulen - 1, return SC_ZERO, 53512853Sgabeblack@google.com// else return s. 53612853Sgabeblack@google.cominline small_type 53712853Sgabeblack@google.comcheck_for_zero(small_type s, int ulen, const sc_digit *u) 53812853Sgabeblack@google.com{ 53912853Sgabeblack@google.com 54012853Sgabeblack@google.com#ifdef DEBUG_SYSTEMC 54112853Sgabeblack@google.com // sc_assert(ulen >= 0); 54212853Sgabeblack@google.com sc_assert((ulen > 0) && (u != NULL)); 54312853Sgabeblack@google.com#endif 54412853Sgabeblack@google.com 54512853Sgabeblack@google.com if (vec_find_first_nonzero(ulen, u) < 0) 54612853Sgabeblack@google.com return SC_ZERO; 54712853Sgabeblack@google.com 54812853Sgabeblack@google.com return s; 54912853Sgabeblack@google.com} 55012853Sgabeblack@google.com 55112853Sgabeblack@google.com// If u[i] is zero for every i = 0,..., ulen - 1, return true, 55212853Sgabeblack@google.com// else return false. 55312853Sgabeblack@google.cominline bool 55412853Sgabeblack@google.comcheck_for_zero(int ulen, const sc_digit *u) 55512853Sgabeblack@google.com{ 55612853Sgabeblack@google.com 55712853Sgabeblack@google.com#ifdef DEBUG_SYSTEMC 55812853Sgabeblack@google.com // sc_assert(ulen >= 0); 55912853Sgabeblack@google.com sc_assert((ulen > 0) && (u != NULL)); 56012853Sgabeblack@google.com#endif 56112853Sgabeblack@google.com 56212853Sgabeblack@google.com if (vec_find_first_nonzero(ulen, u) < 0) 56312853Sgabeblack@google.com return true; 56412853Sgabeblack@google.com 56512853Sgabeblack@google.com return false; 56612853Sgabeblack@google.com} 56712853Sgabeblack@google.com 56812853Sgabeblack@google.cominline small_type 56912853Sgabeblack@google.commake_zero(int nd, sc_digit *d) 57012853Sgabeblack@google.com{ 57112853Sgabeblack@google.com vec_zero(nd, d); 57212853Sgabeblack@google.com return SC_ZERO; 57312853Sgabeblack@google.com} 57412853Sgabeblack@google.com 57512853Sgabeblack@google.com 57612853Sgabeblack@google.com// ---------------------------------------------------------------------------- 57712853Sgabeblack@google.com// Functions for both signed and unsigned numbers to convert sign-magnitude 57812853Sgabeblack@google.com// (SM) and 2's complement (2C) representations. 57912853Sgabeblack@google.com// added = 1 => for signed. 58012853Sgabeblack@google.com// added = 0 => for unsigned. 58112853Sgabeblack@google.com// IF_SC_SIGNED can be used as 'added'. 58212853Sgabeblack@google.com// ---------------------------------------------------------------------------- 58312853Sgabeblack@google.com 58412853Sgabeblack@google.com// Trim the extra leading bits of a signed or unsigned number. 58512853Sgabeblack@google.cominline void 58612853Sgabeblack@google.comtrim(small_type added, int nb, int nd, sc_digit *d) 58712853Sgabeblack@google.com{ 58812853Sgabeblack@google.com#ifdef DEBUG_SYSTEMC 58912853Sgabeblack@google.com sc_assert((nb > 0) && (nd > 0) && (d != NULL)); 59012853Sgabeblack@google.com#endif 59112853Sgabeblack@google.com d[nd - 1] &= one_and_ones(bit_ord(nb - 1) + added); 59212853Sgabeblack@google.com} 59312853Sgabeblack@google.com 59412853Sgabeblack@google.com// Convert an (un)signed number from sign-magnitude representation to 59512853Sgabeblack@google.com// 2's complement representation and trim the extra bits. 59612853Sgabeblack@google.cominline void 59712853Sgabeblack@google.comconvert_SM_to_2C_trimmed(small_type added, 59812853Sgabeblack@google.com small_type s, int nb, int nd, sc_digit *d) 59912853Sgabeblack@google.com{ 60012853Sgabeblack@google.com if (s == SC_NEG) { 60112853Sgabeblack@google.com vec_complement(nd, d); 60212853Sgabeblack@google.com trim(added, nb, nd, d); 60312853Sgabeblack@google.com } 60412853Sgabeblack@google.com} 60512853Sgabeblack@google.com 60612853Sgabeblack@google.com// Convert an (un)signed number from sign-magnitude representation to 60712853Sgabeblack@google.com// 2's complement representation but do not trim the extra bits. 60812853Sgabeblack@google.cominline void 60912853Sgabeblack@google.comconvert_SM_to_2C(small_type s, int nd, sc_digit *d) 61012853Sgabeblack@google.com{ 61112853Sgabeblack@google.com if (s == SC_NEG) 61212853Sgabeblack@google.com vec_complement(nd, d); 61312853Sgabeblack@google.com} 61412853Sgabeblack@google.com 61512853Sgabeblack@google.com 61612853Sgabeblack@google.com// ---------------------------------------------------------------------------- 61712853Sgabeblack@google.com// Functions to convert between sign-magnitude (SM) and 2's complement 61812853Sgabeblack@google.com// (2C) representations of signed numbers. 61912853Sgabeblack@google.com// ---------------------------------------------------------------------------- 62012853Sgabeblack@google.com 62112853Sgabeblack@google.com// Trim the extra leading bits off a signed number. 62212853Sgabeblack@google.cominline void 62312853Sgabeblack@google.comtrim_signed(int nb, int nd, sc_digit *d) 62412853Sgabeblack@google.com{ 62512853Sgabeblack@google.com#ifdef DEBUG_SYSTEMC 62612853Sgabeblack@google.com sc_assert((nb > 0) && (nd > 0) && (d != NULL)); 62712853Sgabeblack@google.com#endif 62812853Sgabeblack@google.com d[nd - 1] &= one_and_ones(bit_ord(nb - 1) + 1); 62912853Sgabeblack@google.com} 63012853Sgabeblack@google.com 63112853Sgabeblack@google.com// Convert a signed number from 2's complement representation to 63212853Sgabeblack@google.com// sign-magnitude representation, and return its sign. nd is d's 63312853Sgabeblack@google.com// actual size, without zeros eliminated. 63412853Sgabeblack@google.cominline small_type 63512853Sgabeblack@google.comconvert_signed_2C_to_SM(int nb, int nd, sc_digit *d) 63612853Sgabeblack@google.com{ 63712853Sgabeblack@google.com#ifdef DEBUG_SYSTEMC 63812853Sgabeblack@google.com sc_assert((nb > 0) && (nd > 0) && (d != NULL)); 63912853Sgabeblack@google.com#endif 64012853Sgabeblack@google.com 64112853Sgabeblack@google.com small_type s; 64212853Sgabeblack@google.com 64312853Sgabeblack@google.com int xnb = bit_ord(nb - 1) + 1; 64412853Sgabeblack@google.com 64512853Sgabeblack@google.com // Test the sign bit. 64612853Sgabeblack@google.com if (d[nd - 1] & one_and_zeros(xnb - 1)) { 64712853Sgabeblack@google.com s = SC_NEG; 64812853Sgabeblack@google.com vec_complement(nd, d); 64912853Sgabeblack@google.com } else { 65012853Sgabeblack@google.com s = SC_POS; 65112853Sgabeblack@google.com } 65212853Sgabeblack@google.com 65312853Sgabeblack@google.com // Trim the last digit. 65412853Sgabeblack@google.com d[nd - 1] &= one_and_ones(xnb); 65512853Sgabeblack@google.com 65612853Sgabeblack@google.com // Check if the new number is zero. 65712853Sgabeblack@google.com if (s == SC_POS) 65812853Sgabeblack@google.com return check_for_zero(s, nd, d); 65912853Sgabeblack@google.com 66012853Sgabeblack@google.com return s; 66112853Sgabeblack@google.com} 66212853Sgabeblack@google.com 66312853Sgabeblack@google.com// Convert a signed number from sign-magnitude representation to 2's 66412853Sgabeblack@google.com// complement representation, get its sign, convert back to 66512853Sgabeblack@google.com// sign-magnitude representation, and return its sign. nd is d's 66612853Sgabeblack@google.com// actual size, without zeros eliminated. 66712853Sgabeblack@google.cominline small_type 66812853Sgabeblack@google.comconvert_signed_SM_to_2C_to_SM(small_type s, int nb, int nd, sc_digit *d) 66912853Sgabeblack@google.com{ 67012853Sgabeblack@google.com convert_SM_to_2C(s, nd, d); 67112853Sgabeblack@google.com return convert_signed_2C_to_SM(nb, nd, d); 67212853Sgabeblack@google.com} 67312853Sgabeblack@google.com 67412853Sgabeblack@google.com// Convert a signed number from sign-magnitude representation to 2's 67512853Sgabeblack@google.com// complement representation and trim the extra bits. 67612853Sgabeblack@google.cominline void 67712853Sgabeblack@google.comconvert_signed_SM_to_2C_trimmed(small_type s, int nb, int nd, sc_digit *d) 67812853Sgabeblack@google.com{ 67912853Sgabeblack@google.com convert_SM_to_2C_trimmed(1, s, nb, nd, d); 68012853Sgabeblack@google.com} 68112853Sgabeblack@google.com 68212853Sgabeblack@google.com// Convert a signed number from sign-magnitude representation to 2's 68312853Sgabeblack@google.com// complement representation but do not trim the extra bits. 68412853Sgabeblack@google.cominline void 68512853Sgabeblack@google.comconvert_signed_SM_to_2C(small_type s, int nd, sc_digit *d) 68612853Sgabeblack@google.com{ 68712853Sgabeblack@google.com convert_SM_to_2C(s, nd, d); 68812853Sgabeblack@google.com} 68912853Sgabeblack@google.com 69012853Sgabeblack@google.com 69112853Sgabeblack@google.com// ---------------------------------------------------------------------------- 69212853Sgabeblack@google.com// Functions to convert between sign-magnitude (SM) and 2's complement 69312853Sgabeblack@google.com// (2C) representations of unsigned numbers. 69412853Sgabeblack@google.com// ---------------------------------------------------------------------------- 69512853Sgabeblack@google.com 69612853Sgabeblack@google.com// Trim the extra leading bits off an unsigned number. 69712853Sgabeblack@google.cominline void 69812853Sgabeblack@google.comtrim_unsigned(int nb, int nd, sc_digit *d) 69912853Sgabeblack@google.com{ 70012853Sgabeblack@google.com#ifdef DEBUG_SYSTEMC 70112853Sgabeblack@google.com sc_assert((nb > 0) && (nd > 0) && (d != NULL)); 70212853Sgabeblack@google.com#endif 70312853Sgabeblack@google.com 70412853Sgabeblack@google.com d[nd - 1] &= one_and_ones(bit_ord(nb - 1)); 70512853Sgabeblack@google.com} 70612853Sgabeblack@google.com 70712853Sgabeblack@google.com// Convert an unsigned number from 2's complement representation to 70812853Sgabeblack@google.com// sign-magnitude representation, and return its sign. nd is d's 70912853Sgabeblack@google.com// actual size, without zeros eliminated. 71012853Sgabeblack@google.cominline small_type 71112853Sgabeblack@google.comconvert_unsigned_2C_to_SM(int nb, int nd, sc_digit *d) 71212853Sgabeblack@google.com{ 71312853Sgabeblack@google.com trim_unsigned(nb, nd, d); 71412853Sgabeblack@google.com return check_for_zero(SC_POS, nd, d); 71512853Sgabeblack@google.com} 71612853Sgabeblack@google.com 71712853Sgabeblack@google.com// Convert an unsigned number from sign-magnitude representation to 71812853Sgabeblack@google.com// 2's complement representation, get its sign, convert back to 71912853Sgabeblack@google.com// sign-magnitude representation, and return its sign. nd is d's 72012853Sgabeblack@google.com// actual size, without zeros eliminated. 72112853Sgabeblack@google.cominline small_type 72212853Sgabeblack@google.comconvert_unsigned_SM_to_2C_to_SM(small_type s, int nb, int nd, sc_digit *d) 72312853Sgabeblack@google.com{ 72412853Sgabeblack@google.com convert_SM_to_2C(s, nd, d); 72512853Sgabeblack@google.com return convert_unsigned_2C_to_SM(nb, nd, d); 72612853Sgabeblack@google.com} 72712853Sgabeblack@google.com 72812853Sgabeblack@google.com// Convert an unsigned number from sign-magnitude representation to 72912853Sgabeblack@google.com// 2's complement representation and trim the extra bits. 73012853Sgabeblack@google.cominline void 73112853Sgabeblack@google.comconvert_unsigned_SM_to_2C_trimmed(small_type s, int nb, int nd, sc_digit *d) 73212853Sgabeblack@google.com{ 73312853Sgabeblack@google.com convert_SM_to_2C_trimmed(0, s, nb, nd, d); 73412853Sgabeblack@google.com} 73512853Sgabeblack@google.com 73612853Sgabeblack@google.com// Convert an unsigned number from sign-magnitude representation to 73712853Sgabeblack@google.com// 2's complement representation but do not trim the extra bits. 73812853Sgabeblack@google.cominline void 73912853Sgabeblack@google.comconvert_unsigned_SM_to_2C(small_type s, int nd, sc_digit *d) 74012853Sgabeblack@google.com{ 74112853Sgabeblack@google.com convert_SM_to_2C(s, nd, d); 74212853Sgabeblack@google.com} 74312853Sgabeblack@google.com 74412853Sgabeblack@google.com 74512853Sgabeblack@google.com// ---------------------------------------------------------------------------- 74612853Sgabeblack@google.com// Functions to copy one (un)signed number to another. 74712853Sgabeblack@google.com// ---------------------------------------------------------------------------- 74812853Sgabeblack@google.com 74912853Sgabeblack@google.com// Copy v to u. 75012853Sgabeblack@google.cominline void 75112853Sgabeblack@google.comcopy_digits_signed(small_type &us, 75212853Sgabeblack@google.com int unb, int und, sc_digit *ud, 75312853Sgabeblack@google.com int vnb, int vnd, const sc_digit *vd) 75412853Sgabeblack@google.com{ 75512853Sgabeblack@google.com if (und <= vnd) { 75612853Sgabeblack@google.com vec_copy(und, ud, vd); 75712853Sgabeblack@google.com 75812853Sgabeblack@google.com if (unb <= vnb) 75912853Sgabeblack@google.com us = convert_signed_SM_to_2C_to_SM(us, unb, und, ud); 76012853Sgabeblack@google.com } else { // und > vnd 76112853Sgabeblack@google.com vec_copy_and_zero(und, ud, vnd, vd); 76212853Sgabeblack@google.com } 76312853Sgabeblack@google.com} 76412853Sgabeblack@google.com 76512853Sgabeblack@google.com// Copy v to u. 76612853Sgabeblack@google.cominline void 76712853Sgabeblack@google.comcopy_digits_unsigned(small_type &us, 76812853Sgabeblack@google.com int unb, int und, sc_digit *ud, 76912853Sgabeblack@google.com int /* vnb */, int vnd, const sc_digit *vd) 77012853Sgabeblack@google.com{ 77112853Sgabeblack@google.com if (und <= vnd) 77212853Sgabeblack@google.com vec_copy(und, ud, vd); 77312853Sgabeblack@google.com else // und > vnd 77412853Sgabeblack@google.com vec_copy_and_zero(und, ud, vnd, vd); 77512853Sgabeblack@google.com 77612853Sgabeblack@google.com us = convert_unsigned_SM_to_2C_to_SM(us, unb, und, ud); 77712853Sgabeblack@google.com} 77812853Sgabeblack@google.com 77912853Sgabeblack@google.com 78012853Sgabeblack@google.com// ---------------------------------------------------------------------------- 78112853Sgabeblack@google.com// Faster set(i, v), without bound checking. 78212853Sgabeblack@google.com// ---------------------------------------------------------------------------- 78312853Sgabeblack@google.com 78412853Sgabeblack@google.com// A version of set(i, v) without bound checking. 78512853Sgabeblack@google.cominline void 78612853Sgabeblack@google.comsafe_set(int i, bool v, sc_digit *d) 78712853Sgabeblack@google.com{ 78812853Sgabeblack@google.com 78912853Sgabeblack@google.com#ifdef DEBUG_SYSTEMC 79012853Sgabeblack@google.com sc_assert((i >= 0) && (d != NULL)); 79112853Sgabeblack@google.com#endif 79212853Sgabeblack@google.com 79312853Sgabeblack@google.com int bit_num = bit_ord(i); 79412853Sgabeblack@google.com int digit_num = digit_ord(i); 79512853Sgabeblack@google.com 79612853Sgabeblack@google.com if (v) 79712853Sgabeblack@google.com d[digit_num] |= one_and_zeros(bit_num); 79812853Sgabeblack@google.com else 79912853Sgabeblack@google.com d[digit_num] &= ~(one_and_zeros(bit_num)); 80012853Sgabeblack@google.com} 80112853Sgabeblack@google.com 80212853Sgabeblack@google.com 80312853Sgabeblack@google.com// ---------------------------------------------------------------------------- 80412853Sgabeblack@google.com// Function to check if a double number is bad (NaN or infinite). 80512853Sgabeblack@google.com// ---------------------------------------------------------------------------- 80612853Sgabeblack@google.com 80712853Sgabeblack@google.cominline bool 80812853Sgabeblack@google.comis_nan(double v) 80912853Sgabeblack@google.com{ 81012853Sgabeblack@google.com return std::numeric_limits<double>::has_quiet_NaN && (v != v); 81112853Sgabeblack@google.com} 81212853Sgabeblack@google.com 81312853Sgabeblack@google.cominline bool 81412853Sgabeblack@google.comis_inf(double v) 81512853Sgabeblack@google.com{ 81612853Sgabeblack@google.com return v == std::numeric_limits<double>::infinity() || 81712853Sgabeblack@google.com v == -std::numeric_limits<double>::infinity(); 81812853Sgabeblack@google.com} 81912853Sgabeblack@google.com 82012853Sgabeblack@google.cominline void 82112853Sgabeblack@google.comis_bad_double(double v) 82212853Sgabeblack@google.com{ 82312853Sgabeblack@google.com // Windows throws exception. 82412853Sgabeblack@google.com if (is_nan(v) || is_inf(v)) 82512853Sgabeblack@google.com SC_REPORT_ERROR("value is not valid", 82612853Sgabeblack@google.com "is_bad_double(double v) : " 82712853Sgabeblack@google.com "v is not finite - NaN or Inf"); 82812853Sgabeblack@google.com} 82912853Sgabeblack@google.com 83012853Sgabeblack@google.com} // namespace sc_dt 83112853Sgabeblack@google.com 83212853Sgabeblack@google.com#endif // __SYSTEMC_EXT_DT_INT_SC_NBUTILS_HH__ 833