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