diff options
Diffstat (limited to 'ext/systemc/src/sysc/datatypes')
80 files changed, 65856 insertions, 0 deletions
diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_bit.cpp b/ext/systemc/src/sysc/datatypes/bit/sc_bit.cpp new file mode 100644 index 000000000..5401eaead --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/bit/sc_bit.cpp @@ -0,0 +1,138 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_bit.cpp -- Bit class. + + Original Author: Gene Bushuyev, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_bit.cpp,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.6 2006/04/12 20:17:52 acg +// Andy Goodrich: enabled deprecation message for sc_bit. +// +// Revision 1.5 2006/01/25 00:31:15 acg +// Andy Goodrich: Changed over to use a standard message id of +// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages. +// +// Revision 1.4 2006/01/24 20:50:55 acg +// Andy Goodrich: added warnings indicating that sc_bit is deprecated and that +// the C bool data type should be used in its place. +// +// Revision 1.3 2006/01/13 18:53:53 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#include "sysc/datatypes/bit/sc_bit.h" +#include "sysc/datatypes/bit/sc_bit_ids.h" +#include "sysc/utils/sc_utils_ids.h" +#include "sysc/datatypes/bit/sc_logic.h" + +#include <cstdio> + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// CLASS : sc_bit +// +// Bit class. +// Note: VSIA compatibility indicated. +// ---------------------------------------------------------------------------- + +// support methods + +void +sc_bit::invalid_value( char c ) +{ + char msg[BUFSIZ]; + std::sprintf( msg, "sc_bit( '%c' )", c ); + SC_REPORT_ERROR( sc_core::SC_ID_VALUE_NOT_VALID_, msg ); +} + +void +sc_bit::invalid_value( int i ) +{ + char msg[BUFSIZ]; + std::sprintf( msg, "sc_bit( %d )", i ); + SC_REPORT_ERROR( sc_core::SC_ID_VALUE_NOT_VALID_, msg ); +} + + +// constructors + +sc_bit::sc_bit( const sc_logic& a ) // non-VSIA + : m_val( a.to_bool() ) +{ + sc_deprecated_sc_bit(); +} + + +// assignment operators + +sc_bit& +sc_bit::operator = ( const sc_logic& b ) // non-VSIA +{ + return ( *this = sc_bit( b ) ); +} + + +// other methods + +void +sc_bit::scan( ::std::istream& is ) +{ + bool b; + is >> b; + *this = b; +} + +void sc_deprecated_sc_bit() +{ + static bool warn_sc_bit_deprecated=true; + if ( warn_sc_bit_deprecated ) + { + warn_sc_bit_deprecated=false; + SC_REPORT_INFO(sc_core::SC_ID_IEEE_1666_DEPRECATION_, + "sc_bit is deprecated, use bool instead"); + } +} + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_bit.h b/ext/systemc/src/sysc/datatypes/bit/sc_bit.h new file mode 100644 index 000000000..2703971b6 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/bit/sc_bit.h @@ -0,0 +1,407 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_bit.h -- Bit class. + + Original Author: Stan Y. Liao, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_bit.h,v $ +// Revision 1.2 2011/08/07 18:54:19 acg +// Philipp A. Hartmann: remove friend function declarations that implement +// code, and clean up how bit and logic operators are defined in general. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.6 2006/05/08 17:49:59 acg +// Andy Goodrich: Added David Long's declarations for friend operators, +// functions, and methods, to keep the Microsoft compiler happy. +// +// Revision 1.5 2006/04/12 20:17:52 acg +// Andy Goodrich: enabled deprecation message for sc_bit. +// +// Revision 1.4 2006/01/24 20:50:55 acg +// Andy Goodrich: added warnings indicating that sc_bit is deprecated and that +// the C bool data type should be used in its place. +// +// Revision 1.3 2006/01/13 18:53:53 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_BIT_H +#define SC_BIT_H + + +#include "sysc/datatypes/int/sc_nbdefs.h" +#include "sysc/utils/sc_iostream.h" + + +namespace sc_dt +{ + +// classes defined in this module +class sc_bit; + +// forward class declarations +class sc_logic; + +extern void sc_deprecated_sc_bit(); + +// ---------------------------------------------------------------------------- +// CLASS : sc_bit +// +// Bit class. +// Note: VSIA compatibility indicated. +// ---------------------------------------------------------------------------- + +class sc_bit +{ + // support methods + + static void invalid_value( char ); + static void invalid_value( int ); + + static bool to_value( char c ) + { + if( c != '0' && c != '1' ) { + invalid_value( c ); + } + return ( c == '0' ? false : true ); + } + + static bool to_value( int i ) + { + if( i != 0 && i != 1 ) { + invalid_value( i ); + } + return ( i == 0 ? false : true ); + } + static bool to_value( bool b ) + { return b; } + +#define DEFN_TO_VALUE_T(tp) \ + static bool to_value( tp i ) \ + { return to_value( (int) i); } + + DEFN_TO_VALUE_T(unsigned) + DEFN_TO_VALUE_T(long) + DEFN_TO_VALUE_T(unsigned long) + DEFN_TO_VALUE_T(int64) + DEFN_TO_VALUE_T(uint64) + +#undef DEFN_TO_VALUE_T + +public: + + // constructors + // MANDATORY + + sc_bit() + : m_val( false ) + { + sc_deprecated_sc_bit(); + } + +#define DEFN_CTOR_T(tp) \ + explicit sc_bit( tp a ) \ + : m_val( to_value(a) ) \ + { sc_deprecated_sc_bit(); } + + DEFN_CTOR_T(bool) + DEFN_CTOR_T(char) + DEFN_CTOR_T(int) + DEFN_CTOR_T(unsigned) + DEFN_CTOR_T(long) + DEFN_CTOR_T(unsigned long) + DEFN_CTOR_T(int64) + DEFN_CTOR_T(uint64) + +#undef DEFN_CTOR_T + + explicit sc_bit( const sc_logic& a ); // non-VSIA + + + // copy constructor + // MANDATORY + + sc_bit( const sc_bit& a ) + : m_val( a.m_val ) + {} + + + // destructor + // MANDATORY + + ~sc_bit() + {} + + + // assignment operators + // MANDATORY + + sc_bit& operator = ( const sc_bit& b ) + { m_val = b.m_val; return *this; } + +#define DEFN_ASN_OP_T(op,tp) \ + sc_bit& operator op( tp b ) \ + { return ( *this op sc_bit( b ) ); } +#define DEFN_ASN_OP(op) \ + DEFN_ASN_OP_T(op,int) \ + DEFN_ASN_OP_T(op,bool) \ + DEFN_ASN_OP_T(op,char) + + DEFN_ASN_OP(=) + DEFN_ASN_OP_T(=,int64) + DEFN_ASN_OP_T(=,uint64) + DEFN_ASN_OP_T(=,long) + DEFN_ASN_OP_T(=,unsigned long) + + sc_bit& operator = ( const sc_logic& b ); // non-VSIA + + + // bitwise assignment operators + + sc_bit& operator &= ( const sc_bit& b ) + { m_val = ( m_val && b.m_val ); return *this; } + + sc_bit& operator |= ( const sc_bit& b ) + { m_val = ( m_val || b.m_val ); return *this; } + + sc_bit& operator ^= ( const sc_bit& b ) + { m_val = ( m_val != b.m_val ); return *this; } + + DEFN_ASN_OP(&=) + DEFN_ASN_OP(|=) + DEFN_ASN_OP(^=) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP + + // conversions + // MANDATORY + + // implicit conversion to bool + + operator bool () const + { return m_val; } + + bool operator ! () const // non-VSIA + { return ! m_val; } + + + // explicit conversions + + bool to_bool() const // non-VSIA + { return m_val; } + + char to_char() const + { return ( m_val ? '1' : '0' ); } + + + // relational operators and functions + + // MANDATORY + + friend bool operator == ( const sc_bit& a, const sc_bit& b ); + friend bool operator != ( const sc_bit& a, const sc_bit& b ); + + // bitwise operators and functions + + // bitwise complement + + // MANDATORY + + friend const sc_bit operator ~ ( const sc_bit& a ); + + // RECOMMENDED + + sc_bit& b_not() + { m_val = ( ! m_val ); return *this; } + + // binary bit-wise operations + + friend const sc_bit operator | ( const sc_bit& a, const sc_bit& b ); + friend const sc_bit operator & ( const sc_bit& a, const sc_bit& b ); + friend const sc_bit operator ^ ( const sc_bit& a, const sc_bit& b ); + + // other methods + + void print( ::std::ostream& os = ::std::cout ) const + { os << to_bool(); } + + void scan( ::std::istream& = ::std::cin ); + +private: + bool m_val; +}; + +// ---------------------------------------------------------------------------- +// relational operators and functions + +#define DEFN_BIN_FUN_T(ret,fun,tp) \ + inline ret fun( const sc_bit& a, tp b ) \ + { return fun(a, sc_bit(b) ); } \ + inline ret fun( tp b, const sc_bit& a ) \ + { return fun( sc_bit(a), b ); } + +#define DEFN_BIN_FUN(ret,fun) \ + DEFN_BIN_FUN_T(ret,fun,bool) \ + DEFN_BIN_FUN_T(ret,fun,char) \ + DEFN_BIN_FUN_T(ret,fun,int) + +// MANDATORY + +inline bool operator == ( const sc_bit& a, const sc_bit& b ) + { return ( a.m_val == b.m_val ); } + +inline bool operator != ( const sc_bit& a, const sc_bit& b ) + { return ( a.m_val != b.m_val ); } + +DEFN_BIN_FUN(bool,operator==) +DEFN_BIN_FUN(bool,operator!=) + +// OPTIONAL + +inline bool equal( const sc_bit& a, const sc_bit& b ) + { return ( a == b ); } + +inline bool not_equal( const sc_bit& a, const sc_bit& b ) + { return ( a != b ); } + +DEFN_BIN_FUN(bool,equal) +DEFN_BIN_FUN(bool,not_equal) + +// ---------------------------------------------------------------------------- +// bitwise operators and functions + +// bitwise complement + + // MANDATORY + + inline const sc_bit operator ~ ( const sc_bit& a ) + { return sc_bit( ! a.m_val ); } + + + // OPTIONAL + + inline const sc_bit b_not( const sc_bit& a ) + { return ( ~ a ); } + + + // RECOMMENDED + + inline void b_not( sc_bit& r, const sc_bit& a ) + { r = ( ~ a ); } + + // binary bit-wise operations + + // MANDATORY + + inline const sc_bit operator & ( const sc_bit& a, const sc_bit& b ) + { return sc_bit( a.m_val && b.m_val ); } + + inline const sc_bit operator | ( const sc_bit& a, const sc_bit& b ) + { return sc_bit( a.m_val || b.m_val ); } + + inline const sc_bit operator ^ ( const sc_bit& a, const sc_bit& b ) + { return sc_bit( a.m_val != b.m_val ); } + + DEFN_BIN_FUN(const sc_bit,operator&) + DEFN_BIN_FUN(const sc_bit,operator|) + DEFN_BIN_FUN(const sc_bit,operator^) + + // OPTIONAL + + inline const sc_bit b_and ( const sc_bit& a, const sc_bit& b ) + { return a & b; } + + inline const sc_bit b_or ( const sc_bit& a, const sc_bit& b ) + { return a | b; } + + inline const sc_bit b_xor ( const sc_bit& a, const sc_bit& b ) + { return a ^ b; } + + DEFN_BIN_FUN(const sc_bit,b_and) + DEFN_BIN_FUN(const sc_bit,b_or) + DEFN_BIN_FUN(const sc_bit,b_xor) + + // RECOMMENDED + +#define DEFN_TRN_FUN_T(fun,tp) \ + inline void fun( sc_bit& r, const sc_bit& a, tp b ) \ + { r = fun( a, sc_bit(b) ); } \ + inline void fun( sc_bit& r, tp a, const sc_bit& b ) \ + { r = fun( sc_bit(a), b ); } + +#define DEFN_TRN_FUN(fun) \ + inline void fun( sc_bit& r, const sc_bit& a, const sc_bit& b ) \ + { r = fun( a , b ); } \ + DEFN_TRN_FUN_T(fun,int) \ + DEFN_TRN_FUN_T(fun,bool) \ + DEFN_TRN_FUN_T(fun,char) + + DEFN_TRN_FUN( b_and ) + DEFN_TRN_FUN( b_or ) + DEFN_TRN_FUN( b_xor ) + +#undef DEFN_BIN_FUN_T +#undef DEFN_BIN_FUN +#undef DEFN_TRN_FUN_T +#undef DEFN_TRN_FUN + + +// ---------------------------------------------------------------------------- + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_bit& a ) +{ + a.print( os ); + return os; +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_bit& a ) +{ + a.scan( is ); + return is; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_bit_ids.h b/ext/systemc/src/sysc/datatypes/bit/sc_bit_ids.h new file mode 100644 index 000000000..0e77e9078 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/bit/sc_bit_ids.h @@ -0,0 +1,106 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_bit_ids.h -- Report ids for the datatypes/bit code. + + Original Author: Martin Janssen, Synopsys, Inc., 2002-01-17 + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_bit_ids.h,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.5 2006/01/25 00:31:15 acg +// Andy Goodrich: Changed over to use a standard message id of +// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages. +// +// Revision 1.4 2006/01/24 20:50:55 acg +// Andy Goodrich: added warnings indicating that sc_bit is deprecated and that +// the C bool data type should be used in its place. +// +// Revision 1.3 2006/01/13 18:53:53 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_BIT_IDS_H +#define SC_BIT_IDS_H + + +#include "sysc/utils/sc_report.h" + + +// ---------------------------------------------------------------------------- +// Report ids (datatypes/bit) +// +// Report ids in the range of 200-299. +// ---------------------------------------------------------------------------- + +#ifndef SC_DEFINE_MESSAGE +#define SC_DEFINE_MESSAGE(id,unused1,unused2) \ + namespace sc_core { extern const char id[]; } +namespace sc_core { + extern const char SC_ID_REGISTER_ID_FAILED_[]; // in sc_report_handler.cpp +} +#endif + + +SC_DEFINE_MESSAGE( SC_ID_LENGTH_MISMATCH_, 200, + "length mismatch in bit/logic vector assignment" ) +SC_DEFINE_MESSAGE( SC_ID_INCOMPATIBLE_TYPES_, 201, + "incompatible types" ) +SC_DEFINE_MESSAGE( SC_ID_CANNOT_CONVERT_, 202, + "cannot perform conversion" ) +SC_DEFINE_MESSAGE( SC_ID_INCOMPATIBLE_VECTORS_, 203, + "incompatible vectors" ) +SC_DEFINE_MESSAGE( SC_ID_VALUE_NOT_VALID_, 204, + "value is not valid" ) +SC_DEFINE_MESSAGE( SC_ID_ZERO_LENGTH_, 205, + "zero length" ) +SC_DEFINE_MESSAGE( SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 206, + "vector contains 4-value logic" ) +SC_DEFINE_MESSAGE( SC_ID_SC_BV_CANNOT_CONTAIN_X_AND_Z_, 207, + "sc_bv cannot contain values X and Z" ) +SC_DEFINE_MESSAGE( SC_ID_VECTOR_TOO_LONG_, 208, + "vector is too long: truncated" ) +SC_DEFINE_MESSAGE( SC_ID_VECTOR_TOO_SHORT_, 209, + "vector is too short: 0-padded" ) +SC_DEFINE_MESSAGE( SC_ID_WRONG_VALUE_, 210, + "wrong value" ) +SC_DEFINE_MESSAGE( SC_ID_LOGIC_Z_TO_BOOL_, 211, + "sc_logic value 'Z' cannot be converted to bool" ) +SC_DEFINE_MESSAGE( SC_ID_LOGIC_X_TO_BOOL_, 212, + "sc_logic value 'X' cannot be converted to bool" ) + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_bit_proxies.h b/ext/systemc/src/sysc/datatypes/bit/sc_bit_proxies.h new file mode 100644 index 000000000..59d997181 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/bit/sc_bit_proxies.h @@ -0,0 +1,3884 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_bit_proxies.h -- Proxy classes for vector data types. + + Original Author: Gene Bushuyev, Synopsys, Inc. + + CHANGE LOG AT THE END OF THE FILE + *****************************************************************************/ + +#ifndef SC_BIT_PROXIES_H +#define SC_BIT_PROXIES_H + + +#include "sysc/datatypes/bit/sc_bit_ids.h" +#include "sysc/datatypes/bit/sc_proxy.h" + + +namespace sc_dt +{ + +// classes defined in this module +template <class X> class sc_bitref_r; +template <class X> class sc_bitref; +template <class X> class sc_subref_r; +template <class X> class sc_subref; +template <class X, class Y> class sc_concref_r; +template <class X, class Y> class sc_concref; + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_bitref_r<T> +// +// Proxy class for sc_proxy bit selection (r-value only). +// ---------------------------------------------------------------------------- + +template <class T> +class sc_bitref_r +{ + friend class sc_bv_base; + friend class sc_lv_base; + +public: + + // typedefs + + typedef typename T::traits_type traits_type; + typedef typename traits_type::bit_type bit_type; + + // constructor + + sc_bitref_r( const T& obj_, int index_ ) + : m_obj( CCAST<T&>( obj_ ) ), m_index( index_ ) + {} + + + // copy constructor + + sc_bitref_r( const sc_bitref_r<T>& a ) + : m_obj( a.m_obj ), m_index( a.m_index ) + {} + + // cloning + + sc_bitref_r<T>* clone() const + { return new sc_bitref_r<T>( *this ); } + + + // bitwise operators and functions + + // bitwise complement + + const bit_type operator ~ () const + { return bit_type( sc_logic::not_table[value()] ); } + + + // implicit conversion to bit_type + + operator const bit_type() const + { return bit_type( m_obj.get_bit( m_index ) ); } + + + // explicit conversions + + sc_logic_value_t value() const + { return m_obj.get_bit( m_index ); } + + + bool is_01() const + { return sc_logic( value() ).is_01(); } + + bool to_bool() const + { return sc_logic( value() ).to_bool(); } + + char to_char() const + { return sc_logic( value() ).to_char(); } + + + // common methods + + int length() const + { return 1; } + + int size() const + { return ( (length() - 1) / SC_DIGIT_SIZE + 1 ); } + + sc_logic_value_t get_bit( int n ) const; + + sc_digit get_word( int i ) const; + sc_digit get_cword( int i ) const; + + + // other methods + + void print( ::std::ostream& os = ::std::cout ) const + { os << to_char(); } + +protected: + + T& m_obj; + int m_index; + +private: + + // disabled + sc_bitref_r(); + sc_bitref_r<T>& operator = ( const sc_bitref_r<T>& ); +}; + + +// bitwise operators and functions + +// bitwise and + +template <class T1, class T2> +inline +const sc_logic +operator & ( const sc_bitref_r<T1>& a, const sc_bitref_r<T2>& b ); + + +// bitwise or + +template <class T1, class T2> +inline +const sc_logic +operator | ( const sc_bitref_r<T1>& a, const sc_bitref_r<T2>& b ); + + +// bitwise xor + +template <class T1, class T2> +inline +const sc_logic +operator ^ ( const sc_bitref_r<T1>& a, const sc_bitref_r<T2>& b ); + + +// relational operators and functions + +template <class T1, class T2> +inline +bool +operator == ( const sc_bitref_r<T1>& a, const sc_bitref_r<T2>& b ); + +template <class T1, class T2> +inline +bool +operator != ( const sc_bitref_r<T1>& a, const sc_bitref_r<T2>& b ); + + +// r-value concatenation operators and functions + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> > +operator , ( sc_bitref_r<T1>, sc_bitref_r<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> > +operator , ( sc_bitref_r<T1>, sc_subref_r<T2> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> > +operator , ( sc_bitref_r<T1>, sc_concref_r<T2,T3> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,T2> +operator , ( sc_bitref_r<T1>, const sc_proxy<T2>& ); + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_lv_base> +operator , ( sc_bitref_r<T>, const char* ); + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_bitref_r<T> > +operator , ( const char*, sc_bitref_r<T> ); + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_lv_base> +operator , ( sc_bitref_r<T>, const sc_logic& ); + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_bitref_r<T> > +operator , ( const sc_logic&, sc_bitref_r<T> ); + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_lv_base> +operator , ( sc_bitref_r<T>, bool ); + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_bitref_r<T> > +operator , ( bool, sc_bitref_r<T> ); + + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> > +concat( sc_bitref_r<T1>, sc_bitref_r<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> > +concat( sc_bitref_r<T1>, sc_subref_r<T2> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> > +concat( sc_bitref_r<T1>, sc_concref_r<T2,T3> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,T2> +concat( sc_bitref_r<T1>, const sc_proxy<T2>& ); + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_lv_base> +concat( sc_bitref_r<T>, const char* ); + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_bitref_r<T> > +concat( const char*, sc_bitref_r<T> ); + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_lv_base> +concat( sc_bitref_r<T>, const sc_logic& ); + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_bitref_r<T> > +concat( const sc_logic&, sc_bitref_r<T> ); + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_lv_base> +concat( sc_bitref_r<T>, bool ); + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_bitref_r<T> > +concat( bool, sc_bitref_r<T> ); + + +#ifdef SC_DT_MIXED_COMMA_OPERATORS + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> > +operator , ( sc_bitref_r<T1>, sc_bitref<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> > +operator , ( sc_bitref<T1>, sc_bitref_r<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> > +operator , ( sc_bitref_r<T1>, sc_subref<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> > +operator , ( sc_bitref<T1>, sc_subref_r<T2> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> > +operator , ( sc_bitref_r<T1>, sc_concref<T2,T3> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> > +operator , ( sc_bitref<T1>, sc_concref_r<T2,T3> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,T2> +operator , ( sc_bitref<T1>, const sc_proxy<T2>& ); + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,T2> +operator , ( sc_bitref_r<T1>, sc_proxy<T2>& ); + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_lv_base> +operator , ( sc_bitref<T>, const char* ); + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_bitref_r<T> > +operator , ( const char*, sc_bitref<T> ); + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_lv_base> +operator , ( sc_bitref<T>, const sc_logic& ); + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_bitref_r<T> > +operator , ( const sc_logic&, sc_bitref<T> ); + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_lv_base> +operator , ( sc_bitref<T>, bool ); + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_bitref_r<T> > +operator , ( bool, sc_bitref<T> ); + + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> > +concat( sc_bitref_r<T1>, sc_bitref<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> > +concat( sc_bitref<T1>, sc_bitref_r<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> > +concat( sc_bitref_r<T1>, sc_subref<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> > +concat( sc_bitref<T1>, sc_subref_r<T2> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> > +concat( sc_bitref_r<T1>, sc_concref<T2,T3> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> > +concat( sc_bitref<T1>, sc_concref_r<T2,T3> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,T2> +concat( sc_bitref<T1>, const sc_proxy<T2>& ); + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,T2> +concat( sc_bitref_r<T1>, sc_proxy<T2>& ); + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_lv_base> +concat( sc_bitref<T>, const char* ); + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_bitref_r<T> > +concat( const char*, sc_bitref<T> ); + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_lv_base> +concat( sc_bitref<T>, const sc_logic& ); + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_bitref_r<T> > +concat( const sc_logic&, sc_bitref<T> ); + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_lv_base> +concat( sc_bitref<T>, bool ); + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_bitref_r<T> > +concat( bool, sc_bitref<T> ); + +#endif + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_bitref<X> +// +// Proxy class for sc_proxy bit selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +template <class X> +class sc_bitref + : public sc_bitref_r<X> +{ + friend class sc_bv_base; + friend class sc_lv_base; + +public: + + // constructor + + sc_bitref( X& obj_, int index_ ) + : sc_bitref_r<X>( obj_, index_ ) + {} + + + // copy constructor + + sc_bitref( const sc_bitref<X>& a ) + : sc_bitref_r<X>( a ) + {} + + + // cloning + + sc_bitref<X>* clone() const + { return new sc_bitref<X>( *this ); } + + + // assignment operators + + sc_bitref<X>& operator = ( const sc_bitref_r<X>& a ); + sc_bitref<X>& operator = ( const sc_bitref<X>& a ); + + sc_bitref<X>& operator = ( const sc_logic& a ) + { this->m_obj.set_bit( this->m_index, a.value() ); return *this; } + + sc_bitref<X>& operator = ( sc_logic_value_t v ) + { *this = sc_logic( v ); return *this; } + + sc_bitref<X>& operator = ( bool a ) + { *this = sc_logic( a ); return *this; } + + sc_bitref<X>& operator = ( char a ) + { *this = sc_logic( a ); return *this; } + + sc_bitref<X>& operator = ( int a ) + { *this = sc_logic( a ); return *this; } + + sc_bitref<X>& operator = ( const sc_bit& a ) + { *this = sc_logic( a ); return *this; } + + + // bitwise assignment operators + + sc_bitref<X>& operator &= ( const sc_bitref_r<X>& a ); + sc_bitref<X>& operator &= ( const sc_logic& a ); + + sc_bitref<X>& operator &= ( sc_logic_value_t v ) + { *this &= sc_logic( v ); return *this; } + + sc_bitref<X>& operator &= ( bool a ) + { *this &= sc_logic( a ); return *this; } + + sc_bitref<X>& operator &= ( char a ) + { *this &= sc_logic( a ); return *this; } + + sc_bitref<X>& operator &= ( int a ) + { *this &= sc_logic( a ); return *this; } + + + sc_bitref<X>& operator |= ( const sc_bitref_r<X>& a ); + sc_bitref<X>& operator |= ( const sc_logic& a ); + + sc_bitref<X>& operator |= ( sc_logic_value_t v ) + { *this |= sc_logic( v ); return *this; } + + sc_bitref<X>& operator |= ( bool a ) + { *this |= sc_logic( a ); return *this; } + + sc_bitref<X>& operator |= ( char a ) + { *this |= sc_logic( a ); return *this; } + + sc_bitref<X>& operator |= ( int a ) + { *this |= sc_logic( a ); return *this; } + + + sc_bitref<X>& operator ^= ( const sc_bitref_r<X>& a ); + sc_bitref<X>& operator ^= ( const sc_logic& a ); + + sc_bitref<X>& operator ^= ( sc_logic_value_t v ) + { *this ^= sc_logic( v ); return *this; } + + sc_bitref<X>& operator ^= ( bool a ) + { *this ^= sc_logic( a ); return *this; } + + sc_bitref<X>& operator ^= ( char a ) + { *this ^= sc_logic( a ); return *this; } + + sc_bitref<X>& operator ^= ( int a ) + { *this ^= sc_logic( a ); return *this; } + + + // bitwise operators and functions + + // bitwise complement + + sc_bitref<X>& b_not(); + + + // common methods + + void set_bit( int n, sc_logic_value_t value ); + + void set_word( int i, sc_digit w ); + void set_cword( int i, sc_digit w ); + + void clean_tail() + { this->m_obj.clean_tail(); } + + + // other methods + + void scan( ::std::istream& is = ::std::cin ); + +private: + + // disabled + sc_bitref(); +}; + + +// l-value concatenation operators and functions + +template <class T1, class T2> +inline +sc_concref<sc_bitref<T1>,sc_bitref<T2> > +operator , ( sc_bitref<T1>, sc_bitref<T2> ); + +template <class T1, class T2> +inline +sc_concref<sc_bitref<T1>,sc_subref<T2> > +operator , ( sc_bitref<T1>, sc_subref<T2> ); + +template <class T1, class T2, class T3> +inline +sc_concref<sc_bitref<T1>,sc_concref<T2,T3> > +operator , ( sc_bitref<T1>, sc_concref<T2,T3> ); + +template <class T1, class T2> +inline +sc_concref<sc_bitref<T1>,T2> +operator , ( sc_bitref<T1>, sc_proxy<T2>& ); + + +template <class T1, class T2> +inline +sc_concref<sc_bitref<T1>,sc_bitref<T2> > +concat( sc_bitref<T1>, sc_bitref<T2> ); + +template <class T1, class T2> +inline +sc_concref<sc_bitref<T1>,sc_subref<T2> > +concat( sc_bitref<T1>, sc_subref<T2> ); + +template <class T1, class T2, class T3> +inline +sc_concref<sc_bitref<T1>,sc_concref<T2,T3> > +concat( sc_bitref<T1>, sc_concref<T2,T3> ); + +template <class T1, class T2> +inline +sc_concref<sc_bitref<T1>,T2> +concat( sc_bitref<T1>, sc_proxy<T2>& ); + + +template <class T> +::std::istream& +operator >> ( ::std::istream&, sc_bitref<T> ); + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_subref_r<X> +// +// Proxy class for sc_proxy part selection (r-value only). +// ---------------------------------------------------------------------------- + +template <class X> +class sc_subref_r + : public sc_proxy<sc_subref_r<X> > +{ + void check_bounds(); + +public: + + // constructor + + sc_subref_r( const X& obj_, int hi_, int lo_ ) + : m_obj( CCAST<X&>( obj_ ) ), m_hi( hi_ ), m_lo( lo_ ), m_len( 0 ) + { check_bounds(); } + + + // copy constructor + + sc_subref_r( const sc_subref_r<X>& a ) + : m_obj( a.m_obj ), m_hi( a.m_hi ), m_lo( a.m_lo ), m_len( a.m_len ) + {} + + + // cloning + + sc_subref_r<X>* clone() const + { return new sc_subref_r<X>( *this ); } + + + // common methods + + int length() const + { return m_len; } + + int size() const + { return ( (length() - 1) / SC_DIGIT_SIZE + 1 ); } + + sc_logic_value_t get_bit( int n ) const; + void set_bit( int n, sc_logic_value_t value ); + + sc_digit get_word( int i )const; + void set_word( int i, sc_digit w ); + + sc_digit get_cword( int i ) const; + void set_cword( int i, sc_digit w ); + + void clean_tail() + { m_obj.clean_tail(); } + + + // other methods + + bool is_01() const; + + bool reversed() const + { return m_lo > m_hi; } + +protected: + + X& m_obj; + int m_hi; + int m_lo; + int m_len; + +private: + + // disabled + sc_subref_r(); + sc_subref_r<X>& operator = ( const sc_subref_r<X>& ); +}; + + +// r-value concatenation operators and functions + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> > +operator , ( sc_subref_r<T1>, sc_bitref_r<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> > +operator , ( sc_subref_r<T1>, sc_subref_r<T2> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> > +operator , ( sc_subref_r<T1>, sc_concref_r<T2,T3> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,T2> +operator , ( sc_subref_r<T1>, const sc_proxy<T2>& ); + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_lv_base> +operator , ( sc_subref_r<T>, const char* ); + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_subref_r<T> > +operator , ( const char*, sc_subref_r<T> ); + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_lv_base> +operator , ( sc_subref_r<T>, const sc_logic& ); + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_subref_r<T> > +operator , ( const sc_logic&, sc_subref_r<T> ); + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_bv_base> +operator , ( sc_subref_r<T>, bool ); + +template <class T> +inline +sc_concref_r<sc_bv_base,sc_subref_r<T> > +operator , ( bool, sc_subref_r<T> ); + + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> > +concat( sc_subref_r<T1>, sc_bitref_r<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> > +concat( sc_subref_r<T1>, sc_subref_r<T2> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> > +concat( sc_subref_r<T1>, sc_concref_r<T2,T3> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,T2> +concat( sc_subref_r<T1>, const sc_proxy<T2>& ); + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_lv_base> +concat( sc_subref_r<T>, const char* ); + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_subref_r<T> > +concat( const char*, sc_subref_r<T> ); + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_lv_base> +concat( sc_subref_r<T>, const sc_logic& ); + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_subref_r<T> > +concat( const sc_logic&, sc_subref_r<T> ); + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_bv_base> +concat( sc_subref_r<T>, bool ); + +template <class T> +inline +sc_concref_r<sc_bv_base,sc_subref_r<T> > +concat( bool, sc_subref_r<T> ); + + +#ifdef SC_DT_MIXED_COMMA_OPERATORS + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> > +operator , ( sc_subref_r<T1>, sc_bitref<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> > +operator , ( sc_subref<T1>, sc_bitref_r<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> > +operator , ( sc_subref_r<T1>, sc_subref<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> > +operator , ( sc_subref<T1>, sc_subref_r<T2> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> > +operator , ( sc_subref_r<T1>, sc_concref<T2,T3> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> > +operator , ( sc_subref<T1>, sc_concref_r<T2,T3> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,T2> +operator , ( sc_subref<T1>, const sc_proxy<T2>& ); + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,T2> +operator , ( sc_subref_r<T1>, sc_proxy<T2>& ); + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_lv_base> +operator , ( sc_subref<T>, const char* ); + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_subref_r<T> > +operator , ( const char*, sc_subref<T> ); + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_lv_base> +operator , ( sc_subref<T>, const sc_logic& ); + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_subref_r<T> > +operator , ( const sc_logic&, sc_subref<T> ); + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_bv_base> +operator , ( sc_subref<T>, bool ); + +template <class T> +inline +sc_concref_r<sc_bv_base,sc_subref_r<T> > +operator , ( bool, sc_subref<T> ); + + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> > +concat( sc_subref_r<T1>, sc_bitref<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> > +concat( sc_subref<T1>, sc_bitref_r<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> > +concat( sc_subref_r<T1>, sc_subref<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> > +concat( sc_subref<T1>, sc_subref_r<T2> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> > +concat( sc_subref_r<T1>, sc_concref<T2,T3> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> > +concat( sc_subref<T1>, sc_concref_r<T2,T3> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,T2> +concat( sc_subref<T1>, const sc_proxy<T2>& ); + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,T2> +concat( sc_subref_r<T1>, sc_proxy<T2>& ); + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_lv_base> +concat( sc_subref<T>, const char* ); + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_subref_r<T> > +concat( const char*, sc_subref<T> ); + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_lv_base> +concat( sc_subref<T>, const sc_logic& ); + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_subref_r<T> > +concat( const sc_logic&, sc_subref<T> ); + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_bv_base> +concat( sc_subref<T>, bool ); + +template <class T> +inline +sc_concref_r<sc_bv_base,sc_subref_r<T> > +concat( bool, sc_subref<T> ); + +#endif + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_subref<X> +// +// Proxy class for sc_proxy part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +template <class X> +class sc_subref + : public sc_subref_r<X> +{ +public: + + // typedefs + + typedef sc_subref_r<X> base_type; + + + // constructor + + sc_subref( X& obj_, int hi_, int lo_ ) + : sc_subref_r<X>( obj_, hi_, lo_ ) + {} + + + // copy constructor + + sc_subref( const sc_subref<X>& a ) + : sc_subref_r<X>( a ) + {} + + + // cloning + + sc_subref<X>* clone() const + { return new sc_subref<X>( *this ); } + + + // assignment operators + + template <class Y> + sc_subref<X>& operator = ( const sc_proxy<Y>& a ) + { base_type::assign_( a ); return *this; } + + sc_subref<X>& operator = ( const sc_subref_r<X>& a ); + sc_subref<X>& operator = ( const sc_subref<X>& a ); + + sc_subref<X>& operator = ( const char* a ) + { base_type::assign_( a ); return *this; } + + sc_subref<X>& operator = ( const bool* a ) + { base_type::assign_( a ); return *this; } + + sc_subref<X>& operator = ( const sc_logic* a ) + { base_type::assign_( a ); return *this; } + + sc_subref<X>& operator = ( const sc_unsigned& a ) + { base_type::assign_( a ); return *this; } + + sc_subref<X>& operator = ( const sc_signed& a ) + { base_type::assign_( a ); return *this; } + + sc_subref<X>& operator = ( const sc_uint_base& a ) + { base_type::assign_( a ); return *this; } + + sc_subref<X>& operator = ( const sc_int_base& a ) + { base_type::assign_( a ); return *this; } + + sc_subref<X>& operator = ( unsigned long a ) + { base_type::assign_( a ); return *this; } + + sc_subref<X>& operator = ( long a ) + { base_type::assign_( a ); return *this; } + + sc_subref<X>& operator = ( unsigned int a ) + { base_type::assign_( a ); return *this; } + + sc_subref<X>& operator = ( int a ) + { base_type::assign_( a ); return *this; } + + sc_subref<X>& operator = ( uint64 a ) + { base_type::assign_( a ); return *this; } + + sc_subref<X>& operator = ( int64 a ) + { base_type::assign_( a ); return *this; } + + + // other methods + + void scan( ::std::istream& = ::std::cin ); + +private: + + // disabled + sc_subref(); +}; + + +// l-value concatenation operators and functions + +template <class T1, class T2> +inline +sc_concref<sc_subref<T1>,sc_bitref<T2> > +operator , ( sc_subref<T1>, sc_bitref<T2> ); + +template <class T1, class T2> +inline +sc_concref<sc_subref<T1>,sc_subref<T2> > +operator , ( sc_subref<T1>, sc_subref<T2> ); + +template <class T1, class T2, class T3> +inline +sc_concref<sc_subref<T1>,sc_concref<T2,T3> > +operator , ( sc_subref<T1>, sc_concref<T2,T3> ); + +template <class T1, class T2> +inline +sc_concref<sc_subref<T1>,T2> +operator , ( sc_subref<T1>, sc_proxy<T2>& ); + + +template <class T1, class T2> +inline +sc_concref<sc_subref<T1>,sc_bitref<T2> > +concat( sc_subref<T1>, sc_bitref<T2> ); + +template <class T1, class T2> +inline +sc_concref<sc_subref<T1>,sc_subref<T2> > +concat( sc_subref<T1>, sc_subref<T2> ); + +template <class T1, class T2, class T3> +inline +sc_concref<sc_subref<T1>,sc_concref<T2,T3> > +concat( sc_subref<T1>, sc_concref<T2,T3> ); + +template <class T1, class T2> +inline +sc_concref<sc_subref<T1>,T2> +concat( sc_subref<T1>, sc_proxy<T2>& ); + + +template <class T> +inline +::std::istream& +operator >> ( ::std::istream&, sc_subref<T> ); + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_concref_r<X,Y> +// +// Proxy class for sc_proxy concatenation (r-value only). +// ---------------------------------------------------------------------------- + +template <class X, class Y> +class sc_concref_r + : public sc_proxy<sc_concref_r<X,Y> > +{ +public: + + // constructor + + sc_concref_r( const X& left_, const Y& right_, int delete_ = 0 ) + : m_left( CCAST<X&>( left_ ) ), m_right( CCAST<Y&>( right_ ) ), + m_delete( delete_ ), m_refs( *new int( 1 ) ) + {} + + + // copy constructor + + sc_concref_r( const sc_concref_r<X,Y>& a ) + : m_left( a.m_left ), m_right( a.m_right ), + m_delete( a.m_delete ), m_refs( a.m_refs ) + { ++ m_refs; } + + + // destructor + + virtual ~sc_concref_r(); + + + // cloning + + sc_concref_r<X,Y>* clone() const + { return new sc_concref_r<X,Y>( *this ); } + + + // common methods + + int length() const + { return ( m_left.length() + m_right.length() ); } + + int size() const + { return ( (length() - 1) / SC_DIGIT_SIZE + 1 ); } + + sc_logic_value_t get_bit( int n ) const; + void set_bit( int n, sc_logic_value_t value ); + + sc_digit get_word( int i ) const; + void set_word( int i, sc_digit w ); + + sc_digit get_cword( int i ) const; + void set_cword( int i, sc_digit w ); + + void clean_tail() + { m_left.clean_tail(); m_right.clean_tail(); } + + + // other methods + + bool is_01() const + { return ( m_left.is_01() && m_right.is_01() ); } + +protected: + + X& m_left; + Y& m_right; + mutable int m_delete; + int& m_refs; + +private: + + // disabled + sc_concref_r(); + sc_concref_r<X,Y>& operator = ( const sc_concref_r<X,Y>& ); +}; + + +// r-value concatenation operators and functions + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> > +operator , ( sc_concref_r<T1,T2>, sc_bitref_r<T3> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> > +operator , ( sc_concref_r<T1,T2>, sc_subref_r<T3> ); + +template <class T1, class T2, class T3, class T4> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> > +operator , ( sc_concref_r<T1,T2>, sc_concref_r<T3,T4> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,T3> +operator , ( sc_concref_r<T1,T2>, const sc_proxy<T3>& ); + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base> +operator , ( sc_concref_r<T1,T2>, const char* ); + +template <class T1, class T2> +inline +sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> > +operator , ( const char*, sc_concref_r<T1,T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base> +operator , ( sc_concref_r<T1,T2>, const sc_logic& ); + +template <class T1, class T2> +inline +sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> > +operator , ( const sc_logic&, sc_concref_r<T1,T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base> +operator , ( sc_concref_r<T1,T2>, bool ); + +template <class T1, class T2> +inline +sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> > +operator , ( bool, sc_concref_r<T1,T2> ); + + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> > +concat( sc_concref_r<T1,T2>, sc_bitref_r<T3> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> > +concat( sc_concref_r<T1,T2>, sc_subref_r<T3> ); + +template <class T1, class T2, class T3, class T4> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> > +concat( sc_concref_r<T1,T2>, sc_concref_r<T3,T4> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,T3> +concat( sc_concref_r<T1,T2>, const sc_proxy<T3>& ); + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base> +concat( sc_concref_r<T1,T2>, const char* ); + +template <class T1, class T2> +inline +sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> > +concat( const char*, sc_concref_r<T1,T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base> +concat( sc_concref_r<T1,T2>, const sc_logic& ); + +template <class T1, class T2> +inline +sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> > +concat( const sc_logic&, sc_concref_r<T1,T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base> +concat( sc_concref_r<T1,T2>, bool ); + +template <class T1, class T2> +inline +sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> > +concat( bool, sc_concref_r<T1,T2> ); + + +#ifdef SC_DT_MIXED_COMMA_OPERATORS + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> > +operator , ( sc_concref_r<T1,T2>, sc_bitref<T3> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> > +operator , ( sc_concref<T1,T2>, sc_bitref_r<T3> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> > +operator , ( sc_concref_r<T1,T2>, sc_subref<T3> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> > +operator , ( sc_concref<T1,T2>, sc_subref_r<T3> ); + +template <class T1, class T2, class T3, class T4> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> > +operator , ( sc_concref_r<T1,T2>, sc_concref<T3,T4> ); + +template <class T1, class T2, class T3, class T4> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> > +operator , ( sc_concref<T1,T2>, sc_concref_r<T3,T4> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,T3> +operator , ( sc_concref<T1,T2>, const sc_proxy<T3>& ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,T3> +operator , ( sc_concref_r<T1,T2>, sc_proxy<T3>& ); + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base> +operator , ( sc_concref<T1,T2>, const char* ); + +template <class T1, class T2> +inline +sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> > +operator , ( const char*, sc_concref<T1,T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base> +operator , ( sc_concref<T1,T2>, const sc_logic& ); + +template <class T1, class T2> +inline +sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> > +operator , ( const sc_logic&, sc_concref<T1,T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base> +operator , ( sc_concref<T1,T2>, bool ); + +template <class T1, class T2> +inline +sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> > +operator , ( bool, sc_concref<T1,T2> ); + + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> > +concat( sc_concref_r<T1,T2>, sc_bitref<T3> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> > +concat( sc_concref<T1,T2>, sc_bitref_r<T3> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> > +concat( sc_concref_r<T1,T2>, sc_subref<T3> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> > +concat( sc_concref<T1,T2>, sc_subref_r<T3> ); + +template <class T1, class T2, class T3, class T4> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> > +concat( sc_concref_r<T1,T2>, sc_concref<T3,T4> ); + +template <class T1, class T2, class T3, class T4> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> > +concat( sc_concref<T1,T2>, sc_concref_r<T3,T4> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,T3> +concat( sc_concref<T1,T2>, const sc_proxy<T3>& ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,T3> +concat( sc_concref_r<T1,T2>, sc_proxy<T3>& ); + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base> +concat( sc_concref<T1,T2>, const char* ); + +template <class T1, class T2> +inline +sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> > +concat( const char*, sc_concref<T1,T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base> +concat( sc_concref<T1,T2>, const sc_logic& ); + +template <class T1, class T2> +inline +sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> > +concat( const sc_logic&, sc_concref<T1,T2> ); + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base> +concat( sc_concref<T1,T2>, bool ); + +template <class T1, class T2> +inline +sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> > +concat( bool, sc_concref<T1,T2> ); + +#endif + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_concref<X,Y> +// +// Proxy class for sc_proxy concatenation (r-value and l-value). +// ---------------------------------------------------------------------------- + +template <class X, class Y> +class sc_concref + : public sc_concref_r<X,Y> +{ +public: + + // typedefs + + typedef sc_concref_r<X,Y> base_type; + + + // constructor + + sc_concref( X& left_, Y& right_, int delete_ = 0 ) + : sc_concref_r<X,Y>( left_, right_, delete_ ) + {} + + + // copy constructor + + sc_concref( const sc_concref<X,Y>& a ) + : sc_concref_r<X,Y>( a ) + {} + + + // cloning + + sc_concref<X,Y>* clone() const + { return new sc_concref<X,Y>( *this ); } + + + // assignment operators + + template <class Z> + sc_concref<X,Y>& operator = ( const sc_proxy<Z>& a ) + { base_type::assign_( a ); return *this; } + + sc_concref<X,Y>& operator = ( const sc_concref<X,Y>& a ) + { base_type::assign_( a ); return *this; } + + sc_concref<X,Y>& operator = ( const char* a ) + { base_type::assign_( a ); return *this; } + + sc_concref<X,Y>& operator = ( const bool* a ) + { base_type::assign_( a ); return *this; } + + sc_concref<X,Y>& operator = ( const sc_logic* a ) + { base_type::assign_( a ); return *this; } + + sc_concref<X,Y>& operator = ( const sc_unsigned& a ) + { base_type::assign_( a ); return *this; } + + sc_concref<X,Y>& operator = ( const sc_signed& a ) + { base_type::assign_( a ); return *this; } + + sc_concref<X,Y>& operator = ( const sc_uint_base& a ) + { base_type::assign_( a ); return *this; } + + sc_concref<X,Y>& operator = ( const sc_int_base& a ) + { base_type::assign_( a ); return *this; } + + sc_concref<X,Y>& operator = ( unsigned long a ) + { base_type::assign_( a ); return *this; } + + sc_concref<X,Y>& operator = ( long a ) + { base_type::assign_( a ); return *this; } + + sc_concref<X,Y>& operator = ( unsigned int a ) + { base_type::assign_( a ); return *this; } + + sc_concref<X,Y>& operator = ( int a ) + { base_type::assign_( a ); return *this; } + + sc_concref<X,Y>& operator = ( uint64 a ) + { base_type::assign_( a ); return *this; } + + sc_concref<X,Y>& operator = ( int64 a ) + { base_type::assign_( a ); return *this; } + + + // other methods + + void scan( ::std::istream& = ::std::cin ); + +private: + + // disabled + sc_concref(); +}; + + +// l-value concatenation operators and functions + +template <class T1, class T2, class T3> +inline +sc_concref<sc_concref<T1,T2>,sc_bitref<T3> > +operator , ( sc_concref<T1,T2>, sc_bitref<T3> ); + +template <class T1, class T2, class T3> +inline +sc_concref<sc_concref<T1,T2>,sc_subref<T3> > +operator , ( sc_concref<T1,T2>, sc_subref<T3> ); + +template <class T1, class T2, class T3, class T4> +inline +sc_concref<sc_concref<T1,T2>,sc_concref<T3,T4> > +operator , ( sc_concref<T1,T2>, sc_concref<T3,T4> ); + +template <class T1, class T2, class T3> +inline +sc_concref<sc_concref<T1,T2>,T3> +operator , ( sc_concref<T1,T2>, sc_proxy<T3>& ); + + +template <class T1, class T2, class T3> +inline +sc_concref<sc_concref<T1,T2>,sc_bitref<T3> > +concat( sc_concref<T1,T2>, sc_bitref<T3> ); + +template <class T1, class T2, class T3> +inline +sc_concref<sc_concref<T1,T2>,sc_subref<T3> > +concat( sc_concref<T1,T2>, sc_subref<T3> ); + +template <class T1, class T2, class T3, class T4> +inline +sc_concref<sc_concref<T1,T2>,sc_concref<T3,T4> > +concat( sc_concref<T1,T2>, sc_concref<T3,T4> ); + +template <class T1, class T2, class T3> +inline +sc_concref<sc_concref<T1,T2>,T3> +concat( sc_concref<T1,T2>, sc_proxy<T3>& ); + + +template <class T1, class T2> +inline +::std::istream& +operator >> ( ::std::istream&, sc_concref<T1,T2> ); + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_proxy<T> +// +// Base class template for bit/logic vector classes. +// (Barton/Nackmann implementation) +// ---------------------------------------------------------------------------- + +// r-value concatenation operators and functions + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_bitref_r<T2> > +operator , ( const sc_proxy<T1>&, sc_bitref_r<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_subref_r<T2> > +operator , ( const sc_proxy<T1>&, sc_subref_r<T2> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<T1,sc_concref_r<T2,T3> > +operator , ( const sc_proxy<T1>&, sc_concref_r<T2,T3> ); + +template <class T1, class T2> +inline +sc_concref_r<T1,T2> +operator , ( const sc_proxy<T1>&, const sc_proxy<T2>& ); + +template <class T> +inline +sc_concref_r<T,sc_lv_base> +operator , ( const sc_proxy<T>&, const char* ); + +template <class T> +inline +sc_concref_r<sc_lv_base,T> +operator , ( const char*, const sc_proxy<T>& ); + +template <class T> +inline +sc_concref_r<T,sc_lv_base> +operator , ( const sc_proxy<T>&, const sc_logic& ); + +template <class T> +inline +sc_concref_r<sc_lv_base,T> +operator , ( const sc_logic&, const sc_proxy<T>& ); + +template <class T> +inline +sc_concref_r<T,sc_bv_base> +operator , ( const sc_proxy<T>&, bool ); + +template <class T> +inline +sc_concref_r<sc_bv_base,T> +operator , ( bool, const sc_proxy<T>& ); + + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_bitref_r<T2> > +concat( const sc_proxy<T1>&, sc_bitref_r<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_subref_r<T2> > +concat( const sc_proxy<T1>&, sc_subref_r<T2> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<T1,sc_concref_r<T2,T3> > +concat( const sc_proxy<T1>&, sc_concref_r<T2,T3> ); + +template <class T1, class T2> +inline +sc_concref_r<T1,T2> +concat( const sc_proxy<T1>&, const sc_proxy<T2>& ); + +template <class T> +inline +sc_concref_r<T,sc_lv_base> +concat( const sc_proxy<T>&, const char* ); + +template <class T> +inline +sc_concref_r<sc_lv_base,T> +concat( const char*, const sc_proxy<T>& ); + +template <class T> +inline +sc_concref_r<T,sc_lv_base> +concat( const sc_proxy<T>&, const sc_logic& ); + +template <class T> +inline +sc_concref_r<sc_lv_base,T> +concat( const sc_logic&, const sc_proxy<T>& ); + +template <class T> +inline +sc_concref_r<T,sc_bv_base> +concat( const sc_proxy<T>&, bool ); + +template <class T> +inline +sc_concref_r<sc_bv_base,T> +concat( bool, const sc_proxy<T>& ); + + +#ifdef SC_DT_MIXED_COMMA_OPERATORS + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_bitref_r<T2> > +operator , ( const sc_proxy<T1>&, sc_bitref<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_bitref_r<T2> > +operator , ( sc_proxy<T1>&, sc_bitref_r<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_subref_r<T2> > +operator , ( const sc_proxy<T1>&, sc_subref<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_subref_r<T2> > +operator , ( sc_proxy<T1>&, sc_subref_r<T2> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<T1,sc_concref_r<T2,T3> > +operator , ( const sc_proxy<T1>&, sc_concref<T2,T3> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<T1,sc_concref_r<T2,T3> > +operator , ( sc_proxy<T1>&, sc_concref_r<T2,T3> ); + +template <class T1, class T2> +inline +sc_concref_r<T1,T2> +operator , ( const sc_proxy<T1>&, sc_proxy<T2>& ); + +template <class T1, class T2> +inline +sc_concref_r<T1,T2> +operator , ( sc_proxy<T1>&, const sc_proxy<T2>& ); + +template <class T> +inline +sc_concref_r<T,sc_lv_base> +operator , ( sc_proxy<T>&, const char* ); + +template <class T> +inline +sc_concref_r<sc_lv_base,T> +operator , ( const char*, sc_proxy<T>& ); + +template <class T> +inline +sc_concref_r<T,sc_lv_base> +operator , ( sc_proxy<T>&, const sc_logic& ); + +template <class T> +inline +sc_concref_r<sc_lv_base,T> +operator , ( const sc_logic&, sc_proxy<T>& ); + +template <class T> +inline +sc_concref_r<T,sc_bv_base> +operator , ( sc_proxy<T>&, bool ); + +template <class T> +inline +sc_concref_r<sc_bv_base,T> +operator , ( bool, sc_proxy<T>& ); + + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_bitref_r<T2> > +concat( const sc_proxy<T1>&, sc_bitref<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_bitref_r<T2> > +concat( sc_proxy<T1>&, sc_bitref_r<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_subref_r<T2> > +concat( const sc_proxy<T1>&, sc_subref<T2> ); + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_subref_r<T2> > +concat( sc_proxy<T1>&, sc_subref_r<T2> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<T1,sc_concref_r<T2,T3> > +concat( const sc_proxy<T1>&, sc_concref<T2,T3> ); + +template <class T1, class T2, class T3> +inline +sc_concref_r<T1,sc_concref_r<T2,T3> > +concat( sc_proxy<T1>&, sc_concref_r<T2,T3> ); + +template <class T1, class T2> +inline +sc_concref_r<T1,T2> +concat( const sc_proxy<T1>&, sc_proxy<T2>& ); + +template <class T1, class T2> +inline +sc_concref_r<T1,T2> +concat( sc_proxy<T1>&, const sc_proxy<T2>& ); + +template <class T> +inline +sc_concref_r<T,sc_lv_base> +concat( sc_proxy<T>&, const char* ); + +template <class T> +inline +sc_concref_r<sc_lv_base,T> +concat( const char*, sc_proxy<T>& ); + +template <class T> +inline +sc_concref_r<T,sc_lv_base> +concat( sc_proxy<T>&, const sc_logic& ); + +template <class T> +inline +sc_concref_r<sc_lv_base,T> +concat( const sc_logic&, sc_proxy<T>& ); + +template <class T> +inline +sc_concref_r<T,sc_bv_base> +concat( sc_proxy<T>&, bool ); + +template <class T> +inline +sc_concref_r<sc_bv_base,T> +concat( bool, sc_proxy<T>& ); + +#endif + + +// l-value concatenation operators and functions + +template <class T1, class T2> +inline +sc_concref<T1,sc_bitref<T2> > +operator , ( sc_proxy<T1>&, sc_bitref<T2> ); + +template <class T1, class T2> +inline +sc_concref<T1,sc_subref<T2> > +operator , ( sc_proxy<T1>&, sc_subref<T2> ); + +template <class T1, class T2, class T3> +inline +sc_concref<T1,sc_concref<T2,T3> > +operator , ( sc_proxy<T1>&, sc_concref<T2,T3> ); + +template <class T1, class T2> +inline +sc_concref<T1,T2> +operator , ( sc_proxy<T1>&, sc_proxy<T2>& ); + + +template <class T1, class T2> +inline +sc_concref<T1,sc_bitref<T2> > +concat( sc_proxy<T1>&, sc_bitref<T2> ); + +template <class T1, class T2> +inline +sc_concref<T1,sc_subref<T2> > +concat( sc_proxy<T1>&, sc_subref<T2> ); + +template <class T1, class T2, class T3> +inline +sc_concref<T1,sc_concref<T2,T3> > +concat( sc_proxy<T1>&, sc_concref<T2,T3> ); + +template <class T1, class T2> +inline +sc_concref<T1,T2> +concat( sc_proxy<T1>&, sc_proxy<T2>& ); + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_bitref_r<T> +// +// Proxy class for sc_proxy bit selection (r-value only). +// ---------------------------------------------------------------------------- + +// bitwise operators and functions + +// bitwise and + +template <class T1, class T2> +inline +const sc_logic +operator & ( const sc_bitref_r<T1>& a, const sc_bitref_r<T2>& b ) +{ + return sc_logic( sc_logic::and_table[a.value()][b.value()] ); +} + + +// bitwise or + +template <class T1, class T2> +inline +const sc_logic +operator | ( const sc_bitref_r<T1>& a, const sc_bitref_r<T2>& b ) +{ + return sc_logic( sc_logic::or_table[a.value()][b.value()] ); +} + + +// bitwise xor + +template <class T1, class T2> +inline +const sc_logic +operator ^ ( const sc_bitref_r<T1>& a, const sc_bitref_r<T2>& b ) +{ + return sc_logic( sc_logic::xor_table[a.value()][b.value()] ); +} + + +// relational operators and functions + +template <class T1, class T2> +inline +bool +operator == ( const sc_bitref_r<T1>& a, const sc_bitref_r<T2>& b ) +{ + return ( (int) a.value() == b.value() ); +} + +template <class T1, class T2> +inline +bool +operator != ( const sc_bitref_r<T1>& a, const sc_bitref_r<T2>& b ) +{ + return ( (int) a.value() != b.value() ); +} + + +// common methods + +template <class T> +inline +sc_logic_value_t +sc_bitref_r<T>::get_bit( int n ) const +{ + if( n == 0 ) { + return m_obj.get_bit( m_index ); + } else { + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_ , 0 ); + // never reached + return Log_0; + } +} + + +template <class T> +inline +sc_digit +sc_bitref_r<T>::get_word( int n ) const +{ + if( n == 0 ) { + return ( get_bit( n ) & SC_DIGIT_ONE ); + } else { + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 ); + // never reached + return 0; + } +} + +template <class T> +inline +sc_digit +sc_bitref_r<T>::get_cword( int n ) const +{ + if( n == 0 ) { + return ( (get_bit( n ) & SC_DIGIT_TWO) >> 1 ); + } else { + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 ); + // never reached + return 0; + } +} + + +// r-value concatenation operators and functions + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> > +operator , ( sc_bitref_r<T1> a, sc_bitref_r<T2> b ) +{ + return sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> > +operator , ( sc_bitref_r<T1> a, sc_subref_r<T2> b ) +{ + return sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> > +operator , ( sc_bitref_r<T1> a, sc_concref_r<T2,T3> b ) +{ + return sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,T2> +operator , ( sc_bitref_r<T1> a, const sc_proxy<T2>& b ) +{ + return sc_concref_r<sc_bitref_r<T1>,T2>( + *a.clone(), b.back_cast(), 1 ); +} + + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> > +concat( sc_bitref_r<T1> a, sc_bitref_r<T2> b ) +{ + return sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> > +concat( sc_bitref_r<T1> a, sc_subref_r<T2> b ) +{ + return sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> > +concat( sc_bitref_r<T1> a, sc_concref_r<T2,T3> b ) +{ + return sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,T2> +concat( sc_bitref_r<T1> a, const sc_proxy<T2>& b ) +{ + return sc_concref_r<sc_bitref_r<T1>,T2>( + *a.clone(), b.back_cast(), 1 ); +} + + +#ifdef SC_DT_MIXED_COMMA_OPERATORS + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> > +operator , ( sc_bitref_r<T1> a, sc_bitref<T2> b ) +{ + return sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> > +operator , ( sc_bitref<T1> a, sc_bitref_r<T2> b ) +{ + return sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> > +operator , ( sc_bitref_r<T1> a, sc_subref<T2> b ) +{ + return sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> > +operator , ( sc_bitref<T1> a, sc_subref_r<T2> b ) +{ + return sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> > +operator , ( sc_bitref_r<T1> a, sc_concref<T2,T3> b ) +{ + return sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> > +operator , ( sc_bitref<T1> a, sc_concref_r<T2,T3> b ) +{ + return sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,T2> +operator , ( sc_bitref<T1> a, const sc_proxy<T2>& b ) +{ + return sc_concref_r<sc_bitref_r<T1>,T2>( + *a.clone(), b.back_cast(), 1 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,T2> +operator , ( sc_bitref_r<T1> a, sc_proxy<T2>& b ) +{ + return sc_concref_r<sc_bitref_r<T1>,T2>( + *a.clone(), b.back_cast(), 1 ); +} + + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> > +concat( sc_bitref_r<T1> a, sc_bitref<T2> b ) +{ + return sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> > +concat( sc_bitref<T1> a, sc_bitref_r<T2> b ) +{ + return sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> > +concat( sc_bitref_r<T1> a, sc_subref<T2> b ) +{ + return sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> > +concat( sc_bitref<T1> a, sc_subref_r<T2> b ) +{ + return sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> > +concat( sc_bitref_r<T1> a, sc_concref<T2,T3> b ) +{ + return sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> > +concat( sc_bitref<T1> a, sc_concref_r<T2,T3> b ) +{ + return sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,T2> +concat( sc_bitref<T1> a, const sc_proxy<T2>& b ) +{ + return sc_concref_r<sc_bitref_r<T1>,T2>( + *a.clone(), b.back_cast(), 1 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>,T2> +concat( sc_bitref_r<T1> a, sc_proxy<T2>& b ) +{ + return sc_concref_r<sc_bitref_r<T1>,T2>( + *a.clone(), b.back_cast(), 1 ); +} + +#endif + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_bitref<X> +// +// Proxy class for sc_proxy bit selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +// assignment operators + +template <class X> +inline +sc_bitref<X>& +sc_bitref<X>::operator = ( const sc_bitref_r<X>& a ) +{ + this->m_obj.set_bit( this->m_index, a.value() ); + return *this; +} + +template <class X> +inline +sc_bitref<X>& +sc_bitref<X>::operator = ( const sc_bitref<X>& a ) +{ + if( &a != this ) { + this->m_obj.set_bit( this->m_index, a.value() ); + } + return *this; +} + + +// bitwise assignment operators + +template <class X> +inline +sc_bitref<X>& +sc_bitref<X>::operator &= ( const sc_bitref_r<X>& a ) +{ + if( &a != this ) { + this->m_obj.set_bit( this->m_index, + sc_logic::and_table[this->value()][a.value()] ); + } + return *this; +} + +template <class X> +inline +sc_bitref<X>& +sc_bitref<X>::operator &= ( const sc_logic& a ) +{ + this->m_obj.set_bit( this->m_index, + sc_logic::and_table[this->value()][a.value()] ); + return *this; +} + + +template <class X> +inline +sc_bitref<X>& +sc_bitref<X>::operator |= ( const sc_bitref_r<X>& a ) +{ + if( &a != this ) { + this->m_obj.set_bit( this->m_index, + sc_logic::or_table[this->value()][a.value()] ); + } + return *this; +} + +template <class X> +inline +sc_bitref<X>& +sc_bitref<X>::operator |= ( const sc_logic& a ) +{ + this->m_obj.set_bit( this->m_index, + sc_logic::or_table[this->value()][a.value()] ); + return *this; +} + + +template <class X> +inline +sc_bitref<X>& +sc_bitref<X>::operator ^= ( const sc_bitref_r<X>& a ) +{ + if( &a != this ) { + this->m_obj.set_bit( this->m_index, + sc_logic::xor_table[this->value()][a.value()] ); + } + return *this; +} + +template <class X> +inline +sc_bitref<X>& +sc_bitref<X>::operator ^= ( const sc_logic& a ) +{ + this->m_obj.set_bit( this->m_index, + sc_logic::xor_table[this->value()][a.value()] ); + return *this; +} + + +// bitwise operators and functions + +// bitwise complement + +template <class X> +inline +sc_bitref<X>& +sc_bitref<X>::b_not() +{ + this->m_obj.set_bit( this->m_index, + sc_logic::not_table[this->value()] ); + return *this; +} + + +// common methods + +template <class X> +inline +void +sc_bitref<X>::set_bit( int n, sc_logic_value_t value ) +{ + if( n == 0 ) { + this->m_obj.set_bit( this->m_index, value ); + } else { + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 ); + } +} + +template <class X> +inline +void +sc_bitref<X>::set_word( int n, sc_digit w ) +{ + unsigned int bi = this->m_index % (8*sizeof(sc_digit)); + sc_digit temp; + unsigned int wi = this->m_index / (8*sizeof(sc_digit)); + if( n == 0 ) { + temp = this->m_obj.get_word(wi); + temp = (temp & ~(1 << bi)) | ((w&1) << bi); + this->m_obj.set_word(wi, temp); + } else { + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 ); + } + +} + +template <class X> +inline +void +sc_bitref<X>::set_cword( int n, sc_digit w ) +{ + unsigned int bi = this->m_index % (8*sizeof(sc_digit)); + sc_digit temp; + unsigned int wi = this->m_index / (8*sizeof(sc_digit)); + if( n == 0 ) { + temp = this->m_obj.get_cword(wi); + temp = (temp & ~(1 << bi)) | ((w&1) << bi); + this->m_obj.set_cword(wi, temp); + } else { + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 ); + } +} + +// other methods + +template <class X> +inline +void +sc_bitref<X>::scan( ::std::istream& is ) +{ + char c; + is >> c; + *this = c; +} + + +// l-value concatenation operators and functions + +template <class T1, class T2> +inline +sc_concref<sc_bitref<T1>,sc_bitref<T2> > +operator , ( sc_bitref<T1> a, sc_bitref<T2> b ) +{ + return sc_concref<sc_bitref<T1>,sc_bitref<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref<sc_bitref<T1>,sc_subref<T2> > +operator , ( sc_bitref<T1> a, sc_subref<T2> b ) +{ + return sc_concref<sc_bitref<T1>,sc_subref<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref<sc_bitref<T1>,sc_concref<T2,T3> > +operator , ( sc_bitref<T1> a, sc_concref<T2,T3> b ) +{ + return sc_concref<sc_bitref<T1>,sc_concref<T2,T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref<sc_bitref<T1>,T2> +operator , ( sc_bitref<T1> a, sc_proxy<T2>& b ) +{ + return sc_concref<sc_bitref<T1>,T2>( + *a.clone(), b.back_cast(), 1 ); +} + + +template <class T1, class T2> +inline +sc_concref<sc_bitref<T1>,sc_bitref<T2> > +concat( sc_bitref<T1> a, sc_bitref<T2> b ) +{ + return sc_concref<sc_bitref<T1>,sc_bitref<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref<sc_bitref<T1>,sc_subref<T2> > +concat( sc_bitref<T1> a, sc_subref<T2> b ) +{ + return sc_concref<sc_bitref<T1>,sc_subref<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref<sc_bitref<T1>,sc_concref<T2,T3> > +concat( sc_bitref<T1> a, sc_concref<T2,T3> b ) +{ + return sc_concref<sc_bitref<T1>,sc_concref<T2,T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref<sc_bitref<T1>,T2> +concat( sc_bitref<T1> a, sc_proxy<T2>& b ) +{ + return sc_concref<sc_bitref<T1>,T2>( + *a.clone(), b.back_cast(), 1 ); +} + + +template <class X> +inline +::std::istream& +operator >> ( ::std::istream& is, sc_bitref<X> a ) +{ + a.scan( is ); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_subref_r<X> +// +// Proxy class for sc_proxy part selection (r-value only). +// ---------------------------------------------------------------------------- + +template <class X> +inline +void +sc_subref_r<X>::check_bounds() +{ + int len = m_obj.length(); + if( m_hi < 0 || m_hi >= len || m_lo < 0 || m_lo >= len ) { + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 ); + } + if( reversed() ) { + m_len = m_lo - m_hi + 1; + } else { + m_len = m_hi - m_lo + 1; + } +} + + +// common methods + +template <class X> +inline +sc_logic_value_t +sc_subref_r<X>::get_bit( int n ) const +{ + if( reversed() ) { + return m_obj.get_bit( m_lo - n ); + } else { + return m_obj.get_bit( m_lo + n ); + } +} + +template <class X> +inline +void +sc_subref_r<X>::set_bit( int n, sc_logic_value_t value ) +{ + if( reversed() ) { + m_obj.set_bit( m_lo - n, value ); + } else { + m_obj.set_bit( m_lo + n, value ); + } +} + + +template <class X> +inline +sc_digit +sc_subref_r<X>::get_word( int i ) const +{ + int n1 = 0; + int n2 = 0; + sc_digit result = 0; + int k = 0; + if( reversed() ) { + n1 = m_lo - i * SC_DIGIT_SIZE; + n2 = sc_max( n1 - SC_DIGIT_SIZE, m_hi - 1 ); + for( int n = n1; n > n2; n -- ) { + result |= (m_obj[n].value() & SC_DIGIT_ONE) << k ++; + } + } else { + n1 = m_lo + i * SC_DIGIT_SIZE; + n2 = sc_min( n1 + SC_DIGIT_SIZE, m_hi + 1 ); + for( int n = n1; n < n2; n ++ ) { + result |= (m_obj[n].value() & SC_DIGIT_ONE) << k ++; + } + } + return result; +} + +template <class X> +inline +void +sc_subref_r<X>::set_word( int i, sc_digit w ) +{ + int n1 = 0; + int n2 = 0; + int k = 0; + if( reversed() ) { + n1 = m_lo - i * SC_DIGIT_SIZE; + n2 = sc_max( n1 - SC_DIGIT_SIZE, m_hi - 1 ); + for( int n = n1; n > n2; n -- ) { + m_obj.set_bit( n, sc_logic_value_t( + ( (w >> k ++) & SC_DIGIT_ONE ) | + ( m_obj[n].value() & SC_DIGIT_TWO ) ) ); + } + } else { + n1 = m_lo + i * SC_DIGIT_SIZE; + n2 = sc_min( n1 + SC_DIGIT_SIZE, m_hi + 1 ); + for( int n = n1; n < n2; n ++ ) { + m_obj.set_bit( n, sc_logic_value_t( + ( (w >> k ++) & SC_DIGIT_ONE ) | + ( m_obj[n].value() & SC_DIGIT_TWO ) ) ); + } + } +} + + +template <class X> +inline +sc_digit +sc_subref_r<X>::get_cword( int i ) const +{ + int n1 = 0; + int n2 = 0; + sc_digit result = 0; + int k = 0; + if( reversed() ) { + n1 = m_lo - i * SC_DIGIT_SIZE; + n2 = sc_max( n1 - SC_DIGIT_SIZE, m_hi - 1 ); + for( int n = n1; n > n2; n -- ) { + result |= ((m_obj[n].value() & SC_DIGIT_TWO) >> 1) << k ++; + } + } else { + n1 = m_lo + i * SC_DIGIT_SIZE; + n2 = sc_min( n1 + SC_DIGIT_SIZE, m_hi + 1 ); + for( int n = n1; n < n2; n ++ ) { + result |= ((m_obj[n].value() & SC_DIGIT_TWO) >> 1) << k ++; + } + } + return result; +} + +template <class X> +inline +void +sc_subref_r<X>::set_cword( int i, sc_digit w ) +{ + int n1 = 0; + int n2 = 0; + int k = 0; + if( reversed() ) { + n1 = m_lo - i * SC_DIGIT_SIZE; + n2 = sc_max( n1 - SC_DIGIT_SIZE, m_hi - 1 ); + for( int n = n1; n > n2; n -- ) { + m_obj.set_bit( n, sc_logic_value_t( + ( ((w >> k ++) & SC_DIGIT_ONE) << 1 ) | + ( m_obj[n].value() & SC_DIGIT_ONE ) ) ); + } + } else { + n1 = m_lo + i * SC_DIGIT_SIZE; + n2 = sc_min( n1 + SC_DIGIT_SIZE, m_hi + 1 ); + for( int n = n1; n < n2; n ++ ) { + m_obj.set_bit( n, sc_logic_value_t( + ( ((w >> k ++) & SC_DIGIT_ONE) << 1 ) | + ( m_obj[n].value() & SC_DIGIT_ONE ) ) ); + } + } +} + + +// other methods + +template <class X> +inline +bool +sc_subref_r<X>::is_01() const +{ + int sz = size(); + for( int i = 0; i < sz; ++ i ) { + if( get_cword( i ) != SC_DIGIT_ZERO ) { + return false; + } + } + return true; +} + + +// r-value concatenation operators and functions + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> > +operator , ( sc_subref_r<T1> a, sc_bitref_r<T2> b ) +{ + return sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> > +operator , ( sc_subref_r<T1> a, sc_subref_r<T2> b ) +{ + return sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> > +operator , ( sc_subref_r<T1> a, sc_concref_r<T2,T3> b ) +{ + return sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,T2> +operator , ( sc_subref_r<T1> a, const sc_proxy<T2>& b ) +{ + return sc_concref_r<sc_subref_r<T1>,T2>( + *a.clone(), b.back_cast(), 1 ); +} + + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> > +concat( sc_subref_r<T1> a, sc_bitref_r<T2> b ) +{ + return sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> > +concat( sc_subref_r<T1> a, sc_subref_r<T2> b ) +{ + return sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> > +concat( sc_subref_r<T1> a, sc_concref_r<T2,T3> b ) +{ + return sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,T2> +concat( sc_subref_r<T1> a, const sc_proxy<T2>& b ) +{ + return sc_concref_r<sc_subref_r<T1>,T2>( + *a.clone(), b.back_cast(), 1 ); +} + + +#ifdef SC_DT_MIXED_COMMA_OPERATORS + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> > +operator , ( sc_subref_r<T1> a, sc_bitref<T2> b ) +{ + return sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> > +operator , ( sc_subref<T1> a, sc_bitref_r<T2> b ) +{ + return sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> > +operator , ( sc_subref_r<T1> a, sc_subref<T2> b ) +{ + return sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> > +operator , ( sc_subref<T1> a, sc_subref_r<T2> b ) +{ + return sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> > +operator , ( sc_subref_r<T1> a, sc_concref<T2,T3> b ) +{ + return sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> > +operator , ( sc_subref<T1> a, sc_concref_r<T2,T3> b ) +{ + return sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,T2> +operator , ( sc_subref<T1> a, const sc_proxy<T2>& b ) +{ + return sc_concref_r<sc_subref_r<T1>,T2>( + *a.clone(), b.back_cast(), 1 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,T2> +operator , ( sc_subref_r<T1> a, sc_proxy<T2>& b ) +{ + return sc_concref_r<sc_subref_r<T1>,T2>( + *a.clone(), b.back_cast(), 1 ); +} + + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> > +concat( sc_subref_r<T1> a, sc_bitref<T2> b ) +{ + return sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> > +concat( sc_subref<T1> a, sc_bitref_r<T2> b ) +{ + return sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> > +concat( sc_subref_r<T1> a, sc_subref<T2> b ) +{ + return sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> > +concat( sc_subref<T1> a, sc_subref_r<T2> b ) +{ + return sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> > +concat( sc_subref_r<T1> a, sc_concref<T2,T3> b ) +{ + return sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> > +concat( sc_subref<T1> a, sc_concref_r<T2,T3> b ) +{ + return sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,T2> +concat( sc_subref<T1> a, const sc_proxy<T2>& b ) +{ + return sc_concref_r<sc_subref_r<T1>,T2>( + *a.clone(), b.back_cast(), 1 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_subref_r<T1>,T2> +concat( sc_subref_r<T1> a, sc_proxy<T2>& b ) +{ + return sc_concref_r<sc_subref_r<T1>,T2>( + *a.clone(), b.back_cast(), 1 ); +} + +#endif + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_subref<X> +// +// Proxy class for sc_proxy part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +// assignment operators + +// sc_subref<X>::operator = ( const sc_subref_r<X>& ) in sc_lv_base.h +// sc_subref<X>::operator = ( const sc_subref<X>& ) in sc_lv_base.h + + +// other methods + +template <class T> +inline +void +sc_subref<T>::scan( ::std::istream& is ) +{ + std::string s; + is >> s; + *this = s.c_str(); +} + + +// l-value concatenation operators and functions + +template <class T1, class T2> +inline +sc_concref<sc_subref<T1>,sc_bitref<T2> > +operator , ( sc_subref<T1> a, sc_bitref<T2> b ) +{ + return sc_concref<sc_subref<T1>,sc_bitref<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref<sc_subref<T1>,sc_subref<T2> > +operator , ( sc_subref<T1> a, sc_subref<T2> b ) +{ + return sc_concref<sc_subref<T1>,sc_subref<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref<sc_subref<T1>,sc_concref<T2,T3> > +operator , ( sc_subref<T1> a, sc_concref<T2,T3> b ) +{ + return sc_concref<sc_subref<T1>,sc_concref<T2,T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref<sc_subref<T1>,T2> +operator , ( sc_subref<T1> a, sc_proxy<T2>& b ) +{ + return sc_concref<sc_subref<T1>,T2>( + *a.clone(), b.back_cast(), 1 ); +} + + +template <class T1, class T2> +inline +sc_concref<sc_subref<T1>,sc_bitref<T2> > +concat( sc_subref<T1> a, sc_bitref<T2> b ) +{ + return sc_concref<sc_subref<T1>,sc_bitref<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref<sc_subref<T1>,sc_subref<T2> > +concat( sc_subref<T1> a, sc_subref<T2> b ) +{ + return sc_concref<sc_subref<T1>,sc_subref<T2> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref<sc_subref<T1>,sc_concref<T2,T3> > +concat( sc_subref<T1> a, sc_concref<T2,T3> b ) +{ + return sc_concref<sc_subref<T1>,sc_concref<T2,T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref<sc_subref<T1>,T2> +concat( sc_subref<T1> a, sc_proxy<T2>& b ) +{ + return sc_concref<sc_subref<T1>,T2>( + *a.clone(), b.back_cast(), 1 ); +} + + +template <class X> +inline +::std::istream& +operator >> ( ::std::istream& is, sc_subref<X> a ) +{ + a.scan( is ); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_concref_r<X,Y> +// +// Proxy class for sc_proxy concatenation (r-value only). +// ---------------------------------------------------------------------------- + +// destructor + +template <class X, class Y> +inline +sc_concref_r<X,Y>::~sc_concref_r() +{ + if( -- m_refs == 0 ) { + delete &m_refs; + if( m_delete == 0 ) { + return; + } + if( m_delete & 1 ) { + delete &m_left; + } + if( m_delete & 2 ) { + delete &m_right; + } + } +} + + +// common methods + +template <class X, class Y> +inline +sc_logic_value_t +sc_concref_r<X,Y>::get_bit( int n ) const +{ + int r_len = m_right.length(); + if( n < r_len ) { + return m_right.get_bit( n ); + } else if( n < r_len + m_left.length() ) { + return m_left.get_bit( n - r_len ); + } else { + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 ); + // never reached + return Log_0; + } +} + +template <class X, class Y> +inline +void +sc_concref_r<X,Y>::set_bit( int n, sc_logic_value_t v ) +{ + int r_len = m_right.length(); + if( n < r_len ) { + m_right.set_bit( n, v ); + } else if( n < r_len + m_left.length() ) { + m_left.set_bit( n - r_len, v ); + } else { + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 ); + } +} + + +template <class X, class Y> +inline +sc_digit +sc_concref_r<X,Y>::get_word( int i ) const +{ + if( i < 0 || i >= size() ) { + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 ); + } + // 0 <= i < size() + Y& r = m_right; + int r_len = r.length(); + int border = r_len / SC_DIGIT_SIZE; + if( i < border ) { + return r.get_word( i ); + } + // border <= i < size() + X& l = m_left; + int shift = r_len % SC_DIGIT_SIZE; + int j = i - border; + if( shift == 0 ) { + return l.get_word( j ); + } + // border <= i < size() && shift != 0 + int nshift = SC_DIGIT_SIZE - shift; + if( i == border ) { + sc_digit rl_mask = ~SC_DIGIT_ZERO >> nshift; + return ( (r.get_word( i ) & rl_mask) | (l.get_word( 0 ) << shift) ); + } + // border < i < size() && shift != 0 + if ( j < l.size() ) + return ( (l.get_word( j - 1 ) >> nshift) | (l.get_word( j ) << shift) ); + else + return (l.get_word( j - 1 ) >> nshift); +} + +template <class X, class Y> +inline +void +sc_concref_r<X,Y>::set_word( int i, sc_digit w ) +{ + if( i < 0 || i >= size() ) { + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 ); + } + // 0 <= i < size() + Y& r = m_right; + int r_len = r.length(); + int border = r_len / SC_DIGIT_SIZE; + if( i < border ) { + r.set_word( i, w ); + return; + } + // border <= i < size() + X& l = m_left; + int shift = r_len % SC_DIGIT_SIZE; + int j = i - border; + if( shift == 0 ) { + l.set_word( j, w ); + return; + } + // border <= i < size() && shift != 0 + int nshift = SC_DIGIT_SIZE - shift; + sc_digit lh_mask = ~SC_DIGIT_ZERO << nshift; + if( i == border ) { + sc_digit rl_mask = ~SC_DIGIT_ZERO >> nshift; + r.set_word( i, w & rl_mask ); + l.set_word( 0, (l.get_word( 0 ) & lh_mask) | (w >> shift) ); + return; + } + // border < i < size() && shift != 0 + sc_digit ll_mask = ~SC_DIGIT_ZERO >> shift; + l.set_word( j - 1, (l.get_word( j - 1 ) & ll_mask) | (w << nshift) ); + if ( j < l.size() ) + l.set_word( j, (l.get_word( j ) & lh_mask) | (w >> shift) ); +} + + +template <class X, class Y> +inline +sc_digit +sc_concref_r<X,Y>::get_cword( int i ) const +{ + if( i < 0 || i >= size() ) { + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 ); + } + // 0 <= i < size() + Y& r = m_right; + int r_len = r.length(); + int border = r_len / SC_DIGIT_SIZE; + if( i < border ) { + return r.get_cword( i ); + } + // border <= i < size() + X& l = m_left; + int shift = r_len % SC_DIGIT_SIZE; + int j = i - border; + if( shift == 0 ) { + return l.get_cword( j ); + } + // border <= i < size() && shift != 0 + int nshift = SC_DIGIT_SIZE - shift; + if( i == border ) { + sc_digit rl_mask = ~SC_DIGIT_ZERO >> nshift; + return ( (r.get_cword( i ) & rl_mask) | (l.get_cword( 0 ) << shift) ); + } + // border < i < size() && shift != 0 + if ( j < l.size() ) + return ( (l.get_cword(j - 1) >> nshift) | (l.get_cword(j) << shift) ); + else + return (l.get_cword( j - 1 ) >> nshift); +} + +template <class X, class Y> +inline +void +sc_concref_r<X,Y>::set_cword( int i, sc_digit w ) +{ + if( i < 0 || i >= size() ) { + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 ); + } + // 0 <= i < size() + Y& r = m_right; + int r_len = r.length(); + int border = r_len / SC_DIGIT_SIZE; + if( i < border ) { + r.set_cword( i, w ); + return; + } + // border <= i < size() + X& l = m_left; + int shift = r_len % SC_DIGIT_SIZE; + int j = i - border; + if( shift == 0 ) { + l.set_cword( j, w ); + return; + } + // border <= i < size() && shift != 0 + int nshift = SC_DIGIT_SIZE - shift; + sc_digit lh_mask = ~SC_DIGIT_ZERO << nshift; + if( i == border ) { + sc_digit rl_mask = ~SC_DIGIT_ZERO >> nshift; + r.set_cword( i, w & rl_mask ); + l.set_cword( 0, (l.get_cword( 0 ) & lh_mask) | (w >> shift) ); + return; + } + // border < i < size() && shift != 0 + sc_digit ll_mask = ~SC_DIGIT_ZERO >> shift; + l.set_cword( j - 1, (l.get_cword( j - 1 ) & ll_mask) | (w << nshift) ); + if ( j < l.size() ) + l.set_cword( j, (l.get_cword( j ) & lh_mask) | (w >> shift) ); +} + + +// r-value concatenation operators and functions + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> > +operator , ( sc_concref_r<T1,T2> a, sc_bitref_r<T3> b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> > +operator , ( sc_concref_r<T1,T2> a, sc_subref_r<T3> b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3, class T4> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> > +operator , ( sc_concref_r<T1,T2> a, sc_concref_r<T3,T4> b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,T3> +operator , ( sc_concref_r<T1,T2> a, const sc_proxy<T3>& b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,T3>( + *a.clone(), b.back_cast(), 1 ); +} + + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> > +concat( sc_concref_r<T1,T2> a, sc_bitref_r<T3> b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> > +concat( sc_concref_r<T1,T2> a, sc_subref_r<T3> b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3, class T4> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> > +concat( sc_concref_r<T1,T2> a, sc_concref_r<T3,T4> b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,T3> +concat( sc_concref_r<T1,T2> a, const sc_proxy<T3>& b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,T3>( + *a.clone(), b.back_cast(), 1 ); +} + + +#ifdef SC_DT_MIXED_COMMA_OPERATORS + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> > +operator , ( sc_concref_r<T1,T2> a, sc_bitref<T3> b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> > +operator , ( sc_concref<T1,T2> a, sc_bitref_r<T3> b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> > +operator , ( sc_concref_r<T1,T2> a, sc_subref<T3> b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> > +operator , ( sc_concref<T1,T2> a, sc_subref_r<T3> b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3, class T4> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> > +operator , ( sc_concref_r<T1,T2> a, sc_concref<T3,T4> b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3, class T4> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> > +operator , ( sc_concref<T1,T2> a, sc_concref_r<T3,T4> b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,T3> +operator , ( sc_concref<T1,T2> a, const sc_proxy<T3>& b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,T3>( + *a.clone(), b.back_cast(), 1 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,T3> +operator , ( sc_concref_r<T1,T2> a, sc_proxy<T3>& b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,T3>( + *a.clone(), b.back_cast(), 1 ); +} + + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> > +concat( sc_concref_r<T1,T2> a, sc_bitref<T3> b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> > +concat( sc_concref<T1,T2> a, sc_bitref_r<T3> b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> > +concat( sc_concref_r<T1,T2> a, sc_subref<T3> b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> > +concat( sc_concref<T1,T2> a, sc_subref_r<T3> b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3, class T4> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> > +concat( sc_concref_r<T1,T2> a, sc_concref<T3,T4> b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3, class T4> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> > +concat( sc_concref<T1,T2> a, sc_concref_r<T3,T4> b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,T3> +concat( sc_concref<T1,T2> a, const sc_proxy<T3>& b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,T3>( + *a.clone(), b.back_cast(), 1 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1,T2>,T3> +concat( sc_concref_r<T1,T2> a, sc_proxy<T3>& b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,T3>( + *a.clone(), b.back_cast(), 1 ); +} + +#endif + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_concref<X,Y> +// +// Proxy class for sc_proxy concatenation (r-value and l-value). +// ---------------------------------------------------------------------------- + +// other methods + +template <class T1, class T2> +inline +void +sc_concref<T1,T2>::scan( ::std::istream& is ) +{ + std::string s; + is >> s; + *this = s.c_str(); +} + + +// l-value concatenation operators and functions + +template <class T1, class T2, class T3> +inline +sc_concref<sc_concref<T1,T2>,sc_bitref<T3> > +operator , ( sc_concref<T1,T2> a, sc_bitref<T3> b ) +{ + return sc_concref<sc_concref<T1,T2>,sc_bitref<T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref<sc_concref<T1,T2>,sc_subref<T3> > +operator , ( sc_concref<T1,T2> a, sc_subref<T3> b ) +{ + return sc_concref<sc_concref<T1,T2>,sc_subref<T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3, class T4> +inline +sc_concref<sc_concref<T1,T2>,sc_concref<T3,T4> > +operator , ( sc_concref<T1,T2> a, sc_concref<T3,T4> b ) +{ + return sc_concref<sc_concref<T1,T2>,sc_concref<T3,T4> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref<sc_concref<T1,T2>,T3> +operator , ( sc_concref<T1,T2> a, sc_proxy<T3>& b ) +{ + return sc_concref<sc_concref<T1,T2>,T3>( + *a.clone(), b.back_cast(), 1 ); +} + + +template <class T1, class T2, class T3> +inline +sc_concref<sc_concref<T1,T2>,sc_bitref<T3> > +concat( sc_concref<T1,T2> a, sc_bitref<T3> b ) +{ + return sc_concref<sc_concref<T1,T2>,sc_bitref<T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref<sc_concref<T1,T2>,sc_subref<T3> > +concat( sc_concref<T1,T2> a, sc_subref<T3> b ) +{ + return sc_concref<sc_concref<T1,T2>,sc_subref<T3> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3, class T4> +inline +sc_concref<sc_concref<T1,T2>,sc_concref<T3,T4> > +concat( sc_concref<T1,T2> a, sc_concref<T3,T4> b ) +{ + return sc_concref<sc_concref<T1,T2>,sc_concref<T3,T4> >( + *a.clone(), *b.clone(), 3 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref<sc_concref<T1,T2>,T3> +concat( sc_concref<T1,T2> a, sc_proxy<T3>& b ) +{ + return sc_concref<sc_concref<T1,T2>,T3>( + *a.clone(), b.back_cast(), 1 ); +} + + +template <class X, class Y> +inline +::std::istream& +operator >> ( ::std::istream& is, sc_concref<X,Y> a ) +{ + a.scan( is ); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_proxy<T> +// +// Base class template for bit/logic vector classes. +// (Barton/Nackmann implementation) +// ---------------------------------------------------------------------------- + +// r-value concatenation operators and functions + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_bitref_r<T2> > +operator , ( const sc_proxy<T1>& a, sc_bitref_r<T2> b ) +{ + return sc_concref_r<T1,sc_bitref_r<T2> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_subref_r<T2> > +operator , ( const sc_proxy<T1>& a, sc_subref_r<T2> b ) +{ + return sc_concref_r<T1,sc_subref_r<T2> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<T1,sc_concref_r<T2,T3> > +operator , ( const sc_proxy<T1>& a, sc_concref_r<T2,T3> b ) +{ + return sc_concref_r<T1,sc_concref_r<T2,T3> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2> +inline +sc_concref_r<T1,T2> +operator , ( const sc_proxy<T1>& a, const sc_proxy<T2>& b ) +{ + return sc_concref_r<T1,T2>( + a.back_cast(), b.back_cast() ); +} + + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_bitref_r<T2> > +concat( const sc_proxy<T1>& a, sc_bitref_r<T2> b ) +{ + return sc_concref_r<T1,sc_bitref_r<T2> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_subref_r<T2> > +concat( const sc_proxy<T1>& a, sc_subref_r<T2> b ) +{ + return sc_concref_r<T1,sc_subref_r<T2> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<T1,sc_concref_r<T2,T3> > +concat( const sc_proxy<T1>& a, sc_concref_r<T2,T3> b ) +{ + return sc_concref_r<T1,sc_concref_r<T2,T3> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2> +inline +sc_concref_r<T1,T2> +concat( const sc_proxy<T1>& a, const sc_proxy<T2>& b ) +{ + return sc_concref_r<T1,T2>( + a.back_cast(), b.back_cast() ); +} + + +#ifdef SC_DT_MIXED_COMMA_OPERATORS + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_bitref_r<T2> > +operator , ( const sc_proxy<T1>& a, sc_bitref<T2> b ) +{ + return sc_concref_r<T1,sc_bitref_r<T2> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_bitref_r<T2> > +operator , ( sc_proxy<T1>& a, sc_bitref_r<T2> b ) +{ + return sc_concref_r<T1,sc_bitref_r<T2> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_subref_r<T2> > +operator , ( const sc_proxy<T1>& a, sc_subref<T2> b ) +{ + return sc_concref_r<T1,sc_subref_r<T2> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_subref_r<T2> > +operator , ( sc_proxy<T1>& a, sc_subref_r<T2> b ) +{ + return sc_concref_r<T1,sc_subref_r<T2> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<T1,sc_concref_r<T2,T3> > +operator , ( const sc_proxy<T1>& a, sc_concref<T2,T3> b ) +{ + return sc_concref_r<T1,sc_concref_r<T2,T3> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<T1,sc_concref_r<T2,T3> > +operator , ( sc_proxy<T1>& a, sc_concref_r<T2,T3> b ) +{ + return sc_concref_r<T1,sc_concref_r<T2,T3> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2> +inline +sc_concref_r<T1,T2> +operator , ( const sc_proxy<T1>& a, sc_proxy<T2>& b ) +{ + return sc_concref_r<T1,T2>( + a.back_cast(), b.back_cast() ); +} + +template <class T1, class T2> +inline +sc_concref_r<T1,T2> +operator , ( sc_proxy<T1>& a, const sc_proxy<T2>& b ) +{ + return sc_concref_r<T1,T2>( + a.back_cast(), b.back_cast() ); +} + + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_bitref_r<T2> > +concat( const sc_proxy<T1>& a, sc_bitref<T2> b ) +{ + return sc_concref_r<T1,sc_bitref_r<T2> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_bitref_r<T2> > +concat( sc_proxy<T1>& a, sc_bitref_r<T2> b ) +{ + return sc_concref_r<T1,sc_bitref_r<T2> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_subref_r<T2> > +concat( const sc_proxy<T1>& a, sc_subref<T2> b ) +{ + return sc_concref_r<T1,sc_subref_r<T2> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2> +inline +sc_concref_r<T1,sc_subref_r<T2> > +concat( sc_proxy<T1>& a, sc_subref_r<T2> b ) +{ + return sc_concref_r<T1,sc_subref_r<T2> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<T1,sc_concref_r<T2,T3> > +concat( const sc_proxy<T1>& a, sc_concref<T2,T3> b ) +{ + return sc_concref_r<T1,sc_concref_r<T2,T3> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<T1,sc_concref_r<T2,T3> > +concat( sc_proxy<T1>& a, sc_concref_r<T2,T3> b ) +{ + return sc_concref_r<T1,sc_concref_r<T2,T3> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2> +inline +sc_concref_r<T1,T2> +concat( const sc_proxy<T1>& a, sc_proxy<T2>& b ) +{ + return sc_concref_r<T1,T2>( + a.back_cast(), b.back_cast() ); +} + +template <class T1, class T2> +inline +sc_concref_r<T1,T2> +concat( sc_proxy<T1>& a, const sc_proxy<T2>& b ) +{ + return sc_concref_r<T1,T2>( + a.back_cast(), b.back_cast() ); +} + +#endif + + +// l-value concatenation operators and functions + +template <class T1, class T2> +inline +sc_concref<T1,sc_bitref<T2> > +operator , ( sc_proxy<T1>& a, sc_bitref<T2> b ) +{ + return sc_concref<T1,sc_bitref<T2> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2> +inline +sc_concref<T1,sc_subref<T2> > +operator , ( sc_proxy<T1>& a, sc_subref<T2> b ) +{ + return sc_concref<T1,sc_subref<T2> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref<T1,sc_concref<T2,T3> > +operator , ( sc_proxy<T1>& a, sc_concref<T2,T3> b ) +{ + return sc_concref<T1,sc_concref<T2,T3> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2> +inline +sc_concref<T1,T2> +operator , ( sc_proxy<T1>& a, sc_proxy<T2>& b ) +{ + return sc_concref<T1,T2>( + a.back_cast(), b.back_cast() ); +} + + +template <class T1, class T2> +inline +sc_concref<T1,sc_bitref<T2> > +concat( sc_proxy<T1>& a, sc_bitref<T2> b ) +{ + return sc_concref<T1,sc_bitref<T2> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2> +inline +sc_concref<T1,sc_subref<T2> > +concat( sc_proxy<T1>& a, sc_subref<T2> b ) +{ + return sc_concref<T1,sc_subref<T2> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2, class T3> +inline +sc_concref<T1,sc_concref<T2,T3> > +concat( sc_proxy<T1>& a, sc_concref<T2,T3> b ) +{ + return sc_concref<T1,sc_concref<T2,T3> >( + a.back_cast(), *b.clone(), 2 ); +} + +template <class T1, class T2> +inline +sc_concref<T1,T2> +concat( sc_proxy<T1>& a, sc_proxy<T2>& b ) +{ + return sc_concref<T1,T2>( + a.back_cast(), b.back_cast() ); +} + +} // namespace sc_dt + +// $Log: sc_bit_proxies.h,v $ +// Revision 1.10 2011/09/05 21:19:53 acg +// Philipp A. Hartmann: added parentheses to expressions to eliminate +// compiler warnings. +// +// Revision 1.9 2011/09/01 15:03:42 acg +// Philipp A. Hartmann: add parentheses to eliminate compiler warnings. +// +// Revision 1.8 2011/08/29 18:04:32 acg +// Philipp A. Hartmann: miscellaneous clean ups. +// +// Revision 1.7 2011/08/24 22:05:40 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.6 2010/02/22 14:25:43 acg +// Andy Goodrich: removed 'mutable' directive from references, since it +// is not a legal C++ construct. +// +// Revision 1.5 2009/02/28 00:26:14 acg +// Andy Goodrich: bug fixes. +// +// Revision 1.4 2007/03/14 17:48:37 acg +// Andy Goodrich: fixed bug. +// +// Revision 1.3 2007/01/18 19:29:18 acg +// Andy Goodrich: fixed bug in concatenations of bit selects on sc_lv and +// sc_bv types. The offending code was in sc_bitref<X>::set_word and +// sc_bitref<X>::get_word. These methods were not writing the bit they +// represented, but rather writing an entire word whose index was the +// index of the bit they represented. This not only did not write the +// correct bit, but clobbered a word that might not even be in the +// variable the reference was for. +// +// Revision 1.2 2007/01/17 22:45:08 acg +// Andy Goodrich: fixed sc_bitref<X>::set_bit(). +// +// Revision 1.1.1.1 2006/12/15 20:31:36 acg +// SystemC 2.2 +// +// Revision 1.3 2006/01/13 18:53:53 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + + +#endif diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_bv.h b/ext/systemc/src/sysc/datatypes/bit/sc_bv.h new file mode 100644 index 000000000..de4221c7f --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/bit/sc_bv.h @@ -0,0 +1,201 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_bv.h -- Arbitrary size bit vector class. + + Original Author: Gene Bushuyev, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_bv.h,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:53 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_BV_H +#define SC_BV_H + + +#include "sysc/datatypes/bit/sc_bv_base.h" + + +namespace sc_dt +{ + +// classes defined in this module +template <int W> class sc_bv; + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_bv<W> +// +// Arbitrary size bit vector class. +// ---------------------------------------------------------------------------- + +template <int W> +class sc_bv + : public sc_bv_base +{ +public: + + // constructors + + sc_bv() + :sc_bv_base( W ) + {} + + explicit sc_bv( bool init_value ) + : sc_bv_base( init_value, W ) + {} + + explicit sc_bv( char init_value ) + : sc_bv_base( (init_value != '0'), W ) + {} + + sc_bv( const char* a ) + : sc_bv_base( W ) + { sc_bv_base::operator = ( a ); } + + sc_bv( const bool* a ) + : sc_bv_base( W ) + { sc_bv_base::operator = ( a ); } + + sc_bv( const sc_logic* a ) + : sc_bv_base( W ) + { sc_bv_base::operator = ( a ); } + + sc_bv( const sc_unsigned& a ) + : sc_bv_base( W ) + { sc_bv_base::operator = ( a ); } + + sc_bv( const sc_signed& a ) + : sc_bv_base( W ) + { sc_bv_base::operator = ( a ); } + + sc_bv( const sc_uint_base& a ) + : sc_bv_base( W ) + { sc_bv_base::operator = ( a ); } + + sc_bv( const sc_int_base& a ) + : sc_bv_base( W ) + { sc_bv_base::operator = ( a ); } + + sc_bv( unsigned long a ) + : sc_bv_base( W ) + { sc_bv_base::operator = ( a ); } + + sc_bv( long a ) + : sc_bv_base( W ) + { sc_bv_base::operator = ( a ); } + + sc_bv( unsigned int a ) + : sc_bv_base( W ) + { sc_bv_base::operator = ( a ); } + + sc_bv( int a ) + : sc_bv_base( W ) + { sc_bv_base::operator = ( a ); } + + sc_bv( uint64 a ) + : sc_bv_base( W ) + { sc_bv_base::operator = ( a ); } + + sc_bv( int64 a ) + : sc_bv_base( W ) + { sc_bv_base::operator = ( a ); } + + template <class X> + sc_bv( const sc_proxy<X>& a ) + : sc_bv_base( W ) + { sc_bv_base::operator = ( a ); } + + sc_bv( const sc_bv<W>& a ) + : sc_bv_base( a ) + {} + + + // assignment operators + + template <class X> + sc_bv<W>& operator = ( const sc_proxy<X>& a ) + { sc_bv_base::operator = ( a ); return *this; } + + sc_bv<W>& operator = ( const sc_bv<W>& a ) + { sc_bv_base::operator = ( a ); return *this; } + + sc_bv<W>& operator = ( const char* a ) + { sc_bv_base::operator = ( a ); return *this; } + + sc_bv<W>& operator = ( const bool* a ) + { sc_bv_base::operator = ( a ); return *this; } + + sc_bv<W>& operator = ( const sc_logic* a ) + { sc_bv_base::operator = ( a ); return *this; } + + sc_bv<W>& operator = ( const sc_unsigned& a ) + { sc_bv_base::operator = ( a ); return *this; } + + sc_bv<W>& operator = ( const sc_signed& a ) + { sc_bv_base::operator = ( a ); return *this; } + + sc_bv<W>& operator = ( const sc_uint_base& a ) + { sc_bv_base::operator = ( a ); return *this; } + + sc_bv<W>& operator = ( const sc_int_base& a ) + { sc_bv_base::operator = ( a ); return *this; } + + sc_bv<W>& operator = ( unsigned long a ) + { sc_bv_base::operator = ( a ); return *this; } + + sc_bv<W>& operator = ( long a ) + { sc_bv_base::operator = ( a ); return *this; } + + sc_bv<W>& operator = ( unsigned int a ) + { sc_bv_base::operator = ( a ); return *this; } + + sc_bv<W>& operator = ( int a ) + { sc_bv_base::operator = ( a ); return *this; } + + sc_bv<W>& operator = ( uint64 a ) + { sc_bv_base::operator = ( a ); return *this; } + + sc_bv<W>& operator = ( int64 a ) + { sc_bv_base::operator = ( a ); return *this; } +}; + +} // namespace sc_dt + + +#endif diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_bv_base.cpp b/ext/systemc/src/sysc/datatypes/bit/sc_bv_base.cpp new file mode 100644 index 000000000..b6ffaa32b --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/bit/sc_bv_base.cpp @@ -0,0 +1,388 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_bv_base.cpp -- Arbitrary size bit vector class. + + Original Author: Gene Bushuyev, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_bv_base.cpp,v $ +// Revision 1.2 2011/08/24 22:05:40 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.4 2006/04/11 23:12:26 acg +// Andy Goodrich: Fixed bug in parsing of extended string constants like +// 0bus1110011. +// +// Revision 1.3 2006/01/13 18:53:53 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#include <string.h> + +#include "sysc/datatypes/bit/sc_bit_ids.h" +#include "sysc/datatypes/bit/sc_bv_base.h" +#include "sysc/datatypes/fx/sc_fix.h" +#include "sysc/datatypes/fx/sc_ufix.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// CLASS : sc_bv_base +// +// Arbitrary size bit vector base class. +// ---------------------------------------------------------------------------- + +void +sc_bv_base::init( int length_, bool init_value ) +{ + // check the length + if( length_ <= 0 ) { + SC_REPORT_ERROR( sc_core::SC_ID_ZERO_LENGTH_, 0 ); + } + // allocate memory for the data and control words + m_len = length_; + m_size = (m_len - 1) / SC_DIGIT_SIZE + 1; + m_data = new sc_digit[m_size]; + // initialize the bits to 'init_value' + sc_digit dw = init_value ? ~SC_DIGIT_ZERO : SC_DIGIT_ZERO; + int sz = m_size; + for( int i = 0; i < sz; ++ i ) { + m_data[i] = dw; + } + clean_tail(); +} + + +void +sc_bv_base::assign_from_string( const std::string& s ) +{ + // s must have been converted to bin + int len = m_len; + int s_len = s.length() - 1; + int min_len = sc_min( len, s_len ); + int i = 0; + for( ; i < min_len; ++ i ) { + char c = s[s_len - i - 1]; + if( c != '0' && c != '1' ) { + SC_REPORT_ERROR( sc_core::SC_ID_CANNOT_CONVERT_, + "string can contain only '0' and '1' characters" ); + } + set_bit( i, sc_logic_value_t( c - '0' ) ); + } + // if formatted, fill the rest with sign(s), otherwise fill with zeros + sc_logic_value_t fill = (s[s_len] == 'F' ? sc_logic_value_t( s[0] - '0' ) + : sc_logic_value_t( 0 )); + for( ; i < len; ++ i ) { + set_bit( i, fill ); + } +} + + +// constructors + +sc_bv_base::sc_bv_base( const char* a ) + : m_len( 0 ), m_size( 0 ), m_data( 0 ) +{ + std::string s = convert_to_bin( a ); + init( s.length() - 1 ); + assign_from_string( s ); +} + +sc_bv_base::sc_bv_base( const char* a, int length_ ) + : m_len( 0 ), m_size( 0 ), m_data( 0 ) +{ + init( length_ ); + assign_from_string( convert_to_bin( a ) ); +} + +sc_bv_base::sc_bv_base( const sc_bv_base& a ) + : sc_proxy<sc_bv_base>(), + m_len( a.m_len ), + m_size( a.m_size ), + m_data( new sc_digit[m_size] ) +{ + // copy the bits + int sz = m_size; + for( int i = 0; i < sz; ++ i ) { + m_data[i] = a.m_data[i]; + } +} + + +// assignment operators + +sc_bv_base& +sc_bv_base::operator = ( const char* a ) +{ + assign_from_string( convert_to_bin( a ) ); + return *this; +} + + +#if 0 + +// bitwise complement + +sc_bv_base& +sc_bv_base::b_not() +{ + int sz = m_size; + for( int i = 0; i < sz; ++ i ) { + m_data[i] = ~m_data[i]; + } + clean_tail(); + return *this; +} + + +// bitwise left shift + +sc_bv_base& +sc_bv_base::operator <<= ( int n ) +{ + if( n < 0 ) { + char msg[BUFSIZ]; + std::sprintf( msg, + "left shift operation is only allowed with positive " + "shift values, shift value = %d", n ); + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); + } + int sz = m_size; + if( n >= m_len ) { + for( int i = 0; i < sz; ++ i ) { + m_data[i] = SC_DIGIT_ZERO; + } + // clean_tail(); + return *this; + } + int wn = n / SC_DIGIT_SIZE; + int bn = n % SC_DIGIT_SIZE; + if( wn != 0 ) { + // shift words + int i = sz - 1; + for( ; i >= wn; -- i ) { + m_data[i] = m_data[i - wn]; + } + for( ; i >= 0; -- i ) { + m_data[i] = SC_DIGIT_ZERO; + } + } + if( bn != 0 ) { + // shift bits + for( int i = sz - 1; i >= 1; -- i ) { + m_data[i] <<= bn; + m_data[i] |= m_data[i - 1] >> (SC_DIGIT_SIZE - bn); + } + m_data[0] <<= bn; + } + clean_tail(); + return *this; +} + + +// bitwise right shift + +sc_bv_base& +sc_bv_base::operator >>= ( int n ) +{ + if( n < 0 ) { + char msg[BUFSIZ]; + std::sprintf( msg, + "right shift operation is only allowed with positive " + "shift values, shift value = %d", n ); + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); + } + int sz = m_size; + if( n >= m_len ) { + for( int i = 0; i < sz; ++ i ) { + m_data[i] = SC_DIGIT_ZERO; + } + // clean_tail(); + return *this; + } + int wn = n / SC_DIGIT_SIZE; + int bn = n % SC_DIGIT_SIZE; + if( wn != 0 ) { + // shift words + int i = 0; + for( ; i < (sz - wn); ++ i ) { + m_data[i] = m_data[i + wn]; + } + for( ; i < sz; ++ i ) { + m_data[i] = SC_DIGIT_ZERO; + } + } + if( bn != 0 ) { + // shift bits + for( int i = 0; i < (sz - 1); ++ i ) { + m_data[i] >>= bn; + m_data[i] |= m_data[i + 1] << (SC_DIGIT_SIZE - bn); + } + m_data[sz - 1] >>= bn; + } + clean_tail(); + return *this; +} + + +// bitwise left rotate + +sc_bv_base& +sc_bv_base::lrotate( int n ) +{ + if( n < 0 ) { + char msg[BUFSIZ]; + std::sprintf( msg, + "left rotate operation is only allowed with positive " + "rotate values, rotate value = %d", n ); + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); + } + int len = m_len; + n %= len; + *this = (*this << n) | (*this >> (len - n)); + return *this; +} + + +// bitwise right rotate + +sc_bv_base& +sc_bv_base::rrotate( int n ) +{ + if( n < 0 ) { + char msg[BUFSIZ]; + std::sprintf( msg, + "right rotate operation is only allowed with positive " + "rotate values, rotate value = %d", n ); + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); + } + int len = m_len; + n %= len; + *this = (*this >> n) | (*this << (len - n)); + return *this; +} + +#endif + + +// ---------------------------------------------------------------------------- + +// convert formatted string to binary string + +const std::string +convert_to_bin( const char* s ) +{ + // Beware: logic character strings cannot start with '0x' or '0X', + // because this is seen as a hexadecimal encoding prefix! + + if( s == 0 ) { + SC_REPORT_ERROR(sc_core::SC_ID_CANNOT_CONVERT_, + "character string is zero" ); + } + if( *s == 0 ) { + SC_REPORT_ERROR(sc_core::SC_ID_CANNOT_CONVERT_, + "character string is empty"); + } + + int n = strlen( s ); + int i = 0; + if( s[0] == '-' || s[0] == '+' ) { + ++ i; + } + if( n > (i + 2) && s[i] == '0' ) + { + if (s[i+1] == 'b' || s[i+1] == 'B' ) + { + if ( s[i+2] == '0' || s[i+2] == '1' ) + { + std::string str( &s[2] ); + str += "F"; + return str; + } + } + if ( s[i+1] == 'b' || s[i+1] == 'B' || + s[i+1] == 'c' || s[i+1] == 'C' || + s[i+1] == 'd' || s[i+1] == 'D' || + s[i+1] == 'o' || s[i+1] == 'O' || + s[i+1] == 'x' || s[i+1] == 'X') + { + try { + // worst case length = n * 4 + sc_fix a( s, n * 4, n * 4, SC_TRN, SC_WRAP, 0, SC_ON ); + std::string str = a.to_bin(); + str += "F"; // mark the string as formatted + // get rid of prefix (0b) and redundant leading bits + const char* p = str.c_str() + 2; + while( p[1] && p[0] == p[1] ) { + ++ p; + } + return std::string( p ); + } catch( sc_core::sc_report ) { + char msg[BUFSIZ]; + std::sprintf( msg, "character string '%s' is not valid", s ); + SC_REPORT_ERROR( sc_core::SC_ID_CANNOT_CONVERT_, msg ); + // never reached + return std::string(); + } + } + + } + + // bin by default + + std::string str( s ); + str += "U"; // mark the string as unformatted + return str; +} + +// convert binary string to formatted string + +const std::string +convert_to_fmt( const std::string& s, sc_numrep numrep, bool w_prefix ) +{ + int n = s.length(); + std::string str("0bus"); + // str += "0bus"; + str += s; + sc_ufix a( str.c_str(), n, n, SC_TRN, SC_WRAP, 0, SC_ON ); + return a.to_string( numrep, w_prefix ); +} + +} // namespace sc_dt diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_bv_base.h b/ext/systemc/src/sysc/datatypes/bit/sc_bv_base.h new file mode 100644 index 000000000..279001da5 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/bit/sc_bv_base.h @@ -0,0 +1,339 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_bv_base.h -- Arbitrary size bit vector class. + + Original Author: Gene Bushuyev, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_bv_base.h,v $ +// Revision 1.3 2011/08/26 22:32:00 acg +// Torsten Maehne: added parentheses to make opearator ordering more obvious. +// +// Revision 1.2 2011/08/15 16:43:24 acg +// Torsten Maehne: changes to remove unused argument warnings. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:53 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_BV_BASE_H +#define SC_BV_BASE_H + + +#include "sysc/datatypes/bit/sc_bit_ids.h" +#include "sysc/datatypes/bit/sc_bit_proxies.h" +#include "sysc/datatypes/bit/sc_proxy.h" +#include "sysc/datatypes/int/sc_length_param.h" + + +namespace sc_dt +{ + +// classes defined in this module +class sc_bv_base; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_bv_base +// +// Arbitrary size bit vector base class. +// ---------------------------------------------------------------------------- + +class sc_bv_base + : public sc_proxy<sc_bv_base> +{ + friend class sc_lv_base; + + + void init( int length_, bool init_value = false ); + + void assign_from_string( const std::string& ); + +public: + + // typedefs + + typedef sc_proxy<sc_bv_base> base_type; + + + // constructors + + explicit sc_bv_base( int length_ = sc_length_param().len() ) + : m_len( 0 ), m_size( 0 ), m_data( 0 ) + { init( length_ ); } + + explicit sc_bv_base( bool a, + int length_ = sc_length_param().len() ) + : m_len( 0 ), m_size( 0 ), m_data( 0 ) + { init( length_, a ); } + + sc_bv_base( const char* a ); + + sc_bv_base( const char* a, int length_ ); + + template <class X> + sc_bv_base( const sc_proxy<X>& a ) + : m_len( 0 ), m_size( 0 ), m_data( 0 ) + { init( a.back_cast().length() ); base_type::assign_( a ); } + + sc_bv_base( const sc_bv_base& a ); + +#ifdef SC_DT_DEPRECATED + + explicit sc_bv_base( const sc_unsigned& a ) + : m_len( 0 ), m_size( 0 ), m_data( 0 ) + { init( a.length() ); base_type::assign_( a ); } + + explicit sc_bv_base( const sc_signed& a ) + : m_len( 0 ), m_size( 0 ), m_data( 0 ) + { init( a.length() ); base_type::assign_( a ); } + + explicit sc_bv_base( const sc_uint_base& a) + : m_len( 0 ), m_size( 0 ), m_data( 0 ) + { init( a.length() ); base_type::assign_( a ); } + + explicit sc_bv_base( const sc_int_base& a) + : m_len( 0 ), m_size( 0 ), m_data( 0 ) + { init( a.length() ); base_type::assign_( a ); } + +#endif + + + // destructor + + virtual ~sc_bv_base() + { delete [] m_data; } + + + // assignment operators + + template <class X> + sc_bv_base& operator = ( const sc_proxy<X>& a ) + { assign_p_( *this, a ); return *this; } + + sc_bv_base& operator = ( const sc_bv_base& a ) + { assign_p_( *this, a ); return *this; } + + sc_bv_base& operator = ( const char* a ); + + sc_bv_base& operator = ( const bool* a ) + { base_type::assign_( a ); return *this; } + + sc_bv_base& operator = ( const sc_logic* a ) + { base_type::assign_( a ); return *this; } + + sc_bv_base& operator = ( const sc_unsigned& a ) + { base_type::assign_( a ); return *this; } + + sc_bv_base& operator = ( const sc_signed& a ) + { base_type::assign_( a ); return *this; } + + sc_bv_base& operator = ( const sc_uint_base& a ) + { base_type::assign_( a ); return *this; } + + sc_bv_base& operator = ( const sc_int_base& a ) + { base_type::assign_( a ); return *this; } + + sc_bv_base& operator = ( unsigned long a ) + { base_type::assign_( a ); return *this; } + + sc_bv_base& operator = ( long a ) + { base_type::assign_( a ); return *this; } + + sc_bv_base& operator = ( unsigned int a ) + { base_type::assign_( a ); return *this; } + + sc_bv_base& operator = ( int a ) + { base_type::assign_( a ); return *this; } + + sc_bv_base& operator = ( uint64 a ) + { base_type::assign_( a ); return *this; } + + sc_bv_base& operator = ( int64 a ) + { base_type::assign_( a ); return *this; } + + +#if 0 + + // bitwise complement + + sc_bv_base& b_not(); + + const sc_bv_base operator ~ () const + { sc_bv_base a( *this ); return a.b_not(); } + + + // bitwise left shift + + sc_bv_base& operator <<= ( int n ); + + const sc_bv_base operator << ( int n ) const + { sc_bv_base a( *this ); return ( a <<= n ); } + + + // bitwise right shift + + sc_bv_base& operator >>= ( int n ); + + const sc_bv_base operator >> ( int n ) const + { sc_bv_base a( *this ); return ( a >>= n ); } + + + // bitwise left rotate + + sc_bv_base& lrotate( int n ); + + + // bitwise right rotate + + sc_bv_base& rrotate( int n ); + +#endif + + + // common methods + + int length() const + { return m_len; } + + int size() const + { return m_size; } + + sc_logic_value_t get_bit( int i ) const; + void set_bit( int i, sc_logic_value_t value ); + + sc_digit get_word( int i ) const + { return m_data[i]; } + + void set_word( int i, sc_digit w ) + { m_data[i] = w; } + + sc_digit get_cword( int /*i*/ ) const + { return SC_DIGIT_ZERO; } + + void set_cword( int i, sc_digit w ); + + void clean_tail(); + + + // other methods + + bool is_01() const + { return true; } + +protected: + + int m_len; // length in bits + int m_size; // size of data array + sc_digit* m_data; // data array +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +#if 0 + +// bitwise left rotate + +inline +const sc_bv_base +lrotate( const sc_bv_base& x, int n ) +{ + sc_bv_base a( x ); + return a.lrotate( n ); +} + + +// bitwise right rotate + +inline +const sc_bv_base +rrotate( const sc_bv_base& x, int n ) +{ + sc_bv_base a( x ); + return a.rrotate( n ); +} + +#endif + + +// common methods + +inline +sc_logic_value_t +sc_bv_base::get_bit( int i ) const +{ + int wi = i / SC_DIGIT_SIZE; + int bi = i % SC_DIGIT_SIZE; + return sc_logic_value_t( (m_data[wi] >> bi) & SC_DIGIT_ONE ); +} + +inline +void +sc_bv_base::set_bit( int i, sc_logic_value_t value ) +{ + int wi = i / SC_DIGIT_SIZE; + int bi = i % SC_DIGIT_SIZE; + sc_digit mask = SC_DIGIT_ONE << bi; + m_data[wi] |= mask; // set bit to 1 + m_data[wi] &= value << bi | ~mask; +} + + +inline +void +sc_bv_base::set_cword( int /*i*/, sc_digit w ) +{ + if( w ) { + SC_REPORT_WARNING( sc_core::SC_ID_SC_BV_CANNOT_CONTAIN_X_AND_Z_, 0 ); + } +} + + +inline +void +sc_bv_base::clean_tail() +{ + int wi = m_size - 1; + int bi = m_len % SC_DIGIT_SIZE; + if ( bi != 0 ) m_data[wi] &= ~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - bi); +} + +} // namespace sc_dt + + +#endif diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_logic.cpp b/ext/systemc/src/sysc/datatypes/bit/sc_logic.cpp new file mode 100644 index 000000000..15525f5c5 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/bit/sc_logic.cpp @@ -0,0 +1,175 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_logic.cpp -- C++ implementation of logic type. Behaves + pretty much the same way as HDLs logic type. + + Original Author: Stan Y. Liao, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_logic.cpp,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:53 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#include "sysc/datatypes/bit/sc_bit_ids.h" +#include "sysc/datatypes/bit/sc_logic.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// CLASS : sc_logic +// +// Four-valued logic type. +// ---------------------------------------------------------------------------- + +// support methods + +void +sc_logic::invalid_value( sc_logic_value_t v ) +{ + char msg[BUFSIZ]; + std::sprintf( msg, "sc_logic( %d )", v ); + SC_REPORT_ERROR( sc_core::SC_ID_VALUE_NOT_VALID_, msg ); +} + +void +sc_logic::invalid_value( char c ) +{ + char msg[BUFSIZ]; + std::sprintf( msg, "sc_logic( '%c' )", c ); + SC_REPORT_ERROR( sc_core::SC_ID_VALUE_NOT_VALID_, msg ); +} + +void +sc_logic::invalid_value( int i ) +{ + char msg[BUFSIZ]; + std::sprintf( msg, "sc_logic( %d )", i ); + SC_REPORT_ERROR( sc_core::SC_ID_VALUE_NOT_VALID_, msg ); +} + + +void +sc_logic::invalid_01() const +{ + if( (int) m_val == Log_Z ) { + SC_REPORT_WARNING( sc_core::SC_ID_LOGIC_Z_TO_BOOL_, 0 ); + } else { + SC_REPORT_WARNING( sc_core::SC_ID_LOGIC_X_TO_BOOL_, 0 ); + } +} + + +// conversion tables + +const sc_logic_value_t sc_logic::char_to_logic[128] = +{ + Log_0, Log_1, Log_Z, Log_X, Log_X, Log_X, Log_X, Log_X, + Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, + Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, + Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, + Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, + Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, + Log_0, Log_1, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, + Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, + Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, + Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, + Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, + Log_X, Log_X, Log_Z, Log_X, Log_X, Log_X, Log_X, Log_X, + Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, + Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, + Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, + Log_X, Log_X, Log_Z, Log_X, Log_X, Log_X, Log_X, Log_X +}; + +const char sc_logic::logic_to_char[4] = { '0', '1', 'Z', 'X' }; + +const sc_logic_value_t sc_logic::and_table[4][4] = +{ + { Log_0, Log_0, Log_0, Log_0 }, + { Log_0, Log_1, Log_X, Log_X }, + { Log_0, Log_X, Log_X, Log_X }, + { Log_0, Log_X, Log_X, Log_X } +}; + +const sc_logic_value_t sc_logic::or_table[4][4] = +{ + { Log_0, Log_1, Log_X, Log_X }, + { Log_1, Log_1, Log_1, Log_1 }, + { Log_X, Log_1, Log_X, Log_X }, + { Log_X, Log_1, Log_X, Log_X } +}; + +const sc_logic_value_t sc_logic::xor_table[4][4] = +{ + { Log_0, Log_1, Log_X, Log_X }, + { Log_1, Log_0, Log_X, Log_X }, + { Log_X, Log_X, Log_X, Log_X }, + { Log_X, Log_X, Log_X, Log_X } +}; + +const sc_logic_value_t sc_logic::not_table[4] = + { Log_1, Log_0, Log_X, Log_X }; + + +// other methods + +void +sc_logic::scan( ::std::istream& is ) +{ + char c; + is >> c; + *this = c; +} + + +// #ifdef SC_DT_DEPRECATED +const sc_logic sc_logic_0( Log_0 ); +const sc_logic sc_logic_1( Log_1 ); +const sc_logic sc_logic_Z( Log_Z ); +const sc_logic sc_logic_X( Log_X ); +// #endif + +const sc_logic SC_LOGIC_0( Log_0 ); +const sc_logic SC_LOGIC_1( Log_1 ); +const sc_logic SC_LOGIC_Z( Log_Z ); +const sc_logic SC_LOGIC_X( Log_X ); + +} // namespace sc_dt diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_logic.h b/ext/systemc/src/sysc/datatypes/bit/sc_logic.h new file mode 100644 index 000000000..6008e3e2e --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/bit/sc_logic.h @@ -0,0 +1,384 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_logic.h -- C++ implementation of logic type. Behaves + pretty much the same way as HDLs except with 4 values. + + Original Author: Stan Y. Liao, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_logic.h,v $ +// Revision 1.3 2011/08/07 18:54:19 acg +// Philipp A. Hartmann: remove friend function declarations that implement +// code, and clean up how bit and logic operators are defined in general. +// +// Revision 1.2 2011/01/25 20:50:37 acg +// Andy Goodrich: changes for IEEE 1666 2011. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.5 2006/12/02 21:00:57 acg +// Andy Goodrich: fixes for concatenation support. +// +// Revision 1.4 2006/05/08 17:49:59 acg +// Andy Goodrich: Added David Long's declarations for friend operators, +// functions, and methods, to keep the Microsoft compiler happy. +// +// Revision 1.3 2006/01/13 18:53:53 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_LOGIC_H +#define SC_LOGIC_H + + +#include <cstdio> + +#include "sysc/utils/sc_iostream.h" +#include "sysc/kernel/sc_macros.h" +#include "sysc/utils/sc_mempool.h" +#include "sysc/datatypes/bit/sc_bit.h" + + +namespace sc_dt +{ + +// classes defined in this module +class sc_logic; + + +// ---------------------------------------------------------------------------- +// ENUM : sc_logic_value_t +// +// Enumeration of values for sc_logic. +// ---------------------------------------------------------------------------- + +enum sc_logic_value_t +{ + Log_0 = 0, + Log_1, + Log_Z, + Log_X +}; + +// ---------------------------------------------------------------------------- +// CLASS : sc_logic +// +// Four-valued logic type. +// ---------------------------------------------------------------------------- + +class sc_logic +{ +private: + + // support methods + + static void invalid_value( sc_logic_value_t ); + static void invalid_value( char ); + static void invalid_value( int ); + + static sc_logic_value_t to_value( sc_logic_value_t v ) + { + if( v < Log_0 || v > Log_X ) { + invalid_value( v ); + } + return v; + } + + static sc_logic_value_t to_value( bool b ) + { return ( b ? Log_1 : Log_0 ); } + + static sc_logic_value_t to_value( char c ) + { + sc_logic_value_t v; + unsigned int index = (int)c; + if ( index > 127 ) + { + invalid_value(c); + v = Log_X; + } + else + { + v = char_to_logic[index]; + if( v < Log_0 || v > Log_X ) { + invalid_value( c ); + } + } + return v; + } + + static sc_logic_value_t to_value( int i ) + { + if( i < 0 || i > 3 ) { + invalid_value( i ); + } + return sc_logic_value_t( i ); + } + + + void invalid_01() const; + +public: + + // conversion tables + + static const sc_logic_value_t char_to_logic[128]; + static const char logic_to_char[4]; + static const sc_logic_value_t and_table[4][4]; + static const sc_logic_value_t or_table[4][4]; + static const sc_logic_value_t xor_table[4][4]; + static const sc_logic_value_t not_table[4]; + + + // constructors + + sc_logic() + : m_val( Log_X ) + {} + + sc_logic( const sc_logic& a ) + : m_val( a.m_val ) + {} + + sc_logic( sc_logic_value_t v ) + : m_val( to_value( v ) ) + {} + + explicit sc_logic( bool a ) + : m_val( to_value( a ) ) + {} + + explicit sc_logic( char a ) + : m_val( to_value( a ) ) + {} + + explicit sc_logic( int a ) + : m_val( to_value( a ) ) + {} + + explicit sc_logic( const sc_bit& a ) + : m_val( to_value( a.to_bool() ) ) + {} + + + // destructor + + ~sc_logic() + {} + + + // (bitwise) assignment operators + +#define DEFN_ASN_OP_T(op,tp) \ + sc_logic& operator op ( tp v ) \ + { *this op sc_logic( v ); return *this; } + +#define DEFN_ASN_OP(op) \ + DEFN_ASN_OP_T(op, sc_logic_value_t) \ + DEFN_ASN_OP_T(op, bool) \ + DEFN_ASN_OP_T(op, char) \ + DEFN_ASN_OP_T(op, int ) \ + DEFN_ASN_OP_T(op, const sc_bit& ) + + sc_logic& operator = ( const sc_logic& a ) + { m_val = a.m_val; return *this; } + + sc_logic& operator &= ( const sc_logic& b ) + { m_val = and_table[m_val][b.m_val]; return *this; } + + sc_logic& operator |= ( const sc_logic& b ) + { m_val = or_table[m_val][b.m_val]; return *this; } + + sc_logic& operator ^= ( const sc_logic& b ) + { m_val = xor_table[m_val][b.m_val]; return *this; } + + DEFN_ASN_OP(=) + DEFN_ASN_OP(&=) + DEFN_ASN_OP(|=) + DEFN_ASN_OP(^=) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP + + + // bitwise operators and functions + + + friend const sc_logic operator & ( const sc_logic&, const sc_logic& ); + friend const sc_logic operator | ( const sc_logic&, const sc_logic& ); + friend const sc_logic operator ^ ( const sc_logic&, const sc_logic& ); + + // relational operators + + friend bool operator == ( const sc_logic&, const sc_logic& ); + friend bool operator != ( const sc_logic&, const sc_logic& ); + + // bitwise complement + + const sc_logic operator ~ () const + { return sc_logic( not_table[m_val] ); } + + sc_logic& b_not() + { m_val = not_table[m_val]; return *this; } + + + // explicit conversions + + sc_logic_value_t value() const + { return m_val; } + + + bool is_01() const + { return ( (int) m_val == Log_0 || (int) m_val == Log_1 ); } + + bool to_bool() const + { if( ! is_01() ) { invalid_01(); } return ( (int) m_val != Log_0 ); } + + char to_char() const + { return logic_to_char[m_val]; } + + + // other methods + + void print( ::std::ostream& os = ::std::cout ) const + { os << to_char(); } + + void scan( ::std::istream& is = ::std::cin ); + + + // memory (de)allocation + + static void* operator new( std::size_t, void* p ) // placement new + { return p; } + + static void* operator new( std::size_t sz ) + { return sc_core::sc_mempool::allocate( sz ); } + + static void operator delete( void* p, std::size_t sz ) + { sc_core::sc_mempool::release( p, sz ); } + + static void* operator new [] ( std::size_t sz ) + { return sc_core::sc_mempool::allocate( sz ); } + + static void operator delete [] ( void* p, std::size_t sz ) + { sc_core::sc_mempool::release( p, sz ); } + +private: + + sc_logic_value_t m_val; + +private: + + // disabled + explicit sc_logic( const char* ); + sc_logic& operator = ( const char* ); +}; + +// ---------------------------------------------------------------------------- + +// bitwise operators + +inline const sc_logic operator & ( const sc_logic& a, const sc_logic& b ) + { return sc_logic( sc_logic::and_table[a.m_val][b.m_val] ); } + +inline const sc_logic operator | ( const sc_logic& a, const sc_logic& b ) + { return sc_logic( sc_logic::or_table[a.m_val][b.m_val] ); } + +inline const sc_logic operator ^ ( const sc_logic& a, const sc_logic& b ) + { return sc_logic( sc_logic::xor_table[a.m_val][b.m_val] ); } + +#define DEFN_BIN_OP_T(ret,op,tp) \ + inline ret operator op ( const sc_logic& a, tp b ) \ + { return ( a op sc_logic( b ) ); } \ + inline ret operator op ( tp a, const sc_logic& b ) \ + { return ( sc_logic( a ) op b ); } + +#define DEFN_BIN_OP(ret,op) \ + DEFN_BIN_OP_T(ret,op,sc_logic_value_t) \ + DEFN_BIN_OP_T(ret,op,bool) \ + DEFN_BIN_OP_T(ret,op,char) \ + DEFN_BIN_OP_T(ret,op,int) + +DEFN_BIN_OP(const sc_logic,&) +DEFN_BIN_OP(const sc_logic,|) +DEFN_BIN_OP(const sc_logic,^) + +// relational operators and functions + +inline bool operator == ( const sc_logic& a, const sc_logic& b ) + { return ( (int) a.m_val == b.m_val ); } + +inline bool operator != ( const sc_logic& a, const sc_logic& b ) + { return ( (int) a.m_val != b.m_val ); } + +DEFN_BIN_OP(bool,==) +DEFN_BIN_OP(bool,!=) + +#undef DEFN_BIN_OP_T +#undef DEFN_BIN_OP + +// ---------------------------------------------------------------------------- + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_logic& a ) +{ + a.print( os ); + return os; +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_logic& a ) +{ + a.scan( is ); + return is; +} + + +extern const sc_logic SC_LOGIC_0; +extern const sc_logic SC_LOGIC_1; +extern const sc_logic SC_LOGIC_Z; +extern const sc_logic SC_LOGIC_X; + +// #ifdef SC_DT_DEPRECATED +extern const sc_logic sc_logic_0; +extern const sc_logic sc_logic_1; +extern const sc_logic sc_logic_Z; +extern const sc_logic sc_logic_X; +// #endif + +} // namespace sc_dt + +#endif diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_lv.h b/ext/systemc/src/sysc/datatypes/bit/sc_lv.h new file mode 100644 index 000000000..8eae23b73 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/bit/sc_lv.h @@ -0,0 +1,205 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_lv.h -- Arbitrary size logic vector class. + + Original Author: Gene Bushuyev, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_lv.h,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:53 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_LV_H +#define SC_LV_H + + +#include "sysc/datatypes/bit/sc_lv_base.h" + + +namespace sc_dt +{ + +// classes defined in this module +template <int W> class sc_lv; + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_lv<W> +// +// Arbitrary size logic vector class. +// ---------------------------------------------------------------------------- + +template <int W> +class sc_lv + : public sc_lv_base +{ +public: + + // constructors + + sc_lv() + : sc_lv_base( W ) + {} + + explicit sc_lv( const sc_logic& init_value ) + : sc_lv_base( init_value, W ) + {} + + explicit sc_lv( bool init_value ) + : sc_lv_base( sc_logic( init_value ), W ) + {} + + explicit sc_lv( char init_value ) + : sc_lv_base( sc_logic( init_value ), W ) + {} + + sc_lv( const char* a ) + : sc_lv_base( W ) + { sc_lv_base::operator = ( a ); } + + sc_lv( const bool* a ) + : sc_lv_base( W ) + { sc_lv_base::operator = ( a ); } + + sc_lv( const sc_logic* a ) + : sc_lv_base( W ) + { sc_lv_base::operator = ( a ); } + + sc_lv( const sc_unsigned& a ) + : sc_lv_base( W ) + { sc_lv_base::operator = ( a ); } + + sc_lv( const sc_signed& a ) + : sc_lv_base( W ) + { sc_lv_base::operator = ( a ); } + + sc_lv( const sc_uint_base& a ) + : sc_lv_base( W ) + { sc_lv_base::operator = ( a ); } + + sc_lv( const sc_int_base& a ) + : sc_lv_base( W ) + { sc_lv_base::operator = ( a ); } + + sc_lv( unsigned long a ) + : sc_lv_base( W ) + { sc_lv_base::operator = ( a ); } + + sc_lv( long a ) + : sc_lv_base( W ) + { sc_lv_base::operator = ( a ); } + + sc_lv( unsigned int a ) + : sc_lv_base( W ) + { sc_lv_base::operator = ( a ); } + + sc_lv( int a ) + : sc_lv_base( W ) + { sc_lv_base::operator = ( a ); } + + sc_lv( uint64 a ) + : sc_lv_base( W ) + { sc_lv_base::operator = ( a ); } + + sc_lv( int64 a ) + : sc_lv_base( W ) + { sc_lv_base::operator = ( a ); } + + template <class X> + sc_lv( const sc_proxy<X>& a ) + : sc_lv_base( W ) + { sc_lv_base::operator = ( a ); } + + sc_lv( const sc_lv<W>& a ) + : sc_lv_base( a ) + {} + + + // assignment operators + + template <class X> + sc_lv<W>& operator = ( const sc_proxy<X>& a ) + { sc_lv_base::operator = ( a ); return *this; } + + sc_lv<W>& operator = ( const sc_lv<W>& a ) + { sc_lv_base::operator = ( a ); return *this; } + + sc_lv<W>& operator = ( const char* a ) + { sc_lv_base::operator = ( a ); return *this; } + + sc_lv<W>& operator = ( const bool* a ) + { sc_lv_base::operator = ( a ); return *this; } + + sc_lv<W>& operator = ( const sc_logic* a ) + { sc_lv_base::operator = ( a ); return *this; } + + sc_lv<W>& operator = ( const sc_unsigned& a ) + { sc_lv_base::operator = ( a ); return *this; } + + sc_lv<W>& operator = ( const sc_signed& a ) + { sc_lv_base::operator = ( a ); return *this; } + + sc_lv<W>& operator = ( const sc_uint_base& a ) + { sc_lv_base::operator = ( a ); return *this; } + + sc_lv<W>& operator = ( const sc_int_base& a ) + { sc_lv_base::operator = ( a ); return *this; } + + sc_lv<W>& operator = ( unsigned long a ) + { sc_lv_base::operator = ( a ); return *this; } + + sc_lv<W>& operator = ( long a ) + { sc_lv_base::operator = ( a ); return *this; } + + sc_lv<W>& operator = ( unsigned int a ) + { sc_lv_base::operator = ( a ); return *this; } + + sc_lv<W>& operator = ( int a ) + { sc_lv_base::operator = ( a ); return *this; } + + sc_lv<W>& operator = ( uint64 a ) + { sc_lv_base::operator = ( a ); return *this; } + + sc_lv<W>& operator = ( int64 a ) + { sc_lv_base::operator = ( a ); return *this; } +}; + +} // namespace sc_dt + + +#endif diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_lv_base.cpp b/ext/systemc/src/sysc/datatypes/bit/sc_lv_base.cpp new file mode 100644 index 000000000..617d74d03 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/bit/sc_lv_base.cpp @@ -0,0 +1,173 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_lv_base.cpp -- Arbitrary size logic vector class. + + Original Author: Gene Bushuyev, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_lv_base.cpp,v $ +// Revision 1.2 2011/08/24 22:05:40 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:53 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#include "sysc/datatypes/bit/sc_bit_ids.h" +#include "sysc/datatypes/bit/sc_lv_base.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// CLASS : sc_lv_base +// +// Arbitrary size logic vector base class. +// ---------------------------------------------------------------------------- + +static const sc_digit data_array[] = + { SC_DIGIT_ZERO, ~SC_DIGIT_ZERO, SC_DIGIT_ZERO, ~SC_DIGIT_ZERO }; + +static const sc_digit ctrl_array[] = + { SC_DIGIT_ZERO, SC_DIGIT_ZERO, ~SC_DIGIT_ZERO, ~SC_DIGIT_ZERO }; + + +void +sc_lv_base::init( int length_, const sc_logic& init_value ) +{ + // check the length + if( length_ <= 0 ) { + SC_REPORT_ERROR( sc_core::SC_ID_ZERO_LENGTH_, 0 ); + } + // allocate memory for the data and control words + m_len = length_; + m_size = (m_len - 1) / SC_DIGIT_SIZE + 1; + m_data = new sc_digit[m_size * 2]; + m_ctrl = m_data + m_size; + // initialize the bits to 'init_value' + sc_digit dw = data_array[init_value.value()]; + sc_digit cw = ctrl_array[init_value.value()]; + int sz = m_size; + for( int i = 0; i < sz; ++ i ) { + m_data[i] = dw; + m_ctrl[i] = cw; + } + clean_tail(); +} + + +void +sc_lv_base::assign_from_string( const std::string& s ) +{ + // s must have been converted to bin + int len = m_len; + int s_len = s.length() - 1; + int min_len = sc_min( len, s_len ); + int i = 0; + for( ; i < min_len; ++ i ) { + char c = s[s_len - i - 1]; + set_bit( i, sc_logic::char_to_logic[(int)c] ); + } + // if formatted, fill the rest with sign(s), otherwise fill with zeros + sc_logic_value_t fill = (s[s_len] == 'F' ? sc_logic_value_t( s[0] - '0' ) + : sc_logic_value_t( 0 )); + for( ; i < len; ++ i ) { + set_bit( i, fill ); + } +} + + +// constructors + +sc_lv_base::sc_lv_base( const char* a ) + : m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 ) +{ + std::string s = convert_to_bin( a ); + init( s.length() - 1 ); + assign_from_string( s ); +} + +sc_lv_base::sc_lv_base( const char* a, int length_ ) + : m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 ) +{ + init( length_ ); + assign_from_string( convert_to_bin( a ) ); +} + +sc_lv_base::sc_lv_base( const sc_lv_base& a ) + : sc_proxy<sc_lv_base>(), + m_len( a.m_len ), + m_size( a.m_size ), + m_data( new sc_digit[m_size * 2] ), + m_ctrl( m_data + m_size ) +{ + // copy the bits + int sz = m_size; + for( int i = 0; i < sz; ++ i ) { + m_data[i] = a.m_data[i]; + m_ctrl[i] = a.m_ctrl[i]; + } +} + + +// assignment operators + +sc_lv_base& +sc_lv_base::operator = ( const char* a ) +{ + assign_from_string( convert_to_bin( a ) ); + return *this; +} + + +// returns true if logic vector contains only 0's and 1's + +bool +sc_lv_base::is_01() const +{ + int sz = m_size; + for( int i = 0; i < sz; ++ i ) { + if( m_ctrl[i] != 0 ) { + return false; + } + } + return true; +} + +} // namespace sc_dt diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_lv_base.h b/ext/systemc/src/sysc/datatypes/bit/sc_lv_base.h new file mode 100644 index 000000000..313afa56e --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/bit/sc_lv_base.h @@ -0,0 +1,1827 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_lv_base.h -- Arbitrary size logic vector class. + + Original Author: Gene Bushuyev, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + Andy Goodrich, Forte Design Systems + Fixed bug in clean_tail for sizes that are modulo 32, which caused + zeroing of values. + + *****************************************************************************/ + +// $Log: sc_lv_base.h,v $ +// Revision 1.4 2011/08/26 22:32:00 acg +// Torsten Maehne: added parentheses to make opearator ordering more obvious. +// +// Revision 1.3 2010/01/27 19:41:29 acg +// Andy Goodrich: fix 8 instances of sc_concref constructor invocations +// that failed to indicate that their arguments should be freed when the +// object was freed. +// +// Revision 1.2 2009/02/28 00:26:14 acg +// Andy Goodrich: bug fixes. +// +// Revision 1.2 2007/03/14 17:47:49 acg +// Andy Goodrich: Formatting. +// +// Revision 1.1.1.1 2006/12/15 20:31:36 acg +// SystemC 2.2 +// +// Revision 1.3 2006/01/13 18:53:53 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_LV_BASE_H +#define SC_LV_BASE_H + + +#include "sysc/datatypes/bit/sc_bit_ids.h" +#include "sysc/datatypes/bit/sc_bv_base.h" +#include "sysc/datatypes/bit/sc_logic.h" +#include "sysc/datatypes/int/sc_length_param.h" + + +namespace sc_dt +{ + +// classes defined in this module +class sc_lv_base; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_lv_base +// +// Arbitrary size logic vector base class. +// ---------------------------------------------------------------------------- + +class sc_lv_base + : public sc_proxy<sc_lv_base> +{ + friend class sc_bv_base; + + + void init( int length_, const sc_logic& init_value = SC_LOGIC_X ); + + void assign_from_string( const std::string& ); + +public: + + // typedefs + + typedef sc_proxy<sc_lv_base> base_type; + + + // constructors + + explicit sc_lv_base( int length_ = sc_length_param().len() ) + : m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 ) + { init( length_ ); } + + explicit sc_lv_base( const sc_logic& a, + int length_ = sc_length_param().len() ) + : m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 ) + { init( length_, a ); } + + sc_lv_base( const char* a ); + + sc_lv_base( const char* a, int length_ ); + + template <class X> + sc_lv_base( const sc_proxy<X>& a ) + : m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 ) + { init( a.back_cast().length() ); base_type::assign_( a ); } + + sc_lv_base( const sc_lv_base& a ); + +#ifdef SC_DT_DEPRECATED + + explicit sc_lv_base( const sc_unsigned& a ) + : m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 ) + { init( a.length() ); base_type::assign_( a ); } + + explicit sc_lv_base( const sc_signed& a ) + : m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 ) + { init( a.length() ); base_type::assign_( a ); } + + explicit sc_lv_base( const sc_uint_base& a ) + : m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 ) + { init( a.length() ); base_type::assign_( a ); } + + explicit sc_lv_base( const sc_int_base& a ) + : m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 ) + { init( a.length() ); base_type::assign_( a ); } + +#endif + + + // destructor + + virtual ~sc_lv_base() + { delete [] m_data; } + + + // assignment operators + + template <class X> + sc_lv_base& operator = ( const sc_proxy<X>& a ) + { assign_p_( *this, a ); return *this; } + + sc_lv_base& operator = ( const sc_lv_base& a ) + { assign_p_( *this, a ); return *this; } + + sc_lv_base& operator = ( const char* a ); + + sc_lv_base& operator = ( const bool* a ) + { base_type::assign_( a ); return *this; } + + sc_lv_base& operator = ( const sc_logic* a ) + { base_type::assign_( a ); return *this; } + + sc_lv_base& operator = ( const sc_unsigned& a ) + { base_type::assign_( a ); return *this; } + + sc_lv_base& operator = ( const sc_signed& a ) + { base_type::assign_( a ); return *this; } + + sc_lv_base& operator = ( const sc_uint_base& a ) + { base_type::assign_( a ); return *this; } + + sc_lv_base& operator = ( const sc_int_base& a ) + { base_type::assign_( a ); return *this; } + + sc_lv_base& operator = ( unsigned long a ) + { base_type::assign_( a ); return *this; } + + sc_lv_base& operator = ( long a ) + { base_type::assign_( a ); return *this; } + + sc_lv_base& operator = ( unsigned int a ) + { base_type::assign_( a ); return *this; } + + sc_lv_base& operator = ( int a ) + { base_type::assign_( a ); return *this; } + + sc_lv_base& operator = ( uint64 a ) + { base_type::assign_( a ); return *this; } + + sc_lv_base& operator = ( int64 a ) + { base_type::assign_( a ); return *this; } + + +#if 0 + + // bitwise complement + + sc_lv_base& b_not() + { return sc_proxy<sc_lv_base>::b_not(); } + + const sc_lv_base operator ~ () const + { sc_lv_base a( *this ); return a.b_not(); } + + + // bitwise left shift + + sc_lv_base& operator <<= ( int n ) + { return sc_proxy<sc_lv_base>::operator <<= ( n ); } + + const sc_lv_base operator << ( int n ) const + { sc_lv_base a( *this ); return ( a <<= n ); } + + + // bitwise right shift + + sc_lv_base& operator >>= ( int n ) + { return sc_proxy<sc_lv_base>::operator >>= ( n ); } + + const sc_lv_base operator >> ( int n ) const + { sc_lv_base a( *this ); return ( a >>= n ); } + + + // bitwise left rotate + + sc_lv_base& lrotate( int n ) + { return sc_proxy<sc_lv_base>::lrotate( n ); } + + + // bitwise right rotate + + sc_lv_base& rrotate( int n ) + { return sc_proxy<sc_lv_base>::rrotate( n ); } + +#endif + + + // common methods + + int length() const + { return m_len; } + + int size() const + { return m_size; } + + sc_logic_value_t get_bit( int i ) const; + void set_bit( int i, sc_logic_value_t value ); + + sc_digit get_word( int wi ) const + { return m_data[wi]; } + + // note the test for out of range access here. this is necessary + // because of the hair-brained way concatenations are set up. + // an extend_sign on a concatenation uses the whole length of + // the concatenation to determine how many words to set. + void set_word( int wi, sc_digit w ) + { assert ( wi < m_size ); m_data[wi] = w; } + + + sc_digit get_cword( int wi ) const + { return m_ctrl[wi]; } + + void set_cword( int wi, sc_digit w ) + { assert ( wi < m_size ); m_ctrl[wi] = w; } + + void clean_tail(); + + + // other methods + + bool is_01() const; + +protected: + + int m_len; // length in bits + int m_size; // size of the data array + sc_digit* m_data; // data array + sc_digit* m_ctrl; // dito (control part) +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +#if 0 + +// bitwise left rotate + +inline +const sc_lv_base +lrotate( const sc_lv_base& x, int n ) +{ + sc_lv_base a( x ); + return a.lrotate( n ); +} + + +// bitwise right rotate + +inline +const sc_lv_base +rrotate( const sc_lv_base& x, int n ) +{ + sc_lv_base a( x ); + return a.rrotate( n ); +} + +#endif + + +inline +sc_logic_value_t +sc_lv_base::get_bit( int i ) const +{ + int wi = i / SC_DIGIT_SIZE; + int bi = i % SC_DIGIT_SIZE; + return sc_logic_value_t( ((m_data[wi] >> bi) & SC_DIGIT_ONE) | + (((m_ctrl[wi] >> bi) << 1) & SC_DIGIT_TWO) ); +} + +inline +void +sc_lv_base::set_bit( int i, sc_logic_value_t value ) +{ + int wi = i / SC_DIGIT_SIZE; // word index + int bi = i % SC_DIGIT_SIZE; // bit index + sc_digit mask = SC_DIGIT_ONE << bi; + m_data[wi] |= mask; // set bit to 1 + m_ctrl[wi] |= mask; // set bit to 1 + m_data[wi] &= value << bi | ~mask; + m_ctrl[wi] &= value >> 1 << bi | ~mask; +} + + +inline +void +sc_lv_base::clean_tail() +{ + int wi = m_size - 1; + int bi = m_len % SC_DIGIT_SIZE; + sc_digit mask = ~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - bi); + if ( mask ) + { + m_data[wi] &= mask; + m_ctrl[wi] &= mask; + } +} + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_proxy +// +// Base class template for bit/logic vector classes. +// (Barton/Nackmann implementation) +// ---------------------------------------------------------------------------- + +// bitwise operators and functions + +// bitwise complement + +template <class X> +inline +const sc_lv_base +sc_proxy<X>::operator ~ () const +{ + sc_lv_base a( back_cast() ); + return a.b_not(); +} + + +// bitwise and + +template <class X, class Y> +inline +X& +operator &= ( sc_proxy<X>& px, const sc_proxy<Y>& py ) +{ + X& x = px.back_cast(); + sc_lv_base a( x.length() ); + a = py.back_cast(); + return b_and_assign_( x, a ); +} + + +#define DEFN_BITWISE_AND_ASN_OP_T(tp) \ +template <class X> \ +inline \ +X& \ +sc_proxy<X>::operator &= ( tp b ) \ +{ \ + X& x = back_cast(); \ + sc_lv_base a( x.length() ); \ + a = b; \ + return b_and_assign_( x, a ); \ +} + +DEFN_BITWISE_AND_ASN_OP_T(const char*) +DEFN_BITWISE_AND_ASN_OP_T(const bool*) +DEFN_BITWISE_AND_ASN_OP_T(const sc_logic*) +DEFN_BITWISE_AND_ASN_OP_T(const sc_unsigned&) +DEFN_BITWISE_AND_ASN_OP_T(const sc_signed&) +DEFN_BITWISE_AND_ASN_OP_T(unsigned long) +DEFN_BITWISE_AND_ASN_OP_T(long) +DEFN_BITWISE_AND_ASN_OP_T(uint64) +DEFN_BITWISE_AND_ASN_OP_T(int64) + +#undef DEFN_BITWISE_AND_ASN_OP_T + + +template <class X, class Y> +inline +const sc_lv_base +operator & ( const sc_proxy<X>& px, const sc_proxy<Y>& py ) +{ + sc_lv_base a( px.back_cast() ); + return ( a &= py.back_cast() ); +} + + +#define DEFN_BITWISE_AND_OP_T_A(tp) \ +template <class X> \ +inline \ +const sc_lv_base \ +sc_proxy<X>::operator & ( tp b ) const \ +{ \ + sc_lv_base a( back_cast() ); \ + return ( a &= b ); \ +} + +DEFN_BITWISE_AND_OP_T_A(const char*) +DEFN_BITWISE_AND_OP_T_A(const bool*) +DEFN_BITWISE_AND_OP_T_A(const sc_logic*) +DEFN_BITWISE_AND_OP_T_A(const sc_unsigned&) +DEFN_BITWISE_AND_OP_T_A(const sc_signed&) +DEFN_BITWISE_AND_OP_T_A(const sc_uint_base&) +DEFN_BITWISE_AND_OP_T_A(const sc_int_base&) +DEFN_BITWISE_AND_OP_T_A(unsigned long) +DEFN_BITWISE_AND_OP_T_A(long) +DEFN_BITWISE_AND_OP_T_A(unsigned int) +DEFN_BITWISE_AND_OP_T_A(int) +DEFN_BITWISE_AND_OP_T_A(uint64) +DEFN_BITWISE_AND_OP_T_A(int64) + +#undef DEFN_BITWISE_AND_OP_T_A + + +#define DEFN_BITWISE_AND_OP_T_B(tp) \ +template <class X> \ +inline \ +const sc_lv_base \ +operator & ( tp b, const sc_proxy<X>& px ) \ +{ \ + return ( px & b ); \ +} + +DEFN_BITWISE_AND_OP_T_B(const char*) +DEFN_BITWISE_AND_OP_T_B(const bool*) +DEFN_BITWISE_AND_OP_T_B(const sc_logic*) +DEFN_BITWISE_AND_OP_T_B(const sc_unsigned&) +DEFN_BITWISE_AND_OP_T_B(const sc_signed&) +DEFN_BITWISE_AND_OP_T_B(const sc_uint_base&) +DEFN_BITWISE_AND_OP_T_B(const sc_int_base&) +DEFN_BITWISE_AND_OP_T_B(unsigned long) +DEFN_BITWISE_AND_OP_T_B(long) +DEFN_BITWISE_AND_OP_T_B(unsigned int) +DEFN_BITWISE_AND_OP_T_B(int) +DEFN_BITWISE_AND_OP_T_B(uint64) +DEFN_BITWISE_AND_OP_T_B(int64) + +#undef DEFN_BITWISE_AND_OP_T_B + + +// bitwise or + +template <class X, class Y> +inline +X& +operator |= ( sc_proxy<X>& px, const sc_proxy<Y>& py ) +{ + X& x = px.back_cast(); + sc_lv_base a( x.length() ); + a = py.back_cast(); + return b_or_assign_( x, a ); +} + + +#define DEFN_BITWISE_OR_ASN_OP_T(tp) \ +template <class X> \ +inline \ +X& \ +sc_proxy<X>::operator |= ( tp b ) \ +{ \ + X& x = back_cast(); \ + sc_lv_base a( x.length() ); \ + a = b; \ + return b_or_assign_( x, a ); \ +} + +DEFN_BITWISE_OR_ASN_OP_T(const char*) +DEFN_BITWISE_OR_ASN_OP_T(const bool*) +DEFN_BITWISE_OR_ASN_OP_T(const sc_logic*) +DEFN_BITWISE_OR_ASN_OP_T(const sc_unsigned&) +DEFN_BITWISE_OR_ASN_OP_T(const sc_signed&) +DEFN_BITWISE_OR_ASN_OP_T(unsigned long) +DEFN_BITWISE_OR_ASN_OP_T(long) +DEFN_BITWISE_OR_ASN_OP_T(uint64) +DEFN_BITWISE_OR_ASN_OP_T(int64) + +#undef DEFN_BITWISE_OR_ASN_OP_T + + +template <class X, class Y> +inline +const sc_lv_base +operator | ( const sc_proxy<X>& px, const sc_proxy<Y>& py ) +{ + sc_lv_base a( px.back_cast() ); + return ( a |= py.back_cast() ); +} + + +#define DEFN_BITWISE_OR_OP_T_A(tp) \ +template <class X> \ +inline \ +const sc_lv_base \ +sc_proxy<X>::operator | ( tp b ) const \ +{ \ + sc_lv_base a( back_cast() ); \ + return ( a |= b ); \ +} + +DEFN_BITWISE_OR_OP_T_A(const char*) +DEFN_BITWISE_OR_OP_T_A(const bool*) +DEFN_BITWISE_OR_OP_T_A(const sc_logic*) +DEFN_BITWISE_OR_OP_T_A(const sc_unsigned&) +DEFN_BITWISE_OR_OP_T_A(const sc_signed&) +DEFN_BITWISE_OR_OP_T_A(const sc_uint_base&) +DEFN_BITWISE_OR_OP_T_A(const sc_int_base&) +DEFN_BITWISE_OR_OP_T_A(unsigned long) +DEFN_BITWISE_OR_OP_T_A(long) +DEFN_BITWISE_OR_OP_T_A(unsigned int) +DEFN_BITWISE_OR_OP_T_A(int) +DEFN_BITWISE_OR_OP_T_A(uint64) +DEFN_BITWISE_OR_OP_T_A(int64) + +#undef DEFN_BITWISE_OR_OP_T_A + + +#define DEFN_BITWISE_OR_OP_T_B(tp) \ +template <class X> \ +inline \ +const sc_lv_base \ +operator | ( tp b, const sc_proxy<X>& px ) \ +{ \ + return ( px | b ); \ +} + +DEFN_BITWISE_OR_OP_T_B(const char*) +DEFN_BITWISE_OR_OP_T_B(const bool*) +DEFN_BITWISE_OR_OP_T_B(const sc_logic*) +DEFN_BITWISE_OR_OP_T_B(const sc_unsigned&) +DEFN_BITWISE_OR_OP_T_B(const sc_signed&) +DEFN_BITWISE_OR_OP_T_B(const sc_uint_base&) +DEFN_BITWISE_OR_OP_T_B(const sc_int_base&) +DEFN_BITWISE_OR_OP_T_B(unsigned long) +DEFN_BITWISE_OR_OP_T_B(long) +DEFN_BITWISE_OR_OP_T_B(unsigned int) +DEFN_BITWISE_OR_OP_T_B(int) +DEFN_BITWISE_OR_OP_T_B(uint64) +DEFN_BITWISE_OR_OP_T_B(int64) + +#undef DEFN_BITWISE_OR_OP_T_B + + +// bitwise xor + +template <class X, class Y> +inline +X& +operator ^= ( sc_proxy<X>& px, const sc_proxy<Y>& py ) +{ + X& x = px.back_cast(); + sc_lv_base a( x.length() ); + a = py.back_cast(); + return b_xor_assign_( x, a ); +} + + +#define DEFN_BITWISE_XOR_ASN_OP_T(tp) \ +template <class X> \ +inline \ +X& \ +sc_proxy<X>::operator ^= ( tp b ) \ +{ \ + X& x = back_cast(); \ + sc_lv_base a( x.length() ); \ + a = b; \ + return b_xor_assign_( x, a ); \ +} + +DEFN_BITWISE_XOR_ASN_OP_T(const char*) +DEFN_BITWISE_XOR_ASN_OP_T(const bool*) +DEFN_BITWISE_XOR_ASN_OP_T(const sc_logic*) +DEFN_BITWISE_XOR_ASN_OP_T(const sc_unsigned&) +DEFN_BITWISE_XOR_ASN_OP_T(const sc_signed&) +DEFN_BITWISE_XOR_ASN_OP_T(unsigned long) +DEFN_BITWISE_XOR_ASN_OP_T(long) +DEFN_BITWISE_XOR_ASN_OP_T(uint64) +DEFN_BITWISE_XOR_ASN_OP_T(int64) + +#undef DEFN_BITWISE_XOR_ASN_OP_T + + +template <class X, class Y> +inline +const sc_lv_base +operator ^ ( const sc_proxy<X>& px, const sc_proxy<Y>& py ) +{ + sc_lv_base a( px.back_cast() ); + return ( a ^= py.back_cast() ); +} + + +#define DEFN_BITWISE_XOR_OP_T_A(tp) \ +template <class X> \ +inline \ +const sc_lv_base \ +sc_proxy<X>::operator ^ ( tp b ) const \ +{ \ + sc_lv_base a( back_cast() ); \ + return ( a ^= b ); \ +} + +DEFN_BITWISE_XOR_OP_T_A(const char*) +DEFN_BITWISE_XOR_OP_T_A(const bool*) +DEFN_BITWISE_XOR_OP_T_A(const sc_logic*) +DEFN_BITWISE_XOR_OP_T_A(const sc_unsigned&) +DEFN_BITWISE_XOR_OP_T_A(const sc_signed&) +DEFN_BITWISE_XOR_OP_T_A(const sc_uint_base&) +DEFN_BITWISE_XOR_OP_T_A(const sc_int_base&) +DEFN_BITWISE_XOR_OP_T_A(unsigned long) +DEFN_BITWISE_XOR_OP_T_A(long) +DEFN_BITWISE_XOR_OP_T_A(unsigned int) +DEFN_BITWISE_XOR_OP_T_A(int) +DEFN_BITWISE_XOR_OP_T_A(uint64) +DEFN_BITWISE_XOR_OP_T_A(int64) + +#undef DEFN_BITWISE_XOR_OP_T_A + + +#define DEFN_BITWISE_XOR_OP_T_B(tp) \ +template <class X> \ +inline \ +const sc_lv_base \ +operator ^ ( tp b, const sc_proxy<X>& px ) \ +{ \ + return ( px ^ b ); \ +} + +DEFN_BITWISE_XOR_OP_T_B(const char*) +DEFN_BITWISE_XOR_OP_T_B(const bool*) +DEFN_BITWISE_XOR_OP_T_B(const sc_logic*) +DEFN_BITWISE_XOR_OP_T_B(const sc_unsigned&) +DEFN_BITWISE_XOR_OP_T_B(const sc_signed&) +DEFN_BITWISE_XOR_OP_T_B(const sc_uint_base&) +DEFN_BITWISE_XOR_OP_T_B(const sc_int_base&) +DEFN_BITWISE_XOR_OP_T_B(unsigned long) +DEFN_BITWISE_XOR_OP_T_B(long) +DEFN_BITWISE_XOR_OP_T_B(unsigned int) +DEFN_BITWISE_XOR_OP_T_B(int) +DEFN_BITWISE_XOR_OP_T_B(uint64) +DEFN_BITWISE_XOR_OP_T_B(int64) + +#undef DEFN_BITWISE_XOR_OP_T_B + + +// bitwise left shift + +template <class X> +inline +const sc_lv_base +sc_proxy<X>::operator << ( int n ) const +{ + sc_lv_base a( back_cast().length()+n ); + a = back_cast(); + return ( a <<= n ); +} + + +// bitwise right shift + +template <class X> +inline +const sc_lv_base +sc_proxy<X>::operator >> ( int n ) const +{ + sc_lv_base a( back_cast() ); + return ( a >>= n ); +} + + +// bitwise left rotate + +template <class X> +inline +X& +sc_proxy<X>::lrotate( int n ) +{ + X& x = back_cast(); + if( n < 0 ) { + char msg[BUFSIZ]; + std::sprintf( msg, + "left rotate operation is only allowed with positive " + "rotate values, rotate value = %d", n ); + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); + } + int len = x.length(); + n %= len; + // x = (x << n) | (x >> (len - n)); + sc_lv_base a( x << n ); + sc_lv_base b( x >> (len - n) ); + int sz = x.size(); + for( int i = 0; i < sz; ++ i ) { + x.set_word( i, a.get_word( i ) | b.get_word( i ) ); + x.set_cword( i, a.get_cword( i ) | b.get_cword( i ) ); + } + x.clean_tail(); + return x; +} + +template <class X> +inline +const sc_lv_base +lrotate( const sc_proxy<X>& x, int n ) +{ + sc_lv_base a( x.back_cast() ); + return a.lrotate( n ); +} + + +// bitwise right rotate + +template <class X> +inline +X& +sc_proxy<X>::rrotate( int n ) +{ + X& x = back_cast(); + if( n < 0 ) { + char msg[BUFSIZ]; + std::sprintf( msg, + "right rotate operation is only allowed with positive " + "rotate values, rotate value = %d", n ); + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); + } + int len = x.length(); + n %= len; + // x = (x >> n) | (x << (len - n)); + sc_lv_base a( x >> n ); + sc_lv_base b( x << (len - n) ); + int sz = x.size(); + for( int i = 0; i < sz; ++ i ) { + x.set_word( i, a.get_word( i ) | b.get_word( i ) ); + x.set_cword( i, a.get_cword( i ) | b.get_cword( i ) ); + } + x.clean_tail(); + return x; +} + +template <class X> +inline +const sc_lv_base +rrotate( const sc_proxy<X>& x, int n ) +{ + sc_lv_base a( x.back_cast() ); + return a.rrotate( n ); +} + + +// bitwise reverse + +template <class X> +inline +const sc_lv_base +reverse( const sc_proxy<X>& x ) +{ + sc_lv_base a( x.back_cast() ); + return a.reverse(); +} + + +// relational operators + +template <class X, class Y> +inline +bool +operator == ( const sc_proxy<X>& px, const sc_proxy<Y>& py ) +{ + const X& x = px.back_cast(); + const Y& y = py.back_cast(); + int x_len = x.length(); + int y_len = y.length(); + if( x_len != y_len ) { + return false; + } + int sz = x.size(); + for( int i = 0; i < sz; ++ i ) { + if( x.get_word( i ) != y.get_word( i ) || + x.get_cword( i ) != y.get_cword( i ) ) { + return false; + } + } + return true; +} + + +#define DEFN_REL_OP_T(tp) \ +template <class X> \ +inline \ +bool \ +sc_proxy<X>::operator == ( tp b ) const \ +{ \ + const X& x = back_cast(); \ + sc_lv_base y( x.length() ); \ + y = b; \ + return ( x == y ); \ +} + +DEFN_REL_OP_T(const char*) +DEFN_REL_OP_T(const bool*) +DEFN_REL_OP_T(const sc_logic*) +DEFN_REL_OP_T(const sc_unsigned&) +DEFN_REL_OP_T(const sc_signed&) +DEFN_REL_OP_T(const sc_uint_base&) +DEFN_REL_OP_T(const sc_int_base&) +DEFN_REL_OP_T(unsigned long) +DEFN_REL_OP_T(long) +DEFN_REL_OP_T(unsigned int) +DEFN_REL_OP_T(int) +DEFN_REL_OP_T(uint64) +DEFN_REL_OP_T(int64) + +#undef DEFN_REL_OP_T + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_bitref_r<X> +// +// Proxy class for sc_proxy bit selection (r-value only). +// ---------------------------------------------------------------------------- + +// r-value concatenation operators and functions + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_lv_base> +operator , ( sc_bitref_r<T> a, const char* b ) +{ + return sc_concref_r<sc_bitref_r<T>,sc_lv_base>( + *a.clone(), *new sc_lv_base( b ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_bitref_r<T> > +operator , ( const char* a, sc_bitref_r<T> b ) +{ + return sc_concref_r<sc_lv_base,sc_bitref_r<T> >( + *new sc_lv_base( a ), *b.clone(), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_lv_base> +operator , ( sc_bitref_r<T> a, const sc_logic& b ) +{ + return sc_concref_r<sc_bitref_r<T>,sc_lv_base>( + *a.clone(), *new sc_lv_base( b, 1 ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_bitref_r<T> > +operator , ( const sc_logic& a, sc_bitref_r<T> b ) +{ + return sc_concref_r<sc_lv_base,sc_bitref_r<T> >( + *new sc_lv_base( a, 1 ), *b.clone(), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_bv_base> +operator , ( sc_bitref_r<T> a, bool b ) +{ + return sc_concref_r<sc_bitref_r<T>,sc_bv_base> + ( *a.clone(), *new sc_bv_base( b, 1 ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_bv_base,sc_bitref_r<T> > +operator , ( bool a, sc_bitref_r<T> b ) +{ + return sc_concref_r<sc_bv_base,sc_bitref_r<T> > + ( *new sc_bv_base( a, 1 ), *b.clone(), 3 ); +} + + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_lv_base> +concat( sc_bitref_r<T> a, const char* b ) +{ + return sc_concref_r<sc_bitref_r<T>,sc_lv_base>( + *a.clone(), *new sc_lv_base( b ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_bitref_r<T> > +concat( const char* a, sc_bitref_r<T> b ) +{ + return sc_concref_r<sc_lv_base,sc_bitref_r<T> >( + *new sc_lv_base( a ), *b.clone(), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_lv_base> +concat( sc_bitref_r<T> a, const sc_logic& b ) +{ + return sc_concref_r<sc_bitref_r<T>,sc_lv_base>( + *a.clone(), *new sc_lv_base( b, 1 ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_bitref_r<T> > +concat( const sc_logic& a, sc_bitref_r<T> b ) +{ + return sc_concref_r<sc_lv_base,sc_bitref_r<T> >( + *new sc_lv_base( a, 1 ), *b.clone(), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_bv_base> +concat( sc_bitref_r<T> a, bool b ) +{ + return sc_concref_r<sc_bitref_r<T>,sc_bv_base> + ( *a.clone(), *new sc_bv_base( b, 1 ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_bv_base,sc_bitref_r<T> > +concat( bool a, sc_bitref_r<T> b ) +{ + return sc_concref_r<sc_bv_base,sc_bitref_r<T> > + ( *new sc_bv_base( a, 1 ), *b.clone(), 3 ); +} + + +#ifdef SC_DT_MIXED_COMMA_OPERATORS + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_lv_base> +operator , ( sc_bitref<T> a, const char* b ) +{ + return sc_concref_r<sc_bitref_r<T>,sc_lv_base>( + *a.clone(), *new sc_lv_base( b ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_bitref_r<T> > +operator , ( const char* a, sc_bitref<T> b ) +{ + return sc_concref_r<sc_lv_base,sc_bitref_r<T> >( + *new sc_lv_base( a ), *b.clone(), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_lv_base> +operator , ( sc_bitref<T> a, const sc_logic& b ) +{ + return sc_concref_r<sc_bitref_r<T>,sc_lv_base>( + *a.clone(), *new sc_lv_base( b, 1 ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_bitref_r<T> > +operator , ( const sc_logic& a, sc_bitref<T> b ) +{ + return sc_concref_r<sc_lv_base,sc_bitref_r<T> >( + *new sc_lv_base( a, 1 ), *b.clone(), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_bv_base> +operator , ( sc_bitref<T> a, bool b ) +{ + return sc_concref_r<sc_bitref_r<T>,sc_bv_base> + ( *a.clone(), *new sc_bv_base( b, 1 ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_bv_base,sc_bitref_r<T> > +operator , ( bool a, sc_bitref<T> b ) +{ + return sc_concref_r<sc_bv_base,sc_bitref_r<T> > + ( *new sc_bv_base( a, 1 ), *b.clone(), 3 ); +} + + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_lv_base> +concat( sc_bitref<T> a, const char* b ) +{ + return sc_concref_r<sc_bitref_r<T>,sc_lv_base>( + *a.clone(), *new sc_lv_base( b ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_bitref_r<T> > +concat( const char* a, sc_bitref<T> b ) +{ + return sc_concref_r<sc_lv_base,sc_bitref_r<T> >( + *new sc_lv_base( a ), *b.clone(), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_lv_base> +concat( sc_bitref<T> a, const sc_logic& b ) +{ + return sc_concref_r<sc_bitref_r<T>,sc_lv_base>( + *a.clone(), *new sc_lv_base( b, 1 ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_bitref_r<T> > +concat( const sc_logic& a, sc_bitref<T> b ) +{ + return sc_concref_r<sc_lv_base,sc_bitref_r<T> >( + *new sc_lv_base( a, 1 ), *b.clone(), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_bitref_r<T>,sc_bv_base> +concat( sc_bitref<T> a, bool b ) +{ + return sc_concref_r<sc_bitref_r<T>,sc_bv_base> + ( *a.clone(), *new sc_bv_base( b, 1 ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_bv_base,sc_bitref_r<T> > +concat( bool a, sc_bitref<T> b ) +{ + return sc_concref_r<sc_bv_base,sc_bitref_r<T> > + ( *new sc_bv_base( a, 1 ), *b.clone(), 3 ); +} + +#endif + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_subref_r<X> +// +// Proxy class for sc_proxy part selection (r-value only). +// ---------------------------------------------------------------------------- + +// r-value concatenation operators and functions + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_lv_base> +operator , ( sc_subref_r<T> a, const char* b ) +{ + return sc_concref_r<sc_subref_r<T>,sc_lv_base>( + *a.clone(), *new sc_lv_base( b ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_subref_r<T> > +operator , ( const char* a, sc_subref_r<T> b ) +{ + return sc_concref_r<sc_lv_base,sc_subref_r<T> >( + *new sc_lv_base( a ), *b.clone(), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_lv_base> +operator , ( sc_subref_r<T> a, const sc_logic& b ) +{ + return sc_concref_r<sc_subref_r<T>,sc_lv_base>( + *a.clone(), *new sc_lv_base( b, 1 ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_subref_r<T> > +operator , ( const sc_logic& a, sc_subref_r<T> b ) +{ + return sc_concref_r<sc_lv_base,sc_subref_r<T> >( + *new sc_lv_base( a, 1 ), *b.clone(), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_bv_base> +operator , ( sc_subref_r<T> a, bool b ) +{ + return sc_concref_r<sc_subref_r<T>,sc_bv_base> + ( *a.clone(), *new sc_bv_base( b, 1 ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_bv_base,sc_subref_r<T> > +operator , ( bool a, sc_subref_r<T> b ) +{ + return sc_concref_r<sc_bv_base,sc_subref_r<T> > + ( *new sc_bv_base( a, 1 ), *b.clone(), 3 ); +} + + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_lv_base> +concat( sc_subref_r<T> a, const char* b ) +{ + return sc_concref_r<sc_subref_r<T>,sc_lv_base>( + *a.clone(), *new sc_lv_base( b ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_subref_r<T> > +concat( const char* a, sc_subref_r<T> b ) +{ + return sc_concref_r<sc_lv_base,sc_subref_r<T> >( + *new sc_lv_base( a ), *b.clone(), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_lv_base> +concat( sc_subref_r<T> a, const sc_logic& b ) +{ + return sc_concref_r<sc_subref_r<T>,sc_lv_base>( + *a.clone(), *new sc_lv_base( b, 1 ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_subref_r<T> > +concat( const sc_logic& a, sc_subref_r<T> b ) +{ + return sc_concref_r<sc_lv_base,sc_subref_r<T> >( + *new sc_lv_base( a, 1 ), *b.clone(), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_bv_base> +concat( sc_subref_r<T> a, bool b ) +{ + return sc_concref_r<sc_subref_r<T>,sc_bv_base> + ( *a.clone(), *new sc_bv_base( b, 1 ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_bv_base,sc_subref_r<T> > +concat( bool a, sc_subref_r<T> b ) +{ + return sc_concref_r<sc_bv_base,sc_subref_r<T> > + ( *new sc_bv_base( a, 1 ), *b.clone(), 3 ); +} + + +#ifdef SC_DT_MIXED_COMMA_OPERATORS + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_lv_base> +operator , ( sc_subref<T> a, const char* b ) +{ + return sc_concref_r<sc_subref_r<T>,sc_lv_base>( + *a.clone(), *new sc_lv_base( b ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_subref_r<T> > +operator , ( const char* a, sc_subref<T> b ) +{ + return sc_concref_r<sc_lv_base,sc_subref_r<T> >( + *new sc_lv_base( a ), *b.clone(), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_lv_base> +operator , ( sc_subref<T> a, const sc_logic& b ) +{ + return sc_concref_r<sc_subref_r<T>,sc_lv_base>( + *a.clone(), *new sc_lv_base( b, 1 ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_subref_r<T> > +operator , ( const sc_logic& a, sc_subref<T> b ) +{ + return sc_concref_r<sc_lv_base,sc_subref_r<T> >( + *new sc_lv_base( a, 1 ), *b.clone(), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_bv_base> +operator , ( sc_subref<T> a, bool b ) +{ + return sc_concref_r<sc_subref_r<T>,sc_bv_base> + ( *a.clone(), *new sc_bv_base( b, 1 ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_bv_base,sc_subref_r<T> > +operator , ( bool a, sc_subref<T> b ) +{ + return sc_concref_r<sc_bv_base,sc_subref_r<T> > + ( *new sc_bv_base( a, 1 ), *b.clone(), 3 ); +} + + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_lv_base> +concat( sc_subref<T> a, const char* b ) +{ + return sc_concref_r<sc_subref_r<T>,sc_lv_base>( + *a.clone(), *new sc_lv_base( b ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_subref_r<T> > +concat( const char* a, sc_subref<T> b ) +{ + return sc_concref_r<sc_lv_base,sc_subref_r<T> >( + *new sc_lv_base( a ), *b.clone(), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_lv_base> +concat( sc_subref<T> a, const sc_logic& b ) +{ + return sc_concref_r<sc_subref_r<T>,sc_lv_base>( + *a.clone(), *new sc_lv_base( b, 1 ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,sc_subref_r<T> > +concat( const sc_logic& a, sc_subref<T> b ) +{ + return sc_concref_r<sc_lv_base,sc_subref_r<T> >( + *new sc_lv_base( a, 1 ), *b.clone(), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_subref_r<T>,sc_bv_base> +concat( sc_subref<T> a, bool b ) +{ + return sc_concref_r<sc_subref_r<T>,sc_bv_base> + ( *a.clone(), *new sc_bv_base( b, 1 ), 3 ); +} + +template <class T> +inline +sc_concref_r<sc_bv_base,sc_subref_r<T> > +concat( bool a, sc_subref<T> b ) +{ + return sc_concref_r<sc_bv_base,sc_subref_r<T> > + ( *new sc_bv_base( a, 1 ), *b.clone(), 3 ); +} + +#endif + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_subref<X> +// +// Proxy class for sc_proxy part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +template <class X> +inline +sc_subref<X>& +sc_subref<X>::operator = ( const sc_subref_r<X>& b ) +{ + sc_lv_base t( b ); // (partial) self assignment protection + int len = sc_min( this->length(), t.length() ); + if( ! this->reversed() ) { + for( int i = len - 1; i >= 0; -- i ) { + this->m_obj.set_bit( this->m_lo + i, t[i].value() ); + } + } else { + for( int i = len - 1; i >= 0; -- i ) { + this->m_obj.set_bit( this->m_lo - i, t[i].value() ); + } + } + return *this; +} + +template <class X> +inline +sc_subref<X>& +sc_subref<X>::operator = ( const sc_subref<X>& b ) +{ + sc_lv_base t( b ); // (partial) self assignment protection + int len = sc_min( this->length(), t.length() ); + if( ! this->reversed() ) { + for( int i = len - 1; i >= 0; -- i ) { + this->m_obj.set_bit( this->m_lo + i, t[i].value() ); + } + } else { + for( int i = len - 1; i >= 0; -- i ) { + this->m_obj.set_bit( this->m_lo - i, t[i].value() ); + } + } + return *this; +} + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_concref_r<X,Y> +// +// Proxy class for sc_proxy concatenation (r-value only). +// ---------------------------------------------------------------------------- + +// r-value concatenation operators and functions + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base> +operator , ( sc_concref_r<T1,T2> a, const char* b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>( + *a.clone(), *new sc_lv_base( b ), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> > +operator , ( const char* a, sc_concref_r<T1,T2> b ) +{ + return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >( + *new sc_lv_base( a ), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base> +operator , ( sc_concref_r<T1,T2> a, const sc_logic& b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>( + *a.clone(), *new sc_lv_base( b, 1 ), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> > +operator , ( const sc_logic& a, sc_concref_r<T1,T2> b ) +{ + return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >( + *new sc_lv_base( a, 1 ), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base> +operator , ( sc_concref_r<T1,T2> a, bool b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base> + ( *a.clone(), *new sc_bv_base( b, 1 ), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> > +operator , ( bool a, sc_concref_r<T1,T2> b ) +{ + return sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> > + ( *new sc_bv_base( a, 1 ), *b.clone(), 3 ); +} + + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base> +concat( sc_concref_r<T1,T2> a, const char* b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base> + ( *a.clone(), *new sc_lv_base( b ), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> > +concat( const char* a, sc_concref_r<T1,T2> b ) +{ + return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> > + ( *new sc_lv_base( a ), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base> +concat( sc_concref_r<T1,T2> a, const sc_logic& b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base> + ( *a.clone(), *new sc_lv_base( b, 1 ), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> > +concat( const sc_logic& a, sc_concref_r<T1,T2> b ) +{ + return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> > + ( *new sc_lv_base( a, 1 ), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base> +concat( sc_concref_r<T1,T2> a, bool b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base> + ( *a.clone(), *new sc_bv_base( b, 1 ), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> > +concat( bool a, sc_concref_r<T1,T2> b ) +{ + return sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> > + ( *new sc_bv_base( a, 1 ), *b.clone(), 3 ); +} + + +#ifdef SC_DT_MIXED_COMMA_OPERATORS + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base> +operator , ( sc_concref<T1,T2> a, const char* b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base> + ( *a.clone(), *new sc_lv_base( b ), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> > +operator , ( const char* a, sc_concref<T1,T2> b ) +{ + return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> > + ( *new sc_lv_base( a ), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base> +operator , ( sc_concref<T1,T2> a, const sc_logic& b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base> + ( *a.clone(), *new sc_lv_base( b, 1 ), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> > +operator , ( const sc_logic& a, sc_concref<T1,T2> b ) +{ + return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> > + ( *new sc_lv_base( a, 1 ), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base> +operator , ( sc_concref<T1,T2> a, bool b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base> + ( *a.clone(), *new sc_bv_base( b, 1 ), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> > +operator , ( bool a, sc_concref<T1,T2> b ) +{ + return sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> > + ( *new sc_bv_base( a, 1 ), *b.clone(), 3 ); +} + + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base> +concat( sc_concref<T1,T2> a, const char* b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base> + ( *a.clone(), *new sc_lv_base( b ), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> > +concat( const char* a, sc_concref<T1,T2> b ) +{ + return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> > + ( *new sc_lv_base( a ), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base> +concat( sc_concref<T1,T2> a, const sc_logic& b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base> + ( *a.clone(), *new sc_lv_base( b, 1 ), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> > +concat( const sc_logic& a, sc_concref<T1,T2> b ) +{ + return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> > + ( *new sc_lv_base( a, 1 ), *b.clone(), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base> +concat( sc_concref<T1,T2> a, bool b ) +{ + return sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base> + ( *a.clone(), *new sc_bv_base( b, 1 ), 3 ); +} + +template <class T1, class T2> +inline +sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> > +concat( bool a, sc_concref<T1,T2> b ) +{ + return sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> > + ( *new sc_bv_base( a, 1 ), *b.clone(), 3 ); +} + +#endif + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_proxy<T> +// +// Base class template for bit/logic vector classes. +// (Barton/Nackmann implementation) +// ---------------------------------------------------------------------------- + +// r-value concatenation operators and functions + +template <class T> +inline +sc_concref_r<T,sc_lv_base> +operator , ( const sc_proxy<T>& a, const char* b ) +{ + return sc_concref_r<T,sc_lv_base> + ( a.back_cast(), *new sc_lv_base( b ), 2 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,T> +operator , ( const char* a, const sc_proxy<T>& b ) +{ + return sc_concref_r<sc_lv_base,T> + ( *new sc_lv_base( a ), b.back_cast(), 1 ); +} + +template <class T> +inline +sc_concref_r<T,sc_lv_base> +operator , ( const sc_proxy<T>& a, const sc_logic& b ) +{ + return sc_concref_r<T,sc_lv_base> + ( a.back_cast(), *new sc_lv_base( b, 1 ), 2 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,T> +operator , ( const sc_logic& a, const sc_proxy<T>& b ) +{ + return sc_concref_r<sc_lv_base,T> + ( *new sc_lv_base( a, 1 ), b.back_cast(), 1 ); +} + +template <class T> +inline +sc_concref_r<T,sc_bv_base> +operator , ( const sc_proxy<T>& a, bool b ) +{ + return sc_concref_r<T,sc_bv_base> + ( a.back_cast(), *new sc_bv_base( b, 1 ), 2 ); +} + +template <class T> +inline +sc_concref_r<sc_bv_base,T> +operator , ( bool a, const sc_proxy<T>& b ) +{ + return sc_concref_r<sc_bv_base,T> + ( *new sc_bv_base( a, 1 ), b.back_cast(), 1 ); +} + + +template <class T> +inline +sc_concref_r<T,sc_lv_base> +concat( const sc_proxy<T>& a, const char* b ) +{ + return sc_concref_r<T,sc_lv_base> + ( a.back_cast(), *new sc_lv_base( b ), 2 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,T> +concat( const char* a, const sc_proxy<T>& b ) +{ + return sc_concref_r<sc_lv_base,T> + ( *new sc_lv_base( a ), b.back_cast(), 1 ); +} + +template <class T> +inline +sc_concref_r<T,sc_lv_base> +concat( const sc_proxy<T>& a, const sc_logic& b ) +{ + return sc_concref_r<T,sc_lv_base> + ( a.back_cast(), *new sc_lv_base( b, 1 ), 2 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,T> +concat( const sc_logic& a, const sc_proxy<T>& b ) +{ + return sc_concref_r<sc_lv_base,T> + ( *new sc_lv_base( a, 1 ), b.back_cast(), 1 ); +} + +template <class T> +inline +sc_concref_r<T,sc_bv_base> +concat( const sc_proxy<T>& a, bool b ) +{ + return sc_concref_r<T,sc_bv_base> + ( a.back_cast(), *new sc_bv_base( b, 1 ), 2 ); +} + +template <class T> +inline +sc_concref_r<sc_bv_base,T> +concat( bool a, const sc_proxy<T>& b ) +{ + return sc_concref_r<sc_bv_base,T> + ( *new sc_bv_base( a, 1 ), b.back_cast(), 1 ); +} + + +#ifdef SC_DT_MIXED_COMMA_OPERATORS + +template <class T> +inline +sc_concref_r<T,sc_lv_base> +operator , ( sc_proxy<T>& a, const char* b ) +{ + return sc_concref_r<T,sc_lv_base> + ( a.back_cast(), *new sc_lv_base( b ), 2 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,T> +operator , ( const char* a, sc_proxy<T>& b ) +{ + return sc_concref_r<sc_lv_base,T> + ( *new sc_lv_base( a ), b.back_cast(), 1 ); +} + +template <class T> +inline +sc_concref_r<T,sc_lv_base> +operator , ( sc_proxy<T>& a, const sc_logic& b ) +{ + return sc_concref_r<T,sc_lv_base> + ( a.back_cast(), *new sc_lv_base( b, 1 ), 2 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,T> +operator , ( const sc_logic& a, sc_proxy<T>& b ) +{ + return sc_concref_r<sc_lv_base,T> + ( *new sc_lv_base( a, 1 ), b.back_cast(), 1 ); +} + +template <class T> +inline +sc_concref_r<T,sc_bv_base> +operator , ( sc_proxy<T>& a, bool b ) +{ + return sc_concref_r<T,sc_bv_base> + ( a.back_cast(), *new sc_bv_base( b, 1 ), 2 ); +} + +template <class T> +inline +sc_concref_r<sc_bv_base,T> +operator , ( bool a, sc_proxy<T>& b ) +{ + return sc_concref_r<sc_bv_base,T> + ( *new sc_bv_base( a, 1 ), b.back_cast(), 1 ); +} + + +template <class T> +inline +sc_concref_r<T,sc_lv_base> +concat( sc_proxy<T>& a, const char* b ) +{ + return sc_concref_r<T,sc_lv_base> + ( a.back_cast(), *new sc_lv_base( b ), 2 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,T> +concat( const char* a, sc_proxy<T>& b ) +{ + return sc_concref_r<sc_lv_base,T> + ( *new sc_lv_base( a ), b.back_cast(), 1 ); +} + +template <class T> +inline +sc_concref_r<T,sc_lv_base> +concat( sc_proxy<T>& a, const sc_logic& b ) +{ + return sc_concref_r<T,sc_lv_base> + ( a.back_cast(), *new sc_lv_base( b, 1 ), 2 ); +} + +template <class T> +inline +sc_concref_r<sc_lv_base,T> +concat( const sc_logic& a, sc_proxy<T>& b ) +{ + return sc_concref_r<sc_lv_base,T> + ( *new sc_lv_base( a, 1 ), b.back_cast(), 1 ); +} + +template <class T> +inline +sc_concref_r<T,sc_bv_base> +concat( sc_proxy<T>& a, bool b ) +{ + return sc_concref_r<T,sc_bv_base> + ( a.back_cast(), *new sc_bv_base( b, 1 ), 2 ); +} + +template <class T> +inline +sc_concref_r<sc_bv_base,T> +concat( bool a, sc_proxy<T>& b ) +{ + return sc_concref_r<sc_bv_base,T> + ( *new sc_bv_base( a, 1 ), b.back_cast(), 1 ); +} + +#endif + +} // namespace sc_dt + + +#endif diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_proxy.h b/ext/systemc/src/sysc/datatypes/bit/sc_proxy.h new file mode 100644 index 000000000..7c67b447d --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/bit/sc_proxy.h @@ -0,0 +1,1609 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_proxy.h -- Proxy base class for vector data types. + + This class is created for several purposes: + 1) hiding operators from the global namespace that would be + otherwise found by Koenig lookup + 2) avoiding repeating the same operations in every class + including proxies that could also be achieved by common + base class, but this method allows + 3) improve performance by using non-virtual functions + + Original Author: Gene Bushuyev, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_proxy.h,v $ +// Revision 1.3 2010/12/07 20:09:07 acg +// Andy Goodrich: Fix for returning enough data +// +// Revision 1.2 2009/02/28 00:26:14 acg +// Andy Goodrich: bug fixes. +// +// Revision 1.1.1.1 2006/12/15 20:31:36 acg +// SystemC 2.2 +// +// Revision 1.3 2006/01/13 18:53:53 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_PROXY_H +#define SC_PROXY_H + + +#include "sysc/kernel/sc_cmnhdr.h" +#include "sysc/utils/sc_iostream.h" +#include "sysc/datatypes/int/sc_signed.h" +#include "sysc/datatypes/int/sc_unsigned.h" +#include "sysc/datatypes/int/sc_int_base.h" +#include "sysc/datatypes/int/sc_uint_base.h" +#include "sysc/datatypes/bit/sc_bit.h" +#include "sysc/datatypes/bit/sc_bit_ids.h" +#include "sysc/datatypes/bit/sc_logic.h" +#include "sysc/kernel/sc_macros.h" + + +namespace sc_dt +{ + +// classes defined in this module +template <class X> class sc_proxy; + +// forward class declarations +class sc_bv_base; +class sc_lv_base; +template <class X> class sc_bitref_r; +template <class X> class sc_bitref; +template <class X> class sc_subref_r; +template <class X> class sc_subref; +template <class X, class Y> class sc_concref_r; +template <class X, class Y> class sc_concref; + + +const int SC_DIGIT_SIZE = BITS_PER_BYTE * sizeof( sc_digit ); + +const sc_digit SC_DIGIT_ZERO = (sc_digit)0; +const sc_digit SC_DIGIT_ONE = (sc_digit)1; +const sc_digit SC_DIGIT_TWO = (sc_digit)2; + + +// assignment functions; forward declarations + +template <class X, class Y> +inline +void +assign_p_( sc_proxy<X>& px, const sc_proxy<Y>& py ); + +// Vector types that are not derived from sc_proxy must have a length() +// function and an operator []. + +template <class X, class T> +inline +void +assign_v_( sc_proxy<X>& px, const T& a ); + + +// other functions; forward declarations + +const std::string convert_to_bin( const char* s ); +const std::string convert_to_fmt( const std::string& s, sc_numrep numrep, bool ); + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_proxy_traits +// +// Template traits helper to select the correct bit/value/vector_types for +// sc_proxy-based vector classes. +// +// All types derived from/based on a bit-vector contain typedef to a plain bool, +// all others point to the sc_logic_value_t/sc_logic/sc_lv_base types. +// ---------------------------------------------------------------------------- + +template<typename X> struct sc_proxy_traits; + +template<> struct sc_proxy_traits<sc_bv_base> +{ + typedef sc_proxy_traits<sc_bv_base> traits_type; + typedef bool value_type; + typedef bool bit_type; + typedef sc_bv_base vector_type; + typedef traits_type type; +}; + +template<> struct sc_proxy_traits<sc_lv_base> +{ + typedef sc_proxy_traits<sc_lv_base> traits_type; + typedef sc_logic_value_t value_type; + typedef sc_logic bit_type; + typedef sc_lv_base vector_type; + typedef traits_type type; +}; + + +template<typename X> struct sc_proxy_traits<sc_bitref_r<X> > + : sc_proxy_traits<X> {}; + +template<typename X> struct sc_proxy_traits<sc_bitref<X> > + : sc_proxy_traits<X> {}; + + +template<typename X> struct sc_proxy_traits<sc_subref_r<X> > + : sc_proxy_traits<X> {}; + +template<typename X> struct sc_proxy_traits<sc_subref<X> > + : sc_proxy_traits<X> {}; + + +template<typename X> struct sc_proxy_traits<sc_proxy<X> > + : sc_proxy_traits<X> {}; + + +template< typename X, typename Y > struct sc_mixed_proxy_traits_helper + : sc_proxy_traits<sc_lv_base> {}; // logic vector by default + +template<typename X> struct sc_mixed_proxy_traits_helper<X,X> + : X {}; + + +template<typename X, typename Y> struct sc_proxy_traits< sc_concref_r<X,Y> > + : sc_mixed_proxy_traits_helper< typename X::traits_type::type + , typename Y::traits_type::type > +{}; + +template<typename X, typename Y> struct sc_proxy_traits<sc_concref<X,Y> > + : sc_mixed_proxy_traits_helper< typename X::traits_type::type + , typename Y::traits_type::type > +{}; + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_proxy +// +// Base class template for bit/logic vector classes. +// (Barton/Nackmann implementation) +// ---------------------------------------------------------------------------- + +template <class X> +class sc_proxy // #### : public sc_value_base +{ +public: + typedef typename sc_proxy_traits<X>::type traits_type; + typedef typename traits_type::bit_type bit_type; + + // virtual destructor + + virtual ~sc_proxy() {} + + + // casts + + X& back_cast() + { return SCAST<X&>( *this ); } + + const X& back_cast() const + { return SCAST<const X&>( *this ); } + + + // assignment operators + + template <class Y> + X& assign_( const sc_proxy<Y>& a ) + { assign_p_( *this, a ); return back_cast(); } + + X& assign_( const char* a ); + X& assign_( const bool* a ); + X& assign_( const sc_logic* a ); + + X& assign_( const sc_unsigned& a ) + { assign_v_( *this, a ); return back_cast(); } + + X& assign_( const sc_signed& a ) + { assign_v_( *this, a ); return back_cast(); } + + X& assign_( const sc_uint_base& a ) + { return assign_( (uint64) a ); } + + X& assign_( const sc_int_base& a ) + { return assign_( (int64) a ); } + + X& assign_( unsigned int a ); + X& assign_( int a ); + + X& assign_( unsigned long a ); + + X& assign_( long a ); + + X& assign_( uint64 a ); + X& assign_( int64 a ); + + + // bitwise operators and functions + + // bitwise complement + + X& b_not(); + + const sc_lv_base operator ~ () const; + + + // bitwise and + + X& operator &= ( const char* b ); + X& operator &= ( const bool* b ); + X& operator &= ( const sc_logic* b ); + X& operator &= ( const sc_unsigned& b ); + X& operator &= ( const sc_signed& b ); + + X& operator &= ( const sc_uint_base& b ) + { return operator &= ( (uint64) b ); } + + X& operator &= ( const sc_int_base& b ) + { return operator &= ( (int64) b ); } + + X& operator &= ( unsigned long b ); + X& operator &= ( long b ); + + X& operator &= ( unsigned int b ) + { return operator &= ( (unsigned long) b ); } + + X& operator &= ( int b ) + { return operator &= ( (long) b ); } + + X& operator &= ( uint64 b ); + X& operator &= ( int64 b ); + + + const sc_lv_base operator & ( const char* b ) const; + const sc_lv_base operator & ( const bool* b ) const; + const sc_lv_base operator & ( const sc_logic* b ) const; + const sc_lv_base operator & ( const sc_unsigned& b ) const; + const sc_lv_base operator & ( const sc_signed& b ) const; + const sc_lv_base operator & ( const sc_uint_base& b ) const; + const sc_lv_base operator & ( const sc_int_base& b ) const; + const sc_lv_base operator & ( unsigned long b ) const; + const sc_lv_base operator & ( long b ) const; + const sc_lv_base operator & ( unsigned int b ) const; + const sc_lv_base operator & ( int b ) const; + const sc_lv_base operator & ( uint64 b ) const; + const sc_lv_base operator & ( int64 b ) const; + + + // bitwise or + + X& operator |= ( const char* b ); + X& operator |= ( const bool* b ); + X& operator |= ( const sc_logic* b ); + X& operator |= ( const sc_unsigned& b ); + X& operator |= ( const sc_signed& b ); + + X& operator |= ( const sc_uint_base& b ) + { return operator |= ( (uint64) b ); } + + X& operator |= ( const sc_int_base& b ) + { return operator |= ( (int64) b ); } + + X& operator |= ( unsigned long b ); + X& operator |= ( long b ); + + X& operator |= ( unsigned int b ) + { return operator |= ( (unsigned long) b ); } + + X& operator |= ( int b ) + { return operator |= ( (long) b ); } + + X& operator |= ( uint64 b ); + X& operator |= ( int64 b ); + + + const sc_lv_base operator | ( const char* b ) const; + const sc_lv_base operator | ( const bool* b ) const; + const sc_lv_base operator | ( const sc_logic* b ) const; + const sc_lv_base operator | ( const sc_unsigned& b ) const; + const sc_lv_base operator | ( const sc_signed& b ) const; + const sc_lv_base operator | ( const sc_uint_base& b ) const; + const sc_lv_base operator | ( const sc_int_base& b ) const; + const sc_lv_base operator | ( unsigned long b ) const; + const sc_lv_base operator | ( long b ) const; + const sc_lv_base operator | ( unsigned int b ) const; + const sc_lv_base operator | ( int b ) const; + const sc_lv_base operator | ( uint64 b ) const; + const sc_lv_base operator | ( int64 b ) const; + + + // bitwise xor + + X& operator ^= ( const char* b ); + X& operator ^= ( const bool* b ); + X& operator ^= ( const sc_logic* b ); + X& operator ^= ( const sc_unsigned& b ); + X& operator ^= ( const sc_signed& b ); + + X& operator ^= ( const sc_uint_base& b ) + { return operator ^= ( (uint64) b ); } + + X& operator ^= ( const sc_int_base& b ) + { return operator ^= ( (int64) b ); } + + X& operator ^= ( unsigned long b ); + X& operator ^= ( long b ); + + X& operator ^= ( unsigned int b ) + { return operator ^= ( (unsigned long) b ); } + + X& operator ^= ( int b ) + { return operator ^= ( (long) b ); } + + X& operator ^= ( uint64 b ); + X& operator ^= ( int64 b ); + + + const sc_lv_base operator ^ ( const char* b ) const; + const sc_lv_base operator ^ ( const bool* b ) const; + const sc_lv_base operator ^ ( const sc_logic* b ) const; + const sc_lv_base operator ^ ( const sc_unsigned& b ) const; + const sc_lv_base operator ^ ( const sc_signed& b ) const; + const sc_lv_base operator ^ ( const sc_uint_base& b ) const; + const sc_lv_base operator ^ ( const sc_int_base& b ) const; + const sc_lv_base operator ^ ( unsigned long b ) const; + const sc_lv_base operator ^ ( long b ) const; + const sc_lv_base operator ^ ( unsigned int b ) const; + const sc_lv_base operator ^ ( int b ) const; + const sc_lv_base operator ^ ( uint64 b ) const; + const sc_lv_base operator ^ ( int64 b ) const; + + + // bitwise left shift + + X& operator <<= ( int n ); + + const sc_lv_base operator << ( int n ) const; + + + // bitwise right shift + + X& operator >>= ( int n ); + + const sc_lv_base operator >> ( int n ) const; + + + // bitwise left rotate + + X& lrotate( int n ); + + + // bitwise right rotate + + X& rrotate( int n ); + + + // bitwise reverse + + X& reverse(); + + + // bit selection + + sc_bitref<X> operator [] ( int i ) + { return sc_bitref<X>( back_cast(), i ); } + + sc_bitref_r<X> operator [] ( int i ) const + { return sc_bitref_r<X>( back_cast(), i ); } + + sc_bitref<X> bit( int i ) + { return sc_bitref<X>( back_cast(), i ); } + + sc_bitref_r<X> bit( int i ) const + { return sc_bitref_r<X>( back_cast(), i ); } + + + // part selection + + sc_subref<X> operator () ( int hi, int lo ) + { return sc_subref<X>( back_cast(), hi, lo ); } + + sc_subref_r<X> operator () ( int hi, int lo ) const + { return sc_subref_r<X>( back_cast(), hi, lo ); } + + sc_subref<X> range( int hi, int lo ) + { return sc_subref<X>( back_cast(), hi, lo ); } + + sc_subref_r<X> range( int hi, int lo ) const + { return sc_subref_r<X>( back_cast(), hi, lo ); } + + + // reduce functions + + sc_logic_value_t and_reduce() const; + + sc_logic_value_t nand_reduce() const + { return sc_logic::not_table[and_reduce()]; } + + sc_logic_value_t or_reduce() const; + + sc_logic_value_t nor_reduce() const + { return sc_logic::not_table[or_reduce()]; } + + sc_logic_value_t xor_reduce() const; + + sc_logic_value_t xnor_reduce() const + { return sc_logic::not_table[xor_reduce()]; } + + + // relational operators + + bool operator == ( const char* b ) const; + bool operator == ( const bool* b ) const; + bool operator == ( const sc_logic* b ) const; + bool operator == ( const sc_unsigned& b ) const; + bool operator == ( const sc_signed& b ) const; + bool operator == ( const sc_uint_base& b ) const; + bool operator == ( const sc_int_base& b ) const; + bool operator == ( unsigned long b ) const; + bool operator == ( long b ) const; + bool operator == ( unsigned int b ) const; + bool operator == ( int b ) const; + bool operator == ( uint64 b ) const; + bool operator == ( int64 b ) const; + + + // explicit conversions to character string + + const std::string to_string() const; + const std::string to_string( sc_numrep ) const; + const std::string to_string( sc_numrep, bool ) const; + + + // explicit conversions + + inline int64 to_int64() const + { return to_anything_signed(); } + inline uint64 to_uint64() const; + int to_int() const + { return (int)to_anything_signed(); } + + unsigned int to_uint() const + { return (unsigned int)to_anything_unsigned(); } + + long to_long() const + { return (long)to_anything_signed(); } + + unsigned long to_ulong() const + { return (unsigned long)to_anything_unsigned(); } + +#ifdef SC_DT_DEPRECATED + + int to_signed() const + { return to_int(); } + + sc_digit to_unsigned() const + { return to_uint(); } + +#endif + + + // other methods + + void print( ::std::ostream& os = ::std::cout ) const + { + // the test below will force printing in binary if decimal is + // specified. + if ( sc_io_base(os, SC_DEC) == SC_DEC ) + os << to_string(); + else + os << to_string(sc_io_base(os,SC_BIN),sc_io_show_base(os)); + } + + void scan( ::std::istream& is = ::std::cin ); + +protected: + + void check_bounds( int n ) const; // check if bit n accessible + void check_wbounds( int n ) const; // check if word n accessible + + sc_digit to_anything_unsigned() const; + int64 to_anything_signed() const; +}; + + +// ---------------------------------------------------------------------------- + +// bitwise operators and functions + +// bitwise and + +template <class X, class Y> +inline +X& +operator &= ( sc_proxy<X>& px, const sc_proxy<Y>& py ); + + +template <class X, class Y> +inline +const sc_lv_base +operator & ( const sc_proxy<X>& px, const sc_proxy<Y>& py ); + + +#define DECL_BITWISE_AND_OP_T(tp) \ +template <class X> \ +inline \ +const sc_lv_base \ +operator & ( tp b, const sc_proxy<X>& px ); + +DECL_BITWISE_AND_OP_T(const char*) +DECL_BITWISE_AND_OP_T(const bool*) +DECL_BITWISE_AND_OP_T(const sc_logic*) +DECL_BITWISE_AND_OP_T(const sc_unsigned&) +DECL_BITWISE_AND_OP_T(const sc_signed&) +DECL_BITWISE_AND_OP_T(const sc_uint_base&) +DECL_BITWISE_AND_OP_T(const sc_int_base&) +DECL_BITWISE_AND_OP_T(unsigned long) +DECL_BITWISE_AND_OP_T(long) +DECL_BITWISE_AND_OP_T(unsigned int) +DECL_BITWISE_AND_OP_T(int) +DECL_BITWISE_AND_OP_T(uint64) +DECL_BITWISE_AND_OP_T(int64) + +#undef DECL_BITWISE_AND_OP_T + + +// bitwise or + +template <class X, class Y> +inline +X& +operator |= ( sc_proxy<X>& px, const sc_proxy<Y>& py ); + + +template <class X, class Y> +inline +const sc_lv_base +operator | ( const sc_proxy<X>& px, const sc_proxy<Y>& py ); + + +#define DECL_BITWISE_OR_OP_T(tp) \ +template <class X> \ +inline \ +const sc_lv_base \ +operator | ( tp a, const sc_proxy<X>& px ); + +DECL_BITWISE_OR_OP_T(const char*) +DECL_BITWISE_OR_OP_T(const bool*) +DECL_BITWISE_OR_OP_T(const sc_logic*) +DECL_BITWISE_OR_OP_T(const sc_unsigned&) +DECL_BITWISE_OR_OP_T(const sc_signed&) +DECL_BITWISE_OR_OP_T(const sc_uint_base&) +DECL_BITWISE_OR_OP_T(const sc_int_base&) +DECL_BITWISE_OR_OP_T(unsigned long) +DECL_BITWISE_OR_OP_T(long) +DECL_BITWISE_OR_OP_T(unsigned int) +DECL_BITWISE_OR_OP_T(int) +DECL_BITWISE_OR_OP_T(uint64) +DECL_BITWISE_OR_OP_T(int64) + +#undef DECL_BITWISE_OR_OP_T + + +// bitwise xor + +template <class X, class Y> +inline +X& +operator ^= ( sc_proxy<X>& px, const sc_proxy<Y>& py ); + + +template <class X, class Y> +inline +const sc_lv_base +operator ^ ( const sc_proxy<X>& px, const sc_proxy<Y>& py ); + + +#define DECL_BITWISE_XOR_OP_T(tp) \ +template <class X> \ +inline \ +const sc_lv_base \ +operator ^ ( tp a, const sc_proxy<X>& px ); + +DECL_BITWISE_XOR_OP_T(const char*) +DECL_BITWISE_XOR_OP_T(const bool*) +DECL_BITWISE_XOR_OP_T(const sc_logic*) +DECL_BITWISE_XOR_OP_T(const sc_unsigned&) +DECL_BITWISE_XOR_OP_T(const sc_signed&) +DECL_BITWISE_XOR_OP_T(const sc_uint_base&) +DECL_BITWISE_XOR_OP_T(const sc_int_base&) +DECL_BITWISE_XOR_OP_T(unsigned long) +DECL_BITWISE_XOR_OP_T(long) +DECL_BITWISE_XOR_OP_T(unsigned int) +DECL_BITWISE_XOR_OP_T(int) +DECL_BITWISE_XOR_OP_T(uint64) +DECL_BITWISE_XOR_OP_T(int64) + +#undef DECL_BITWISE_XOR_OP_T + + +// relational operators + +template <class X, class Y> +inline +bool +operator == ( const sc_proxy<X>& px, const sc_proxy<Y>& py ); + +template <class X, class Y> +inline +bool +operator != ( const sc_proxy<X>& px, const sc_proxy<Y>& py ); + + +#define DECL_REL_OP_T(tp) \ +template <class X> \ +inline \ +bool \ +operator == ( tp b, const sc_proxy<X>& px ); \ + \ +template <class X> \ +inline \ +bool \ +operator != ( const sc_proxy<X>& px, tp b ); \ + \ +template <class X> \ +inline \ +bool \ +operator != ( tp b, const sc_proxy<X>& px ); + +DECL_REL_OP_T(const char*) +DECL_REL_OP_T(const bool*) +DECL_REL_OP_T(const sc_logic*) +DECL_REL_OP_T(const sc_unsigned&) +DECL_REL_OP_T(const sc_signed&) +DECL_REL_OP_T(const sc_uint_base&) +DECL_REL_OP_T(const sc_int_base&) +DECL_REL_OP_T(unsigned long) +DECL_REL_OP_T(long) +DECL_REL_OP_T(unsigned int) +DECL_REL_OP_T(int) +DECL_REL_OP_T(uint64) +DECL_REL_OP_T(int64) + +#undef DECL_REL_OP_T + + +// l-value concatenation + +// Due to the fact that temporary objects cannot be passed to non-const +// references, we have to enumerate, use call by value, and use dynamic +// memory allocation (and deallocation). + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +template <class X> +inline +void +get_words_( const X& x, int wi, sc_digit& x_dw, sc_digit& x_cw ) +{ + x_dw = x.get_word( wi ); + x_cw = x.get_cword( wi ); +} + +template <class X> +inline +void +set_words_( X& x, int wi, sc_digit x_dw, sc_digit x_cw ) +{ + x.set_word( wi, x_dw ); + x.set_cword( wi, x_cw ); +} + +template <class X> +inline +void +extend_sign_w_( X& x, int wi, bool sign ) +{ + int sz = x.size(); + unsigned int sgn = (sign ? ~SC_DIGIT_ZERO : SC_DIGIT_ZERO); + for( int i = wi; i < sz; ++ i ) { + set_words_( x, i, sgn, SC_DIGIT_ZERO ); + } +} + + +// assignment functions + +template <class X, class Y> +inline +void +assign_p_( sc_proxy<X>& px, const sc_proxy<Y>& py ) +{ + if( (void*) &px != (void*) &py ) { + X& x = px.back_cast(); + const Y& y = py.back_cast(); + int sz = x.size(); + int min_sz = sc_min( sz, y.size() ); + int i = 0; + for( ; i < min_sz; ++ i ) { + set_words_( x, i, y.get_word( i ), y.get_cword( i ) ); + } + // extend with zeros + extend_sign_w_( x, i, false ); + x.clean_tail(); + } +} + +// Vector types that are not derived from sc_proxy, sc_int_base, +// sc_uint_base, sc_signed, or sc_unsigned, must have a length() +// function and an operator []. The vector argument type must support +// accessing bits that are beyond the msb. The vector argument type +// decides what to do there (e.g. sign extension or zero padding). + +template <class X, class T> +inline +void +assign_v_( sc_proxy<X>& px, const T& a ) +{ + X& x = px.back_cast(); + int i; + int len_x = x.length(); + int len_a = a.length(); + if ( len_a > len_x ) len_a = len_x; + for( i = 0 ; i < len_a; ++ i ) { + x.set_bit( i, sc_logic_value_t( (bool) a[i] ) ); + } + for( ; i < len_x; ++ i ) { + x.set_bit( i, sc_logic_value_t( false ) ); + } +} + +template <class X> +inline +void +assign_v_( sc_proxy<X>& px, const sc_int_base& a ) +{ + X& x = px.back_cast(); + int i; + bool sign = a < 0; + int len_x = x.length(); + int len_a = a.length(); + if ( len_a > len_x ) len_a = len_x; + for( i = 0 ; i < len_a; ++ i ) { + x.set_bit( i, sc_logic_value_t( (bool) a[i] ) ); + } + for( ; i < len_x; ++ i ) { + x.set_bit( i, sc_logic_value_t( sign ) ); + } +} + +template <class X> +inline +void +assign_v_( sc_proxy<X>& px, const sc_signed& a ) +{ + X& x = px.back_cast(); + int i; + bool sign = a < 0; + int len_x = x.length(); + int len_a = a.length(); + if ( len_a > len_x ) len_a = len_x; + for( i = 0 ; i < len_a; ++ i ) { + x.set_bit( i, sc_logic_value_t( (bool) a[i] ) ); + } + for( ; i < len_x; ++ i ) { + x.set_bit( i, sc_logic_value_t( sign ) ); + } +} + +template <class X> +inline +void +assign_v_( sc_proxy<X>& px, const sc_uint_base& a ) +{ + X& x = px.back_cast(); + int i; + int len_x = x.length(); + int len_a = a.length(); + if ( len_a > len_x ) len_a = len_x; + for( i = 0 ; i < len_a; ++ i ) { + x.set_bit( i, sc_logic_value_t( (bool) a[i] ) ); + } + for( ; i < len_x; ++ i ) { + x.set_bit( i, sc_logic_value_t( false ) ); + } +} + +template <class X> +inline +void +assign_v_( sc_proxy<X>& px, const sc_unsigned& a ) +{ + X& x = px.back_cast(); + int i; + int len_x = x.length(); + int len_a = a.length(); + if ( len_a > len_x ) len_a = len_x; + for( i = 0 ; i < len_a; ++ i ) { + x.set_bit( i, sc_logic_value_t( (bool) a[i] ) ); + } + for( ; i < len_x; ++ i ) { + x.set_bit( i, sc_logic_value_t( false ) ); + } +} + + +// assignment operators + +template <class X> +inline +X& +sc_proxy<X>::assign_( const char* a ) +{ + X& x = back_cast(); + std::string s = convert_to_bin( a ); + int len = x.length(); + int s_len = s.length() - 1; + int min_len = sc_min( len, s_len ); + int i = 0; + for( ; i < min_len; ++ i ) { + char c = s[s_len - i - 1]; + x.set_bit( i, sc_logic::char_to_logic[(int)c] ); + } + // if formatted, fill the rest with sign(s), otherwise fill with zeros + sc_logic_value_t fill = (s[s_len] == 'F' ? sc_logic_value_t( s[0] - '0' ) + : sc_logic_value_t( 0 )); + for( ; i < len; ++ i ) { + x.set_bit( i, fill ); + } + return x; +} + +template <class X> +inline +X& +sc_proxy<X>::assign_( const bool* a ) +{ + // the length of 'a' must be larger than or equal to the length of 'this' + X& x = back_cast(); + int len = x.length(); + for( int i = 0; i < len; ++ i ) { + x.set_bit( i, sc_logic_value_t( a[i] ) ); + } + return x; +} + +template <class X> +inline +X& +sc_proxy<X>::assign_( const sc_logic* a ) +{ + // the length of 'a' must be larger than or equal to the length of 'this' + X& x = back_cast(); + int len = x.length(); + for( int i = 0; i < len; ++ i ) { + x.set_bit( i, a[i].value() ); + } + return x; +} + +template <class X> +inline +X& +sc_proxy<X>::assign_( unsigned int a ) +{ + X& x = back_cast(); + set_words_( x, 0, (sc_digit)a, SC_DIGIT_ZERO ); + // extend with zeros + extend_sign_w_( x, 1, false ); + x.clean_tail(); + return x; +} + +template <class X> +inline +X& +sc_proxy<X>::assign_( int a ) +{ + X& x = back_cast(); + set_words_( x, 0, (sc_digit) a, SC_DIGIT_ZERO ); + // extend with sign(a) + extend_sign_w_( x, 1, (a < 0) ); + x.clean_tail(); + return x; +} + +#if defined(SC_LONG_64) + template <class X> + inline + X& + sc_proxy<X>::assign_( unsigned long a ) + { + X& x = back_cast(); + set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO ); + if( x.size() > 1 ) { + set_words_( x, 1, + ((sc_digit) (a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO), + SC_DIGIT_ZERO ); + // extend with zeros + extend_sign_w_( x, 2, false ); + } + x.clean_tail(); + return x; + } + + template <class X> + inline + X& + sc_proxy<X>::assign_( long a ) + { + X& x = back_cast(); + set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO ); + if( x.size() > 1 ) { + set_words_( x, 1, + ((sc_digit) ((uint64) a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO), + SC_DIGIT_ZERO ); + // extend with sign(a) + extend_sign_w_( x, 2, (a < 0) ); + } + x.clean_tail(); + return x; + } + +#else + template <class X> + inline + X& + sc_proxy<X>::assign_( unsigned long a ) + { + X& x = back_cast(); + set_words_( x, 0, (sc_digit)a, SC_DIGIT_ZERO ); + // extend with zeros + extend_sign_w_( x, 1, false ); + x.clean_tail(); + return x; + } + + template <class X> + inline + X& + sc_proxy<X>::assign_( long a ) + { + X& x = back_cast(); + set_words_( x, 0, (sc_digit) a, SC_DIGIT_ZERO ); + // extend with sign(a) + extend_sign_w_( x, 1, (a < 0) ); + x.clean_tail(); + return x; + } +#endif +template <class X> +inline +X& +sc_proxy<X>::assign_( uint64 a ) +{ + X& x = back_cast(); + set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO ); + if( x.size() > 1 ) { + set_words_( x, 1, + ((sc_digit) (a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO), + SC_DIGIT_ZERO ); + // extend with zeros + extend_sign_w_( x, 2, false ); + } + x.clean_tail(); + return x; +} + +template <class X> +inline +X& +sc_proxy<X>::assign_( int64 a ) +{ + X& x = back_cast(); + set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO ); + if( x.size() > 1 ) { + set_words_( x, 1, + ((sc_digit) ((uint64) a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO), + SC_DIGIT_ZERO ); + // extend with sign(a) + extend_sign_w_( x, 2, (a < 0) ); + } + x.clean_tail(); + return x; +} + + +// bitwise operators and functions + +// bitwise complement + +template <class X> +inline +X& +sc_proxy<X>::b_not() +{ + X& x = back_cast(); + int sz = x.size(); + for( int i = 0; i < sz; ++ i ) { + sc_digit x_dw, x_cw; + get_words_( x, i, x_dw, x_cw ); + x.set_word( i, x_cw | ~x_dw ); + } + x.clean_tail(); + return x; +} + + +// bitwise and + +template <class X, class Y> +inline +X& +b_and_assign_( sc_proxy<X>& px, const sc_proxy<Y>& py ) +{ + X& x = px.back_cast(); + const Y& y = py.back_cast(); + assert( x.length() == y.length() ); + int sz = x.size(); + for( int i = 0; i < sz; ++ i ) { + sc_digit x_dw, x_cw, y_dw, y_cw; + get_words_( x, i, x_dw, x_cw ); + get_words_( y, i, y_dw, y_cw ); + sc_digit cw = (x_dw & y_cw) | (x_cw & y_dw) | (x_cw & y_cw); + sc_digit dw = cw | (x_dw & y_dw); + set_words_( x, i, dw, cw ); + } + // tail cleaning not needed + return x; +} + + +// bitwise or + +template <class X, class Y> +inline +X& +b_or_assign_( sc_proxy<X>& px, const sc_proxy<Y>& py ) +{ + X& x = px.back_cast(); + const Y& y = py.back_cast(); + assert( x.length() == y.length() ); + int sz = x.size(); + for( int i = 0; i < sz; ++ i ) { + sc_digit x_dw, x_cw, y_dw, y_cw; + get_words_( x, i, x_dw, x_cw ); + get_words_( y, i, y_dw, y_cw ); + sc_digit cw = (x_cw & y_cw) | (x_cw & ~y_dw) | (~x_dw & y_cw); + sc_digit dw = cw | x_dw | y_dw; + set_words_( x, i, dw, cw ); + } + // tail cleaning not needed + return x; +} + + +// bitwise xor + +template <class X, class Y> +inline +X& +b_xor_assign_( sc_proxy<X>& a, const sc_proxy<Y>& b ) +{ + X& x = a.back_cast(); + const Y& y = b.back_cast(); + assert( x.length() == y.length() ); + int sz = x.size(); + for( int i = 0; i < sz; ++ i ) { + sc_digit x_dw, x_cw, y_dw, y_cw; + get_words_( x, i, x_dw, x_cw ); + get_words_( y, i, y_dw, y_cw ); + sc_digit cw = x_cw | y_cw; + sc_digit dw = cw | (x_dw ^ y_dw); + set_words_( x, i, dw, cw ); + } + // tail cleaning not needed + return x; +} + + +// bitwise left shift + +template <class X> +inline +X& +sc_proxy<X>::operator <<= ( int n ) +{ + X& x = back_cast(); + if( n < 0 ) { + char msg[BUFSIZ]; + std::sprintf( msg, + "left shift operation is only allowed with positive " + "shift values, shift value = %d", n ); + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); + } + if( n >= x.length() ) { + extend_sign_w_( x, 0, false ); + // no tail cleaning needed + return x; + } + int sz = x.size(); + int wn = n / SC_DIGIT_SIZE; + int bn = n % SC_DIGIT_SIZE; + if( wn != 0 ) { + // shift words + int i = sz - 1; + for( ; i >= wn; -- i ) { + set_words_( x, i, x.get_word( i - wn ), x.get_cword( i - wn ) ); + } + for( ; i >= 0; -- i ) { + set_words_( x, i, SC_DIGIT_ZERO, SC_DIGIT_ZERO ); + } + } + if( bn != 0 ) { + // shift bits + for( int i = sz - 1; i >= 1; -- i ) { + sc_digit x_dw, x_cw; + get_words_( x, i, x_dw, x_cw ); + x_dw <<= bn; + x_dw |= x.get_word( i - 1 ) >> (SC_DIGIT_SIZE - bn); + x_cw <<= bn; + x_cw |= x.get_cword( i - 1 ) >> (SC_DIGIT_SIZE - bn); + set_words_( x, i, x_dw, x_cw ); + } + sc_digit x_dw, x_cw; + get_words_( x, 0, x_dw, x_cw ); + x_dw <<= bn; + x_cw <<= bn; + set_words_( x, 0, x_dw, x_cw ); + } + x.clean_tail(); + return x; +} + + +// bitwise right shift + + +template <class X> +inline +X& +sc_proxy<X>::operator >>= ( int n ) +{ + X& x = back_cast(); + if( n < 0 ) { + char msg[BUFSIZ]; + std::sprintf( msg, + "right shift operation is only allowed with positive " + "shift values, shift value = %d", n ); + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); + } + if( n >= x.length() ) { + extend_sign_w_( x, 0, false ); + // no tail cleaning needed + return x; + } + int sz = x.size(); + int wn = n / SC_DIGIT_SIZE; + int bn = n % SC_DIGIT_SIZE; + if( wn != 0 ) { + // shift words + int i = 0; + for( ; i < (sz - wn); ++ i ) { + set_words_( x, i, x.get_word( i + wn ), x.get_cword( i + wn ) ); + } + for( ; i < sz; ++ i ) { + set_words_( x, i, SC_DIGIT_ZERO, SC_DIGIT_ZERO ); + } + } + if( bn != 0 ) { + // shift bits + for( int i = 0; i < (sz - 1); ++ i ) { + sc_digit x_dw, x_cw; + get_words_( x, i, x_dw, x_cw ); + x_dw >>= bn; + x_dw |= x.get_word( i + 1 ) << (SC_DIGIT_SIZE - bn); + x_cw >>= bn; + x_cw |= x.get_cword( i + 1 ) << (SC_DIGIT_SIZE - bn); + set_words_( x, i, x_dw, x_cw ); + } + sc_digit x_dw, x_cw; + get_words_( x, sz - 1, x_dw, x_cw ); + x_dw >>= bn; + x_cw >>= bn; + set_words_( x, sz - 1, x_dw, x_cw ); + } + x.clean_tail(); + return x; +} + + +// bitwise left rotate + +template <class X> +inline +const sc_lv_base +lrotate( const sc_proxy<X>& x, int n ); + + +// bitwise right rotate + +template <class X> +inline +const sc_lv_base +rrotate( const sc_proxy<X>& x, int n ); + + +// bitwise reverse + +template <class X> +inline +X& +sc_proxy<X>::reverse() +{ + X& x = back_cast(); + int len = x.length(); + int half_len = len / 2; + for( int i = 0, j = len - 1; i < half_len; ++ i, --j ) { + sc_logic_value_t t = x.get_bit( i ); + x.set_bit( i, x.get_bit( j ) ); + x.set_bit( j, t ); + } + return x; +} + +template <class X> +inline +const sc_lv_base +reverse( const sc_proxy<X>& a ); + + +// reduce functions + +template <class X> +inline +sc_logic_value_t +sc_proxy<X>::and_reduce() const +{ + const X& x = back_cast(); + sc_logic_value_t result = sc_logic_value_t( 1 ); + int len = x.length(); + for( int i = 0; i < len; ++ i ) { + result = sc_logic::and_table[result][x.get_bit( i )]; + } + return result; +} + +template <class X> +inline +sc_logic_value_t +sc_proxy<X>::or_reduce() const +{ + const X& x = back_cast(); + sc_logic_value_t result = sc_logic_value_t( 0 ); + int len = x.length(); + for( int i = 0; i < len; ++ i ) { + result = sc_logic::or_table[result][x.get_bit( i )]; + } + return result; +} + +template <class X> +inline +sc_logic_value_t +sc_proxy<X>::xor_reduce() const +{ + const X& x = back_cast(); + sc_logic_value_t result = sc_logic_value_t( 0 ); + int len = x.length(); + for( int i = 0; i < len; ++ i ) { + result = sc_logic::xor_table[result][x.get_bit( i )]; + } + return result; +} + + +// relational operators + +template <class X, class Y> +inline +bool +operator != ( const sc_proxy<X>& px, const sc_proxy<Y>& py ) +{ + return !( px == py ); +} + + +#define DEFN_REL_OP_T(tp) \ +template <class X> \ +inline \ +bool \ +operator == ( tp b, const sc_proxy<X>& px ) \ +{ \ + return ( px == b ); \ +} \ + \ +template <class X> \ +inline \ +bool \ +operator != ( const sc_proxy<X>& px, tp b ) \ +{ \ + return !( px == b ); \ +} \ + \ +template <class X> \ +inline \ +bool \ +operator != ( tp b, const sc_proxy<X>& px ) \ +{ \ + return !( px == b ); \ +} + +DEFN_REL_OP_T(const char*) +DEFN_REL_OP_T(const bool*) +DEFN_REL_OP_T(const sc_logic*) +DEFN_REL_OP_T(const sc_unsigned&) +DEFN_REL_OP_T(const sc_signed&) +DEFN_REL_OP_T(const sc_uint_base&) +DEFN_REL_OP_T(const sc_int_base&) +DEFN_REL_OP_T(unsigned long) +DEFN_REL_OP_T(long) +DEFN_REL_OP_T(unsigned int) +DEFN_REL_OP_T(int) +DEFN_REL_OP_T(uint64) +DEFN_REL_OP_T(int64) + +#undef DEFN_REL_OP_T + + +// explicit conversions to character string + +template <class X> +inline +const std::string +sc_proxy<X>::to_string() const +{ + const X& x = back_cast(); + int len = x.length(); + std::string s; // ( len + 1 ); + for( int i = 0; i < len; ++ i ) { + s += sc_logic::logic_to_char[x.get_bit( len - i - 1 )]; + } + return s; +} + +template <class X> +inline +const std::string +sc_proxy<X>::to_string( sc_numrep numrep ) const +{ + return convert_to_fmt( to_string(), numrep, true ); +} + +template <class X> +inline +const std::string +sc_proxy<X>::to_string( sc_numrep numrep, bool w_prefix ) const +{ + return convert_to_fmt( to_string(), numrep, w_prefix ); +} + + +// other methods + +template <class X> +inline +void +sc_proxy<X>::scan( ::std::istream& is ) +{ + std::string s; + is >> s; + back_cast() = s.c_str(); +} + + +template <class X> +inline +void +sc_proxy<X>::check_bounds( int n ) const // check if bit n accessible +{ + if( n < 0 || n >= back_cast().length() ) { + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 ); + } +} + +template <class X> +inline +void +sc_proxy<X>::check_wbounds( int n ) const // check if word n accessible +{ + if( n < 0 || n >= back_cast().size() ) { + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 ); + } +} + + +template <class X> +inline +sc_digit +sc_proxy<X>::to_anything_unsigned() const +{ + // only 0 word is returned + // can't convert logic values other than 0 and 1 + const X& x = back_cast(); + int len = x.length(); + if( x.get_cword( 0 ) != SC_DIGIT_ZERO ) { + SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 ); + } + sc_digit w = x.get_word( 0 ); + if( len >= SC_DIGIT_SIZE ) { + return w; + } + return ( w & (~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - len)) ); +} + +template <class X> +inline +uint64 +sc_proxy<X>::to_uint64() const +{ + // words 1 and 0 returned. + // can't convert logic values other than 0 and 1 + const X& x = back_cast(); + int len = x.length(); + if( x.get_cword( 0 ) != SC_DIGIT_ZERO ) { + SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 ); + } + uint64 w = x.get_word( 0 ); + if( len > SC_DIGIT_SIZE ) + { + if( x.get_cword( 1 ) != SC_DIGIT_ZERO ) { + SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 ); + } + uint64 w1 = x.get_word( 1 ); + w = w | (w1 << SC_DIGIT_SIZE); + return w; + } + else if( len == SC_DIGIT_SIZE ) + { + return w; + } + else + { + return ( w & (~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - len)) ); + } +} + +template <class X> +inline +int64 +sc_proxy<X>::to_anything_signed() const +{ + const X& x = back_cast(); + int len = x.length(); + int64 w = 0; + + if( len > SC_DIGIT_SIZE ) + { + if( x.get_cword( 1 ) != SC_DIGIT_ZERO ) + SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 ); + w = x.get_word(1); + } + if( x.get_cword( 0 ) != SC_DIGIT_ZERO ) + SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 ); + w = (w << SC_DIGIT_SIZE) | x.get_word( 0 ); + if( len >= 64 ) { + return w; + } + + uint64 zero = 0; + sc_logic_value_t sgn = x.get_bit( len - 1 ); + if( sgn == 0 ) { + return (int64)( w & (~zero >> (64 - len)) ); + } else { + return (int64)( w | (~zero << len) ); + } +} + + +// ---------------------------------------------------------------------------- + +// functional notation for the reduce methods + +template <class X> +inline +sc_logic_value_t +and_reduce( const sc_proxy<X>& a ) +{ + return a.and_reduce(); +} + +template <class X> +inline +sc_logic_value_t +nand_reduce( const sc_proxy<X>& a ) +{ + return a.nand_reduce(); +} + +template <class X> +inline +sc_logic_value_t +or_reduce( const sc_proxy<X>& a ) +{ + return a.or_reduce(); +} + +template <class X> +inline +sc_logic_value_t +nor_reduce( const sc_proxy<X>& a ) +{ + return a.nor_reduce(); +} + +template <class X> +inline +sc_logic_value_t +xor_reduce( const sc_proxy<X>& a ) +{ + return a.xor_reduce(); +} + +template <class X> +inline +sc_logic_value_t +xnor_reduce( const sc_proxy<X>& a ) +{ + return a.xnor_reduce(); +} + + +// ---------------------------------------------------------------------------- + +template <class X> +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_proxy<X>& a ) +{ + a.print( os ); + return os; +} + +template <class X> +inline +::std::istream& +operator >> ( ::std::istream& is, sc_proxy<X>& a ) +{ + a.scan( is ); + return is; +} + +} // namespace sc_dt + + +#endif diff --git a/ext/systemc/src/sysc/datatypes/fx/fx.h b/ext/systemc/src/sysc/datatypes/fx/fx.h new file mode 100644 index 000000000..9c35014fa --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/fx.h @@ -0,0 +1,61 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + fx.h - Master include file for the fixed-point types. + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: fx.h,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:57 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef FX_H +#define FX_H + + +#include "sysc/datatypes/fx/sc_fixed.h" +#include "sysc/datatypes/fx/sc_fxcast_switch.h" +#include "sysc/datatypes/fx/sc_fxtype_params.h" +#include "sysc/datatypes/fx/sc_ufixed.h" + +#include "sysc/datatypes/fx/scfx_other_defs.h" + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_context.h b/ext/systemc/src/sysc/datatypes/fx/sc_context.h new file mode 100644 index 000000000..1e313a486 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_context.h @@ -0,0 +1,316 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_context.h - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_context.h,v $ +// Revision 1.2 2011/08/24 22:05:43 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.5 2006/05/26 20:36:52 acg +// Andy Goodrich: added a using for sc_core::default_ptr_hash_fn to keep HP +// aCC happy. +// +// Revision 1.4 2006/03/21 00:00:31 acg +// Andy Goodrich: changed name of sc_get_current_process_base() to be +// sc_get_current_process_b() since its returning an sc_process_b instance. +// +// Revision 1.3 2006/01/13 18:53:57 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_CONTEXT_H +#define SC_CONTEXT_H + + +#include "sysc/datatypes/fx/sc_fx_ids.h" +#include "sysc/kernel/sc_simcontext.h" +#include "sysc/utils/sc_hash.h" + + +namespace sc_core { + class sc_process_b; +} + +using sc_core::default_ptr_hash_fn; // To keep HP aCC happy. + +namespace sc_dt +{ + +// classes defined in this module +class sc_without_context; +template <class T> class sc_global; +template <class T> class sc_context; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_without_context +// +// Empty class that is used for its type only. +// ---------------------------------------------------------------------------- + +class sc_without_context {}; + + +// ---------------------------------------------------------------------------- +// TEMPLATE CLASS : sc_global +// +// Template global variable class; singleton; co-routine safe. +// ---------------------------------------------------------------------------- + +template <class T> +class sc_global +{ + + sc_global(); + + void update(); + +public: + + static sc_global<T>* instance(); + + const T*& value_ptr(); + +private: + static sc_global<T>* m_instance; + + sc_core::sc_phash<void*,const T*> m_map; + void* m_proc; // context (current process or NULL) + const T* m_value_ptr; + +}; + + +// ---------------------------------------------------------------------------- +// ENUM : sc_context_begin +// +// Enumeration of context begin options. +// ---------------------------------------------------------------------------- + +enum sc_context_begin +{ + SC_NOW, + SC_LATER +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_context +// +// Template context class; co-routine safe. +// ---------------------------------------------------------------------------- + +template <class T> +class sc_context +{ + // disabled + sc_context( const sc_context<T>& ); + void* operator new( std::size_t ); + +public: + + explicit sc_context( const T&, sc_context_begin = SC_NOW ); + ~sc_context(); + + void begin(); + void end(); + + static const T& default_value(); + const T& value() const; + +private: + + const T m_value; + const T*& m_def_value_ptr; + const T* m_old_value_ptr; +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// ---------------------------------------------------------------------------- +// TEMPLATE CLASS : sc_global +// +// Template global variable class; singleton; co-routine safe. +// ---------------------------------------------------------------------------- + +template <class T> +sc_global<T>* sc_global<T>::m_instance = 0; + +template <class T> +inline +sc_global<T>::sc_global() + : m_map() + // use &m_instance as unique "non-process" key (NULL denotes 'sc_main' context) + , m_proc( &m_instance ) + , m_value_ptr( 0 ) +{} + + +template <class T> +inline +void +sc_global<T>::update() +{ + void* p = sc_core::sc_get_current_process_b(); + if( p != m_proc ) + { + const T* vp = m_map[p]; + if( vp == 0 ) + { + vp = new T( sc_without_context() ); + m_map.insert( p, vp ); + } + m_proc = p; + m_value_ptr = vp; + } +} + + +template <class T> +inline +sc_global<T>* +sc_global<T>::instance() +{ + if( m_instance == 0 ) + { + m_instance = new sc_global<T>; + } + return m_instance; +} + + +template <class T> +inline +const T*& +sc_global<T>::value_ptr() +{ + update(); + return m_value_ptr; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_context +// +// Template context class; co-routine safe. +// ---------------------------------------------------------------------------- + +template <class T> +inline +sc_context<T>::sc_context( const T& value_, sc_context_begin begin ) +: m_value( value_ ), + m_def_value_ptr( sc_global<T>::instance()->value_ptr() ), + m_old_value_ptr( 0 ) +{ + if( begin == SC_NOW ) + { + m_old_value_ptr = m_def_value_ptr; + m_def_value_ptr = &m_value; + } +} + +template <class T> +inline +sc_context<T>::~sc_context() +{ + if( m_old_value_ptr != 0 ) + { + m_def_value_ptr = m_old_value_ptr; + m_old_value_ptr = 0; + } +} + + +template <class T> +inline +void +sc_context<T>::begin() +{ + if( m_old_value_ptr == 0 ) + { + m_old_value_ptr = m_def_value_ptr; + m_def_value_ptr = &m_value; + } + else + { + SC_REPORT_ERROR( sc_core::SC_ID_CONTEXT_BEGIN_FAILED_, 0 ); + } +} + +template <class T> +inline +void +sc_context<T>::end() +{ + if( m_old_value_ptr != 0 ) + { + m_def_value_ptr = m_old_value_ptr; + m_old_value_ptr = 0; + } + else + { + SC_REPORT_ERROR( sc_core::SC_ID_CONTEXT_END_FAILED_, 0 ); + } +} + + +template <class T> +inline +const T& +sc_context<T>::default_value() +{ + return *sc_global<T>::instance()->value_ptr(); +} + +template <class T> +inline +const T& +sc_context<T>::value() const +{ + return m_value; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fix.h b/ext/systemc/src/sysc/datatypes/fx/sc_fix.h new file mode 100644 index 000000000..80df65a2c --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fix.h @@ -0,0 +1,1938 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fix.h - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_fix.h,v $ +// Revision 1.2 2011/01/19 18:57:40 acg +// Andy Goodrich: changes for IEEE_1666_2011. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:57 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_FIX_H +#define SC_FIX_H + + +#include "sysc/datatypes/fx/sc_fxnum.h" + + +namespace sc_dt +{ + +// classes defined in this module +class sc_fix; +class sc_fix_fast; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fix +// +// "Unconstrained" signed fixed-point class; arbitrary precision. +// ---------------------------------------------------------------------------- + +class sc_fix : public sc_fxnum +{ + +public: + + // constructors + + explicit sc_fix( sc_fxnum_observer* = 0 ); + sc_fix( int, int, + sc_fxnum_observer* = 0 ); + sc_fix( sc_q_mode, sc_o_mode, + sc_fxnum_observer* = 0 ); + sc_fix( sc_q_mode, sc_o_mode, int, + sc_fxnum_observer* = 0 ); + sc_fix( int, int, sc_q_mode, sc_o_mode, + sc_fxnum_observer* = 0 ); + sc_fix( int, int, sc_q_mode, sc_o_mode, int, + sc_fxnum_observer* = 0 ); + explicit sc_fix( const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + sc_fix( int, int, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + sc_fix( sc_q_mode, sc_o_mode, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + sc_fix( sc_q_mode, sc_o_mode, int, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + sc_fix( int, int, sc_q_mode, sc_o_mode, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + sc_fix( int, int, sc_q_mode, sc_o_mode, int, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + explicit sc_fix( const sc_fxtype_params&, + sc_fxnum_observer* = 0 ); + sc_fix( const sc_fxtype_params&, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + +#define DECL_CTORS_T(tp) \ + sc_fix( tp, \ + int, int, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + sc_q_mode, sc_o_mode, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + sc_q_mode, sc_o_mode, int, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + int, int, sc_q_mode, sc_o_mode, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + int, int, sc_q_mode, sc_o_mode, int, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + int, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + sc_q_mode, sc_o_mode, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + sc_q_mode, sc_o_mode, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + int, int, sc_q_mode, sc_o_mode, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + int, int, sc_q_mode, sc_o_mode, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + const sc_fxtype_params&, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + const sc_fxtype_params&, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); + +#define DECL_CTORS_T_A(tp) \ + sc_fix( tp, \ + sc_fxnum_observer* = 0 ); \ + DECL_CTORS_T(tp) + +#define DECL_CTORS_T_B(tp) \ + explicit sc_fix( tp, \ + sc_fxnum_observer* = 0 ); \ + DECL_CTORS_T(tp) + + DECL_CTORS_T_A(int) + DECL_CTORS_T_A(unsigned int) + DECL_CTORS_T_A(long) + DECL_CTORS_T_A(unsigned long) + DECL_CTORS_T_A(float) + DECL_CTORS_T_A(double) + DECL_CTORS_T_A(const char*) + DECL_CTORS_T_A(const sc_fxval&) + DECL_CTORS_T_A(const sc_fxval_fast&) + DECL_CTORS_T_A(const sc_fxnum&) + DECL_CTORS_T_A(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_CTORS_T_B(int64) + DECL_CTORS_T_B(uint64) + DECL_CTORS_T_B(const sc_int_base&) + DECL_CTORS_T_B(const sc_uint_base&) + DECL_CTORS_T_B(const sc_signed&) + DECL_CTORS_T_B(const sc_unsigned&) +#endif + +#undef DECL_CTORS_T +#undef DECL_CTORS_T_A +#undef DECL_CTORS_T_B + + // copy constructor + + sc_fix( const sc_fix& ); + + + // unary bitwise operators + + const sc_fix operator ~ () const; + + + // unary bitwise functions + + friend void b_not( sc_fix&, const sc_fix& ); + + + // binary bitwise operators + + friend const sc_fix operator & ( const sc_fix&, const sc_fix& ); + friend const sc_fix operator & ( const sc_fix&, const sc_fix_fast& ); + friend const sc_fix operator & ( const sc_fix_fast&, const sc_fix& ); + friend const sc_fix operator | ( const sc_fix&, const sc_fix& ); + friend const sc_fix operator | ( const sc_fix&, const sc_fix_fast& ); + friend const sc_fix operator | ( const sc_fix_fast&, const sc_fix& ); + friend const sc_fix operator ^ ( const sc_fix&, const sc_fix& ); + friend const sc_fix operator ^ ( const sc_fix&, const sc_fix_fast& ); + friend const sc_fix operator ^ ( const sc_fix_fast&, const sc_fix& ); + + + // binary bitwise functions + + friend void b_and( sc_fix&, const sc_fix&, const sc_fix& ); + friend void b_and( sc_fix&, const sc_fix&, const sc_fix_fast& ); + friend void b_and( sc_fix&, const sc_fix_fast&, const sc_fix& ); + friend void b_or ( sc_fix&, const sc_fix&, const sc_fix& ); + friend void b_or ( sc_fix&, const sc_fix&, const sc_fix_fast& ); + friend void b_or ( sc_fix&, const sc_fix_fast&, const sc_fix& ); + friend void b_xor( sc_fix&, const sc_fix&, const sc_fix& ); + friend void b_xor( sc_fix&, const sc_fix&, const sc_fix_fast& ); + friend void b_xor( sc_fix&, const sc_fix_fast&, const sc_fix& ); + + + // assignment operators + + sc_fix& operator = ( const sc_fix& ); + +#define DECL_ASN_OP_T(op,tp) \ + sc_fix& operator op ( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + + DECL_ASN_OP_T(&=,const sc_fix&) + DECL_ASN_OP_T(&=,const sc_fix_fast&) + DECL_ASN_OP_T(|=,const sc_fix&) + DECL_ASN_OP_T(|=,const sc_fix_fast&) + DECL_ASN_OP_T(^=,const sc_fix&) + DECL_ASN_OP_T(^=,const sc_fix_fast&) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval operator ++ ( int ); + const sc_fxval operator -- ( int ); + + sc_fix& operator ++ (); + sc_fix& operator -- (); + +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fix_fast +// +// "Unconstrained" signed fixed-point class; limited precision. +// ---------------------------------------------------------------------------- + +class sc_fix_fast : public sc_fxnum_fast +{ + +public: + + // constructors + + explicit sc_fix_fast( sc_fxnum_fast_observer* = 0 ); + sc_fix_fast( int, int, + sc_fxnum_fast_observer* = 0 ); + sc_fix_fast( sc_q_mode, sc_o_mode, + sc_fxnum_fast_observer* = 0 ); + sc_fix_fast( sc_q_mode, sc_o_mode, int, + sc_fxnum_fast_observer* = 0 ); + sc_fix_fast( int, int, sc_q_mode, sc_o_mode, + sc_fxnum_fast_observer* = 0 ); + sc_fix_fast( int, int, sc_q_mode, sc_o_mode, int, + sc_fxnum_fast_observer* = 0 ); + explicit sc_fix_fast( const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + sc_fix_fast( int, int, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + sc_fix_fast( sc_q_mode, sc_o_mode, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + sc_fix_fast( sc_q_mode, sc_o_mode, int, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + sc_fix_fast( int, int, sc_q_mode, sc_o_mode, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + sc_fix_fast( int, int, sc_q_mode, sc_o_mode, int, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + explicit sc_fix_fast( const sc_fxtype_params&, + sc_fxnum_fast_observer* = 0 ); + sc_fix_fast( const sc_fxtype_params&, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + +#define DECL_CTORS_T(tp) \ + sc_fix_fast( tp, \ + int, int, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + sc_q_mode, sc_o_mode, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + sc_q_mode, sc_o_mode, int, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + int, int, sc_q_mode, sc_o_mode, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + int, int, sc_q_mode, sc_o_mode, int, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + int, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + sc_q_mode, sc_o_mode, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + sc_q_mode, sc_o_mode, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + int, int, sc_q_mode, sc_o_mode, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + int, int, sc_q_mode, sc_o_mode, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + const sc_fxtype_params&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + const sc_fxtype_params&, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); + +#define DECL_CTORS_T_A(tp) \ + sc_fix_fast( tp, \ + sc_fxnum_fast_observer* = 0 ); \ + DECL_CTORS_T(tp) + +#define DECL_CTORS_T_B(tp) \ + explicit sc_fix_fast( tp, \ + sc_fxnum_fast_observer* = 0 ); \ + DECL_CTORS_T(tp) + + DECL_CTORS_T_A(int) + DECL_CTORS_T_A(unsigned int) + DECL_CTORS_T_A(long) + DECL_CTORS_T_A(unsigned long) + DECL_CTORS_T_A(float) + DECL_CTORS_T_A(double) + DECL_CTORS_T_A(const char*) + DECL_CTORS_T_A(const sc_fxval&) + DECL_CTORS_T_A(const sc_fxval_fast&) + DECL_CTORS_T_A(const sc_fxnum&) + DECL_CTORS_T_A(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_CTORS_T_B(int64) + DECL_CTORS_T_B(uint64) + DECL_CTORS_T_B(const sc_int_base&) + DECL_CTORS_T_B(const sc_uint_base&) + DECL_CTORS_T_B(const sc_signed&) + DECL_CTORS_T_B(const sc_unsigned&) +#endif + +#undef DECL_CTORS_T +#undef DECL_CTORS_T_A +#undef DECL_CTORS_T_B + + // copy constructor + + sc_fix_fast( const sc_fix_fast& ); + + + // unary bitwise operators + + const sc_fix_fast operator ~ () const; + + + // unary bitwise functions + + friend void b_not( sc_fix_fast&, const sc_fix_fast& ); + + + // binary bitwise operators + + friend const sc_fix_fast operator & ( const sc_fix_fast&, + const sc_fix_fast& ); + friend const sc_fix_fast operator ^ ( const sc_fix_fast&, + const sc_fix_fast& ); + friend const sc_fix_fast operator | ( const sc_fix_fast&, + const sc_fix_fast& ); + + + // binary bitwise functions + + friend void b_and( sc_fix_fast&, const sc_fix_fast&, const sc_fix_fast& ); + friend void b_or ( sc_fix_fast&, const sc_fix_fast&, const sc_fix_fast& ); + friend void b_xor( sc_fix_fast&, const sc_fix_fast&, const sc_fix_fast& ); + + + // assignment operators + + sc_fix_fast& operator = ( const sc_fix_fast& ); + +#define DECL_ASN_OP_T(op,tp) \ + sc_fix_fast& operator op ( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + + DECL_ASN_OP_T(&=,const sc_fix&) + DECL_ASN_OP_T(&=,const sc_fix_fast&) + DECL_ASN_OP_T(|=,const sc_fix&) + DECL_ASN_OP_T(|=,const sc_fix_fast&) + DECL_ASN_OP_T(^=,const sc_fix&) + DECL_ASN_OP_T(^=,const sc_fix_fast&) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval_fast operator ++ ( int ); + const sc_fxval_fast operator -- ( int ); + + sc_fix_fast& operator ++ (); + sc_fix_fast& operator -- (); + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// ---------------------------------------------------------------------------- +// CLASS : sc_fix +// +// "Unconstrained" signed fixed-point class; arbitrary precision. +// ---------------------------------------------------------------------------- + +// constructors + +inline +sc_fix::sc_fix( sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params(), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix::sc_fix( int wl_, int iwl_, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_ ), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix::sc_fix( sc_q_mode qm, sc_o_mode om, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( qm, om ), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix::sc_fix( sc_q_mode qm, sc_o_mode om, int nb, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( qm, om, nb ), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix::sc_fix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om ), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix::sc_fix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om, nb ), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix::sc_fix( const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params(), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix::sc_fix( int wl_, int iwl_, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_ ), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix::sc_fix( sc_q_mode qm, sc_o_mode om, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( qm, om ), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix::sc_fix( sc_q_mode qm, sc_o_mode om, int nb, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( qm, om, nb ), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix::sc_fix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om ), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix::sc_fix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om, nb ), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix::sc_fix( const sc_fxtype_params& type_params, + sc_fxnum_observer* observer_ ) +: sc_fxnum( type_params, + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix::sc_fix( const sc_fxtype_params& type_params, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( type_params, + SC_TC_, + cast_sw, + observer_ ) +{} + +#define DEFN_CTORS_T_A(tp) \ +inline \ +sc_fix::sc_fix( tp a, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params(), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_ ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( qm, om ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( qm, om, nb ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params(), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_ ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( qm, om ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( qm, om, nb ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + const sc_fxtype_params& type_params, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + type_params, \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + const sc_fxtype_params& type_params, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + type_params, \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} + +#define DEFN_CTORS_T_B(tp) \ +inline \ +sc_fix::sc_fix( tp a, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + a.type_params(), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), wl_, iwl_ ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), qm, om ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), qm, om, nb ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + a.type_params(), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), wl_, iwl_ ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), qm, om ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), qm, om, nb ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + const sc_fxtype_params& type_params, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + type_params, \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + const sc_fxtype_params& type_params, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + type_params, \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} + +DEFN_CTORS_T_A(int) +DEFN_CTORS_T_A(unsigned int) +DEFN_CTORS_T_A(long) +DEFN_CTORS_T_A(unsigned long) +DEFN_CTORS_T_A(float) +DEFN_CTORS_T_A(double) +DEFN_CTORS_T_A(const char*) +DEFN_CTORS_T_A(const sc_fxval&) +DEFN_CTORS_T_A(const sc_fxval_fast&) +DEFN_CTORS_T_B(const sc_fxnum&) +DEFN_CTORS_T_B(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTORS_T_A(int64) +DEFN_CTORS_T_A(uint64) +DEFN_CTORS_T_A(const sc_int_base&) +DEFN_CTORS_T_A(const sc_uint_base&) +DEFN_CTORS_T_A(const sc_signed&) +DEFN_CTORS_T_A(const sc_unsigned&) +#endif + +#undef DEFN_CTORS_T_A +#undef DEFN_CTORS_T_B + +// copy constructor + +inline +sc_fix::sc_fix( const sc_fix& a ) +: sc_fxnum( a, + a.type_params(), + SC_TC_, + sc_fxcast_switch(), + 0 ) +{} + + +// unary bitwise operators + +inline +const sc_fix +sc_fix::operator ~ () const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + int iwl_c = iwl(); + int wl_c = wl(); + sc_fix c( wl_c, iwl_c ); + for( int i = iwl_c - wl_c; i < iwl_c; ++ i ) + c.set_bit( i, ! get_bit( i ) ); + return sc_fix( c, wl_c, iwl_c ); +} + + +// unary bitwise functions + +inline +void +b_not( sc_fix& c, const sc_fix& a ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + int iwl_c = c.iwl(); + for( int i = iwl_c - c.wl(); i < iwl_c; ++ i ) + c.set_bit( i, ! a.get_bit( i ) ); + c.cast(); + SC_FXNUM_OBSERVER_WRITE_( c ) +} + + +// binary bitwise operators + +#define DEFN_BIN_OP_T(op,op2,tp1,tp2) \ +inline \ +const sc_fix \ +operator op ( const tp1& a, const tp2& b ) \ +{ \ + a.observer_read(); \ + b.observer_read(); \ + int iwl_a = a.iwl(); \ + int iwl_b = b.iwl(); \ + int iwl_c = sc_max( iwl_a, iwl_b ); \ + int fwl_c = sc_max( a.wl() - iwl_a, b.wl() - iwl_b ); \ + sc_fix c( iwl_c + fwl_c, iwl_c ); \ + for( int i = -fwl_c; i < iwl_c; ++ i ) \ + c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \ + return sc_fix( c, iwl_c + fwl_c, iwl_c ); \ +} + +DEFN_BIN_OP_T(&,&&,sc_fix,sc_fix) +DEFN_BIN_OP_T(&,&&,sc_fix,sc_fix_fast) +DEFN_BIN_OP_T(&,&&,sc_fix_fast,sc_fix) + +DEFN_BIN_OP_T(|,||,sc_fix,sc_fix) +DEFN_BIN_OP_T(|,||,sc_fix,sc_fix_fast) +DEFN_BIN_OP_T(|,||,sc_fix_fast,sc_fix) + +DEFN_BIN_OP_T(^,!=,sc_fix,sc_fix) +DEFN_BIN_OP_T(^,!=,sc_fix,sc_fix_fast) +DEFN_BIN_OP_T(^,!=,sc_fix_fast,sc_fix) + +#undef DEFN_BIN_OP_T + + +// binary bitwise functions + +#define DEFN_BIN_FNC_T(fnc,op2,tp1,tp2) \ +inline \ +void \ +fnc ( sc_fix& c, const tp1& a, const tp2& b ) \ +{ \ + a.observer_read(); \ + b.observer_read(); \ + int iwl_c = c.iwl(); \ + for( int i = iwl_c - c.wl(); i < iwl_c; ++ i ) \ + c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \ + c.cast(); \ + SC_FXNUM_OBSERVER_WRITE_( c ) \ +} + +DEFN_BIN_FNC_T(b_and,&&,sc_fix,sc_fix) +DEFN_BIN_FNC_T(b_and,&&,sc_fix,sc_fix_fast) +DEFN_BIN_FNC_T(b_and,&&,sc_fix_fast,sc_fix) + +DEFN_BIN_FNC_T(b_or,||,sc_fix,sc_fix) +DEFN_BIN_FNC_T(b_or,||,sc_fix,sc_fix_fast) +DEFN_BIN_FNC_T(b_or,||,sc_fix_fast,sc_fix) + +DEFN_BIN_FNC_T(b_xor,!=,sc_fix,sc_fix) +DEFN_BIN_FNC_T(b_xor,!=,sc_fix,sc_fix_fast) +DEFN_BIN_FNC_T(b_xor,!=,sc_fix_fast,sc_fix) + +#undef DEFN_BIN_FNC_T + + +// assignment operators + +inline +sc_fix& +sc_fix::operator = ( const sc_fix& a ) +{ + sc_fxnum::operator = ( a ); + return *this; +} + +#define DEFN_ASN_OP_T(op,tp) \ +inline \ +sc_fix& \ +sc_fix::operator op ( tp a ) \ +{ \ + sc_fxnum::operator op( a ); \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op) \ +DEFN_ASN_OP_T(op,int64) \ +DEFN_ASN_OP_T(op,uint64) \ +DEFN_ASN_OP_T(op,const sc_int_base&) \ +DEFN_ASN_OP_T(op,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,const sc_signed&) \ +DEFN_ASN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op) +#endif + +#define DEFN_ASN_OP(op) \ +DEFN_ASN_OP_T(op,int) \ +DEFN_ASN_OP_T(op,unsigned int) \ +DEFN_ASN_OP_T(op,long) \ +DEFN_ASN_OP_T(op,unsigned long) \ +DEFN_ASN_OP_T(op,float) \ +DEFN_ASN_OP_T(op,double) \ +DEFN_ASN_OP_T(op,const char*) \ +DEFN_ASN_OP_T(op,const sc_fxval&) \ +DEFN_ASN_OP_T(op,const sc_fxval_fast&) \ +DEFN_ASN_OP_T(op,const sc_fxnum&) \ +DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \ +DEFN_ASN_OP_OTHER(op) + +DEFN_ASN_OP(=) + +DEFN_ASN_OP(*=) +DEFN_ASN_OP(/=) +DEFN_ASN_OP(+=) +DEFN_ASN_OP(-=) + +DEFN_ASN_OP_T(<<=,int) +DEFN_ASN_OP_T(>>=,int) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +#define DEFN_ASN_OP_T(op,op2,tp) \ +inline \ +sc_fix& \ +sc_fix::operator op ( const tp& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( *this ) \ + b.observer_read(); \ + int iwl_c = iwl(); \ + for( int i = iwl_c - wl(); i < iwl_c; ++ i ) \ + set_bit( i, get_bit( i ) op2 b.get_bit( i ) ); \ + cast(); \ + SC_FXNUM_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +DEFN_ASN_OP_T(&=,&&,sc_fix) +DEFN_ASN_OP_T(&=,&&,sc_fix_fast) +DEFN_ASN_OP_T(|=,||,sc_fix) +DEFN_ASN_OP_T(|=,||,sc_fix_fast) +DEFN_ASN_OP_T(^=,!=,sc_fix) +DEFN_ASN_OP_T(^=,!=,sc_fix_fast) + +#undef DEFN_ASN_OP_T + + +// auto-increment and auto-decrement + +inline +const sc_fxval +sc_fix::operator ++ ( int ) +{ + return sc_fxval( sc_fxnum::operator ++ ( 0 ) ); +} + +inline +const sc_fxval +sc_fix::operator -- ( int ) +{ + return sc_fxval( sc_fxnum::operator -- ( 0 ) ); +} + +inline +sc_fix& +sc_fix::operator ++ () +{ + sc_fxnum::operator ++ (); + return *this; +} + +inline +sc_fix& +sc_fix::operator -- () +{ + sc_fxnum::operator -- (); + return *this; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fix_fast +// +// "Unconstrained" signed fixed-point class; limited precision. +// ---------------------------------------------------------------------------- + +// constructors + +inline +sc_fix_fast::sc_fix_fast( sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params(), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( int wl_, int iwl_, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_ ), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( sc_q_mode qm, sc_o_mode om, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( qm, om ), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( sc_q_mode qm, sc_o_mode om, int nb, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( qm, om, nb ), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om ), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( int wl_, int iwl_, + sc_q_mode qm, sc_o_mode om, int nb, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om, nb ), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params(), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( int wl_, int iwl_, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_ ), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( sc_q_mode qm, sc_o_mode om, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( qm, om ), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( sc_q_mode qm, sc_o_mode om, int nb, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( qm, om, nb ), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om ), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( int wl_, int iwl_, + sc_q_mode qm, sc_o_mode om, int nb, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om, nb ), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( const sc_fxtype_params& type_params, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( type_params, + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( const sc_fxtype_params& type_params, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( type_params, + SC_TC_, + cast_sw, + observer_ ) +{} + +#define DEFN_CTORS_T_A(tp) \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params(), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_ ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( qm, om ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( qm, om, nb ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params(), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_ ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( qm, om ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( qm, om, nb ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + const sc_fxtype_params& type_params, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + type_params, \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + const sc_fxtype_params& type_params, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + type_params, \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} + +#define DEFN_CTORS_T_B(tp) \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + a.type_params(), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), wl_, iwl_ ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), qm, om ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), qm, om, nb ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + a.type_params(), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), wl_, iwl_ ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), qm, om ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), qm, om, nb ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + const sc_fxtype_params& type_params, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + type_params, \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + const sc_fxtype_params& type_params, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + type_params, \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} + +DEFN_CTORS_T_A(int) +DEFN_CTORS_T_A(unsigned int) +DEFN_CTORS_T_A(long) +DEFN_CTORS_T_A(unsigned long) +DEFN_CTORS_T_A(float) +DEFN_CTORS_T_A(double) +DEFN_CTORS_T_A(const char*) +DEFN_CTORS_T_A(const sc_fxval&) +DEFN_CTORS_T_A(const sc_fxval_fast&) +DEFN_CTORS_T_B(const sc_fxnum&) +DEFN_CTORS_T_B(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTORS_T_A(int64) +DEFN_CTORS_T_A(uint64) +DEFN_CTORS_T_A(const sc_int_base&) +DEFN_CTORS_T_A(const sc_uint_base&) +DEFN_CTORS_T_A(const sc_signed&) +DEFN_CTORS_T_A(const sc_unsigned&) +#endif + +#undef DEFN_CTORS_T_A +#undef DEFN_CTORS_T_B + +// copy constructor + +inline +sc_fix_fast::sc_fix_fast( const sc_fix_fast& a ) +: sc_fxnum_fast( a, + a.type_params(), + SC_TC_, + sc_fxcast_switch(), + 0 ) +{} + + +// unary bitwise operators + +inline +const sc_fix_fast +sc_fix_fast::operator ~ () const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + int iwl_c = iwl(); + int wl_c = wl(); + sc_fix_fast c( wl_c, iwl_c ); + for( int i = iwl_c - wl_c; i < iwl_c; ++ i ) + c.set_bit( i, ! get_bit( i ) ); + return sc_fix_fast( c, wl_c, iwl_c ); +} + + +// unary bitwise functions + +inline +void +b_not( sc_fix_fast& c, const sc_fix_fast& a ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + int iwl_c = c.iwl(); + for( int i = iwl_c - c.wl(); i < iwl_c; ++ i ) + c.set_bit( i, ! a.get_bit( i ) ); + c.cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) +} + + +// binary bitwise operators + +#define DEFN_BIN_OP_T(op,op2,tp1,tp2) \ +inline \ +const sc_fix_fast \ +operator op ( const tp1& a, const tp2& b ) \ +{ \ + a.observer_read(); \ + b.observer_read(); \ + int iwl_a = a.iwl(); \ + int iwl_b = b.iwl(); \ + int iwl_c = sc_max( iwl_a, iwl_b ); \ + int fwl_c = sc_max( a.wl() - iwl_a, b.wl() - iwl_b ); \ + sc_fix_fast c( iwl_c + fwl_c, iwl_c ); \ + for( int i = -fwl_c; i < iwl_c; ++ i ) \ + c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \ + return sc_fix_fast( c, iwl_c + fwl_c, iwl_c ); \ +} + +DEFN_BIN_OP_T(&,&&,sc_fix_fast,sc_fix_fast) +DEFN_BIN_OP_T(|,||,sc_fix_fast,sc_fix_fast) +DEFN_BIN_OP_T(^,!=,sc_fix_fast,sc_fix_fast) + +#undef DEFN_BIN_OP_T + + +// binary bitwise functions + +#define DEFN_BIN_FNC_T(fnc,op2,tp1,tp2) \ +inline \ +void \ +fnc ( sc_fix_fast& c, const tp1& a, const tp2& b ) \ +{ \ + a.observer_read(); \ + b.observer_read(); \ + int iwl_c = c.iwl(); \ + for( int i = iwl_c - c.wl(); i < iwl_c; ++ i ) \ + c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \ + c.cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) \ +} + +DEFN_BIN_FNC_T(b_and,&&,sc_fix_fast,sc_fix_fast) +DEFN_BIN_FNC_T(b_or,||,sc_fix_fast,sc_fix_fast) +DEFN_BIN_FNC_T(b_xor,!=,sc_fix_fast,sc_fix_fast) + +#undef DEFN_BIN_FNC_T + + +// assignment operators + +inline +sc_fix_fast& +sc_fix_fast::operator = ( const sc_fix_fast& a ) +{ + sc_fxnum_fast::operator = ( a ); + return *this; +} + +#define DEFN_ASN_OP_T(op,tp) \ +inline \ +sc_fix_fast& \ +sc_fix_fast::operator op ( tp a ) \ +{ \ + sc_fxnum_fast::operator op( a ); \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op) \ +DEFN_ASN_OP_T(op,int64) \ +DEFN_ASN_OP_T(op,uint64) \ +DEFN_ASN_OP_T(op,const sc_int_base&) \ +DEFN_ASN_OP_T(op,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,const sc_signed&) \ +DEFN_ASN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op) +#endif + +#define DEFN_ASN_OP(op) \ +DEFN_ASN_OP_T(op,int) \ +DEFN_ASN_OP_T(op,unsigned int) \ +DEFN_ASN_OP_T(op,long) \ +DEFN_ASN_OP_T(op,unsigned long) \ +DEFN_ASN_OP_T(op,float) \ +DEFN_ASN_OP_T(op,double) \ +DEFN_ASN_OP_T(op,const char*) \ +DEFN_ASN_OP_T(op,const sc_fxval&) \ +DEFN_ASN_OP_T(op,const sc_fxval_fast&) \ +DEFN_ASN_OP_T(op,const sc_fxnum&) \ +DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \ +DEFN_ASN_OP_OTHER(op) + +DEFN_ASN_OP(=) + +DEFN_ASN_OP(*=) +DEFN_ASN_OP(/=) +DEFN_ASN_OP(+=) +DEFN_ASN_OP(-=) + +DEFN_ASN_OP_T(<<=,int) +DEFN_ASN_OP_T(>>=,int) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +#define DEFN_ASN_OP_T(op,op2,tp) \ +inline \ +sc_fix_fast& \ +sc_fix_fast::operator op ( const tp& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) \ + b.observer_read(); \ + int iwl_c = iwl(); \ + for( int i = iwl_c - wl(); i < iwl_c; ++ i ) \ + set_bit( i, get_bit( i ) op2 b.get_bit( i ) ); \ + cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +DEFN_ASN_OP_T(&=,&&,sc_fix) +DEFN_ASN_OP_T(&=,&&,sc_fix_fast) +DEFN_ASN_OP_T(|=,||,sc_fix) +DEFN_ASN_OP_T(|=,||,sc_fix_fast) +DEFN_ASN_OP_T(^=,!=,sc_fix) +DEFN_ASN_OP_T(^=,!=,sc_fix_fast) + +#undef DEFN_ASN_OP_T + + +// auto-increment and auto-decrement + +inline +const sc_fxval_fast +sc_fix_fast::operator ++ ( int ) +{ + return sc_fxval_fast( sc_fxnum_fast::operator ++ ( 0 ) ); +} + +inline +const sc_fxval_fast +sc_fix_fast::operator -- ( int ) +{ + return sc_fxval_fast( sc_fxnum_fast::operator -- ( 0 ) ); +} + +inline +sc_fix_fast& +sc_fix_fast::operator ++ () +{ + sc_fxnum_fast::operator ++ (); + return *this; +} + +inline +sc_fix_fast& +sc_fix_fast::operator -- () +{ + sc_fxnum_fast::operator -- (); + return *this; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fixed.h b/ext/systemc/src/sysc/datatypes/fx/sc_fixed.h new file mode 100644 index 000000000..b885da1f9 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fixed.h @@ -0,0 +1,660 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fixed.h - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_fixed.h,v $ +// Revision 1.2 2011/01/19 18:57:40 acg +// Andy Goodrich: changes for IEEE_1666_2011. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:57 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_FIXED_H +#define SC_FIXED_H + + +#include "sysc/datatypes/fx/sc_fix.h" + + +namespace sc_dt +{ + +// classes defined in this module +template <int W, int I, sc_q_mode Q, sc_o_mode O, int N> class sc_fixed; +template <int W, int I, sc_q_mode Q, sc_o_mode O, int N> class sc_fixed_fast; + + +// ---------------------------------------------------------------------------- +// TEMPLATE CLASS : sc_fixed +// +// "Constrained" signed fixed-point class; arbitrary precision. +// ---------------------------------------------------------------------------- + +template <int W, int I, + sc_q_mode Q = SC_DEFAULT_Q_MODE_, + sc_o_mode O = SC_DEFAULT_O_MODE_, int N = SC_DEFAULT_N_BITS_> +class sc_fixed : public sc_fix +{ + +public: + + // constructors + + explicit sc_fixed( sc_fxnum_observer* = 0 ); + explicit sc_fixed( const sc_fxcast_switch&, sc_fxnum_observer* = 0 ); + +#define DECL_CTORS_T_A(tp) \ + sc_fixed( tp, sc_fxnum_observer* = 0 ); \ + sc_fixed( tp, const sc_fxcast_switch&, sc_fxnum_observer* = 0 ); + +#define DECL_CTORS_T_B(tp) \ + explicit sc_fixed( tp, sc_fxnum_observer* = 0 ); \ + sc_fixed( tp, const sc_fxcast_switch&, sc_fxnum_observer* = 0 ); + + DECL_CTORS_T_A(int) + DECL_CTORS_T_A(unsigned int) + DECL_CTORS_T_A(long) + DECL_CTORS_T_A(unsigned long) + DECL_CTORS_T_A(float) + DECL_CTORS_T_A(double) + DECL_CTORS_T_A(const char*) + DECL_CTORS_T_A(const sc_fxval&) + DECL_CTORS_T_A(const sc_fxval_fast&) + DECL_CTORS_T_A(const sc_fxnum&) + DECL_CTORS_T_A(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_CTORS_T_B(int64) + DECL_CTORS_T_B(uint64) + DECL_CTORS_T_B(const sc_int_base&) + DECL_CTORS_T_B(const sc_uint_base&) + DECL_CTORS_T_B(const sc_signed&) + DECL_CTORS_T_B(const sc_unsigned&) +#endif + +#undef DECL_CTORS_T_A +#undef DECL_CTORS_T_B + + // copy constructor + + sc_fixed( const sc_fixed<W,I,Q,O,N>& ); + + + // assignment operators + + sc_fixed& operator = ( const sc_fixed<W,I,Q,O,N>& ); + +#define DECL_ASN_OP_T(op,tp) \ + sc_fixed& operator op ( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + + DECL_ASN_OP_T(&=,const sc_fix&) + DECL_ASN_OP_T(&=,const sc_fix_fast&) + DECL_ASN_OP_T(|=,const sc_fix&) + DECL_ASN_OP_T(|=,const sc_fix_fast&) + DECL_ASN_OP_T(^=,const sc_fix&) + DECL_ASN_OP_T(^=,const sc_fix_fast&) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval operator ++ ( int ); + const sc_fxval operator -- ( int ); + + sc_fixed& operator ++ (); + sc_fixed& operator -- (); + +}; + + +// ---------------------------------------------------------------------------- +// TEMPLATE CLASS : sc_fixed_fast +// +// "Constrained" signed fixed-point class; limited precision. +// ---------------------------------------------------------------------------- + +template <int W, int I, + sc_q_mode Q = SC_DEFAULT_Q_MODE_, + sc_o_mode O = SC_DEFAULT_O_MODE_, int N = SC_DEFAULT_N_BITS_> +class sc_fixed_fast : public sc_fix_fast +{ + +public: + + // constructors + + explicit sc_fixed_fast( sc_fxnum_fast_observer* = 0 ); + explicit sc_fixed_fast( const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + +#define DECL_CTORS_T_A(tp) \ + sc_fixed_fast( tp, sc_fxnum_fast_observer* = 0 ); \ + sc_fixed_fast( tp, const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); + +#define DECL_CTORS_T_B(tp) \ + explicit sc_fixed_fast( tp, sc_fxnum_fast_observer* = 0 ); \ + sc_fixed_fast( tp, const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); + + DECL_CTORS_T_A(int) + DECL_CTORS_T_A(unsigned int) + DECL_CTORS_T_A(long) + DECL_CTORS_T_A(unsigned long) + DECL_CTORS_T_A(float) + DECL_CTORS_T_A(double) + DECL_CTORS_T_A(const char*) + DECL_CTORS_T_A(const sc_fxval&) + DECL_CTORS_T_A(const sc_fxval_fast&) + DECL_CTORS_T_A(const sc_fxnum&) + DECL_CTORS_T_A(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_CTORS_T_B(int64) + DECL_CTORS_T_B(uint64) + DECL_CTORS_T_B(const sc_int_base&) + DECL_CTORS_T_B(const sc_uint_base&) + DECL_CTORS_T_B(const sc_signed&) + DECL_CTORS_T_B(const sc_unsigned&) +#endif + +#undef DECL_CTORS_T_A +#undef DECL_CTORS_T_B + + // copy constructor + + sc_fixed_fast( const sc_fixed_fast<W,I,Q,O,N>& ); + + + // assignment operators + + sc_fixed_fast& operator = ( const sc_fixed_fast<W,I,Q,O,N>& ); + +#define DECL_ASN_OP_T(op,tp) \ + sc_fixed_fast& operator op ( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + + DECL_ASN_OP_T(&=,const sc_fix&) + DECL_ASN_OP_T(&=,const sc_fix_fast&) + DECL_ASN_OP_T(|=,const sc_fix&) + DECL_ASN_OP_T(|=,const sc_fix_fast&) + DECL_ASN_OP_T(^=,const sc_fix&) + DECL_ASN_OP_T(^=,const sc_fix_fast&) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval_fast operator ++ ( int ); + const sc_fxval_fast operator -- ( int ); + + sc_fixed_fast& operator ++ (); + sc_fixed_fast& operator -- (); + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// ---------------------------------------------------------------------------- +// TEMPLATE CLASS : sc_fixed +// +// "Constrained" signed fixed-point class; arbitrary precision. +// ---------------------------------------------------------------------------- + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed<W,I,Q,O,N>::sc_fixed( sc_fxnum_observer* observer_ ) +: sc_fix( W, I, Q, O, N, observer_ ) +{} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed<W,I,Q,O,N>::sc_fixed( const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fix( W, I, Q, O, N, cast_sw, observer_ ) +{} + +#define DEFN_CTORS_T(tp) \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_fixed<W,I,Q,O,N>::sc_fixed( tp a, \ + sc_fxnum_observer* observer_ ) \ +: sc_fix( a, W, I, Q, O, N, observer_ ) \ +{} \ + \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_fixed<W,I,Q,O,N>::sc_fixed( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fix( a, W, I, Q, O, N, cast_sw, observer_ ) \ +{} + +DEFN_CTORS_T(int) +DEFN_CTORS_T(unsigned int) +DEFN_CTORS_T(long) +DEFN_CTORS_T(unsigned long) +DEFN_CTORS_T(float) +DEFN_CTORS_T(double) +DEFN_CTORS_T(const char*) +DEFN_CTORS_T(const sc_fxval&) +DEFN_CTORS_T(const sc_fxval_fast&) +DEFN_CTORS_T(const sc_fxnum&) +DEFN_CTORS_T(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTORS_T(int64) +DEFN_CTORS_T(uint64) +DEFN_CTORS_T(const sc_int_base&) +DEFN_CTORS_T(const sc_uint_base&) +DEFN_CTORS_T(const sc_signed&) +DEFN_CTORS_T(const sc_unsigned&) +#endif + +#undef DEFN_CTORS_T + +// copy constructor + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed<W,I,Q,O,N>::sc_fixed( const sc_fixed<W,I,Q,O,N>& a ) +: sc_fix( a, W, I, Q, O, N ) +{} + + +// assignment operators + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed<W,I,Q,O,N>& +sc_fixed<W,I,Q,O,N>::operator = ( const sc_fixed<W,I,Q,O,N>& a ) +{ + sc_fix::operator = ( a ); + return *this; +} + +#define DEFN_ASN_OP_T(op,tp) \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_fixed<W,I,Q,O,N>& \ +sc_fixed<W,I,Q,O,N>::operator op ( tp a ) \ +{ \ + sc_fix::operator op ( a ); \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op) \ +DEFN_ASN_OP_T(op,int64) \ +DEFN_ASN_OP_T(op,uint64) \ +DEFN_ASN_OP_T(op,const sc_int_base&) \ +DEFN_ASN_OP_T(op,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,const sc_signed&) \ +DEFN_ASN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op) +#endif + +#define DEFN_ASN_OP(op) \ +DEFN_ASN_OP_T(op,int) \ +DEFN_ASN_OP_T(op,unsigned int) \ +DEFN_ASN_OP_T(op,long) \ +DEFN_ASN_OP_T(op,unsigned long) \ +DEFN_ASN_OP_T(op,float) \ +DEFN_ASN_OP_T(op,double) \ +DEFN_ASN_OP_T(op,const char*) \ +DEFN_ASN_OP_T(op,const sc_fxval&) \ +DEFN_ASN_OP_T(op,const sc_fxval_fast&) \ +DEFN_ASN_OP_T(op,const sc_fxnum&) \ +DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \ +DEFN_ASN_OP_OTHER(op) + +DEFN_ASN_OP(=) + +DEFN_ASN_OP(*=) +DEFN_ASN_OP(/=) +DEFN_ASN_OP(+=) +DEFN_ASN_OP(-=) + +DEFN_ASN_OP_T(<<=,int) +DEFN_ASN_OP_T(>>=,int) + +DEFN_ASN_OP_T(&=,const sc_fix&) +DEFN_ASN_OP_T(&=,const sc_fix_fast&) +DEFN_ASN_OP_T(|=,const sc_fix&) +DEFN_ASN_OP_T(|=,const sc_fix_fast&) +DEFN_ASN_OP_T(^=,const sc_fix&) +DEFN_ASN_OP_T(^=,const sc_fix_fast&) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +// auto-increment and auto-decrement + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +const sc_fxval +sc_fixed<W,I,Q,O,N>::operator ++ ( int ) +{ + return sc_fxval( sc_fix::operator ++ ( 0 ) ); +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +const sc_fxval +sc_fixed<W,I,Q,O,N>::operator -- ( int ) +{ + return sc_fxval( sc_fix::operator -- ( 0 ) ); +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed<W,I,Q,O,N>& +sc_fixed<W,I,Q,O,N>::operator ++ () +{ + sc_fix::operator ++ (); + return *this; +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed<W,I,Q,O,N>& +sc_fixed<W,I,Q,O,N>::operator -- () +{ + sc_fix::operator -- (); + return *this; +} + + +// ---------------------------------------------------------------------------- +// TEMPLATE CLASS : sc_fixed_fast +// +// "Constrained" signed fixed-point class; limited precision. +// ---------------------------------------------------------------------------- + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed_fast<W,I,Q,O,N>::sc_fixed_fast( sc_fxnum_fast_observer* observer_ ) +: sc_fix_fast( W, I, Q, O, N, observer_ ) +{} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed_fast<W,I,Q,O,N>::sc_fixed_fast( const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fix_fast( W, I, Q, O, N, cast_sw, observer_ ) +{} + +#define DEFN_CTORS_T(tp) \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_fixed_fast<W,I,Q,O,N>::sc_fixed_fast( tp a, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fix_fast( a, W, I, Q, O, N, observer_ ) \ +{} \ + \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_fixed_fast<W,I,Q,O,N>::sc_fixed_fast( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fix_fast( a, W, I, Q, O, N, cast_sw, observer_ ) \ +{} + +DEFN_CTORS_T(int) +DEFN_CTORS_T(unsigned int) +DEFN_CTORS_T(long) +DEFN_CTORS_T(unsigned long) +DEFN_CTORS_T(float) +DEFN_CTORS_T(double) +DEFN_CTORS_T(const char*) +DEFN_CTORS_T(const sc_fxval&) +DEFN_CTORS_T(const sc_fxval_fast&) +DEFN_CTORS_T(const sc_fxnum&) +DEFN_CTORS_T(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTORS_T(int64) +DEFN_CTORS_T(uint64) +DEFN_CTORS_T(const sc_int_base&) +DEFN_CTORS_T(const sc_uint_base&) +DEFN_CTORS_T(const sc_signed&) +DEFN_CTORS_T(const sc_unsigned&) +#endif + +#undef DEFN_CTORS_T + +// copy constructor + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed_fast<W,I,Q,O,N>::sc_fixed_fast( const sc_fixed_fast<W,I,Q,O,N>& a ) +: sc_fix_fast( a, W, I, Q, O, N ) +{} + + +// assignment operators + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed_fast<W,I,Q,O,N>& +sc_fixed_fast<W,I,Q,O,N>::operator = ( const sc_fixed_fast<W,I,Q,O,N>& a ) +{ + sc_fix_fast::operator = ( a ); + return *this; +} + +#define DEFN_ASN_OP_T(op,tp) \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_fixed_fast<W,I,Q,O,N>& \ +sc_fixed_fast<W,I,Q,O,N>::operator op ( tp a ) \ +{ \ + sc_fix_fast::operator op ( a ); \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op) \ +DEFN_ASN_OP_T(op,int64) \ +DEFN_ASN_OP_T(op,uint64) \ +DEFN_ASN_OP_T(op,const sc_int_base&) \ +DEFN_ASN_OP_T(op,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,const sc_signed&) \ +DEFN_ASN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op) +#endif + +#define DEFN_ASN_OP(op) \ +DEFN_ASN_OP_T(op,int) \ +DEFN_ASN_OP_T(op,unsigned int) \ +DEFN_ASN_OP_T(op,long) \ +DEFN_ASN_OP_T(op,unsigned long) \ +DEFN_ASN_OP_T(op,float) \ +DEFN_ASN_OP_T(op,double) \ +DEFN_ASN_OP_T(op,const char*) \ +DEFN_ASN_OP_T(op,const sc_fxval&) \ +DEFN_ASN_OP_T(op,const sc_fxval_fast&) \ +DEFN_ASN_OP_T(op,const sc_fxnum&) \ +DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \ +DEFN_ASN_OP_OTHER(op) + +DEFN_ASN_OP(=) + +DEFN_ASN_OP(*=) +DEFN_ASN_OP(/=) +DEFN_ASN_OP(+=) +DEFN_ASN_OP(-=) + +DEFN_ASN_OP_T(<<=,int) +DEFN_ASN_OP_T(>>=,int) + +DEFN_ASN_OP_T(&=,const sc_fix&) +DEFN_ASN_OP_T(&=,const sc_fix_fast&) +DEFN_ASN_OP_T(|=,const sc_fix&) +DEFN_ASN_OP_T(|=,const sc_fix_fast&) +DEFN_ASN_OP_T(^=,const sc_fix&) +DEFN_ASN_OP_T(^=,const sc_fix_fast&) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +// auto-increment and auto-decrement + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +const sc_fxval_fast +sc_fixed_fast<W,I,Q,O,N>::operator ++ ( int ) +{ + return sc_fxval_fast( sc_fix_fast::operator ++ ( 0 ) ); +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +const sc_fxval_fast +sc_fixed_fast<W,I,Q,O,N>::operator -- ( int ) +{ + return sc_fxval_fast( sc_fix_fast::operator -- ( 0 ) ); +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed_fast<W,I,Q,O,N>& +sc_fixed_fast<W,I,Q,O,N>::operator ++ () +{ + sc_fix_fast::operator ++ (); + return *this; +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed_fast<W,I,Q,O,N>& +sc_fixed_fast<W,I,Q,O,N>::operator -- () +{ + sc_fix_fast::operator -- (); + return *this; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fx_ids.h b/ext/systemc/src/sysc/datatypes/fx/sc_fx_ids.h new file mode 100644 index 000000000..b40c2dc48 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fx_ids.h @@ -0,0 +1,96 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fx_ids.h -- Report ids for the datatypes/fx code. + + Original Author: Martin Janssen, Synopsys, Inc., 2002-01-17 + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_fx_ids.h,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:57 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_FX_IDS_H +#define SC_FX_IDS_H + + +#include "sysc/utils/sc_report.h" + + +// ---------------------------------------------------------------------------- +// Report ids (datatypes/fx) +// +// Report ids in the range of 300-399. +// ---------------------------------------------------------------------------- + +#ifndef SC_DEFINE_MESSAGE +#define SC_DEFINE_MESSAGE(id,unused1,unused2) \ + namespace sc_core { extern const char id[]; } +namespace sc_core { + extern const char SC_ID_REGISTER_ID_FAILED_[]; // in sc_report_handler.cpp +} +#endif + + +SC_DEFINE_MESSAGE( SC_ID_INVALID_WL_, 300, + "total wordlength <= 0 is not valid" ) +SC_DEFINE_MESSAGE( SC_ID_INVALID_N_BITS_, 301, + "number of bits < 0 is not valid" ) +SC_DEFINE_MESSAGE( SC_ID_INVALID_DIV_WL_, 302, + "division wordlength <= 0 is not valid" ) +SC_DEFINE_MESSAGE( SC_ID_INVALID_CTE_WL_, 303, + "constant wordlength <= 0 is not valid" ) +SC_DEFINE_MESSAGE( SC_ID_INVALID_MAX_WL_, 304, + "maximum wordlength <= 0 and != -1 is not valid" ) +SC_DEFINE_MESSAGE( SC_ID_INVALID_FX_VALUE_, 305, + "invalid fixed-point value" ) +SC_DEFINE_MESSAGE( SC_ID_INVALID_O_MODE_, 306, + "invalid overflow mode" ) +SC_DEFINE_MESSAGE( SC_ID_OUT_OF_RANGE_, 307, + "index out of range" ) +SC_DEFINE_MESSAGE( SC_ID_CONTEXT_BEGIN_FAILED_, 308, + "context begin failed" ) +SC_DEFINE_MESSAGE( SC_ID_CONTEXT_END_FAILED_, 309, + "context end failed" ) +SC_DEFINE_MESSAGE( SC_ID_WRAP_SM_NOT_DEFINED_, 310, + "SC_WRAP_SM not defined for unsigned numbers" ) + + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxcast_switch.cpp b/ext/systemc/src/sysc/datatypes/fx/sc_fxcast_switch.cpp new file mode 100644 index 000000000..c5c5a939c --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxcast_switch.cpp @@ -0,0 +1,88 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxcast_switch.cpp - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: Gene Bushuyev, Synopsys, Inc. + Description of Modification: - fix explicit instantiation syntax. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_fxcast_switch.cpp,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:57 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#include "sysc/datatypes/fx/sc_fxcast_switch.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxcast_switch +// +// Fixed-point cast switch class. +// ---------------------------------------------------------------------------- + +const std::string +sc_fxcast_switch::to_string() const +{ + return sc_dt::to_string( m_sw ); +} + + +void +sc_fxcast_switch::print( ::std::ostream& os ) const +{ + os << sc_dt::to_string( m_sw ); +} + +void +sc_fxcast_switch::dump( ::std::ostream& os ) const +{ + os << "sc_fxcast_switch" << ::std::endl; + os << "(" << ::std::endl; + os << "sw = " << sc_dt::to_string( m_sw ) << ::std::endl; + os << ")" << ::std::endl; +} + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxcast_switch.h b/ext/systemc/src/sysc/datatypes/fx/sc_fxcast_switch.h new file mode 100644 index 000000000..6bfbd25a4 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxcast_switch.h @@ -0,0 +1,174 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxcast_switch.h - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_fxcast_switch.h,v $ +// Revision 1.2 2011/08/24 22:05:43 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:57 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_FXCAST_SWITCH_H +#define SC_FXCAST_SWITCH_H + + +#include "sysc/datatypes/fx/sc_context.h" + + +namespace sc_dt +{ + +// classes defined in this module +class sc_fxcast_switch; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxcast_switch +// +// Fixed-point cast switch class. +// ---------------------------------------------------------------------------- + +class sc_fxcast_switch +{ + +public: + + sc_fxcast_switch(); + sc_fxcast_switch( sc_switch ); + sc_fxcast_switch( const sc_fxcast_switch& ); + explicit sc_fxcast_switch( sc_without_context ); + + sc_fxcast_switch& operator = ( const sc_fxcast_switch& ); + + friend bool operator == ( const sc_fxcast_switch&, + const sc_fxcast_switch& ); + friend bool operator != ( const sc_fxcast_switch&, + const sc_fxcast_switch& ); + + const std::string to_string() const; + + void print( ::std::ostream& = ::std::cout ) const; + void dump( ::std::ostream& = ::std::cout ) const; + +private: + + sc_switch m_sw; + +}; + + +// ---------------------------------------------------------------------------- +// TYPEDEF : sc_fxcast_context +// +// Context type for the fixed-point cast switch parameter. +// ---------------------------------------------------------------------------- + +typedef sc_context<sc_fxcast_switch> sc_fxcast_context; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +inline +sc_fxcast_switch::sc_fxcast_switch() +: m_sw() +{ + *this = sc_fxcast_context::default_value(); +} + +inline +sc_fxcast_switch::sc_fxcast_switch( sc_switch sw_ ) +: m_sw( sw_ ) +{} + +inline +sc_fxcast_switch::sc_fxcast_switch( const sc_fxcast_switch& a ) +: m_sw( a.m_sw ) +{} + +inline +sc_fxcast_switch::sc_fxcast_switch( sc_without_context ) +: m_sw( SC_DEFAULT_CAST_SWITCH_ ) +{} + + +inline +sc_fxcast_switch& +sc_fxcast_switch::operator = ( const sc_fxcast_switch& a ) +{ + if( &a != this ) + { + m_sw = a.m_sw; + } + return *this; +} + + +inline +bool +operator == ( const sc_fxcast_switch& a, const sc_fxcast_switch& b ) +{ + return ( a.m_sw == b.m_sw ); +} + + +inline +bool +operator != ( const sc_fxcast_switch& a, const sc_fxcast_switch& b ) +{ + return ( a.m_sw != b.m_sw ); +} + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_fxcast_switch& a ) +{ + a.print( os ); + return os; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxdefs.cpp b/ext/systemc/src/sysc/datatypes/fx/sc_fxdefs.cpp new file mode 100644 index 000000000..66ade2076 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxdefs.cpp @@ -0,0 +1,175 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxdefs.cpp - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_fxdefs.cpp,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:57 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#include "sysc/datatypes/fx/sc_fxdefs.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// ENUM : sc_enc +// +// Enumeration of sign encodings. +// ---------------------------------------------------------------------------- + +const std::string +to_string( sc_enc enc ) +{ + switch( enc ) + { + case SC_TC_: + return std::string( "SC_TC_" ); + case SC_US_: + return std::string( "SC_US_" ); + default: + return std::string( "unknown" ); + } +} + + +// ---------------------------------------------------------------------------- +// ENUM : sc_q_mode +// +// Enumeration of quantization modes. +// ---------------------------------------------------------------------------- + +const std::string +to_string( sc_q_mode q_mode ) +{ + switch( q_mode ) + { + case SC_RND: + return std::string( "SC_RND" ); + case SC_RND_ZERO: + return std::string( "SC_RND_ZERO" ); + case SC_RND_MIN_INF: + return std::string( "SC_RND_MIN_INF" ); + case SC_RND_INF: + return std::string( "SC_RND_INF" ); + case SC_RND_CONV: + return std::string( "SC_RND_CONV" ); + case SC_TRN: + return std::string( "SC_TRN" ); + case SC_TRN_ZERO: + return std::string( "SC_TRN_ZERO" ); + default: + return std::string( "unknown" ); + } +} + + +// ---------------------------------------------------------------------------- +// ENUM : sc_o_mode +// +// Enumeration of overflow modes. +// ---------------------------------------------------------------------------- + +const std::string +to_string( sc_o_mode o_mode ) +{ + switch( o_mode ) + { + case SC_SAT: + return std::string( "SC_SAT" ); + case SC_SAT_ZERO: + return std::string( "SC_SAT_ZERO" ); + case SC_SAT_SYM: + return std::string( "SC_SAT_SYM" ); + case SC_WRAP: + return std::string( "SC_WRAP" ); + case SC_WRAP_SM: + return std::string( "SC_WRAP_SM" ); + default: + return std::string( "unknown" ); + } +} + + +// ---------------------------------------------------------------------------- +// ENUM : sc_switch +// +// Enumeration of switch states. +// ---------------------------------------------------------------------------- + +const std::string +to_string( sc_switch sw ) +{ + switch( sw ) { + case SC_OFF: + return std::string( "SC_OFF" ); + case SC_ON: + return std::string( "SC_ON" ); + default: + return std::string( "unknown" ); + } +} + + +// ---------------------------------------------------------------------------- +// ENUM : sc_fmt +// +// Enumeration of formats for character string conversion. +// ---------------------------------------------------------------------------- + +const std::string +to_string( sc_fmt fmt ) +{ + switch( fmt ) { + case SC_F: + return std::string( "SC_F" ); + case SC_E: + return std::string( "SC_E" ); + default: + return std::string( "unknown" ); + } +} + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxdefs.h b/ext/systemc/src/sysc/datatypes/fx/sc_fxdefs.h new file mode 100644 index 000000000..1ac1bb707 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxdefs.h @@ -0,0 +1,308 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxdefs.h - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_fxdefs.h,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:57 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_FXDEFS_H +#define SC_FXDEFS_H + + +#include "sysc/utils/sc_machine.h" +#include "sysc/datatypes/fx/sc_fx_ids.h" +#include "sysc/datatypes/int/sc_nbutils.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// ENUM : sc_enc +// +// Enumeration of sign encodings. +// ---------------------------------------------------------------------------- + +enum sc_enc +{ + SC_TC_, // two's complement + SC_US_ // unsigned +}; + + +const std::string to_string( sc_enc ); + + +inline +::std::ostream& +operator << ( ::std::ostream& os, sc_enc enc ) +{ + return os << to_string( enc ); +} + + +// ---------------------------------------------------------------------------- +// ENUM : sc_q_mode +// +// Enumeration of quantization modes. +// ---------------------------------------------------------------------------- + +enum sc_q_mode +{ + SC_RND, // rounding to plus infinity + SC_RND_ZERO, // rounding to zero + SC_RND_MIN_INF, // rounding to minus infinity + SC_RND_INF, // rounding to infinity + SC_RND_CONV, // convergent rounding + SC_TRN, // truncation + SC_TRN_ZERO // truncation to zero +}; + + +const std::string to_string( sc_q_mode ); + + +inline +::std::ostream& +operator << ( ::std::ostream& os, sc_q_mode q_mode ) +{ + return os << to_string( q_mode ); +} + + +// ---------------------------------------------------------------------------- +// ENUM : sc_o_mode +// +// Enumeration of overflow modes. +// ---------------------------------------------------------------------------- + +enum sc_o_mode +{ + SC_SAT, // saturation + SC_SAT_ZERO, // saturation to zero + SC_SAT_SYM, // symmetrical saturation + SC_WRAP, // wrap-around (*) + SC_WRAP_SM // sign magnitude wrap-around (*) +}; + +// (*) uses the number of saturated bits argument, see the documentation. + + +const std::string to_string( sc_o_mode ); + + +inline +::std::ostream& +operator << ( ::std::ostream& os, sc_o_mode o_mode ) +{ + return os << to_string( o_mode ); +} + + +// ---------------------------------------------------------------------------- +// ENUM : sc_switch +// +// Enumeration of switch states. +// ---------------------------------------------------------------------------- + +enum sc_switch +{ + SC_OFF, + SC_ON +}; + + +const std::string to_string( sc_switch ); + + +inline +::std::ostream& +operator << ( ::std::ostream& os, sc_switch sw ) +{ + return os << to_string( sw ); +} + + +// ---------------------------------------------------------------------------- +// ENUM : sc_fmt +// +// Enumeration of formats for character string conversion. +// ---------------------------------------------------------------------------- + +enum sc_fmt +{ + SC_F, // fixed + SC_E // scientific +}; + + +const std::string to_string( sc_fmt ); + + +inline +::std::ostream& +operator << ( ::std::ostream& os, sc_fmt fmt ) +{ + return os << to_string( fmt ); +} + + +// ---------------------------------------------------------------------------- +// Built-in & default fixed-point type parameter values. +// ---------------------------------------------------------------------------- + +const int SC_BUILTIN_WL_ = 32; +const int SC_BUILTIN_IWL_ = 32; +const sc_q_mode SC_BUILTIN_Q_MODE_ = SC_TRN; +const sc_o_mode SC_BUILTIN_O_MODE_ = SC_WRAP; +const int SC_BUILTIN_N_BITS_ = 0; + + +const int SC_DEFAULT_WL_ = SC_BUILTIN_WL_; +const int SC_DEFAULT_IWL_ = SC_BUILTIN_IWL_; +const sc_q_mode SC_DEFAULT_Q_MODE_ = SC_BUILTIN_Q_MODE_; +const sc_o_mode SC_DEFAULT_O_MODE_ = SC_BUILTIN_O_MODE_; +const int SC_DEFAULT_N_BITS_ = SC_BUILTIN_N_BITS_; + + +// ---------------------------------------------------------------------------- +// Built-in & default fixed-point cast switch parameter values. +// ---------------------------------------------------------------------------- + +const sc_switch SC_BUILTIN_CAST_SWITCH_ = SC_ON; + + +const sc_switch SC_DEFAULT_CAST_SWITCH_ = SC_BUILTIN_CAST_SWITCH_; + + +// ---------------------------------------------------------------------------- +// Built-in & default fixed-point value type parameter values. +// ---------------------------------------------------------------------------- + +const int SC_BUILTIN_DIV_WL_ = 64; +const int SC_BUILTIN_CTE_WL_ = 64; +const int SC_BUILTIN_MAX_WL_ = 1024; + + +#if defined( SC_FXDIV_WL ) && ( SC_FXDIV_WL > 0 ) +const int SC_DEFAULT_DIV_WL_ = SC_FXDIV_WL; +#else +const int SC_DEFAULT_DIV_WL_ = SC_BUILTIN_DIV_WL_; +#endif + +#if defined( SC_FXCTE_WL ) && ( SC_FXCTE_WL > 0 ) +const int SC_DEFAULT_CTE_WL_ = SC_FXCTE_WL; +#else +const int SC_DEFAULT_CTE_WL_ = SC_BUILTIN_CTE_WL_; +#endif + +#if defined( SC_FXMAX_WL ) && ( SC_FXMAX_WL > 0 || SC_FXMAX_WL == -1 ) +const int SC_DEFAULT_MAX_WL_ = SC_FXMAX_WL; +#else +const int SC_DEFAULT_MAX_WL_ = SC_BUILTIN_MAX_WL_; +#endif + + +// ---------------------------------------------------------------------------- +// Dedicated error reporting and checking. +// ---------------------------------------------------------------------------- + +#ifdef DEBUG_SYSTEMC +#define SC_ASSERT_(cnd,msg) \ +{ \ + if( ! (cnd) ) \ + SC_REPORT_ERROR( sc_core::SC_ID_INTERNAL_ERROR_, msg ); \ +} +#else +#define SC_ASSERT_(cnd,msg) +#endif + +#define SC_ERROR_IF_(cnd,id) \ +{ \ + if( cnd ) \ + SC_REPORT_ERROR( id, 0 ); \ +} + + +#define SC_CHECK_WL_(wl) \ + SC_ERROR_IF_( (wl) <= 0, sc_core::SC_ID_INVALID_WL_ ) + +#define SC_CHECK_N_BITS_(n_bits) \ + SC_ERROR_IF_( (n_bits) < 0, sc_core::SC_ID_INVALID_N_BITS_ ) + +#define SC_CHECK_DIV_WL_(div_wl) \ + SC_ERROR_IF_( (div_wl) <= 0, sc_core::SC_ID_INVALID_DIV_WL_ ) + +#define SC_CHECK_CTE_WL_(cte_wl) \ + SC_ERROR_IF_( (cte_wl) <= 0, sc_core::SC_ID_INVALID_CTE_WL_ ) + +#define SC_CHECK_MAX_WL_(max_wl) \ + SC_ERROR_IF_( (max_wl) <= 0 && (max_wl) != -1, \ + sc_core::SC_ID_INVALID_MAX_WL_ ) + + +// ---------------------------------------------------------------------------- +// Generic observer macros. +// ---------------------------------------------------------------------------- + +#define SC_OBSERVER_(object,observer_type,event) \ +{ \ + if( (object).observer() != 0 ) \ + { \ + observer_type observer = (object).lock_observer(); \ + observer->event( (object) ); \ + (object).unlock_observer( observer ); \ + } \ +} + +#define SC_OBSERVER_DEFAULT_(observer_type) \ +{ \ + if( m_observer == 0 && observer_type ## ::default_observer != 0 ) \ + m_observer = (* ## observer_type ## ::default_observer)(); \ +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxnum.cpp b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum.cpp new file mode 100644 index 000000000..520c41854 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum.cpp @@ -0,0 +1,958 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxnum.cpp - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_fxnum.cpp,v $ +// Revision 1.3 2011/01/19 18:57:40 acg +// Andy Goodrich: changes for IEEE_1666_2011. +// +// Revision 1.2 2010/12/07 20:09:08 acg +// Andy Goodrich: Philipp Hartmann's constructor disambiguation fix +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:57 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#include <math.h> + +#include "sysc/datatypes/fx/sc_fxnum.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_bitref +// +// Proxy class for bit-selection in class sc_fxnum, behaves like sc_bit. +// ---------------------------------------------------------------------------- + +bool +sc_fxnum_bitref::get() const +{ + return m_num.get_bit( m_idx ); +} + +void +sc_fxnum_bitref::set( bool high ) +{ + m_num.set_bit( m_idx, high ); +} + + +// print or dump content + +void +sc_fxnum_bitref::print( ::std::ostream& os ) const +{ + os << get(); +} + +void +sc_fxnum_bitref::scan( ::std::istream& is ) +{ + bool b; + is >> b; + *this = b; +} + +void +sc_fxnum_bitref::dump( ::std::ostream& os ) const +{ + os << "sc_fxnum_bitref" << ::std::endl; + os << "(" << ::std::endl; + os << "num = "; + m_num.dump( os ); + os << "idx = " << m_idx << ::std::endl; + os << ")" << ::std::endl; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast_bitref +// +// Proxy class for bit-selection in class sc_fxnum_fast, behaves like sc_bit. +// ---------------------------------------------------------------------------- + +bool +sc_fxnum_fast_bitref::get() const +{ + return m_num.get_bit( m_idx ); +} + +void +sc_fxnum_fast_bitref::set( bool high ) +{ + m_num.set_bit( m_idx, high ); +} + + +// print or dump content + +void +sc_fxnum_fast_bitref::print( ::std::ostream& os ) const +{ + os << get(); +} + +void +sc_fxnum_fast_bitref::scan( ::std::istream& is ) +{ + bool b; + is >> b; + *this = b; +} + +void +sc_fxnum_fast_bitref::dump( ::std::ostream& os ) const +{ + os << "sc_fxnum_fast_bitref" << ::std::endl; + os << "(" << ::std::endl; + os << "num = "; + m_num.dump( os ); + os << "idx = " << m_idx << ::std::endl; + os << ")" << ::std::endl; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_subref +// +// Proxy class for part-selection in class sc_fxnum, +// behaves like sc_bv_base. +// ---------------------------------------------------------------------------- + +bool +sc_fxnum_subref::get() const +{ + return m_num.get_slice( m_from, m_to, m_bv ); +} + +bool +sc_fxnum_subref::set() +{ + return m_num.set_slice( m_from, m_to, m_bv ); +} + + +// print or dump content + +void +sc_fxnum_subref::print( ::std::ostream& os ) const +{ + get(); + m_bv.print( os ); +} + +void +sc_fxnum_subref::scan( ::std::istream& is ) +{ + m_bv.scan( is ); + set(); +} + +void +sc_fxnum_subref::dump( ::std::ostream& os ) const +{ + os << "sc_fxnum_subref" << ::std::endl; + os << "(" << ::std::endl; + os << "num = "; + m_num.dump( os ); + os << "from = " << m_from << ::std::endl; + os << "to = " << m_to << ::std::endl; + os << ")" << ::std::endl; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast_subref +// +// Proxy class for part-selection in class sc_fxnum_fast, +// behaves like sc_bv_base. +// ---------------------------------------------------------------------------- + +bool +sc_fxnum_fast_subref::get() const +{ + return m_num.get_slice( m_from, m_to, m_bv ); +} + +bool +sc_fxnum_fast_subref::set() +{ + return m_num.set_slice( m_from, m_to, m_bv ); +} + + +// print or dump content + +void +sc_fxnum_fast_subref::print( ::std::ostream& os ) const +{ + get(); + m_bv.print( os ); +} + +void +sc_fxnum_fast_subref::scan( ::std::istream& is ) +{ + m_bv.scan( is ); + set(); +} + +void +sc_fxnum_fast_subref::dump( ::std::ostream& os ) const +{ + os << "sc_fxnum_fast_subref" << ::std::endl; + os << "(" << ::std::endl; + os << "num = "; + m_num.dump( os ); + os << "from = " << m_from << ::std::endl; + os << "to = " << m_to << ::std::endl; + os << ")" << ::std::endl; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum +// +// Base class for the fixed-point types; arbitrary precision. +// ---------------------------------------------------------------------------- + +// explicit conversion to character string + +const std::string +sc_fxnum::to_string() const +{ + return std::string( m_rep->to_string( SC_DEC, -1, SC_F, &m_params ) ); +} + +const std::string +sc_fxnum::to_string( sc_numrep numrep ) const +{ + return std::string( m_rep->to_string( numrep, -1, SC_F, &m_params ) ); +} + +const std::string +sc_fxnum::to_string( sc_numrep numrep, bool w_prefix ) const +{ + return std::string( m_rep->to_string( numrep, (w_prefix ? 1 : 0), + SC_F, &m_params ) ); +} + +const std::string +sc_fxnum::to_string( sc_fmt fmt ) const +{ + return std::string( m_rep->to_string( SC_DEC, -1, fmt, &m_params ) ); +} + +const std::string +sc_fxnum::to_string( sc_numrep numrep, sc_fmt fmt ) const +{ + return std::string( m_rep->to_string( numrep, -1, fmt, &m_params ) ); +} + +const std::string +sc_fxnum::to_string( sc_numrep numrep, bool w_prefix, sc_fmt fmt ) const +{ + return std::string( m_rep->to_string( numrep, (w_prefix ? 1 : 0), + fmt, &m_params ) ); +} + + +const std::string +sc_fxnum::to_dec() const +{ + return std::string( m_rep->to_string( SC_DEC, -1, SC_F, &m_params ) ); +} + +const std::string +sc_fxnum::to_bin() const +{ + return std::string( m_rep->to_string( SC_BIN, -1, SC_F, &m_params ) ); +} + +const std::string +sc_fxnum::to_oct() const +{ + return std::string( m_rep->to_string( SC_OCT, -1, SC_F, &m_params ) ); +} + +const std::string +sc_fxnum::to_hex() const +{ + return std::string( m_rep->to_string( SC_HEX, -1, SC_F, &m_params ) ); +} + + +// print or dump content + +void +sc_fxnum::print( ::std::ostream& os ) const +{ + os << m_rep->to_string( SC_DEC, -1, SC_F, &m_params ); +} + +void +sc_fxnum::scan( ::std::istream& is ) +{ + std::string s; + is >> s; + *this = s.c_str(); +} + +void +sc_fxnum::dump( ::std::ostream& os ) const +{ + os << "sc_fxnum" << ::std::endl; + os << "(" << ::std::endl; + os << "rep = "; + m_rep->dump( os ); + os << "params = "; + m_params.dump( os ); + os << "q_flag = " << m_q_flag << ::std::endl; + os << "o_flag = " << m_o_flag << ::std::endl; + // TO BE COMPLETED + // os << "observer = "; + // if( m_observer != 0 ) + // m_observer->dump( os ); + // else + // os << "0" << ::std::endl; + os << ")" << ::std::endl; +} + + +sc_fxnum_observer* +sc_fxnum::lock_observer() const +{ + SC_ASSERT_( m_observer != 0, "lock observer failed" ); + sc_fxnum_observer* tmp = m_observer; + m_observer = 0; + return tmp; +} + +void +sc_fxnum::unlock_observer( sc_fxnum_observer* observer_ ) const +{ + SC_ASSERT_( observer_ != 0, "unlock observer failed" ); + m_observer = observer_; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast +// +// Base class for the fixed-point types; limited precision. +// ---------------------------------------------------------------------------- + +static +void +quantization( double& c, const scfx_params& params, bool& q_flag ) +{ + int fwl = params.wl() - params.iwl(); + double scale = scfx_pow2( fwl ); + double val = scale * c; + double int_part; + double frac_part = modf( val, &int_part ); + + q_flag = ( frac_part != 0.0 ); + + if( q_flag ) + { + val = int_part; + + switch( params.q_mode() ) + { + case SC_TRN: // truncation + { + if( c < 0.0 ) + val -= 1.0; + break; + } + case SC_RND: // rounding to plus infinity + { + if( frac_part >= 0.5 ) + val += 1.0; + else if( frac_part < -0.5 ) + val -= 1.0; + break; + } + case SC_TRN_ZERO: // truncation to zero + { + break; + } + case SC_RND_INF: // rounding to infinity + { + if( frac_part >= 0.5 ) + val += 1.0; + else if( frac_part <= -0.5 ) + val -= 1.0; + break; + } + case SC_RND_CONV: // convergent rounding + { + if( frac_part > 0.5 || + ( frac_part == 0.5 && fmod( int_part, 2.0 ) != 0.0 ) ) + val += 1.0; + else if( frac_part < -0.5 || + ( frac_part == -0.5 && fmod( int_part, 2.0 ) != 0.0 ) ) + val -= 1.0; + break; + } + case SC_RND_ZERO: // rounding to zero + { + if( frac_part > 0.5 ) + val += 1.0; + else if( frac_part < -0.5 ) + val -= 1.0; + break; + } + case SC_RND_MIN_INF: // rounding to minus infinity + { + if( frac_part > 0.5 ) + val += 1.0; + else if( frac_part <= -0.5 ) + val -= 1.0; + break; + } + default: + ; + } + } + + val /= scale; + c = val; +} + +static +void +overflow( double& c, const scfx_params& params, bool& o_flag ) +{ + int iwl = params.iwl(); + int fwl = params.wl() - iwl; + double full_circle = scfx_pow2( iwl ); + double resolution = scfx_pow2( -fwl ); + double low, high; + if( params.enc() == SC_TC_ ) + { + high = full_circle / 2.0 - resolution; + if( params.o_mode() == SC_SAT_SYM ) + low = - high; + else + low = - full_circle / 2.0; + } + else + { + low = 0.0; + high = full_circle - resolution; + } + double val = c; + sc_fxval_fast c2(c); + + bool under = ( val < low ); + bool over = ( val > high ); + + o_flag = ( under || over ); + + if( o_flag ) + { + switch( params.o_mode() ) + { + case SC_WRAP: // wrap-around + { + int n_bits = params.n_bits(); + + if( n_bits == 0 ) + { + // wrap-around all 'wl' bits + val -= floor( val / full_circle ) * full_circle; + if( val > high ) + val -= full_circle; + } + else if( n_bits < params.wl() ) + { + double X = scfx_pow2( iwl - n_bits ); + + // wrap-around least significant 'wl - n_bits' bits + val -= floor( val / X ) * X; + if( val > ( X - resolution ) ) + val -= X; + + // saturate most significant 'n_bits' bits + if( under ) + val += low; + else + { + if( params.enc() == SC_TC_ ) + val += full_circle / 2.0 - X; + else + val += full_circle - X; + } + } + else + { + // saturate all 'wl' bits + if( under ) + val = low; + else + val = high; + } + break; + } + case SC_SAT: // saturation + case SC_SAT_SYM: // symmetrical saturation + { + if( under ) + val = low; + else + val = high; + break; + } + case SC_SAT_ZERO: // saturation to zero + { + val = 0.0; + break; + } + case SC_WRAP_SM: // sign magnitude wrap-around + { + SC_ERROR_IF_( params.enc() == SC_US_, + sc_core::SC_ID_WRAP_SM_NOT_DEFINED_ ); + + int n_bits = params.n_bits(); + + if( n_bits == 0 ) + { + // invert conditionally + if( c2.get_bit( iwl ) != c2.get_bit( iwl - 1 ) ) + val = -val - resolution; + + // wrap-around all 'wl' bits + val -= floor( val / full_circle ) * full_circle; + if( val > high ) + val -= full_circle; + } + else if( n_bits == 1 ) + { + // invert conditionally + if( c2.is_neg() != c2.get_bit( iwl - 1 ) ) + val = -val - resolution; + + // wrap-around all 'wl' bits + val -= floor( val / full_circle ) * full_circle; + if( val > high ) + val -= full_circle; + } + else if( n_bits < params.wl() ) + { + // invert conditionally + if( c2.is_neg() == c2.get_bit( iwl - n_bits ) ) + val = -val - resolution; + + double X = scfx_pow2( iwl - n_bits ); + + // wrap-around least significant 'wl - n_bits' bits + val -= floor( val / X ) * X; + if( val > ( X - resolution ) ) + val -= X; + + // saturate most significant 'n_bits' bits + if( under ) + val += low; + else + val += full_circle / 2.0 - X; + } else { + // saturate all 'wl' bits + if( under ) + val = low; + else + val = high; + } + break; + } + default: + ; + } + + c = val; + } +} + + +void +sc_fxnum_fast::cast() +{ + scfx_ieee_double id( m_val ); + SC_ERROR_IF_( id.is_nan() || id.is_inf(), sc_core::SC_ID_INVALID_FX_VALUE_); + + if( m_params.cast_switch() == SC_ON ) + { + m_q_flag = false; + m_o_flag = false; + + // check for special cases + + if( id.is_zero() ) + { + if( id.negative() != 0 ) + m_val = -m_val; + return; + } + + // perform casting + + sc_dt::quantization( m_val, m_params, m_q_flag ); + sc_dt::overflow( m_val, m_params, m_o_flag ); + + // check for special case: -0 + + id = m_val; + if( id.is_zero() && id.negative() != 0 ) { + m_val = -m_val; + } + + // check for special case: NaN of Inf + + if( id.is_nan() || id.is_inf() ) { + m_val = 0.0; + } + } +} + + +// defined in sc_fxval.cpp; +extern +const char* +to_string( const scfx_ieee_double&, + sc_numrep, + int, + sc_fmt, + const scfx_params* = 0 ); + + +// explicit conversion to character string + +const std::string +sc_fxnum_fast::to_string() const +{ + return std::string( sc_dt::to_string( m_val, SC_DEC, -1, SC_F, &m_params ) ); +} + +const std::string +sc_fxnum_fast::to_string( sc_numrep numrep ) const +{ + return std::string( sc_dt::to_string( m_val, numrep, -1, SC_F, &m_params ) ); +} + +const std::string +sc_fxnum_fast::to_string( sc_numrep numrep, bool w_prefix ) const +{ + return std::string( sc_dt::to_string( m_val, numrep, (w_prefix ? 1 : 0), + SC_F, &m_params ) ); +} + +const std::string +sc_fxnum_fast::to_string( sc_fmt fmt ) const +{ + return std::string( sc_dt::to_string( m_val, SC_DEC, -1, fmt, &m_params ) ); +} + +const std::string +sc_fxnum_fast::to_string( sc_numrep numrep, sc_fmt fmt ) const +{ + return std::string( sc_dt::to_string( m_val, numrep, -1, fmt, &m_params ) ); +} + +const std::string +sc_fxnum_fast::to_string( sc_numrep numrep, bool w_prefix, sc_fmt fmt ) const +{ + return std::string( sc_dt::to_string( m_val, numrep, (w_prefix ? 1 : 0), + fmt, &m_params ) ); +} + + +const std::string +sc_fxnum_fast::to_dec() const +{ + return std::string( sc_dt::to_string( m_val, SC_DEC, -1, SC_F, &m_params ) ); +} + +const std::string +sc_fxnum_fast::to_bin() const +{ + return std::string( sc_dt::to_string( m_val, SC_BIN, -1, SC_F, &m_params ) ); +} + +const std::string +sc_fxnum_fast::to_oct() const +{ + return std::string( sc_dt::to_string( m_val, SC_OCT, -1, SC_F, &m_params ) ); +} + +const std::string +sc_fxnum_fast::to_hex() const +{ + return std::string( sc_dt::to_string( m_val, SC_HEX, -1, SC_F, &m_params ) ); +} + + +// print or dump content + +void +sc_fxnum_fast::print( ::std::ostream& os ) const +{ + os << sc_dt::to_string( m_val, SC_DEC, -1, SC_F, &m_params ); +} + +void +sc_fxnum_fast::scan( ::std::istream& is ) +{ + std::string s; + is >> s; + *this = s.c_str(); +} + +void +sc_fxnum_fast::dump( ::std::ostream& os ) const +{ + os << "sc_fxnum_fast" << ::std::endl; + os << "(" << ::std::endl; + os << "val = " << m_val << ::std::endl; + os << "params = "; + m_params.dump( os ); + os << "q_flag = " << m_q_flag << ::std::endl; + os << "o_flag = " << m_o_flag << ::std::endl; + // TO BE COMPLETED + // os << "observer = "; + // if( m_observer != 0 ) + // m_observer->dump( os ); + // else + // os << "0" << ::std::endl; + os << ")" << ::std::endl; +} + + +// internal use only; +bool +sc_fxnum_fast::get_bit( int i ) const +{ + scfx_ieee_double id( m_val ); + if( id.is_zero() || id.is_nan() || id.is_inf() ) + return false; + + // convert to two's complement + + unsigned int m0 = id.mantissa0(); + unsigned int m1 = id.mantissa1(); + + if( id.is_normal() ) + m0 += 1U << 20; + + if( id.negative() != 0 ) + { + m0 = ~ m0; + m1 = ~ m1; + unsigned int tmp = m1; + m1 += 1U; + if( m1 <= tmp ) + m0 += 1U; + } + + // get the right bit + + int j = i - id.exponent(); + if( ( j += 20 ) >= 32 ) + return ( ( m0 & 1U << 31 ) != 0 ); + else if( j >= 0 ) + return ( ( m0 & 1U << j ) != 0 ); + else if( ( j += 32 ) >= 0 ) + return ( ( m1 & 1U << j ) != 0 ); + else + return false; +} + + +bool +sc_fxnum_fast::set_bit( int i, bool high ) +{ + scfx_ieee_double id( m_val ); + if( id.is_nan() || id.is_inf() ) + return false; + + if( high ) + { + if( get_bit( i ) ) + return true; + + if( m_params.enc() == SC_TC_ && i == m_params.iwl() - 1 ) + m_val -= scfx_pow2( i ); + else + m_val += scfx_pow2( i ); + } + else + { + if( ! get_bit( i ) ) + return true; + + if( m_params.enc() == SC_TC_ && i == m_params.iwl() - 1 ) + m_val += scfx_pow2( i ); + else + m_val -= scfx_pow2( i ); + } + + return true; +} + + +bool +sc_fxnum_fast::get_slice( int i, int j, sc_bv_base& bv ) const +{ + scfx_ieee_double id( m_val ); + if( id.is_nan() || id.is_inf() ) + return false; + + // convert to two's complement + + unsigned int m0 = id.mantissa0(); + unsigned int m1 = id.mantissa1(); + + if( id.is_normal() ) + m0 += 1U << 20; + + if( id.negative() != 0 ) + { + m0 = ~ m0; + m1 = ~ m1; + unsigned int tmp = m1; + m1 += 1U; + if( m1 <= tmp ) + m0 += 1U; + } + + // get the bits + + int l = j; + for( int k = 0; k < bv.length(); ++ k ) + { + bool b = false; + + int n = l - id.exponent(); + if( ( n += 20 ) >= 32 ) + b = ( ( m0 & 1U << 31 ) != 0 ); + else if( n >= 0 ) + b = ( ( m0 & 1U << n ) != 0 ); + else if( ( n += 32 ) >= 0 ) + b = ( ( m1 & 1U << n ) != 0 ); + + bv[k] = b; + + if( i >= j ) + ++ l; + else + -- l; + } + + return true; +} + +bool +sc_fxnum_fast::set_slice( int i, int j, const sc_bv_base& bv ) +{ + scfx_ieee_double id( m_val ); + if( id.is_nan() || id.is_inf() ) + return false; + + // set the bits + + int l = j; + for( int k = 0; k < bv.length(); ++ k ) + { + if( bv[k].to_bool() ) + { + if( ! get_bit( l ) ) + { + if( m_params.enc() == SC_TC_ && l == m_params.iwl() - 1 ) + m_val -= scfx_pow2( l ); + else + m_val += scfx_pow2( l ); + } + } + else + { + if( get_bit( l ) ) + { + if( m_params.enc() == SC_TC_ && l == m_params.iwl() - 1 ) + m_val += scfx_pow2( l ); + else + m_val -= scfx_pow2( l ); + } + } + + + if( i >= j ) + ++ l; + else + -- l; + } + + return true; +} + + +sc_fxnum_fast_observer* +sc_fxnum_fast::lock_observer() const +{ + SC_ASSERT_( m_observer != 0, "lock observer failed" ); + sc_fxnum_fast_observer* tmp = m_observer; + m_observer = 0; + return tmp; +} + +void +sc_fxnum_fast::unlock_observer( sc_fxnum_fast_observer* observer_ ) const +{ + SC_ASSERT_( observer_ != 0, "unlock observer failed" ); + m_observer = observer_; +} + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxnum.h b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum.h new file mode 100644 index 000000000..ed3750811 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum.h @@ -0,0 +1,5102 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxnum.h - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_fxnum.h,v $ +// Revision 1.5 2011/08/29 18:04:32 acg +// Philipp A. Hartmann: miscellaneous clean ups. +// +// Revision 1.4 2011/08/24 22:05:43 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.3 2011/01/19 18:57:40 acg +// Andy Goodrich: changes for IEEE_1666_2011. +// +// Revision 1.2 2009/03/09 17:26:46 acg +// Andy Goodrich: removed ; from namespace { } +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_FXNUM_H +#define SC_FXNUM_H + + +#include "sysc/datatypes/bit/sc_lv_base.h" +#include "sysc/datatypes/fx/sc_fxval.h" +#include "sysc/datatypes/fx/scfx_params.h" +#include "sysc/datatypes/fx/sc_fxnum_observer.h" + + +namespace sc_core { + class vcd_sc_fxnum_trace; + class vcd_sc_fxnum_fast_trace; + class wif_sc_fxnum_trace; + class wif_sc_fxnum_fast_trace; +} + + +namespace sc_dt +{ + +// classes defined in this module +class sc_fxnum_bitref; +class sc_fxnum_fast_bitref; +class sc_fxnum_subref; +class sc_fxnum_fast_subref; +class sc_fxnum; +class sc_fxnum_fast; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_bitref +// +// Proxy class for bit-selection in class sc_fxnum, behaves like sc_bit. +// ---------------------------------------------------------------------------- + +class sc_fxnum_bitref +{ + friend class sc_fxnum; + friend class sc_fxnum_fast_bitref; + + + bool get() const; + void set( bool ); + + + // constructor + + sc_fxnum_bitref( sc_fxnum&, int ); + +public: + + // copy constructor + + sc_fxnum_bitref( const sc_fxnum_bitref& ); + + + // assignment operators + +#define DECL_ASN_OP_T(op,tp) \ + sc_fxnum_bitref& operator op ( tp ); + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,const sc_fxnum_bitref&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast_bitref&) \ + DECL_ASN_OP_T(op,const sc_bit&) \ + DECL_ASN_OP_T(op,bool) + + DECL_ASN_OP(=) + + DECL_ASN_OP(&=) + DECL_ASN_OP(|=) + DECL_ASN_OP(^=) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP + + + // implicit conversion + + operator bool() const; + + + // print or dump content + + void print( ::std::ostream& = ::std::cout ) const; + void scan( ::std::istream& = ::std::cin ); + void dump( ::std::ostream& = ::std::cout ) const; + +private: + + sc_fxnum& m_num; + int m_idx; + +private: + + // disabled + sc_fxnum_bitref(); +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast_bitref +// +// Proxy class for bit-selection in class sc_fxnum_fast, behaves like sc_bit. +// ---------------------------------------------------------------------------- + +class sc_fxnum_fast_bitref +{ + friend class sc_fxnum_fast; + friend class sc_fxnum_bitref; + + + bool get() const; + void set( bool ); + + + // constructor + + sc_fxnum_fast_bitref( sc_fxnum_fast&, int ); + +public: + + // copy constructor + + sc_fxnum_fast_bitref( const sc_fxnum_fast_bitref& ); + + + // assignment operators + +#define DECL_ASN_OP_T(op,tp) \ + sc_fxnum_fast_bitref& operator op ( tp ); + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,const sc_fxnum_bitref&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast_bitref&) \ + DECL_ASN_OP_T(op,const sc_bit&) \ + DECL_ASN_OP_T(op,bool) + + DECL_ASN_OP(=) + + DECL_ASN_OP(&=) + DECL_ASN_OP(|=) + DECL_ASN_OP(^=) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP + + + // implicit conversion + + operator bool() const; + + + // print or dump content + + void print( ::std::ostream& = ::std::cout ) const; + void scan( ::std::istream& = ::std::cin ); + void dump( ::std::ostream& = ::std::cout ) const; + +private: + + sc_fxnum_fast& m_num; + int m_idx; + +private: + + // disabled + sc_fxnum_fast_bitref(); +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_subref +// +// Proxy class for part-selection in class sc_fxnum, +// behaves like sc_bv_base. +// ---------------------------------------------------------------------------- + +class sc_fxnum_subref +{ + friend class sc_fxnum; + friend class sc_fxnum_fast_subref; + + bool get() const; + bool set(); + + + // constructor + + sc_fxnum_subref( sc_fxnum&, int, int ); + +public: + + // copy constructor + + sc_fxnum_subref( const sc_fxnum_subref& ); + + + // destructor + + ~sc_fxnum_subref(); + + + // assignment operators + +#define DECL_ASN_OP_T(tp) \ + sc_fxnum_subref& operator = ( tp ); + + DECL_ASN_OP_T(const sc_fxnum_subref&) + DECL_ASN_OP_T(const sc_fxnum_fast_subref&) + DECL_ASN_OP_T(const sc_bv_base&) + DECL_ASN_OP_T(const sc_lv_base&) + DECL_ASN_OP_T(const char*) + DECL_ASN_OP_T(const bool*) + DECL_ASN_OP_T(const sc_signed&) + DECL_ASN_OP_T(const sc_unsigned&) + DECL_ASN_OP_T(const sc_int_base&) + DECL_ASN_OP_T(const sc_uint_base&) + DECL_ASN_OP_T(int64) + DECL_ASN_OP_T(uint64) + DECL_ASN_OP_T(int) + DECL_ASN_OP_T(unsigned int) + DECL_ASN_OP_T(long) + DECL_ASN_OP_T(unsigned long) + DECL_ASN_OP_T(char) + +#undef DECL_ASN_OP_T + +#define DECL_ASN_OP_T_A(op,tp) \ + sc_fxnum_subref& operator op ## = ( tp ); + +#define DECL_ASN_OP_A(op) \ + DECL_ASN_OP_T_A(op,const sc_fxnum_subref&) \ + DECL_ASN_OP_T_A(op,const sc_fxnum_fast_subref&) \ + DECL_ASN_OP_T_A(op,const sc_bv_base&) \ + DECL_ASN_OP_T_A(op,const sc_lv_base&) + + DECL_ASN_OP_A(&) + DECL_ASN_OP_A(|) + DECL_ASN_OP_A(^) + +#undef DECL_ASN_OP_T_A +#undef DECL_ASN_OP_A + + + // relational operators + +#define DECL_REL_OP_T(op,tp) \ + friend bool operator op ( const sc_fxnum_subref&, tp ); \ + friend bool operator op ( tp, const sc_fxnum_subref& ); + +#define DECL_REL_OP(op) \ + friend bool operator op ( const sc_fxnum_subref&, \ + const sc_fxnum_subref& ); \ + friend bool operator op ( const sc_fxnum_subref&, \ + const sc_fxnum_fast_subref& ); \ + DECL_REL_OP_T(op,const sc_bv_base&) \ + DECL_REL_OP_T(op,const sc_lv_base&) \ + DECL_REL_OP_T(op,const char*) \ + DECL_REL_OP_T(op,const bool*) \ + DECL_REL_OP_T(op,const sc_signed&) \ + DECL_REL_OP_T(op,const sc_unsigned&) \ + DECL_REL_OP_T(op,int) \ + DECL_REL_OP_T(op,unsigned int) \ + DECL_REL_OP_T(op,long) \ + DECL_REL_OP_T(op,unsigned long) + + DECL_REL_OP(==) + DECL_REL_OP(!=) + +#undef DECL_REL_OP_T +#undef DECL_REL_OP + + + // reduce functions + + bool and_reduce() const; + bool nand_reduce() const; + bool or_reduce() const; + bool nor_reduce() const; + bool xor_reduce() const; + bool xnor_reduce() const; + + + // query parameter + + int length() const; + + + // explicit conversions + + int to_int() const; + unsigned int to_uint() const; + long to_long() const; + unsigned long to_ulong() const; + int64 to_int64() const; + uint64 to_uint64() const; + +#ifdef SC_DT_DEPRECATED + int to_signed() const; + unsigned int to_unsigned() const; +#endif + + const std::string to_string() const; + const std::string to_string( sc_numrep ) const; + const std::string to_string( sc_numrep, bool ) const; + + + // implicit conversion + + operator sc_bv_base() const; + + + // print or dump content + + void print( ::std::ostream& = ::std::cout ) const; + void scan( ::std::istream& = ::std::cin ); + void dump( ::std::ostream& = ::std::cout ) const; + +private: + + sc_fxnum& m_num; + int m_from; + int m_to; + + sc_bv_base& m_bv; + +private: + + // disabled + sc_fxnum_subref(); +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast_subref +// +// Proxy class for part-selection in class sc_fxnum_fast, +// behaves like sc_bv_base. +// ---------------------------------------------------------------------------- + +class sc_fxnum_fast_subref +{ + friend class sc_fxnum_fast; + friend class sc_fxnum_subref; + + bool get() const; + bool set(); + + + // constructor + + sc_fxnum_fast_subref( sc_fxnum_fast&, int, int ); + +public: + + // copy constructor + + sc_fxnum_fast_subref( const sc_fxnum_fast_subref& ); + + + // destructor + + ~sc_fxnum_fast_subref(); + + + // assignment operators + +#define DECL_ASN_OP_T(tp) \ + sc_fxnum_fast_subref& operator = ( tp ); + + DECL_ASN_OP_T(const sc_fxnum_subref&) + DECL_ASN_OP_T(const sc_fxnum_fast_subref&) + DECL_ASN_OP_T(const sc_bv_base&) + DECL_ASN_OP_T(const sc_lv_base&) + DECL_ASN_OP_T(const char*) + DECL_ASN_OP_T(const bool*) + DECL_ASN_OP_T(const sc_signed&) + DECL_ASN_OP_T(const sc_unsigned&) + DECL_ASN_OP_T(const sc_int_base&) + DECL_ASN_OP_T(const sc_uint_base&) + DECL_ASN_OP_T(int64) + DECL_ASN_OP_T(uint64) + DECL_ASN_OP_T(int) + DECL_ASN_OP_T(unsigned int) + DECL_ASN_OP_T(long) + DECL_ASN_OP_T(unsigned long) + DECL_ASN_OP_T(char) + +#undef DECL_ASN_OP_T + +#define DECL_ASN_OP_T_A(op,tp) \ + sc_fxnum_fast_subref& operator op ## = ( tp ); + +#define DECL_ASN_OP_A(op) \ + DECL_ASN_OP_T_A(op,const sc_fxnum_subref&) \ + DECL_ASN_OP_T_A(op,const sc_fxnum_fast_subref&) \ + DECL_ASN_OP_T_A(op,const sc_bv_base&) \ + DECL_ASN_OP_T_A(op,const sc_lv_base&) + + DECL_ASN_OP_A(&) + DECL_ASN_OP_A(|) + DECL_ASN_OP_A(^) + +#undef DECL_ASN_OP_T_A +#undef DECL_ASN_OP_A + + + // relational operators + +#define DECL_REL_OP_T(op,tp) \ + friend bool operator op ( const sc_fxnum_fast_subref&, tp ); \ + friend bool operator op ( tp, const sc_fxnum_fast_subref& ); + +#define DECL_REL_OP(op) \ + friend bool operator op ( const sc_fxnum_fast_subref&, \ + const sc_fxnum_fast_subref& ); \ + friend bool operator op ( const sc_fxnum_fast_subref&, \ + const sc_fxnum_subref& ); \ + DECL_REL_OP_T(op,const sc_bv_base&) \ + DECL_REL_OP_T(op,const sc_lv_base&) \ + DECL_REL_OP_T(op,const char*) \ + DECL_REL_OP_T(op,const bool*) \ + DECL_REL_OP_T(op,const sc_signed&) \ + DECL_REL_OP_T(op,const sc_unsigned&) \ + DECL_REL_OP_T(op,int) \ + DECL_REL_OP_T(op,unsigned int) \ + DECL_REL_OP_T(op,long) \ + DECL_REL_OP_T(op,unsigned long) + + DECL_REL_OP(==) + DECL_REL_OP(!=) + +#undef DECL_REL_OP_T +#undef DECL_REL_OP + + + // reduce functions + + bool and_reduce() const; + bool nand_reduce() const; + bool or_reduce() const; + bool nor_reduce() const; + bool xor_reduce() const; + bool xnor_reduce() const; + + + // query parameter + + int length() const; + + + // explicit conversions + + int to_int() const; + unsigned int to_uint() const; + long to_long() const; + unsigned long to_ulong() const; + int64 to_int64() const; + uint64 to_uint64() const; + +#ifdef SC_DT_DEPRECATED + int to_signed() const; + unsigned int to_unsigned() const; +#endif + + const std::string to_string() const; + const std::string to_string( sc_numrep ) const; + const std::string to_string( sc_numrep, bool ) const; + + + // implicit conversion + + operator sc_bv_base() const; + + + // print or dump content + + void print( ::std::ostream& = ::std::cout ) const; + void scan( ::std::istream& = ::std::cin ); + void dump( ::std::ostream& = ::std::cout ) const; + +private: + + sc_fxnum_fast& m_num; + int m_from; + int m_to; + + sc_bv_base& m_bv; + +private: + + // disabled + sc_fxnum_fast_subref(); +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum +// +// Base class for the fixed-point types; arbitrary precision. +// ---------------------------------------------------------------------------- + +class sc_fxnum +{ + friend class sc_fxval; + + friend class sc_fxnum_bitref; + friend class sc_fxnum_subref; + friend class sc_fxnum_fast_bitref; + friend class sc_fxnum_fast_subref; + + friend class sc_core::vcd_sc_fxnum_trace; + friend class sc_core::wif_sc_fxnum_trace; + +protected: + + sc_fxnum_observer* observer() const; + + + void cast(); + + + // constructors + + sc_fxnum( const sc_fxtype_params&, + sc_enc, + const sc_fxcast_switch&, + sc_fxnum_observer* ); + +#define DECL_CTOR_T(tp) \ + sc_fxnum( tp, \ + const sc_fxtype_params&, \ + sc_enc, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* ); + + DECL_CTOR_T(int) + DECL_CTOR_T(unsigned int) + DECL_CTOR_T(long) + DECL_CTOR_T(unsigned long) + DECL_CTOR_T(float) + DECL_CTOR_T(double) + DECL_CTOR_T(const char*) + DECL_CTOR_T(const sc_fxval&) + DECL_CTOR_T(const sc_fxval_fast&) + DECL_CTOR_T(const sc_fxnum&) + DECL_CTOR_T(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_CTOR_T(int64) + DECL_CTOR_T(uint64) + DECL_CTOR_T(const sc_int_base&) + DECL_CTOR_T(const sc_uint_base&) + DECL_CTOR_T(const sc_signed&) + DECL_CTOR_T(const sc_unsigned&) +#endif + +#undef DECL_CTOR_T + + ~sc_fxnum(); + + + // internal use only; + const scfx_rep* get_rep() const; + +public: + + // unary operators + + const sc_fxval operator - () const; + const sc_fxval operator + () const; + + + // unary functions + + friend void neg( sc_fxval&, const sc_fxnum& ); + friend void neg( sc_fxnum&, const sc_fxnum& ); + + + // binary operators + +#define DECL_BIN_OP_T(op,tp) \ + friend const sc_fxval operator op ( const sc_fxnum&, tp ); \ + friend const sc_fxval operator op ( tp, const sc_fxnum& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_BIN_OP_OTHER(op) \ + DECL_BIN_OP_T(op,int64) \ + DECL_BIN_OP_T(op,uint64) \ + DECL_BIN_OP_T(op,const sc_int_base&) \ + DECL_BIN_OP_T(op,const sc_uint_base&) \ + DECL_BIN_OP_T(op,const sc_signed&) \ + DECL_BIN_OP_T(op,const sc_unsigned&) +#else +#define DECL_BIN_OP_OTHER(op) +#endif + +#define DECL_BIN_OP(op,dummy) \ + friend const sc_fxval operator op ( const sc_fxnum&, const sc_fxnum& ); \ + DECL_BIN_OP_T(op,int) \ + DECL_BIN_OP_T(op,unsigned int) \ + DECL_BIN_OP_T(op,long) \ + DECL_BIN_OP_T(op,unsigned long) \ + DECL_BIN_OP_T(op,float) \ + DECL_BIN_OP_T(op,double) \ + DECL_BIN_OP_T(op,const char*) \ + DECL_BIN_OP_T(op,const sc_fxval&) \ + DECL_BIN_OP_T(op,const sc_fxval_fast&) \ + DECL_BIN_OP_T(op,const sc_fxnum_fast&) \ + DECL_BIN_OP_OTHER(op) + + DECL_BIN_OP(*,mult) + DECL_BIN_OP(+,add) + DECL_BIN_OP(-,sub) +// don't use macros +// DECL_BIN_OP(/,div) + friend const sc_fxval operator / ( const sc_fxnum&, const sc_fxnum& ); + DECL_BIN_OP_T(/,int) + DECL_BIN_OP_T(/,unsigned int) + DECL_BIN_OP_T(/,long) + DECL_BIN_OP_T(/,unsigned long) + DECL_BIN_OP_T(/,float) + DECL_BIN_OP_T(/,double) + DECL_BIN_OP_T(/,const char*) + DECL_BIN_OP_T(/,const sc_fxval&) + DECL_BIN_OP_T(/,const sc_fxval_fast&) + DECL_BIN_OP_T(/,const sc_fxnum_fast&) +// DECL_BIN_OP_OTHER(op) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_BIN_OP_T(/,int64) + DECL_BIN_OP_T(/,uint64) + DECL_BIN_OP_T(/,const sc_int_base&) + DECL_BIN_OP_T(/,const sc_uint_base&) + DECL_BIN_OP_T(/,const sc_signed&) + DECL_BIN_OP_T(/,const sc_unsigned&) +#endif + +#undef DECL_BIN_OP_T +#undef DECL_BIN_OP_OTHER +#undef DECL_BIN_OP + + friend const sc_fxval operator << ( const sc_fxnum&, int ); + friend const sc_fxval operator >> ( const sc_fxnum&, int ); + + + // binary functions + +#define DECL_BIN_FNC_T(fnc,tp) \ + friend void fnc ( sc_fxval&, const sc_fxnum&, tp ); \ + friend void fnc ( sc_fxval&, tp, const sc_fxnum& ); \ + friend void fnc ( sc_fxnum&, const sc_fxnum&, tp ); \ + friend void fnc ( sc_fxnum&, tp, const sc_fxnum& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_BIN_FNC_OTHER(fnc) \ + DECL_BIN_FNC_T(fnc,int64) \ + DECL_BIN_FNC_T(fnc,uint64) \ + DECL_BIN_FNC_T(fnc,const sc_int_base&) \ + DECL_BIN_FNC_T(fnc,const sc_uint_base&) \ + DECL_BIN_FNC_T(fnc,const sc_signed&) \ + DECL_BIN_FNC_T(fnc,const sc_unsigned&) +#else +#define DECL_BIN_FNC_OTHER(fnc) +#endif + +#define DECL_BIN_FNC(fnc) \ + friend void fnc ( sc_fxval&, const sc_fxnum&, const sc_fxnum& ); \ + friend void fnc ( sc_fxnum&, const sc_fxnum&, const sc_fxnum& ); \ + DECL_BIN_FNC_T(fnc,int) \ + DECL_BIN_FNC_T(fnc,unsigned int) \ + DECL_BIN_FNC_T(fnc,long) \ + DECL_BIN_FNC_T(fnc,unsigned long) \ + DECL_BIN_FNC_T(fnc,float) \ + DECL_BIN_FNC_T(fnc,double) \ + DECL_BIN_FNC_T(fnc,const char*) \ + DECL_BIN_FNC_T(fnc,const sc_fxval&) \ + DECL_BIN_FNC_T(fnc,const sc_fxval_fast&) \ + DECL_BIN_FNC_T(fnc,const sc_fxnum_fast&) \ + DECL_BIN_FNC_OTHER(fnc) + + DECL_BIN_FNC(mult) + DECL_BIN_FNC(div) + DECL_BIN_FNC(add) + DECL_BIN_FNC(sub) + +#undef DECL_BIN_FNC_T +#undef DECL_BIN_FNC_OTHER +#undef DECL_BIN_FNC + + friend void lshift( sc_fxval&, const sc_fxnum&, int ); + friend void rshift( sc_fxval&, const sc_fxnum&, int ); + friend void lshift( sc_fxnum&, const sc_fxnum&, int ); + friend void rshift( sc_fxnum&, const sc_fxnum&, int ); + + + // relational (including equality) operators + +#define DECL_REL_OP_T(op,tp) \ + friend bool operator op ( const sc_fxnum&, tp ); \ + friend bool operator op ( tp, const sc_fxnum& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_REL_OP_OTHER(op) \ + DECL_REL_OP_T(op,int64) \ + DECL_REL_OP_T(op,uint64) \ + DECL_REL_OP_T(op,const sc_int_base&) \ + DECL_REL_OP_T(op,const sc_uint_base&) \ + DECL_REL_OP_T(op,const sc_signed&) \ + DECL_REL_OP_T(op,const sc_unsigned&) +#else +#define DECL_REL_OP_OTHER(op) +#endif + +#define DECL_REL_OP(op) \ + friend bool operator op ( const sc_fxnum&, const sc_fxnum& ); \ + DECL_REL_OP_T(op,int) \ + DECL_REL_OP_T(op,unsigned int) \ + DECL_REL_OP_T(op,long) \ + DECL_REL_OP_T(op,unsigned long) \ + DECL_REL_OP_T(op,float) \ + DECL_REL_OP_T(op,double) \ + DECL_REL_OP_T(op,const char*) \ + DECL_REL_OP_T(op,const sc_fxval&) \ + DECL_REL_OP_T(op,const sc_fxval_fast&) \ + DECL_REL_OP_T(op,const sc_fxnum_fast&) \ + DECL_REL_OP_OTHER(op) + + DECL_REL_OP(<) + DECL_REL_OP(<=) + DECL_REL_OP(>) + DECL_REL_OP(>=) + DECL_REL_OP(==) + DECL_REL_OP(!=) + +#undef DECL_REL_OP_T +#undef DECL_REL_OP_OTHER +#undef DECL_REL_OP + + + // assignment operators + +#define DECL_ASN_OP_T(op,tp) \ + sc_fxnum& operator op( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval operator ++ ( int ); + const sc_fxval operator -- ( int ); + + sc_fxnum& operator ++ (); + sc_fxnum& operator -- (); + + + // bit selection + + const sc_fxnum_bitref operator [] ( int ) const; + sc_fxnum_bitref operator [] ( int ); + + const sc_fxnum_bitref bit( int ) const; + sc_fxnum_bitref bit( int ); + + + // part selection + + const sc_fxnum_subref operator () ( int, int ) const; + sc_fxnum_subref operator () ( int, int ); + + const sc_fxnum_subref range( int, int ) const; + sc_fxnum_subref range( int, int ); + + + const sc_fxnum_subref operator () () const; + sc_fxnum_subref operator () (); + + const sc_fxnum_subref range() const; + sc_fxnum_subref range(); + + + // implicit conversion + + operator double() const; // necessary evil! + + + // explicit conversion to primitive types + + short to_short() const; + unsigned short to_ushort() const; + int to_int() const; + unsigned int to_uint() const; + long to_long() const; + unsigned long to_ulong() const; + int64 to_int64() const; + uint64 to_uint64() const; + float to_float() const; + double to_double() const; + + + // explicit conversion to character string + + const std::string to_string() const; + const std::string to_string( sc_numrep ) const; + const std::string to_string( sc_numrep, bool ) const; + const std::string to_string( sc_fmt ) const; + const std::string to_string( sc_numrep, sc_fmt ) const; + const std::string to_string( sc_numrep, bool, sc_fmt ) const; + + const std::string to_dec() const; + const std::string to_bin() const; + const std::string to_oct() const; + const std::string to_hex() const; + + + // query value + + bool is_neg() const; + bool is_zero() const; + + // internal use only; + bool is_normal() const; + + bool quantization_flag() const; + bool overflow_flag() const; + + const sc_fxval value() const; + + + // query parameters + + int wl() const; + int iwl() const; + sc_q_mode q_mode() const; + sc_o_mode o_mode() const; + int n_bits() const; + + const sc_fxtype_params& type_params() const; + + const sc_fxcast_switch& cast_switch() const; + + + // print or dump content + + void print( ::std::ostream& = ::std::cout ) const; + void scan( ::std::istream& = ::std::cin ); + void dump( ::std::ostream& = ::std::cout ) const; + + + // internal use only; + void observer_read() const; + + + // internal use only; + bool get_bit( int ) const; + +protected: + + bool set_bit( int, bool ); + + + bool get_slice( int, int, sc_bv_base& ) const; + bool set_slice( int, int, const sc_bv_base& ); + + + sc_fxnum_observer* lock_observer() const; + void unlock_observer( sc_fxnum_observer* ) const; + +private: + + scfx_rep* m_rep; + + scfx_params m_params; + bool m_q_flag; + bool m_o_flag; + + mutable sc_fxnum_observer* m_observer; + +private: + + // disabled + sc_fxnum(); + sc_fxnum( const sc_fxnum& ); +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast +// +// Base class for the fixed-point types; limited precision. +// ---------------------------------------------------------------------------- + +class sc_fxnum_fast +{ + friend class sc_fxval_fast; + + friend class sc_fxnum_bitref; + friend class sc_fxnum_subref; + friend class sc_fxnum_fast_bitref; + friend class sc_fxnum_fast_subref; + + friend class sc_core::vcd_sc_fxnum_fast_trace; + friend class sc_core::wif_sc_fxnum_fast_trace; + +protected: + + sc_fxnum_fast_observer* observer() const; + + + void cast(); + + + // constructors + + sc_fxnum_fast( const sc_fxtype_params&, + sc_enc, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* ); + +#define DECL_CTOR_T(tp) \ + sc_fxnum_fast( tp, \ + const sc_fxtype_params&, \ + sc_enc, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* ); + + DECL_CTOR_T(int) + DECL_CTOR_T(unsigned int) + DECL_CTOR_T(long) + DECL_CTOR_T(unsigned long) + DECL_CTOR_T(float) + DECL_CTOR_T(double) + DECL_CTOR_T(const char*) + DECL_CTOR_T(const sc_fxval&) + DECL_CTOR_T(const sc_fxval_fast&) + DECL_CTOR_T(const sc_fxnum&) + DECL_CTOR_T(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_CTOR_T(int64) + DECL_CTOR_T(uint64) + DECL_CTOR_T(const sc_int_base&) + DECL_CTOR_T(const sc_uint_base&) + DECL_CTOR_T(const sc_signed&) + DECL_CTOR_T(const sc_unsigned&) +#endif + +#undef DECL_CTOR_T + + ~sc_fxnum_fast(); + + + // internal use only; + double get_val() const; + +public: + + // unary operators + + const sc_fxval_fast operator - () const; + const sc_fxval_fast operator + () const; + + + // unary functions + + friend void neg( sc_fxval_fast&, const sc_fxnum_fast& ); + friend void neg( sc_fxnum_fast&, const sc_fxnum_fast& ); + + + // binary operators + +#define DECL_BIN_OP_T(op,tp) \ + friend const sc_fxval_fast operator op ( const sc_fxnum_fast&, tp ); \ + friend const sc_fxval_fast operator op ( tp, const sc_fxnum_fast& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_BIN_OP_OTHER(op) \ + DECL_BIN_OP_T(op,int64) \ + DECL_BIN_OP_T(op,uint64) \ + DECL_BIN_OP_T(op,const sc_int_base&) \ + DECL_BIN_OP_T(op,const sc_uint_base&) \ + DECL_BIN_OP_T(op,const sc_signed&) \ + DECL_BIN_OP_T(op,const sc_unsigned&) +#else +#define DECL_BIN_OP_OTHER(op) +#endif + +#define DECL_BIN_OP(op,dummy) \ + friend const sc_fxval_fast operator op ( const sc_fxnum_fast&, \ + const sc_fxnum_fast& ); \ + DECL_BIN_OP_T(op,int) \ + DECL_BIN_OP_T(op,unsigned int) \ + DECL_BIN_OP_T(op,long) \ + DECL_BIN_OP_T(op,unsigned long) \ + DECL_BIN_OP_T(op,float) \ + DECL_BIN_OP_T(op,double) \ + DECL_BIN_OP_T(op,const char*) \ + DECL_BIN_OP_T(op,const sc_fxval_fast&) \ + DECL_BIN_OP_OTHER(op) + + DECL_BIN_OP(*,mult) + DECL_BIN_OP(+,add) + DECL_BIN_OP(-,sub) +// DECL_BIN_OP(/,div) + friend const sc_fxval_fast operator / ( const sc_fxnum_fast&, + const sc_fxnum_fast& ); + DECL_BIN_OP_T(/,int) + DECL_BIN_OP_T(/,unsigned int) + DECL_BIN_OP_T(/,long) + DECL_BIN_OP_T(/,unsigned long) + DECL_BIN_OP_T(/,float) + DECL_BIN_OP_T(/,double) + DECL_BIN_OP_T(/,const char*) + DECL_BIN_OP_T(/,const sc_fxval_fast&) +// DECL_BIN_OP_OTHER(op) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_BIN_OP_T(/,int64) \ + DECL_BIN_OP_T(/,uint64) \ + DECL_BIN_OP_T(/,const sc_int_base&) \ + DECL_BIN_OP_T(/,const sc_uint_base&) \ + DECL_BIN_OP_T(/,const sc_signed&) \ + DECL_BIN_OP_T(/,const sc_unsigned&) +#endif + +#undef DECL_BIN_OP_T +#undef DECL_BIN_OP_OTHER +#undef DECL_BIN_OP + + friend const sc_fxval_fast operator << ( const sc_fxnum_fast&, int ); + friend const sc_fxval_fast operator >> ( const sc_fxnum_fast&, int ); + + + // binary functions + +#define DECL_BIN_FNC_T(fnc,tp) \ + friend void fnc ( sc_fxval_fast&, const sc_fxnum_fast&, tp ); \ + friend void fnc ( sc_fxval_fast&, tp, const sc_fxnum_fast& ); \ + friend void fnc ( sc_fxnum_fast&, const sc_fxnum_fast&, tp ); \ + friend void fnc ( sc_fxnum_fast&, tp, const sc_fxnum_fast& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_BIN_FNC_OTHER(fnc) \ + DECL_BIN_FNC_T(fnc,int64) \ + DECL_BIN_FNC_T(fnc,uint64) \ + DECL_BIN_FNC_T(fnc,const sc_int_base&) \ + DECL_BIN_FNC_T(fnc,const sc_uint_base&) \ + DECL_BIN_FNC_T(fnc,const sc_signed&) \ + DECL_BIN_FNC_T(fnc,const sc_unsigned&) +#else +#define DECL_BIN_FNC_OTHER(fnc) +#endif + +#define DECL_BIN_FNC(fnc) \ + friend void fnc ( sc_fxval_fast&, const sc_fxnum_fast&, \ + const sc_fxnum_fast& ); \ + friend void fnc ( sc_fxnum_fast&, const sc_fxnum_fast&, \ + const sc_fxnum_fast& ); \ + DECL_BIN_FNC_T(fnc,int) \ + DECL_BIN_FNC_T(fnc,unsigned int) \ + DECL_BIN_FNC_T(fnc,long) \ + DECL_BIN_FNC_T(fnc,unsigned long) \ + DECL_BIN_FNC_T(fnc,float) \ + DECL_BIN_FNC_T(fnc,double) \ + DECL_BIN_FNC_T(fnc,const char*) \ + DECL_BIN_FNC_T(fnc,const sc_fxval&) \ + DECL_BIN_FNC_T(fnc,const sc_fxval_fast&) \ + DECL_BIN_FNC_T(fnc,const sc_fxnum&) \ + DECL_BIN_FNC_OTHER(fnc) + + DECL_BIN_FNC(mult) + DECL_BIN_FNC(div) + DECL_BIN_FNC(add) + DECL_BIN_FNC(sub) + +#undef DECL_BIN_FNC_T +#undef DECL_BIN_FNC_OTHER +#undef DECL_BIN_FNC + + friend void lshift( sc_fxval_fast&, const sc_fxnum_fast&, int ); + friend void rshift( sc_fxval_fast&, const sc_fxnum_fast&, int ); + friend void lshift( sc_fxnum_fast&, const sc_fxnum_fast&, int ); + friend void rshift( sc_fxnum_fast&, const sc_fxnum_fast&, int ); + + + // relational (including equality) operators + +#define DECL_REL_OP_T(op,tp) \ + friend bool operator op ( const sc_fxnum_fast&, tp ); \ + friend bool operator op ( tp, const sc_fxnum_fast& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_REL_OP_OTHER(op) \ + DECL_REL_OP_T(op,int64) \ + DECL_REL_OP_T(op,uint64) \ + DECL_REL_OP_T(op,const sc_int_base&) \ + DECL_REL_OP_T(op,const sc_uint_base&) \ + DECL_REL_OP_T(op,const sc_signed&) \ + DECL_REL_OP_T(op,const sc_unsigned&) +#else +#define DECL_REL_OP_OTHER(op) +#endif + +#define DECL_REL_OP(op) \ + friend bool operator op ( const sc_fxnum_fast&, const sc_fxnum_fast& ); \ + DECL_REL_OP_T(op,int) \ + DECL_REL_OP_T(op,unsigned int) \ + DECL_REL_OP_T(op,long) \ + DECL_REL_OP_T(op,unsigned long) \ + DECL_REL_OP_T(op,float) \ + DECL_REL_OP_T(op,double) \ + DECL_REL_OP_T(op,const char*) \ + DECL_REL_OP_T(op,const sc_fxval_fast&) \ + DECL_REL_OP_OTHER(op) + + DECL_REL_OP(<) + DECL_REL_OP(<=) + DECL_REL_OP(>) + DECL_REL_OP(>=) + DECL_REL_OP(==) + DECL_REL_OP(!=) + +#undef DECL_REL_OP_T +#undef DECL_REL_OP_OTHER +#undef DECL_REL_OP + + + // assignment operators + +#define DECL_ASN_OP_T(op,tp) \ + sc_fxnum_fast& operator op( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval_fast operator ++ ( int ); + const sc_fxval_fast operator -- ( int ); + + sc_fxnum_fast& operator ++ (); + sc_fxnum_fast& operator -- (); + + + // bit selection + + const sc_fxnum_fast_bitref operator [] ( int ) const; + sc_fxnum_fast_bitref operator [] ( int ); + + const sc_fxnum_fast_bitref bit( int ) const; + sc_fxnum_fast_bitref bit( int ); + + + // part selection + + const sc_fxnum_fast_subref operator () ( int, int ) const; + sc_fxnum_fast_subref operator () ( int, int ); + + const sc_fxnum_fast_subref range( int, int ) const; + sc_fxnum_fast_subref range( int, int ); + + + const sc_fxnum_fast_subref operator () () const; + sc_fxnum_fast_subref operator () (); + + const sc_fxnum_fast_subref range() const; + sc_fxnum_fast_subref range(); + + + // implicit conversion + + operator double() const; // necessary evil! + + + // explicit conversion to primitive types + + short to_short() const; + unsigned short to_ushort() const; + int to_int() const; + unsigned int to_uint() const; + long to_long() const; + unsigned long to_ulong() const; + int64 to_int64() const; + uint64 to_uint64() const; + float to_float() const; + double to_double() const; + + + // explicit conversion to character string + + const std::string to_string() const; + const std::string to_string( sc_numrep ) const; + const std::string to_string( sc_numrep, bool ) const; + const std::string to_string( sc_fmt ) const; + const std::string to_string( sc_numrep, sc_fmt ) const; + const std::string to_string( sc_numrep, bool, sc_fmt ) const; + + const std::string to_dec() const; + const std::string to_bin() const; + const std::string to_oct() const; + const std::string to_hex() const; + + + // query value + + bool is_neg() const; + bool is_zero() const; + + // internal use only; + bool is_normal() const; + + bool quantization_flag() const; + bool overflow_flag() const; + + const sc_fxval_fast value() const; + + + // query parameters + + int wl() const; + int iwl() const; + sc_q_mode q_mode() const; + sc_o_mode o_mode() const; + int n_bits() const; + + const sc_fxtype_params& type_params() const; + + const sc_fxcast_switch& cast_switch() const; + + + // print or dump content + + void print( ::std::ostream& = ::std::cout ) const; + void scan( ::std::istream& = ::std::cin ); + void dump( ::std::ostream& = ::std::cout ) const; + + + // internal use only; + void observer_read() const; + + + // internal use only; + bool get_bit( int ) const; + +protected: + + bool set_bit( int, bool ); + + + bool get_slice( int, int, sc_bv_base& ) const; + bool set_slice( int, int, const sc_bv_base& ); + + + sc_fxnum_fast_observer* lock_observer() const; + void unlock_observer( sc_fxnum_fast_observer* ) const; + +private: + + double m_val; + + scfx_params m_params; + bool m_q_flag; + bool m_o_flag; + + mutable sc_fxnum_fast_observer* m_observer; + +private: + + // disabled + sc_fxnum_fast(); + sc_fxnum_fast( const sc_fxnum_fast& ); +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_bitref +// +// Proxy class for bit-selection in class sc_fxnum, behaves like sc_bit. +// ---------------------------------------------------------------------------- + +// constructor + +inline +sc_fxnum_bitref::sc_fxnum_bitref( sc_fxnum& num_, int idx_ ) + : m_num( num_ ), m_idx( idx_ ) +{} + + +// copy constructor + +inline +sc_fxnum_bitref::sc_fxnum_bitref( const sc_fxnum_bitref& a ) + : m_num( a.m_num ), m_idx( a.m_idx ) +{} + + +// assignment operators + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator = ( const sc_fxnum_bitref& a ) +{ + if( &a != this ) + { + SC_FXNUM_OBSERVER_READ_( a.m_num ) + set( a.get() ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + } + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator = ( const sc_fxnum_fast_bitref& a ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a.m_num ) + set( a.get() ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator = ( const sc_bit& a ) +{ + set( static_cast<bool>( a ) ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator = ( bool a ) +{ + set( a ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator &= ( const sc_fxnum_bitref& b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + SC_FXNUM_OBSERVER_READ_( b.m_num ) + set( get() && b.get() ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator &= ( const sc_fxnum_fast_bitref& b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + SC_FXNUM_FAST_OBSERVER_READ_( b.m_num ) + set( get() && b.get() ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator &= ( const sc_bit& b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + set( get() && static_cast<bool>( b ) ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator &= ( bool b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + set( get() && b ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator |= ( const sc_fxnum_bitref& b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + SC_FXNUM_OBSERVER_READ_( b.m_num ) + set( get() || b.get() ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator |= ( const sc_fxnum_fast_bitref& b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + SC_FXNUM_FAST_OBSERVER_READ_( b.m_num ) + set( get() || b.get() ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator |= ( const sc_bit& b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + set( get() || static_cast<bool>( b ) ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator |= ( bool b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + set( get() || b ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator ^= ( const sc_fxnum_bitref& b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + SC_FXNUM_OBSERVER_READ_( b.m_num ) + set( get() != b.get() ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator ^= ( const sc_fxnum_fast_bitref& b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + SC_FXNUM_FAST_OBSERVER_READ_( b.m_num ) + set( get() != b.get() ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator ^= ( const sc_bit& b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + set( get() != static_cast<bool>( b ) ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator ^= ( bool b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + set( get() != b ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + + +// implicit conversion + +inline +sc_fxnum_bitref::operator bool() const +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + return get(); +} + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_fxnum_bitref& a ) +{ + a.print( os ); + return os; +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_fxnum_bitref& a ) +{ + a.scan( is ); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast_bitref +// +// Proxy class for bit-selection in class sc_fxnum_fast, behaves like sc_bit. +// ---------------------------------------------------------------------------- + +// constructor + +inline +sc_fxnum_fast_bitref::sc_fxnum_fast_bitref( sc_fxnum_fast& num_, int idx_ ) + : m_num( num_ ), m_idx( idx_ ) +{} + + +// copy constructor + +inline +sc_fxnum_fast_bitref::sc_fxnum_fast_bitref( const sc_fxnum_fast_bitref& a ) + : m_num( a.m_num ), m_idx( a.m_idx ) +{} + + +// assignment operators + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator = ( const sc_fxnum_bitref& a ) +{ + SC_FXNUM_OBSERVER_READ_( a.m_num ) + set( a.get() ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator = ( const sc_fxnum_fast_bitref& a ) +{ + if( &a != this ) + { + SC_FXNUM_FAST_OBSERVER_READ_( a.m_num ) + set( a.get() ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + } + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator = ( const sc_bit& a ) +{ + set( static_cast<bool>( a ) ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator = ( bool a ) +{ + set( a ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator &= ( const sc_fxnum_bitref& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + SC_FXNUM_OBSERVER_READ_( b.m_num ) + set( get() && b.get() ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator &= ( const sc_fxnum_fast_bitref& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + SC_FXNUM_FAST_OBSERVER_READ_( b.m_num ) + set( get() && b.get() ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator &= ( const sc_bit& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + set( get() && static_cast<bool>( b ) ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator &= ( bool b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + set( get() && b ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator |= ( const sc_fxnum_bitref& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + SC_FXNUM_OBSERVER_READ_( b.m_num ) + set( get() || b.get() ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator |= ( const sc_fxnum_fast_bitref& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + SC_FXNUM_FAST_OBSERVER_READ_( b.m_num ) + set( get() || b.get() ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator |= ( const sc_bit& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + set( get() || static_cast<bool>( b ) ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator |= ( bool b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + set( get() || b ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator ^= ( const sc_fxnum_bitref& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + SC_FXNUM_OBSERVER_READ_( b.m_num ) + set( get() != b.get() ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator ^= ( const sc_fxnum_fast_bitref& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + SC_FXNUM_FAST_OBSERVER_READ_( b.m_num ) + set( get() != b.get() ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator ^= ( const sc_bit& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + set( get() != static_cast<bool>( b ) ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator ^= ( bool b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + set( get() != b ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + + +// implicit conversion + +inline +sc_fxnum_fast_bitref::operator bool() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + return get(); +} + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_fxnum_fast_bitref& a ) +{ + a.print( os ); + return os; +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_fxnum_fast_bitref& a ) +{ + a.scan( is ); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_subref +// +// Proxy class for part-selection in class sc_fxnum, +// behaves like sc_bv_base. +// ---------------------------------------------------------------------------- + +// constructor + +inline +sc_fxnum_subref::sc_fxnum_subref( sc_fxnum& num_, int from_, int to_ ) + : m_num( num_ ), m_from( from_ ), m_to( to_ ), + m_bv( *new sc_bv_base( sc_max( m_from, m_to ) - + sc_min( m_from, m_to ) + 1 ) ) +{} + + +// copy constructor + +inline +sc_fxnum_subref::sc_fxnum_subref( const sc_fxnum_subref& a ) + : m_num( a.m_num ), m_from( a.m_from ), m_to( a.m_to ), + m_bv( *new sc_bv_base( a.m_bv ) ) +{} + + +// destructor + +inline +sc_fxnum_subref::~sc_fxnum_subref() +{ + delete &m_bv; +} + + +// assignment operators + +inline +sc_fxnum_subref& +sc_fxnum_subref::operator = ( const sc_fxnum_subref& a ) +{ + if( &a != this ) + { + m_bv = static_cast<sc_bv_base>( a ); + set(); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + } + return *this; +} + +inline +sc_fxnum_subref& +sc_fxnum_subref::operator = ( const sc_fxnum_fast_subref& a ) +{ + m_bv = static_cast<sc_bv_base>( a ); + set(); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +#define DEFN_ASN_OP_T(tp) \ +inline \ +sc_fxnum_subref& \ +sc_fxnum_subref::operator = ( tp a ) \ +{ \ + m_bv = a; \ + set(); \ + SC_FXNUM_OBSERVER_WRITE_( m_num ) \ + return *this; \ +} + +DEFN_ASN_OP_T(const sc_bv_base&) +DEFN_ASN_OP_T(const sc_lv_base&) +DEFN_ASN_OP_T(const char*) +DEFN_ASN_OP_T(const bool*) +DEFN_ASN_OP_T(const sc_signed&) +DEFN_ASN_OP_T(const sc_unsigned&) +DEFN_ASN_OP_T(const sc_int_base&) +DEFN_ASN_OP_T(const sc_uint_base&) +DEFN_ASN_OP_T(int64) +DEFN_ASN_OP_T(uint64) +DEFN_ASN_OP_T(int) +DEFN_ASN_OP_T(unsigned int) +DEFN_ASN_OP_T(long) +DEFN_ASN_OP_T(unsigned long) +DEFN_ASN_OP_T(char) + +#undef DEFN_ASN_OP_T + + +#define DEFN_ASN_OP_T(op,tp) \ +inline \ +sc_fxnum_subref& \ +sc_fxnum_subref::operator op ## = ( tp a ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( m_num ) \ + get(); \ + m_bv = m_bv op a; \ + set(); \ + SC_FXNUM_OBSERVER_WRITE_( m_num ) \ + return *this; \ +} + +#define DEFN_ASN_OP(op) \ +inline \ +sc_fxnum_subref& \ +sc_fxnum_subref::operator op ## = ( const sc_fxnum_subref& a ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( m_num ) \ + get(); \ + m_bv = m_bv op static_cast<sc_bv_base>( a ); \ + set(); \ + SC_FXNUM_OBSERVER_WRITE_( m_num ) \ + return *this; \ +} \ + \ +inline \ +sc_fxnum_subref& \ +sc_fxnum_subref::operator op ## = ( const sc_fxnum_fast_subref& a ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( m_num ) \ + get(); \ + m_bv = m_bv op static_cast<sc_bv_base>( a ); \ + set(); \ + SC_FXNUM_OBSERVER_WRITE_( m_num ) \ + return *this; \ +} \ + \ +DEFN_ASN_OP_T(op,const sc_bv_base&) \ +DEFN_ASN_OP_T(op,const sc_lv_base&) + +DEFN_ASN_OP(&) +DEFN_ASN_OP(|) +DEFN_ASN_OP(^) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP + + +// relational operators + +#define DEFN_REL_OP_T(op,tp) \ +inline \ +bool \ +operator op ( const sc_fxnum_subref& a, tp b ) \ +{ \ + return ( static_cast<sc_bv_base>( a ) op b ); \ +} \ + \ +inline \ +bool \ +operator op ( tp a, const sc_fxnum_subref& b ) \ +{ \ + return ( static_cast<sc_bv_base>( b ) op a ); \ +} + +#define DEFN_REL_OP(op) \ +inline \ +bool \ +operator op ( const sc_fxnum_subref& a, const sc_fxnum_subref& b ) \ +{ \ + return ( static_cast<sc_bv_base>( a ) op static_cast<sc_bv_base>( b ) ); \ +} \ + \ +inline \ +bool \ +operator op ( const sc_fxnum_subref& a, const sc_fxnum_fast_subref& b ) \ +{ \ + return ( static_cast<sc_bv_base>( a ) op static_cast<sc_bv_base>( b ) ); \ +} \ + \ +DEFN_REL_OP_T(op,const sc_bv_base&) \ +DEFN_REL_OP_T(op,const sc_lv_base&) \ +DEFN_REL_OP_T(op,const char*) \ +DEFN_REL_OP_T(op,const bool*) \ +DEFN_REL_OP_T(op,const sc_signed&) \ +DEFN_REL_OP_T(op,const sc_unsigned&) \ +DEFN_REL_OP_T(op,int) \ +DEFN_REL_OP_T(op,unsigned int) \ +DEFN_REL_OP_T(op,long) \ +DEFN_REL_OP_T(op,unsigned long) + +DEFN_REL_OP(==) +DEFN_REL_OP(!=) + +#undef DEFN_REL_OP_T +#undef DEFN_REL_OP + + +// reduce functions + +#define DEFN_RED_FNC(fnc) \ +inline \ +bool \ +sc_fxnum_subref::fnc() const \ +{ \ + SC_FXNUM_OBSERVER_READ_( m_num ) \ + get(); \ + return static_cast<bool>( m_bv.fnc() ); \ +} + +DEFN_RED_FNC(and_reduce) +DEFN_RED_FNC(nand_reduce) +DEFN_RED_FNC(or_reduce) +DEFN_RED_FNC(nor_reduce) +DEFN_RED_FNC(xor_reduce) +DEFN_RED_FNC(xnor_reduce) + +#undef DEFN_RED_FNC + + +// query parameter + +inline +int +sc_fxnum_subref::length() const +{ + return m_bv.length(); +} + + +// explicit conversions + +inline +int +sc_fxnum_subref::to_int() const +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_int(); +} + +inline +int64 +sc_fxnum_subref::to_int64() const +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_int64(); +} + +inline +unsigned int +sc_fxnum_subref::to_uint() const +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_uint(); +} + +inline +uint64 +sc_fxnum_subref::to_uint64() const +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_uint64(); +} + +inline +long +sc_fxnum_subref::to_long() const +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_long(); +} + +inline +unsigned long +sc_fxnum_subref::to_ulong() const +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_ulong(); +} + + +#ifdef SC_DT_DEPRECATED + +inline +int +sc_fxnum_subref::to_signed() const +{ + return to_int(); +} + +inline +unsigned int +sc_fxnum_subref::to_unsigned() const +{ + return to_uint(); +} + +#endif + + +inline +const std::string +sc_fxnum_subref::to_string() const +{ + get(); + return m_bv.to_string(); +} + +inline +const std::string +sc_fxnum_subref::to_string( sc_numrep numrep ) const +{ + get(); + return m_bv.to_string( numrep ); +} + +inline +const std::string +sc_fxnum_subref::to_string( sc_numrep numrep, bool w_prefix ) const +{ + get(); + return m_bv.to_string( numrep, w_prefix ); +} + + +// implicit conversion + +inline +sc_fxnum_subref::operator sc_bv_base () const +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + get(); + return m_bv; +} + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_fxnum_subref& a ) +{ + a.print( os ); + return os; +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_fxnum_subref& a ) +{ + a.scan( is ); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast_subref +// +// Proxy class for part-selection in class sc_fxnum_fast, +// behaves like sc_bv_base. +// ---------------------------------------------------------------------------- + +// constructor + +inline +sc_fxnum_fast_subref::sc_fxnum_fast_subref( sc_fxnum_fast& num_, + int from_, int to_ ) + : m_num( num_ ), m_from( from_ ), m_to( to_ ), + m_bv( *new sc_bv_base( sc_max( m_from, m_to ) - + sc_min( m_from, m_to ) + 1 ) ) +{} + + +// copy constructor + +inline +sc_fxnum_fast_subref::sc_fxnum_fast_subref( const sc_fxnum_fast_subref& a ) + : m_num( a.m_num ), m_from( a.m_from ), m_to( a.m_to ), + m_bv( *new sc_bv_base( a.m_bv ) ) +{} + + +// destructor + +inline +sc_fxnum_fast_subref::~sc_fxnum_fast_subref() +{ + delete &m_bv; +} + + +// assignment operators + +inline +sc_fxnum_fast_subref& +sc_fxnum_fast_subref::operator = ( const sc_fxnum_subref& a ) +{ + m_bv = static_cast<sc_bv_base>( a ); + set(); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_subref& +sc_fxnum_fast_subref::operator = ( const sc_fxnum_fast_subref& a ) +{ + if( &a != this ) + { + m_bv = static_cast<sc_bv_base>( a ); + set(); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + } + return *this; +} + +#define DEFN_ASN_OP_T(tp) \ +inline \ +sc_fxnum_fast_subref& \ +sc_fxnum_fast_subref::operator = ( tp a ) \ +{ \ + m_bv = a; \ + set(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) \ + return *this; \ +} + +DEFN_ASN_OP_T(const sc_bv_base&) +DEFN_ASN_OP_T(const sc_lv_base&) +DEFN_ASN_OP_T(const char*) +DEFN_ASN_OP_T(const bool*) +DEFN_ASN_OP_T(const sc_signed&) +DEFN_ASN_OP_T(const sc_unsigned&) +DEFN_ASN_OP_T(const sc_int_base&) +DEFN_ASN_OP_T(const sc_uint_base&) +DEFN_ASN_OP_T(int64) +DEFN_ASN_OP_T(uint64) +DEFN_ASN_OP_T(int) +DEFN_ASN_OP_T(unsigned int) +DEFN_ASN_OP_T(long) +DEFN_ASN_OP_T(unsigned long) +DEFN_ASN_OP_T(char) + +#undef DEFN_ASN_OP_T + + +#define DEFN_ASN_OP_T(op,tp) \ +inline \ +sc_fxnum_fast_subref& \ +sc_fxnum_fast_subref::operator op ## = ( tp a ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) \ + get(); \ + m_bv = m_bv op a; \ + set(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) \ + return *this; \ +} + +#define DEFN_ASN_OP(op) \ +inline \ +sc_fxnum_fast_subref& \ +sc_fxnum_fast_subref::operator op ## = ( const sc_fxnum_subref& a ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) \ + get(); \ + m_bv = m_bv op static_cast<sc_bv_base>( a ); \ + set(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) \ + return *this; \ +} \ + \ +inline \ +sc_fxnum_fast_subref& \ +sc_fxnum_fast_subref::operator op ## = ( const sc_fxnum_fast_subref& a ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) \ + get(); \ + m_bv = m_bv op static_cast<sc_bv_base>( a ); \ + set(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) \ + return *this; \ +} \ + \ +DEFN_ASN_OP_T(op,const sc_bv_base&) \ +DEFN_ASN_OP_T(op,const sc_lv_base&) + +DEFN_ASN_OP(&) +DEFN_ASN_OP(|) +DEFN_ASN_OP(^) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP + + +// relational operators + +#define DEFN_REL_OP_T(op,tp) \ +inline \ +bool \ +operator op ( const sc_fxnum_fast_subref& a, tp b ) \ +{ \ + return ( static_cast<sc_bv_base>( a ) op b ); \ +} \ + \ +inline \ +bool \ +operator op ( tp a, const sc_fxnum_fast_subref& b ) \ +{ \ + return ( static_cast<sc_bv_base>( b ) op a ); \ +} + +#define DEFN_REL_OP(op) \ +inline \ +bool \ +operator op ( const sc_fxnum_fast_subref& a, const sc_fxnum_fast_subref& b ) \ +{ \ + return ( static_cast<sc_bv_base>( a ) op static_cast<sc_bv_base>( b ) ); \ +} \ + \ +inline \ +bool \ +operator op ( const sc_fxnum_fast_subref& a, const sc_fxnum_subref& b ) \ +{ \ + return ( static_cast<sc_bv_base>( a ) op static_cast<sc_bv_base>( b ) ); \ +} \ + \ +DEFN_REL_OP_T(op,const sc_bv_base&) \ +DEFN_REL_OP_T(op,const sc_lv_base&) \ +DEFN_REL_OP_T(op,const char*) \ +DEFN_REL_OP_T(op,const bool*) \ +DEFN_REL_OP_T(op,const sc_signed&) \ +DEFN_REL_OP_T(op,const sc_unsigned&) \ +DEFN_REL_OP_T(op,int) \ +DEFN_REL_OP_T(op,unsigned int) \ +DEFN_REL_OP_T(op,long) \ +DEFN_REL_OP_T(op,unsigned long) + +DEFN_REL_OP(==) +DEFN_REL_OP(!=) + +#undef DEFN_REL_OP_T +#undef DEFN_REL_OP + + +// reduce functions + +#define DEFN_RED_FNC(fnc) \ +inline \ +bool \ +sc_fxnum_fast_subref::fnc() const \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) \ + get(); \ + return static_cast<bool>( m_bv.fnc() ); \ +} + +DEFN_RED_FNC(and_reduce) +DEFN_RED_FNC(nand_reduce) +DEFN_RED_FNC(or_reduce) +DEFN_RED_FNC(nor_reduce) +DEFN_RED_FNC(xor_reduce) +DEFN_RED_FNC(xnor_reduce) + +#undef DEFN_RED_FNC + + +// query parameter + +inline +int +sc_fxnum_fast_subref::length() const +{ + return m_bv.length(); +} + + +// explicit conversions + +inline +int +sc_fxnum_fast_subref::to_int() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_int(); +} + +inline +int64 +sc_fxnum_fast_subref::to_int64() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_int64(); +} + +inline +unsigned int +sc_fxnum_fast_subref::to_uint() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_uint(); +} + +inline +uint64 +sc_fxnum_fast_subref::to_uint64() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_uint64(); +} + +inline +long +sc_fxnum_fast_subref::to_long() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_long(); +} + +inline +unsigned long +sc_fxnum_fast_subref::to_ulong() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_ulong(); +} + + +#ifdef SC_DT_DEPRECATED + +inline +int +sc_fxnum_fast_subref::to_signed() const +{ + return to_int(); +} + +inline +unsigned int +sc_fxnum_fast_subref::to_unsigned() const +{ + return to_uint(); +} + +#endif + + +inline +const std::string +sc_fxnum_fast_subref::to_string() const +{ + get(); + return m_bv.to_string(); +} + +inline +const std::string +sc_fxnum_fast_subref::to_string( sc_numrep numrep ) const +{ + get(); + return m_bv.to_string( numrep ); +} + +inline +const std::string +sc_fxnum_fast_subref::to_string( sc_numrep numrep, bool w_prefix ) const +{ + get(); + return m_bv.to_string( numrep, w_prefix ); +} + + +// implicit conversion + +inline +sc_fxnum_fast_subref::operator sc_bv_base () const +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + get(); + return m_bv; +} + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_fxnum_fast_subref& a ) +{ + a.print( os ); + return os; +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_fxnum_fast_subref& a ) +{ + a.scan( is ); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum +// +// Base class for the fixed-point types; arbitrary precision. +// ---------------------------------------------------------------------------- + +inline +sc_fxnum_observer* +sc_fxnum::observer() const +{ + return m_observer; +} + + +inline +void +sc_fxnum::cast() +{ + SC_ERROR_IF_( ! m_rep->is_normal(), sc_core::SC_ID_INVALID_FX_VALUE_ ); + + if( m_params.cast_switch() == SC_ON ) + m_rep->cast( m_params, m_q_flag, m_o_flag ); +} + + +// constructors + +inline +sc_fxnum::sc_fxnum( const sc_fxtype_params& type_params_, + sc_enc enc_, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: m_rep( new scfx_rep ), + m_params( type_params_, enc_, cast_sw ), + m_q_flag( false ), + m_o_flag( false ), + m_observer( observer_ ) +{ + SC_FXNUM_OBSERVER_DEFAULT_ + SC_FXNUM_OBSERVER_CONSTRUCT_( *this ) +} + +#define DEFN_CTOR_T(tp,arg) \ +inline \ +sc_fxnum::sc_fxnum( tp a, \ + const sc_fxtype_params& type_params_, \ + sc_enc enc_, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: m_rep( new scfx_rep( arg ) ), \ + m_params( type_params_, enc_, cast_sw ), \ + m_q_flag( false ), \ + m_o_flag( false ), \ + m_observer( observer_ ) \ +{ \ + SC_FXNUM_OBSERVER_DEFAULT_ \ + cast(); \ + SC_FXNUM_OBSERVER_CONSTRUCT_( *this ) \ + SC_FXNUM_OBSERVER_WRITE_( *this ) \ +} + +#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp,a) +#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp,*a.m_rep) +#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp,a.to_double()) +#define DEFN_CTOR_T_D(tp) DEFN_CTOR_T(tp,a.value()) + +DEFN_CTOR_T_A(int) +DEFN_CTOR_T_A(unsigned int) +DEFN_CTOR_T_A(long) +DEFN_CTOR_T_A(unsigned long) +DEFN_CTOR_T_A(float) +DEFN_CTOR_T_A(double) +DEFN_CTOR_T_A(const char*) +DEFN_CTOR_T_B(const sc_fxval&) +DEFN_CTOR_T_C(const sc_fxval_fast&) +DEFN_CTOR_T_B(const sc_fxnum&) +DEFN_CTOR_T_C(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTOR_T_A(int64) +DEFN_CTOR_T_A(uint64) +DEFN_CTOR_T_D(const sc_int_base&) +DEFN_CTOR_T_D(const sc_uint_base&) +DEFN_CTOR_T_A(const sc_signed&) +DEFN_CTOR_T_A(const sc_unsigned&) +#endif + +#undef DEFN_CTOR_T +#undef DEFN_CTOR_T_A +#undef DEFN_CTOR_T_B +#undef DEFN_CTOR_T_C +#undef DEFN_CTOR_T_D + + +inline +sc_fxnum::~sc_fxnum() +{ + SC_FXNUM_OBSERVER_DESTRUCT_( *this ) + delete m_rep; +} + + +// internal use only; +inline +const scfx_rep* +sc_fxnum::get_rep() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return m_rep; +} + + +// unary operators + +inline +const sc_fxval +sc_fxnum::operator - () const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return sc_fxval( sc_dt::neg_scfx_rep( *m_rep ) ); +} + +inline +const sc_fxval +sc_fxnum::operator + () const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return sc_fxval( new scfx_rep( *m_rep ) ); +} + + +// unary functions + +inline +void +neg( sc_fxval& c, const sc_fxnum& a ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + c.set_rep( sc_dt::neg_scfx_rep( *a.m_rep ) ); +} + +inline +void +neg( sc_fxnum& c, const sc_fxnum& a ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + delete c.m_rep; + c.m_rep = sc_dt::neg_scfx_rep( *a.m_rep ); + c.cast(); + SC_FXNUM_OBSERVER_WRITE_( c ) +} + + +// binary operators + +#define DEFN_BIN_OP_T(op,fnc,tp) \ +inline \ +const sc_fxval \ +operator op ( const sc_fxnum& a, tp b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + sc_fxval tmp( b ); \ + return sc_fxval( sc_dt::fnc ## _scfx_rep( *a.m_rep, *tmp.get_rep() ) ); \ +} \ + \ +inline \ +const sc_fxval \ +operator op ( tp a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( b ) \ + sc_fxval tmp( a ); \ + return sc_fxval( sc_dt::fnc ## _scfx_rep( *tmp.get_rep(), *b.m_rep ) ); \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_BIN_OP_OTHER(op,fnc) \ +DEFN_BIN_OP_T(op,fnc,int64) \ +DEFN_BIN_OP_T(op,fnc,uint64) \ +DEFN_BIN_OP_T(op,fnc,const sc_int_base&) \ +DEFN_BIN_OP_T(op,fnc,const sc_uint_base&) \ +DEFN_BIN_OP_T(op,fnc,const sc_signed&) \ +DEFN_BIN_OP_T(op,fnc,const sc_unsigned&) +#else +#define DEFN_BIN_OP_OTHER(op,fnc) +#endif + +#define DEFN_BIN_OP(op,fnc) \ +inline \ +const sc_fxval \ +operator op ( const sc_fxnum& a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + SC_FXNUM_OBSERVER_READ_( b ) \ + return sc_fxval( sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.m_rep ) ); \ +} \ + \ +inline \ +const sc_fxval \ +operator op ( const sc_fxnum& a, const sc_fxval& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + return sc_fxval( sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.get_rep() ) ); \ +} \ + \ +inline \ +const sc_fxval \ +operator op ( const sc_fxval& a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( b ) \ + return sc_fxval( sc_dt::fnc ## _scfx_rep( *a.get_rep(), *b.m_rep ) ); \ +} \ + \ +DEFN_BIN_OP_T(op,fnc,int) \ +DEFN_BIN_OP_T(op,fnc,unsigned int) \ +DEFN_BIN_OP_T(op,fnc,long) \ +DEFN_BIN_OP_T(op,fnc,unsigned long) \ +DEFN_BIN_OP_T(op,fnc,float) \ +DEFN_BIN_OP_T(op,fnc,double) \ +DEFN_BIN_OP_T(op,fnc,const char*) \ +DEFN_BIN_OP_T(op,fnc,const sc_fxval_fast&) \ +DEFN_BIN_OP_T(op,fnc,const sc_fxnum_fast&) \ +DEFN_BIN_OP_OTHER(op,fnc) + +DEFN_BIN_OP(*,mult) +DEFN_BIN_OP(+,add) +DEFN_BIN_OP(-,sub) +// don't use macros +//DEFN_BIN_OP(/,div) +inline +const sc_fxval +operator / ( const sc_fxnum& a, const sc_fxnum& b ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + SC_FXNUM_OBSERVER_READ_( b ) + return sc_fxval( sc_dt::div_scfx_rep( *a.m_rep, *b.m_rep ) ); +} + +inline +const sc_fxval +operator / ( const sc_fxnum& a, const sc_fxval& b ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + return sc_fxval( sc_dt::div_scfx_rep( *a.m_rep, *b.get_rep() ) ); +} + +inline +const sc_fxval +operator / ( const sc_fxval& a, const sc_fxnum& b ) +{ + SC_FXNUM_OBSERVER_READ_( b ) + return sc_fxval( sc_dt::div_scfx_rep( *a.get_rep(), *b.m_rep ) ); +} + +DEFN_BIN_OP_T(/,div,int) +DEFN_BIN_OP_T(/,div,unsigned int) +DEFN_BIN_OP_T(/,div,long) +DEFN_BIN_OP_T(/,div,unsigned long) +DEFN_BIN_OP_T(/,div,float) +DEFN_BIN_OP_T(/,div,double) +DEFN_BIN_OP_T(/,div,const char*) +DEFN_BIN_OP_T(/,div,const sc_fxval_fast&) +DEFN_BIN_OP_T(/,div,const sc_fxnum_fast&) +//DEFN_BIN_OP_OTHER(/,div) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_BIN_OP_T(/,div,int64) +DEFN_BIN_OP_T(/,div,uint64) +DEFN_BIN_OP_T(/,div,const sc_int_base&) +DEFN_BIN_OP_T(/,div,const sc_uint_base&) +DEFN_BIN_OP_T(/,div,const sc_signed&) +DEFN_BIN_OP_T(/,div,const sc_unsigned&) +#endif + +#undef DEFN_BIN_OP_T +#undef DEFN_BIN_OP_OTHER +#undef DEFN_BIN_OP + + +inline +const sc_fxval +operator << ( const sc_fxnum& a, int b ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + return sc_fxval( sc_dt::lsh_scfx_rep( *a.m_rep, b ) ); +} + +inline +const sc_fxval +operator >> ( const sc_fxnum& a, int b ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + return sc_fxval( sc_dt::rsh_scfx_rep( *a.m_rep, b ) ); +} + + +// binary functions + +#define DEFN_BIN_FNC_T(fnc,tp) \ +inline \ +void \ +fnc ( sc_fxval& c, const sc_fxnum& a, tp b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + sc_fxval tmp( b ); \ + c.set_rep( sc_dt::fnc ## _scfx_rep( *a.m_rep, *tmp.get_rep() ) ); \ +} \ + \ +inline \ +void \ +fnc ( sc_fxval& c, tp a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( b ) \ + sc_fxval tmp( a ); \ + c.set_rep( sc_dt::fnc ## _scfx_rep( *tmp.get_rep(), *b.m_rep ) ); \ +} \ + \ +inline \ +void \ +fnc ( sc_fxnum& c, const sc_fxnum& a, tp b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + sc_fxval tmp( b ); \ + delete c.m_rep; \ + c.m_rep = sc_dt::fnc ## _scfx_rep( *a.m_rep, *tmp.get_rep() ); \ + c.cast(); \ + SC_FXNUM_OBSERVER_WRITE_( c ) \ +} \ + \ +inline \ +void \ +fnc ( sc_fxnum& c, tp a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( b ) \ + sc_fxval tmp( a ); \ + delete c.m_rep; \ + c.m_rep = sc_dt::fnc ## _scfx_rep( *tmp.get_rep(), *b.m_rep ); \ + c.cast(); \ + SC_FXNUM_OBSERVER_WRITE_( c ) \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_BIN_FNC_OTHER(fnc) \ +DEFN_BIN_FNC_T(fnc,int64) \ +DEFN_BIN_FNC_T(fnc,uint64) \ +DEFN_BIN_FNC_T(fnc,const sc_int_base&) \ +DEFN_BIN_FNC_T(fnc,const sc_uint_base&) \ +DEFN_BIN_FNC_T(fnc,const sc_signed&) \ +DEFN_BIN_FNC_T(fnc,const sc_unsigned&) +#else +#define DEFN_BIN_FNC_OTHER(fnc) +#endif + +#define DEFN_BIN_FNC(fnc) \ +inline \ +void \ +fnc ( sc_fxval& c, const sc_fxnum& a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + SC_FXNUM_OBSERVER_READ_( b ) \ + c.set_rep( sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.m_rep ) ); \ +} \ + \ +inline \ +void \ +fnc ( sc_fxnum& c, const sc_fxnum& a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + SC_FXNUM_OBSERVER_READ_( b ) \ + delete c.m_rep; \ + c.m_rep = sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.m_rep ); \ + c.cast(); \ + SC_FXNUM_OBSERVER_WRITE_( c ) \ +} \ + \ +inline \ +void \ +fnc ( sc_fxval& c, const sc_fxnum& a, const sc_fxval& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + c.set_rep( sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.get_rep() ) ); \ +} \ + \ +inline \ +void \ +fnc ( sc_fxval& c, const sc_fxval& a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( b ) \ + c.set_rep( sc_dt::fnc ## _scfx_rep( *a.get_rep(), *b.m_rep ) ); \ +} \ + \ +inline \ +void \ +fnc ( sc_fxnum& c, const sc_fxnum& a, const sc_fxval& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + delete c.m_rep; \ + c.m_rep = sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.get_rep() ); \ + c.cast(); \ + SC_FXNUM_OBSERVER_WRITE_( c ) \ +} \ + \ +inline \ +void \ +fnc ( sc_fxnum& c, const sc_fxval& a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( b ) \ + delete c.m_rep; \ + c.m_rep = sc_dt::fnc ## _scfx_rep( *a.get_rep(), *b.m_rep ); \ + c.cast(); \ + SC_FXNUM_OBSERVER_WRITE_( c ) \ +} \ + \ +DEFN_BIN_FNC_T(fnc,int) \ +DEFN_BIN_FNC_T(fnc,unsigned int) \ +DEFN_BIN_FNC_T(fnc,long) \ +DEFN_BIN_FNC_T(fnc,unsigned long) \ +DEFN_BIN_FNC_T(fnc,float) \ +DEFN_BIN_FNC_T(fnc,double) \ +DEFN_BIN_FNC_T(fnc,const char*) \ +DEFN_BIN_FNC_T(fnc,const sc_fxval_fast&) \ +DEFN_BIN_FNC_T(fnc,const sc_fxnum_fast&) \ +DEFN_BIN_FNC_OTHER(fnc) + +DEFN_BIN_FNC(mult) +DEFN_BIN_FNC(div) +DEFN_BIN_FNC(add) +DEFN_BIN_FNC(sub) + +#undef DEFN_BIN_FNC_T +#undef DEFN_BIN_FNC_OTHER +#undef DEFN_BIN_FNC + + +inline +void +lshift( sc_fxval& c, const sc_fxnum& a, int b ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + c.set_rep( sc_dt::lsh_scfx_rep( *a.m_rep, b ) ); +} + +inline +void +rshift( sc_fxval& c, const sc_fxnum& a, int b ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + c.set_rep( sc_dt::rsh_scfx_rep( *a.m_rep, b ) ); +} + +inline +void +lshift( sc_fxnum& c, const sc_fxnum& a, int b ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + delete c.m_rep; + c.m_rep = sc_dt::lsh_scfx_rep( *a.m_rep, b ); + c.cast(); + SC_FXNUM_OBSERVER_WRITE_( c ) +} + +inline +void +rshift( sc_fxnum& c, const sc_fxnum& a, int b ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + delete c.m_rep; + c.m_rep = sc_dt::rsh_scfx_rep( *a.m_rep, b ); + c.cast(); + SC_FXNUM_OBSERVER_WRITE_( c ) +} + + +// relational (including equality) operators + +#define DEFN_REL_OP_T(op,ret,tp) \ +inline \ +bool \ +operator op ( const sc_fxnum& a, tp b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + sc_fxval tmp( b ); \ + int result = sc_dt::cmp_scfx_rep( *a.m_rep, *tmp.get_rep() ); \ + return ( ret ); \ +} \ + \ +inline \ +bool \ +operator op ( tp a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( b ) \ + sc_fxval tmp( a ); \ + int result = sc_dt::cmp_scfx_rep( *tmp.get_rep(), *b.m_rep ); \ + return ( ret ); \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_REL_OP_OTHER(op,ret) \ +DEFN_REL_OP_T(op,ret,int64) \ +DEFN_REL_OP_T(op,ret,uint64) \ +DEFN_REL_OP_T(op,ret,const sc_int_base&) \ +DEFN_REL_OP_T(op,ret,const sc_uint_base&) \ +DEFN_REL_OP_T(op,ret,const sc_signed&) \ +DEFN_REL_OP_T(op,ret,const sc_unsigned&) +#else +#define DEFN_REL_OP_OTHER(op,ret) +#endif + +#define DEFN_REL_OP(op,ret) \ +inline \ +bool \ +operator op ( const sc_fxnum& a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + SC_FXNUM_OBSERVER_READ_( b ) \ + int result = sc_dt::cmp_scfx_rep( *a.m_rep, *b.m_rep ); \ + return ( ret ); \ +} \ + \ +inline \ +bool \ +operator op ( const sc_fxnum& a, const sc_fxval& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + int result = sc_dt::cmp_scfx_rep( *a.m_rep, *b.get_rep() ); \ + return ( ret ); \ +} \ + \ +inline \ +bool \ +operator op ( const sc_fxval& a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( b ) \ + int result = sc_dt::cmp_scfx_rep( *a.get_rep(), *b.m_rep ); \ + return ( ret ); \ +} \ + \ +DEFN_REL_OP_T(op,ret,int) \ +DEFN_REL_OP_T(op,ret,unsigned int) \ +DEFN_REL_OP_T(op,ret,long) \ +DEFN_REL_OP_T(op,ret,unsigned long) \ +DEFN_REL_OP_T(op,ret,float) \ +DEFN_REL_OP_T(op,ret,double) \ +DEFN_REL_OP_T(op,ret,const char*) \ +DEFN_REL_OP_T(op,ret,const sc_fxval_fast&) \ +DEFN_REL_OP_T(op,ret,const sc_fxnum_fast&) \ +DEFN_REL_OP_OTHER(op,ret) + +DEFN_REL_OP(<,result < 0) +DEFN_REL_OP(<=,result <= 0) +DEFN_REL_OP(>,result > 0 && result != 2) +DEFN_REL_OP(>=,result >= 0 && result != 2) +DEFN_REL_OP(==,result == 0) +DEFN_REL_OP(!=,result != 0) + +#undef DEFN_REL_OP_T +#undef DEFN_REL_OP_OTHER +#undef DEFN_REL_OP + + +// assignment operators + +inline +sc_fxnum& +sc_fxnum::operator = ( const sc_fxnum& a ) +{ + if( &a != this ) + { + SC_FXNUM_OBSERVER_READ_( a ) + *m_rep = *a.m_rep; + cast(); + SC_FXNUM_OBSERVER_WRITE_( *this ) + } + return *this; +} + +inline +sc_fxnum& +sc_fxnum::operator = ( const sc_fxval& a ) +{ + *m_rep = *a.get_rep(); + cast(); + SC_FXNUM_OBSERVER_WRITE_( *this ) + return *this; +} + +#define DEFN_ASN_OP_T(tp) \ +inline \ +sc_fxnum& \ +sc_fxnum::operator = ( tp a ) \ +{ \ + sc_fxval tmp( a ); \ + *m_rep = *tmp.get_rep(); \ + cast(); \ + SC_FXNUM_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +DEFN_ASN_OP_T(int) +DEFN_ASN_OP_T(unsigned int) +DEFN_ASN_OP_T(long) +DEFN_ASN_OP_T(unsigned long) +DEFN_ASN_OP_T(float) +DEFN_ASN_OP_T(double) +DEFN_ASN_OP_T(const char*) +DEFN_ASN_OP_T(const sc_fxval_fast&) +DEFN_ASN_OP_T(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_ASN_OP_T(int64) +DEFN_ASN_OP_T(uint64) +DEFN_ASN_OP_T(const sc_int_base&) +DEFN_ASN_OP_T(const sc_uint_base&) +DEFN_ASN_OP_T(const sc_signed&) +DEFN_ASN_OP_T(const sc_unsigned&) +#endif + +#undef DEFN_ASN_OP_T + + +#define DEFN_ASN_OP_T(op,fnc,tp) \ +inline \ +sc_fxnum& \ +sc_fxnum::operator op ( tp b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( *this ) \ + sc_fxval tmp( b ); \ + scfx_rep* new_rep = sc_dt::fnc ## _scfx_rep( *m_rep, *tmp.get_rep() ); \ + delete m_rep; \ + m_rep = new_rep; \ + cast(); \ + SC_FXNUM_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op,fnc) \ +DEFN_ASN_OP_T(op,fnc,int64) \ +DEFN_ASN_OP_T(op,fnc,uint64) \ +DEFN_ASN_OP_T(op,fnc,const sc_int_base&) \ +DEFN_ASN_OP_T(op,fnc,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,fnc,const sc_signed&) \ +DEFN_ASN_OP_T(op,fnc,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op,fnc) +#endif + +#define DEFN_ASN_OP(op,fnc) \ +inline \ +sc_fxnum& \ +sc_fxnum::operator op ( const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( *this ) \ + SC_FXNUM_OBSERVER_READ_( b ) \ + scfx_rep* new_rep = sc_dt::fnc ## _scfx_rep( *m_rep, *b.m_rep ); \ + delete m_rep; \ + m_rep = new_rep; \ + cast(); \ + SC_FXNUM_OBSERVER_WRITE_( *this ) \ + return *this; \ +} \ + \ +inline \ +sc_fxnum& \ +sc_fxnum::operator op ( const sc_fxval& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( *this ) \ + scfx_rep* new_rep = sc_dt::fnc ## _scfx_rep( *m_rep, *b.get_rep() ); \ + delete m_rep; \ + m_rep = new_rep; \ + cast(); \ + SC_FXNUM_OBSERVER_WRITE_( *this ) \ + return *this; \ +} \ + \ +DEFN_ASN_OP_T(op,fnc,int) \ +DEFN_ASN_OP_T(op,fnc,unsigned int) \ +DEFN_ASN_OP_T(op,fnc,long) \ +DEFN_ASN_OP_T(op,fnc,unsigned long) \ +DEFN_ASN_OP_T(op,fnc,float) \ +DEFN_ASN_OP_T(op,fnc,double) \ +DEFN_ASN_OP_T(op,fnc,const char*) \ +DEFN_ASN_OP_T(op,fnc,const sc_fxval_fast&) \ +DEFN_ASN_OP_T(op,fnc,const sc_fxnum_fast&) \ +DEFN_ASN_OP_OTHER(op,fnc) + +DEFN_ASN_OP(*=,mult) +DEFN_ASN_OP(/=,div) +DEFN_ASN_OP(+=,add) +DEFN_ASN_OP(-=,sub) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +inline +sc_fxnum& +sc_fxnum::operator <<= ( int b ) +{ + SC_FXNUM_OBSERVER_READ_( *this ) + m_rep->lshift( b ); + cast(); + SC_FXNUM_OBSERVER_WRITE_( *this ) + return *this; +} + +inline +sc_fxnum& +sc_fxnum::operator >>= ( int b ) +{ + SC_FXNUM_OBSERVER_READ_( *this ) + m_rep->rshift( b ); + cast(); + SC_FXNUM_OBSERVER_WRITE_( *this ) + return *this; +} + + +// auto-increment and auto-decrement + +inline +const sc_fxval +sc_fxnum::operator ++ ( int ) +{ + sc_fxval c( *this ); + (*this) += 1; + return c; +} + +inline +const sc_fxval +sc_fxnum::operator -- ( int ) +{ + sc_fxval c( *this ); + (*this) -= 1; + return c; +} + +inline +sc_fxnum& +sc_fxnum::operator ++ () +{ + (*this) += 1; + return *this; +} + +inline +sc_fxnum& +sc_fxnum::operator -- () +{ + (*this) -= 1; + return *this; +} + + +// bit selection + +inline +const sc_fxnum_bitref +sc_fxnum::operator [] ( int i ) const +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + return sc_fxnum_bitref( const_cast<sc_fxnum&>( *this ), + i - m_params.fwl() ); +} + +inline +sc_fxnum_bitref +sc_fxnum::operator [] ( int i ) +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + return sc_fxnum_bitref( *this, i - m_params.fwl() ); +} + +inline +const sc_fxnum_bitref +sc_fxnum::bit( int i ) const +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + return sc_fxnum_bitref( const_cast<sc_fxnum&>( *this ), + i - m_params.fwl() ); +} + +inline +sc_fxnum_bitref +sc_fxnum::bit( int i ) +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + return sc_fxnum_bitref( *this, i - m_params.fwl() ); +} + + +// part selection + +inline +const sc_fxnum_subref +sc_fxnum::operator () ( int i, int j ) const +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + + return sc_fxnum_subref( const_cast<sc_fxnum&>( *this ), + i - m_params.fwl(), j - m_params.fwl() ); +} + +inline +sc_fxnum_subref +sc_fxnum::operator () ( int i, int j ) +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + + return sc_fxnum_subref( *this, i - m_params.fwl(), j - m_params.fwl() ); +} + +inline +const sc_fxnum_subref +sc_fxnum::range( int i, int j ) const +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + + return sc_fxnum_subref( const_cast<sc_fxnum&>( *this ), + i - m_params.fwl(), j - m_params.fwl() ); +} + +inline +sc_fxnum_subref +sc_fxnum::range( int i, int j ) +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + + return sc_fxnum_subref( *this, i - m_params.fwl(), j - m_params.fwl() ); +} + + +inline +const sc_fxnum_subref +sc_fxnum::operator () () const +{ + return this->operator () ( m_params.wl() - 1, 0 ); +} + +inline +sc_fxnum_subref +sc_fxnum::operator () () +{ + return this->operator () ( m_params.wl() - 1, 0 ); +} + +inline +const sc_fxnum_subref +sc_fxnum::range() const +{ + return this->range( m_params.wl() - 1, 0 ); +} + +inline +sc_fxnum_subref +sc_fxnum::range() +{ + return this->range( m_params.wl() - 1, 0 ); +} + + +// implicit conversion + +inline +sc_fxnum::operator double() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return m_rep->to_double(); +} + + +// explicit conversion to primitive types + +inline +short +sc_fxnum::to_short() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return static_cast<short>( m_rep->to_double() ); +} + +inline +unsigned short +sc_fxnum::to_ushort() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return static_cast<unsigned short>( m_rep->to_double() ); +} + +inline +int +sc_fxnum::to_int() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return static_cast<int>( m_rep->to_double() ); +} + +inline +int64 +sc_fxnum::to_int64() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return static_cast<int64>( m_rep->to_double() ); +} + +inline +unsigned int +sc_fxnum::to_uint() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return static_cast<unsigned int>( m_rep->to_double() ); +} + +inline +uint64 +sc_fxnum::to_uint64() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return static_cast<uint64>( m_rep->to_double() ); +} + +inline +long +sc_fxnum::to_long() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return static_cast<long>( m_rep->to_double() ); +} + +inline +unsigned long +sc_fxnum::to_ulong() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return static_cast<unsigned long>( m_rep->to_double() ); +} + +inline +float +sc_fxnum::to_float() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return static_cast<float>( m_rep->to_double() ); +} + +inline +double +sc_fxnum::to_double() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return m_rep->to_double(); +} + + +// query value + +inline +bool +sc_fxnum::is_neg() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return m_rep->is_neg(); +} + +inline +bool +sc_fxnum::is_zero() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return m_rep->is_zero(); +} + +// internal use only; +inline +bool +sc_fxnum::is_normal() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return m_rep->is_normal(); +} + +inline +bool +sc_fxnum::quantization_flag() const +{ + return m_q_flag; +} + +inline +bool +sc_fxnum::overflow_flag() const +{ + return m_o_flag; +} + + +inline +const sc_fxval +sc_fxnum::value() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return sc_fxval( new scfx_rep( *m_rep ) ); +} + + +// query parameters + +inline +int +sc_fxnum::wl() const +{ + return m_params.wl(); +} + +inline +int +sc_fxnum::iwl() const +{ + return m_params.iwl(); +} + +inline +sc_q_mode +sc_fxnum::q_mode() const +{ + return m_params.q_mode(); +} + +inline +sc_o_mode +sc_fxnum::o_mode() const +{ + return m_params.o_mode(); +} + +inline +int +sc_fxnum::n_bits() const +{ + return m_params.n_bits(); +} + + +inline +const sc_fxtype_params& +sc_fxnum::type_params() const +{ + return m_params.type_params(); +} + + +inline +const sc_fxcast_switch& +sc_fxnum::cast_switch() const +{ + return m_params.cast_switch(); +} + + +// internal use only; +inline +void +sc_fxnum::observer_read() const +{ + SC_FXNUM_OBSERVER_READ_( *this ); +} + + +// internal use only; +inline +bool +sc_fxnum::get_bit( int i ) const +{ + return m_rep->get_bit( i ); +} + + +// protected methods and friend functions + +inline +bool +sc_fxnum::set_bit( int i, bool high ) +{ + if( high ) + return m_rep->set( i, m_params ); + else + return m_rep->clear( i, m_params ); +} + + +inline +bool +sc_fxnum::get_slice( int i, int j, sc_bv_base& bv ) const +{ + return m_rep->get_slice( i, j, m_params, bv ); +} + +inline +bool +sc_fxnum::set_slice( int i, int j, const sc_bv_base& bv ) +{ + return m_rep->set_slice( i, j, m_params, bv ); +} + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_fxnum& a ) +{ + a.print( os ); + return os; +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_fxnum& a ) +{ + a.scan( is ); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast +// +// Base class for the fixed-point types; limited precision. +// ---------------------------------------------------------------------------- + +inline +sc_fxnum_fast_observer* +sc_fxnum_fast::observer() const +{ + return m_observer; +} + + +// constructors + +inline +sc_fxnum_fast::sc_fxnum_fast( const sc_fxtype_params& type_params_, + sc_enc enc_, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: m_val( 0.0 ), + m_params( type_params_, enc_, cast_sw ), + m_q_flag( false ), + m_o_flag( false ), + m_observer( observer_ ) +{ + SC_FXNUM_FAST_OBSERVER_DEFAULT_ + SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(*this) +} + +inline +sc_fxnum_fast::sc_fxnum_fast( const sc_fxnum_fast& a, + const sc_fxtype_params& type_params_, + sc_enc enc_, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: m_val( a.m_val ), + m_params( type_params_, enc_, cast_sw ), + m_q_flag( false ), + m_o_flag( false ), + m_observer( observer_ ) +{ + SC_FXNUM_FAST_OBSERVER_DEFAULT_ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + cast(); + SC_FXNUM_FAST_OBSERVER_CONSTRUCT_( *this ) + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) +} + +#define DEFN_CTOR_T(tp,arg) \ +inline \ +sc_fxnum_fast::sc_fxnum_fast( tp a, \ + const sc_fxtype_params& type_params_, \ + sc_enc enc_, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: m_val( arg ), \ + m_params( type_params_, enc_, cast_sw ), \ + m_q_flag( false ), \ + m_o_flag( false ), \ + m_observer( observer_ ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_DEFAULT_ \ + cast(); \ + SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(*this) \ + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) \ +} + +#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp,static_cast<double>( a )) +#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp,sc_fxval_fast::from_string( a )) +#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp,a.to_double()) + +DEFN_CTOR_T_A(int) +DEFN_CTOR_T_A(unsigned int) +DEFN_CTOR_T_A(long) +DEFN_CTOR_T_A(unsigned long) +DEFN_CTOR_T_A(float) +DEFN_CTOR_T_A(double) +DEFN_CTOR_T_B(const char*) +DEFN_CTOR_T_C(const sc_fxval&) +DEFN_CTOR_T_C(const sc_fxval_fast&) +DEFN_CTOR_T_C(const sc_fxnum&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTOR_T_A(int64) +DEFN_CTOR_T_A(uint64) +DEFN_CTOR_T_C(const sc_int_base&) +DEFN_CTOR_T_C(const sc_uint_base&) +DEFN_CTOR_T_C(const sc_signed&) +DEFN_CTOR_T_C(const sc_unsigned&) +#endif + +#undef DEFN_CTOR_T +#undef DEFN_CTOR_T_A +#undef DEFN_CTOR_T_B +#undef DEFN_CTOR_T_C +#undef DEFN_CTOR_T_D +#undef DEFN_CTOR_T_E + + +inline +sc_fxnum_fast::~sc_fxnum_fast() +{ + SC_FXNUM_FAST_OBSERVER_DESTRUCT_( *this ) +} + + +// internal use only; +inline +double +sc_fxnum_fast::get_val() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return m_val; +} + + +// unary operators + +inline +const sc_fxval_fast +sc_fxnum_fast::operator - () const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return sc_fxval_fast( - m_val ); +} + +inline +const sc_fxval_fast +sc_fxnum_fast::operator + () const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return sc_fxval_fast( m_val ); +} + + +// unary functions + +inline +void +neg( sc_fxval_fast& c, const sc_fxnum_fast& a ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + c.set_val( - a.m_val ); +} + +inline +void +neg( sc_fxnum_fast& c, const sc_fxnum_fast& a ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + c.m_val = - a.m_val; + c.cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) +} + + +// binary operators + +#define DEFN_BIN_OP_T(op,tp) \ +inline \ +const sc_fxval_fast \ +operator op ( const sc_fxnum_fast& a, tp b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + sc_fxval_fast tmp( b ); \ + return sc_fxval_fast( a.m_val op tmp.get_val() ); \ +} \ + \ +inline \ +const sc_fxval_fast \ +operator op ( tp a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + sc_fxval_fast tmp( a ); \ + return sc_fxval_fast( tmp.get_val() op b.m_val ); \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_BIN_OP_OTHER(op) \ +DEFN_BIN_OP_T(op,int64) \ +DEFN_BIN_OP_T(op,uint64) \ +DEFN_BIN_OP_T(op,const sc_int_base&) \ +DEFN_BIN_OP_T(op,const sc_uint_base&) \ +DEFN_BIN_OP_T(op,const sc_signed&) \ +DEFN_BIN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_BIN_OP_OTHER(op) +#endif + +#define DEFN_BIN_OP(op,dummy) \ +inline \ +const sc_fxval_fast \ +operator op ( const sc_fxnum_fast& a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + return sc_fxval_fast( a.m_val op b.m_val ); \ +} \ + \ +inline \ +const sc_fxval_fast \ +operator op ( const sc_fxnum_fast& a, const sc_fxval_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + return sc_fxval_fast( a.m_val op b.get_val() ); \ +} \ + \ +inline \ +const sc_fxval_fast \ +operator op ( const sc_fxval_fast& a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + return sc_fxval_fast( a.get_val() op b.m_val ); \ +} \ + \ +DEFN_BIN_OP_T(op,int) \ +DEFN_BIN_OP_T(op,unsigned int) \ +DEFN_BIN_OP_T(op,long) \ +DEFN_BIN_OP_T(op,unsigned long) \ +DEFN_BIN_OP_T(op,float) \ +DEFN_BIN_OP_T(op,double) \ +DEFN_BIN_OP_T(op,const char*) \ +DEFN_BIN_OP_OTHER(op) + +DEFN_BIN_OP(*,mult) +DEFN_BIN_OP(+,add) +DEFN_BIN_OP(-,sub) +//DEFN_BIN_OP(/,div) +inline +const sc_fxval_fast +operator / ( const sc_fxnum_fast& a, const sc_fxnum_fast& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + SC_FXNUM_FAST_OBSERVER_READ_( b ) + return sc_fxval_fast( a.m_val / b.m_val ); +} + +inline +const sc_fxval_fast +operator / ( const sc_fxnum_fast& a, const sc_fxval_fast& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + return sc_fxval_fast( a.m_val / b.get_val() ); +} + +inline +const sc_fxval_fast +operator / ( const sc_fxval_fast& a, const sc_fxnum_fast& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( b ) + return sc_fxval_fast( a.get_val() / b.m_val ); +} + +DEFN_BIN_OP_T(/,int) +DEFN_BIN_OP_T(/,unsigned int) +DEFN_BIN_OP_T(/,long) +DEFN_BIN_OP_T(/,unsigned long) +DEFN_BIN_OP_T(/,float) +DEFN_BIN_OP_T(/,double) +DEFN_BIN_OP_T(/,const char*) +//DEFN_BIN_OP_OTHER(/) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_BIN_OP_T(/,int64) +DEFN_BIN_OP_T(/,uint64) +DEFN_BIN_OP_T(/,const sc_int_base&) +DEFN_BIN_OP_T(/,const sc_uint_base&) +DEFN_BIN_OP_T(/,const sc_signed&) +DEFN_BIN_OP_T(/,const sc_unsigned&) +#endif + +#undef DEFN_BIN_OP_T +#undef DEFN_BIN_OP_OTHER +#undef DEFN_BIN_OP + + +inline +const sc_fxval_fast +operator << ( const sc_fxnum_fast& a, int b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + return sc_fxval_fast( a.m_val * scfx_pow2( b ) ); +} + +inline +const sc_fxval_fast +operator >> ( const sc_fxnum_fast& a, int b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + return sc_fxval_fast( a.m_val * scfx_pow2( -b ) ); +} + + +// binary functions + +#define DEFN_BIN_FNC_T(fnc,op,tp) \ +inline \ +void \ +fnc ( sc_fxval_fast& c, const sc_fxnum_fast& a, tp b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + sc_fxval_fast tmp( b ); \ + c.set_val( a.m_val op tmp.get_val() ); \ +} \ + \ +inline \ +void \ +fnc ( sc_fxval_fast& c, tp a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + sc_fxval_fast tmp( a ); \ + c.set_val( tmp.get_val() op b.m_val ); \ +} \ + \ +inline \ +void \ +fnc ( sc_fxnum_fast& c, const sc_fxnum_fast& a, tp b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + sc_fxval_fast tmp( b ); \ + c.m_val = a.m_val op tmp.get_val(); \ + c.cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) \ +} \ + \ +inline \ +void \ +fnc ( sc_fxnum_fast& c, tp a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + sc_fxval_fast tmp( a ); \ + c.m_val = tmp.get_val() op b.m_val; \ + c.cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_BIN_FNC_OTHER(fnc,op) \ +DEFN_BIN_FNC_T(fnc,op,int64) \ +DEFN_BIN_FNC_T(fnc,op,uint64) \ +DEFN_BIN_FNC_T(fnc,op,const sc_int_base&) \ +DEFN_BIN_FNC_T(fnc,op,const sc_uint_base&) \ +DEFN_BIN_FNC_T(fnc,op,const sc_signed&) \ +DEFN_BIN_FNC_T(fnc,op,const sc_unsigned&) +#else +#define DEFN_BIN_FNC_OTHER(fnc,op) +#endif + +#define DEFN_BIN_FNC(fnc,op) \ +inline \ +void \ +fnc ( sc_fxval_fast& c, const sc_fxnum_fast& a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + c.set_val( a.m_val op b.m_val ); \ +} \ + \ +inline \ +void \ +fnc ( sc_fxnum_fast& c, const sc_fxnum_fast& a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + c.m_val = a.m_val op b.m_val; \ + c.cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) \ +} \ + \ +inline \ +void \ +fnc ( sc_fxval_fast& c, const sc_fxnum_fast& a, const sc_fxval_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + c.set_val( a.m_val op b.get_val() ); \ +} \ + \ +inline \ +void \ +fnc ( sc_fxval_fast& c, const sc_fxval_fast& a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + c.set_val( a.get_val() op b.m_val ); \ +} \ + \ +inline \ +void \ +fnc ( sc_fxnum_fast& c, const sc_fxnum_fast& a, const sc_fxval_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + c.m_val = a.m_val op b.get_val(); \ + c.cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) \ +} \ + \ +inline \ +void \ +fnc ( sc_fxnum_fast& c, const sc_fxval_fast& a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + c.m_val = a.get_val() op b.m_val; \ + c.cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) \ +} \ + \ +DEFN_BIN_FNC_T(fnc,op,int) \ +DEFN_BIN_FNC_T(fnc,op,unsigned int) \ +DEFN_BIN_FNC_T(fnc,op,long) \ +DEFN_BIN_FNC_T(fnc,op,unsigned long) \ +DEFN_BIN_FNC_T(fnc,op,float) \ +DEFN_BIN_FNC_T(fnc,op,double) \ +DEFN_BIN_FNC_T(fnc,op,const char*) \ +DEFN_BIN_FNC_T(fnc,op,const sc_fxval&) \ +DEFN_BIN_FNC_T(fnc,op,const sc_fxnum&) \ +DEFN_BIN_FNC_OTHER(fnc,op) + +DEFN_BIN_FNC(mult,*) +DEFN_BIN_FNC(div,/) +DEFN_BIN_FNC(add,+) +DEFN_BIN_FNC(sub,-) + +#undef DEFN_BIN_FNC_T +#undef DEFN_BIN_FNC_OTHER +#undef DEFN_BIN_FNC + + +inline +void +lshift( sc_fxval_fast& c, const sc_fxnum_fast& a, int b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + c.set_val( a.m_val * scfx_pow2( b ) ); +} + +inline +void +rshift( sc_fxval_fast& c, const sc_fxnum_fast& a, int b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + c.set_val( a.m_val * scfx_pow2( -b ) ); +} + +inline +void +lshift( sc_fxnum_fast& c, const sc_fxnum_fast& a, int b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + c.m_val = a.m_val * scfx_pow2( b ); + c.cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) +} + +inline +void +rshift( sc_fxnum_fast& c, const sc_fxnum_fast& a, int b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + c.m_val = a.m_val * scfx_pow2( -b ); + c.cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) +} + + +// relational (including equality) operators + +#define DEFN_REL_OP_T(op,tp) \ +inline \ +bool \ +operator op ( const sc_fxnum_fast& a, tp b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + sc_fxval_fast tmp( b ); \ + return ( a.m_val op tmp.get_val() ); \ +} \ + \ +inline \ +bool \ +operator op ( tp a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + sc_fxval_fast tmp( a ); \ + return ( tmp.get_val() op b.m_val ); \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_REL_OP_OTHER(op) \ +DEFN_REL_OP_T(op,int64) \ +DEFN_REL_OP_T(op,uint64) \ +DEFN_REL_OP_T(op,const sc_int_base&) \ +DEFN_REL_OP_T(op,const sc_uint_base&) \ +DEFN_REL_OP_T(op,const sc_signed&) \ +DEFN_REL_OP_T(op,const sc_unsigned&) +#else +#define DEFN_REL_OP_OTHER(op) +#endif + +#define DEFN_REL_OP(op) \ +inline \ +bool \ +operator op ( const sc_fxnum_fast& a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + return ( a.m_val op b.m_val ); \ +} \ + \ +inline \ +bool \ +operator op ( const sc_fxnum_fast& a, const sc_fxval_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + return ( a.m_val op b.get_val() ); \ +} \ + \ +inline \ +bool \ +operator op ( const sc_fxval_fast& a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + return ( a.get_val() op b.m_val ); \ +} \ + \ +DEFN_REL_OP_T(op,int) \ +DEFN_REL_OP_T(op,unsigned int) \ +DEFN_REL_OP_T(op,long) \ +DEFN_REL_OP_T(op,unsigned long) \ +DEFN_REL_OP_T(op,float) \ +DEFN_REL_OP_T(op,double) \ +DEFN_REL_OP_T(op,const char*) \ +DEFN_REL_OP_OTHER(op) + +DEFN_REL_OP(<) +DEFN_REL_OP(<=) +DEFN_REL_OP(>) +DEFN_REL_OP(>=) +DEFN_REL_OP(==) +DEFN_REL_OP(!=) + +#undef DEFN_REL_OP_T +#undef DEFN_REL_OP_OTHER +#undef DEFN_REL_OP + + +// assignment operators + +inline +sc_fxnum_fast& +sc_fxnum_fast::operator = ( const sc_fxnum_fast& a ) +{ + if( &a != this ) + { + SC_FXNUM_FAST_OBSERVER_READ_( a ) + m_val = a.m_val; + cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) + } + return *this; +} + +inline +sc_fxnum_fast& +sc_fxnum_fast::operator = ( const sc_fxval_fast& a ) +{ + m_val = a.get_val(); + cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) + return *this; +} + +#define DEFN_ASN_OP_T(tp) \ +inline \ +sc_fxnum_fast& \ +sc_fxnum_fast::operator = ( tp a ) \ +{ \ + sc_fxval_fast tmp( a ); \ + m_val = tmp.get_val(); \ + cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +DEFN_ASN_OP_T(int) +DEFN_ASN_OP_T(unsigned int) +DEFN_ASN_OP_T(long) +DEFN_ASN_OP_T(unsigned long) +DEFN_ASN_OP_T(float) +DEFN_ASN_OP_T(double) +DEFN_ASN_OP_T(const char*) +DEFN_ASN_OP_T(const sc_fxval&) +DEFN_ASN_OP_T(const sc_fxnum&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_ASN_OP_T(int64) +DEFN_ASN_OP_T(uint64) +DEFN_ASN_OP_T(const sc_int_base&) +DEFN_ASN_OP_T(const sc_uint_base&) +DEFN_ASN_OP_T(const sc_signed&) +DEFN_ASN_OP_T(const sc_unsigned&) +#endif + +#undef DEFN_ASN_OP_T + + +#define DEFN_ASN_OP_T(op,tp) \ +inline \ +sc_fxnum_fast& \ +sc_fxnum_fast::operator op ( tp b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) \ + sc_fxval_fast tmp( b ); \ + m_val op tmp.get_val(); \ + cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op) \ +DEFN_ASN_OP_T(op,int64) \ +DEFN_ASN_OP_T(op,uint64) \ +DEFN_ASN_OP_T(op,const sc_int_base&) \ +DEFN_ASN_OP_T(op,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,const sc_signed&) \ +DEFN_ASN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op) +#endif + +#define DEFN_ASN_OP(op) \ +inline \ +sc_fxnum_fast& \ +sc_fxnum_fast::operator op ( const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + m_val op b.m_val; \ + cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} \ + \ +inline \ +sc_fxnum_fast& \ +sc_fxnum_fast::operator op ( const sc_fxval_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) \ + m_val op b.get_val(); \ + cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} \ + \ +DEFN_ASN_OP_T(op,int) \ +DEFN_ASN_OP_T(op,unsigned int) \ +DEFN_ASN_OP_T(op,long) \ +DEFN_ASN_OP_T(op,unsigned long) \ +DEFN_ASN_OP_T(op,float) \ +DEFN_ASN_OP_T(op,double) \ +DEFN_ASN_OP_T(op,const char*) \ +DEFN_ASN_OP_T(op,const sc_fxval&) \ +DEFN_ASN_OP_T(op,const sc_fxnum&) \ +DEFN_ASN_OP_OTHER(op) + +DEFN_ASN_OP(*=) +DEFN_ASN_OP(/=) +DEFN_ASN_OP(+=) +DEFN_ASN_OP(-=) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +inline +sc_fxnum_fast& +sc_fxnum_fast::operator <<= ( int b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + m_val *= scfx_pow2( b ); + cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) + return *this; +} + +inline +sc_fxnum_fast& +sc_fxnum_fast::operator >>= ( int b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + m_val *= scfx_pow2( -b ); + cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) + return *this; +} + + +// auto-increment and auto-decrement + +inline +const sc_fxval_fast +sc_fxnum_fast::operator ++ ( int ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + double c = m_val; + m_val = m_val + 1; + cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) + return sc_fxval_fast( c ); +} + +inline +const sc_fxval_fast +sc_fxnum_fast::operator -- ( int ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + double c = m_val; + m_val = m_val - 1; + cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) + return sc_fxval_fast( c ); +} + +inline +sc_fxnum_fast& +sc_fxnum_fast::operator ++ () +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + m_val = m_val + 1; + cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) + return *this; +} + +inline +sc_fxnum_fast& +sc_fxnum_fast::operator -- () +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + m_val = m_val - 1; + cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) + return *this; +} + + +// bit selection + +inline +const sc_fxnum_fast_bitref +sc_fxnum_fast::operator [] ( int i ) const +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + return sc_fxnum_fast_bitref( const_cast<sc_fxnum_fast&>( *this ), + i - m_params.fwl() ); +} + +inline +sc_fxnum_fast_bitref +sc_fxnum_fast::operator [] ( int i ) +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + return sc_fxnum_fast_bitref( *this, i - m_params.fwl() ); +} + +inline +const sc_fxnum_fast_bitref +sc_fxnum_fast::bit( int i ) const +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + return sc_fxnum_fast_bitref( const_cast<sc_fxnum_fast&>( *this ), + i - m_params.fwl() ); +} + +inline +sc_fxnum_fast_bitref +sc_fxnum_fast::bit( int i ) +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + return sc_fxnum_fast_bitref( *this, i - m_params.fwl() ); +} + + +// part selection + +inline +const sc_fxnum_fast_subref +sc_fxnum_fast::operator () ( int i, int j ) const +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + + return sc_fxnum_fast_subref( const_cast<sc_fxnum_fast&>( *this ), + i - m_params.fwl(), j - m_params.fwl() ); +} + +inline +sc_fxnum_fast_subref +sc_fxnum_fast::operator () ( int i, int j ) +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + + return sc_fxnum_fast_subref( *this, + i - m_params.fwl(), j - m_params.fwl() ); +} + +inline +const sc_fxnum_fast_subref +sc_fxnum_fast::range( int i, int j ) const +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + + return sc_fxnum_fast_subref( const_cast<sc_fxnum_fast&>( *this ), + i - m_params.fwl(), j - m_params.fwl() ); +} + +inline +sc_fxnum_fast_subref +sc_fxnum_fast::range( int i, int j ) +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + + return sc_fxnum_fast_subref( *this, + i - m_params.fwl(), j - m_params.fwl() ); +} + +inline +const sc_fxnum_fast_subref +sc_fxnum_fast::operator () () const +{ + return this->operator () ( m_params.wl() - 1, 0 ); +} + +inline +sc_fxnum_fast_subref +sc_fxnum_fast::operator () () +{ + return this->operator () ( m_params.wl() - 1, 0 ); +} + +inline +const sc_fxnum_fast_subref +sc_fxnum_fast::range() const +{ + return this->range( m_params.wl() - 1, 0 ); +} + +inline +sc_fxnum_fast_subref +sc_fxnum_fast::range() +{ + return this->range( m_params.wl() - 1, 0 ); +} + + +// implicit conversion + +inline +sc_fxnum_fast::operator double() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return m_val; +} + + +// explicit conversion to primitive types + +inline +short +sc_fxnum_fast::to_short() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return static_cast<short>( m_val ); +} + +inline +unsigned short +sc_fxnum_fast::to_ushort() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return static_cast<unsigned short>( m_val ); +} + +inline +int +sc_fxnum_fast::to_int() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return static_cast<int>( m_val ); +} + +inline +int64 +sc_fxnum_fast::to_int64() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return static_cast<int64>( m_val ); +} + +inline +unsigned int +sc_fxnum_fast::to_uint() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return static_cast<unsigned int>( m_val ); +} + +inline +uint64 +sc_fxnum_fast::to_uint64() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return static_cast<uint64>( m_val ); +} + +inline +long +sc_fxnum_fast::to_long() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return static_cast<long>( m_val ); +} + +inline +unsigned long +sc_fxnum_fast::to_ulong() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return static_cast<unsigned long>( m_val ); +} + +inline +float +sc_fxnum_fast::to_float() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return static_cast<float>( m_val ); +} + +inline +double +sc_fxnum_fast::to_double() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return m_val; +} + + +// query value + +inline +bool +sc_fxnum_fast::is_neg() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + scfx_ieee_double id( m_val ); + return ( id.negative() != 0 ); +} + +inline +bool +sc_fxnum_fast::is_zero() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + scfx_ieee_double id( m_val ); + return id.is_zero(); +} + +// internal use only; +inline +bool +sc_fxnum_fast::is_normal() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + scfx_ieee_double id( m_val ); + return ( id.is_normal() || id.is_subnormal() || id.is_zero() ); +} + + +inline +bool +sc_fxnum_fast::quantization_flag() const +{ + return m_q_flag; +} + +inline +bool +sc_fxnum_fast::overflow_flag() const +{ + return m_o_flag; +} + + +inline +const sc_fxval_fast +sc_fxnum_fast::value() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return sc_fxval_fast( m_val ); +} + + +// query parameters + +inline +int +sc_fxnum_fast::wl() const +{ + return m_params.wl(); +} + +inline +int +sc_fxnum_fast::iwl() const +{ + return m_params.iwl(); +} + +inline +sc_q_mode +sc_fxnum_fast::q_mode() const +{ + return m_params.q_mode(); +} + +inline +sc_o_mode +sc_fxnum_fast::o_mode() const +{ + return m_params.o_mode(); +} + +inline +int +sc_fxnum_fast::n_bits() const +{ + return m_params.n_bits(); +} + + +inline +const sc_fxtype_params& +sc_fxnum_fast::type_params() const +{ + return m_params.type_params(); +} + + +inline +const sc_fxcast_switch& +sc_fxnum_fast::cast_switch() const +{ + return m_params.cast_switch(); +} + + +// internal use only; +inline +void +sc_fxnum_fast::observer_read() const +{ + SC_FXNUM_OBSERVER_READ_( *this ); +} + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_fxnum_fast& a ) +{ + a.print( os ); + return os; +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_fxnum_fast& a ) +{ + a.scan( is ); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval +// +// Fixed-point value type; arbitrary precision. +// ---------------------------------------------------------------------------- + +// public constructors + +inline +sc_fxval::sc_fxval( const sc_fxnum& a, + sc_fxval_observer* observer_ ) +: m_rep( new scfx_rep( *a.get_rep() ) ), + m_observer( observer_ ) +{ + SC_FXVAL_OBSERVER_DEFAULT_ + SC_FXVAL_OBSERVER_CONSTRUCT_( *this ) + SC_FXVAL_OBSERVER_WRITE_( *this ) +} + +inline +sc_fxval::sc_fxval( const sc_fxnum_fast& a, + sc_fxval_observer* observer_ ) +: m_rep( new scfx_rep( a.to_double() ) ), + m_observer( observer_ ) +{ + SC_FXVAL_OBSERVER_DEFAULT_ + SC_FXVAL_OBSERVER_CONSTRUCT_( *this ) + SC_FXVAL_OBSERVER_WRITE_( *this ) +} + + +// binary operators + +#define DEFN_BIN_OP_T(op,fnc,tp) \ +inline \ +const sc_fxval \ +operator op ( const sc_fxval& a, tp b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( a ) \ + sc_fxval tmp( b ); \ + return sc_fxval( sc_dt::fnc ## _scfx_rep( *a.m_rep, *tmp.m_rep ) ); \ +} \ + \ +inline \ +const sc_fxval \ +operator op ( tp a, const sc_fxval& b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( b ) \ + sc_fxval tmp( a ); \ + return sc_fxval( sc_dt::fnc ## _scfx_rep( *tmp.m_rep, *b.m_rep ) ); \ +} + +#define DEFN_BIN_OP(op,fnc) \ +DEFN_BIN_OP_T(op,fnc,const sc_fxnum_fast&) + +DEFN_BIN_OP(*,mult) +DEFN_BIN_OP(+,add) +DEFN_BIN_OP(-,sub) +//DEFN_BIN_OP(/,div) +DEFN_BIN_OP_T(/,div,const sc_fxnum_fast&) + +#undef DEFN_BIN_OP_T +#undef DEFN_BIN_OP + + +// binary functions + +#define DEFN_BIN_FNC_T(fnc,tp) \ +inline \ +void \ +fnc ( sc_fxval& c, const sc_fxval& a, tp b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( a ) \ + sc_fxval tmp( b ); \ + delete c.m_rep; \ + c.m_rep = sc_dt::fnc ## _scfx_rep( *a.m_rep, *tmp.m_rep ); \ + SC_FXVAL_OBSERVER_WRITE_( c ) \ +} \ + \ +inline \ +void \ +fnc ( sc_fxval& c, tp a, const sc_fxval& b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( b ) \ + sc_fxval tmp( a ); \ + delete c.m_rep; \ + c.m_rep = sc_dt::fnc ## _scfx_rep( *tmp.m_rep, *b.m_rep ); \ + SC_FXVAL_OBSERVER_WRITE_( c ) \ +} + +#define DEFN_BIN_FNC(fnc) \ +DEFN_BIN_FNC_T(fnc,const sc_fxnum_fast&) + +DEFN_BIN_FNC(mult) +DEFN_BIN_FNC(div) +DEFN_BIN_FNC(add) +DEFN_BIN_FNC(sub) + +#undef DEFN_BIN_FNC_T +#undef DEFN_BIN_FNC + + +// relational (including equality) operators + +#define DEFN_REL_OP_T(op,ret,tp) \ +inline \ +bool \ +operator op ( const sc_fxval& a, tp b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( a ) \ + sc_fxval tmp( b ); \ + int result = sc_dt::cmp_scfx_rep( *a.m_rep, *tmp.m_rep ); \ + return ( ret ); \ +} \ + \ +inline \ +bool \ +operator op ( tp a, const sc_fxval& b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( b ) \ + sc_fxval tmp( a ); \ + int result = sc_dt::cmp_scfx_rep( *tmp.m_rep, *b.m_rep ); \ + return ( ret ); \ +} + + +#define DEFN_REL_OP(op,ret) \ +DEFN_REL_OP_T(op,ret,const sc_fxnum_fast&) + +DEFN_REL_OP(<,result < 0) +DEFN_REL_OP(<=,result <= 0) +DEFN_REL_OP(>,result > 0 && result != 2) +DEFN_REL_OP(>=,result >= 0 && result != 2) +DEFN_REL_OP(==,result == 0) +DEFN_REL_OP(!=,result != 0) + +#undef DEFN_REL_OP_T +#undef DEFN_REL_OP + + +// assignment operators + +inline +sc_fxval& +sc_fxval::operator = ( const sc_fxnum& a ) +{ + *m_rep = *a.get_rep(); + SC_FXVAL_OBSERVER_WRITE_( *this ) + return *this; +} + +#define DEFN_ASN_OP_T(tp) \ +inline \ +sc_fxval& \ +sc_fxval::operator = ( tp b ) \ +{ \ + sc_fxval tmp( b ); \ + *m_rep = *tmp.m_rep; \ + SC_FXVAL_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +DEFN_ASN_OP_T(const sc_fxnum_fast&) + +#undef DEFN_ASN_OP_T + + +#define DEFN_ASN_OP_T(op,fnc,tp) \ +inline \ +sc_fxval& \ +sc_fxval::operator op ( tp b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( *this ) \ + sc_fxval tmp( b ); \ + scfx_rep* new_rep = sc_dt::fnc ## _scfx_rep( *m_rep, *tmp.m_rep ); \ + delete m_rep; \ + m_rep = new_rep; \ + SC_FXVAL_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +#define DEFN_ASN_OP(op,fnc) \ +inline \ +sc_fxval& \ +sc_fxval::operator op ( const sc_fxnum& b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( *this ) \ + scfx_rep* new_rep = sc_dt::fnc ## _scfx_rep( *m_rep, *b.get_rep() ); \ + delete m_rep; \ + m_rep = new_rep; \ + SC_FXVAL_OBSERVER_WRITE_( *this ) \ + return *this; \ +} \ + \ +DEFN_ASN_OP_T(op,fnc,const sc_fxnum_fast&) + +DEFN_ASN_OP(*=,mult) +DEFN_ASN_OP(/=,div) +DEFN_ASN_OP(+=,add) +DEFN_ASN_OP(-=,sub) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval_fast +// +// Fixed-point value types; limited precision. +// ---------------------------------------------------------------------------- + +// public constructors + +inline +sc_fxval_fast::sc_fxval_fast( const sc_fxnum& a, + sc_fxval_fast_observer* observer_ ) +: m_val( a.to_double() ), + m_observer( observer_ ) +{ + SC_FXVAL_FAST_OBSERVER_DEFAULT_ + SC_FXVAL_FAST_OBSERVER_CONSTRUCT_( *this ) + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) +} + +inline +sc_fxval_fast::sc_fxval_fast( const sc_fxnum_fast& a, + sc_fxval_fast_observer* observer_ ) +: m_val( a.get_val() ), + m_observer( observer_ ) +{ + SC_FXVAL_FAST_OBSERVER_DEFAULT_ + SC_FXVAL_FAST_OBSERVER_CONSTRUCT_( *this ) + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) +} + + +// binary functions + +#define DEFN_BIN_FNC_T(fnc,op,tp) \ +inline \ +void \ +fnc ( sc_fxval_fast& c, const sc_fxval_fast& a, tp b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( a ) \ + sc_fxval_fast tmp( b ); \ + c.m_val = a.m_val op tmp.m_val; \ + SC_FXVAL_FAST_OBSERVER_WRITE_( c ) \ +} \ + \ +inline \ +void \ +fnc ( sc_fxval_fast& c, tp a, const sc_fxval_fast& b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( b ) \ + sc_fxval_fast tmp( a ); \ + c.m_val = tmp.m_val op b.m_val; \ + SC_FXVAL_FAST_OBSERVER_WRITE_( c ) \ +} + +#define DEFN_BIN_FNC(fnc,op) \ +DEFN_BIN_FNC_T(fnc,op,const sc_fxval&) \ +DEFN_BIN_FNC_T(fnc,op,const sc_fxnum&) + +DEFN_BIN_FNC(mult,*) +DEFN_BIN_FNC(div,/) +DEFN_BIN_FNC(add,+) +DEFN_BIN_FNC(sub,-) + +#undef DEFN_BIN_FNC_T +#undef DEFN_BIN_FNC + + +// assignment operators + +inline +sc_fxval_fast& +sc_fxval_fast::operator = ( const sc_fxnum_fast& a ) +{ + m_val = a.get_val(); + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) + return *this; +} + +#define DEFN_ASN_OP_T(tp) \ +inline \ +sc_fxval_fast& \ +sc_fxval_fast::operator = ( tp a ) \ +{ \ + sc_fxval_fast tmp( a ); \ + m_val = tmp.m_val; \ + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +DEFN_ASN_OP_T(const sc_fxnum&) + +#undef DEFN_ASN_OP_T + + +#define DEFN_ASN_OP_T(op,tp) \ +inline \ +sc_fxval_fast& \ +sc_fxval_fast::operator op ( tp b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) \ + sc_fxval_fast tmp( b ); \ + m_val op tmp.m_val; \ + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +#define DEFN_ASN_OP(op) \ +inline \ +sc_fxval_fast& \ +sc_fxval_fast::operator op ( const sc_fxnum_fast& b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) \ + m_val op b.get_val(); \ + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} \ + \ +DEFN_ASN_OP_T(op,const sc_fxnum&) + +DEFN_ASN_OP(*=) +DEFN_ASN_OP(/=) +DEFN_ASN_OP(+=) +DEFN_ASN_OP(-=) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxnum_observer.cpp b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum_observer.cpp new file mode 100644 index 000000000..709a3c50b --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum_observer.cpp @@ -0,0 +1,74 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxnum_observer.cpp - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_fxnum_observer.cpp,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#include "sysc/datatypes/fx/sc_fxnum_observer.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_observer +// +// Abstract base class for fixed-point types observers; arbitrary precision. +// ---------------------------------------------------------------------------- + +sc_fxnum_observer* (*sc_fxnum_observer::default_observer) () = 0; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast_observer +// +// Abstract base class for fixed-point types observers; limited precision. +// ---------------------------------------------------------------------------- + +sc_fxnum_fast_observer* (*sc_fxnum_fast_observer::default_observer) () = 0; + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxnum_observer.h b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum_observer.h new file mode 100644 index 000000000..2769df31b --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum_observer.h @@ -0,0 +1,219 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxnum_observer.h - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_fxnum_observer.h,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_FXNUM_OBSERVER_H +#define SC_FXNUM_OBSERVER_H + + +#include "sysc/datatypes/fx/sc_fxdefs.h" + + +namespace sc_dt +{ + +// classes defined in this module +class sc_fxnum_observer; +class sc_fxnum_fast_observer; + +// forward class declarations +class sc_fxnum; +class sc_fxnum_fast; + + +#ifdef SC_ENABLE_OBSERVERS + +#define SC_FXNUM_OBSERVER_CONSTRUCT_(object) \ + SC_OBSERVER_(object,sc_fxnum_observer*,construct) +#define SC_FXNUM_OBSERVER_DESTRUCT_(object) \ + SC_OBSERVER_(object,sc_fxnum_observer*,destruct) +#define SC_FXNUM_OBSERVER_READ_(object) \ + SC_OBSERVER_(object,sc_fxnum_observer*,read) +#define SC_FXNUM_OBSERVER_WRITE_(object) \ + SC_OBSERVER_(object,sc_fxnum_observer*,write) +#define SC_FXNUM_OBSERVER_DEFAULT_ \ + SC_OBSERVER_DEFAULT_(sc_fxnum_observer) + +#define SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(object) \ + SC_OBSERVER_(object,sc_fxnum_fast_observer*,construct) +#define SC_FXNUM_FAST_OBSERVER_DESTRUCT_(object) \ + SC_OBSERVER_(object,sc_fxnum_fast_observer*,destruct) +#define SC_FXNUM_FAST_OBSERVER_READ_(object) \ + SC_OBSERVER_(object,sc_fxnum_fast_observer*,read) +#define SC_FXNUM_FAST_OBSERVER_WRITE_(object) \ + SC_OBSERVER_(object,sc_fxnum_fast_observer*,write) +#define SC_FXNUM_FAST_OBSERVER_DEFAULT_ \ + SC_OBSERVER_DEFAULT_(sc_fxnum_fast_observer) + +#else + +#define SC_FXNUM_OBSERVER_CONSTRUCT_(object) +#define SC_FXNUM_OBSERVER_DESTRUCT_(object) +#define SC_FXNUM_OBSERVER_READ_(object) +#define SC_FXNUM_OBSERVER_WRITE_(object) +#define SC_FXNUM_OBSERVER_DEFAULT_ + +#define SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(object) +#define SC_FXNUM_FAST_OBSERVER_DESTRUCT_(object) +#define SC_FXNUM_FAST_OBSERVER_READ_(object) +#define SC_FXNUM_FAST_OBSERVER_WRITE_(object) +#define SC_FXNUM_FAST_OBSERVER_DEFAULT_ + +#endif + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_observer +// +// Abstract base class for fixed-point types observers; arbitrary precision. +// ---------------------------------------------------------------------------- + +class sc_fxnum_observer +{ + +protected: + + sc_fxnum_observer() {} + virtual ~sc_fxnum_observer() {} + +public: + + virtual void construct( const sc_fxnum& ); + virtual void destruct( const sc_fxnum& ); + virtual void read( const sc_fxnum& ); + virtual void write( const sc_fxnum& ); + + static sc_fxnum_observer* (*default_observer) (); + +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast_observer +// +// Abstract base class for fixed-point types observers; limited precision. +// ---------------------------------------------------------------------------- + +class sc_fxnum_fast_observer +{ + +protected: + + sc_fxnum_fast_observer() {} + virtual ~sc_fxnum_fast_observer() {} + +public: + + virtual void construct( const sc_fxnum_fast& ); + virtual void destruct( const sc_fxnum_fast& ); + virtual void read( const sc_fxnum_fast& ); + virtual void write( const sc_fxnum_fast& ); + + static sc_fxnum_fast_observer* (*default_observer) (); + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_observer +// +// Abstract base class for fixed-point types observers; arbitrary precision. +// ---------------------------------------------------------------------------- + +inline +void +sc_fxnum_observer::construct( const sc_fxnum& ) +{} + +inline +void +sc_fxnum_observer::destruct( const sc_fxnum& ) +{} + +inline +void +sc_fxnum_observer::read( const sc_fxnum& ) +{} + +inline +void +sc_fxnum_observer::write( const sc_fxnum& ) +{} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast_observer +// +// Abstract base class for fixed-point types observers; limited precision. +// ---------------------------------------------------------------------------- + +inline +void +sc_fxnum_fast_observer::construct( const sc_fxnum_fast& ) +{} + +inline +void +sc_fxnum_fast_observer::destruct( const sc_fxnum_fast& ) +{} + +inline +void +sc_fxnum_fast_observer::read( const sc_fxnum_fast& ) +{} + +inline +void +sc_fxnum_fast_observer::write( const sc_fxnum_fast& ) +{} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxtype_params.cpp b/ext/systemc/src/sysc/datatypes/fx/sc_fxtype_params.cpp new file mode 100644 index 000000000..60c18a2b5 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxtype_params.cpp @@ -0,0 +1,108 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxtype_params.cpp - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_fxtype_params.cpp,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#include "sysc/datatypes/fx/sc_fxtype_params.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxtype_params +// +// Fixed-point type parameters class. +// ---------------------------------------------------------------------------- + +const std::string +sc_fxtype_params::to_string() const +{ + std::string s; + + char buf[BUFSIZ]; + + s += "("; + std::sprintf( buf, "%d", m_wl ); + s += buf; + s += ","; + std::sprintf( buf, "%d", m_iwl ); + s += buf; + s += ","; + s += sc_dt::to_string( m_q_mode ); + s += ","; + s += sc_dt::to_string( m_o_mode ); + s += ","; + std::sprintf( buf, "%d", m_n_bits ); + s += buf; + s += ")"; + + return s; +} + + +void +sc_fxtype_params::print( ::std::ostream& os ) const +{ + os << to_string(); +} + +void +sc_fxtype_params::dump( ::std::ostream& os ) const +{ + os << "sc_fxtype_params" << ::std::endl; + os << "(" << ::std::endl; + os << "wl = " << m_wl << ::std::endl; + os << "iwl = " << m_iwl << ::std::endl; + os << "q_mode = " << m_q_mode << ::std::endl; + os << "o_mode = " << m_o_mode << ::std::endl; + os << "n_bits = " << m_n_bits << ::std::endl; + os << ")" << ::std::endl; +} + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxtype_params.h b/ext/systemc/src/sysc/datatypes/fx/sc_fxtype_params.h new file mode 100644 index 000000000..a59ba293b --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxtype_params.h @@ -0,0 +1,342 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxtype_params.h - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_fxtype_params.h,v $ +// Revision 1.2 2011/08/24 22:05:43 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_FXTYPE_PARAMS_H +#define SC_FXTYPE_PARAMS_H + + +#include "sysc/datatypes/fx/sc_context.h" + + +namespace sc_dt +{ + +// classes defined in this module +class sc_fxtype_params; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxtype_params +// +// Fixed-point type parameters class. +// ---------------------------------------------------------------------------- + +class sc_fxtype_params +{ +public: + + sc_fxtype_params(); + sc_fxtype_params( int, int ); + sc_fxtype_params( sc_q_mode, sc_o_mode, int = 0 ); + sc_fxtype_params( int, int, sc_q_mode, sc_o_mode, int = 0 ); + sc_fxtype_params( const sc_fxtype_params& ); + sc_fxtype_params( const sc_fxtype_params&, + int, int ); + sc_fxtype_params( const sc_fxtype_params&, + sc_q_mode, sc_o_mode, int = 0 ); + explicit sc_fxtype_params( sc_without_context ); + + sc_fxtype_params& operator = ( const sc_fxtype_params& ); + + friend bool operator == ( const sc_fxtype_params&, + const sc_fxtype_params& ); + friend bool operator != ( const sc_fxtype_params&, + const sc_fxtype_params& ); + + int wl() const; + void wl( int ); + + int iwl() const; + void iwl( int ); + + sc_q_mode q_mode() const; + void q_mode( sc_q_mode ); + + sc_o_mode o_mode() const; + void o_mode( sc_o_mode ); + + int n_bits() const; + void n_bits( int ); + + const std::string to_string() const; + + void print( ::std::ostream& = ::std::cout ) const; + void dump( ::std::ostream& = ::std::cout ) const; + +private: + + int m_wl; + int m_iwl; + sc_q_mode m_q_mode; + sc_o_mode m_o_mode; + int m_n_bits; +}; + + +// ---------------------------------------------------------------------------- +// TYPEDEF : sc_fxtype_context +// +// Context type for the fixed-point type parameters. +// ---------------------------------------------------------------------------- + +typedef sc_context<sc_fxtype_params> sc_fxtype_context; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +inline +sc_fxtype_params::sc_fxtype_params() +: m_wl(), m_iwl(), m_q_mode(), m_o_mode(), m_n_bits() +{ + *this = sc_fxtype_context::default_value(); +} + +inline +sc_fxtype_params::sc_fxtype_params( int wl_, int iwl_ ) +: m_wl(), m_iwl(), m_q_mode(), m_o_mode(), m_n_bits() +{ + *this = sc_fxtype_context::default_value(); + + SC_CHECK_WL_( wl_ ); + m_wl = wl_; + m_iwl = iwl_; +} + +inline +sc_fxtype_params::sc_fxtype_params( sc_q_mode q_mode_, + sc_o_mode o_mode_, int n_bits_ ) +: m_wl(), m_iwl(), m_q_mode(), m_o_mode(), m_n_bits() +{ + *this = sc_fxtype_context::default_value(); + + SC_CHECK_N_BITS_( n_bits_ ); + m_q_mode = q_mode_; + m_o_mode = o_mode_; + m_n_bits = n_bits_; +} + +inline +sc_fxtype_params::sc_fxtype_params( int wl_, int iwl_, + sc_q_mode q_mode_, + sc_o_mode o_mode_, int n_bits_ ) +: m_wl(), m_iwl(), m_q_mode(), m_o_mode(), m_n_bits() +{ + SC_CHECK_WL_( wl_ ); + SC_CHECK_N_BITS_( n_bits_ ); + m_wl = wl_; + m_iwl = iwl_; + m_q_mode = q_mode_; + m_o_mode = o_mode_; + m_n_bits = n_bits_; +} + +inline +sc_fxtype_params::sc_fxtype_params( const sc_fxtype_params& a ) +: m_wl( a.m_wl ), m_iwl( a.m_iwl ), + m_q_mode( a.m_q_mode ), + m_o_mode( a.m_o_mode ), m_n_bits( a.m_n_bits ) +{} + +inline +sc_fxtype_params::sc_fxtype_params( const sc_fxtype_params& a, + int wl_, int iwl_ ) +: m_wl( wl_ ), m_iwl( iwl_ ), + m_q_mode( a.m_q_mode ), + m_o_mode( a.m_o_mode ), m_n_bits( a.m_n_bits ) +{} + +inline +sc_fxtype_params::sc_fxtype_params( const sc_fxtype_params& a, + sc_q_mode q_mode_, + sc_o_mode o_mode_, int n_bits_ ) +: m_wl( a.m_wl ), m_iwl( a.m_iwl ), + m_q_mode( q_mode_ ), + m_o_mode( o_mode_ ), m_n_bits( n_bits_ ) +{} + +inline +sc_fxtype_params::sc_fxtype_params( sc_without_context ) +: m_wl ( SC_DEFAULT_WL_ ), + m_iwl ( SC_DEFAULT_IWL_ ), + m_q_mode( SC_DEFAULT_Q_MODE_ ), + m_o_mode( SC_DEFAULT_O_MODE_ ), + m_n_bits( SC_DEFAULT_N_BITS_ ) +{} + + +inline +sc_fxtype_params& +sc_fxtype_params::operator = ( const sc_fxtype_params& a ) +{ + if( &a != this ) + { + m_wl = a.m_wl; + m_iwl = a.m_iwl; + m_q_mode = a.m_q_mode; + m_o_mode = a.m_o_mode; + m_n_bits = a.m_n_bits; + } + return *this; +} + + +inline +bool +operator == ( const sc_fxtype_params& a, const sc_fxtype_params& b ) +{ + return ( a.m_wl == b.m_wl && + a.m_iwl == b.m_iwl && + a.m_q_mode == b.m_q_mode && + a.m_o_mode == b.m_o_mode && + a.m_n_bits == b.m_n_bits ); +} + +inline +bool +operator != ( const sc_fxtype_params& a, const sc_fxtype_params& b ) +{ + return ( a.m_wl != b.m_wl || + a.m_iwl != b.m_iwl || + a.m_q_mode != b.m_q_mode || + a.m_o_mode != b.m_o_mode || + a.m_n_bits != b.m_n_bits ); +} + + +inline +int +sc_fxtype_params::wl() const +{ + return m_wl; +} + +inline +void +sc_fxtype_params::wl( int wl_ ) +{ + SC_CHECK_WL_( wl_ ); + m_wl = wl_; +} + + +inline +int +sc_fxtype_params::iwl() const +{ + return m_iwl; +} + +inline +void +sc_fxtype_params::iwl( int iwl_ ) +{ + m_iwl = iwl_; +} + + +inline +sc_q_mode +sc_fxtype_params::q_mode() const +{ + return m_q_mode; +} + +inline +void +sc_fxtype_params::q_mode( sc_q_mode q_mode_ ) +{ + m_q_mode = q_mode_; +} + + +inline +sc_o_mode +sc_fxtype_params::o_mode() const +{ + return m_o_mode; +} + +inline +void +sc_fxtype_params::o_mode( sc_o_mode o_mode_ ) +{ + m_o_mode = o_mode_; +} + + +inline +int +sc_fxtype_params::n_bits() const +{ + return m_n_bits; +} + +inline +void +sc_fxtype_params::n_bits( int n_bits_ ) +{ + SC_CHECK_N_BITS_( n_bits_ ); + m_n_bits = n_bits_; +} + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_fxtype_params& a ) +{ + a.print( os ); + return os; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxval.cpp b/ext/systemc/src/sysc/datatypes/fx/sc_fxval.cpp new file mode 100644 index 000000000..3ba5fbacd --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxval.cpp @@ -0,0 +1,884 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxval.cpp - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_fxval.cpp,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#include <ctype.h> +#include <stdlib.h> +#include <math.h> +#include <float.h> + +#include "sysc/datatypes/fx/sc_fxval.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval +// +// Fixed-point value type; arbitrary precision. +// ---------------------------------------------------------------------------- + +// explicit conversion to character string + +const std::string +sc_fxval::to_string() const +{ + return std::string( m_rep->to_string( SC_DEC, -1, SC_E ) ); +} + +const std::string +sc_fxval::to_string( sc_numrep numrep ) const +{ + return std::string( m_rep->to_string( numrep, -1, SC_E ) ); +} + +const std::string +sc_fxval::to_string( sc_numrep numrep, bool w_prefix ) const +{ + return std::string( m_rep->to_string( numrep, (w_prefix ? 1 : 0), SC_E ) ); +} + +const std::string +sc_fxval::to_string( sc_fmt fmt ) const +{ + return std::string( m_rep->to_string( SC_DEC, -1, fmt ) ); +} + +const std::string +sc_fxval::to_string( sc_numrep numrep, sc_fmt fmt ) const +{ + return std::string( m_rep->to_string( numrep, -1, fmt ) ); +} + +const std::string +sc_fxval::to_string( sc_numrep numrep, bool w_prefix, sc_fmt fmt ) const +{ + return std::string( m_rep->to_string( numrep, (w_prefix ? 1 : 0), fmt ) ); +} + + +const std::string +sc_fxval::to_dec() const +{ + return std::string( m_rep->to_string( SC_DEC, -1, SC_E ) ); +} + +const std::string +sc_fxval::to_bin() const +{ + return std::string( m_rep->to_string( SC_BIN, -1, SC_E ) ); +} + +const std::string +sc_fxval::to_oct() const +{ + return std::string( m_rep->to_string( SC_OCT, -1, SC_E ) ); +} + +const std::string +sc_fxval::to_hex() const +{ + return std::string( m_rep->to_string( SC_HEX, -1, SC_E ) ); +} + + +// print or dump content + +void +sc_fxval::print( ::std::ostream& os ) const +{ + m_rep->print( os ); +} + +void +sc_fxval::scan( ::std::istream& is ) +{ + std::string s; + is >> s; + *this = s.c_str(); +} + +void +sc_fxval::dump( ::std::ostream& os ) const +{ + os << "sc_fxval" << ::std::endl; + os << "(" << ::std::endl; + os << "rep = "; + m_rep->dump( os ); + // TO BE COMPLETED + // os << "r_flag = " << m_r_flag << ::std::endl; + // os << "observer = "; + // if( m_observer != 0 ) + // m_observer->dump( os ); + // else + // os << "0" << ::std::endl; + os << ")" << ::std::endl; +} + + +// protected methods and friend functions + +sc_fxval_observer* +sc_fxval::lock_observer() const +{ + SC_ASSERT_( m_observer != 0, "lock observer failed" ); + sc_fxval_observer* tmp = m_observer; + m_observer = 0; + return tmp; +} + +void +sc_fxval::unlock_observer( sc_fxval_observer* observer_ ) const +{ + SC_ASSERT_( observer_ != 0, "unlock observer failed" ); + m_observer = observer_; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval_fast +// +// Fixed-point value types; limited precision. +// ---------------------------------------------------------------------------- + +static +void +print_dec( scfx_string& s, scfx_ieee_double id, int w_prefix, sc_fmt fmt ) +{ + if( id.negative() != 0 ) + { + id.negative( 0 ); + s += '-'; + } + + if( w_prefix == 1 ) { + scfx_print_prefix( s, SC_DEC ); + } + + if( id.is_zero() ) + { + s += '0'; + return; + } + + // split 'id' into its integer and fractional part + + double int_part; + double frac_part = modf( static_cast<double>( id ), &int_part ); + + int i; + + // print integer part + + int int_digits = 0; + int int_zeros = 0; + + if( int_part != 0.0 ) + { + int_digits = (int) ceil( log10( int_part + 1.0 ) ); + + int len = s.length(); + s.append( int_digits ); + + bool zero_digits = ( frac_part == 0.0 && fmt != SC_F ); + + for( i = int_digits + len - 1; i >= len; i-- ) + { + unsigned int remainder = (unsigned int) fmod( int_part, 10.0 ); + s[i] = static_cast<char>( '0' + remainder ); + + if( zero_digits ) + { + if( remainder == 0 ) + int_zeros ++; + else + zero_digits = false; + } + + int_part /= 10.0; + } + + // discard trailing zeros from int_part + s.discard( int_zeros ); + + if( s[len] == '0' ) + { + // int_digits was overestimated by one + s.remove( len ); + -- int_digits; + } + } + + // print fractional part + + int frac_digits = 0; + int frac_zeros = 0; + + if( frac_part != 0.0 ) + { + s += '.'; + + bool zero_digits = ( int_digits == 0 && fmt != SC_F ); + + frac_zeros = (int) floor( - log10( frac_part + DBL_EPSILON ) ); + + frac_part *= pow( 10.0, frac_zeros ); + + frac_digits = frac_zeros; + if( ! zero_digits ) + { + for( i = 0; i < frac_zeros; i ++ ) + s += '0'; + frac_zeros = 0; + } + + while( frac_part != 0.0 ) + { + frac_part *= 10.0; + int n = static_cast<int>( frac_part ); + + if( zero_digits ) + { + if( n == 0 ) + frac_zeros ++; + else + zero_digits = false; + } + + if( ! zero_digits ) + s += static_cast<char>( '0' + n ); + + frac_part -= n; + frac_digits ++; + } + } + + // print exponent + + if( fmt != SC_F ) + { + if( frac_digits == 0 ) + scfx_print_exp( s, int_zeros ); + else if( int_digits == 0 ) + scfx_print_exp( s, - frac_zeros ); + } +} + + +static +void +print_other( scfx_string& s, const scfx_ieee_double& id, sc_numrep numrep, + int w_prefix, sc_fmt fmt, const scfx_params* params ) +{ + scfx_ieee_double id2 = id; + + sc_numrep numrep2 = numrep; + + bool numrep_is_sm = ( numrep == SC_BIN_SM || + numrep == SC_OCT_SM || + numrep == SC_HEX_SM ); + + if( numrep_is_sm ) + { + if( id2.negative() != 0 ) + { + s += '-'; + id2.negative( 0 ); + } + switch( numrep ) + { + case SC_BIN_SM: + numrep2 = SC_BIN_US; + break; + case SC_OCT_SM: + numrep2 = SC_OCT_US; + break; + case SC_HEX_SM: + numrep2 = SC_HEX_US; + break; + default: + ; + } + } + + if( w_prefix != 0 ) { + scfx_print_prefix( s, numrep ); + } + + numrep = numrep2; + + sc_fxval_fast a( id2 ); + + int msb, lsb; + + if( params != 0 ) + { + msb = params->iwl() - 1; + lsb = params->iwl() - params->wl(); + + if( params->enc() == SC_TC_ && + ( numrep == SC_BIN_US || + numrep == SC_OCT_US || + numrep == SC_HEX_US ) && + ! numrep_is_sm && + params->wl() > 1 ) + -- msb; + else if( params->enc() == SC_US_ && + ( numrep == SC_BIN || + numrep == SC_OCT || + numrep == SC_HEX || + numrep == SC_CSD ) ) + ++ msb; + } + else + { + if( a.is_zero() ) + { + msb = 0; + lsb = 0; + } + else + { + msb = id2.exponent() + 1; + while( a.get_bit( msb ) == a.get_bit( msb - 1 ) ) + -- msb; + + if( numrep == SC_BIN_US || + numrep == SC_OCT_US || + numrep == SC_HEX_US ) + -- msb; + + lsb = id2.exponent() - 52; + while( ! a.get_bit( lsb ) ) + ++ lsb; + } + } + + int step; + + switch( numrep ) + { + case SC_BIN: + case SC_BIN_US: + case SC_CSD: + step = 1; + break; + case SC_OCT: + case SC_OCT_US: + step = 3; + break; + case SC_HEX: + case SC_HEX_US: + step = 4; + break; + default: + step = 0; + } + + msb = (int) ceil( double( msb + 1 ) / step ) * step - 1; + + lsb = (int) floor( double( lsb ) / step ) * step; + + if( msb < 0 ) + { + s += '.'; + if( fmt == SC_F ) + { + int sign = ( id2.negative() != 0 ) ? ( 1 << step ) - 1 : 0; + for( int i = ( msb + 1 ) / step; i < 0; i ++ ) + { + if( sign < 10 ) + s += static_cast<char>( sign + '0' ); + else + s += static_cast<char>( sign + 'a' - 10 ); + } + } + } + + int i = msb; + while( i >= lsb ) + { + int value = 0; + for( int j = step - 1; j >= 0; -- j ) + { + value += static_cast<int>( a.get_bit( i ) ) << j; + -- i; + } + if( value < 10 ) + s += static_cast<char>( value + '0' ); + else + s += static_cast<char>( value + 'a' - 10 ); + if( i == -1 ) + s += '.'; + } + + if( lsb > 0 && fmt == SC_F ) + { + for( int i = lsb / step; i > 0; i -- ) + s += '0'; + } + + if( s[s.length() - 1] == '.' ) + s.discard( 1 ); + + if( fmt != SC_F ) + { + if( msb < 0 ) + scfx_print_exp( s, ( msb + 1 ) / step ); + else if( lsb > 0 ) + scfx_print_exp( s, lsb / step ); + } + + if( numrep == SC_CSD ) + scfx_tc2csd( s, w_prefix ); +} + + +const char* +to_string( const scfx_ieee_double& id, sc_numrep numrep, int w_prefix, + sc_fmt fmt, const scfx_params* params = 0 ) +{ + static scfx_string s; + + s.clear(); + + if( id.is_nan() ) + scfx_print_nan( s ); + else if( id.is_inf() ) + scfx_print_inf( s, static_cast<bool>( id.negative() ) ); + else if( id.negative() && ! id.is_zero() && + ( numrep == SC_BIN_US || + numrep == SC_OCT_US || + numrep == SC_HEX_US ) ) + s += "negative"; + else if( numrep == SC_DEC ) + sc_dt::print_dec( s, id, w_prefix, fmt ); + else + sc_dt::print_other( s, id, numrep, w_prefix, fmt, params ); + + return s; +} + + +// explicit conversion to character string + +const std::string +sc_fxval_fast::to_string() const +{ + return std::string( sc_dt::to_string( m_val, SC_DEC, -1, SC_E ) ); +} + +const std::string +sc_fxval_fast::to_string( sc_numrep numrep ) const +{ + return std::string( sc_dt::to_string( m_val, numrep, -1, SC_E ) ); +} + +const std::string +sc_fxval_fast::to_string( sc_numrep numrep, bool w_prefix ) const +{ + return std::string( sc_dt::to_string( m_val, numrep, (w_prefix ? 1 : 0), + SC_E ) ); +} + +const std::string +sc_fxval_fast::to_string( sc_fmt fmt ) const +{ + return std::string( sc_dt::to_string( m_val, SC_DEC, -1, fmt ) ); +} + +const std::string +sc_fxval_fast::to_string( sc_numrep numrep, sc_fmt fmt ) const +{ + return std::string( sc_dt::to_string( m_val, numrep, -1, fmt ) ); +} + +const std::string +sc_fxval_fast::to_string( sc_numrep numrep, bool w_prefix, sc_fmt fmt ) const +{ + return std::string( sc_dt::to_string( m_val, numrep, (w_prefix ? 1 : 0), + fmt ) ); +} + + +const std::string +sc_fxval_fast::to_dec() const +{ + return std::string( sc_dt::to_string( m_val, SC_DEC, -1, SC_E ) ); +} + +const std::string +sc_fxval_fast::to_bin() const +{ + return std::string( sc_dt::to_string( m_val, SC_BIN, -1, SC_E ) ); +} + +const std::string +sc_fxval_fast::to_oct() const +{ + return std::string( sc_dt::to_string( m_val, SC_OCT, -1, SC_E ) ); +} + +const std::string +sc_fxval_fast::to_hex() const +{ + return std::string( sc_dt::to_string( m_val, SC_HEX, -1, SC_E ) ); +} + + +// print or dump content + +void +sc_fxval_fast::print( ::std::ostream& os ) const +{ + os << sc_dt::to_string( m_val, SC_DEC, -1, SC_E ); +} + +void +sc_fxval_fast::scan( ::std::istream& is ) +{ + std::string s; + is >> s; + *this = s.c_str(); +} + +void +sc_fxval_fast::dump( ::std::ostream& os ) const +{ + os << "sc_fxval_fast" << ::std::endl; + os << "(" << ::std::endl; + os << "val = " << m_val << ::std::endl; + // TO BE COMPLETED + // os << "r_flag = " << m_r_flag << ::std::endl; + // os << "observer = "; + // if( m_observer != 0 ) + // m_observer->dump( os ); + // else + // os << "0" << ::std::endl; + os << ")" << ::std::endl; +} + + +// internal use only; +bool +sc_fxval_fast::get_bit( int i ) const +{ + scfx_ieee_double id( m_val ); + if( id.is_zero() || id.is_nan() || id.is_inf() ) + return false; + + // convert to two's complement + + unsigned int m0 = id.mantissa0(); + unsigned int m1 = id.mantissa1(); + + if( id.is_normal() ) + m0 += 1U << 20; + + if( id.negative() != 0 ) + { + m0 = ~ m0; + m1 = ~ m1; + unsigned int tmp = m1; + m1 += 1U; + if( m1 <= tmp ) + m0 += 1U; + } + + // get the right bit + + int j = i - id.exponent(); + if( ( j += 20 ) >= 32 ) + return ( ( m0 & 1U << 31 ) != 0 ); + else if( j >= 0 ) + return ( ( m0 & 1U << j ) != 0 ); + else if( ( j += 32 ) >= 0 ) + return ( ( m1 & 1U << j ) != 0 ); + else + return false; +} + + +// protected methods and friend functions + +sc_fxval_fast_observer* +sc_fxval_fast::lock_observer() const +{ + SC_ASSERT_( m_observer != 0, "lock observer failed" ); + sc_fxval_fast_observer* tmp = m_observer; + m_observer = 0; + return tmp; +} + +void +sc_fxval_fast::unlock_observer( sc_fxval_fast_observer* observer_ ) const +{ + SC_ASSERT_( observer_ != 0, "unlock observer failed" ); + m_observer = observer_; +} + + +#define SCFX_FAIL_IF_(cnd) \ +{ \ + if( ( cnd ) ) \ + return static_cast<double>( scfx_ieee_double::nan() ); \ +} + +double +sc_fxval_fast::from_string( const char* s ) +{ + SCFX_FAIL_IF_( s == 0 || *s == 0 ); + + scfx_string s2; + s2 += s; + s2 += '\0'; + + bool sign_char; + int sign = scfx_parse_sign( s, sign_char ); + + sc_numrep numrep = scfx_parse_prefix( s ); + + int base = 0; + + switch( numrep ) + { + case SC_DEC: + { + base = 10; + if( scfx_is_nan( s ) ) // special case: NaN + return static_cast<double>( scfx_ieee_double::nan() ); + if( scfx_is_inf( s ) ) // special case: Infinity + return static_cast<double>( scfx_ieee_double::inf( sign ) ); + break; + } + case SC_BIN: + case SC_BIN_US: + { + SCFX_FAIL_IF_( sign_char ); + base = 2; + break; + } + + case SC_BIN_SM: + { + base = 2; + break; + } + case SC_OCT: + case SC_OCT_US: + { + SCFX_FAIL_IF_( sign_char ); + base = 8; + break; + } + case SC_OCT_SM: + { + base = 8; + break; + } + case SC_HEX: + case SC_HEX_US: + { + SCFX_FAIL_IF_( sign_char ); + base = 16; + break; + } + case SC_HEX_SM: + { + base = 16; + break; + } + case SC_CSD: + { + SCFX_FAIL_IF_( sign_char ); + base = 2; + scfx_csd2tc( s2 ); + s = (const char*) s2 + 4; + numrep = SC_BIN; + break; + } + default:;// Martin, what is default??? + } + + // + // find end of mantissa and count the digits and points + // + + const char *end = s; + bool based_point = false; + int int_digits = 0; + int frac_digits = 0; + + while( *end ) + { + if( scfx_exp_start( end ) ) + break; + + if( *end == '.' ) + { + SCFX_FAIL_IF_( based_point ); + based_point = true; + } + else + { + SCFX_FAIL_IF_( ! scfx_is_digit( *end, numrep ) ); + if( based_point ) + frac_digits ++; + else + int_digits ++; + } + + end ++; + } + + SCFX_FAIL_IF_( int_digits == 0 && frac_digits == 0 ); + + // [ exponent ] + + int exponent = 0; + + if( *end ) + { + for( const char *e = end + 2; *e; e ++ ) + SCFX_FAIL_IF_( ! scfx_is_digit( *e, SC_DEC ) ); + exponent = atoi( end + 1 ); + } + + // + // convert the mantissa + // + + double integer = 0.0; + + if( int_digits != 0 ) + { + + bool first_digit = true; + + for( ; s < end; s ++ ) + { + if( *s == '.' ) + break; + + if( first_digit ) + { + integer = scfx_to_digit( *s, numrep ); + switch( numrep ) + { + case SC_BIN: + case SC_OCT: + case SC_HEX: + { + if( integer >= ( base >> 1 ) ) + integer -= base; // two's complement + break; + } + default: + ; + } + first_digit = false; + } + else + { + integer *= base; + integer += scfx_to_digit( *s, numrep ); + } + } + } + + // [ . fraction ] + + double fraction = 0.0; + + if( frac_digits != 0 ) + { + s ++; // skip '.' + + bool first_digit = ( int_digits == 0 ); + + double scale = 1.0; + + for( ; s < end; s ++ ) + { + scale /= base; + + if( first_digit ) + { + fraction = scfx_to_digit( *s, numrep ); + switch( numrep ) + { + case SC_BIN: + case SC_OCT: + case SC_HEX: + { + if( fraction >= ( base >> 1 ) ) + fraction -= base; // two's complement + break; + } + default: + ; + } + fraction *= scale; + first_digit = false; + } + else + fraction += scfx_to_digit( *s, numrep ) * scale; + } + } + + double exp = ( exponent != 0 ) ? pow( (double) base, (double) exponent ) + : 1; + + return ( sign * ( integer + fraction ) * exp ); +} + +#undef SCFX_FAIL_IF_ + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxval.h b/ext/systemc/src/sysc/datatypes/fx/sc_fxval.h new file mode 100644 index 000000000..1f199875c --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxval.h @@ -0,0 +1,2269 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxval.h - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_fxval.h,v $ +// Revision 1.3 2011/01/19 18:57:40 acg +// Andy Goodrich: changes for IEEE_1666_2011. +// +// Revision 1.2 2010/12/07 20:09:08 acg +// Andy Goodrich: Philipp Hartmann's constructor disambiguation fix +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_FXVAL_H +#define SC_FXVAL_H + + +#include "sysc/datatypes/fx/scfx_rep.h" +#ifndef SC_FX_EXCLUDE_OTHER +#include "sysc/datatypes/int/sc_int_base.h" +#include "sysc/datatypes/int/sc_uint_base.h" +#include "sysc/datatypes/int/sc_signed.h" +#include "sysc/datatypes/int/sc_unsigned.h" +#endif +#include "sysc/datatypes/fx/sc_fxval_observer.h" + +#ifdef SC_FXVAL_IMPLICIT_CONV +# define SCFX_EXPLICIT_ // nothing +#else +# define SCFX_EXPLICIT_ explicit +#endif +#ifdef SC_FXVAL_IMPLICIT_OTHER +# define SCFX_EXPLICIT_OTHER_ +#else +# define SCFX_EXPLICIT_OTHER_ explicit +#endif + +namespace sc_dt +{ + +// classes defined in this module +class sc_fxval; +class sc_fxval_fast; + +// forward class declarations +class sc_fxnum; +class sc_fxnum_fast; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval +// +// Fixed-point value type; arbitrary precision. +// ---------------------------------------------------------------------------- + +class sc_fxval +{ + + friend class sc_fxnum; + +protected: + + sc_fxval_observer* observer() const; + +public: + + // internal use only; + explicit sc_fxval( scfx_rep* ); + + + explicit sc_fxval( sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval( int, sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval( unsigned int, sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval( long, sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval( unsigned long, sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval( float, sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval( double, sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval( const char*, sc_fxval_observer* = 0 ); + sc_fxval( const sc_fxval&, sc_fxval_observer* = 0 ); + sc_fxval( const sc_fxval_fast&, sc_fxval_observer* = 0 ); + sc_fxval( const sc_fxnum&, sc_fxval_observer* = 0 ); + sc_fxval( const sc_fxnum_fast&, sc_fxval_observer* = 0 ); +#ifndef SC_FX_EXCLUDE_OTHER + SCFX_EXPLICIT_OTHER_ sc_fxval( int64, sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_OTHER_ sc_fxval( uint64, sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_OTHER_ sc_fxval( const sc_int_base&, sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_OTHER_ sc_fxval( const sc_uint_base&, sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_OTHER_ sc_fxval( const sc_signed&, sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_OTHER_ sc_fxval( const sc_unsigned&, sc_fxval_observer* = 0 ); +#endif + + ~sc_fxval(); + + + // internal use only; + const scfx_rep* get_rep() const; + void set_rep( scfx_rep* ); + + + // unary operators + + const sc_fxval operator - () const; + const sc_fxval& operator + () const; + + + // unary functions + + friend void neg( sc_fxval&, const sc_fxval& ); + + + // binary operators + +#define DECL_BIN_OP_T(op,tp) \ + friend const sc_fxval operator op ( const sc_fxval&, tp ); \ + friend const sc_fxval operator op ( tp, const sc_fxval& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_BIN_OP_OTHER(op) \ + DECL_BIN_OP_T(op,int64) \ + DECL_BIN_OP_T(op,uint64) \ + DECL_BIN_OP_T(op,const sc_int_base&) \ + DECL_BIN_OP_T(op,const sc_uint_base&) \ + DECL_BIN_OP_T(op,const sc_signed&) \ + DECL_BIN_OP_T(op,const sc_unsigned&) +#else +#define DECL_BIN_OP_OTHER(op) +#endif + +#define DECL_BIN_OP(op,dummy) \ + friend const sc_fxval operator op ( const sc_fxval&, const sc_fxval& ); \ + DECL_BIN_OP_T(op,int) \ + DECL_BIN_OP_T(op,unsigned int) \ + DECL_BIN_OP_T(op,long) \ + DECL_BIN_OP_T(op,unsigned long) \ + DECL_BIN_OP_T(op,float) \ + DECL_BIN_OP_T(op,double) \ + DECL_BIN_OP_T(op,const char*) \ + DECL_BIN_OP_T(op,const sc_fxval_fast&) \ + DECL_BIN_OP_T(op,const sc_fxnum_fast&) \ + DECL_BIN_OP_OTHER(op) + + DECL_BIN_OP(*,mult) + DECL_BIN_OP(+,add) + DECL_BIN_OP(-,sub) +// declaration below doesn't compile with BCB5 (E2206) +// DECL_BIN_OP(/,div) +// previous macro expanded + friend const sc_fxval operator / ( const sc_fxval&, const sc_fxval& ); + DECL_BIN_OP_T(/,int) + DECL_BIN_OP_T(/,unsigned int) + DECL_BIN_OP_T(/,long) + DECL_BIN_OP_T(/,unsigned long) + DECL_BIN_OP_T(/,float) + DECL_BIN_OP_T(/,double) + DECL_BIN_OP_T(/,const char*) + DECL_BIN_OP_T(/,const sc_fxval_fast&) + DECL_BIN_OP_T(/,const sc_fxnum_fast&) +// DECL_BIN_OP_OTHER(/) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_BIN_OP_T(/,int64) \ + DECL_BIN_OP_T(/,uint64) \ + DECL_BIN_OP_T(/,const sc_int_base&) \ + DECL_BIN_OP_T(/,const sc_uint_base&) \ + DECL_BIN_OP_T(/,const sc_signed&) \ + DECL_BIN_OP_T(/,const sc_unsigned&) +#endif + + +#undef DECL_BIN_OP_T +#undef DECL_BIN_OP_OTHER +#undef DECL_BIN_OP + + friend const sc_fxval operator << ( const sc_fxval&, int ); + friend const sc_fxval operator >> ( const sc_fxval&, int ); + + + // binary functions + +#define DECL_BIN_FNC_T(fnc,tp) \ + friend void fnc ( sc_fxval&, const sc_fxval&, tp ); \ + friend void fnc ( sc_fxval&, tp, const sc_fxval& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_BIN_FNC_OTHER(fnc) \ + DECL_BIN_FNC_T(fnc,int64) \ + DECL_BIN_FNC_T(fnc,uint64) \ + DECL_BIN_FNC_T(fnc,const sc_int_base&) \ + DECL_BIN_FNC_T(fnc,const sc_uint_base&) \ + DECL_BIN_FNC_T(fnc,const sc_signed&) \ + DECL_BIN_FNC_T(fnc,const sc_unsigned&) +#else +#define DECL_BIN_FNC_OTHER(fnc) +#endif + +#define DECL_BIN_FNC(fnc) \ + friend void fnc ( sc_fxval&, const sc_fxval&, const sc_fxval& ); \ + DECL_BIN_FNC_T(fnc,int) \ + DECL_BIN_FNC_T(fnc,unsigned int) \ + DECL_BIN_FNC_T(fnc,long) \ + DECL_BIN_FNC_T(fnc,unsigned long) \ + DECL_BIN_FNC_T(fnc,float) \ + DECL_BIN_FNC_T(fnc,double) \ + DECL_BIN_FNC_T(fnc,const char*) \ + DECL_BIN_FNC_T(fnc,const sc_fxval_fast&) \ + DECL_BIN_FNC_T(fnc,const sc_fxnum_fast&) \ + DECL_BIN_FNC_OTHER(fnc) + + DECL_BIN_FNC(mult) + DECL_BIN_FNC(div) + DECL_BIN_FNC(add) + DECL_BIN_FNC(sub) + +#undef DECL_BIN_FNC_T +#undef DECL_BIN_FNC_OTHER +#undef DECL_BIN_FNC + + friend void lshift( sc_fxval&, const sc_fxval&, int ); + friend void rshift( sc_fxval&, const sc_fxval&, int ); + + + // relational (including equality) operators + +#define DECL_REL_OP_T(op,tp) \ + friend bool operator op ( const sc_fxval&, tp ); \ + friend bool operator op ( tp, const sc_fxval& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_REL_OP_OTHER(op) \ + DECL_REL_OP_T(op,int64) \ + DECL_REL_OP_T(op,uint64) \ + DECL_REL_OP_T(op,const sc_int_base&) \ + DECL_REL_OP_T(op,const sc_uint_base&) \ + DECL_REL_OP_T(op,const sc_signed&) \ + DECL_REL_OP_T(op,const sc_unsigned&) +#else +#define DECL_REL_OP_OTHER(op) +#endif + +#define DECL_REL_OP(op) \ + friend bool operator op ( const sc_fxval&, const sc_fxval& ); \ + DECL_REL_OP_T(op,int) \ + DECL_REL_OP_T(op,unsigned int) \ + DECL_REL_OP_T(op,long) \ + DECL_REL_OP_T(op,unsigned long) \ + DECL_REL_OP_T(op,float) \ + DECL_REL_OP_T(op,double) \ + DECL_REL_OP_T(op,const char*) \ + DECL_REL_OP_T(op,const sc_fxval_fast&) \ + DECL_REL_OP_T(op,const sc_fxnum_fast&) \ + DECL_REL_OP_OTHER(op) + + DECL_REL_OP(<) + DECL_REL_OP(<=) + DECL_REL_OP(>) + DECL_REL_OP(>=) + DECL_REL_OP(==) + DECL_REL_OP(!=) + +#undef DECL_REL_OP_T +#undef DECL_REL_OP_OTHER +#undef DECL_REL_OP + + + // assignment operators + +#define DECL_ASN_OP_T(op,tp) \ + sc_fxval& operator op( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval operator ++ ( int ); + const sc_fxval operator -- ( int ); + + sc_fxval& operator ++ (); + sc_fxval& operator -- (); + + + // implicit conversion + + operator double() const; // necessary evil! + + + // explicit conversion to primitive types + + short to_short() const; + unsigned short to_ushort() const; + int to_int() const; + unsigned int to_uint() const; + long to_long() const; + unsigned long to_ulong() const; + int64 to_int64() const; + uint64 to_uint64() const; + float to_float() const; + double to_double() const; + + + // explicit conversion to character string + + const std::string to_string() const; + const std::string to_string( sc_numrep ) const; + const std::string to_string( sc_numrep, bool ) const; + const std::string to_string( sc_fmt ) const; + const std::string to_string( sc_numrep, sc_fmt ) const; + const std::string to_string( sc_numrep, bool, sc_fmt ) const; + + const std::string to_dec() const; + const std::string to_bin() const; + const std::string to_oct() const; + const std::string to_hex() const; + + + // query value + + bool is_neg() const; + bool is_zero() const; + bool is_nan() const; + bool is_inf() const; + bool is_normal() const; + + bool rounding_flag() const; + + + // print or dump content + + void print( ::std::ostream& = ::std::cout ) const; + void scan( ::std::istream& = ::std::cin ); + void dump( ::std::ostream& = ::std::cout ) const; + + + // internal use only; + bool get_bit( int ) const; + +protected: + + sc_fxval_observer* lock_observer() const; + void unlock_observer( sc_fxval_observer* ) const; + + + void get_type( int&, int&, sc_enc& ) const; + + const sc_fxval quantization( const scfx_params&, bool& ) const; + const sc_fxval overflow( const scfx_params&, bool& ) const; + +private: + + scfx_rep* m_rep; + + mutable sc_fxval_observer* m_observer; + +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval_fast +// +// Fixed-point value type; limited precision. +// ---------------------------------------------------------------------------- + +class sc_fxval_fast +{ + + friend class sc_fxnum_fast; + +protected: + + sc_fxval_fast_observer* observer() const; + +public: + + explicit sc_fxval_fast( sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval_fast( int, sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval_fast( unsigned int, sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval_fast( long, sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval_fast( unsigned long, sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval_fast( float, sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval_fast( double, sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval_fast( const char*, sc_fxval_fast_observer* = 0 ); + sc_fxval_fast( const sc_fxval&, sc_fxval_fast_observer* = 0 ); + sc_fxval_fast( const sc_fxval_fast&, sc_fxval_fast_observer* = 0 ); + sc_fxval_fast( const sc_fxnum&, sc_fxval_fast_observer* = 0 ); + sc_fxval_fast( const sc_fxnum_fast&, sc_fxval_fast_observer* = 0 ); +#ifndef SC_FX_EXCLUDE_OTHER + SCFX_EXPLICIT_OTHER_ sc_fxval_fast( int64, sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_OTHER_ sc_fxval_fast( uint64, sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_OTHER_ sc_fxval_fast( const sc_int_base&, sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_OTHER_ sc_fxval_fast( const sc_uint_base&, sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_OTHER_ sc_fxval_fast( const sc_signed&, sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_OTHER_ sc_fxval_fast( const sc_unsigned&, sc_fxval_fast_observer* = 0 ); +#endif + + ~sc_fxval_fast(); + + // internal use only; + double get_val() const; + void set_val( double ); + + + // unary operators + + const sc_fxval_fast operator - () const; + const sc_fxval_fast& operator + () const; + + + // unary functions + + friend void neg( sc_fxval_fast&, const sc_fxval_fast& ); + + + // binary operators + +#define DECL_BIN_OP_T(op,tp) \ + friend const sc_fxval_fast operator op ( const sc_fxval_fast&, tp ); \ + friend const sc_fxval_fast operator op ( tp, const sc_fxval_fast& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_BIN_OP_OTHER(op) \ + DECL_BIN_OP_T(op,int64) \ + DECL_BIN_OP_T(op,uint64) \ + DECL_BIN_OP_T(op,const sc_int_base&) \ + DECL_BIN_OP_T(op,const sc_uint_base&) \ + DECL_BIN_OP_T(op,const sc_signed&) \ + DECL_BIN_OP_T(op,const sc_unsigned&) +#else +#define DECL_BIN_OP_OTHER(op) +#endif + +#define DECL_BIN_OP(op,dummy) \ + friend const sc_fxval_fast operator op ( const sc_fxval_fast&, \ + const sc_fxval_fast& ); \ + DECL_BIN_OP_T(op,int) \ + DECL_BIN_OP_T(op,unsigned int) \ + DECL_BIN_OP_T(op,long) \ + DECL_BIN_OP_T(op,unsigned long) \ + DECL_BIN_OP_T(op,float) \ + DECL_BIN_OP_T(op,double) \ + DECL_BIN_OP_T(op,const char*) \ + DECL_BIN_OP_OTHER(op) + + DECL_BIN_OP(*,mult) + DECL_BIN_OP(+,add) + DECL_BIN_OP(-,sub) +// don't use macro +// DECL_BIN_OP(/,div) + friend const sc_fxval_fast operator / ( const sc_fxval_fast&, + const sc_fxval_fast& ); + DECL_BIN_OP_T(/,int) + DECL_BIN_OP_T(/,unsigned int) + DECL_BIN_OP_T(/,long) + DECL_BIN_OP_T(/,unsigned long) + DECL_BIN_OP_T(/,float) + DECL_BIN_OP_T(/,double) + DECL_BIN_OP_T(/,const char*) +// DECL_BIN_OP_OTHER(/) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_BIN_OP_T(/,int64) \ + DECL_BIN_OP_T(/,uint64) \ + DECL_BIN_OP_T(/,const sc_int_base&) \ + DECL_BIN_OP_T(/,const sc_uint_base&) \ + DECL_BIN_OP_T(/,const sc_signed&) \ + DECL_BIN_OP_T(/,const sc_unsigned&) +#endif + +#undef DECL_BIN_OP_T +#undef DECL_BIN_OP_OTHER +#undef DECL_BIN_OP + + friend const sc_fxval_fast operator << ( const sc_fxval_fast&, int ); + friend const sc_fxval_fast operator >> ( const sc_fxval_fast&, int ); + + + // binary functions + +#define DECL_BIN_FNC_T(fnc,tp) \ + friend void fnc ( sc_fxval_fast&, const sc_fxval_fast&, tp ); \ + friend void fnc ( sc_fxval_fast&, tp, const sc_fxval_fast& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_BIN_FNC_OTHER(fnc) \ + DECL_BIN_FNC_T(fnc,int64) \ + DECL_BIN_FNC_T(fnc,uint64) \ + DECL_BIN_FNC_T(fnc,const sc_int_base&) \ + DECL_BIN_FNC_T(fnc,const sc_uint_base&) \ + DECL_BIN_FNC_T(fnc,const sc_signed&) \ + DECL_BIN_FNC_T(fnc,const sc_unsigned&) +#else +#define DECL_BIN_FNC_OTHER(fnc) +#endif + +#define DECL_BIN_FNC(fnc) \ + friend void fnc ( sc_fxval_fast&, const sc_fxval_fast&, \ + const sc_fxval_fast& ); \ + DECL_BIN_FNC_T(fnc,int) \ + DECL_BIN_FNC_T(fnc,unsigned int) \ + DECL_BIN_FNC_T(fnc,long) \ + DECL_BIN_FNC_T(fnc,unsigned long) \ + DECL_BIN_FNC_T(fnc,float) \ + DECL_BIN_FNC_T(fnc,double) \ + DECL_BIN_FNC_T(fnc,const char*) \ + DECL_BIN_FNC_T(fnc,const sc_fxval&) \ + DECL_BIN_FNC_T(fnc,const sc_fxnum&) \ + DECL_BIN_FNC_OTHER(fnc) + + DECL_BIN_FNC(mult) + DECL_BIN_FNC(div) + DECL_BIN_FNC(add) + DECL_BIN_FNC(sub) + +#undef DECL_BIN_FNC_T +#undef DECL_BIN_FNC_OTHER +#undef DECL_BIN_FNC + + friend void lshift( sc_fxval_fast&, const sc_fxval_fast&, int ); + friend void rshift( sc_fxval_fast&, const sc_fxval_fast&, int ); + + + // relational (including equality) operators + +#define DECL_REL_OP_T(op,tp) \ + friend bool operator op ( const sc_fxval_fast&, tp ); \ + friend bool operator op ( tp, const sc_fxval_fast& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_REL_OP_OTHER(op) \ + DECL_REL_OP_T(op,int64) \ + DECL_REL_OP_T(op,uint64) \ + DECL_REL_OP_T(op,const sc_int_base&) \ + DECL_REL_OP_T(op,const sc_uint_base&) \ + DECL_REL_OP_T(op,const sc_signed&) \ + DECL_REL_OP_T(op,const sc_unsigned&) +#else +#define DECL_REL_OP_OTHER(op) +#endif + +#define DECL_REL_OP(op) \ + friend bool operator op ( const sc_fxval_fast&, const sc_fxval_fast& ); \ + DECL_REL_OP_T(op,int) \ + DECL_REL_OP_T(op,unsigned int) \ + DECL_REL_OP_T(op,long) \ + DECL_REL_OP_T(op,unsigned long) \ + DECL_REL_OP_T(op,float) \ + DECL_REL_OP_T(op,double) \ + DECL_REL_OP_T(op,const char*) \ + DECL_REL_OP_OTHER(op) + + DECL_REL_OP(<) + DECL_REL_OP(<=) + DECL_REL_OP(>) + DECL_REL_OP(>=) + DECL_REL_OP(==) + DECL_REL_OP(!=) + +#undef DECL_REL_OP_T +#undef DECL_REL_OP_OTHER +#undef DECL_REL_OP + + + // assignment operators + +#define DECL_ASN_OP_T(op,tp) \ + sc_fxval_fast& operator op( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval_fast operator ++ ( int ); + const sc_fxval_fast operator -- ( int ); + + sc_fxval_fast& operator ++ (); + sc_fxval_fast& operator -- (); + + + // implicit conversion + + operator double() const; // necessary evil! + + + // explicit conversion to primitive types + + short to_short() const; + unsigned short to_ushort() const; + int to_int() const; + unsigned int to_uint() const; + long to_long() const; + unsigned long to_ulong() const; + int64 to_int64() const; + uint64 to_uint64() const; + float to_float() const; + double to_double() const; + + + // explicit conversion to character string + + const std::string to_string() const; + const std::string to_string( sc_numrep ) const; + const std::string to_string( sc_numrep, bool ) const; + const std::string to_string( sc_fmt ) const; + const std::string to_string( sc_numrep, sc_fmt ) const; + const std::string to_string( sc_numrep, bool, sc_fmt ) const; + + const std::string to_dec() const; + const std::string to_bin() const; + const std::string to_oct() const; + const std::string to_hex() const; + + + // query value + + bool is_neg() const; + bool is_zero() const; + bool is_nan() const; + bool is_inf() const; + bool is_normal() const; + + bool rounding_flag() const; + + + // print or dump content + + void print( ::std::ostream& = ::std::cout ) const; + void scan( ::std::istream& = ::std::cin ); + void dump( ::std::ostream& = ::std::cout ) const; + + + // internal use only; + bool get_bit( int ) const; + +protected: + + sc_fxval_fast_observer* lock_observer() const; + void unlock_observer( sc_fxval_fast_observer* ) const; + + + static double from_string( const char* ); + +private: + + double m_val; + + mutable sc_fxval_fast_observer* m_observer; + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval +// +// Fixed-point value type; arbitrary precision. +// ---------------------------------------------------------------------------- + +// protected method + +inline +sc_fxval_observer* +sc_fxval::observer() const +{ + return m_observer; +} + + +// internal use only; +inline +sc_fxval::sc_fxval( scfx_rep* a ) +: m_rep( a != 0 ? a : new scfx_rep ), + m_observer( 0 ) +{} + + +// public constructors + +inline +sc_fxval::sc_fxval( sc_fxval_observer* observer_ ) +: m_rep( new scfx_rep ), + m_observer( observer_ ) +{ + SC_FXVAL_OBSERVER_DEFAULT_ + SC_FXVAL_OBSERVER_CONSTRUCT_( *this ) +} + +inline +sc_fxval::sc_fxval( const sc_fxval& a, + sc_fxval_observer* observer_ ) +: m_rep( new scfx_rep( *a.m_rep ) ), + m_observer( observer_ ) +{ + SC_FXVAL_OBSERVER_DEFAULT_ + SC_FXVAL_OBSERVER_READ_( a ) + SC_FXVAL_OBSERVER_CONSTRUCT_( *this ) + SC_FXVAL_OBSERVER_WRITE_( *this ) +} + +#define DEFN_CTOR_T(tp,arg) \ +inline \ +sc_fxval::sc_fxval( tp a, \ + sc_fxval_observer* observer_ ) \ +: m_rep( new scfx_rep( arg ) ), \ + m_observer( observer_ ) \ +{ \ + SC_FXVAL_OBSERVER_DEFAULT_ \ + SC_FXVAL_OBSERVER_CONSTRUCT_( *this ) \ + SC_FXVAL_OBSERVER_WRITE_( *this ) \ +} + +#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp,a) +#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp,a.to_double()) +#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp,a.value()) + +DEFN_CTOR_T_A(int) +DEFN_CTOR_T_A(unsigned int) +DEFN_CTOR_T_A(long) +DEFN_CTOR_T_A(unsigned long) +DEFN_CTOR_T_A(float) +DEFN_CTOR_T_A(double) +DEFN_CTOR_T_A(const char*) +DEFN_CTOR_T_B(const sc_fxval_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTOR_T_A(int64) +DEFN_CTOR_T_A(uint64) +DEFN_CTOR_T_C(const sc_int_base&) +DEFN_CTOR_T_C(const sc_uint_base&) +DEFN_CTOR_T_A(const sc_signed&) +DEFN_CTOR_T_A(const sc_unsigned&) +#endif + +#undef DEFN_CTOR_T +#undef DEFN_CTOR_T_A +#undef DEFN_CTOR_T_B +#undef DEFN_CTOR_T_C + + +inline +sc_fxval::~sc_fxval() +{ + SC_FXVAL_OBSERVER_DESTRUCT_( *this ) + delete m_rep; +} + + +// internal use only; +inline +const scfx_rep* +sc_fxval::get_rep() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return m_rep; +} + +// internal use only; +inline +void +sc_fxval::set_rep( scfx_rep* rep_ ) +{ + delete m_rep; + m_rep = rep_; + SC_FXVAL_OBSERVER_WRITE_( *this ) +} + + +// unary operators + +inline +const sc_fxval +sc_fxval::operator - () const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return sc_fxval( sc_dt::neg_scfx_rep( *m_rep ) ); +} + +inline +const sc_fxval& +sc_fxval::operator + () const +{ + // SC_FXVAL_OBSERVER_READ_( *this ) + return *this; +} + + +// unary functions + +inline +void +neg( sc_fxval& c, const sc_fxval& a ) +{ + SC_FXVAL_OBSERVER_READ_( a ) + delete c.m_rep; + c.m_rep = sc_dt::neg_scfx_rep( *a.m_rep ); + SC_FXVAL_OBSERVER_WRITE_( c ) +} + + +// binary operators + +#define DEFN_BIN_OP_T(op,fnc,tp) \ +inline \ +const sc_fxval \ +operator op ( const sc_fxval& a, tp b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( a ) \ + sc_fxval tmp( b ); \ + return sc_fxval( sc_dt::fnc ## _scfx_rep( *a.m_rep, *tmp.m_rep ) ); \ +} \ + \ +inline \ +const sc_fxval \ +operator op ( tp a, const sc_fxval& b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( b ) \ + sc_fxval tmp( a ); \ + return sc_fxval( sc_dt::fnc ## _scfx_rep( *tmp.m_rep, *b.m_rep ) ); \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_BIN_OP_OTHER(op,fnc) \ +DEFN_BIN_OP_T(op,fnc,int64) \ +DEFN_BIN_OP_T(op,fnc,uint64) \ +DEFN_BIN_OP_T(op,fnc,const sc_int_base&) \ +DEFN_BIN_OP_T(op,fnc,const sc_uint_base&) \ +DEFN_BIN_OP_T(op,fnc,const sc_signed&) \ +DEFN_BIN_OP_T(op,fnc,const sc_unsigned&) +#else +#define DEFN_BIN_OP_OTHER(op,fnc) +#endif + +#define DEFN_BIN_OP(op,fnc) \ +inline \ +const sc_fxval \ +operator op ( const sc_fxval& a, const sc_fxval& b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( a ) \ + SC_FXVAL_OBSERVER_READ_( b ) \ + return sc_fxval( sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.m_rep ) ); \ +} \ + \ +DEFN_BIN_OP_T(op,fnc,int) \ +DEFN_BIN_OP_T(op,fnc,unsigned int) \ +DEFN_BIN_OP_T(op,fnc,long) \ +DEFN_BIN_OP_T(op,fnc,unsigned long) \ +DEFN_BIN_OP_T(op,fnc,float) \ +DEFN_BIN_OP_T(op,fnc,double) \ +DEFN_BIN_OP_T(op,fnc,const char*) \ +DEFN_BIN_OP_T(op,fnc,const sc_fxval_fast&) \ +DEFN_BIN_OP_OTHER(op,fnc) + +DEFN_BIN_OP(*,mult) +DEFN_BIN_OP(+,add) +DEFN_BIN_OP(-,sub) +// don't use macro +//DEFN_BIN_OP(/,div) +inline +const sc_fxval +operator / ( const sc_fxval& a, const sc_fxval& b ) +{ + SC_FXVAL_OBSERVER_READ_( a ) + SC_FXVAL_OBSERVER_READ_( b ) + return sc_fxval( sc_dt::div_scfx_rep( *a.m_rep, *b.m_rep ) ); +} + +DEFN_BIN_OP_T(/,div,int) +DEFN_BIN_OP_T(/,div,unsigned int) +DEFN_BIN_OP_T(/,div,long) +DEFN_BIN_OP_T(/,div,unsigned long) +DEFN_BIN_OP_T(/,div,float) +DEFN_BIN_OP_T(/,div,double) +DEFN_BIN_OP_T(/,div,const char*) +DEFN_BIN_OP_T(/,div,const sc_fxval_fast&) +//DEFN_BIN_OP_OTHER(/,div) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_BIN_OP_T(/,div,int64) \ +DEFN_BIN_OP_T(/,div,uint64) \ +DEFN_BIN_OP_T(/,div,const sc_int_base&) \ +DEFN_BIN_OP_T(/,div,const sc_uint_base&) \ +DEFN_BIN_OP_T(/,div,const sc_signed&) \ +DEFN_BIN_OP_T(/,div,const sc_unsigned&) +#endif + +#undef DEFN_BIN_OP_T +#undef DEFN_BIN_OP_OTHER +#undef DEFN_BIN_OP + + +inline +const sc_fxval +operator << ( const sc_fxval& a, int b ) +{ + SC_FXVAL_OBSERVER_READ_( a ) + return sc_fxval( sc_dt::lsh_scfx_rep( *a.m_rep, b ) ); +} + +inline +const sc_fxval +operator >> ( const sc_fxval& a, int b ) +{ + SC_FXVAL_OBSERVER_READ_( a ) + return sc_fxval( sc_dt::rsh_scfx_rep( *a.m_rep, b ) ); +} + + +// binary functions + +#define DEFN_BIN_FNC_T(fnc,tp) \ +inline \ +void \ +fnc ( sc_fxval& c, const sc_fxval& a, tp b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( a ) \ + sc_fxval tmp( b ); \ + delete c.m_rep; \ + c.m_rep = sc_dt::fnc ## _scfx_rep( *a.m_rep, *tmp.m_rep ); \ + SC_FXVAL_OBSERVER_WRITE_( c ) \ +} \ + \ +inline \ +void \ +fnc ( sc_fxval& c, tp a, const sc_fxval& b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( b ) \ + sc_fxval tmp( a ); \ + delete c.m_rep; \ + c.m_rep = sc_dt::fnc ## _scfx_rep( *tmp.m_rep, *b.m_rep ); \ + SC_FXVAL_OBSERVER_WRITE_( c ) \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_BIN_FNC_OTHER(fnc) \ +DEFN_BIN_FNC_T(fnc,int64) \ +DEFN_BIN_FNC_T(fnc,uint64) \ +DEFN_BIN_FNC_T(fnc,const sc_int_base&) \ +DEFN_BIN_FNC_T(fnc,const sc_uint_base&) \ +DEFN_BIN_FNC_T(fnc,const sc_signed&) \ +DEFN_BIN_FNC_T(fnc,const sc_unsigned&) +#else +#define DEFN_BIN_FNC_OTHER(fnc) +#endif + +#define DEFN_BIN_FNC(fnc) \ +inline \ +void \ +fnc( sc_fxval& c, const sc_fxval& a, const sc_fxval& b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( a ) \ + SC_FXVAL_OBSERVER_READ_( b ) \ + delete c.m_rep; \ + c.m_rep = sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.m_rep ); \ + SC_FXVAL_OBSERVER_WRITE_( c ) \ +} \ + \ +DEFN_BIN_FNC_T(fnc,int) \ +DEFN_BIN_FNC_T(fnc,unsigned int) \ +DEFN_BIN_FNC_T(fnc,long) \ +DEFN_BIN_FNC_T(fnc,unsigned long) \ +DEFN_BIN_FNC_T(fnc,float) \ +DEFN_BIN_FNC_T(fnc,double) \ +DEFN_BIN_FNC_T(fnc,const char*) \ +DEFN_BIN_FNC_T(fnc,const sc_fxval_fast&) \ +DEFN_BIN_FNC_OTHER(fnc) + +DEFN_BIN_FNC(mult) +DEFN_BIN_FNC(div) +DEFN_BIN_FNC(add) +DEFN_BIN_FNC(sub) + +#undef DEFN_BIN_FNC_T +#undef DEFN_BIN_FNC_OTHER +#undef DEFN_BIN_FNC + + +inline +void +lshift( sc_fxval& c, const sc_fxval& a, int b ) +{ + SC_FXVAL_OBSERVER_READ_( a ) + delete c.m_rep; + c.m_rep = sc_dt::lsh_scfx_rep( *a.m_rep, b ); + SC_FXVAL_OBSERVER_WRITE_( c ) +} + +inline +void +rshift( sc_fxval& c, const sc_fxval& a, int b ) +{ + SC_FXVAL_OBSERVER_READ_( a ) + delete c.m_rep; + c.m_rep = sc_dt::rsh_scfx_rep( *a.m_rep, b ); + SC_FXVAL_OBSERVER_WRITE_( c ) +} + + +// relational (including equality) operators + +#define DEFN_REL_OP_T(op,ret,tp) \ +inline \ +bool \ +operator op ( const sc_fxval& a, tp b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( a ) \ + sc_fxval tmp( b ); \ + int result = sc_dt::cmp_scfx_rep( *a.m_rep, *tmp.m_rep ); \ + return ( ret ); \ +} \ + \ +inline \ +bool \ +operator op ( tp a, const sc_fxval& b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( b ) \ + sc_fxval tmp( a ); \ + int result = sc_dt::cmp_scfx_rep( *tmp.m_rep, *b.m_rep ); \ + return ( ret ); \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_REL_OP_OTHER(op,ret) \ +DEFN_REL_OP_T(op,ret,int64) \ +DEFN_REL_OP_T(op,ret,uint64) \ +DEFN_REL_OP_T(op,ret,const sc_int_base&) \ +DEFN_REL_OP_T(op,ret,const sc_uint_base&) \ +DEFN_REL_OP_T(op,ret,const sc_signed&) \ +DEFN_REL_OP_T(op,ret,const sc_unsigned&) +#else +#define DEFN_REL_OP_OTHER(op,ret) +#endif + +#define DEFN_REL_OP(op,ret) \ +inline \ +bool \ +operator op ( const sc_fxval& a, const sc_fxval& b) \ +{ \ + SC_FXVAL_OBSERVER_READ_( a ) \ + SC_FXVAL_OBSERVER_READ_( b ) \ + int result = sc_dt::cmp_scfx_rep( *a.m_rep, *b.m_rep ); \ + return ( ret ); \ +} \ + \ +DEFN_REL_OP_T(op,ret,int) \ +DEFN_REL_OP_T(op,ret,unsigned int) \ +DEFN_REL_OP_T(op,ret,long) \ +DEFN_REL_OP_T(op,ret,unsigned long) \ +DEFN_REL_OP_T(op,ret,float) \ +DEFN_REL_OP_T(op,ret,double) \ +DEFN_REL_OP_T(op,ret,const char*) \ +DEFN_REL_OP_T(op,ret,const sc_fxval_fast&) \ +DEFN_REL_OP_OTHER(op,ret) + +DEFN_REL_OP(<,result < 0) +DEFN_REL_OP(<=,result <= 0) +DEFN_REL_OP(>,result > 0 && result != 2) +DEFN_REL_OP(>=,result >= 0 && result != 2) +DEFN_REL_OP(==,result == 0) +DEFN_REL_OP(!=,result != 0) + +#undef DEFN_REL_OP_T +#undef DEFN_REL_OP_OTHER +#undef DEFN_REL_OP + + +// assignment operators + +inline +sc_fxval& +sc_fxval::operator = ( const sc_fxval& a ) +{ + if( &a != this ) + { + SC_FXVAL_OBSERVER_READ_( a ) + *m_rep = *a.m_rep; + SC_FXVAL_OBSERVER_WRITE_( *this ) + } + return *this; +} + +#define DEFN_ASN_OP_T(tp) \ +inline \ +sc_fxval& \ +sc_fxval::operator = ( tp b ) \ +{ \ + sc_fxval tmp( b ); \ + *m_rep = *tmp.m_rep; \ + SC_FXVAL_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +DEFN_ASN_OP_T(int) +DEFN_ASN_OP_T(unsigned int) +DEFN_ASN_OP_T(long) +DEFN_ASN_OP_T(unsigned long) +DEFN_ASN_OP_T(float) +DEFN_ASN_OP_T(double) +DEFN_ASN_OP_T(const char*) +DEFN_ASN_OP_T(const sc_fxval_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_ASN_OP_T(int64) +DEFN_ASN_OP_T(uint64) +DEFN_ASN_OP_T(const sc_int_base&) +DEFN_ASN_OP_T(const sc_uint_base&) +DEFN_ASN_OP_T(const sc_signed&) +DEFN_ASN_OP_T(const sc_unsigned&) +#endif + +#undef DEFN_ASN_OP_T + + +#define DEFN_ASN_OP_T(op,fnc,tp) \ +inline \ +sc_fxval& \ +sc_fxval::operator op ( tp b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( *this ) \ + sc_fxval tmp( b ); \ + scfx_rep* new_rep = sc_dt::fnc ## _scfx_rep( *m_rep, *tmp.m_rep ); \ + delete m_rep; \ + m_rep = new_rep; \ + SC_FXVAL_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op,fnc) \ +DEFN_ASN_OP_T(op,fnc,int64) \ +DEFN_ASN_OP_T(op,fnc,uint64) \ +DEFN_ASN_OP_T(op,fnc,const sc_int_base&) \ +DEFN_ASN_OP_T(op,fnc,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,fnc,const sc_signed&) \ +DEFN_ASN_OP_T(op,fnc,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op,fnc) +#endif + +#define DEFN_ASN_OP(op,fnc) \ +inline \ +sc_fxval& \ +sc_fxval::operator op ( const sc_fxval& b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( *this ) \ + SC_FXVAL_OBSERVER_READ_( b ) \ + scfx_rep* new_rep = sc_dt::fnc ## _scfx_rep( *m_rep, *b.m_rep ); \ + delete m_rep; \ + m_rep = new_rep; \ + SC_FXVAL_OBSERVER_WRITE_( *this ) \ + return *this; \ +} \ + \ +DEFN_ASN_OP_T(op,fnc,int) \ +DEFN_ASN_OP_T(op,fnc,unsigned int) \ +DEFN_ASN_OP_T(op,fnc,long) \ +DEFN_ASN_OP_T(op,fnc,unsigned long) \ +DEFN_ASN_OP_T(op,fnc,float) \ +DEFN_ASN_OP_T(op,fnc,double) \ +DEFN_ASN_OP_T(op,fnc,const char*) \ +DEFN_ASN_OP_T(op,fnc,const sc_fxval_fast&) \ +DEFN_ASN_OP_OTHER(op,fnc) + +DEFN_ASN_OP(*=,mult) +DEFN_ASN_OP(/=,div) +DEFN_ASN_OP(+=,add) +DEFN_ASN_OP(-=,sub) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +inline +sc_fxval& +sc_fxval::operator <<= ( int b ) +{ + SC_FXVAL_OBSERVER_READ_( *this ) + m_rep->lshift( b ); + SC_FXVAL_OBSERVER_WRITE_( *this ) + return *this; +} + +inline +sc_fxval& +sc_fxval::operator >>= ( int b ) +{ + SC_FXVAL_OBSERVER_READ_( *this ) + m_rep->rshift( b ); + SC_FXVAL_OBSERVER_WRITE_( *this ) + return *this; +} + + +// auto-increment and auto-decrement + +inline +const sc_fxval +sc_fxval::operator ++ ( int ) +{ + sc_fxval c = *this; + (*this) += 1; + return c; +} + +inline +const sc_fxval +sc_fxval::operator -- ( int ) +{ + sc_fxval c = *this; + (*this) -= 1; + return c; +} + +inline +sc_fxval& +sc_fxval::operator ++ () +{ + (*this) += 1; + return *this; +} + +inline +sc_fxval& +sc_fxval::operator -- () +{ + (*this) -= 1; + return *this; +} + + +// implicit conversion + +inline +sc_fxval::operator double() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return m_rep->to_double(); +} + + +// explicit conversion to primitive types + +inline +short +sc_fxval::to_short() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return static_cast<short>( m_rep->to_double() ); +} + +inline +unsigned short +sc_fxval::to_ushort() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return static_cast<unsigned short>( m_rep->to_double() ); +} + +inline +int +sc_fxval::to_int() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return static_cast<int>( m_rep->to_double() ); +} + +inline +int64 +sc_fxval::to_int64() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return static_cast<int64>( m_rep->to_double() ); +} + +inline +uint64 +sc_fxval::to_uint64() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return static_cast<uint64>( m_rep->to_double() ); +} + +inline +long +sc_fxval::to_long() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return static_cast<long>( m_rep->to_double() ); +} + +inline +unsigned int +sc_fxval::to_uint() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return static_cast<unsigned int>( m_rep->to_double() ); +} + +inline +unsigned long +sc_fxval::to_ulong() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return static_cast<unsigned long>( m_rep->to_double() ); +} + +inline +float +sc_fxval::to_float() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return static_cast<float>( m_rep->to_double() ); +} + +inline +double +sc_fxval::to_double() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return m_rep->to_double(); +} + + +// query value + +inline +bool +sc_fxval::is_neg() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return m_rep->is_neg(); +} + +inline +bool +sc_fxval::is_zero() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return m_rep->is_zero(); +} + +inline +bool +sc_fxval::is_nan() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return m_rep->is_nan(); +} + +inline +bool +sc_fxval::is_inf() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return m_rep->is_inf(); +} + +inline +bool +sc_fxval::is_normal() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return m_rep->is_normal(); +} + + +inline +bool +sc_fxval::rounding_flag() const +{ + return m_rep->rounding_flag(); +} + + +// internal use only; +inline +bool +sc_fxval::get_bit( int i ) const +{ + return m_rep->get_bit( i ); +} + + +// protected methods and friend functions + +inline +void +sc_fxval::get_type( int& wl, int& iwl, sc_enc& enc ) const +{ + m_rep->get_type( wl, iwl, enc ); +} + + +inline +const sc_fxval +sc_fxval::quantization( const scfx_params& params, bool& q_flag ) const +{ + return sc_fxval( sc_dt::quantization_scfx_rep( *m_rep, params, q_flag ) ); +} + +inline +const sc_fxval +sc_fxval::overflow( const scfx_params& params, bool& o_flag ) const +{ + return sc_fxval( sc_dt::overflow_scfx_rep( *m_rep, params, o_flag ) ); +} + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_fxval& a ) +{ + a.print( os ); + return os; +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_fxval& a ) +{ + a.scan( is ); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval_fast +// +// Fixed-point value type; limited precision. +// ---------------------------------------------------------------------------- + +// protected method + +inline +sc_fxval_fast_observer* +sc_fxval_fast::observer() const +{ + return m_observer; +} + + +// public constructors + +inline +sc_fxval_fast::sc_fxval_fast( sc_fxval_fast_observer* observer_ ) +: m_val( 0.0 ), + m_observer( observer_ ) +{ + SC_FXVAL_FAST_OBSERVER_DEFAULT_ + SC_FXVAL_FAST_OBSERVER_CONSTRUCT_( *this ) +} + +inline +sc_fxval_fast::sc_fxval_fast( const sc_fxval_fast& a, + sc_fxval_fast_observer* observer_ ) +: m_val( a.m_val ), + m_observer( observer_ ) +{ + SC_FXVAL_FAST_OBSERVER_DEFAULT_ + SC_FXVAL_FAST_OBSERVER_READ_( a ) + SC_FXVAL_FAST_OBSERVER_CONSTRUCT_( *this ) + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) +} + +#define DEFN_CTOR_T(tp,arg) \ +inline \ +sc_fxval_fast::sc_fxval_fast( tp a, \ + sc_fxval_fast_observer* observer_ ) \ +: m_val( arg ), \ + m_observer( observer_ ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_DEFAULT_ \ + SC_FXVAL_FAST_OBSERVER_CONSTRUCT_( *this ) \ + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) \ +} + +#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp,static_cast<double>( a )) +#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp,from_string( a )) +#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp,a.to_double()) + +DEFN_CTOR_T_A(int) +DEFN_CTOR_T_A(unsigned int) +DEFN_CTOR_T_A(long) +DEFN_CTOR_T_A(unsigned long) +DEFN_CTOR_T_A(float) +DEFN_CTOR_T_A(double) +DEFN_CTOR_T_B(const char*) +DEFN_CTOR_T_C(const sc_fxval&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTOR_T_A(int64) +DEFN_CTOR_T_A(uint64) +DEFN_CTOR_T_C(const sc_int_base&) +DEFN_CTOR_T_C(const sc_uint_base&) +DEFN_CTOR_T_C(const sc_signed&) +DEFN_CTOR_T_C(const sc_unsigned&) +#endif + +#undef DEFN_CTOR_T +#undef DEFN_CTOR_T_A +#undef DEFN_CTOR_T_B +#undef DEFN_CTOR_T_C +#undef DEFN_CTOR_T_D +#undef DEFN_CTOR_T_E + + +inline +sc_fxval_fast::~sc_fxval_fast() +{ + SC_FXVAL_FAST_OBSERVER_DESTRUCT_( *this ) +} + + +// internal use only; +inline +double +sc_fxval_fast::get_val() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return m_val; +} + +// internal use only; +inline +void +sc_fxval_fast::set_val( double val_ ) +{ + m_val = val_; + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) +} + + +// unary operators + +inline +const sc_fxval_fast +sc_fxval_fast::operator - () const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return sc_fxval_fast( - m_val ); +} + +inline +const sc_fxval_fast& +sc_fxval_fast::operator + () const +{ + // SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return *this; +} + + +// unary functions + +inline +void +neg( sc_fxval_fast& c, const sc_fxval_fast& a ) +{ + SC_FXVAL_FAST_OBSERVER_READ_( a ) + c.m_val = - a.m_val; + SC_FXVAL_FAST_OBSERVER_WRITE_( c ) +} + + +// binary operators + +#define DEFN_BIN_OP_T(op,tp) \ +inline \ +const sc_fxval_fast \ +operator op ( const sc_fxval_fast& a, tp b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( a ) \ + sc_fxval_fast tmp( b ); \ + return sc_fxval_fast( a.m_val op tmp.m_val ); \ +} \ + \ +inline \ +const sc_fxval_fast \ +operator op ( tp a, const sc_fxval_fast& b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( b ) \ + sc_fxval_fast tmp( a ); \ + return sc_fxval_fast( tmp.m_val op b.m_val ); \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_BIN_OP_OTHER(op) \ +DEFN_BIN_OP_T(op,int64) \ +DEFN_BIN_OP_T(op,uint64) \ +DEFN_BIN_OP_T(op,const sc_int_base&) \ +DEFN_BIN_OP_T(op,const sc_uint_base&) \ +DEFN_BIN_OP_T(op,const sc_signed&) \ +DEFN_BIN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_BIN_OP_OTHER(op) +#endif + +#define DEFN_BIN_OP(op,dummy) \ +inline \ +const sc_fxval_fast \ +operator op ( const sc_fxval_fast& a, const sc_fxval_fast& b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( a ) \ + SC_FXVAL_FAST_OBSERVER_READ_( b ) \ + return sc_fxval_fast( a.m_val op b.m_val ); \ +} \ + \ +DEFN_BIN_OP_T(op,int) \ +DEFN_BIN_OP_T(op,unsigned int) \ +DEFN_BIN_OP_T(op,long) \ +DEFN_BIN_OP_T(op,unsigned long) \ +DEFN_BIN_OP_T(op,float) \ +DEFN_BIN_OP_T(op,double) \ +DEFN_BIN_OP_T(op,const char*) \ +DEFN_BIN_OP_OTHER(op) + +DEFN_BIN_OP(*,mult) +DEFN_BIN_OP(+,add) +DEFN_BIN_OP(-,sub) +//DEFN_BIN_OP(/,div) +inline +const sc_fxval_fast +operator / ( const sc_fxval_fast& a, const sc_fxval_fast& b ) +{ + SC_FXVAL_FAST_OBSERVER_READ_( a ) + SC_FXVAL_FAST_OBSERVER_READ_( b ) + return sc_fxval_fast( a.m_val / b.m_val ); +} + +DEFN_BIN_OP_T(/,int) +DEFN_BIN_OP_T(/,unsigned int) +DEFN_BIN_OP_T(/,long) +DEFN_BIN_OP_T(/,unsigned long) +DEFN_BIN_OP_T(/,float) +DEFN_BIN_OP_T(/,double) +DEFN_BIN_OP_T(/,const char*) +//DEFN_BIN_OP_OTHER(/) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_BIN_OP_T(/,int64) +DEFN_BIN_OP_T(/,uint64) +DEFN_BIN_OP_T(/,const sc_int_base&) +DEFN_BIN_OP_T(/,const sc_uint_base&) +DEFN_BIN_OP_T(/,const sc_signed&) +DEFN_BIN_OP_T(/,const sc_unsigned&) +#endif + + +#undef DEFN_BIN_OP_T +#undef DEFN_BIN_OP_OTHER +#undef DEFN_BIN_OP + + +inline +const sc_fxval_fast +operator << ( const sc_fxval_fast& a, int b ) +{ + SC_FXVAL_FAST_OBSERVER_READ_( a ) + return sc_fxval_fast( a.m_val * scfx_pow2( b ) ); +} + +inline +const sc_fxval_fast +operator >> ( const sc_fxval_fast& a, int b ) +{ + SC_FXVAL_FAST_OBSERVER_READ_( a ) + return sc_fxval_fast( a.m_val * scfx_pow2( -b ) ); +} + + +// binary functions + +#define DEFN_BIN_FNC_T(fnc,op,tp) \ +inline \ +void \ +fnc ( sc_fxval_fast& c, const sc_fxval_fast& a, tp b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( a ) \ + sc_fxval_fast tmp( b ); \ + c.m_val = a.m_val op tmp.m_val; \ + SC_FXVAL_FAST_OBSERVER_WRITE_( c ) \ +} \ + \ +inline \ +void \ +fnc ( sc_fxval_fast& c, tp a, const sc_fxval_fast& b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( b ) \ + sc_fxval_fast tmp( a ); \ + c.m_val = tmp.m_val op b.m_val; \ + SC_FXVAL_FAST_OBSERVER_WRITE_( c ) \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_BIN_FNC_OTHER(fnc,op) \ +DEFN_BIN_FNC_T(fnc,op,int64) \ +DEFN_BIN_FNC_T(fnc,op,uint64) \ +DEFN_BIN_FNC_T(fnc,op,const sc_int_base&) \ +DEFN_BIN_FNC_T(fnc,op,const sc_uint_base&) \ +DEFN_BIN_FNC_T(fnc,op,const sc_signed&) \ +DEFN_BIN_FNC_T(fnc,op,const sc_unsigned&) +#else +#define DEFN_BIN_FNC_OTHER(fnc,op) +#endif + +#define DEFN_BIN_FNC(fnc,op) \ +inline \ +void \ +fnc ( sc_fxval_fast& c, const sc_fxval_fast& a, const sc_fxval_fast& b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( a ) \ + SC_FXVAL_FAST_OBSERVER_READ_( b ) \ + c.m_val = a.m_val op b.m_val; \ + SC_FXVAL_FAST_OBSERVER_WRITE_( c ) \ +} \ + \ +DEFN_BIN_FNC_T(fnc,op,int) \ +DEFN_BIN_FNC_T(fnc,op,unsigned int) \ +DEFN_BIN_FNC_T(fnc,op,long) \ +DEFN_BIN_FNC_T(fnc,op,unsigned long) \ +DEFN_BIN_FNC_T(fnc,op,float) \ +DEFN_BIN_FNC_T(fnc,op,double) \ +DEFN_BIN_FNC_T(fnc,op,const char*) \ +DEFN_BIN_FNC_OTHER(fnc,op) + +DEFN_BIN_FNC(mult,*) +DEFN_BIN_FNC(div,/) +DEFN_BIN_FNC(add,+) +DEFN_BIN_FNC(sub,-) + +#undef DEFN_BIN_FNC_T +#undef DEFN_BIN_FNC_OTHER +#undef DEFN_BIN_FNC + + +inline +void +lshift( sc_fxval_fast& c, const sc_fxval_fast& a, int b ) +{ + SC_FXVAL_FAST_OBSERVER_READ_( a ) + c.m_val = a.m_val * scfx_pow2( b ); + SC_FXVAL_FAST_OBSERVER_WRITE_( c ) +} + +inline +void +rshift( sc_fxval_fast& c, const sc_fxval_fast& a, int b ) +{ + SC_FXVAL_FAST_OBSERVER_READ_( a ) + c.m_val = a.m_val * scfx_pow2( -b ); + SC_FXVAL_FAST_OBSERVER_WRITE_( c ) +} + + +// relational (including equality) operators + +#define DEFN_REL_OP_T(op,tp) \ +inline \ +bool \ +operator op ( const sc_fxval_fast& a, tp b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( a ) \ + sc_fxval_fast tmp( b ); \ + return ( a.m_val op tmp.m_val ); \ +} \ + \ +inline \ +bool \ +operator op ( tp a, const sc_fxval_fast& b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( b ) \ + sc_fxval_fast tmp( a ); \ + return ( tmp.m_val op b.m_val ); \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_REL_OP_OTHER(op) \ +DEFN_REL_OP_T(op,int64) \ +DEFN_REL_OP_T(op,uint64) \ +DEFN_REL_OP_T(op,const sc_int_base&) \ +DEFN_REL_OP_T(op,const sc_uint_base&) \ +DEFN_REL_OP_T(op,const sc_signed&) \ +DEFN_REL_OP_T(op,const sc_unsigned&) +#else +#define DEFN_REL_OP_OTHER(op) +#endif + +#define DEFN_REL_OP(op) \ +inline \ +bool \ +operator op ( const sc_fxval_fast& a, const sc_fxval_fast& b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( a ) \ + SC_FXVAL_FAST_OBSERVER_READ_( b ) \ + return ( a.m_val op b.m_val ); \ +} \ + \ +DEFN_REL_OP_T(op,int) \ +DEFN_REL_OP_T(op,unsigned int) \ +DEFN_REL_OP_T(op,long) \ +DEFN_REL_OP_T(op,unsigned long) \ +DEFN_REL_OP_T(op,float) \ +DEFN_REL_OP_T(op,double) \ +DEFN_REL_OP_T(op,const char*) \ +DEFN_REL_OP_OTHER(op) + +DEFN_REL_OP(<) +DEFN_REL_OP(<=) +DEFN_REL_OP(>) +DEFN_REL_OP(>=) +DEFN_REL_OP(==) +DEFN_REL_OP(!=) + +#undef DEFN_REL_OP_T +#undef DEFN_REL_OP_OTHER +#undef DEFN_REL_OP + + +// assignment operators + +inline +sc_fxval_fast& +sc_fxval_fast::operator = ( const sc_fxval_fast& a ) +{ + if( &a != this ) + { + SC_FXVAL_FAST_OBSERVER_READ_( a ) + m_val = a.m_val; + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) + } + return *this; +} + +#define DEFN_ASN_OP_T(tp) \ +inline \ +sc_fxval_fast& \ +sc_fxval_fast::operator = ( tp a ) \ +{ \ + sc_fxval_fast tmp( a ); \ + m_val = tmp.m_val; \ + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +DEFN_ASN_OP_T(int) +DEFN_ASN_OP_T(unsigned int) +DEFN_ASN_OP_T(long) +DEFN_ASN_OP_T(unsigned long) +DEFN_ASN_OP_T(float) +DEFN_ASN_OP_T(double) +DEFN_ASN_OP_T(const char*) +DEFN_ASN_OP_T(const sc_fxval&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_ASN_OP_T(int64) +DEFN_ASN_OP_T(uint64) +DEFN_ASN_OP_T(const sc_int_base&) +DEFN_ASN_OP_T(const sc_uint_base&) +DEFN_ASN_OP_T(const sc_signed&) +DEFN_ASN_OP_T(const sc_unsigned&) +#endif + +#undef DEFN_ASN_OP_T + + +#define DEFN_ASN_OP_T(op,tp) \ +inline \ +sc_fxval_fast& \ +sc_fxval_fast::operator op ( tp b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) \ + sc_fxval_fast tmp( b ); \ + m_val op tmp.m_val; \ + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op) \ +DEFN_ASN_OP_T(op,int64) \ +DEFN_ASN_OP_T(op,uint64) \ +DEFN_ASN_OP_T(op,const sc_int_base&) \ +DEFN_ASN_OP_T(op,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,const sc_signed&) \ +DEFN_ASN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op) +#endif + +#define DEFN_ASN_OP(op) \ +inline \ +sc_fxval_fast& \ +sc_fxval_fast::operator op ( const sc_fxval_fast& b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) \ + SC_FXVAL_FAST_OBSERVER_READ_( b ) \ + m_val op b.m_val; \ + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} \ + \ +DEFN_ASN_OP_T(op,int) \ +DEFN_ASN_OP_T(op,unsigned int) \ +DEFN_ASN_OP_T(op,long) \ +DEFN_ASN_OP_T(op,unsigned long) \ +DEFN_ASN_OP_T(op,float) \ +DEFN_ASN_OP_T(op,double) \ +DEFN_ASN_OP_T(op,const char*) \ +DEFN_ASN_OP_T(op,const sc_fxval&) \ +DEFN_ASN_OP_OTHER(op) + +DEFN_ASN_OP(*=) +DEFN_ASN_OP(/=) +DEFN_ASN_OP(+=) +DEFN_ASN_OP(-=) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +inline +sc_fxval_fast& +sc_fxval_fast::operator <<= ( int b ) +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + m_val *= scfx_pow2( b ); + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) + return *this; +} + +inline +sc_fxval_fast& +sc_fxval_fast::operator >>= ( int b ) +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + m_val *= scfx_pow2( -b ); + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) + return *this; +} + + +// auto-increment and auto-decrement + +inline +const sc_fxval_fast +sc_fxval_fast::operator ++ ( int ) +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + double c = m_val; + m_val = m_val + 1; + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) + return sc_fxval_fast( c ); +} + +inline +const sc_fxval_fast +sc_fxval_fast::operator -- ( int ) +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + double c = m_val; + m_val = m_val - 1; + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) + return sc_fxval_fast( c ); +} + +inline +sc_fxval_fast& +sc_fxval_fast::operator ++ () +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + m_val = m_val + 1; + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) + return *this; +} + +inline +sc_fxval_fast& +sc_fxval_fast::operator -- () +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + m_val = m_val - 1; + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) + return *this; +} + + +// implicit conversion + +inline +sc_fxval_fast::operator double() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return m_val; +} + + +// explicit conversion to primitive types + +inline +short +sc_fxval_fast::to_short() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return static_cast<short>( m_val ); +} + +inline +unsigned short +sc_fxval_fast::to_ushort() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return static_cast<unsigned short>( m_val ); +} + +inline +int64 +sc_fxval_fast::to_int64() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return static_cast<int64>( m_val ); +} + +inline +int +sc_fxval_fast::to_int() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return static_cast<int>( m_val ); +} + +inline +unsigned int +sc_fxval_fast::to_uint() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return static_cast<unsigned int>( m_val ); +} + +inline +uint64 +sc_fxval_fast::to_uint64() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return static_cast<uint64>( m_val ); +} + +inline +long +sc_fxval_fast::to_long() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return static_cast<long>( m_val ); +} + +inline +unsigned long +sc_fxval_fast::to_ulong() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return static_cast<unsigned long>( m_val ); +} + +inline +float +sc_fxval_fast::to_float() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return static_cast<float>( m_val ); +} + +inline +double +sc_fxval_fast::to_double() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return m_val; +} + + +// query value + +inline +bool +sc_fxval_fast::is_neg() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + scfx_ieee_double id( m_val ); + return ( id.negative() != 0 ); +} + +inline +bool +sc_fxval_fast::is_zero() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + scfx_ieee_double id( m_val ); + return id.is_zero(); +} + +inline +bool +sc_fxval_fast::is_nan() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + scfx_ieee_double id( m_val ); + return id.is_nan(); +} + +inline +bool +sc_fxval_fast::is_inf() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + scfx_ieee_double id( m_val ); + return id.is_inf(); +} + +inline +bool +sc_fxval_fast::is_normal() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + scfx_ieee_double id( m_val ); + return ( id.is_normal() || id.is_subnormal() || id.is_zero() ); +} + + +inline +bool +sc_fxval_fast::rounding_flag() const +{ + // does not apply to sc_fxval_fast; included for API compatibility + return false; +} + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_fxval_fast& a ) +{ + a.print( os ); + return os; +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_fxval_fast& a ) +{ + a.scan( is ); + return is; +} + +} // namespace sc_dt + +#undef SCFX_EXPLICIT_ +#undef SCFX_EXPLICIT_OTHER_ + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxval_observer.cpp b/ext/systemc/src/sysc/datatypes/fx/sc_fxval_observer.cpp new file mode 100644 index 000000000..ae651cc14 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxval_observer.cpp @@ -0,0 +1,76 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxval_observer.cpp - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_fxval_observer.cpp,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#include "sysc/datatypes/fx/sc_fxval_observer.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval_observer +// +// Abstract base class for fixed-point value type observers; +// arbitrary precision. +// ---------------------------------------------------------------------------- + +sc_fxval_observer* (*sc_fxval_observer::default_observer) () = 0; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval_fast_observer +// +// Abstract base class for fixed-point value type observers; +// limited precision. +// ---------------------------------------------------------------------------- + +sc_fxval_fast_observer* (*sc_fxval_fast_observer::default_observer) () = 0; + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxval_observer.h b/ext/systemc/src/sysc/datatypes/fx/sc_fxval_observer.h new file mode 100644 index 000000000..e34d85c1b --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxval_observer.h @@ -0,0 +1,223 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxval_observer.h - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_fxval_observer.h,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_FXVAL_OBSERVER_H +#define SC_FXVAL_OBSERVER_H + + +#include "sysc/datatypes/fx/sc_fxdefs.h" + + +namespace sc_dt +{ + +// classes defined in this module +class sc_fxval_observer; +class sc_fxval_fast_observer; + +// forward class declarations +class sc_fxval; +class sc_fxval_fast; + + +#ifdef SC_ENABLE_OBSERVERS + +#define SC_FXVAL_OBSERVER_CONSTRUCT_(object) \ + SC_OBSERVER_(object,sc_fxval_observer*,construct) +#define SC_FXVAL_OBSERVER_DESTRUCT_(object) \ + SC_OBSERVER_(object,sc_fxval_observer*,destruct) +#define SC_FXVAL_OBSERVER_READ_(object) \ + SC_OBSERVER_(object,sc_fxval_observer*,read) +#define SC_FXVAL_OBSERVER_WRITE_(object) \ + SC_OBSERVER_(object,sc_fxval_observer*,write) +#define SC_FXVAL_OBSERVER_DEFAULT_ \ + SC_OBSERVER_DEFAULT_(sc_fxval_observer) + +#define SC_FXVAL_FAST_OBSERVER_CONSTRUCT_(object) \ + SC_OBSERVER_(object,sc_fxval_fast_observer*,construct) +#define SC_FXVAL_FAST_OBSERVER_DESTRUCT_(object) \ + SC_OBSERVER_(object,sc_fxval_fast_observer*,destruct) +#define SC_FXVAL_FAST_OBSERVER_READ_(object) \ + SC_OBSERVER_(object,sc_fxval_fast_observer*,read) +#define SC_FXVAL_FAST_OBSERVER_WRITE_(object) \ + SC_OBSERVER_(object,sc_fxval_fast_observer*,write) +#define SC_FXVAL_FAST_OBSERVER_DEFAULT_ \ + SC_OBSERVER_DEFAULT_(sc_fxval_fast_observer) + +#else + +#define SC_FXVAL_OBSERVER_CONSTRUCT_(object) +#define SC_FXVAL_OBSERVER_DESTRUCT_(object) +#define SC_FXVAL_OBSERVER_READ_(object) +#define SC_FXVAL_OBSERVER_WRITE_(object) +#define SC_FXVAL_OBSERVER_DEFAULT_ + +#define SC_FXVAL_FAST_OBSERVER_CONSTRUCT_(object) +#define SC_FXVAL_FAST_OBSERVER_DESTRUCT_(object) +#define SC_FXVAL_FAST_OBSERVER_READ_(object) +#define SC_FXVAL_FAST_OBSERVER_WRITE_(object) +#define SC_FXVAL_FAST_OBSERVER_DEFAULT_ + +#endif + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval_observer +// +// Abstract base class for fixed-point value type observers; +// arbitrary precision. +// ---------------------------------------------------------------------------- + +class sc_fxval_observer +{ + +protected: + + sc_fxval_observer() {} + virtual ~sc_fxval_observer() {} + +public: + + virtual void construct( const sc_fxval& ); + virtual void destruct( const sc_fxval& ); + virtual void read( const sc_fxval& ); + virtual void write( const sc_fxval& ); + + static sc_fxval_observer* (*default_observer) (); + +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval_fast_observer +// +// Abstract base class for fixed-point value type observers; +// limited precision. +// ---------------------------------------------------------------------------- + +class sc_fxval_fast_observer +{ + +protected: + + sc_fxval_fast_observer() {} + virtual ~sc_fxval_fast_observer() {} + +public: + + virtual void construct( const sc_fxval_fast& ); + virtual void destruct( const sc_fxval_fast& ); + virtual void read( const sc_fxval_fast& ); + virtual void write( const sc_fxval_fast& ); + + static sc_fxval_fast_observer* (*default_observer) (); + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval_observer +// +// Abstract base class for fixed-point value type observers; +// arbitrary precision. +// ---------------------------------------------------------------------------- + +inline +void +sc_fxval_observer::construct( const sc_fxval& ) +{} + +inline +void +sc_fxval_observer::destruct( const sc_fxval& ) +{} + +inline +void +sc_fxval_observer::read( const sc_fxval& ) +{} + +inline +void +sc_fxval_observer::write( const sc_fxval& ) +{} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval_fast_observer +// +// Abstract base class for fixed-point value type observers; +// limited precision. +// ---------------------------------------------------------------------------- + +inline +void +sc_fxval_fast_observer::construct( const sc_fxval_fast& ) +{} + +inline +void +sc_fxval_fast_observer::destruct( const sc_fxval_fast& ) +{} + +inline +void +sc_fxval_fast_observer::read( const sc_fxval_fast& ) +{} + +inline +void +sc_fxval_fast_observer::write( const sc_fxval_fast& ) +{} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_ufix.h b/ext/systemc/src/sysc/datatypes/fx/sc_ufix.h new file mode 100644 index 000000000..b8d9acaa1 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_ufix.h @@ -0,0 +1,1941 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_ufix.h - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_ufix.h,v $ +// Revision 1.2 2011/01/20 22:52:30 acg +// Andy Goodrich: Add float constructors. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_UFIX_H +#define SC_UFIX_H + + +#include "sysc/datatypes/fx/sc_fxnum.h" + + +namespace sc_dt +{ + +// classes defined in this module +class sc_ufix; +class sc_ufix_fast; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_ufix +// +// "Unconstrained" unsigned fixed-point class; arbitrary precision. +// ---------------------------------------------------------------------------- + +class sc_ufix : public sc_fxnum +{ + +public: + + // constructors + + explicit sc_ufix( sc_fxnum_observer* = 0 ); + sc_ufix( int, int, + sc_fxnum_observer* = 0 ); + sc_ufix( sc_q_mode, sc_o_mode, + sc_fxnum_observer* = 0 ); + sc_ufix( sc_q_mode, sc_o_mode, int, + sc_fxnum_observer* = 0 ); + sc_ufix( int, int, sc_q_mode, sc_o_mode, + sc_fxnum_observer* = 0 ); + sc_ufix( int, int, sc_q_mode, sc_o_mode, int, + sc_fxnum_observer* = 0 ); + explicit sc_ufix( const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + sc_ufix( int, int, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + sc_ufix( sc_q_mode, sc_o_mode, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + sc_ufix( sc_q_mode, sc_o_mode, int, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + sc_ufix( int, int, sc_q_mode, sc_o_mode, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + sc_ufix( int, int, sc_q_mode, sc_o_mode, int, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + explicit sc_ufix( const sc_fxtype_params&, + sc_fxnum_observer* = 0 ); + sc_ufix( const sc_fxtype_params&, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + +#define DECL_CTORS_T(tp) \ + sc_ufix( tp, \ + int, int, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + sc_q_mode, sc_o_mode, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + sc_q_mode, sc_o_mode, int, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + int, int, sc_q_mode, sc_o_mode, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + int, int, sc_q_mode, sc_o_mode, int, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + int, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + sc_q_mode, sc_o_mode, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + sc_q_mode, sc_o_mode, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + int, int, sc_q_mode, sc_o_mode, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + int, int, sc_q_mode, sc_o_mode, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + const sc_fxtype_params&, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + const sc_fxtype_params&, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); + +#define DECL_CTORS_T_A(tp) \ + sc_ufix( tp, \ + sc_fxnum_observer* = 0 ); \ + DECL_CTORS_T(tp) + +#define DECL_CTORS_T_B(tp) \ + explicit sc_ufix( tp, \ + sc_fxnum_observer* = 0 ); \ + DECL_CTORS_T(tp) + + DECL_CTORS_T_A(int) + DECL_CTORS_T_A(unsigned int) + DECL_CTORS_T_A(long) + DECL_CTORS_T_A(unsigned long) + DECL_CTORS_T_A(float) + DECL_CTORS_T_A(double) + DECL_CTORS_T_A(const char*) + DECL_CTORS_T_A(const sc_fxval&) + DECL_CTORS_T_A(const sc_fxval_fast&) + DECL_CTORS_T_A(const sc_fxnum&) + DECL_CTORS_T_A(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_CTORS_T_B(int64) + DECL_CTORS_T_B(uint64) + DECL_CTORS_T_B(const sc_int_base&) + DECL_CTORS_T_B(const sc_uint_base&) + DECL_CTORS_T_B(const sc_signed&) + DECL_CTORS_T_B(const sc_unsigned&) +#endif + +#undef DECL_CTORS_T +#undef DECL_CTORS_T_A +#undef DECL_CTORS_T_B + + // copy constructor + + sc_ufix( const sc_ufix& ); + + + // unary bitwise operators + + const sc_ufix operator ~ () const; + + + // unary bitwise functions + + friend void b_not( sc_ufix&, const sc_ufix& ); + + + // binary bitwise operators + + friend const sc_ufix operator & ( const sc_ufix&, const sc_ufix& ); + friend const sc_ufix operator & ( const sc_ufix&, const sc_ufix_fast& ); + friend const sc_ufix operator & ( const sc_ufix_fast&, const sc_ufix& ); + friend const sc_ufix operator | ( const sc_ufix&, const sc_ufix& ); + friend const sc_ufix operator | ( const sc_ufix&, const sc_ufix_fast& ); + friend const sc_ufix operator | ( const sc_ufix_fast&, const sc_ufix& ); + friend const sc_ufix operator ^ ( const sc_ufix&, const sc_ufix& ); + friend const sc_ufix operator ^ ( const sc_ufix&, const sc_ufix_fast& ); + friend const sc_ufix operator ^ ( const sc_ufix_fast&, const sc_ufix& ); + + + // binary bitwise functions + + friend void b_and( sc_ufix&, const sc_ufix&, const sc_ufix& ); + friend void b_and( sc_ufix&, const sc_ufix&, const sc_ufix_fast& ); + friend void b_and( sc_ufix&, const sc_ufix_fast&, const sc_ufix& ); + friend void b_or ( sc_ufix&, const sc_ufix&, const sc_ufix& ); + friend void b_or ( sc_ufix&, const sc_ufix&, const sc_ufix_fast& ); + friend void b_or ( sc_ufix&, const sc_ufix_fast&, const sc_ufix& ); + friend void b_xor( sc_ufix&, const sc_ufix&, const sc_ufix& ); + friend void b_xor( sc_ufix&, const sc_ufix&, const sc_ufix_fast& ); + friend void b_xor( sc_ufix&, const sc_ufix_fast&, const sc_ufix& ); + + + // assignment operators + + sc_ufix& operator = ( const sc_ufix& ); + +#define DECL_ASN_OP_T(op,tp) \ + sc_ufix& operator op ( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + + DECL_ASN_OP_T(&=,const sc_ufix&) + DECL_ASN_OP_T(&=,const sc_ufix_fast&) + DECL_ASN_OP_T(|=,const sc_ufix&) + DECL_ASN_OP_T(|=,const sc_ufix_fast&) + DECL_ASN_OP_T(^=,const sc_ufix&) + DECL_ASN_OP_T(^=,const sc_ufix_fast&) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval operator ++ ( int ); + const sc_fxval operator -- ( int ); + + sc_ufix& operator ++ (); + sc_ufix& operator -- (); + +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_ufix_fast +// +// "Unconstrained" unsigned fixed-point class; limited precision. +// ---------------------------------------------------------------------------- + +class sc_ufix_fast : public sc_fxnum_fast +{ + +public: + + // constructors + + explicit sc_ufix_fast( sc_fxnum_fast_observer* = 0 ); + sc_ufix_fast( int, int, + sc_fxnum_fast_observer* = 0 ); + sc_ufix_fast( sc_q_mode, sc_o_mode, + sc_fxnum_fast_observer* = 0 ); + sc_ufix_fast( sc_q_mode, sc_o_mode, int, + sc_fxnum_fast_observer* = 0 ); + sc_ufix_fast( int, int, sc_q_mode, sc_o_mode, + sc_fxnum_fast_observer* = 0 ); + sc_ufix_fast( int, int, sc_q_mode, sc_o_mode, int, + sc_fxnum_fast_observer* = 0 ); + explicit sc_ufix_fast( const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + sc_ufix_fast( int, int, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + sc_ufix_fast( sc_q_mode, sc_o_mode, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + sc_ufix_fast( sc_q_mode, sc_o_mode, int, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + sc_ufix_fast( int, int, sc_q_mode, sc_o_mode, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + sc_ufix_fast( int, int, sc_q_mode, sc_o_mode, int, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + explicit sc_ufix_fast( const sc_fxtype_params&, + sc_fxnum_fast_observer* = 0 ); + sc_ufix_fast( const sc_fxtype_params&, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + +#define DECL_CTORS_T(tp) \ + sc_ufix_fast( tp, \ + int, int, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + sc_q_mode, sc_o_mode, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + sc_q_mode, sc_o_mode, int, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + int, int, sc_q_mode, sc_o_mode, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + int, int, sc_q_mode, sc_o_mode, int, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + int, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + sc_q_mode, sc_o_mode, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + sc_q_mode, sc_o_mode, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + int, int, sc_q_mode, sc_o_mode, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + int, int, sc_q_mode, sc_o_mode, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + const sc_fxtype_params&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + const sc_fxtype_params&, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); + +#define DECL_CTORS_T_A(tp) \ + sc_ufix_fast( tp, \ + sc_fxnum_fast_observer* = 0 ); \ + DECL_CTORS_T(tp) + +#define DECL_CTORS_T_B(tp) \ + explicit sc_ufix_fast( tp, \ + sc_fxnum_fast_observer* = 0 ); \ + DECL_CTORS_T(tp) + + DECL_CTORS_T_A(int) + DECL_CTORS_T_A(unsigned int) + DECL_CTORS_T_A(long) + DECL_CTORS_T_A(unsigned long) + DECL_CTORS_T_A(float) + DECL_CTORS_T_A(double) + DECL_CTORS_T_A(const char*) + DECL_CTORS_T_A(const sc_fxval&) + DECL_CTORS_T_A(const sc_fxval_fast&) + DECL_CTORS_T_A(const sc_fxnum&) + DECL_CTORS_T_A(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_CTORS_T_B(int64) + DECL_CTORS_T_B(uint64) + DECL_CTORS_T_B(const sc_int_base&) + DECL_CTORS_T_B(const sc_uint_base&) + DECL_CTORS_T_B(const sc_signed&) + DECL_CTORS_T_B(const sc_unsigned&) +#endif + +#undef DECL_CTORS_T +#undef DECL_CTORS_T_A +#undef DECL_CTORS_T_B + + // copy constructor + + sc_ufix_fast( const sc_ufix_fast& ); + + + // unary bitwise operators + + const sc_ufix_fast operator ~ () const; + + + // unary bitwise functions + + friend void b_not( sc_ufix_fast&, const sc_ufix_fast& ); + + + // binary bitwise operators + + friend const sc_ufix_fast operator & ( const sc_ufix_fast&, + const sc_ufix_fast& ); + friend const sc_ufix_fast operator ^ ( const sc_ufix_fast&, + const sc_ufix_fast& ); + friend const sc_ufix_fast operator | ( const sc_ufix_fast&, + const sc_ufix_fast& ); + + + // binary bitwise functions + + friend void b_and( sc_ufix_fast&, const sc_ufix_fast&, + const sc_ufix_fast& ); + friend void b_or ( sc_ufix_fast&, const sc_ufix_fast&, + const sc_ufix_fast& ); + friend void b_xor( sc_ufix_fast&, const sc_ufix_fast&, + const sc_ufix_fast& ); + + + // assignment operators + + sc_ufix_fast& operator = ( const sc_ufix_fast& ); + +#define DECL_ASN_OP_T(op,tp) \ + sc_ufix_fast& operator op ( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + + DECL_ASN_OP_T(&=,const sc_ufix&) + DECL_ASN_OP_T(&=,const sc_ufix_fast&) + DECL_ASN_OP_T(|=,const sc_ufix&) + DECL_ASN_OP_T(|=,const sc_ufix_fast&) + DECL_ASN_OP_T(^=,const sc_ufix&) + DECL_ASN_OP_T(^=,const sc_ufix_fast&) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval_fast operator ++ ( int ); + const sc_fxval_fast operator -- ( int ); + + sc_ufix_fast& operator ++ (); + sc_ufix_fast& operator -- (); + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// ---------------------------------------------------------------------------- +// CLASS : sc_ufix +// +// "Unconstrained" unsigned fixed-point class; arbitrary precision. +// ---------------------------------------------------------------------------- + +// constructors + +inline +sc_ufix::sc_ufix( sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params(), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix::sc_ufix( int wl_, int iwl_, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_ ), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix::sc_ufix( sc_q_mode qm, sc_o_mode om, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( qm, om ), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix::sc_ufix( sc_q_mode qm, sc_o_mode om, int nb, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( qm, om, nb ), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix::sc_ufix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om ), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix::sc_ufix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om, nb ), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix::sc_ufix( const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params(), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix::sc_ufix( int wl_, int iwl_, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_ ), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix::sc_ufix( sc_q_mode qm, sc_o_mode om, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( qm, om ), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix::sc_ufix( sc_q_mode qm, sc_o_mode om, int nb, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( qm, om, nb ), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix::sc_ufix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om ), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix::sc_ufix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om, nb ), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix::sc_ufix( const sc_fxtype_params& type_params, + sc_fxnum_observer* observer_ ) +: sc_fxnum( type_params, + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix::sc_ufix( const sc_fxtype_params& type_params, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( type_params, + SC_US_, + cast_sw, + observer_ ) +{} + +#define DEFN_CTORS_T_A(tp) \ +inline \ +sc_ufix::sc_ufix( tp a, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params(), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_ ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( qm, om ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( qm, om, nb ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params(), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_ ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( qm, om ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( qm, om, nb ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + const sc_fxtype_params& type_params, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + type_params, \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + const sc_fxtype_params& type_params, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + type_params, \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} + +#define DEFN_CTORS_T_B(tp) \ +inline \ +sc_ufix::sc_ufix( tp a, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + a.type_params(), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), wl_, iwl_ ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), qm, om ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), qm, om, nb ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + a.type_params(), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), wl_, iwl_ ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), qm, om ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), qm, om, nb ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + const sc_fxtype_params& type_params, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + type_params, \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + const sc_fxtype_params& type_params, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + type_params, \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} + +DEFN_CTORS_T_A(int) +DEFN_CTORS_T_A(unsigned int) +DEFN_CTORS_T_A(long) +DEFN_CTORS_T_A(unsigned long) +DEFN_CTORS_T_A(float) +DEFN_CTORS_T_A(double) +DEFN_CTORS_T_A(const char*) +DEFN_CTORS_T_A(const sc_fxval&) +DEFN_CTORS_T_A(const sc_fxval_fast&) +DEFN_CTORS_T_B(const sc_fxnum&) +DEFN_CTORS_T_B(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTORS_T_A(int64) +DEFN_CTORS_T_A(uint64) +DEFN_CTORS_T_A(const sc_int_base&) +DEFN_CTORS_T_A(const sc_uint_base&) +DEFN_CTORS_T_A(const sc_signed&) +DEFN_CTORS_T_A(const sc_unsigned&) +#endif + +#undef DEFN_CTORS_T_A +#undef DEFN_CTORS_T_B + +// copy constructor + +inline +sc_ufix::sc_ufix( const sc_ufix& a ) +: sc_fxnum( a, + a.type_params(), + SC_US_, + sc_fxcast_switch(), + 0 ) +{} + + +// unary bitwise operators + +inline +const sc_ufix +sc_ufix::operator ~ () const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + int iwl_c = iwl(); + int wl_c = wl(); + sc_ufix c( wl_c, iwl_c ); + for( int i = iwl_c - wl_c; i < iwl_c; ++ i ) + c.set_bit( i, ! get_bit( i ) ); + return sc_ufix( c, wl_c, iwl_c ); +} + + +// unary bitwise functions + +inline +void +b_not( sc_ufix& c, const sc_ufix& a ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + int iwl_c = c.iwl(); + for( int i = iwl_c - c.wl(); i < iwl_c; ++ i ) + c.set_bit( i, ! a.get_bit( i ) ); + c.cast(); + SC_FXNUM_OBSERVER_WRITE_( c ) +} + + +// binary bitwise operators + +#define DEFN_BIN_OP_T(op,op2,tp1,tp2) \ +inline \ +const sc_ufix \ +operator op ( const tp1& a, const tp2& b ) \ +{ \ + a.observer_read(); \ + b.observer_read(); \ + int iwl_a = a.iwl(); \ + int iwl_b = b.iwl(); \ + int iwl_c = sc_max( iwl_a, iwl_b ); \ + int fwl_c = sc_max( a.wl() - iwl_a, b.wl() - iwl_b ); \ + sc_ufix c( iwl_c + fwl_c, iwl_c ); \ + for( int i = -fwl_c; i < iwl_c; ++ i ) \ + c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \ + return sc_ufix( c, iwl_c + fwl_c, iwl_c ); \ +} + +DEFN_BIN_OP_T(&,&&,sc_ufix,sc_ufix) +DEFN_BIN_OP_T(&,&&,sc_ufix,sc_ufix_fast) +DEFN_BIN_OP_T(&,&&,sc_ufix_fast,sc_ufix) + +DEFN_BIN_OP_T(|,||,sc_ufix,sc_ufix) +DEFN_BIN_OP_T(|,||,sc_ufix,sc_ufix_fast) +DEFN_BIN_OP_T(|,||,sc_ufix_fast,sc_ufix) + +DEFN_BIN_OP_T(^,!=,sc_ufix,sc_ufix) +DEFN_BIN_OP_T(^,!=,sc_ufix,sc_ufix_fast) +DEFN_BIN_OP_T(^,!=,sc_ufix_fast,sc_ufix) + +#undef DEFN_BIN_OP_T + + +// binary bitwise functions + +#define DEFN_BIN_FNC_T(fnc,op2,tp1,tp2) \ +inline \ +void \ +fnc ( sc_ufix& c, const tp1& a, const tp2& b ) \ +{ \ + a.observer_read(); \ + b.observer_read(); \ + int iwl_c = c.iwl(); \ + for( int i = iwl_c - c.wl(); i < iwl_c; ++ i ) \ + c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \ + c.cast(); \ + SC_FXNUM_OBSERVER_WRITE_( c ) \ +} + +DEFN_BIN_FNC_T(b_and,&&,sc_ufix,sc_ufix) +DEFN_BIN_FNC_T(b_and,&&,sc_ufix,sc_ufix_fast) +DEFN_BIN_FNC_T(b_and,&&,sc_ufix_fast,sc_ufix) + +DEFN_BIN_FNC_T(b_or,||,sc_ufix,sc_ufix) +DEFN_BIN_FNC_T(b_or,||,sc_ufix,sc_ufix_fast) +DEFN_BIN_FNC_T(b_or,||,sc_ufix_fast,sc_ufix) + +DEFN_BIN_FNC_T(b_xor,!=,sc_ufix,sc_ufix) +DEFN_BIN_FNC_T(b_xor,!=,sc_ufix,sc_ufix_fast) +DEFN_BIN_FNC_T(b_xor,!=,sc_ufix_fast,sc_ufix) + +#undef DEFN_BIN_FNC_T + + +// assignment operators + +inline +sc_ufix& +sc_ufix::operator = ( const sc_ufix& a ) +{ + sc_fxnum::operator = ( a ); + return *this; +} + +#define DEFN_ASN_OP_T(op,tp) \ +inline \ +sc_ufix& \ +sc_ufix::operator op ( tp a ) \ +{ \ + sc_fxnum::operator op( a ); \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op) \ +DEFN_ASN_OP_T(op,int64) \ +DEFN_ASN_OP_T(op,uint64) \ +DEFN_ASN_OP_T(op,const sc_int_base&) \ +DEFN_ASN_OP_T(op,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,const sc_signed&) \ +DEFN_ASN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op) +#endif + +#define DEFN_ASN_OP(op) \ +DEFN_ASN_OP_T(op,int) \ +DEFN_ASN_OP_T(op,unsigned int) \ +DEFN_ASN_OP_T(op,long) \ +DEFN_ASN_OP_T(op,unsigned long) \ +DEFN_ASN_OP_T(op,float) \ +DEFN_ASN_OP_T(op,double) \ +DEFN_ASN_OP_T(op,const char*) \ +DEFN_ASN_OP_T(op,const sc_fxval&) \ +DEFN_ASN_OP_T(op,const sc_fxval_fast&) \ +DEFN_ASN_OP_T(op,const sc_fxnum&) \ +DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \ +DEFN_ASN_OP_OTHER(op) + +DEFN_ASN_OP(=) + +DEFN_ASN_OP(*=) +DEFN_ASN_OP(/=) +DEFN_ASN_OP(+=) +DEFN_ASN_OP(-=) + +DEFN_ASN_OP_T(<<=,int) +DEFN_ASN_OP_T(>>=,int) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +#define DEFN_ASN_OP_T(op,op2,tp) \ +inline \ +sc_ufix& \ +sc_ufix::operator op ( const tp& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( *this ) \ + b.observer_read(); \ + int iwl_c = iwl(); \ + for( int i = iwl_c - wl(); i < iwl_c; ++ i ) \ + set_bit( i, get_bit( i ) op2 b.get_bit( i ) ); \ + cast(); \ + SC_FXNUM_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +DEFN_ASN_OP_T(&=,&&,sc_ufix) +DEFN_ASN_OP_T(&=,&&,sc_ufix_fast) +DEFN_ASN_OP_T(|=,||,sc_ufix) +DEFN_ASN_OP_T(|=,||,sc_ufix_fast) +DEFN_ASN_OP_T(^=,!=,sc_ufix) +DEFN_ASN_OP_T(^=,!=,sc_ufix_fast) + +#undef DEFN_ASN_OP_T + + +// auto-increment and auto-decrement + +inline +const sc_fxval +sc_ufix::operator ++ ( int ) +{ + return sc_fxval( sc_fxnum::operator ++ ( 0 ) ); +} + +inline +const sc_fxval +sc_ufix::operator -- ( int ) +{ + return sc_fxval( sc_fxnum::operator -- ( 0 ) ); +} + +inline +sc_ufix& +sc_ufix::operator ++ () +{ + sc_fxnum::operator ++ (); + return *this; +} + +inline +sc_ufix& +sc_ufix::operator -- () +{ + sc_fxnum::operator -- (); + return *this; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_ufix_fast +// +// "Unconstrained" unsigned fixed-point class; limited precision. +// ---------------------------------------------------------------------------- + +// constructors + +inline +sc_ufix_fast::sc_ufix_fast( sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params(), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( int wl_, int iwl_, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_ ), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( sc_q_mode qm, sc_o_mode om, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( qm, om ), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( sc_q_mode qm, sc_o_mode om, int nb, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( qm, om, nb ), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om ), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( int wl_, int iwl_, + sc_q_mode qm, sc_o_mode om, int nb, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om, nb ), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params(), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( int wl_, int iwl_, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_ ), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( sc_q_mode qm, sc_o_mode om, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( qm, om ), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( sc_q_mode qm, sc_o_mode om, int nb, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( qm, om, nb ), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om ), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( int wl_, int iwl_, + sc_q_mode qm, sc_o_mode om, int nb, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om, nb ), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( const sc_fxtype_params& type_params, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( type_params, + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( const sc_fxtype_params& type_params, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( type_params, + SC_US_, + cast_sw, + observer_ ) +{} + +#define DEFN_CTORS_T_A(tp) \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params(), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_ ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( qm, om ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( qm, om, nb ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params(), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_ ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( qm, om ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( qm, om, nb ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + const sc_fxtype_params& type_params, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + type_params, \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + const sc_fxtype_params& type_params, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + type_params, \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} + +#define DEFN_CTORS_T_B(tp) \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + a.type_params(), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), wl_, iwl_ ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), qm, om ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), qm, om, nb ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + a.type_params(), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), wl_, iwl_ ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), qm, om ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), qm, om, nb ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + const sc_fxtype_params& type_params, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + type_params, \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + const sc_fxtype_params& type_params, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + type_params, \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} + +DEFN_CTORS_T_A(int) +DEFN_CTORS_T_A(unsigned int) +DEFN_CTORS_T_A(long) +DEFN_CTORS_T_A(unsigned long) +DEFN_CTORS_T_A(float) +DEFN_CTORS_T_A(double) +DEFN_CTORS_T_A(const char*) +DEFN_CTORS_T_A(const sc_fxval&) +DEFN_CTORS_T_A(const sc_fxval_fast&) +DEFN_CTORS_T_B(const sc_fxnum&) +DEFN_CTORS_T_B(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTORS_T_A(int64) +DEFN_CTORS_T_A(uint64) +DEFN_CTORS_T_A(const sc_int_base&) +DEFN_CTORS_T_A(const sc_uint_base&) +DEFN_CTORS_T_A(const sc_signed&) +DEFN_CTORS_T_A(const sc_unsigned&) +#endif + +#undef DEFN_CTORS_T_A +#undef DEFN_CTORS_T_B + +// copy constructor + +inline +sc_ufix_fast::sc_ufix_fast( const sc_ufix_fast& a ) +: sc_fxnum_fast( a, + a.type_params(), + SC_US_, + sc_fxcast_switch(), + 0 ) +{} + + +// unary bitwise operators + +inline +const sc_ufix_fast +sc_ufix_fast::operator ~ () const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + int iwl_c = iwl(); + int wl_c = wl(); + sc_ufix_fast c( wl_c, iwl_c ); + for( int i = iwl_c - wl_c; i < iwl_c; ++ i ) + c.set_bit( i, ! get_bit( i ) ); + return sc_ufix_fast( c, wl_c, iwl_c ); +} + + +// unary bitwise functions + +inline +void +b_not( sc_ufix_fast& c, const sc_ufix_fast& a ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + int iwl_c = c.iwl(); + for( int i = iwl_c - c.wl(); i < iwl_c; ++ i ) + c.set_bit( i, ! a.get_bit( i ) ); + c.cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) +} + + +// binary bitwise operators + +#define DEFN_BIN_OP_T(op,op2,tp1,tp2) \ +inline \ +const sc_ufix_fast \ +operator op ( const tp1& a, const tp2& b ) \ +{ \ + a.observer_read(); \ + b.observer_read(); \ + int iwl_a = a.iwl(); \ + int iwl_b = b.iwl(); \ + int iwl_c = sc_max( iwl_a, iwl_b ); \ + int fwl_c = sc_max( a.wl() - iwl_a, b.wl() - iwl_b ); \ + sc_ufix_fast c( iwl_c + fwl_c, iwl_c ); \ + for( int i = -fwl_c; i < iwl_c; ++ i ) \ + c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \ + return sc_ufix_fast( c, iwl_c + fwl_c, iwl_c ); \ +} + +DEFN_BIN_OP_T(&,&&,sc_ufix_fast,sc_ufix_fast) +DEFN_BIN_OP_T(|,||,sc_ufix_fast,sc_ufix_fast) +DEFN_BIN_OP_T(^,!=,sc_ufix_fast,sc_ufix_fast) + +#undef DEFN_BIN_OP_T + + +// binary bitwise functions + +#define DEFN_BIN_FNC_T(fnc,op2,tp1,tp2) \ +inline \ +void \ +fnc ( sc_ufix_fast& c, const tp1& a, const tp2& b ) \ +{ \ + a.observer_read(); \ + b.observer_read(); \ + int iwl_c = c.iwl(); \ + for( int i = iwl_c - c.wl(); i < iwl_c; ++ i ) \ + c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \ + c.cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) \ +} + +DEFN_BIN_FNC_T(b_and,&&,sc_ufix_fast,sc_ufix_fast) +DEFN_BIN_FNC_T(b_or,||,sc_ufix_fast,sc_ufix_fast) +DEFN_BIN_FNC_T(b_xor,!=,sc_ufix_fast,sc_ufix_fast) + +#undef DEFN_BIN_FNC_T + + +// assignment operators + +inline +sc_ufix_fast& +sc_ufix_fast::operator = ( const sc_ufix_fast& a ) +{ + sc_fxnum_fast::operator = ( a ); + return *this; +} + +#define DEFN_ASN_OP_T(op,tp) \ +inline \ +sc_ufix_fast& \ +sc_ufix_fast::operator op ( tp a ) \ +{ \ + sc_fxnum_fast::operator op( a ); \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op) \ +DEFN_ASN_OP_T(op,int64) \ +DEFN_ASN_OP_T(op,uint64) \ +DEFN_ASN_OP_T(op,const sc_int_base&) \ +DEFN_ASN_OP_T(op,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,const sc_signed&) \ +DEFN_ASN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op) +#endif + +#define DEFN_ASN_OP(op) \ +DEFN_ASN_OP_T(op,int) \ +DEFN_ASN_OP_T(op,unsigned int) \ +DEFN_ASN_OP_T(op,long) \ +DEFN_ASN_OP_T(op,unsigned long) \ +DEFN_ASN_OP_T(op,float) \ +DEFN_ASN_OP_T(op,double) \ +DEFN_ASN_OP_T(op,const char*) \ +DEFN_ASN_OP_T(op,const sc_fxval&) \ +DEFN_ASN_OP_T(op,const sc_fxval_fast&) \ +DEFN_ASN_OP_T(op,const sc_fxnum&) \ +DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \ +DEFN_ASN_OP_OTHER(op) + +DEFN_ASN_OP(=) + +DEFN_ASN_OP(*=) +DEFN_ASN_OP(/=) +DEFN_ASN_OP(+=) +DEFN_ASN_OP(-=) + +DEFN_ASN_OP_T(<<=,int) +DEFN_ASN_OP_T(>>=,int) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +#define DEFN_ASN_OP_T(op,op2,tp) \ +inline \ +sc_ufix_fast& \ +sc_ufix_fast::operator op ( const tp& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) \ + b.observer_read(); \ + int iwl_c = iwl(); \ + for( int i = iwl_c - wl(); i < iwl_c; ++ i ) \ + set_bit( i, get_bit( i ) op2 b.get_bit( i ) ); \ + cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +DEFN_ASN_OP_T(&=,&&,sc_ufix) +DEFN_ASN_OP_T(&=,&&,sc_ufix_fast) +DEFN_ASN_OP_T(|=,||,sc_ufix) +DEFN_ASN_OP_T(|=,||,sc_ufix_fast) +DEFN_ASN_OP_T(^=,!=,sc_ufix) +DEFN_ASN_OP_T(^=,!=,sc_ufix_fast) + +#undef DEFN_ASN_OP_T + + +// auto-increment and auto-decrement + +inline +const sc_fxval_fast +sc_ufix_fast::operator ++ ( int ) +{ + return sc_fxval_fast( sc_fxnum_fast::operator ++ ( 0 ) ); +} + +inline +const sc_fxval_fast +sc_ufix_fast::operator -- ( int ) +{ + return sc_fxval_fast( sc_fxnum_fast::operator -- ( 0 ) ); +} + +inline +sc_ufix_fast& +sc_ufix_fast::operator ++ () +{ + sc_fxnum_fast::operator ++ (); + return *this; +} + +inline +sc_ufix_fast& +sc_ufix_fast::operator -- () +{ + sc_fxnum_fast::operator -- (); + return *this; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_ufixed.h b/ext/systemc/src/sysc/datatypes/fx/sc_ufixed.h new file mode 100644 index 000000000..266e4b7bb --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_ufixed.h @@ -0,0 +1,660 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_ufixed.h - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_ufixed.h,v $ +// Revision 1.2 2011/01/19 18:57:40 acg +// Andy Goodrich: changes for IEEE_1666_2011. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_UFIXED_H +#define SC_UFIXED_H + + +#include "sysc/datatypes/fx/sc_ufix.h" + + +namespace sc_dt +{ + +// classes defined in this module +template <int W, int I, sc_q_mode Q, sc_o_mode O, int N> class sc_ufixed; +template <int W, int I, sc_q_mode Q, sc_o_mode O, int N> class sc_ufixed_fast; + + +// ---------------------------------------------------------------------------- +// TEMPLATE CLASS : sc_ufixed +// +// "Constrained" unsigned fixed-point class; arbitrary precision. +// ---------------------------------------------------------------------------- + +template <int W, int I, + sc_q_mode Q = SC_DEFAULT_Q_MODE_, + sc_o_mode O = SC_DEFAULT_O_MODE_, int N = SC_DEFAULT_N_BITS_> +class sc_ufixed : public sc_ufix +{ + +public: + + // constructors + + explicit sc_ufixed( sc_fxnum_observer* = 0 ); + explicit sc_ufixed( const sc_fxcast_switch&, sc_fxnum_observer* = 0 ); + +#define DECL_CTORS_T_A(tp) \ + sc_ufixed( tp, sc_fxnum_observer* = 0 ); \ + sc_ufixed( tp, const sc_fxcast_switch&, sc_fxnum_observer* = 0 ); + +#define DECL_CTORS_T_B(tp) \ + explicit sc_ufixed( tp, sc_fxnum_observer* = 0 ); \ + sc_ufixed( tp, const sc_fxcast_switch&, sc_fxnum_observer* = 0 ); + + DECL_CTORS_T_A(int) + DECL_CTORS_T_A(unsigned int) + DECL_CTORS_T_A(long) + DECL_CTORS_T_A(unsigned long) + DECL_CTORS_T_A(float) + DECL_CTORS_T_A(double) + DECL_CTORS_T_A(const char*) + DECL_CTORS_T_A(const sc_fxval&) + DECL_CTORS_T_A(const sc_fxval_fast&) + DECL_CTORS_T_A(const sc_fxnum&) + DECL_CTORS_T_A(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_CTORS_T_B(int64) + DECL_CTORS_T_B(uint64) + DECL_CTORS_T_B(const sc_int_base&) + DECL_CTORS_T_B(const sc_uint_base&) + DECL_CTORS_T_B(const sc_signed&) + DECL_CTORS_T_B(const sc_unsigned&) +#endif + +#undef DECL_CTORS_T_A +#undef DECL_CTORS_T_B + + // copy constructor + + sc_ufixed( const sc_ufixed<W,I,Q,O,N>& ); + + + // assignment operators + + sc_ufixed& operator = ( const sc_ufixed<W,I,Q,O,N>& ); + +#define DECL_ASN_OP_T(op,tp) \ + sc_ufixed& operator op ( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + + DECL_ASN_OP_T(&=,const sc_ufix&) + DECL_ASN_OP_T(&=,const sc_ufix_fast&) + DECL_ASN_OP_T(|=,const sc_ufix&) + DECL_ASN_OP_T(|=,const sc_ufix_fast&) + DECL_ASN_OP_T(^=,const sc_ufix&) + DECL_ASN_OP_T(^=,const sc_ufix_fast&) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval operator ++ ( int ); + const sc_fxval operator -- ( int ); + + sc_ufixed& operator ++ (); + sc_ufixed& operator -- (); + +}; + + +// ---------------------------------------------------------------------------- +// TEMPLATE CLASS : sc_ufixed_fast +// +// "Constrained" unsigned fixed-point class; limited precision. +// ---------------------------------------------------------------------------- + +template <int W, int I, + sc_q_mode Q = SC_DEFAULT_Q_MODE_, + sc_o_mode O = SC_DEFAULT_O_MODE_, int N = SC_DEFAULT_N_BITS_> +class sc_ufixed_fast : public sc_ufix_fast +{ + +public: + + // constructors + + explicit sc_ufixed_fast( sc_fxnum_fast_observer* = 0 ); + explicit sc_ufixed_fast( const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + +#define DECL_CTORS_T_A(tp) \ + sc_ufixed_fast( tp, sc_fxnum_fast_observer* = 0 ); \ + sc_ufixed_fast( tp, const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); + +#define DECL_CTORS_T_B(tp) \ + explicit sc_ufixed_fast( tp, sc_fxnum_fast_observer* = 0 ); \ + sc_ufixed_fast( tp, const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); + + DECL_CTORS_T_A(int) + DECL_CTORS_T_A(unsigned int) + DECL_CTORS_T_A(long) + DECL_CTORS_T_A(unsigned long) + DECL_CTORS_T_A(float) + DECL_CTORS_T_A(double) + DECL_CTORS_T_A(const char*) + DECL_CTORS_T_A(const sc_fxval&) + DECL_CTORS_T_A(const sc_fxval_fast&) + DECL_CTORS_T_A(const sc_fxnum&) + DECL_CTORS_T_A(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_CTORS_T_B(int64) + DECL_CTORS_T_B(uint64) + DECL_CTORS_T_B(const sc_int_base&) + DECL_CTORS_T_B(const sc_uint_base&) + DECL_CTORS_T_B(const sc_signed&) + DECL_CTORS_T_B(const sc_unsigned&) +#endif + +#undef DECL_CTORS_T_A +#undef DECL_CTORS_T_B + + // copy constructor + + sc_ufixed_fast( const sc_ufixed_fast<W,I,Q,O,N>& ); + + + // assignment operators + + sc_ufixed_fast& operator = ( const sc_ufixed_fast<W,I,Q,O,N>& ); + +#define DECL_ASN_OP_T(op,tp) \ + sc_ufixed_fast& operator op ( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + + DECL_ASN_OP_T(&=,const sc_ufix&) + DECL_ASN_OP_T(&=,const sc_ufix_fast&) + DECL_ASN_OP_T(|=,const sc_ufix&) + DECL_ASN_OP_T(|=,const sc_ufix_fast&) + DECL_ASN_OP_T(^=,const sc_ufix&) + DECL_ASN_OP_T(^=,const sc_ufix_fast&) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval_fast operator ++ ( int ); + const sc_fxval_fast operator -- ( int ); + + sc_ufixed_fast& operator ++ (); + sc_ufixed_fast& operator -- (); + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// ---------------------------------------------------------------------------- +// TEMPLATE CLASS : sc_ufixed +// +// "Constrained" unsigned fixed-point class; arbitrary precision. +// ---------------------------------------------------------------------------- + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed<W,I,Q,O,N>::sc_ufixed( sc_fxnum_observer* observer_ ) +: sc_ufix( W, I, Q, O, N, observer_ ) +{} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed<W,I,Q,O,N>::sc_ufixed( const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_ufix( W, I, Q, O, N, cast_sw, observer_ ) +{} + +#define DEFN_CTORS_T(tp) \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_ufixed<W,I,Q,O,N>::sc_ufixed( tp a, \ + sc_fxnum_observer* observer_ ) \ +: sc_ufix( a, W, I, Q, O, N, observer_ ) \ +{} \ + \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_ufixed<W,I,Q,O,N>::sc_ufixed( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_ufix( a, W, I, Q, O, N, cast_sw, observer_ ) \ +{} + +DEFN_CTORS_T(int) +DEFN_CTORS_T(unsigned int) +DEFN_CTORS_T(long) +DEFN_CTORS_T(unsigned long) +DEFN_CTORS_T(float) +DEFN_CTORS_T(double) +DEFN_CTORS_T(const char*) +DEFN_CTORS_T(const sc_fxval&) +DEFN_CTORS_T(const sc_fxval_fast&) +DEFN_CTORS_T(const sc_fxnum&) +DEFN_CTORS_T(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTORS_T(int64) +DEFN_CTORS_T(uint64) +DEFN_CTORS_T(const sc_int_base&) +DEFN_CTORS_T(const sc_uint_base&) +DEFN_CTORS_T(const sc_signed&) +DEFN_CTORS_T(const sc_unsigned&) +#endif + +#undef DEFN_CTORS_T + +// copy constructor + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed<W,I,Q,O,N>::sc_ufixed( const sc_ufixed<W,I,Q,O,N>& a ) +: sc_ufix( a, W, I, Q, O, N ) +{} + + +// assignment operators + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed<W,I,Q,O,N>& +sc_ufixed<W,I,Q,O,N>::operator = ( const sc_ufixed<W,I,Q,O,N>& a ) +{ + sc_ufix::operator = ( a ); + return *this; +} + +#define DEFN_ASN_OP_T(op,tp) \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_ufixed<W,I,Q,O,N>& \ +sc_ufixed<W,I,Q,O,N>::operator op ( tp a ) \ +{ \ + sc_ufix::operator op ( a ); \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op) \ +DEFN_ASN_OP_T(op,int64) \ +DEFN_ASN_OP_T(op,uint64) \ +DEFN_ASN_OP_T(op,const sc_int_base&) \ +DEFN_ASN_OP_T(op,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,const sc_signed&) \ +DEFN_ASN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op) +#endif + +#define DEFN_ASN_OP(op) \ +DEFN_ASN_OP_T(op,int) \ +DEFN_ASN_OP_T(op,unsigned int) \ +DEFN_ASN_OP_T(op,long) \ +DEFN_ASN_OP_T(op,unsigned long) \ +DEFN_ASN_OP_T(op,float) \ +DEFN_ASN_OP_T(op,double) \ +DEFN_ASN_OP_T(op,const char*) \ +DEFN_ASN_OP_T(op,const sc_fxval&) \ +DEFN_ASN_OP_T(op,const sc_fxval_fast&) \ +DEFN_ASN_OP_T(op,const sc_fxnum&) \ +DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \ +DEFN_ASN_OP_OTHER(op) + +DEFN_ASN_OP(=) + +DEFN_ASN_OP(*=) +DEFN_ASN_OP(/=) +DEFN_ASN_OP(+=) +DEFN_ASN_OP(-=) + +DEFN_ASN_OP_T(<<=,int) +DEFN_ASN_OP_T(>>=,int) + +DEFN_ASN_OP_T(&=,const sc_ufix&) +DEFN_ASN_OP_T(&=,const sc_ufix_fast&) +DEFN_ASN_OP_T(|=,const sc_ufix&) +DEFN_ASN_OP_T(|=,const sc_ufix_fast&) +DEFN_ASN_OP_T(^=,const sc_ufix&) +DEFN_ASN_OP_T(^=,const sc_ufix_fast&) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +// auto-increment and auto-decrement + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +const sc_fxval +sc_ufixed<W,I,Q,O,N>::operator ++ ( int ) +{ + return sc_fxval( sc_ufix::operator ++ ( 0 ) ); +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +const sc_fxval +sc_ufixed<W,I,Q,O,N>::operator -- ( int ) +{ + return sc_fxval( sc_ufix::operator -- ( 0 ) ); +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed<W,I,Q,O,N>& +sc_ufixed<W,I,Q,O,N>::operator ++ () +{ + sc_ufix::operator ++ (); + return *this; +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed<W,I,Q,O,N>& +sc_ufixed<W,I,Q,O,N>::operator -- () +{ + sc_ufix::operator -- (); + return *this; +} + + +// ---------------------------------------------------------------------------- +// TEMPLATE CLASS : sc_ufixed_fast +// +// "Constrained" unsigned fixed-point class; limited precision. +// ---------------------------------------------------------------------------- + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed_fast<W,I,Q,O,N>::sc_ufixed_fast( sc_fxnum_fast_observer* observer_ ) +: sc_ufix_fast( W, I, Q, O, N, observer_ ) +{} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed_fast<W,I,Q,O,N>::sc_ufixed_fast( const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_ufix_fast( W, I, Q, O, N, cast_sw, observer_ ) +{} + +#define DEFN_CTORS_T(tp) \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_ufixed_fast<W,I,Q,O,N>::sc_ufixed_fast( tp a, \ + sc_fxnum_fast_observer* observer_ )\ +: sc_ufix_fast( a, W, I, Q, O, N, observer_ ) \ +{} \ + \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_ufixed_fast<W,I,Q,O,N>::sc_ufixed_fast( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ )\ +: sc_ufix_fast( a, W, I, Q, O, N, cast_sw, observer_ ) \ +{} + +DEFN_CTORS_T(int) +DEFN_CTORS_T(unsigned int) +DEFN_CTORS_T(long) +DEFN_CTORS_T(unsigned long) +DEFN_CTORS_T(float) +DEFN_CTORS_T(double) +DEFN_CTORS_T(const char*) +DEFN_CTORS_T(const sc_fxval&) +DEFN_CTORS_T(const sc_fxval_fast&) +DEFN_CTORS_T(const sc_fxnum&) +DEFN_CTORS_T(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTORS_T(int64) +DEFN_CTORS_T(uint64) +DEFN_CTORS_T(const sc_int_base&) +DEFN_CTORS_T(const sc_uint_base&) +DEFN_CTORS_T(const sc_signed&) +DEFN_CTORS_T(const sc_unsigned&) +#endif + +#undef DEFN_CTORS_T + +// copy constructor + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed_fast<W,I,Q,O,N>::sc_ufixed_fast( const sc_ufixed_fast<W,I,Q,O,N>& a ) +: sc_ufix_fast( a, W, I, Q, O, N ) +{} + + +// assignment operators + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed_fast<W,I,Q,O,N>& +sc_ufixed_fast<W,I,Q,O,N>::operator = ( const sc_ufixed_fast<W,I,Q,O,N>& a ) +{ + sc_ufix_fast::operator = ( a ); + return *this; +} + +#define DEFN_ASN_OP_T(op,tp) \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_ufixed_fast<W,I,Q,O,N>& \ +sc_ufixed_fast<W,I,Q,O,N>::operator op ( tp a ) \ +{ \ + sc_ufix_fast::operator op ( a ); \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op) \ +DEFN_ASN_OP_T(op,int64) \ +DEFN_ASN_OP_T(op,uint64) \ +DEFN_ASN_OP_T(op,const sc_int_base&) \ +DEFN_ASN_OP_T(op,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,const sc_signed&) \ +DEFN_ASN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op) +#endif + +#define DEFN_ASN_OP(op) \ +DEFN_ASN_OP_T(op,int) \ +DEFN_ASN_OP_T(op,unsigned int) \ +DEFN_ASN_OP_T(op,long) \ +DEFN_ASN_OP_T(op,unsigned long) \ +DEFN_ASN_OP_T(op,float) \ +DEFN_ASN_OP_T(op,double) \ +DEFN_ASN_OP_T(op,const char*) \ +DEFN_ASN_OP_T(op,const sc_fxval&) \ +DEFN_ASN_OP_T(op,const sc_fxval_fast&) \ +DEFN_ASN_OP_T(op,const sc_fxnum&) \ +DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \ +DEFN_ASN_OP_OTHER(op) + +DEFN_ASN_OP(=) + +DEFN_ASN_OP(*=) +DEFN_ASN_OP(/=) +DEFN_ASN_OP(+=) +DEFN_ASN_OP(-=) + +DEFN_ASN_OP_T(<<=,int) +DEFN_ASN_OP_T(>>=,int) + +DEFN_ASN_OP_T(&=,const sc_ufix&) +DEFN_ASN_OP_T(&=,const sc_ufix_fast&) +DEFN_ASN_OP_T(|=,const sc_ufix&) +DEFN_ASN_OP_T(|=,const sc_ufix_fast&) +DEFN_ASN_OP_T(^=,const sc_ufix&) +DEFN_ASN_OP_T(^=,const sc_ufix_fast&) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +// auto-increment and auto-decrement + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +const sc_fxval_fast +sc_ufixed_fast<W,I,Q,O,N>::operator ++ ( int ) +{ + return sc_fxval_fast( sc_ufix_fast::operator ++ ( 0 ) ); +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +const sc_fxval_fast +sc_ufixed_fast<W,I,Q,O,N>::operator -- ( int ) +{ + return sc_fxval_fast( sc_ufix_fast::operator -- ( 0 ) ); +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed_fast<W,I,Q,O,N>& +sc_ufixed_fast<W,I,Q,O,N>::operator ++ () +{ + sc_ufix_fast::operator ++ (); + return *this; +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed_fast<W,I,Q,O,N>& +sc_ufixed_fast<W,I,Q,O,N>::operator -- () +{ + sc_ufix_fast::operator -- (); + return *this; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_ieee.h b/ext/systemc/src/sysc/datatypes/fx/scfx_ieee.h new file mode 100644 index 000000000..b2da95432 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_ieee.h @@ -0,0 +1,701 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_ieee.h - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: scfx_ieee.h,v $ +// Revision 1.3 2011/08/24 22:05:43 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.2 2011/08/07 18:55:24 acg +// Philipp A. Hartmann: added guard for __clang__ to get the clang platform +// working. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SCFX_IEEE_H +#define SCFX_IEEE_H + + +#include "sysc/datatypes/fx/sc_fxdefs.h" + + +namespace sc_dt +{ + +// classes defined in this module +union ieee_double; +class scfx_ieee_double; +union ieee_float; +class scfx_ieee_float; + +#define SCFX_MASK_(Size) \ + ((1u << (Size))-1u) + +// ---------------------------------------------------------------------------- +// UNION : ieee_double +// +// IEEE 754 double-precision format. +// ---------------------------------------------------------------------------- + +union ieee_double +{ + + double d; + + struct + { +#if defined( SC_BIG_ENDIAN ) + unsigned negative:1; + unsigned exponent:11; + unsigned mantissa0:20; + unsigned mantissa1:32; +#elif defined( SC_LITTLE_ENDIAN ) + unsigned mantissa1:32; + unsigned mantissa0:20; + unsigned exponent:11; + unsigned negative:1; +#endif + } s; + +}; + + +const unsigned int SCFX_IEEE_DOUBLE_BIAS = 1023U; + +const int SCFX_IEEE_DOUBLE_E_MAX = 1023; +const int SCFX_IEEE_DOUBLE_E_MIN = -1022; + +const unsigned int SCFX_IEEE_DOUBLE_M_SIZE = 52; +const unsigned int SCFX_IEEE_DOUBLE_M0_SIZE = 20; +const unsigned int SCFX_IEEE_DOUBLE_M1_SIZE = 32; +const unsigned int SCFX_IEEE_DOUBLE_E_SIZE = 11; + + + +// ---------------------------------------------------------------------------- +// CLASS : scfx_ieee_double +// +// Convenient interface to union ieee_double. +// ---------------------------------------------------------------------------- + +class scfx_ieee_double +{ + + ieee_double m_id; + +public: + + scfx_ieee_double(); + scfx_ieee_double( double ); + scfx_ieee_double( const scfx_ieee_double& ); + + scfx_ieee_double& operator = ( double ); + scfx_ieee_double& operator = ( const scfx_ieee_double& ); + + operator double() const; + + unsigned int negative() const; + void negative( unsigned int ); + int exponent() const; + void exponent( int ); + unsigned int mantissa0() const; + void mantissa0( unsigned int ); + unsigned int mantissa1() const; + void mantissa1( unsigned int ); + + bool is_zero() const; + bool is_subnormal() const; + bool is_normal() const; + bool is_inf() const; + bool is_nan() const; + + void set_inf(); + void set_nan(); + + int msb() const; // most significant non-zero bit + int lsb() const; // least significant non-zero bit + + static const scfx_ieee_double nan(); + static const scfx_ieee_double inf( int ); + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +inline +scfx_ieee_double::scfx_ieee_double() : m_id() +{ + m_id.d = 0.0; +} + +inline +scfx_ieee_double::scfx_ieee_double( double d ) : m_id() +{ + m_id.d = d; +} + +inline +scfx_ieee_double::scfx_ieee_double( const scfx_ieee_double& a ) : m_id(a.m_id) +{ + // m_id.d = a.m_id.d; +} + + +inline +scfx_ieee_double& +scfx_ieee_double::operator = ( double d ) +{ + m_id.d = d; + return *this; +} + +inline +scfx_ieee_double& +scfx_ieee_double::operator = ( const scfx_ieee_double& a ) +{ + m_id.d = a.m_id.d; + return *this; +} + + +inline +scfx_ieee_double::operator double() const +{ + return m_id.d; +} + + +inline +unsigned int +scfx_ieee_double::negative() const +{ + return m_id.s.negative; +} + +inline +void +scfx_ieee_double::negative( unsigned int a ) +{ + m_id.s.negative = a & SCFX_MASK_(1); +} + +inline +int +scfx_ieee_double::exponent() const +{ + return m_id.s.exponent - SCFX_IEEE_DOUBLE_BIAS; +} + +inline +void +scfx_ieee_double::exponent( int a ) +{ + m_id.s.exponent = (SCFX_IEEE_DOUBLE_BIAS + a) + & SCFX_MASK_(SCFX_IEEE_DOUBLE_E_SIZE); +} + +inline +unsigned int +scfx_ieee_double::mantissa0() const +{ + return m_id.s.mantissa0; +} + +inline +void +scfx_ieee_double::mantissa0( unsigned int a ) +{ + m_id.s.mantissa0 = a & SCFX_MASK_(SCFX_IEEE_DOUBLE_M0_SIZE); +} + +inline +unsigned int +scfx_ieee_double::mantissa1() const +{ + return m_id.s.mantissa1; +} + +inline +void +scfx_ieee_double::mantissa1( unsigned int a ) +{ + m_id.s.mantissa1 = a; // & SCFX_MASK_(SCFX_IEEE_DOUBLE_M1_SIZE); +} + + +inline +bool +scfx_ieee_double::is_zero() const +{ + return ( exponent() == SCFX_IEEE_DOUBLE_E_MIN - 1 && + mantissa0() == 0U && mantissa1() == 0U ); +} + +inline +bool +scfx_ieee_double::is_subnormal() const +{ + return ( exponent() == SCFX_IEEE_DOUBLE_E_MIN - 1 && + ( mantissa0() != 0U || mantissa1() != 0U ) ); +} + +inline +bool +scfx_ieee_double::is_normal() const +{ + return ( exponent() >= SCFX_IEEE_DOUBLE_E_MIN && + exponent() <= SCFX_IEEE_DOUBLE_E_MAX ); +} + +inline +bool +scfx_ieee_double::is_inf() const +{ + return ( exponent() == SCFX_IEEE_DOUBLE_E_MAX + 1 && + mantissa0() == 0U && mantissa1() == 0U ); +} + +inline +bool +scfx_ieee_double::is_nan() const +{ + return ( exponent() == SCFX_IEEE_DOUBLE_E_MAX + 1 && + ( mantissa0() != 0U || mantissa1() != 0U ) ); +} + + +inline +void +scfx_ieee_double::set_inf() +{ + exponent( SCFX_IEEE_DOUBLE_E_MAX + 1 ); + mantissa0( 0U ); + mantissa1( 0U ); +} + +inline +void +scfx_ieee_double::set_nan() +{ + exponent( SCFX_IEEE_DOUBLE_E_MAX + 1 ); + mantissa0( (unsigned int) -1 ); + mantissa1( (unsigned int) -1 ); +} + + +#define MSB_STATEMENT(x,n) if( x >> n ) { x >>= n; i += n; } + +inline +int +scfx_ieee_double::msb() const +{ + unsigned int m0 = mantissa0(); + unsigned int m1 = mantissa1(); + if( m0 != 0 ) + { + int i = 0; + MSB_STATEMENT(m0,16); + MSB_STATEMENT(m0,8); + MSB_STATEMENT(m0,4); + MSB_STATEMENT(m0,2); + MSB_STATEMENT(m0,1); + return ( i - 20 ); + } + else if( m1 != 0 ) + { + int i = 0; + MSB_STATEMENT(m1,16); + MSB_STATEMENT(m1,8); + MSB_STATEMENT(m1,4); + MSB_STATEMENT(m1,2); + MSB_STATEMENT(m1,1); + return ( i - 52 ); + } + else + { + return 0; + } +} + +#undef MSB_STATEMENT + +#define LSB_STATEMENT(x,n) if( x << n ) { x <<= n; i -= n; } + +inline +int +scfx_ieee_double::lsb() const +{ + unsigned int m0 = mantissa0(); + unsigned int m1 = mantissa1(); + if( m1 != 0 ) + { + int i = 31; + LSB_STATEMENT(m1,16); + LSB_STATEMENT(m1,8); + LSB_STATEMENT(m1,4); + LSB_STATEMENT(m1,2); + LSB_STATEMENT(m1,1); + return ( i - 52 ); + } + else if( m0 != 0 ) + { + int i = 31; + LSB_STATEMENT(m0,16); + LSB_STATEMENT(m0,8); + LSB_STATEMENT(m0,4); + LSB_STATEMENT(m0,2); + LSB_STATEMENT(m0,1); + return ( i - 20 ); + } + else + { + return 0; + } +} + +#undef LSB_STATEMENT + + +inline +const scfx_ieee_double +scfx_ieee_double::nan() +{ + scfx_ieee_double id; + id.set_nan(); + return id; +} + +inline +const scfx_ieee_double +scfx_ieee_double::inf( int sign ) +{ + scfx_ieee_double id( sign ); + id.set_inf(); + return id; +} + + +// ---------------------------------------------------------------------------- +// UNION : ieee_float +// +// IEEE 754 single-precision format. +// ---------------------------------------------------------------------------- + +union ieee_float +{ + + float f; + + struct + { +#if defined( SC_BIG_ENDIAN ) + unsigned negative:1; + unsigned exponent:8; + unsigned mantissa:23; +#elif defined( SC_LITTLE_ENDIAN ) + unsigned mantissa:23; + unsigned exponent:8; + unsigned negative:1; +#endif + } s; + +}; + + +const unsigned int SCFX_IEEE_FLOAT_BIAS = 127U; + +const int SCFX_IEEE_FLOAT_E_MAX = 127; +const int SCFX_IEEE_FLOAT_E_MIN = -126; + +const unsigned int SCFX_IEEE_FLOAT_M_SIZE = 23; +const unsigned int SCFX_IEEE_FLOAT_E_SIZE = 8; + + +// ---------------------------------------------------------------------------- +// CLASS : scfx_ieee_float +// +// Convenient wrapper to union ieee_float. +// ---------------------------------------------------------------------------- + +class scfx_ieee_float +{ + + ieee_float m_if; + +public: + + scfx_ieee_float(); + scfx_ieee_float( float ); + scfx_ieee_float( const scfx_ieee_float& ); + + scfx_ieee_float& operator = ( float ); + scfx_ieee_float& operator = ( const scfx_ieee_float& ); + + operator float() const; + + unsigned int negative() const; + void negative( unsigned int ); + int exponent() const; + void exponent( int ); + unsigned int mantissa() const; + void mantissa( unsigned int ); + + bool is_zero() const; + bool is_subnormal() const; + bool is_normal() const; + bool is_inf() const; + bool is_nan() const; + + void set_inf(); + void set_nan(); + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +inline +scfx_ieee_float::scfx_ieee_float() : m_if() +{ + m_if.f = 0.0; +} + +inline +scfx_ieee_float::scfx_ieee_float( float f ) : m_if() +{ + m_if.f = f; +} + +inline +scfx_ieee_float::scfx_ieee_float( const scfx_ieee_float& a ) : m_if(a.m_if) +{ + // m_if.f = a.m_if.f; +} + + +inline +scfx_ieee_float& +scfx_ieee_float::operator = ( float f ) +{ + m_if.f = f; + return *this; +} + +inline +scfx_ieee_float& +scfx_ieee_float::operator = ( const scfx_ieee_float& a ) +{ + m_if.f = a.m_if.f; + return *this; +} + + +inline +scfx_ieee_float::operator float() const +{ + return m_if.f; +} + + +inline +unsigned int +scfx_ieee_float::negative() const +{ + return m_if.s.negative; +} + +inline +void +scfx_ieee_float::negative( unsigned int a ) +{ + m_if.s.negative = a & SCFX_MASK_(1); +} + +inline +int +scfx_ieee_float::exponent() const +{ + return m_if.s.exponent - SCFX_IEEE_FLOAT_BIAS; +} + +inline +void +scfx_ieee_float::exponent( int a ) +{ + m_if.s.exponent = (SCFX_IEEE_FLOAT_BIAS + a) + & SCFX_MASK_(SCFX_IEEE_FLOAT_E_SIZE); +} + +inline +unsigned int +scfx_ieee_float::mantissa() const +{ + return m_if.s.mantissa; +} + +inline +void +scfx_ieee_float::mantissa( unsigned int a ) +{ + m_if.s.mantissa = a & SCFX_MASK_(SCFX_IEEE_FLOAT_M_SIZE); +} + + +inline +bool +scfx_ieee_float::is_zero() const +{ + return ( exponent() == SCFX_IEEE_FLOAT_E_MIN - 1 && mantissa() == 0U ); +} + +inline +bool +scfx_ieee_float::is_subnormal() const +{ + return ( exponent() == SCFX_IEEE_FLOAT_E_MIN - 1 && mantissa() != 0U ); +} + +inline +bool +scfx_ieee_float::is_normal() const +{ + return ( exponent() >= SCFX_IEEE_FLOAT_E_MIN && + exponent() <= SCFX_IEEE_FLOAT_E_MAX ); +} + +inline +bool +scfx_ieee_float::is_inf() const +{ + return ( exponent() == SCFX_IEEE_FLOAT_E_MAX + 1 && mantissa() == 0U ); +} + +inline +bool +scfx_ieee_float::is_nan() const +{ + return ( exponent() == SCFX_IEEE_FLOAT_E_MAX + 1 && mantissa() != 0U ); +} + + +inline +void +scfx_ieee_float::set_inf() +{ + exponent( SCFX_IEEE_FLOAT_E_MAX + 1 ); + mantissa( 0U ); +} + +inline +void +scfx_ieee_float::set_nan() +{ + exponent( SCFX_IEEE_FLOAT_E_MAX + 1 ); + mantissa( (unsigned int) -1 ); +} + + +// ---------------------------------------------------------------------------- +// FUNCTION : scfx_pow2 +// +// Computes 2.0**exp in double-precision. +// ---------------------------------------------------------------------------- + +inline +double scfx_pow2( int exp ) +{ + scfx_ieee_double r; + if( exp < SCFX_IEEE_DOUBLE_E_MIN ) + { + r = 0.0; + // handle subnormal case + exp -= SCFX_IEEE_DOUBLE_E_MIN; + if( ( exp += 20 ) >= 0 ) + { + r.mantissa0( 1U << exp ); + } + else if( ( exp += 32 ) >= 0 ) + { + r.mantissa1( 1U << exp ); + } + } + else if( exp > SCFX_IEEE_DOUBLE_E_MAX ) + { + r.set_inf(); + } + else + { + r = 1.0; + r.exponent( exp ); + } + return r; +} + + +// ---------------------------------------------------------------------------- +// FUNCTION : uint64_to_double +// +// Platform independent conversion from double uint64 to double. +// Needed because VC++6 doesn't support this conversion. +// ---------------------------------------------------------------------------- + +inline +double +uint64_to_double( uint64 a ) +{ +#if defined( _MSC_VER ) || defined( __clang__ ) + // conversion from uint64 to double not implemented; use int64 + double tmp = static_cast<double>( static_cast<int64>( a ) ); + return ( tmp >= 0 ) ? tmp : tmp + sc_dt::scfx_pow2( 64 ); +#else + return static_cast<double>( a ); +#endif +} + +} // namespace sc_dt + +#undef SCFX_MASK_ + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_mant.cpp b/ext/systemc/src/sysc/datatypes/fx/scfx_mant.cpp new file mode 100644 index 000000000..fc29764f6 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_mant.cpp @@ -0,0 +1,125 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_mant.cpp - + + Original Author: Robert Graulich, Synopsys, Inc. + Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: scfx_mant.cpp,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#include "sysc/datatypes/fx/scfx_mant.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// word memory management +// ---------------------------------------------------------------------------- + +class word_list { // Entry in free_words bucket. + public: + word_list* m_next_p; +}; + +static inline +int +next_pow2_index( std::size_t size ) +{ + int index = scfx_find_msb( size ); + // If this was a power of 2 we are one bucket too low. + if( ~ (1 << index) & size ) index ++; + // If this is a 64-bit machine and we are using 32-bit words go down + // one slot size, as all the slots are 2x in size. + if ( index != 0 && ( sizeof(word_list) != sizeof(word) ) ) + { + index -= 1; + } + return index; +} + +static word_list* free_words[32] = { 0 }; + +word* +scfx_mant::alloc_word( std::size_t size ) +{ + const int ALLOC_SIZE = 128; + + int slot_index = next_pow2_index( size ); + + int alloc_size = ( 1 << slot_index ); + + word_list*& slot = free_words[slot_index]; + + if( ! slot ) + { + slot = new word_list[ALLOC_SIZE * alloc_size]; + int i; + for( i = 0; i < alloc_size*(ALLOC_SIZE-1) ; i+=alloc_size ) + { + slot[i].m_next_p = &slot[i+alloc_size]; + } + slot[i].m_next_p = 0; + } + + word* result = (word*)slot; + free_words[slot_index] = slot[0].m_next_p; + return result; +} + +void +scfx_mant::free_word( word* array, std::size_t size ) +{ + if( array && size ) + { + int slot_index = next_pow2_index( size ); + word_list* wl_p = (word_list*)array; + + wl_p->m_next_p = free_words[slot_index]; + free_words[slot_index] = wl_p; + } +} + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_mant.h b/ext/systemc/src/sysc/datatypes/fx/scfx_mant.h new file mode 100644 index 000000000..84d9b0bd8 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_mant.h @@ -0,0 +1,490 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_mant.h - + + Original Author: Robert Graulich, Synopsys, Inc. + Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: scfx_mant.h,v $ +// Revision 1.2 2011/08/24 22:05:43 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SCFX_MANT_H +#define SCFX_MANT_H + + +#include "sysc/datatypes/fx/scfx_ieee.h" +#include "sysc/datatypes/fx/scfx_utils.h" +#include "sysc/kernel/sc_macros.h" + + +namespace sc_dt +{ + +// classes defined in this module +class scfx_mant; +class scfx_mant_ref; + + +typedef unsigned int word; // Using int because of 64-bit machines. +typedef unsigned short half_word; + + +// ---------------------------------------------------------------------------- +// CLASS : scfx_mant +// +// Mantissa class. +// ---------------------------------------------------------------------------- + +class scfx_mant +{ + + word* m_array; + int m_size; + +public: + + explicit scfx_mant( std::size_t ); + scfx_mant( const scfx_mant& ); + + scfx_mant& operator = ( const scfx_mant& ); + + ~scfx_mant(); + + void clear(); + + void resize_to( int, int = 0 ); + + int size() const; + + word operator [] ( int ) const; + word& operator [] ( int ); + + half_word half_at( int ) const; + half_word& half_at( int ); + + half_word* half_addr( int = 0 ) const; + +private: + + static word* alloc( std::size_t ); + static void free( word*, std::size_t ); + + static word* alloc_word( std::size_t size ); + static void free_word( word* array, std::size_t size ); + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +inline +int +scfx_mant::size() const +{ + return m_size; +} + + +inline +word* +scfx_mant::alloc( std::size_t size ) +{ +#if defined( SC_BIG_ENDIAN ) + return alloc_word( size ) + ( size - 1 ); +#elif defined( SC_LITTLE_ENDIAN ) + return alloc_word( size ); +#endif +} + +inline +void +scfx_mant::free( word* mant, std::size_t size ) +{ +#if defined( SC_BIG_ENDIAN ) + free_word( mant - ( size - 1 ), size ); +#elif defined( SC_LITTLE_ENDIAN ) + free_word( mant, size ); +#endif +} + +inline +word +scfx_mant::operator[]( int i ) const +{ + SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" ); +#if defined( SC_BIG_ENDIAN ) + return m_array[-i]; +#elif defined( SC_LITTLE_ENDIAN ) + return m_array[i]; +#endif +} + +inline +word& +scfx_mant::operator[]( int i ) +{ + SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" ); +#if defined( SC_BIG_ENDIAN ) + return m_array[-i]; +#elif defined( SC_LITTLE_ENDIAN ) + return m_array[i]; +#endif +} + +inline +scfx_mant::scfx_mant( std::size_t size ) +: m_array(0), m_size(size) +{ + m_array = alloc( size ); +} + +inline +scfx_mant::scfx_mant( const scfx_mant& rhs ) +: m_array(0), m_size(rhs.m_size) +{ + m_array = alloc( m_size ); + for( int i = 0; i < m_size; i ++ ) + { + (*this)[i] = rhs[i]; + } +} + +inline +scfx_mant& +scfx_mant::operator = ( const scfx_mant& rhs ) +{ + if( &rhs != this ) + { + if( m_size != rhs.m_size ) + { + free( m_array, m_size ); + m_array = alloc( m_size = rhs.m_size ); + } + + for( int i = 0; i < m_size; i ++ ) + { + (*this)[i] = rhs[i]; + } + } + return *this; +} + +inline +scfx_mant::~scfx_mant() +{ + if( m_array != 0 ) + { + free( m_array, m_size ); + } +} + +inline +void +scfx_mant::clear() +{ + for( int i = 0; i < m_size; i ++ ) + { + (*this)[i] = 0; + } +} + +inline +void +scfx_mant::resize_to( int size, int restore ) +{ + if( size == m_size ) + { + return; + } + + if( ! m_array ) + { + m_array = alloc( m_size = size ); + } + else + { + word* p = alloc( size ); + + if( restore ) + { + int end = sc_min( size, m_size ); + if( restore == 1 ) // msb resized -> align at 0 + { + for( int i = 0; i < size; i ++ ) + { + if( i < end ) + { +#if defined( SC_BIG_ENDIAN ) + p[-i] = m_array[-i]; +#elif defined( SC_LITTLE_ENDIAN ) + p[i] = m_array[i]; +#endif + } + else + { +#if defined( SC_BIG_ENDIAN ) + p[-i] = 0; +#elif defined( SC_LITTLE_ENDIAN ) + p[i] = 0; +#endif + } + } + } + else // lsb resized -> align at size-1 + { + for( int i = 0; i < size; i ++ ) + { + if( i < end ) + { +#if defined( SC_BIG_ENDIAN ) + p[-size+1+i] = m_array[-m_size+1+i]; +#elif defined( SC_LITTLE_ENDIAN ) + p[size-1-i] = m_array[m_size-1-i]; +#endif + } + else + { +#if defined( SC_BIG_ENDIAN ) + p[-size+1+i] = 0; +#elif defined( SC_LITTLE_ENDIAN ) + p[size-1-i] = 0; +#endif + } + } + } + } + + free( m_array, m_size ); + m_array = p; + m_size = size; + } +} + +inline +half_word +scfx_mant::half_at( int i ) const +{ + SC_ASSERT_( ( i >> 1 ) >= 0 && ( i >> 1 ) < m_size, + "mantissa index out of range" ); +#if defined( SC_BIG_ENDIAN ) + return reinterpret_cast<half_word*>( m_array )[-i]; +#elif defined( SC_LITTLE_ENDIAN ) + return reinterpret_cast<half_word*>( m_array )[i]; +#endif +} + +inline +half_word& +scfx_mant::half_at( int i ) +{ + SC_ASSERT_( ( i >> 1 ) >= 0 && ( i >> 1 ) < m_size, + "mantissa index out of range" ); +#if defined( SC_BIG_ENDIAN ) + return reinterpret_cast<half_word*>( m_array )[-i]; +#elif defined( SC_LITTLE_ENDIAN ) + return reinterpret_cast<half_word*>( m_array )[i]; +#endif +} + +inline +half_word* +scfx_mant::half_addr( int i ) const +{ + SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" ); +#if defined( SC_BIG_ENDIAN ) + return reinterpret_cast<half_word*>( m_array - i ) + 1; +#elif defined( SC_LITTLE_ENDIAN ) + return reinterpret_cast<half_word*>( m_array + i ); +#endif +} + + +// ---------------------------------------------------------------------------- +// one's complement of a mantissa +// ---------------------------------------------------------------------------- + +inline +void +complement( scfx_mant& target, const scfx_mant& source, int size ) +{ + for( int i = 0; i < size; i ++ ) + { + target[i] = ~source[i]; + } +} + + +// ---------------------------------------------------------------------------- +// increment mantissa +// ---------------------------------------------------------------------------- + +inline +void +inc( scfx_mant& mant ) +{ + for( int i = 0; i < mant.size(); i ++ ) + { + if( ++ mant[i] ) + { + break; + } + } +} + + +// ---------------------------------------------------------------------------- +// CLASS : scfx_mant_ref +// +// Mantissa reference class. +// ---------------------------------------------------------------------------- + +class scfx_mant_ref +{ + + scfx_mant* m_mant; + bool m_not_const; + +public: + + scfx_mant_ref(); + scfx_mant_ref( const scfx_mant& ); + scfx_mant_ref( scfx_mant* ); + + scfx_mant_ref& operator = ( const scfx_mant& ); + scfx_mant_ref& operator = ( scfx_mant* ); + + ~scfx_mant_ref(); + + operator scfx_mant&(); + + word operator [] ( int ); + +private: + + void remove_it(); + + scfx_mant_ref( const scfx_mant_ref& ); + scfx_mant_ref& operator = ( const scfx_mant_ref& ); + + void* operator new( std::size_t sz ) { return ::operator new( sz ); } + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +inline +void +scfx_mant_ref::remove_it() +{ + if( m_not_const ) + { + delete m_mant; + } +} + +inline +scfx_mant_ref::scfx_mant_ref() +: m_mant( 0 ), m_not_const( false ) +{} + +inline +scfx_mant_ref::scfx_mant_ref( const scfx_mant& mant ) +: m_mant( const_cast<scfx_mant*>( &mant ) ), m_not_const( false ) +{} + +inline +scfx_mant_ref::scfx_mant_ref( scfx_mant* mant ) +: m_mant( mant ), m_not_const( true ) +{} + +inline +scfx_mant_ref& +scfx_mant_ref::operator = ( const scfx_mant& mant ) +{ + remove_it(); + + m_mant = const_cast<scfx_mant*>( &mant ); + m_not_const = false; + + return *this; +} + +inline +scfx_mant_ref& +scfx_mant_ref::operator = ( scfx_mant* mant ) +{ + remove_it(); + + m_mant = mant; + m_not_const = true; + + return *this; +} + +inline +scfx_mant_ref::~scfx_mant_ref() +{ + remove_it(); +} + +inline +scfx_mant_ref::operator scfx_mant&() +{ + // SC_ASSERT_( m_not_const, "not allowed to modify mant" ); + return *m_mant; +} + +inline +word +scfx_mant_ref::operator [] ( int i ) +{ + return (*m_mant)[i]; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_other_defs.h b/ext/systemc/src/sysc/datatypes/fx/scfx_other_defs.h new file mode 100644 index 000000000..a52d74b6b --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_other_defs.h @@ -0,0 +1,433 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_other_defs.h - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: scfx_other_defs.h,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SCFX_OTHER_DEFS_H +#define SCFX_OTHER_DEFS_H + + +#include "sysc/datatypes/fx/sc_fx_ids.h" +#include "sysc/datatypes/int/sc_signed.h" +#include "sysc/datatypes/int/sc_unsigned.h" +#include "sysc/datatypes/int/sc_int_base.h" +#include "sysc/datatypes/int/sc_uint_base.h" +#include "sysc/tracing/sc_trace.h" + + +namespace sc_dt +{ + +#ifdef SC_INCLUDE_FX + +// ---------------------------------------------------------------------------- +// CLASS : sc_signed +// ---------------------------------------------------------------------------- + +// assignment operators + +inline +const sc_signed& +sc_signed::operator = ( const sc_fxval& v ) +{ + if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */ + { + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_signed::operator = ( const sc_fxval& )" ); + } + + for( int i = 0; i < length(); ++ i ) + (*this)[i] = v.get_bit( i ); + + return *this; +} + +inline +const sc_signed& +sc_signed::operator = ( const sc_fxval_fast& v ) +{ + if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */ + { + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_signed::operator = ( const sc_fxval_fast& )" ); + } + + for( int i = 0; i < length(); ++ i ) + (*this)[i] = v.get_bit( i ); + + return *this; +} + +inline +const sc_signed& +sc_signed::operator = ( const sc_fxnum& v ) +{ + if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */ + { + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_signed::operator = ( const sc_fxnum& )" ); + } + + for( int i = 0; i < length(); ++ i ) + (*this)[i] = v.get_bit( i ); + + return *this; +} + +inline +const sc_signed& +sc_signed::operator = ( const sc_fxnum_fast& v ) +{ + if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */ + { + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_signed::operator = ( const sc_fxnum_fast& )" ); + } + + for( int i = 0; i < length(); ++ i ) + (*this)[i] = v.get_bit( i ); + + return *this; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned +// ---------------------------------------------------------------------------- + +// assignment operators + +inline +const sc_unsigned& +sc_unsigned::operator = ( const sc_fxval& v ) +{ + if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */ + { + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_unsigned::operator = ( const sc_fxval& )" ); + } + + for( int i = 0; i < length(); ++ i ) + (*this)[i] = v.get_bit( i ); + + return *this; +} + +inline +const sc_unsigned& +sc_unsigned::operator = ( const sc_fxval_fast& v ) +{ + if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */ + { + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_unsigned::operator = ( const sc_fxval_fast& )" ); + } + + for( int i = 0; i < length(); ++ i ) + (*this)[i] = v.get_bit( i ); + + return *this; +} + +inline +const sc_unsigned& +sc_unsigned::operator = ( const sc_fxnum& v ) +{ + if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */ + { + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_unsigned::operator = ( const sc_fxnum& )" ); + } + + for( int i = 0; i < length(); ++ i ) + (*this)[i] = v.get_bit( i ); + + return *this; +} + +inline +const sc_unsigned& +sc_unsigned::operator = ( const sc_fxnum_fast& v ) +{ + if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */ + { + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_unsigned::operator = ( const sc_fxnum_fast& )" ); + } + + for( int i = 0; i < length(); ++ i ) + (*this)[i] = v.get_bit( i ); + + return *this; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_base +// ---------------------------------------------------------------------------- + +#ifndef _32BIT_ +#define NUM_WIDTH LLWIDTH +#else +#define NUM_WIDTH INTWIDTH +#endif + + +// assignment operators + +inline +sc_int_base& +sc_int_base::operator = ( const sc_fxval& v ) +{ + if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */ + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_int_base::operator = ( const sc_fxval& )" ); + } + for( int i = 0; i < m_len; ++ i ) { + set( i, v.get_bit( i ) ); + } + extend_sign(); + return *this; +} + +inline +sc_int_base& +sc_int_base::operator = ( const sc_fxval_fast& v ) +{ + if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */ + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_int_base::operator = ( const sc_fxval_fast& )" ); + } + for( int i = 0; i < m_len; ++ i ) { + set( i, v.get_bit( i ) ); + } + extend_sign(); + return *this; +} + +inline +sc_int_base& +sc_int_base::operator = ( const sc_fxnum& v ) +{ + if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */ + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_int_base::operator = ( const sc_fxnum& )" ); + } + for( int i = 0; i < m_len; ++ i ) { + set( i, v.get_bit( i ) ); + } + extend_sign(); + return *this; +} + +inline +sc_int_base& +sc_int_base::operator = ( const sc_fxnum_fast& v ) +{ + if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */ + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_int_base::operator = ( const sc_fxnum_fast& )" ); + } + for( int i = 0; i < m_len; ++ i ) { + set( i, v.get_bit( i ) ); + } + extend_sign(); + return *this; +} + +#undef NUM_WIDTH + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_base +// ---------------------------------------------------------------------------- + +// assignment operators + +inline +sc_uint_base& +sc_uint_base::operator = ( const sc_fxval& v ) +{ + if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */ + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_uint_base::operator = ( const sc_fxval& )" ); + } + for( int i = 0; i < m_len; ++ i ) { + set( i, v.get_bit( i ) ); + } + extend_sign(); + return *this; +} + +inline +sc_uint_base& +sc_uint_base::operator = ( const sc_fxval_fast& v ) +{ + if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */ + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_uint_base::operator = ( const sc_fxval_fast& )" ); + } + for( int i = 0; i < m_len; ++ i ) { + set( i, v.get_bit( i ) ); + } + extend_sign(); + return *this; +} + +inline +sc_uint_base& +sc_uint_base::operator = ( const sc_fxnum& v ) +{ + if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */ + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_uint_base::operator = ( const sc_fxnum& )" ); + } + for( int i = 0; i < m_len; ++ i ) { + set( i, v.get_bit( i ) ); + } + extend_sign(); + return *this; +} + +inline +sc_uint_base& +sc_uint_base::operator = ( const sc_fxnum_fast& v ) +{ + if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */ + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_uint_base::operator = ( const sc_fxnum_fast& )" ); + } + for( int i = 0; i < m_len; ++ i ) { + set( i, v.get_bit( i ) ); + } + extend_sign(); + return *this; +} + + +#endif + + +// ---------------------------------------------------------------------------- +// FUNCTION : sc_trace +// ---------------------------------------------------------------------------- + +inline +void +sc_trace( sc_core::sc_trace_file* tf, + const sc_fxval& object, const std::string& name ) +{ + if( tf ) + tf->trace( object, name ); +} + +inline +void +sc_trace( sc_core::sc_trace_file* tf, + const sc_fxval* object, const std::string& name ) +{ + if( tf ) + tf->trace( *object, name ); +} + +inline +void +sc_trace( sc_core::sc_trace_file* tf, + const sc_fxval_fast& object, const std::string& name ) +{ + if( tf ) + tf->trace( object, name ); +} + +inline +void +sc_trace( sc_core::sc_trace_file* tf, + const sc_fxval_fast* object, const std::string& name ) +{ + if( tf ) + tf->trace( *object, name ); +} + +inline +void +sc_trace( sc_core::sc_trace_file* tf, + const sc_fxnum& object, const std::string& name ) +{ + if( tf ) + tf->trace( object, name ); +} + +inline +void +sc_trace( sc_core::sc_trace_file* tf, + const sc_fxnum* object, const std::string& name ) +{ + if( tf ) + tf->trace( *object, name ); +} + +inline +void +sc_trace( sc_core::sc_trace_file* tf, + const sc_fxnum_fast& object, const std::string& name ) +{ + if( tf ) + tf->trace( object, name ); +} + +inline +void +sc_trace( sc_core::sc_trace_file* tf, + const sc_fxnum_fast* object, const std::string& name ) +{ + if( tf ) + tf->trace( *object, name ); +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_params.h b/ext/systemc/src/sysc/datatypes/fx/scfx_params.h new file mode 100644 index 000000000..8cd646651 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_params.h @@ -0,0 +1,222 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_params.h - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: scfx_params.h,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SCFX_PARAMS_H +#define SCFX_PARAMS_H + + +#include "sysc/datatypes/fx/sc_fx_ids.h" +#include "sysc/datatypes/fx/sc_fxcast_switch.h" +#include "sysc/datatypes/fx/sc_fxtype_params.h" + + +namespace sc_dt +{ + +// classes defined in this module +class scfx_params; + + +// ---------------------------------------------------------------------------- +// CLASS : scfx_params +// +// ... +// ---------------------------------------------------------------------------- + +class scfx_params +{ + +public: + + // constructor + + scfx_params( const sc_fxtype_params&, + sc_enc, + const sc_fxcast_switch& ); + + + // query functions + + const sc_fxtype_params& type_params() const; + sc_enc enc() const; + const sc_fxcast_switch& cast_switch() const; + + + // shortcuts + + int wl() const; + int iwl() const; + int fwl() const; + sc_q_mode q_mode() const; + sc_o_mode o_mode() const; + int n_bits() const; + + + // dump content + + void dump( ::std::ostream& ) const; + +private: + + sc_fxtype_params m_type_params; + sc_enc m_enc; + sc_fxcast_switch m_cast_switch; + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// constructor + +inline +scfx_params::scfx_params( const sc_fxtype_params& type_params_, + sc_enc enc_, + const sc_fxcast_switch& cast_sw ) +: m_type_params( type_params_ ), + m_enc( enc_ ), + m_cast_switch( cast_sw ) +{ + if( m_enc == SC_US_ && m_type_params.o_mode() == SC_WRAP_SM ) + { + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_O_MODE_, + "SC_WRAP_SM not defined for unsigned numbers" ); + } + +} + + +// query functions + +inline +const sc_fxtype_params& +scfx_params::type_params() const +{ + return m_type_params; +} + +inline +sc_enc +scfx_params::enc() const +{ + return m_enc; +} + +inline +const sc_fxcast_switch& +scfx_params::cast_switch() const +{ + return m_cast_switch; +} + + +// shortcuts + +inline +int +scfx_params::wl() const +{ + return m_type_params.wl(); +} + +inline +int +scfx_params::iwl() const +{ + return m_type_params.iwl(); +} + +inline +int +scfx_params::fwl() const +{ + return ( m_type_params.wl() - m_type_params.iwl() ); +} + +inline +sc_q_mode +scfx_params::q_mode() const +{ + return m_type_params.q_mode(); +} + +inline +sc_o_mode +scfx_params::o_mode() const +{ + return m_type_params.o_mode(); +} + +inline +int +scfx_params::n_bits() const +{ + return m_type_params.n_bits(); +} + + +// dump content + +inline +void +scfx_params::dump( ::std::ostream& os ) const +{ + os << "scfx_params" << ::std::endl; + os << "(" << ::std::endl; + os << "type_params = "; + m_type_params.dump( os ); + os << "enc = " << m_enc << ::std::endl; + os << "cast_switch = "; + m_cast_switch.dump( os ); + os << ")" << ::std::endl; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_pow10.cpp b/ext/systemc/src/sysc/datatypes/fx/scfx_pow10.cpp new file mode 100644 index 000000000..ac931763b --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_pow10.cpp @@ -0,0 +1,147 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_pow10.cpp - + + Original Author: Robert Graulich, Synopsys, Inc. + Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: scfx_pow10.cpp,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#include "sysc/datatypes/fx/scfx_pow10.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// CLASS : scfx_pow10 +// +// Class to compute (and cache) powers of 10 in arbitrary precision. +// ---------------------------------------------------------------------------- + +scfx_pow10::scfx_pow10() +{ + m_pos[0] = scfx_rep( 10.0 ); + m_neg[0] = scfx_rep( 0.1 ); + + for( int i = 1; i < SCFX_POW10_TABLE_SIZE; i ++ ) + { + m_pos[i].set_nan(); + m_neg[i].set_nan(); + } +} + +scfx_pow10::~scfx_pow10() +{} + + +const scfx_rep +scfx_pow10::operator() ( int i ) +{ + if( i == 0 ) { + return scfx_rep( 1.0 ); + } + + if( i > 0 ) + { + int bit = scfx_find_msb( i ); + scfx_rep result = *pos( bit ); + if( bit ) + { + while( -- bit >= 0 ) + { + if( ( 1 << bit ) & i ) + { + scfx_rep* tmp = mult_scfx_rep( result, *pos( bit ) ); + result = *tmp; + delete tmp; + } + } + } + return result; + } + else + { + i = -i; + int bit = scfx_find_msb( i ); + scfx_rep result = *neg( bit ); + if( bit ) + { + while( -- bit >= 0 ) + { + if( ( 1 << bit ) & i ) + { + scfx_rep* tmp = mult_scfx_rep( result, *neg( bit ) ); + result = *tmp; + delete tmp; + } + } + } + return result; + } +} + + +scfx_rep* +scfx_pow10::pos( int i ) +{ + if( ! m_pos[i].is_normal() ) + { + multiply( m_pos[i], *pos( i - 1 ), *pos( i - 1 ) ); + } + return &m_pos[i]; +} + +scfx_rep* +scfx_pow10::neg( int i ) +{ + if( ! m_neg[i].is_normal() ) + { + multiply( m_neg[i], *neg( i - 1 ), *neg( i - 1 ) ); + } + return &m_neg[i]; +} + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_pow10.h b/ext/systemc/src/sysc/datatypes/fx/scfx_pow10.h new file mode 100644 index 000000000..c9b278561 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_pow10.h @@ -0,0 +1,95 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_pow10.h - + + Original Author: Robert Graulich, Synopsys, Inc. + Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: scfx_pow10.h,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SCFX_POW10_H +#define SCFX_POW10_H + + +#include "sysc/datatypes/fx/scfx_rep.h" + + +namespace sc_dt +{ + +// classes defined in this module +class scfx_pow10; + + +// ---------------------------------------------------------------------------- +// CLASS : scfx_pow10 +// +// Class to compute (and cache) powers of 10 in arbitrary precision. +// ---------------------------------------------------------------------------- + +const int SCFX_POW10_TABLE_SIZE = 32; + + +class scfx_pow10 +{ + +public: + + scfx_pow10(); + ~scfx_pow10(); + + const scfx_rep operator() ( int ); + +private: + + scfx_rep* pos( int ); + scfx_rep* neg( int ); + + scfx_rep m_pos[SCFX_POW10_TABLE_SIZE]; + scfx_rep m_neg[SCFX_POW10_TABLE_SIZE]; +}; + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_rep.cpp b/ext/systemc/src/sysc/datatypes/fx/scfx_rep.cpp new file mode 100644 index 000000000..772835e6d --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_rep.cpp @@ -0,0 +1,2926 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_rep.cpp - + + Original Author: Robert Graulich, Synopsys, Inc. + Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: scfx_rep.cpp,v $ +// Revision 1.4 2011/08/24 22:05:43 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.3 2011/08/15 16:43:24 acg +// Torsten Maehne: changes to remove unused argument warnings. +// +// Revision 1.2 2009/02/28 00:26:20 acg +// Andy Goodrich: bug fixes. +// +// Revision 1.2 2008/11/06 17:22:47 acg +// Andy Goodrich: bug fixes for 2.2.1. +// +// Revision 1.1.1.1 2006/12/15 20:31:36 acg +// SystemC 2.2 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#include "sysc/utils/sc_machine.h" +#include "sysc/datatypes/fx/scfx_rep.h" + +#include "sysc/datatypes/fx/scfx_ieee.h" +#include "sysc/datatypes/fx/scfx_pow10.h" +#include "sysc/datatypes/fx/scfx_utils.h" + +#include "sysc/datatypes/bit/sc_bv_base.h" + +#include <ctype.h> +#include <cstdio> +#include <stdlib.h> +#include <math.h> + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// some utilities +// ---------------------------------------------------------------------------- + +static scfx_pow10 pow10_fx; + +static const int mantissa0_size = SCFX_IEEE_DOUBLE_M_SIZE - bits_in_int; + +static inline +int +n_word( int x ) +{ + return ( x + bits_in_word - 1 ) / bits_in_word; +} + + +// ---------------------------------------------------------------------------- +// CONSTRUCTORS +// ---------------------------------------------------------------------------- + +scfx_rep::scfx_rep() +: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(), + m_r_flag( false ) +{ + set_zero(); +} + +scfx_rep::scfx_rep( int a ) +: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(), + m_r_flag( false ) +{ + if( a != 0 ) + { + m_mant.clear(); + m_wp = m_msw = m_lsw = 2; + m_state = normal; + if( a > 0 ) + { + m_mant[2] = a; + m_sign = 1; + } + else + { + m_mant[2] = -a; + m_sign = -1; + } + } + else + set_zero(); +} + +scfx_rep::scfx_rep( unsigned int a ) +: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(), + m_r_flag( false ) +{ + if( a != 0 ) + { + m_mant.clear(); + m_wp = m_msw = m_lsw = 2; + m_state = normal; + m_mant[2] = a; + m_sign = 1; + } + else + set_zero(); +} + +scfx_rep::scfx_rep( long a ) +: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(), + m_r_flag( false ) +{ + if( a != 0 ) + { + m_mant.clear(); + m_state = normal; + if ( a > 0 ) + { + m_sign = 1; + } + else + { + a = -a; + m_sign = -1; + } +# if defined(SC_LONG_64) + m_wp = 1; + m_mant[1] = static_cast<word>( a ); + m_mant[2] = static_cast<word>( a >> bits_in_word ); + find_sw(); +# else + m_wp = 2; + m_msw = 2; + m_lsw = 2; + m_mant[2] = a; +# endif + + } + else + set_zero(); +} + +scfx_rep::scfx_rep( unsigned long a ) +: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(), + m_r_flag( false ) +{ + if( a != 0 ) + { + m_mant.clear(); + m_wp = m_msw = m_lsw = 2; + m_state = normal; +# if defined(SC_LONG_64) + m_wp = 1; + m_mant[1] = static_cast<word>( a ); + m_mant[2] = static_cast<word>( a >> bits_in_word ); + find_sw(); +# else + m_wp = 2; + m_msw = 2; + m_lsw = 2; + m_mant[2] = a; +# endif + m_sign = 1; + } + else + set_zero(); +} + +scfx_rep::scfx_rep( double a ) +: m_mant( min_mant ), m_wp( 0 ), m_sign(), m_state( normal ), m_msw( 0 ), + m_lsw( 0 ), m_r_flag( false ) +{ + m_mant.clear(); + + scfx_ieee_double id( a ); + + m_sign = id.negative() ? -1 : 1; + + if( id.is_nan() ) + m_state = not_a_number; + else if( id.is_inf() ) + m_state = infinity; + else if( id.is_subnormal() ) + { + m_mant[0] = id.mantissa1(); + m_mant[1] = id.mantissa0(); + normalize( id.exponent() + 1 - SCFX_IEEE_DOUBLE_M_SIZE ); + } + else if( id.is_normal() ) + { + m_mant[0] = id.mantissa1(); + m_mant[1] = id.mantissa0() | ( 1 << mantissa0_size ); + normalize( id.exponent() - SCFX_IEEE_DOUBLE_M_SIZE ); + } +} + +scfx_rep::scfx_rep( int64 a ) +: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(), + m_r_flag( false ) +{ + if( a != 0 ) + { + m_mant.clear(); + m_wp = 1; + m_state = normal; + if( a > 0 ) + { + m_mant[1] = static_cast<word>( a ); + m_mant[2] = static_cast<word>( a >> bits_in_word ); + m_sign = 1; + } + else + { + m_mant[1] = static_cast<word>( -a ); + m_mant[2] = static_cast<word>( (-a) >> bits_in_word ); + m_sign = -1; + } + find_sw(); + } + else + set_zero(); +} + +scfx_rep::scfx_rep( uint64 a ) +: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(), + m_r_flag( false ) +{ + if( a != 0 ) + { + m_mant.clear(); + m_wp = 1; + m_state = normal; + m_mant[1] = static_cast<word>( a ); + m_mant[2] = static_cast<word>( a >> bits_in_word ); + m_sign = 1; + find_sw(); + } + else + set_zero(); +} + +scfx_rep::scfx_rep( const sc_signed& a ) +: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(), + m_r_flag( false ) +{ + if( a.iszero() ) + set_zero(); + else + { + int words = n_word( a.length() ); + if( words > size() ) + resize_to( words ); + m_mant.clear(); + m_wp = 0; + m_state = normal; + if( a.sign() ) + { + sc_signed a2 = -a; + for( int i = 0; i < a2.length(); ++ i ) + { + if( a2[i] ) + { + scfx_index x = calc_indices( i ); + m_mant[x.wi()] |= 1 << x.bi(); + } + } + m_sign = -1; + } + else + { + for( int i = 0; i < a.length(); ++ i ) + { + if( a[i] ) + { + scfx_index x = calc_indices( i ); + m_mant[x.wi()] |= 1 << x.bi(); + } + } + m_sign = 1; + } + find_sw(); + } +} + +scfx_rep::scfx_rep( const sc_unsigned& a ) +: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(), + m_r_flag( false ) +{ + if( a.iszero() ) + set_zero(); + else + { + int words = n_word( a.length() ); + if( words > size() ) + resize_to( words ); + m_mant.clear(); + m_wp = 0; + m_state = normal; + for( int i = 0; i < a.length(); ++ i ) + { + if( a[i] ) + { + scfx_index x = calc_indices( i ); + m_mant[x.wi()] |= 1 << x.bi(); + } + } + m_sign = 1; + find_sw(); + } +} + + +// copy constructor + +scfx_rep::scfx_rep( const scfx_rep& a ) +: m_mant( a.m_mant ), m_wp( a.m_wp ), m_sign( a.m_sign ), m_state( a.m_state ), + m_msw( a.m_msw ), m_lsw( a.m_lsw ), m_r_flag( false ) +{} + + +// ---------------------------------------------------------------------------- +// OPERATORS : new, delete +// +// Memory management for class scfx_rep. +// ---------------------------------------------------------------------------- + +union scfx_rep_node +{ + char data[sizeof( scfx_rep )]; + scfx_rep_node* next; +}; + + +static scfx_rep_node* list = 0; + + +void* +scfx_rep::operator new( std::size_t size ) +{ + const int ALLOC_SIZE = 1024; + + if( size != sizeof( scfx_rep ) ) + return ::operator new( size ); + + if( ! list ) + { + list = new scfx_rep_node[ALLOC_SIZE]; + for( int i = 0; i < ALLOC_SIZE - 1; i ++ ) + list[i].next = list + i + 1; + list[ALLOC_SIZE - 1].next = 0; + } + + scfx_rep* ptr = reinterpret_cast<scfx_rep*>( list->data ); + list = list->next; + + return ptr; +} + + +void scfx_rep::operator delete( void* ptr, std::size_t size ) +{ + if( size != sizeof( scfx_rep ) ) + { + ::operator delete( ptr ); + return; + } + + scfx_rep_node* node = static_cast<scfx_rep_node*>( ptr ); + node->next = list; + list = node; +} + + +// ---------------------------------------------------------------------------- +// METHOD : from_string +// +// Convert from character string to sc_fxrep. +// ---------------------------------------------------------------------------- + +#define SCFX_FAIL_IF_(cnd) \ +{ \ + if( ( cnd ) ) \ + { \ + m_state = not_a_number; \ + m_mant.clear(); /* to avoid Purify UMRs during assignment */ \ + return; \ + } \ +} + + +void +scfx_rep::from_string( const char* s, int cte_wl ) +{ + SCFX_FAIL_IF_( s == 0 || *s == 0 ); + + scfx_string s2; + s2 += s; + s2 += '\0'; + + bool sign_char; + m_sign = scfx_parse_sign( s, sign_char ); + + sc_numrep numrep = scfx_parse_prefix( s ); + + int base = 0; + + switch( numrep ) + { + case SC_DEC: + { + base = 10; + if( scfx_is_nan( s ) ) + { // special case: NaN + m_state = not_a_number; + m_mant.clear(); /* to avoid Purify UMRs during assignment */ + return; + } + if( scfx_is_inf( s ) ) + { // special case: Infinity + m_state = infinity; + m_mant.clear(); /* to avoid Purify UMRs during assignment */ + return; + } + break; + } + case SC_BIN: + case SC_BIN_US: + { + SCFX_FAIL_IF_( sign_char ); + base = 2; + break; + } + + case SC_BIN_SM: + { + base = 2; + break; + } + case SC_OCT: + case SC_OCT_US: + { + SCFX_FAIL_IF_( sign_char ); + base = 8; + break; + } + case SC_OCT_SM: + { + base = 8; + break; + } + case SC_HEX: + case SC_HEX_US: + { + SCFX_FAIL_IF_( sign_char ); + base = 16; + break; + } + case SC_HEX_SM: + { + base = 16; + break; + } + case SC_CSD: + { + SCFX_FAIL_IF_( sign_char ); + base = 2; + scfx_csd2tc( s2 ); + s = (const char*) s2 + 4; + numrep = SC_BIN; + break; + } + default:; + } + + // + // find end of mantissa and count the digits and points + // + + const char *end = s; + bool based_point = false; + int int_digits = 0; + int frac_digits = 0; + + while( *end ) + { + if( scfx_exp_start( end ) ) + break; + + if( *end == '.' ) + { + SCFX_FAIL_IF_( based_point ); + based_point = true; + } + else + { + SCFX_FAIL_IF_( ! scfx_is_digit( *end, numrep ) ); + if( based_point ) + frac_digits ++; + else + int_digits ++; + } + + ++ end; + } + + SCFX_FAIL_IF_( int_digits == 0 && frac_digits == 0 ); + + // [ exponent ] + + int exponent = 0; + + if( *end ) + { + for( const char *e = end + 2; *e; ++ e ) + SCFX_FAIL_IF_( ! scfx_is_digit( *e, SC_DEC ) ); + exponent = atoi( end + 1 ); + } + + // + // check if the mantissa is negative + // + + bool mant_is_neg = false; + + switch( numrep ) + { + case SC_BIN: + case SC_OCT: + case SC_HEX: + { + const char* p = s; + if( *p == '.' ) + ++ p; + + mant_is_neg = ( scfx_to_digit( *p, numrep ) >= ( base >> 1 ) ); + + break; + } + default: + ; + } + + // + // convert the mantissa + // + + switch( base ) + { + case 2: + { + int bit_offset = exponent % bits_in_word; + int word_offset = exponent / bits_in_word; + + int_digits += bit_offset; + frac_digits -= bit_offset; + + int words = n_word( int_digits ) + n_word( frac_digits ); + if( words > size() ) + resize_to( words ); + m_mant.clear(); + + int j = n_word( frac_digits ) * bits_in_word + int_digits - 1; + + for( ; s < end; s ++ ) + { + switch( *s ) + { + case '1': + set_bin( j ); + case '0': + j --; + case '.': + break; + default: + SCFX_FAIL_IF_( true ); // should not happen + } + } + + m_wp = n_word( frac_digits ) - word_offset; + break; + } + case 8: + { + exponent *= 3; + int_digits *= 3; + frac_digits *= 3; + + int bit_offset = exponent % bits_in_word; + int word_offset = exponent / bits_in_word; + + int_digits += bit_offset; + frac_digits -= bit_offset; + + int words = n_word( int_digits ) + n_word( frac_digits ); + if( words > size() ) + resize_to( words ); + m_mant.clear(); + + int j = n_word( frac_digits ) * bits_in_word + int_digits - 3; + + for( ; s < end; s ++ ) + { + switch( *s ) + { + case '7': case '6': case '5': case '4': + case '3': case '2': case '1': + set_oct( j, *s - '0' ); + case '0': + j -= 3; + case '.': + break; + default: + SCFX_FAIL_IF_( true ); // should not happen + } + } + + m_wp = n_word( frac_digits ) - word_offset; + break; + } + case 10: + { + word carry, temp; + int length = int_digits + frac_digits; + resize_to( sc_max( min_mant, n_word( 4 * length ) ) ); + + m_mant.clear(); + m_msw = m_lsw = 0; + + for( ; s < end; s ++ ) + { + switch( *s ) + { + case '9': case '8': case '7': case '6': case '5': + case '4': case '3': case '2': case '1': case '0': + multiply_by_ten(); + carry = *s - '0'; + for ( int i = 0; carry && i < m_mant.size(); i++ ) + { + temp = m_mant[i]; + temp += carry; + carry = temp < m_mant[i]; + m_mant[i] = temp; + } + case '.': + break; + default: + SCFX_FAIL_IF_( true ); // should not happen + } + } + + m_wp = 0; + find_sw(); + + int denominator = frac_digits - exponent; + + if( denominator ) + { + scfx_rep frac_num = pow10_fx( denominator ); + scfx_rep* temp_num = + div_scfx_rep( const_cast<const scfx_rep&>( *this ), + frac_num, cte_wl ); + *this = *temp_num; + delete temp_num; + } + + break; + } + case 16: + { + exponent *= 4; + int_digits *= 4; + frac_digits *= 4; + + int bit_offset = exponent % bits_in_word; + int word_offset = exponent / bits_in_word; + + int_digits += bit_offset; + frac_digits -= bit_offset; + + int words = n_word( int_digits ) + n_word( frac_digits ); + if( words > size() ) + resize_to( words ); + m_mant.clear(); + + int j = n_word( frac_digits ) * bits_in_word + int_digits - 4; + + for( ; s < end; s ++ ) + { + switch( *s ) + { + case 'f': case 'e': case 'd': case 'c': case 'b': case 'a': + set_hex( j, *s - 'a' + 10 ); + j -= 4; + break; + case 'F': case 'E': case 'D': case 'C': case 'B': case 'A': + set_hex( j, *s - 'A' + 10 ); + j -= 4; + break; + case '9': case '8': case '7': case '6': case '5': + case '4': case '3': case '2': case '1': + set_hex( j, *s - '0' ); + case '0': + j -= 4; + case '.': + break; + default: + SCFX_FAIL_IF_( true ); // should not happen + } + } + + m_wp = n_word( frac_digits ) - word_offset; + break; + } + } + + m_state = normal; + find_sw(); + + // + // two's complement of mantissa if it is negative + // + + if( mant_is_neg ) + { + m_mant[m_msw] |= -1 << scfx_find_msb( m_mant[m_msw] ); + for( int i = m_msw + 1; i < m_mant.size(); ++ i ) + m_mant[i] = static_cast<word>( -1 ); + complement( m_mant, m_mant, m_mant.size() ); + inc( m_mant ); + m_sign *= -1; + find_sw(); + } +} + + +#undef SCFX_FAIL_IF_ + + +// ---------------------------------------------------------------------------- +// METHOD : to_double +// +// Convert from scfx_rep to double. +// ---------------------------------------------------------------------------- + +double +scfx_rep::to_double() const +{ + scfx_ieee_double id; + + // handle special cases + + if( is_nan() ) + { + id.set_nan(); + return id; + } + + if( is_inf() ) + { + id.set_inf(); + id.negative( m_sign < 0 ); + return id; + } + + if( is_zero() ) + { + id = 0.; + id.negative( m_sign < 0 ); + return id; + } + + int msb = scfx_find_msb( m_mant[m_msw] ); + + int exp = (m_msw - m_wp) * bits_in_word + msb; + + if( exp > SCFX_IEEE_DOUBLE_E_MAX ) + { + id.set_inf(); + id.negative( m_sign < 0 ); + return id; + } + + if( exp < SCFX_IEEE_DOUBLE_E_MIN + - static_cast<int>( SCFX_IEEE_DOUBLE_M_SIZE ) ) + { + id = 0.; + return id; + } + + int shift = mantissa0_size - msb; + + unsigned int m0; + unsigned int m1 = 0; + unsigned int guard = 0; + + if( shift == 0 ) + { + m0 = m_mant[m_msw] & ~( 1 << mantissa0_size ); + if( m_msw > m_lsw ) + { + m1 = m_mant[m_msw - 1]; + if( m_msw - 1 > m_lsw ) + guard = m_mant[m_msw - 2] >> ( bits_in_word - 1 ); + } + } + else if( shift < 0 ) + { + m0 = ( m_mant[m_msw] >> -shift ) & ~( 1 << mantissa0_size ); + m1 = m_mant[m_msw] << ( bits_in_word + shift ); + if( m_msw > m_lsw ) + { + m1 |= m_mant[m_msw - 1] >> -shift; + guard = ( m_mant[m_msw - 1] >> ( -shift - 1 ) ) & 1; + } + } + else + { + m0 = ( m_mant[m_msw] << shift ) & ~( 1 << mantissa0_size ); + if( m_msw > m_lsw ) + { + m0 |= m_mant[m_msw - 1] >> ( bits_in_word - shift ); + m1 = m_mant[m_msw - 1] << shift; + if( m_msw - 1 > m_lsw ) + { + m1 |= m_mant[m_msw - 2] >> ( bits_in_word - shift ); + guard = ( m_mant[m_msw - 2] >> (bits_in_word - shift - 1) ) + & 1; + } + } + } + + if( exp < SCFX_IEEE_DOUBLE_E_MIN ) + { + m0 |= ( 1 << mantissa0_size ); + + int subnormal_shift = SCFX_IEEE_DOUBLE_E_MIN - exp; + + if( subnormal_shift < bits_in_word ) + { + m1 = m1 >> subnormal_shift + | m0 << ( bits_in_word - subnormal_shift ); + m0 = m0 >> subnormal_shift; + } + else + { + m1 = m0 >> ( subnormal_shift - bits_in_word ); + m0 = 0; + } + + guard = 0; + + exp = SCFX_IEEE_DOUBLE_E_MIN - 1; + } + + id.mantissa0( m0 ); + id.mantissa1( m1 ); + id.exponent( exp ); + id.negative( m_sign < 0 ); + + double result = id; + + if( guard != 0 ) + result += m_sign * scfx_pow2( exp - SCFX_IEEE_DOUBLE_M_SIZE ); + + return result; +} + + +// ---------------------------------------------------------------------------- +// METHOD : to_string +// +// Convert from scfx_rep to character string. +// ---------------------------------------------------------------------------- + +void +print_dec( scfx_string& s, const scfx_rep& num, int w_prefix, sc_fmt fmt ) +{ + if( num.is_neg() ) + s += '-'; + + if( w_prefix == 1 ) { + scfx_print_prefix( s, SC_DEC ); + } + + if( num.is_zero() ) + { + s += '0'; + return; + } + + // split 'num' into its integer and fractional part + + scfx_rep int_part = num; + scfx_rep frac_part = num; + + int i; + + for( i = int_part.m_lsw; i <= int_part.m_msw && i < int_part.m_wp; i ++ ) + int_part.m_mant[i] = 0; + int_part.find_sw(); + if( int_part.m_wp < int_part.m_lsw ) + int_part.resize_to( int_part.size() - int_part.m_wp, -1 ); + + for( i = frac_part.m_msw; + i >= frac_part.m_lsw && i >= frac_part.m_wp; + i -- ) + frac_part.m_mant[i] = 0; + frac_part.find_sw(); + if( frac_part.m_msw == frac_part.size() - 1 ) + frac_part.resize_to( frac_part.size() + 1, 1 ); + + // print integer part + + int int_digits = 0; + int int_zeros = 0; + + if( ! int_part.is_zero() ) + { + double int_wl = ( int_part.m_msw - int_part.m_wp ) * bits_in_word + + scfx_find_msb( int_part.m_mant[int_part.m_msw] ) + 1; + int_digits = (int) ceil( int_wl * log10( 2. ) ); + + int len = s.length(); + s.append( int_digits ); + + bool zero_digits = ( frac_part.is_zero() && fmt != SC_F ); + + for( i = int_digits + len - 1; i >= len; i-- ) + { + unsigned int remainder = int_part.divide_by_ten(); + s[i] = static_cast<char>( '0' + remainder ); + + if( zero_digits ) + { + if( remainder == 0 ) + int_zeros ++; + else + zero_digits = false; + } + } + + // discard trailing zeros from int_part + s.discard( int_zeros ); + + if( s[len] == '0' ) + { + // int_digits was overestimated by one + s.remove( len ); + -- int_digits; + } + } + + // print fractional part + + int frac_digits = 0; + int frac_zeros = 0; + + if( ! frac_part.is_zero() ) + { + s += '.'; + + bool zero_digits = ( int_digits == 0 && fmt != SC_F ); + + double frac_wl = ( frac_part.m_wp - frac_part.m_msw ) * bits_in_word + - scfx_find_msb( frac_part.m_mant[frac_part.m_msw] ) + - 1; + frac_zeros = (int) floor( frac_wl * log10( 2. ) ); + + scfx_rep temp; + sc_dt::multiply( temp, frac_part, pow10_fx( frac_zeros ) ); + frac_part = temp; + if( frac_part.m_msw == frac_part.size() - 1 ) + frac_part.resize_to( frac_part.size() + 1, 1 ); + + frac_digits = frac_zeros; + if( ! zero_digits ) + { + for( i = 0; i < frac_zeros; i ++ ) + s += '0'; + frac_zeros = 0; + } + + while( ! frac_part.is_zero() ) + { + frac_part.multiply_by_ten(); + int n = frac_part.m_mant[frac_part.m_msw + 1]; + + if( zero_digits ) + { + if( n == 0 ) + frac_zeros ++; + else + zero_digits = false; + } + + if( ! zero_digits ) + s += static_cast<char>( '0' + n ); + + frac_part.m_mant[frac_part.m_msw + 1] = 0; + frac_digits ++; + } + } + + // print exponent + + if( fmt != SC_F ) + { + if( frac_digits == 0 ) + scfx_print_exp( s, int_zeros ); + else if( int_digits == 0 ) + scfx_print_exp( s, - frac_zeros ); + } +} + +void +print_other( scfx_string& s, const scfx_rep& a, sc_numrep numrep, int w_prefix, + sc_fmt fmt, const scfx_params* params ) +{ + scfx_rep b = a; + + sc_numrep numrep2 = numrep; + + bool numrep_is_sm = ( numrep == SC_BIN_SM || + numrep == SC_OCT_SM || + numrep == SC_HEX_SM ); + + if( numrep_is_sm ) + { + if( b.is_neg() ) + { + s += '-'; + b = *neg_scfx_rep( a ); + } + switch( numrep ) + { + case SC_BIN_SM: + numrep2 = SC_BIN_US; + break; + case SC_OCT_SM: + numrep2 = SC_OCT_US; + break; + case SC_HEX_SM: + numrep2 = SC_HEX_US; + break; + default: + ; + } + } + + if( w_prefix != 0 ) { + scfx_print_prefix( s, numrep ); + } + + numrep = numrep2; + + int msb, lsb; + + if( params != 0 ) + { + msb = params->iwl() - 1; + lsb = params->iwl() - params->wl(); + + if( params->enc() == SC_TC_ && + ( numrep == SC_BIN_US || + numrep == SC_OCT_US || + numrep == SC_HEX_US ) && + ! numrep_is_sm && + params->wl() > 1 ) + -- msb; + else if( params->enc() == SC_US_ && + ( numrep == SC_BIN || + numrep == SC_OCT || + numrep == SC_HEX || + numrep == SC_CSD ) ) + ++ msb; + } + else + { + if( b.is_zero() ) + { + msb = 0; + lsb = 0; + } + else + { + msb = ( b.m_msw - b.m_wp ) * bits_in_word + + scfx_find_msb( b.m_mant[ b.m_msw ] ) + 1; + while( b.get_bit( msb ) == b.get_bit( msb - 1 ) ) + -- msb; + + if( numrep == SC_BIN_US || + numrep == SC_OCT_US || + numrep == SC_HEX_US ) + -- msb; + + lsb = ( b.m_lsw - b.m_wp ) * bits_in_word + + scfx_find_lsb( b.m_mant[ b.m_lsw ] ); + } + } + + int step; + + switch( numrep ) + { + case SC_BIN: + case SC_BIN_US: + case SC_CSD: + step = 1; + break; + case SC_OCT: + case SC_OCT_US: + step = 3; + break; + case SC_HEX: + case SC_HEX_US: + step = 4; + break; + default: + step = 0; + } + + msb = (int) ceil( double( msb + 1 ) / step ) * step - 1; + + lsb = (int) floor( double( lsb ) / step ) * step; + + if( msb < 0 ) + { + s += '.'; + if( fmt == SC_F ) + { + int sign = ( b.is_neg() ) ? ( 1 << step ) - 1 : 0; + for( int i = ( msb + 1 ) / step; i < 0; i ++ ) + { + if( sign < 10 ) + s += static_cast<char>( sign + '0' ); + else + s += static_cast<char>( sign + 'a' - 10 ); + } + } + } + + int i = msb; + while( i >= lsb ) + { + int value = 0; + for( int j = step - 1; j >= 0; -- j ) + { + value += static_cast<int>( b.get_bit( i ) ) << j; + -- i; + } + if( value < 10 ) + s += static_cast<char>( value + '0' ); + else + s += static_cast<char>( value + 'a' - 10 ); + if( i == -1 ) + s += '.'; + } + + if( lsb > 0 && fmt == SC_F ) + { + for( int i = lsb / step; i > 0; i -- ) + s += '0'; + } + + if( s[s.length() - 1] == '.' ) + s.discard( 1 ); + + if( fmt != SC_F ) + { + if( msb < 0 ) + scfx_print_exp( s, ( msb + 1 ) / step ); + else if( lsb > 0 ) + scfx_print_exp( s, lsb / step ); + } + + if( numrep == SC_CSD ) + scfx_tc2csd( s, w_prefix ); +} + +const char* +scfx_rep::to_string( sc_numrep numrep, int w_prefix, + sc_fmt fmt, const scfx_params* params ) const +{ + static scfx_string s; + + s.clear(); + + if( is_nan() ) + scfx_print_nan( s ); + else if( is_inf() ) + scfx_print_inf( s, is_neg() ); + else if( is_neg() && ! is_zero() && + ( numrep == SC_BIN_US || + numrep == SC_OCT_US || + numrep == SC_HEX_US ) ) + s += "negative"; + else if( numrep == SC_DEC || numrep == SC_NOBASE ) + sc_dt::print_dec( s, *this, w_prefix, fmt ); + else + sc_dt::print_other( s, *this, numrep, w_prefix, fmt, params ); + + return s; +} + + +// ---------------------------------------------------------------------------- +// ADD +// +// add two mantissas of the same size +// result has the same size +// returns carry of operation +// ---------------------------------------------------------------------------- + +static inline +int +add_mants( int size, scfx_mant& result, + const scfx_mant& a, const scfx_mant& b ) +{ + unsigned int carry = 0; + + int index = 0; + + do + { + word x = a[index]; + word y = b[index]; + + y += carry; + carry = y < carry; + y += x; + carry += y < x; + result[index] = y; + } + while( ++ index < size ); + + return ( carry ? 1 : 0 ); +} + + +static inline +int +sub_mants( int size, scfx_mant& result, + const scfx_mant& a, const scfx_mant& b ) +{ + unsigned carry = 0; + + int index = 0; + + do + { + word x = a[index]; + word y = b[index]; + + y += carry; + carry = y < carry; + y = x - y; + carry += y > x; + result[index] = y; + } + while( ++ index < size ); + + return ( carry ? 1 : 0 ); +} + + +scfx_rep* +add_scfx_rep( const scfx_rep& lhs, const scfx_rep& rhs, int max_wl ) +{ + scfx_rep& result = *new scfx_rep; + + // + // check for special cases + // + + if( lhs.is_nan() || rhs.is_nan() + || ( lhs.is_inf() && rhs.is_inf() && lhs.m_sign != rhs.m_sign ) ) + { + result.set_nan(); + return &result; + } + + if( lhs.is_inf() ) + { + result.set_inf( lhs.m_sign ); + return &result; + } + + if( rhs.is_inf() ) + { + result.set_inf( rhs.m_sign ); + return &result; + } + + // + // align operands if needed + // + + scfx_mant_ref lhs_mant; + scfx_mant_ref rhs_mant; + + int len_mant = lhs.size(); + int new_wp = lhs.m_wp; + + align( lhs, rhs, new_wp, len_mant, lhs_mant, rhs_mant ); + + // + // size the result mantissa + // + + result.resize_to( len_mant ); + result.m_wp = new_wp; + + // + // do it + // + + if( lhs.m_sign == rhs.m_sign ) + { + add_mants( len_mant, result.m_mant, lhs_mant, rhs_mant ); + result.m_sign = lhs.m_sign; + } + else + { + int cmp = compare_abs( lhs, rhs ); + + if( cmp == 1 ) + { + sub_mants( len_mant, result.m_mant, lhs_mant, rhs_mant ); + result.m_sign = lhs.m_sign; + } + else if ( cmp == -1 ) + { + sub_mants( len_mant, result.m_mant, rhs_mant, lhs_mant ); + result.m_sign = rhs.m_sign; + } + else + { + result.m_mant.clear(); + result.m_sign = 1; + } + } + + result.find_sw(); + result.round( max_wl ); + + return &result; +} + + +// ---------------------------------------------------------------------------- +// SUB +// +// sub two word's of the same size +// result has the same size +// returns carry of operation +// ---------------------------------------------------------------------------- + +static inline +int +sub_with_index( scfx_mant& a, int a_msw, int /*a_lsw*/, + const scfx_mant& b, int b_msw, int b_lsw ) +{ + unsigned carry = 0; + + int size = b_msw - b_lsw; + int a_index = a_msw - size; + int b_index = b_msw - size; + + do + { + word x = a[a_index]; + word y = b[b_index]; + + y += carry; + carry = y < carry; + y = x - y; + carry += y > x; + a[a_index] = y; + + a_index ++; + b_index ++; + } + while( size -- ); + + if( carry ) + { + // special case: a[a_msw + 1 ] == 1 + a[a_msw + 1] = 0; + } + + return ( carry ? 1 : 0 ); +} + + +scfx_rep* +sub_scfx_rep( const scfx_rep& lhs, const scfx_rep& rhs, int max_wl ) +{ + scfx_rep& result = *new scfx_rep; + + // + // check for special cases + // + + if( lhs.is_nan() || rhs.is_nan() + || ( lhs.is_inf() && rhs.is_inf() && lhs.m_sign == rhs.m_sign ) ) + { + result.set_nan(); + return &result; + } + + if( lhs.is_inf() ) + { + result.set_inf( lhs.m_sign ); + return &result; + } + + if( rhs.is_inf() ) + { + result.set_inf( -1 * rhs.m_sign ); + return &result; + } + + // + // align operands if needed + // + + scfx_mant_ref lhs_mant; + scfx_mant_ref rhs_mant; + + int len_mant = lhs.size(); + int new_wp = lhs.m_wp; + + align( lhs, rhs, new_wp, len_mant, lhs_mant, rhs_mant ); + + // + // size the result mantissa + // + + result.resize_to( len_mant ); + result.m_wp = new_wp; + + // + // do it + // + + if( lhs.m_sign != rhs.m_sign ) + { + add_mants( len_mant, result.m_mant, lhs_mant, rhs_mant ); + result.m_sign = lhs.m_sign; + } + else + { + int cmp = compare_abs( lhs, rhs ); + + if( cmp == 1 ) + { + sub_mants( len_mant, result.m_mant, lhs_mant, rhs_mant ); + result.m_sign = lhs.m_sign; + } + else if ( cmp == -1 ) + { + sub_mants( len_mant, result.m_mant, rhs_mant, lhs_mant ); + result.m_sign = -rhs.m_sign; + } else { + result.m_mant.clear(); + result.m_sign = 1; + } + } + + result.find_sw(); + result.round( max_wl ); + + return &result; +} + + +// ---------------------------------------------------------------------------- +// MUL +// ---------------------------------------------------------------------------- + +union word_short +{ + word l; + struct + { +#if defined( SC_BIG_ENDIAN ) + half_word u; + half_word l; +#elif defined( SC_LITTLE_ENDIAN ) + half_word l; + half_word u; +#endif + } s; +}; + + +#if defined( SC_BIG_ENDIAN ) +static const int half_word_incr = -1; +#elif defined( SC_LITTLE_ENDIAN ) +static const int half_word_incr = 1; +#endif + + +void +multiply( scfx_rep& result, const scfx_rep& lhs, const scfx_rep& rhs, + int max_wl ) +{ + // + // check for special cases + // + + if( lhs.is_nan() || rhs.is_nan() + || (lhs.is_inf() && rhs.is_zero()) + || (lhs.is_zero() && rhs.is_inf()) ) + { + result.set_nan(); + return; + } + + if( lhs.is_inf() || rhs.is_inf() ) + { + result.set_inf( lhs.m_sign * rhs.m_sign ); + return; + } + + if( lhs.is_zero() || rhs.is_zero() ) { + result.set_zero( lhs.m_sign * rhs.m_sign ); + return; + } + + // + // do it + // + + int len_lhs = lhs.m_msw - lhs.m_lsw + 1; + int len_rhs = rhs.m_msw - rhs.m_lsw + 1; + + int new_size = sc_max( min_mant, len_lhs + len_rhs ); + int new_wp = ( lhs.m_wp - lhs.m_lsw ) + ( rhs.m_wp - rhs.m_lsw ); + int new_sign = lhs.m_sign * rhs.m_sign; + + result.resize_to( new_size ); + result.m_mant.clear(); + result.m_wp = new_wp; + result.m_sign = new_sign; + result.m_state = scfx_rep::normal; + + half_word *s1 = lhs.m_mant.half_addr( lhs.m_lsw ); + half_word *s2 = rhs.m_mant.half_addr( rhs.m_lsw ); + + half_word *t = result.m_mant.half_addr(); + + len_lhs <<= 1; + len_rhs <<= 1; + + int i1, i2; + + for( i1 = 0; i1 * half_word_incr < len_lhs; i1 += half_word_incr ) + { + word_short ls; + ls.l = 0; + + half_word v1 = s1[i1]; + + for( i2 = 0; i2 * half_word_incr < len_rhs; i2 += half_word_incr ) + { + ls.l += v1 * s2[i2]; + ls.s.l = ls.s.u + ( ( t[i2] += ls.s.l ) < ls.s.l ); + ls.s.u = 0; + } + + t[i2] = ls.s.l; + t += half_word_incr; + } + + result.find_sw(); + result.round( max_wl ); +} + + +// ---------------------------------------------------------------------------- +// DIV +// ---------------------------------------------------------------------------- + +scfx_rep* +div_scfx_rep( const scfx_rep& lhs, const scfx_rep& rhs, int div_wl ) +{ + scfx_rep& result = *new scfx_rep; + + // + // check for special cases + // + + if( lhs.is_nan() || rhs.is_nan() || (lhs.is_inf() && rhs.is_inf()) || + (lhs.is_zero() && rhs.is_zero()) ) + { + result.set_nan(); + return &result; + } + + if( lhs.is_inf() || rhs.is_zero() ) + { + result.set_inf( lhs.m_sign * rhs.m_sign ); + return &result; + } + + if( lhs.is_zero() || rhs.is_inf() ) + { + result.set_zero( lhs.m_sign * rhs.m_sign ); + return &result; + } + + // + // do it + // + + // compute one bit more for rounding + div_wl ++; + + result.resize_to( sc_max( n_word( div_wl ) + 1, min_mant ) ); + result.m_mant.clear(); + result.m_sign = lhs.m_sign * rhs.m_sign; + + int msb_lhs = scfx_find_msb( lhs.m_mant[lhs.m_msw] ) + + ( lhs.m_msw - lhs.m_wp ) * bits_in_word; + int msb_rhs = scfx_find_msb( rhs.m_mant[rhs.m_msw] ) + + ( rhs.m_msw - rhs.m_wp ) * bits_in_word; + + int msb_res = msb_lhs - msb_rhs; + int to_shift = -msb_res % bits_in_word; + int result_index; + + int c = ( msb_res % bits_in_word >= 0 ) ? 1 : 0; + + result_index = (result.size() - c) * bits_in_word + msb_res % bits_in_word; + result.m_wp = (result.size() - c) - msb_res / bits_in_word; + + scfx_rep remainder = lhs; + + // align msb from remainder to msb from rhs + remainder.lshift( to_shift ); + + // make sure msw( remainder ) < size - 1 + if( remainder.m_msw == remainder.size() - 1 ) + remainder.resize_to( remainder.size() + 1, 1 ); + + // make sure msw( remainder ) >= msw( rhs )! + int msw_diff = rhs.m_msw - remainder.m_msw; + if (msw_diff > 0) + remainder.resize_to( remainder.size() + msw_diff, -1 ); + + int counter; + + for( counter = div_wl; counter && ! remainder.is_zero(); counter -- ) + { + if( compare_msw_ff( rhs, remainder ) <= 0 ) + { + result.set_bin( result_index ); + sub_with_index( remainder.m_mant, remainder.m_msw, remainder.m_lsw, + rhs.m_mant, rhs.m_msw, rhs.m_lsw ); + } + result_index --; + remainder.shift_left( 1 ); + remainder.m_lsw = remainder.find_lsw(); + } + + // perform convergent rounding, if needed + if( counter == 0 ) + { + int index = result_index + 1 - result.m_wp * bits_in_word; + + scfx_index x = result.calc_indices( index ); + scfx_index x1 = result.calc_indices( index + 1 ); + + if( result.o_bit_at( x ) && result.o_bit_at( x1 ) ) + result.q_incr( x ); + + result.m_r_flag = true; + } + + result.find_sw(); + + return &result; +} + + +// ---------------------------------------------------------------------------- +// destructive shift mantissa to the left +// ---------------------------------------------------------------------------- + +void +scfx_rep::lshift( int n ) +{ + if( n == 0 ) + return; + + if( n < 0 ) + { + rshift( -n ); + return; + } + + if( is_normal() ) + { + int shift_bits = n % bits_in_word; + int shift_words = n / bits_in_word; + + // resize if needed + if( m_msw == size() - 1 && + scfx_find_msb( m_mant[m_msw] ) >= bits_in_word - shift_bits ) + resize_to( size() + 1, 1 ); + + // do it + m_wp -= shift_words; + shift_left( shift_bits ); + find_sw(); + } +} + + +// ---------------------------------------------------------------------------- +// destructive shift mantissa to the right +// ---------------------------------------------------------------------------- + +void +scfx_rep::rshift( int n ) +{ + if( n == 0 ) + return; + + if( n < 0 ) + { + lshift( -n ); + return; + } + + if( is_normal() ) + { + int shift_bits = n % bits_in_word; + int shift_words = n / bits_in_word; + + // resize if needed + if( m_lsw == 0 && scfx_find_lsb( m_mant[m_lsw] ) < shift_bits ) + resize_to( size() + 1, -1 ); + + // do it + m_wp += shift_words; + shift_right( shift_bits ); + find_sw(); + } +} + + +// ---------------------------------------------------------------------------- +// FRIEND FUNCTION : compare_abs +// +// Compares the absolute values of two scfx_reps, excluding the special cases. +// ---------------------------------------------------------------------------- + +int +compare_abs( const scfx_rep& a, const scfx_rep& b ) +{ + // check for zero + + word a_word = a.m_mant[a.m_msw]; + word b_word = b.m_mant[b.m_msw]; + + if( a_word == 0 || b_word == 0 ) + { + if( a_word != 0 ) + return 1; + if( b_word != 0 ) + return -1; + return 0; + } + + // compare msw index + + int a_msw = a.m_msw - a.m_wp; + int b_msw = b.m_msw - b.m_wp; + + if( a_msw > b_msw ) + return 1; + + if( a_msw < b_msw ) + return -1; + + // compare content + + int a_i = a.m_msw; + int b_i = b.m_msw; + + while( a_i >= a.m_lsw && b_i >= b.m_lsw ) + { + a_word = a.m_mant[a_i]; + b_word = b.m_mant[b_i]; + if( a_word > b_word ) + return 1; + if( a_word < b_word ) + return -1; + -- a_i; + -- b_i; + } + + bool a_zero = true; + while( a_i >= a.m_lsw ) + { + a_zero = a_zero && ( a.m_mant[a_i] == 0 ); + -- a_i; + } + + bool b_zero = true; + while( b_i >= b.m_lsw ) + { + b_zero = b_zero && ( b.m_mant[b_i] == 0 ); + -- b_i; + } + + // assertion: a_zero || b_zero == true + + if( ! a_zero && b_zero ) + return 1; + + if( a_zero && ! b_zero ) + return -1; + + return 0; +} + + +// ---------------------------------------------------------------------------- +// FRIEND FUNCTION : cmp_scfx_rep +// +// Compares the values of two scfx_reps, including the special cases. +// ---------------------------------------------------------------------------- + +int +cmp_scfx_rep( const scfx_rep& a, const scfx_rep& b ) +{ + // handle special cases + + if( a.is_nan() || b.is_nan() ) + { +#if 0 + if( a.is_nan() && b.is_nan() ) + { + return 0; + } +#endif + return 2; + } + + if( a.is_inf() || b.is_inf() ) + { + if( a.is_inf() ) + { + if( ! a.is_neg() ) + { + if( b.is_inf() && ! b.is_neg() ) + { + return 0; + } + else + { + return 1; + } + } + else + { + if( b.is_inf() && b.is_neg() ) + { + return 0; + } + else + { + return -1; + } + } + } + if( b.is_inf() ) + { + if( ! b.is_neg() ) + { + return -1; + } + else + { + return 1; + } + } + } + + if( a.is_zero() && b.is_zero() ) + { + return 0; + } + + // compare sign + + if( a.m_sign != b.m_sign ) + { + return a.m_sign; + } + + return ( a.m_sign * compare_abs( a, b ) ); +} + + +// ---------------------------------------------------------------------------- +// PRIVATE METHOD : quantization +// +// Performs destructive quantization. +// ---------------------------------------------------------------------------- + +void +scfx_rep::quantization( const scfx_params& params, bool& q_flag ) +{ + scfx_index x = calc_indices( params.iwl() - params.wl() ); + + if( x.wi() < 0 ) + return; + + if( x.wi() >= size() ) + resize_to( x.wi() + 1, 1 ); + + bool qb = q_bit( x ); + bool qz = q_zero( x ); + + q_flag = ( qb || ! qz ); + + if( q_flag ) + { + switch( params.q_mode() ) + { + case SC_TRN: // truncation + { + if( is_neg() ) + q_incr( x ); + break; + } + case SC_RND: // rounding to plus infinity + { + if( ! is_neg() ) + { + if( qb ) + q_incr( x ); + } + else + { + if( qb && ! qz ) + q_incr( x ); + } + break; + } + case SC_TRN_ZERO: // truncation to zero + { + break; + } + case SC_RND_INF: // rounding to infinity + { + if( qb ) + q_incr( x ); + break; + } + case SC_RND_CONV: // convergent rounding + { + if( (qb && ! qz) || (qb && qz && q_odd( x )) ) + q_incr( x ); + break; + } + case SC_RND_ZERO: // rounding to zero + { + if( qb && ! qz ) + q_incr( x ); + break; + } + case SC_RND_MIN_INF: // rounding to minus infinity + { + if( ! is_neg() ) + { + if( qb && ! qz ) + q_incr( x ); + } + else + { + if( qb ) + q_incr( x ); + } + break; + } + default: + ; + } + q_clear( x ); + + find_sw(); + } +} + + +// ---------------------------------------------------------------------------- +// PRIVATE METHOD : overflow +// +// Performs destructive overflow handling. +// ---------------------------------------------------------------------------- + +void +scfx_rep::overflow( const scfx_params& params, bool& o_flag ) +{ + scfx_index x = calc_indices( params.iwl() - 1 ); + + if( x.wi() >= size() ) + resize_to( x.wi() + 1, 1 ); + + if( x.wi() < 0 ) + { + resize_to( size() - x.wi(), -1 ); + x.wi( 0 ); + } + + bool zero_left = o_zero_left( x ); + bool bit_at = o_bit_at( x ); + bool zero_right = o_zero_right( x ); + + bool under = false; + bool over = false; + + sc_enc enc = params.enc(); + + if( enc == SC_TC_ ) + { + if( is_neg() ) + { + if( params.o_mode() == SC_SAT_SYM ) + under = ( ! zero_left || bit_at ); + else + under = (! zero_left || (zero_left && bit_at && ! zero_right)); + } + else + over = ( ! zero_left || bit_at ); + } + else + { + if( is_neg() ) + under = ( ! is_zero() ); + else + over = ( ! zero_left ); + } + + o_flag = ( under || over ); + + if( o_flag ) + { + scfx_index x2 = calc_indices( params.iwl() - params.wl() ); + + if( x2.wi() < 0 ) + { + resize_to( size() - x2.wi(), -1 ); + x.wi( x.wi() - x2.wi() ); + x2.wi( 0 ); + } + + switch( params.o_mode() ) + { + case SC_WRAP: // wrap-around + { + int n_bits = params.n_bits(); + + if( n_bits == 0 ) + { + // wrap-around all 'wl' bits + toggle_tc(); + o_extend( x, enc ); + toggle_tc(); + } + else if( n_bits < params.wl() ) + { + scfx_index x3 = calc_indices( params.iwl() - 1 - n_bits ); + + // wrap-around least significant 'wl - n_bits' bits; + // saturate most significant 'n_bits' bits + toggle_tc(); + o_set( x, x3, enc, under ); + o_extend( x, enc ); + toggle_tc(); + } + else + { + // saturate all 'wl' bits + if( under ) + o_set_low( x, enc ); + else + o_set_high( x, x2, enc ); + } + break; + } + case SC_SAT: // saturation + { + if( under ) + o_set_low( x, enc ); + else + o_set_high( x, x2, enc ); + break; + } + case SC_SAT_SYM: // symmetrical saturation + { + if( under ) + { + if( enc == SC_TC_ ) + o_set_high( x, x2, SC_TC_, -1 ); + else + o_set_low( x, SC_US_ ); + } + else + o_set_high( x, x2, enc ); + break; + } + case SC_SAT_ZERO: // saturation to zero + { + set_zero(); + break; + } + case SC_WRAP_SM: // sign magnitude wrap-around + { + SC_ERROR_IF_( enc == SC_US_, + sc_core::SC_ID_WRAP_SM_NOT_DEFINED_ ); + + int n_bits = params.n_bits(); + + if( n_bits == 0 ) + { + scfx_index x4 = calc_indices( params.iwl() ); + + if( x4.wi() >= size() ) + resize_to( x4.wi() + 1, 1 ); + + toggle_tc(); + if( o_bit_at( x4 ) != o_bit_at( x ) ) + o_invert( x2 ); + o_extend( x, SC_TC_ ); + toggle_tc(); + } + else if( n_bits == 1 ) + { + toggle_tc(); + if( is_neg() != o_bit_at( x ) ) + o_invert( x2 ); + o_extend( x, SC_TC_ ); + toggle_tc(); + } + else if( n_bits < params.wl() ) + { + scfx_index x3 = calc_indices( params.iwl() - 1 - n_bits ); + scfx_index x4 = calc_indices( params.iwl() - n_bits ); + + // wrap-around least significant 'wl - n_bits' bits; + // saturate most significant 'n_bits' bits + toggle_tc(); + if( is_neg() == o_bit_at( x4 ) ) + o_invert( x2 ); + o_set( x, x3, SC_TC_, under ); + o_extend( x, SC_TC_ ); + toggle_tc(); + } + else + { + if( under ) + o_set_low( x, SC_TC_ ); + else + o_set_high( x, x2, SC_TC_ ); + } + break; + } + default: + ; + } + + find_sw(); + } +} + + +// ---------------------------------------------------------------------------- +// PUBLIC METHOD : cast +// +// Performs a destructive cast operation on a scfx_rep. +// ---------------------------------------------------------------------------- + +void +scfx_rep::cast( const scfx_params& params, bool& q_flag, bool& o_flag ) +{ + q_flag = false; + o_flag = false; + + // check for special cases + + if( is_zero() ) + { + if( is_neg() ) + m_sign = 1; + return; + } + + // perform casting + + quantization( params, q_flag ); + overflow( params, o_flag ); + + // check for special case: -0 + + if( is_zero() && is_neg() ) + m_sign = 1; +} + + +// ---------------------------------------------------------------------------- +// make sure, the two mantissas are aligned +// ---------------------------------------------------------------------------- + +void +align( const scfx_rep& lhs, const scfx_rep& rhs, int& new_wp, + int& len_mant, scfx_mant_ref& lhs_mant, scfx_mant_ref& rhs_mant ) +{ + bool need_lhs = true; + bool need_rhs = true; + + if( lhs.m_wp != rhs.m_wp || lhs.size() != rhs.size() ) + { + int lower_bound_lhs = lhs.m_lsw - lhs.m_wp; + int upper_bound_lhs = lhs.m_msw - lhs.m_wp; + int lower_bound_rhs = rhs.m_lsw - rhs.m_wp; + int upper_bound_rhs = rhs.m_msw - rhs.m_wp; + + int lower_bound = sc_min( lower_bound_lhs, lower_bound_rhs ); + int upper_bound = sc_max( upper_bound_lhs, upper_bound_rhs ); + + new_wp = -lower_bound; + len_mant = sc_max( min_mant, upper_bound - lower_bound + 1 ); + + if( new_wp != lhs.m_wp || len_mant != lhs.size() ) + { + lhs_mant = lhs.resize( len_mant, new_wp ); + need_lhs = false; + } + + if( new_wp != rhs.m_wp || len_mant != rhs.size() ) + { + rhs_mant = rhs.resize( len_mant, new_wp ); + need_rhs = false; + } + } + + if( need_lhs ) + { + lhs_mant = lhs.m_mant; + } + + if( need_rhs ) + { + rhs_mant = rhs.m_mant; + } +} + + +// ---------------------------------------------------------------------------- +// compare two mantissas +// ---------------------------------------------------------------------------- + +int +compare_msw_ff( const scfx_rep& lhs, const scfx_rep& rhs ) +{ + // special case: rhs.m_mant[rhs.m_msw + 1] == 1 + if( rhs.m_msw < rhs.size() - 1 && rhs.m_mant[rhs.m_msw + 1 ] != 0 ) + { + return -1; + } + + int lhs_size = lhs.m_msw - lhs.m_lsw + 1; + int rhs_size = rhs.m_msw - rhs.m_lsw + 1; + + int size = sc_min( lhs_size, rhs_size ); + + int lhs_index = lhs.m_msw; + int rhs_index = rhs.m_msw; + + int i; + + for( i = 0; + i < size && lhs.m_mant[lhs_index] == rhs.m_mant[rhs_index]; + i ++ ) + { + lhs_index --; + rhs_index --; + } + + if( i == size ) + { + if( lhs_size == rhs_size ) + { + return 0; + } + + if( lhs_size < rhs_size ) + { + return -1; + } + else + { + return 1; + } + } + + if( lhs.m_mant[lhs_index] < rhs.m_mant[rhs_index] ) + { + return -1; + } else { + return 1; + } +} + + +// ---------------------------------------------------------------------------- +// divide the mantissa by ten +// ---------------------------------------------------------------------------- + +unsigned int +scfx_rep::divide_by_ten() +{ +#if defined( SC_BIG_ENDIAN ) + half_word* hw = (half_word*) &m_mant[m_msw]; +#elif defined( SC_LITTLE_ENDIAN ) + half_word* hw = ( (half_word*) &m_mant[m_msw] ) + 1; +#endif + + unsigned int remainder = 0; + + word_short ls; + ls.l = 0; + +#if defined( SC_BIG_ENDIAN ) + for( int i = 0, end = ( m_msw - m_wp + 1 ) * 2; i < end; i ++ ) +#elif defined( SC_LITTLE_ENDIAN ) + for( int i = 0, end = -( m_msw - m_wp + 1 ) * 2; i > end; i -- ) +#endif + { + ls.s.u = static_cast<half_word>( remainder ); + ls.s.l = hw[i]; + remainder = ls.l % 10; + ls.l /= 10; + hw[i] = ls.s.l; + } + + return remainder; +} + + +// ---------------------------------------------------------------------------- +// multiply the mantissa by ten +// ---------------------------------------------------------------------------- + +void +scfx_rep::multiply_by_ten() +{ + int size = m_mant.size() + 1; + + scfx_mant mant8( size ); + scfx_mant mant2( size ); + + size --; + + mant8[size] = (m_mant[size - 1] >> (bits_in_word - 3)); + mant2[size] = (m_mant[size - 1] >> (bits_in_word - 1)); + + while( -- size ) + { + mant8[size] = ( m_mant[size] << 3 ) | + ( m_mant[size - 1] >> ( bits_in_word - 3 ) ); + mant2[size] = ( m_mant[size] << 1 ) | + ( m_mant[size - 1] >> ( bits_in_word - 1 ) ); + } + + mant8[0] = ( m_mant[0] << 3 ); + mant2[0] = ( m_mant[0] << 1 ); + + add_mants( m_mant.size(), m_mant, mant8, mant2 ); + +#if 0 + for( int i = size() - 1; i > 0; i -- ) + { + m_mant[i] = ( m_mant[i] << 3 ) | + ( m_mant[i-1] >> ( bits_in_word - 3 ) ) + + ( m_mant[i] << 1 ) | + ( m_mant[i-1] >> ( bits_in_word - 1 ) ); + } + m_mant[0] = ( m_mant[0] << 3 ) + ( m_mant[0] << 1 ); +#endif +} + + +// ---------------------------------------------------------------------------- +// normalize +// ---------------------------------------------------------------------------- + +void +scfx_rep::normalize( int exponent ) +{ + int shift = exponent % bits_in_word; + if( shift < 0 ) + { + shift += bits_in_word; + } + + if( shift ) + { + shift_left( shift ); + } + + find_sw(); + + m_wp = (shift - exponent) / bits_in_word; +} + + +// ---------------------------------------------------------------------------- +// return a new mantissa that is aligned and resized +// ---------------------------------------------------------------------------- + +scfx_mant* +scfx_rep::resize( int new_size, int new_wp ) const +{ + scfx_mant *result = new scfx_mant( new_size ); + + result->clear(); + + int shift = new_wp - m_wp; + + for( int j = m_lsw; j <= m_msw; j ++ ) + { + (*result)[j+shift] = m_mant[j]; + } + + return result; +} + + +// ---------------------------------------------------------------------------- +// set a single bit +// ---------------------------------------------------------------------------- + +void +scfx_rep::set_bin( int i ) +{ + m_mant[i >> 5] |= 1 << ( i & 31 ); +} + + +// ---------------------------------------------------------------------------- +// set three bits +// ---------------------------------------------------------------------------- + +void +scfx_rep::set_oct( int i, int n ) +{ + if( n & 1 ) + { + m_mant[i >> 5] |= 1 << ( i & 31 ); + } + i ++; + if( n & 2 ) + { + m_mant[i >> 5] |= 1 << ( i & 31 ); + } + i ++; + if( n & 4 ) + { + m_mant[i >> 5] |= 1 << ( i & 31 ); + } +} + + +// ---------------------------------------------------------------------------- +// set four bits +// ---------------------------------------------------------------------------- + +void +scfx_rep::set_hex( int i, int n ) +{ + if( n & 1 ) + { + m_mant[i >> 5] |= 1 << ( i & 31 ); + } + i ++; + if( n & 2 ) + { + m_mant[i >> 5] |= 1 << ( i & 31 ); + } + i ++; + if( n & 4 ) + { + m_mant[i >> 5] |= 1 << ( i & 31 ); + } + i ++; + if( n & 8 ) + { + m_mant[i >> 5] |= 1 << ( i & 31 ); + } +} + + +// ---------------------------------------------------------------------------- +// PRIVATE METHOD : shift_left +// +// Shifts a scfx_rep to the left by a MAXIMUM of bits_in_word - 1 bits. +// ---------------------------------------------------------------------------- + +void +scfx_rep::shift_left( int n ) +{ + if( n != 0 ) + { + int shift_left = n; + int shift_right = bits_in_word - n; + + SC_ASSERT_( !(m_mant[size()-1] >> shift_right), + "shift_left overflow" ); + + for( int i = size() - 1; i > 0; i -- ) + { + m_mant[i] = ( m_mant[i] << shift_left ) | + ( m_mant[i-1] >> shift_right ); + } + m_mant[0] <<= shift_left; + } +} + + +// ---------------------------------------------------------------------------- +// PRIVATE METHOD : shift_right +// +// Shifts a scfx_rep to the right by a MAXIMUM of bits_in_word - 1 bits. +// ---------------------------------------------------------------------------- + +void +scfx_rep::shift_right( int n ) +{ + if( n != 0 ) + { + int shift_left = bits_in_word - n; + int shift_right = n; + + SC_ASSERT_( !(m_mant[0] << shift_left), "shift_right overflow" ); + + for( int i = 0; i < size() - 1; i ++ ) + { + m_mant[i] = ( m_mant[i] >> shift_right ) | + ( m_mant[i+1] << shift_left ); + } + m_mant[size()-1] >>= shift_right; + } +} + + +// ---------------------------------------------------------------------------- +// METHOD : get_bit +// +// Tests a bit, in two's complement. +// ---------------------------------------------------------------------------- + +bool +scfx_rep::get_bit( int i ) const +{ + if( ! is_normal() ) + return false; + + scfx_index x = calc_indices( i ); + + if( x.wi() >= size() ) + return is_neg(); + + if( x.wi() < 0 ) + return false; + + const_cast<scfx_rep*>( this )->toggle_tc(); + + bool result = ( m_mant[x.wi()] & ( 1 << x.bi() ) ) != 0; + + const_cast<scfx_rep*>( this )->toggle_tc(); + + return result; +} + + +// ---------------------------------------------------------------------------- +// METHOD : set +// +// Sets a bit, in two's complement, between iwl-1 and -fwl. +// ---------------------------------------------------------------------------- + +bool +scfx_rep::set( int i, const scfx_params& params ) +{ + if( ! is_normal() ) + return false; + + scfx_index x = calc_indices( i ); + + if( x.wi() >= size() ) + { + if( is_neg() ) + return true; + else + resize_to( x.wi() + 1, 1 ); + } + else if( x.wi() < 0 ) + { + resize_to( size() - x.wi(), -1 ); + x.wi( 0 ); + } + + toggle_tc(); + + m_mant[x.wi()] |= 1 << x.bi(); + + if( i == params.iwl() - 1 ) + o_extend( x, params.enc() ); // sign extension + + toggle_tc(); + + find_sw(); + + return true; +} + + +// ---------------------------------------------------------------------------- +// METHOD : clear +// +// Clears a bit, in two's complement, between iwl-1 and -fwl. +// ---------------------------------------------------------------------------- + +bool +scfx_rep::clear( int i, const scfx_params& params ) +{ + if( ! is_normal() ) + return false; + + scfx_index x = calc_indices( i ); + + if( x.wi() >= size() ) + { + if( ! is_neg() ) + return true; + else + resize_to( x.wi() + 1, 1 ); + } + else if( x.wi() < 0 ) + return true; + + toggle_tc(); + + m_mant[x.wi()] &= ~( 1 << x.bi() ); + + if( i == params.iwl() - 1 ) + o_extend( x, params.enc() ); // sign extension + + toggle_tc(); + + find_sw(); + + return true; +} + + +// ---------------------------------------------------------------------------- +// METHOD : get_slice +// ---------------------------------------------------------------------------- + +bool +scfx_rep::get_slice( int i, int j, const scfx_params&, + sc_bv_base& bv ) const +{ + if( is_nan() || is_inf() ) + return false; + + // get the bits + + int l = j; + for( int k = 0; k < bv.length(); ++ k ) + { + bv[k] = get_bit( l ); + + if( i >= j ) + ++ l; + else + -- l; + } + + return true; +} + +bool +scfx_rep::set_slice( int i, int j, const scfx_params& params, + const sc_bv_base& bv ) +{ + if( is_nan() || is_inf() ) + return false; + + // set the bits + + int l = j; + for( int k = 0; k < bv.length(); ++ k ) + { + if( bv[k].to_bool() ) + set( l, params ); + else + clear( l, params ); + + if( i >= j ) + ++ l; + else + -- l; + } + + return true; +} + + +// ---------------------------------------------------------------------------- +// METHOD : print +// ---------------------------------------------------------------------------- + +void +scfx_rep::print( ::std::ostream& os ) const +{ + os << to_string( SC_DEC, -1, SC_E ); +} + + +// ---------------------------------------------------------------------------- +// METHOD : dump +// ---------------------------------------------------------------------------- + +void +scfx_rep::dump( ::std::ostream& os ) const +{ + os << "scfx_rep" << ::std::endl; + os << "(" << ::std::endl; + + os << "mant =" << ::std::endl; + for( int i = size() - 1; i >= 0; i -- ) + { + char buf[BUFSIZ]; + std::sprintf( buf, " %d: %10u (%8x)", i, (int) m_mant[i], (int) m_mant[i] ); + os << buf << ::std::endl; + } + + os << "wp = " << m_wp << ::std::endl; + os << "sign = " << m_sign << ::std::endl; + + os << "state = "; + switch( m_state ) + { + case normal: + os << "normal"; + break; + case infinity: + os << "infinity"; + break; + case not_a_number: + os << "not_a_number"; + break; + default: + os << "unknown"; + } + os << ::std::endl; + + os << "msw = " << m_msw << ::std::endl; + os << "lsw = " << m_lsw << ::std::endl; + + os << ")" << ::std::endl; +} + + +// ---------------------------------------------------------------------------- +// METHOD : get_type +// ---------------------------------------------------------------------------- + +void +scfx_rep::get_type( int& wl, int& iwl, sc_enc& enc ) const +{ + if( is_nan() || is_inf() ) + { + wl = 0; + iwl = 0; + enc = SC_TC_; + return; + } + + if( is_zero() ) + { + wl = 1; + iwl = 1; + enc = SC_US_; + return; + } + + int msb = ( m_msw - m_wp ) * bits_in_word + + scfx_find_msb( m_mant[ m_msw ] ) + 1; + while( get_bit( msb ) == get_bit( msb - 1 ) ) + { + -- msb; + } + + int lsb = ( m_lsw - m_wp ) * bits_in_word + + scfx_find_lsb( m_mant[ m_lsw ] ); + + if( is_neg() ) + { + wl = msb - lsb + 1; + iwl = msb + 1; + enc = SC_TC_; + } + else + { + wl = msb - lsb; + iwl = msb; + enc = SC_US_; + } +} + + +// ---------------------------------------------------------------------------- +// PRIVATE METHOD : round +// +// Performs convergent rounding (rounding to even) as in floating-point. +// ---------------------------------------------------------------------------- + +void +scfx_rep::round( int wl ) +{ + // check for special cases + + if( is_nan() || is_inf() || is_zero() ) + return; + + // estimate effective wordlength and compare + + int wl_effective; + + wl_effective = ( m_msw - m_lsw + 1 ) * bits_in_word; + if( wl_effective <= wl ) + return; + + // calculate effective wordlength and compare + + int msb = scfx_find_msb( m_mant[m_msw] ); + int lsb = scfx_find_lsb( m_mant[m_lsw] ); + + wl_effective = ( m_msw * bits_in_word + msb ) - + ( m_lsw * bits_in_word + lsb ) + 1; + if( wl_effective <= wl ) + return; + + // perform rounding + + int wi = m_msw - ( wl - 1 ) / bits_in_word; + int bi = msb - ( wl - 1 ) % bits_in_word; + if( bi < 0 ) + { + -- wi; + bi += bits_in_word; + } + + scfx_index x( wi, bi ); + + if( (q_bit( x ) && ! q_zero( x )) || + (q_bit( x ) && q_zero( x ) && q_odd( x )) ) + q_incr( x ); + q_clear( x ); + + find_sw(); + + m_r_flag = true; +} + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_rep.h b/ext/systemc/src/sysc/datatypes/fx/scfx_rep.h new file mode 100644 index 000000000..c5b76ce54 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_rep.h @@ -0,0 +1,842 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_rep.h - + + Original Author: Robert Graulich, Synopsys, Inc. + Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: scfx_rep.h,v $ +// Revision 1.6 2011/08/24 22:05:43 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.5 2011/07/25 10:20:29 acg +// Andy Goodrich: check in aftermath of call to automake. +// +// Revision 1.4 2010/12/07 20:09:08 acg +// Andy Goodrich: Philipp Hartmann's constructor disambiguation fix +// +// Revision 1.3 2010/08/03 15:54:52 acg +// Andy Goodrich: formatting. +// +// Revision 1.2 2010/03/15 18:29:01 acg +// Andy Goodrich: Moved default argument specifications from friend +// declarations to the actual function signatures. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.4 2006/03/13 20:24:27 acg +// Andy Goodrich: Addition of function declarations, e.g., neg_scfx_rep(), +// to keep gcc 4.x happy. +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SCFX_REP_H +#define SCFX_REP_H + + +#include <climits> + +#include "sysc/datatypes/fx/scfx_mant.h" +#include "sysc/datatypes/fx/scfx_params.h" +#include "sysc/datatypes/fx/scfx_string.h" + + +namespace sc_dt +{ + +// classes defined in this module +class scfx_index; +class scfx_rep; + +// forward class declarations +class sc_bv_base; +class sc_signed; +class sc_unsigned; + +// function declarations +void multiply( scfx_rep&, const scfx_rep&, const scfx_rep&, + int max_wl = SC_DEFAULT_MAX_WL_ ); +scfx_rep* neg_scfx_rep( const scfx_rep& ); +scfx_rep* mult_scfx_rep( const scfx_rep&, const scfx_rep&, + int max_wl = SC_DEFAULT_MAX_WL_ ); +scfx_rep* div_scfx_rep( const scfx_rep&, const scfx_rep&, + int max_wl = SC_DEFAULT_DIV_WL_ ); +scfx_rep* add_scfx_rep( const scfx_rep&, const scfx_rep&, + int max_wl = SC_DEFAULT_MAX_WL_ ); +scfx_rep* sub_scfx_rep( const scfx_rep&, const scfx_rep&, + int max_wl = SC_DEFAULT_MAX_WL_ ); +scfx_rep* lsh_scfx_rep( const scfx_rep&, int ); +scfx_rep* rsh_scfx_rep( const scfx_rep&, int ); +int cmp_scfx_rep( const scfx_rep&, const scfx_rep& ); + + +const int min_mant = 4; + +const int bits_in_int = sizeof(int) * CHAR_BIT; +const int bits_in_word = sizeof(word) * CHAR_BIT; + + +// ---------------------------------------------------------------------------- +// CLASS : scfx_index +// ---------------------------------------------------------------------------- + +class scfx_index +{ + +public: + + scfx_index( int wi_, int bi_ ) : m_wi( wi_ ), m_bi( bi_ ) {} + + int wi() const { return m_wi; } + int bi() const { return m_bi; } + + void wi( int wi_ ) { m_wi = wi_; } + +private: + + int m_wi; + int m_bi; + +}; + + +// ---------------------------------------------------------------------------- +// CLASS : scfx_rep +// +// Arbitrary-precision fixed-point implementation class. +// ---------------------------------------------------------------------------- + +class scfx_rep +{ + enum state + { + normal, + infinity, + not_a_number + }; + +public: + + // constructors + + scfx_rep(); + explicit scfx_rep( int ); + explicit scfx_rep( unsigned int ); + explicit scfx_rep( long ); + explicit scfx_rep( unsigned long ); + explicit scfx_rep( double ); + explicit scfx_rep( const char* ); + explicit scfx_rep( int64 ); + explicit scfx_rep( uint64 ); + explicit scfx_rep( const sc_signed& ); + explicit scfx_rep( const sc_unsigned& ); + + + // copy constructor + + scfx_rep( const scfx_rep& ); + + + // destructor + + ~scfx_rep(); + + + void* operator new( std::size_t ); + void operator delete( void*, std::size_t ); + + + void from_string( const char*, int ); + + double to_double() const; + + const char* to_string( sc_numrep, + int, + sc_fmt, + const scfx_params* = 0 ) const; + + + // assignment operator + + void operator = ( const scfx_rep& ); + + friend void multiply( scfx_rep&, const scfx_rep&, const scfx_rep&, int ); + + friend scfx_rep* neg_scfx_rep( const scfx_rep& ); + friend scfx_rep* mult_scfx_rep( const scfx_rep&, const scfx_rep&, int ); + friend scfx_rep* div_scfx_rep( const scfx_rep&, const scfx_rep&, int ); + friend scfx_rep* add_scfx_rep( const scfx_rep&, const scfx_rep&, int ); + friend scfx_rep* sub_scfx_rep( const scfx_rep&, const scfx_rep&, int ); + friend scfx_rep* lsh_scfx_rep( const scfx_rep&, int ); + friend scfx_rep* rsh_scfx_rep( const scfx_rep&, int ); + + void lshift( int ); + void rshift( int ); + + friend int cmp_scfx_rep( const scfx_rep&, const scfx_rep& ); + + void cast( const scfx_params&, bool&, bool& ); + + bool is_neg() const; + bool is_zero() const; + bool is_nan() const; + bool is_inf() const; + bool is_normal() const; + + void set_zero( int = 1 ); + void set_nan(); + void set_inf( int ); + + bool get_bit( int ) const; + bool set( int, const scfx_params& ); + bool clear( int, const scfx_params& ); + + bool get_slice( int, int, const scfx_params&, sc_bv_base& ) const; + bool set_slice( int, int, const scfx_params&, const sc_bv_base& ); + + void print( ::std::ostream& ) const; + void dump( ::std::ostream& ) const; + + void get_type( int&, int&, sc_enc& ) const; + + friend scfx_rep* quantization_scfx_rep( const scfx_rep&, + const scfx_params&, + bool& ); + friend scfx_rep* overflow_scfx_rep( const scfx_rep&, + const scfx_params&, + bool& ); + + bool rounding_flag() const; + +private: + + friend void align( const scfx_rep&, const scfx_rep&, int&, int&, + scfx_mant_ref&, scfx_mant_ref& ); + friend int compare_msw( const scfx_rep&, const scfx_rep& ); + friend int compare_msw_ff( const scfx_rep& lhs, const scfx_rep& rhs ); + unsigned int divide_by_ten(); + int find_lsw() const; + int find_msw() const; + void find_sw(); + void multiply_by_ten(); + void normalize( int ); + scfx_mant* resize( int, int ) const; + void set_bin( int ); + void set_oct( int, int ); + void set_hex( int, int ); + void shift_left( int ); + void shift_right( int ); + + const scfx_index calc_indices( int ) const; + + void o_extend( const scfx_index&, sc_enc ); + bool o_bit_at( const scfx_index& ) const; + bool o_zero_left( const scfx_index& ) const; + bool o_zero_right( const scfx_index& ) const; + void o_set_low( const scfx_index&, sc_enc ); + void o_set_high( const scfx_index&, const scfx_index&, sc_enc, int = 1 ); + void o_set( const scfx_index&, const scfx_index&, sc_enc, bool ); + void o_invert( const scfx_index& ); + bool q_bit( const scfx_index& ) const; + void q_clear( const scfx_index& ); + void q_incr( const scfx_index& ); + bool q_odd( const scfx_index& ) const; + bool q_zero( const scfx_index& ) const; + + void resize_to( int, int = 0 ); + int size() const; + void toggle_tc(); + + friend void print_dec( scfx_string&, const scfx_rep&, int, sc_fmt ); + friend void print_other( scfx_string&, const scfx_rep&, sc_numrep, int, + sc_fmt, const scfx_params* ); + + void quantization( const scfx_params&, bool& ); + void overflow( const scfx_params&, bool& ); + + friend int compare_abs( const scfx_rep&, const scfx_rep& ); + + void round( int ); + +private: + + scfx_mant m_mant; // mantissa (bits of the value). + int m_wp; // index of highest order word in value. + int m_sign; // sign of value. + state m_state; // value state, e.g., normal, inf, etc. + int m_msw; // index of most significant non-zero word. + int m_lsw; // index of least significant non-zero word. + bool m_r_flag; // true if founding occurred. + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +inline +void +scfx_rep::set_zero( int sign ) +{ + m_mant.clear(); + m_wp = m_msw = m_lsw = 0; + m_sign = sign; + m_state = normal; +} + +inline +void +scfx_rep::set_nan() +{ + m_mant.resize_to( min_mant ); + m_state = not_a_number; +} + +inline +void +scfx_rep::set_inf( int sign ) +{ + m_mant.resize_to( min_mant ); + m_state = infinity; + m_sign = sign; +} + + +// constructors + +inline +scfx_rep::scfx_rep( const char* s ) +: m_mant( min_mant ), m_wp( 2 ), m_sign( 1 ), m_state( normal ), + m_msw(0), m_lsw(0), m_r_flag( false ) +{ + from_string( s, SC_DEFAULT_CTE_WL_ ); +} + + +// destructor + +inline +scfx_rep::~scfx_rep() +{} + + +// assignment operator + +inline +void +scfx_rep::operator = ( const scfx_rep& f ) +{ + if( &f != this ) + { + m_mant = f.m_mant; + m_wp = f.m_wp; + m_sign = f.m_sign; + m_state = f.m_state; + m_msw = f.m_msw; + m_lsw = f.m_lsw; + round( SC_DEFAULT_MAX_WL_ ); + } +} + +inline +scfx_rep* +neg_scfx_rep( const scfx_rep& a ) +{ + scfx_rep& c = *new scfx_rep( a ); + c.m_sign = - c.m_sign; + return &c; +} + +inline +scfx_rep* +mult_scfx_rep( const scfx_rep& a, const scfx_rep& b, int max_wl ) +{ + scfx_rep& c = *new scfx_rep; + sc_dt::multiply( c, a, b, max_wl ); + return &c; +} + +inline +scfx_rep* +lsh_scfx_rep( const scfx_rep& a, int b ) +{ + scfx_rep& c = *new scfx_rep( a ); + c.lshift( b ); + return &c; +} + +inline +scfx_rep* +rsh_scfx_rep( const scfx_rep& a, int b ) +{ + scfx_rep& c = *new scfx_rep( a ); + c.rshift( b ); + return &c; +} + +inline +int +scfx_rep::size() const +{ + return m_mant.size(); +} + +inline +bool +scfx_rep::is_neg() const +{ + return ( m_sign == -1 ); +} + +inline +bool +scfx_rep::is_zero() const +{ + if( m_state != normal ) + return false; + + for( int i = 0; i < size(); i ++ ) + { + if( m_mant[i] ) + return false; + } + + return true; +} + +inline +bool +scfx_rep::is_nan() const +{ + return ( m_state == not_a_number ); +} + +inline +bool +scfx_rep::is_inf() const +{ + return ( m_state == infinity ); +} + +inline +bool +scfx_rep::is_normal() const +{ + return ( m_state == normal ); +} + +inline +scfx_rep* +quantization_scfx_rep( const scfx_rep& a, + const scfx_params& params, + bool& q_flag ) +{ + scfx_rep& c = *new scfx_rep( a ); + c.quantization( params, q_flag ); + return &c; +} + +inline +scfx_rep* +overflow_scfx_rep( const scfx_rep& a, + const scfx_params& params, + bool& o_flag ) +{ + scfx_rep& c = *new scfx_rep( a ); + c.overflow( params, o_flag ); + return &c; +} + +inline +bool +scfx_rep::rounding_flag() const +{ + return m_r_flag; +} + +inline +void +scfx_rep::resize_to( int new_size, int restore ) +{ + if( restore == -1 ) + { + int size_incr = new_size - size(); + m_wp += size_incr; + m_msw += size_incr; + m_lsw += size_incr; + } + m_mant.resize_to( new_size, restore ); +} + +inline +const scfx_index +scfx_rep::calc_indices( int n ) const +{ + int wi = n / bits_in_word + m_wp; + int bi = n % bits_in_word; + + if( bi < 0 ) + { + bi += bits_in_word; + -- wi; + } + + return scfx_index( wi, bi ); +} + +inline +void +scfx_rep::o_extend( const scfx_index& x, sc_enc enc ) +{ + int wi = x.wi(); + int bi = x.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + + if( enc == SC_US_ || ( m_mant[wi] & ( ((word)1) << bi ) ) == 0 ) + { + if( bi != bits_in_word - 1 ) + m_mant[wi] &= ~( ((word)-1) << ( bi + 1 ) ); + for( int i = wi + 1; i < size(); ++ i ) + m_mant[i] = 0; + m_sign = 1; + } + else + { + if( bi != bits_in_word - 1 ) + m_mant[wi] |= ( ((word)-1) << ( bi + 1 ) ); + for( int i = wi + 1; i < size(); ++ i ) + m_mant[i] = static_cast<word>( -1 ); + m_sign = -1; + } +} + +inline +bool +scfx_rep::o_bit_at( const scfx_index& x ) const +{ + int wi = x.wi(); + int bi = x.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + + return ( m_mant[wi] & ( ((word)1) << bi ) ) != 0; +} + +inline +bool +scfx_rep::o_zero_left( const scfx_index& x ) const +{ + int wi = x.wi(); + int bi = x.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + + bool zero = true; + if( bi != bits_in_word - 1 ) + zero = ( m_mant[wi] & ( ((word)-1) << ( bi + 1 ) ) ) == 0; + for( int i = wi + 1; i < size(); ++ i ) + zero = zero && m_mant[i] == 0; + + return zero; +} + +inline +bool +scfx_rep::o_zero_right( const scfx_index& x ) const +{ + int wi = x.wi(); + int bi = x.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + + bool zero = ( m_mant[wi] & ~( ((word)-1) << bi ) ) == 0; + for( int i = wi - 1; i >= 0; -- i ) + zero = zero && m_mant[i] == 0; + + return zero; +} + +inline +void +scfx_rep::o_set_low( const scfx_index& x, sc_enc enc ) +{ + int wi = x.wi(); + int bi = x.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + + m_mant.clear(); + + if( enc == SC_TC_ ) + { + m_mant[wi] |= ( ((word)1) << bi ); + m_sign = -1; + } + else + m_sign = 1; +} + +inline +void +scfx_rep::o_set_high( const scfx_index& x, const scfx_index& x2, + sc_enc enc, int sign ) +{ + int wi = x.wi(); + int bi = x.bi(); + int wi2 = x2.wi(); + int bi2 = x2.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + SC_ASSERT_( wi2 >= 0 && wi2 < size(), "word index out of range" ); + + int i; + + for( i = 0; i < size(); ++ i ) + m_mant[i] = static_cast<word>( -1 ); + + m_mant[wi] &= ~( ((word)-1) << bi ); + for( i = wi + 1; i < size(); ++ i ) + m_mant[i] = 0; + + m_mant[wi2] &= ( ((word)-1) << bi2 ); + for( i = wi2 - 1; i >= 0; -- i ) + m_mant[i] = 0; + + if( enc == SC_TC_ ) + m_sign = sign; + else + { + m_mant[wi] |= ( ((word)1) << bi ); + m_sign = 1; + } +} + +inline +void +scfx_rep::o_set( const scfx_index& x, const scfx_index& x3, + sc_enc enc, bool under ) +{ + int wi = x.wi(); + int bi = x.bi(); + int wi3 = x3.wi(); + int bi3 = x3.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + SC_ASSERT_( wi3 >= 0 && wi3 < size(), "word index out of range" ); + + if( bi3 != bits_in_word - 1 ) + { + if( under ) + m_mant[wi3] &= ~( ((word)-1) << ( bi3 + 1 ) ); + else + m_mant[wi3] |= ( ((word)-1) << ( bi3 + 1 ) ); + } + for( int i = wi3 + 1; i < size(); ++ i ) + { + if( under ) + m_mant[i] = 0; + else + m_mant[i] = static_cast<word>( -1 ); + } + + if( enc == SC_TC_ ) + { + if( under ) + m_mant[wi] |= ( ((word)1) << bi ); + else + m_mant[wi] &= ~( ((word)1) << bi ); + } +} + +inline +void +scfx_rep::o_invert( const scfx_index& x2 ) +{ + int wi2 = x2.wi(); + int bi2 = x2.bi(); + + m_mant[wi2] ^= ( ((word)-1) << bi2 ); + for( int i = wi2 + 1; i < size(); ++ i ) + m_mant[i] = ~ m_mant[i]; +} + +inline +bool +scfx_rep::q_bit( const scfx_index& x ) const +{ + int wi = x.wi(); + int bi = x.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + + if( bi != 0 ) + return ( m_mant[wi] & ( ((word)1) << ( bi - 1 ) ) ) != 0; + else if( wi != 0 ) + return ( m_mant[wi - 1] & ( ((word)1) << ( bits_in_word - 1 ) ) ) != 0; + else + return false; +} + +inline +void +scfx_rep::q_clear( const scfx_index& x ) +{ + int wi = x.wi(); + int bi = x.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + + m_mant[wi] &= ( ((word)-1) << bi ); + for( int i = wi - 1; i >= 0; -- i ) + m_mant[i] = 0; +} + +inline +void +scfx_rep::q_incr( const scfx_index& x ) +{ + int wi = x.wi(); + int bi = x.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + + word old_val = m_mant[wi]; + m_mant[wi] += ( ((word)1) << bi ); + if( m_mant[wi] <= old_val ) + { + if( wi + 1 == size() ) + resize_to( size() + 1, 1 ); + + for( int i = wi + 1; i < size(); ++ i ) + { + if( ++ m_mant[i] != 0 ) + break; + } + } +} + +inline +bool +scfx_rep::q_odd( const scfx_index& x ) const +{ + int wi = x.wi(); + int bi = x.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + + return ( m_mant[wi] & ( ((word)1) << bi ) ) != 0; +} + +inline +bool +scfx_rep::q_zero( const scfx_index& x ) const +{ + int wi = x.wi(); + int bi = x.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + + bool zero; + + if( bi != 0 ) + { + zero = ( m_mant[wi] & ~( ((word)-1) << (bi - 1) ) ) == 0; + for( int i = wi - 1; i >= 0; -- i ) + zero = zero && m_mant[i] == 0; + } + else if( wi != 0 ) + { + zero = ( m_mant[wi - 1] & ~( ((word)-1) << (bits_in_word - 1) ) ) == 0; + for( int i = wi - 2; i >= 0; -- i ) + zero = zero && m_mant[i] == 0; + } + else + zero = true; + + return zero; +} + +inline +int +scfx_rep::find_lsw() const +{ + for( int i = 0; i < size(); i ++ ) + { + if( m_mant[i] ) + return i; + } + return 0; +} + +inline +int +scfx_rep::find_msw() const +{ + for( int i = size() - 1; i >= 0; i -- ) + { + if( m_mant[i] ) + return i; + } + return 0; +} + +inline +void +scfx_rep::find_sw() +{ + m_lsw = find_lsw(); + m_msw = find_msw(); +} + +inline +void +scfx_rep::toggle_tc() +{ + if( is_neg() ) + { + complement( m_mant, m_mant, m_mant.size() ); + inc( m_mant ); + } +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_string.h b/ext/systemc/src/sysc/datatypes/fx/scfx_string.h new file mode 100644 index 000000000..338031ccc --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_string.h @@ -0,0 +1,232 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_string.h - + + Original Author: Robert Graulich, Synopsys, Inc. + Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ +// $Log: scfx_string.h,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.2 2006/01/03 23:18:34 acg +// Changed copyright to include 2006. +// +// Revision 1.1.1.1 2005/12/19 23:16:43 acg +// First check in of SystemC 2.1 into its own archive. +// +// Revision 1.9 2005/09/15 23:02:03 acg +// Added std:: prefix to appropriate methods and types to get around +// issues with the Edison Front End. +// +// Revision 1.8 2005/06/07 17:27:02 acg +// Fixed bug in scfx_string::operator += where an array reference was used +// rather than the [] operator. This meant that the buffer may have been +// accessed beyond its allocated storage. +// + +#ifndef SCFX_STRING_H +#define SCFX_STRING_H + +#include <cstdio> + + +namespace sc_dt +{ + +// classes defined in this module +class scfx_string; + + +// ---------------------------------------------------------------------------- +// CLASS : scfx_string +// +// Simple string class for internal use. +// ---------------------------------------------------------------------------- + +class scfx_string +{ + void resize( std::size_t ); + +public: + + scfx_string(); + + ~scfx_string(); + + int length() const; + + void clear(); + + char& operator [] ( int ); + + void append( int ); + void discard( int ); + void remove( int ); + + void operator += ( char ); + void operator += ( const char* ); + + operator const char* (); + +private: + + std::size_t m_len; + std::size_t m_alloc; + char* m_buffer; +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +inline +void +scfx_string::resize( std::size_t i ) +{ + do { + m_alloc *= 2; + } while( i >= m_alloc ); + + char* temp = new char[m_alloc]; + + for( int j = 0; j < (int) m_len; ++ j ) { + temp[j] = m_buffer[j]; + } + temp[m_len] = 0; + + delete [] m_buffer; + m_buffer = temp; +} + + +inline +scfx_string::scfx_string() +: m_len( 0 ), m_alloc( BUFSIZ ), m_buffer( new char[m_alloc] ) +{ + m_buffer[m_len] = 0; +} + + +inline +scfx_string::~scfx_string() +{ + delete [] m_buffer; +} + + +inline +int +scfx_string::length() const +{ + return m_len; +} + + +inline +void +scfx_string::clear() +{ + m_len = 0; + m_buffer[m_len] = 0; +} + + +inline +char& +scfx_string::operator [] ( int i ) +{ + if( i >= (int) m_alloc ) { + resize( i ); + } + return m_buffer[i]; +} + + +inline +void +scfx_string::append( int n ) +{ + m_len += n; + m_buffer[m_len] = 0; +} + +inline +void +scfx_string::discard( int n ) +{ + m_len -= n; + m_buffer[m_len] = 0; +} + +inline +void +scfx_string::remove( int i ) +{ + for( int j = i + 1; j < (int) m_len; ++ j ) + m_buffer[j - 1] = m_buffer[j]; + -- m_len; + m_buffer[m_len] = 0; +} + + +inline +void +scfx_string::operator += ( char c ) +{ + this->operator [] ( m_len ) = c; + m_len ++; + this->operator [] ( m_len ) = 0; +} + +inline +void +scfx_string::operator += ( const char* s ) +{ + while( *s ) + (*this) += *s ++; +} + + +inline +scfx_string::operator const char*() +{ + m_buffer[m_len] = 0; + return m_buffer; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_utils.cpp b/ext/systemc/src/sysc/datatypes/fx/scfx_utils.cpp new file mode 100644 index 000000000..0735a6c25 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_utils.cpp @@ -0,0 +1,176 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_utils.cpp - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: scfx_utils.cpp,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#include "sysc/datatypes/fx/scfx_utils.h" + + +namespace sc_dt +{ + +void +scfx_tc2csd( scfx_string& s, int w_prefix ) +{ + if( w_prefix != 0 ) { + SC_ASSERT_( s[0] == '0' && s[1] == 'c' && + s[2] == 's' && s[3] == 'd', "invalid prefix" ); + } + + scfx_string csd; + + // copy bits from 's' into 'csd'; skip prefix, point, and exponent + int i = 0; + int j = (w_prefix != 0 ? 4 : 0); + while( s[j] ) + { + if( s[j] == '0' || s[j] == '1' ) + csd[i ++] = s[j]; + else if( s[j] != '.' ) + break; + ++ j; + } + csd[i] = '\0'; + + // convert 'csd' from two's complement to csd + -- i; + while( i >= 0 ) + { + if( csd[i] == '0' ) + -- i; + else + { + if( i > 0 && csd[i - 1] == '0' ) + -- i; + else if( i == 0 ) + csd[i --] = '-'; + else + { // i > 0 && csd[i - 1] == '1' + csd[i --] = '-'; + while( i >= 0 && csd[i] == '1' ) + csd[i --] = '0'; + if( i > 0 ) + csd[i] = '1'; + else if( i == 0 ) + csd[i --] = '1'; + } + } + } + + // copy bits from 'csd' back into 's' + i = 0; + j = (w_prefix != 0 ? 4 : 0); + while( csd[i] ) + { + if( s[j] == '.' ) + ++ j; + s[j ++] = csd[i ++]; + } +} + + +void +scfx_csd2tc( scfx_string& csd ) +{ + SC_ASSERT_( csd[0] == '0' && csd[1] == 'c' && + csd[2] == 's' && csd[3] == 'd', "invalid prefix" ); + + scfx_string s; + + // copy bits from 'csd' into 's'; skip prefix, point, and exponent + int i = 0; + s[i ++] = '0'; + int j = 4; + while( csd[j] ) + { + if( csd[j] == '-' || csd[j] == '0' || csd[j] == '1' ) + s[i ++] = csd[j]; + else if( csd[j] != '.' ) + break; + ++ j; + } + s[i] = '\0'; + + // convert 's' from csd to two's complement + int len = i; + i = 1; + while( i < len ) + { + while( i < len && s[i] != '-' ) + i ++; + if( i < len ) + { + j = i ++; + s[j --] = '1'; + while( j >= 0 && s[j] == '0' ) + s[j --] = '1'; + if( j >= 0 ) + s[j] = '0'; + } + } + + // copy bits from 's' back into 'csd' + j = csd.length(); + csd[j + 1] = '\0'; + while( j > 4 ) + { + csd[j] = csd[j - 1]; + -- j; + } + + i = 0; + j = 4; + while( s[i] ) + { + if( csd[j] == '.' ) + ++ j; + csd[j ++] = s[i ++]; + } +} + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_utils.h b/ext/systemc/src/sysc/datatypes/fx/scfx_utils.h new file mode 100644 index 000000000..55fabe045 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_utils.h @@ -0,0 +1,534 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_utils.h - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: scfx_utils.h,v $ +// Revision 1.2 2009/02/28 00:26:20 acg +// Andy Goodrich: bug fixes. +// +// Revision 1.1.1.1 2006/12/15 20:31:36 acg +// SystemC 2.2 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SCFX_UTILS_H +#define SCFX_UTILS_H + + +#include "sysc/datatypes/fx/sc_fxdefs.h" +#include "sysc/datatypes/fx/scfx_params.h" +#include "sysc/datatypes/fx/scfx_string.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// Find the most and least significant non-zero bits in a unsigned long +// ---------------------------------------------------------------------------- + +#define MSB_STATEMENT(n) if( x >> n ) { x >>= n; i += n; } + +inline +int +scfx_find_msb( unsigned long x ) +{ + int i = 0; +# if defined(SC_LONG_64) + MSB_STATEMENT( 32 ); +# endif // defined(SC_LONG_64) + MSB_STATEMENT( 16 ); + MSB_STATEMENT( 8 ); + MSB_STATEMENT( 4 ); + MSB_STATEMENT( 2 ); + MSB_STATEMENT( 1 ); + return i; +} + +#undef MSB_STATEMENT + +#define LSB_STATEMENT(n) if( x << n ) { x <<= n; i -= n; } + +inline +int +scfx_find_lsb( unsigned long x ) +{ + int i; +# if defined(SC_LONG_64) + i = 63; + LSB_STATEMENT( 32 ); +# else + i = 31; +# endif // defined(SC_LONG_64) + LSB_STATEMENT( 16 ); + LSB_STATEMENT( 8 ); + LSB_STATEMENT( 4 ); + LSB_STATEMENT( 2 ); + LSB_STATEMENT( 1 ); + return i; +} + +#undef LSB_STATEMENT + + +// ---------------------------------------------------------------------------- +// Utilities for parsing a character string number +// ---------------------------------------------------------------------------- + +inline +int +scfx_parse_sign( const char*& s, bool& sign_char ) +{ + int sign = 1; + + if( *s == '+' ) + { + ++ s; + sign_char = true; + } + else if( *s == '-' ) + { + sign = -1; + ++ s; + sign_char = true; + } + else + sign_char = false; + + return sign; +} + +inline +sc_numrep +scfx_parse_prefix( const char*& s ) +{ + if( s[0] == '0' ) { + switch( s[1] ) + { + case 'b': + case 'B': + { + if( (s[2] == 'u' || s[2] == 'U') && (s[3] == 's' || s[3] == 'S') ) { + s += 4; + return SC_BIN_US; + } + if( (s[2] == 's' || s[2] == 'S') && (s[3] == 'm' || s[3] == 'M') ) { + s += 4; + return SC_BIN_SM; + } + s += 2; + return SC_BIN; + } + case 'o': + case 'O': + { + if( (s[2] == 'u' || s[2] == 'U') && (s[3] == 's' || s[3] == 'S') ) { + s += 4; + return SC_OCT_US; + } + if( (s[2] == 's' || s[2] == 'S') && (s[3] == 'm' || s[3] == 'M') ) { + s += 4; + return SC_OCT_SM; + } + s += 2; + return SC_OCT; + } + case 'x': + case 'X': + { + if( (s[2] == 'u' || s[2] == 'U') && (s[3] == 's' || s[3] == 'S') ) { + s += 4; + return SC_HEX_US; + } + if( (s[2] == 's' || s[2] == 'S') && (s[3] == 'm' || s[3] == 'M') ) { + s += 4; + return SC_HEX_SM; + } + s += 2; + return SC_HEX; + } + case 'd': + case 'D': + { + s += 2; + return SC_DEC; + } + case 'c': + case 'C': + { + if( (s[2] == 's' || s[2] == 'S') && (s[3] == 'd' || s[3] == 'D') ) { + s += 4; + return SC_CSD; + } + break; + } + default: + break; + } + } + + return SC_DEC; +} + + +inline +int +scfx_parse_base( const char*& s ) +{ + const char* s1 = s + 1; + + int base = 10; + + if( *s == '0' ) + { + switch( *s1 ) + { + case 'b': + case 'B': base = 2; s += 2; break; + case 'o': + case 'O': base = 8; s += 2; break; + case 'd': + case 'D': base = 10; s += 2; break; + case 'x': + case 'X': base = 16; s += 2; break; + } + } + + return base; +} + +inline +bool +scfx_is_equal( const char* a, const char* b ) +{ + while( *a != 0 && *b != 0 && *a == *b ) + { + ++ a; + ++ b; + } + return ( *a == 0 && *b == 0 ); +} + +inline +bool +scfx_is_nan( const char* s ) +{ + return scfx_is_equal( s, "NaN" ); +} + +inline +bool +scfx_is_inf( const char* s ) +{ + return ( scfx_is_equal( s, "Inf" ) || scfx_is_equal( s, "Infinity" ) ); +} + +inline +bool +scfx_exp_start( const char* s ) +{ + if( *s == 'e' || *s == 'E' ) + { + ++ s; + if( *s == '+' || *s == '-' ) + return true; + } + return false; +} + +inline +bool +scfx_is_digit( char c, sc_numrep numrep ) +{ + bool is_digit; + + switch( numrep ) + { + case SC_DEC: + { + switch( c ) + { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + { + is_digit = true; + break; + } + default: + is_digit = false; + } + break; + } + case SC_BIN: + case SC_BIN_US: + case SC_BIN_SM: + { + switch( c ) + { + case '0': case '1': + { + is_digit = true; + break; + } + default: + is_digit = false; + } + break; + } + case SC_OCT: + case SC_OCT_US: + case SC_OCT_SM: + { + switch( c ) + { + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + { + is_digit = true; + break; + } + default: + is_digit = false; + } + break; + } + case SC_HEX: + case SC_HEX_US: + case SC_HEX_SM: + { + switch( c ) + { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + { + is_digit = true; + break; + } + default: + is_digit = false; + } + break; + } + case SC_CSD: + { + switch( c ) + { + case '0': case '1': case '-': + { + is_digit = true; + break; + } + default: + is_digit = false; + } + break; + } + default: + is_digit = false; + } + + return is_digit; +} + +inline +int +scfx_to_digit( char c, sc_numrep numrep ) +{ + int to_digit; + + switch( numrep ) + { + case SC_DEC: + case SC_BIN: + case SC_BIN_US: + case SC_BIN_SM: + case SC_OCT: + case SC_OCT_US: + case SC_OCT_SM: + { + to_digit = c - '0'; + break; + } + case SC_HEX: + case SC_HEX_US: + case SC_HEX_SM: + { + switch( c ) + { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + to_digit = c - '0'; + break; + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + to_digit = c - 'a' + 10; + break; + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + to_digit = c - 'A' + 10; + break; + default: + to_digit = -2; + } + break; + } + case SC_CSD: + { + if( c == '-' ) + to_digit = -1; + else + to_digit = c - '0'; + break; + } + default: + to_digit = -2; + } + + return to_digit; +} + + +// ---------------------------------------------------------------------------- +// Utilities for printing a character string number +// ---------------------------------------------------------------------------- + +inline +void +scfx_print_nan( scfx_string& s ) +{ + s += "NaN"; +} + +inline +void +scfx_print_inf( scfx_string& s, bool negative ) +{ + if( negative ) + s += "-Inf"; + else + s += "Inf"; +} + +inline +void +scfx_print_prefix( scfx_string& s, sc_numrep numrep ) +{ + switch( numrep ) + { + case SC_DEC: + s += "0d"; + break; + case SC_BIN: + s += "0b"; + break; + case SC_BIN_US: + s += "0bus"; + break; + case SC_BIN_SM: + s += "0bsm"; + break; + case SC_OCT: + s += "0o"; + break; + case SC_OCT_US: + s += "0ous"; + break; + case SC_OCT_SM: + s += "0osm"; + break; + case SC_HEX: + s += "0x"; + break; + case SC_HEX_US: + s += "0xus"; + break; + case SC_HEX_SM: + s += "0xsm"; + break; + case SC_CSD: + s += "0csd"; + break; + default: + s += "unknown"; + } +} + +inline +void +scfx_print_exp( scfx_string& s, int exp ) +{ + if( exp != 0 ) + { + s += 'e'; + + if( exp < 0 ) + { + exp = - exp; + s += '-'; + } + else + s += '+'; + + bool first = true; + int scale = 1000000000; + do + { + int digit = exp / scale; + exp = exp % scale; + if( digit != 0 || ! first ) + { + s += static_cast<char>( digit + '0' ); + first = false; + } + scale /= 10; + } + while( scale > 0 ); + } +} + + +void scfx_tc2csd( scfx_string&, int ); +void scfx_csd2tc( scfx_string& ); + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/int/sc_bigint.h b/ext/systemc/src/sysc/datatypes/int/sc_bigint.h new file mode 100644 index 000000000..d5445fc84 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_bigint.h @@ -0,0 +1,271 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_bigint.h -- Template version of sc_signed. This class enables + compile-time bit widths for sc_signed numbers. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: Gene Bushayev, Synopsys, Inc. + Description of Modification: - Interface between sc_bigint and sc_bv/sc_lv. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_bigint.h,v $ +// Revision 1.2 2011/02/18 20:19:14 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:31 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef SC_BIGINT_H +#define SC_BIGINT_H + + +#include "sysc/datatypes/int/sc_signed.h" +#include "sysc/datatypes/int/sc_unsigned.h" + +namespace sc_dt +{ + +// classes defined in this module +template <int W> class sc_bigint; + +// forward class declarations +class sc_bv_base; +class sc_lv_base; +class sc_fxval; +class sc_fxval_fast; +class sc_fxnum; +class sc_fxnum_fast; + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_bigint<W> +// +// Arbitrary size signed integer type. +// ---------------------------------------------------------------------------- + +#ifdef SC_MAX_NBITS +template< int W = SC_MAX_NBITS > +#else +template< int W > +#endif +class sc_bigint + : public sc_signed +{ +public: + + // constructors + + sc_bigint() + : sc_signed( W ) + {} + + sc_bigint( const sc_bigint<W>& v ) + : sc_signed( W ) + { *this = v; } + + sc_bigint( const sc_signed& v ) + : sc_signed( W ) + { *this = v; } + + sc_bigint( const sc_signed_subref& v ) + : sc_signed( W ) + { *this = v; } + + template< class T > + sc_bigint( const sc_generic_base<T>& a ) + : sc_signed( W ) + { a->to_sc_signed(*this); } + + sc_bigint( const sc_unsigned& v ) + : sc_signed( W ) + { *this = v; } + + sc_bigint( const sc_unsigned_subref& v ) + : sc_signed( W ) + { *this = v; } + + sc_bigint( const char* v ) + : sc_signed( W ) + { *this = v; } + + sc_bigint( int64 v ) + : sc_signed( W ) + { *this = v; } + + sc_bigint( uint64 v ) + : sc_signed( W ) + { *this = v; } + + sc_bigint( long v ) + : sc_signed( W ) + { *this = v; } + + sc_bigint( unsigned long v ) + : sc_signed( W ) + { *this = v; } + + sc_bigint( int v ) + : sc_signed( W ) + { *this = v; } + + sc_bigint( unsigned int v ) + : sc_signed( W ) + { *this = v; } + + sc_bigint( double v ) + : sc_signed( W ) + { *this = v; } + + sc_bigint( const sc_bv_base& v ) + : sc_signed( W ) + { *this = v; } + + sc_bigint( const sc_lv_base& v ) + : sc_signed( W ) + { *this = v; } + +#ifdef SC_INCLUDE_FX + + explicit sc_bigint( const sc_fxval& v ) + : sc_signed( W ) + { *this = v; } + + explicit sc_bigint( const sc_fxval_fast& v ) + : sc_signed( W ) + { *this = v; } + + explicit sc_bigint( const sc_fxnum& v ) + : sc_signed( W ) + { *this = v; } + + explicit sc_bigint( const sc_fxnum_fast& v ) + : sc_signed( W ) + { *this = v; } + +#endif + + +#ifndef SC_MAX_NBITS + + // destructor + + ~sc_bigint() + {} + +#endif + + // assignment operators + + sc_bigint<W>& operator = ( const sc_bigint<W>& v ) + { sc_signed::operator = ( v ); return *this; } + + sc_bigint<W>& operator = ( const sc_signed& v ) + { sc_signed::operator = ( v ); return *this; } + + sc_bigint<W>& operator = (const sc_signed_subref& v ) + { sc_signed::operator = ( v ); return *this; } + + template< class T > + sc_bigint<W>& operator = ( const sc_generic_base<T>& a ) + { a->to_sc_signed(*this); return *this;} + + sc_bigint<W>& operator = ( const sc_unsigned& v ) + { sc_signed::operator = ( v ); return *this; } + + sc_bigint<W>& operator = ( const sc_unsigned_subref& v ) + { sc_signed::operator = ( v ); return *this; } + + sc_bigint<W>& operator = ( const char* v ) + { sc_signed::operator = ( v ); return *this; } + + sc_bigint<W>& operator = ( int64 v ) + { sc_signed::operator = ( v ); return *this; } + + sc_bigint<W>& operator = ( uint64 v ) + { sc_signed::operator = ( v ); return *this; } + + sc_bigint<W>& operator = ( long v ) + { sc_signed::operator = ( v ); return *this; } + + sc_bigint<W>& operator = ( unsigned long v ) + { sc_signed::operator = ( v ); return *this; } + + sc_bigint<W>& operator = ( int v ) + { sc_signed::operator = ( v ); return *this; } + + sc_bigint<W>& operator = ( unsigned int v ) + { sc_signed::operator = ( v ); return *this; } + + sc_bigint<W>& operator = ( double v ) + { sc_signed::operator = ( v ); return *this; } + + + sc_bigint<W>& operator = ( const sc_bv_base& v ) + { sc_signed::operator = ( v ); return *this; } + + sc_bigint<W>& operator = ( const sc_lv_base& v ) + { sc_signed::operator = ( v ); return *this; } + + sc_bigint<W>& operator = ( const sc_int_base& v ) + { sc_signed::operator = ( v ); return *this; } + + sc_bigint<W>& operator = ( const sc_uint_base& v ) + { sc_signed::operator = ( v ); return *this; } + +#ifdef SC_INCLUDE_FX + + sc_bigint<W>& operator = ( const sc_fxval& v ) + { sc_signed::operator = ( v ); return *this; } + + sc_bigint<W>& operator = ( const sc_fxval_fast& v ) + { sc_signed::operator = ( v ); return *this; } + + sc_bigint<W>& operator = ( const sc_fxnum& v ) + { sc_signed::operator = ( v ); return *this; } + + sc_bigint<W>& operator = ( const sc_fxnum_fast& v ) + { sc_signed::operator = ( v ); return *this; } + +#endif +}; + +} // namespace sc_dt + + +#endif diff --git a/ext/systemc/src/sysc/datatypes/int/sc_biguint.h b/ext/systemc/src/sysc/datatypes/int/sc_biguint.h new file mode 100644 index 000000000..689f41e63 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_biguint.h @@ -0,0 +1,272 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_biguint.h -- Template version of sc_unsigned. This class + enables compile-time bit widths for sc_unsigned numbers. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: Gene Bushayev, Synopsys, Inc. + Description of Modification: - Interface between sc_bigint and sc_bv/sc_lv. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_biguint.h,v $ +// Revision 1.2 2011/02/18 20:19:14 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:31 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef SC_BIGUINT_H +#define SC_BIGUINT_H + + +#include "sysc/datatypes/int/sc_signed.h" +#include "sysc/datatypes/int/sc_unsigned.h" + +namespace sc_dt +{ + +// classes defined in this module +template <int W> class sc_biguint; + +// forward class declarations +class sc_bv_base; +class sc_lv_base; +class sc_fxval; +class sc_fxval_fast; +class sc_fxnum; +class sc_fxnum_fast; + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_biguint<W> +// +// Arbitrary size unsigned integer type. +// ---------------------------------------------------------------------------- + +#ifdef SC_MAX_NBITS +template< int W = SC_MAX_NBITS > +#else +template< int W > +#endif +class sc_biguint + : public sc_unsigned +{ +public: + + // constructors + + sc_biguint() + : sc_unsigned( W ) + {} + + sc_biguint( const sc_biguint<W>& v ) + : sc_unsigned( W ) + { *this = v; } + + sc_biguint( const sc_unsigned& v ) + : sc_unsigned( W ) + { *this = v; } + + sc_biguint( const sc_unsigned_subref& v ) + : sc_unsigned( W ) + { *this = v; } + + template< class T > + sc_biguint( const sc_generic_base<T>& a ) + : sc_unsigned( W ) + { a->to_sc_unsigned(*this); } + + sc_biguint( const sc_signed& v ) + : sc_unsigned( W ) + { *this = v; } + + sc_biguint( const sc_signed_subref& v ) + : sc_unsigned( W ) + { *this = v; } + + sc_biguint( const char* v ) + : sc_unsigned( W ) + { *this = v; } + + sc_biguint( int64 v ) + : sc_unsigned( W ) + { *this = v; } + + sc_biguint( uint64 v ) + : sc_unsigned( W ) + { *this = v; } + + sc_biguint( long v ) + : sc_unsigned( W ) + { *this = v; } + + sc_biguint( unsigned long v ) + : sc_unsigned( W ) + { *this = v; } + + sc_biguint( int v ) + : sc_unsigned( W ) + { *this = v; } + + sc_biguint( unsigned int v ) + : sc_unsigned( W ) + { *this = v; } + + sc_biguint( double v ) + : sc_unsigned( W ) + { *this = v; } + + sc_biguint( const sc_bv_base& v ) + : sc_unsigned( W ) + { *this = v; } + + sc_biguint( const sc_lv_base& v ) + : sc_unsigned( W ) + { *this = v; } + +#ifdef SC_INCLUDE_FX + + explicit sc_biguint( const sc_fxval& v ) + : sc_unsigned( W ) + { *this = v; } + + explicit sc_biguint( const sc_fxval_fast& v ) + : sc_unsigned( W ) + { *this = v; } + + explicit sc_biguint( const sc_fxnum& v ) + : sc_unsigned( W ) + { *this = v; } + + explicit sc_biguint( const sc_fxnum_fast& v ) + : sc_unsigned( W ) + { *this = v; } + +#endif + + +#ifndef SC_MAX_NBITS + + // destructor + + ~sc_biguint() + {} + +#endif + + + // assignment operators + + sc_biguint<W>& operator = ( const sc_biguint<W>& v ) + { sc_unsigned::operator = ( v ); return *this; } + + sc_biguint<W>& operator = ( const sc_unsigned& v ) + { sc_unsigned::operator = ( v ); return *this; } + + sc_biguint<W>& operator = ( const sc_unsigned_subref& v ) + { sc_unsigned::operator = ( v ); return *this; } + + template< class T > + sc_biguint<W>& operator = ( const sc_generic_base<T>& a ) + { a->to_sc_unsigned(*this); return *this; } + + sc_biguint<W>& operator = ( const sc_signed& v ) + { sc_unsigned::operator = ( v ); return *this; } + + sc_biguint<W>& operator = ( const sc_signed_subref& v ) + { sc_unsigned::operator = ( v ); return *this; } + + sc_biguint<W>& operator = ( const char* v ) + { sc_unsigned::operator = ( v ); return *this; } + + sc_biguint<W>& operator = ( int64 v ) + { sc_unsigned::operator = ( v ); return *this; } + + sc_biguint<W>& operator = ( uint64 v ) + { sc_unsigned::operator = ( v ); return *this; } + + sc_biguint<W>& operator = ( long v ) + { sc_unsigned::operator = ( v ); return *this; } + + sc_biguint<W>& operator = ( unsigned long v ) + { sc_unsigned::operator = ( v ); return *this; } + + sc_biguint<W>& operator = ( int v ) + { sc_unsigned::operator = ( v ); return *this; } + + sc_biguint<W>& operator = ( unsigned int v ) + { sc_unsigned::operator = ( v ); return *this; } + + sc_biguint<W>& operator = ( double v ) + { sc_unsigned::operator = ( v ); return *this; } + + + sc_biguint<W>& operator = ( const sc_bv_base& v ) + { sc_unsigned::operator = ( v ); return *this; } + + sc_biguint<W>& operator = ( const sc_lv_base& v ) + { sc_unsigned::operator = ( v ); return *this; } + + sc_biguint<W>& operator = ( const sc_int_base& v ) + { sc_unsigned::operator = ( v ); return *this; } + + sc_biguint<W>& operator = ( const sc_uint_base& v ) + { sc_unsigned::operator = ( v ); return *this; } + +#ifdef SC_INCLUDE_FX + + sc_biguint<W>& operator = ( const sc_fxval& v ) + { sc_unsigned::operator = ( v ); return *this; } + + sc_biguint<W>& operator = ( const sc_fxval_fast& v ) + { sc_unsigned::operator = ( v ); return *this; } + + sc_biguint<W>& operator = ( const sc_fxnum& v ) + { sc_unsigned::operator = ( v ); return *this; } + + sc_biguint<W>& operator = ( const sc_fxnum_fast& v ) + { sc_unsigned::operator = ( v ); return *this; } + +#endif +}; + +} // namespace sc_dt + + +#endif diff --git a/ext/systemc/src/sysc/datatypes/int/sc_int.h b/ext/systemc/src/sysc/datatypes/int/sc_int.h new file mode 100644 index 000000000..adcb6b321 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_int.h @@ -0,0 +1,312 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_int.h -- A sc_int is a signed integer whose length is less than the + machine's native integer length. We provide two implementations + (i) sc_int with length between 1 - 64, and (ii) sc_int with + length between 1 - 32. Implementation (i) is the default + implementation, while implementation (ii) can be used only if + the class library is compiled with -D_32BIT_. Unlike arbitrary + precision, arithmetic and bitwise operations are performed + using the native types (hence capped at 32/64 bits). The sc_int + integer is useful when the user does not need arbitrary + precision and the performance is superior to + sc_bigint/sc_biguint. + + Original Author: Amit Rao, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc. + Description of Modification: - Resolved ambiguity with sc_(un)signed. + - Merged the code for 64- and 32-bit versions + via the constants in sc_nbdefs.h. + - Eliminated redundant file inclusions. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_int.h,v $ +// Revision 1.2 2011/02/18 20:19:14 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:31 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef SC_INT_H +#define SC_INT_H + + +#include "sysc/datatypes/int/sc_int_base.h" + + +namespace sc_dt +{ + +// classes defined in this module +template <int W> class sc_int; + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_int<W> +// +// Template class sc_int<W> is the interface that the user sees. It is +// derived from sc_int_base and most of its methods are just wrappers +// that call the corresponding method in the parent class. Note that +// the length of sc_int datatype is specified as a template parameter. +// ---------------------------------------------------------------------------- + +template <int W> +class sc_int + : public sc_int_base +{ +public: + + // constructors + + sc_int() + : sc_int_base( W ) + {} + + sc_int( int_type v ) + : sc_int_base( v, W ) + {} + + sc_int( const sc_int<W>& a ) + : sc_int_base( a ) + {} + + sc_int( const sc_int_base& a ) + : sc_int_base( W ) + { sc_int_base::operator = ( a ); } + + sc_int( const sc_int_subref_r& a ) + : sc_int_base( W ) + { sc_int_base::operator = ( a ); } + + template< class T > + sc_int( const sc_generic_base<T>& a ) + : sc_int_base( W ) + { sc_int_base::operator = ( a->to_int64() ); } + + sc_int( const sc_signed& a ) + : sc_int_base( W ) + { sc_int_base::operator = ( a ); } + + sc_int( const sc_unsigned& a ) + : sc_int_base( W ) + { sc_int_base::operator = ( a ); } + +#ifdef SC_INCLUDE_FX + + explicit sc_int( const sc_fxval& a ) + : sc_int_base( W ) + { sc_int_base::operator = ( a ); } + + explicit sc_int( const sc_fxval_fast& a ) + : sc_int_base( W ) + { sc_int_base::operator = ( a ); } + + explicit sc_int( const sc_fxnum& a ) + : sc_int_base( W ) + { sc_int_base::operator = ( a ); } + + explicit sc_int( const sc_fxnum_fast& a ) + : sc_int_base( W ) + { sc_int_base::operator = ( a ); } + +#endif + + sc_int( const sc_bv_base& a ) + : sc_int_base( W ) + { sc_int_base::operator = ( a ); } + + sc_int( const sc_lv_base& a ) + : sc_int_base( W ) + { sc_int_base::operator = ( a ); } + + sc_int( const char* a ) + : sc_int_base( W ) + { sc_int_base::operator = ( a ); } + + sc_int( unsigned long a ) + : sc_int_base( W ) + { sc_int_base::operator = ( a ); } + + sc_int( long a ) + : sc_int_base( W ) + { sc_int_base::operator = ( a ); } + + sc_int( unsigned int a ) + : sc_int_base( W ) + { sc_int_base::operator = ( a ); } + + sc_int( int a ) + : sc_int_base( W ) + { sc_int_base::operator = ( a ); } + + sc_int( uint64 a ) + : sc_int_base( W ) + { sc_int_base::operator = ( a ); } + + sc_int( double a ) + : sc_int_base( W ) + { sc_int_base::operator = ( a ); } + + + // assignment operators + + sc_int<W>& operator = ( int_type v ) + { sc_int_base::operator = ( v ); return *this; } + + sc_int<W>& operator = ( const sc_int_base& a ) + { sc_int_base::operator = ( a ); return *this; } + + sc_int<W>& operator = ( const sc_int_subref_r& a ) + { sc_int_base::operator = ( a ); return *this; } + + sc_int<W>& operator = ( const sc_int<W>& a ) + { m_val = a.m_val; return *this; } + + template< class T > + sc_int<W>& operator = ( const sc_generic_base<T>& a ) + { sc_int_base::operator = ( a->to_int64() ); return *this; } + + sc_int<W>& operator = ( const sc_signed& a ) + { sc_int_base::operator = ( a ); return *this; } + + sc_int<W>& operator = ( const sc_unsigned& a ) + { sc_int_base::operator = ( a ); return *this; } + +#ifdef SC_INCLUDE_FX + + sc_int<W>& operator = ( const sc_fxval& a ) + { sc_int_base::operator = ( a ); return *this; } + + sc_int<W>& operator = ( const sc_fxval_fast& a ) + { sc_int_base::operator = ( a ); return *this; } + + sc_int<W>& operator = ( const sc_fxnum& a ) + { sc_int_base::operator = ( a ); return *this; } + + sc_int<W>& operator = ( const sc_fxnum_fast& a ) + { sc_int_base::operator = ( a ); return *this; } + +#endif + + sc_int<W>& operator = ( const sc_bv_base& a ) + { sc_int_base::operator = ( a ); return *this; } + + sc_int<W>& operator = ( const sc_lv_base& a ) + { sc_int_base::operator = ( a ); return *this; } + + sc_int<W>& operator = ( const char* a ) + { sc_int_base::operator = ( a ); return *this; } + + sc_int<W>& operator = ( unsigned long a ) + { sc_int_base::operator = ( a ); return *this; } + + sc_int<W>& operator = ( long a ) + { sc_int_base::operator = ( a ); return *this; } + + sc_int<W>& operator = ( unsigned int a ) + { sc_int_base::operator = ( a ); return *this; } + + sc_int<W>& operator = ( int a ) + { sc_int_base::operator = ( a ); return *this; } + + sc_int<W>& operator = ( uint64 a ) + { sc_int_base::operator = ( a ); return *this; } + + sc_int<W>& operator = ( double a ) + { sc_int_base::operator = ( a ); return *this; } + + + // arithmetic assignment operators + + sc_int<W>& operator += ( int_type v ) + { sc_int_base::operator += ( v ); return *this; } + + sc_int<W>& operator -= ( int_type v ) + { sc_int_base::operator -= ( v ); return *this; } + + sc_int<W>& operator *= ( int_type v ) + { sc_int_base::operator *= ( v ); return *this; } + + sc_int<W>& operator /= ( int_type v ) + { sc_int_base::operator /= ( v ); return *this; } + + sc_int<W>& operator %= ( int_type v ) + { sc_int_base::operator %= ( v ); return *this; } + + + // bitwise assignment operators + + sc_int<W>& operator &= ( int_type v ) + { sc_int_base::operator &= ( v ); return *this; } + + sc_int<W>& operator |= ( int_type v ) + { sc_int_base::operator |= ( v ); return *this; } + + sc_int<W>& operator ^= ( int_type v ) + { sc_int_base::operator ^= ( v ); return *this; } + + + sc_int<W>& operator <<= ( int_type v ) + { sc_int_base::operator <<= ( v ); return *this; } + + sc_int<W>& operator >>= ( int_type v ) + { sc_int_base::operator >>= ( v ); return *this; } + + + // prefix and postfix increment and decrement operators + + sc_int<W>& operator ++ () // prefix + { sc_int_base::operator ++ (); return *this; } + + const sc_int<W> operator ++ ( int ) // postfix + { return sc_int<W>( sc_int_base::operator ++ ( 0 ) ); } + + sc_int<W>& operator -- () // prefix + { sc_int_base::operator -- (); return *this; } + + const sc_int<W> operator -- ( int ) // postfix + { return sc_int<W>( sc_int_base::operator -- ( 0 ) ); } +}; + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/int/sc_int32_mask.cpp b/ext/systemc/src/sysc/datatypes/int/sc_int32_mask.cpp new file mode 100644 index 000000000..5e55dfb87 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_int32_mask.cpp @@ -0,0 +1,665 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_int32_mask.cpp -- Fills the mask_int lookup table to enable efficient + part-selection on 32-bit sc_ints and sc_uints. + + Original Author: Amit Rao, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc. + Description of Modification: - Resolved ambiguity with sc_(un)signed. + - Merged the code for 64- and 32-bit versions + via the constants in sc_nbdefs.h. + - Eliminated redundant file inclusions. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_int32_mask.cpp,v $ +// Revision 1.2 2011/02/18 20:19:14 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:31 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifdef _32BIT_ + +#include "sysc/datatypes/int/sc_int_base.h" +#include "sysc/datatypes/int/sc_uint_base.h" + + +namespace sc_dt +{ + +const uint_type mask_int[SC_INTWIDTH][SC_INTWIDTH] = +{ +{ +0xfffffffeU +}, +{ +0xfffffffcU, +0xfffffffdU +}, +{ +0xfffffff8U, +0xfffffff9U, +0xfffffffbU +}, +{ +0xfffffff0U, +0xfffffff1U, +0xfffffff3U, +0xfffffff7U +}, +{ +0xffffffe0U, +0xffffffe1U, +0xffffffe3U, +0xffffffe7U, +0xffffffefU +}, +{ +0xffffffc0U, +0xffffffc1U, +0xffffffc3U, +0xffffffc7U, +0xffffffcfU, +0xffffffdfU +}, +{ +0xffffff80U, +0xffffff81U, +0xffffff83U, +0xffffff87U, +0xffffff8fU, +0xffffff9fU, +0xffffffbfU +}, +{ +0xffffff00U, +0xffffff01U, +0xffffff03U, +0xffffff07U, +0xffffff0fU, +0xffffff1fU, +0xffffff3fU, +0xffffff7fU +}, +{ +0xfffffe00U, +0xfffffe01U, +0xfffffe03U, +0xfffffe07U, +0xfffffe0fU, +0xfffffe1fU, +0xfffffe3fU, +0xfffffe7fU, +0xfffffeffU +}, +{ +0xfffffc00U, +0xfffffc01U, +0xfffffc03U, +0xfffffc07U, +0xfffffc0fU, +0xfffffc1fU, +0xfffffc3fU, +0xfffffc7fU, +0xfffffcffU, +0xfffffdffU +}, +{ +0xfffff800U, +0xfffff801U, +0xfffff803U, +0xfffff807U, +0xfffff80fU, +0xfffff81fU, +0xfffff83fU, +0xfffff87fU, +0xfffff8ffU, +0xfffff9ffU, +0xfffffbffU +}, +{ +0xfffff000U, +0xfffff001U, +0xfffff003U, +0xfffff007U, +0xfffff00fU, +0xfffff01fU, +0xfffff03fU, +0xfffff07fU, +0xfffff0ffU, +0xfffff1ffU, +0xfffff3ffU, +0xfffff7ffU +}, +{ +0xffffe000U, +0xffffe001U, +0xffffe003U, +0xffffe007U, +0xffffe00fU, +0xffffe01fU, +0xffffe03fU, +0xffffe07fU, +0xffffe0ffU, +0xffffe1ffU, +0xffffe3ffU, +0xffffe7ffU, +0xffffefffU +}, +{ +0xffffc000U, +0xffffc001U, +0xffffc003U, +0xffffc007U, +0xffffc00fU, +0xffffc01fU, +0xffffc03fU, +0xffffc07fU, +0xffffc0ffU, +0xffffc1ffU, +0xffffc3ffU, +0xffffc7ffU, +0xffffcfffU, +0xffffdfffU +}, +{ +0xffff8000U, +0xffff8001U, +0xffff8003U, +0xffff8007U, +0xffff800fU, +0xffff801fU, +0xffff803fU, +0xffff807fU, +0xffff80ffU, +0xffff81ffU, +0xffff83ffU, +0xffff87ffU, +0xffff8fffU, +0xffff9fffU, +0xffffbfffU +}, +{ +0xffff0000U, +0xffff0001U, +0xffff0003U, +0xffff0007U, +0xffff000fU, +0xffff001fU, +0xffff003fU, +0xffff007fU, +0xffff00ffU, +0xffff01ffU, +0xffff03ffU, +0xffff07ffU, +0xffff0fffU, +0xffff1fffU, +0xffff3fffU, +0xffff7fffU +}, +{ +0xfffe0000U, +0xfffe0001U, +0xfffe0003U, +0xfffe0007U, +0xfffe000fU, +0xfffe001fU, +0xfffe003fU, +0xfffe007fU, +0xfffe00ffU, +0xfffe01ffU, +0xfffe03ffU, +0xfffe07ffU, +0xfffe0fffU, +0xfffe1fffU, +0xfffe3fffU, +0xfffe7fffU, +0xfffeffffU +}, +{ +0xfffc0000U, +0xfffc0001U, +0xfffc0003U, +0xfffc0007U, +0xfffc000fU, +0xfffc001fU, +0xfffc003fU, +0xfffc007fU, +0xfffc00ffU, +0xfffc01ffU, +0xfffc03ffU, +0xfffc07ffU, +0xfffc0fffU, +0xfffc1fffU, +0xfffc3fffU, +0xfffc7fffU, +0xfffcffffU, +0xfffdffffU +}, +{ +0xfff80000U, +0xfff80001U, +0xfff80003U, +0xfff80007U, +0xfff8000fU, +0xfff8001fU, +0xfff8003fU, +0xfff8007fU, +0xfff800ffU, +0xfff801ffU, +0xfff803ffU, +0xfff807ffU, +0xfff80fffU, +0xfff81fffU, +0xfff83fffU, +0xfff87fffU, +0xfff8ffffU, +0xfff9ffffU, +0xfffbffffU +}, +{ +0xfff00000U, +0xfff00001U, +0xfff00003U, +0xfff00007U, +0xfff0000fU, +0xfff0001fU, +0xfff0003fU, +0xfff0007fU, +0xfff000ffU, +0xfff001ffU, +0xfff003ffU, +0xfff007ffU, +0xfff00fffU, +0xfff01fffU, +0xfff03fffU, +0xfff07fffU, +0xfff0ffffU, +0xfff1ffffU, +0xfff3ffffU, +0xfff7ffffU +}, +{ +0xffe00000U, +0xffe00001U, +0xffe00003U, +0xffe00007U, +0xffe0000fU, +0xffe0001fU, +0xffe0003fU, +0xffe0007fU, +0xffe000ffU, +0xffe001ffU, +0xffe003ffU, +0xffe007ffU, +0xffe00fffU, +0xffe01fffU, +0xffe03fffU, +0xffe07fffU, +0xffe0ffffU, +0xffe1ffffU, +0xffe3ffffU, +0xffe7ffffU, +0xffefffffU +}, +{ +0xffc00000U, +0xffc00001U, +0xffc00003U, +0xffc00007U, +0xffc0000fU, +0xffc0001fU, +0xffc0003fU, +0xffc0007fU, +0xffc000ffU, +0xffc001ffU, +0xffc003ffU, +0xffc007ffU, +0xffc00fffU, +0xffc01fffU, +0xffc03fffU, +0xffc07fffU, +0xffc0ffffU, +0xffc1ffffU, +0xffc3ffffU, +0xffc7ffffU, +0xffcfffffU, +0xffdfffffU +}, +{ +0xff800000U, +0xff800001U, +0xff800003U, +0xff800007U, +0xff80000fU, +0xff80001fU, +0xff80003fU, +0xff80007fU, +0xff8000ffU, +0xff8001ffU, +0xff8003ffU, +0xff8007ffU, +0xff800fffU, +0xff801fffU, +0xff803fffU, +0xff807fffU, +0xff80ffffU, +0xff81ffffU, +0xff83ffffU, +0xff87ffffU, +0xff8fffffU, +0xff9fffffU, +0xffbfffffU +}, +{ +0xff000000U, +0xff000001U, +0xff000003U, +0xff000007U, +0xff00000fU, +0xff00001fU, +0xff00003fU, +0xff00007fU, +0xff0000ffU, +0xff0001ffU, +0xff0003ffU, +0xff0007ffU, +0xff000fffU, +0xff001fffU, +0xff003fffU, +0xff007fffU, +0xff00ffffU, +0xff01ffffU, +0xff03ffffU, +0xff07ffffU, +0xff0fffffU, +0xff1fffffU, +0xff3fffffU, +0xff7fffffU +}, +{ +0xfe000000U, +0xfe000001U, +0xfe000003U, +0xfe000007U, +0xfe00000fU, +0xfe00001fU, +0xfe00003fU, +0xfe00007fU, +0xfe0000ffU, +0xfe0001ffU, +0xfe0003ffU, +0xfe0007ffU, +0xfe000fffU, +0xfe001fffU, +0xfe003fffU, +0xfe007fffU, +0xfe00ffffU, +0xfe01ffffU, +0xfe03ffffU, +0xfe07ffffU, +0xfe0fffffU, +0xfe1fffffU, +0xfe3fffffU, +0xfe7fffffU, +0xfeffffffU +}, +{ +0xfc000000U, +0xfc000001U, +0xfc000003U, +0xfc000007U, +0xfc00000fU, +0xfc00001fU, +0xfc00003fU, +0xfc00007fU, +0xfc0000ffU, +0xfc0001ffU, +0xfc0003ffU, +0xfc0007ffU, +0xfc000fffU, +0xfc001fffU, +0xfc003fffU, +0xfc007fffU, +0xfc00ffffU, +0xfc01ffffU, +0xfc03ffffU, +0xfc07ffffU, +0xfc0fffffU, +0xfc1fffffU, +0xfc3fffffU, +0xfc7fffffU, +0xfcffffffU, +0xfdffffffU +}, +{ +0xf8000000U, +0xf8000001U, +0xf8000003U, +0xf8000007U, +0xf800000fU, +0xf800001fU, +0xf800003fU, +0xf800007fU, +0xf80000ffU, +0xf80001ffU, +0xf80003ffU, +0xf80007ffU, +0xf8000fffU, +0xf8001fffU, +0xf8003fffU, +0xf8007fffU, +0xf800ffffU, +0xf801ffffU, +0xf803ffffU, +0xf807ffffU, +0xf80fffffU, +0xf81fffffU, +0xf83fffffU, +0xf87fffffU, +0xf8ffffffU, +0xf9ffffffU, +0xfbffffffU +}, +{ +0xf0000000U, +0xf0000001U, +0xf0000003U, +0xf0000007U, +0xf000000fU, +0xf000001fU, +0xf000003fU, +0xf000007fU, +0xf00000ffU, +0xf00001ffU, +0xf00003ffU, +0xf00007ffU, +0xf0000fffU, +0xf0001fffU, +0xf0003fffU, +0xf0007fffU, +0xf000ffffU, +0xf001ffffU, +0xf003ffffU, +0xf007ffffU, +0xf00fffffU, +0xf01fffffU, +0xf03fffffU, +0xf07fffffU, +0xf0ffffffU, +0xf1ffffffU, +0xf3ffffffU, +0xf7ffffffU +}, +{ +0xe0000000U, +0xe0000001U, +0xe0000003U, +0xe0000007U, +0xe000000fU, +0xe000001fU, +0xe000003fU, +0xe000007fU, +0xe00000ffU, +0xe00001ffU, +0xe00003ffU, +0xe00007ffU, +0xe0000fffU, +0xe0001fffU, +0xe0003fffU, +0xe0007fffU, +0xe000ffffU, +0xe001ffffU, +0xe003ffffU, +0xe007ffffU, +0xe00fffffU, +0xe01fffffU, +0xe03fffffU, +0xe07fffffU, +0xe0ffffffU, +0xe1ffffffU, +0xe3ffffffU, +0xe7ffffffU, +0xefffffffU +}, +{ +0xc0000000U, +0xc0000001U, +0xc0000003U, +0xc0000007U, +0xc000000fU, +0xc000001fU, +0xc000003fU, +0xc000007fU, +0xc00000ffU, +0xc00001ffU, +0xc00003ffU, +0xc00007ffU, +0xc0000fffU, +0xc0001fffU, +0xc0003fffU, +0xc0007fffU, +0xc000ffffU, +0xc001ffffU, +0xc003ffffU, +0xc007ffffU, +0xc00fffffU, +0xc01fffffU, +0xc03fffffU, +0xc07fffffU, +0xc0ffffffU, +0xc1ffffffU, +0xc3ffffffU, +0xc7ffffffU, +0xcfffffffU, +0xdfffffffU +}, +{ +0x80000000U, +0x80000001U, +0x80000003U, +0x80000007U, +0x8000000fU, +0x8000001fU, +0x8000003fU, +0x8000007fU, +0x800000ffU, +0x800001ffU, +0x800003ffU, +0x800007ffU, +0x80000fffU, +0x80001fffU, +0x80003fffU, +0x80007fffU, +0x8000ffffU, +0x8001ffffU, +0x8003ffffU, +0x8007ffffU, +0x800fffffU, +0x801fffffU, +0x803fffffU, +0x807fffffU, +0x80ffffffU, +0x81ffffffU, +0x83ffffffU, +0x87ffffffU, +0x8fffffffU, +0x9fffffffU, +0xbfffffffU +}, +{ +0x0U, +0x1U, +0x3U, +0x7U, +0xfU, +0x1fU, +0x3fU, +0x7fU, +0xffU, +0x1ffU, +0x3ffU, +0x7ffU, +0xfffU, +0x1fffU, +0x3fffU, +0x7fffU, +0xffffU, +0x1ffffU, +0x3ffffU, +0x7ffffU, +0xfffffU, +0x1fffffU, +0x3fffffU, +0x7fffffU, +0xffffffU, +0x1ffffffU, +0x3ffffffU, +0x7ffffffU, +0xfffffffU, +0x1fffffffU, +0x3fffffffU, +0x7fffffffU +} +}; + +} // namespace sc_dt + +#endif diff --git a/ext/systemc/src/sysc/datatypes/int/sc_int64_io.cpp b/ext/systemc/src/sysc/datatypes/int/sc_int64_io.cpp new file mode 100644 index 000000000..b43bc6ed8 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_int64_io.cpp @@ -0,0 +1,182 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_int64_io.cpp -- + + Original Author: Amit Rao, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_int64_io.cpp,v $ +// Revision 1.2 2011/02/18 20:19:14 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:31 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#include "sysc/utils/sc_iostream.h" +#include "sysc/datatypes/int/sc_unsigned.h" +#include "sysc/datatypes/int/sc_signed.h" +#include "sysc/datatypes/int/sc_int_base.h" +#include "sysc/datatypes/int/sc_uint_base.h" + + +#if defined( _MSC_VER ) + +namespace sc_dt +{ + +static void +write_uint64(::std::ostream& os, uint64 val, int sign) +{ + const int WRITE_BUF_SIZE = 10 + sizeof(uint64)*3; + char buf[WRITE_BUF_SIZE]; + char* buf_ptr = buf + WRITE_BUF_SIZE; + const char* show_base = ""; + int show_base_len = 0; + int show_pos = 0; + fmtflags flags = os.flags(); + + if ((flags & ::std::ios::basefield) == ::std::ios::oct) { + do { + *--buf_ptr = (char)((val & 7) + '0'); + val = val >> 3; + } while (val != 0); + if ((flags & ::std::ios::showbase) && (*buf_ptr != '0')) + *--buf_ptr = '0'; + } else if ((flags & ::std::ios::basefield) == ::std::ios::hex) { + const char* xdigs = (flags & ::std::ios::uppercase) ? + "0123456789ABCDEF0X" : + "0123456789abcdef0x"; + do { + *--buf_ptr = xdigs[val & 15]; + val = val >> 4; + } while (val != 0); + if ((flags & ::std::ios::showbase)) { + show_base = xdigs + 16; + show_base_len = 2; + } + } else { + while (val > UINT_MAX) { + *--buf_ptr = (char)((val % 10) + '0'); + val /= 10; + } + unsigned ival = (unsigned) val; + do { + *--buf_ptr = (ival % 10) + '0'; + ival /= 10; + } while (ival != 0); + if (sign > 0 && (flags & ::std::ios::showpos)) + show_pos = 1; + } + + int buf_len = buf + WRITE_BUF_SIZE - buf_ptr; + int w = os.width(0); + + int len = buf_len + show_pos; + if (sign < 0) len++; + len += show_base_len; + + int padding = len > w ? 0 : w - len; + fmtflags pad_kind = flags & ::std::ios::adjustfield; + char fill_char = os.fill(); + + if (padding > 0 && + ::std::ios::left != pad_kind && + ::std::ios::internal != pad_kind) { + for (int i = padding - 1; i >= 0; --i) { + if (! os.put(fill_char)) + goto fail; + } + } + if (sign < 0 || show_pos) { + if (! os.put(sign < 0 ? '-' : '+')) + goto fail; + } + if (show_base_len) { + if (! os.write(show_base, show_base_len)) + goto fail; + } + if ((fmtflags)::std::ios::internal == pad_kind && padding > 0) { + for (int i = padding - 1; i >= 0; --i) { + if (! os.put(fill_char)) + goto fail; + } + } + if (! os.write(buf_ptr, buf_len)) + goto fail; + if ((fmtflags)::std::ios::left == pad_kind && padding > 0) { + for (int i = padding - 1; i >= 0; --i) { + if (! os.put(fill_char)) + goto fail; + } + } + os.osfx(); + return; +fail: + //os.set(::std::ios::badbit); + os.osfx(); +} + +::std::ostream& +operator << ( ::std::ostream& os, int64 n ) +{ + if (os.opfx()) { + int sign = 1; + uint64 abs_n = (uint64) n; + if (n < 0 && (os.flags() & (::std::ios::oct|::std::ios::hex)) == 0) { + abs_n = -1*((uint64) n); + sign = -1; + } + sc_dt::write_uint64(os, abs_n, sign); + } + return os; +} + +::std::ostream& +operator << ( ::std::ostream& os, uint64 n ) +{ + if (os.opfx()) { + sc_dt::write_uint64(os, n, 0); + } + return os; +} + +} // namespace sc_dt + + +#endif diff --git a/ext/systemc/src/sysc/datatypes/int/sc_int64_mask.cpp b/ext/systemc/src/sysc/datatypes/int/sc_int64_mask.cpp new file mode 100644 index 000000000..df69a6dda --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_int64_mask.cpp @@ -0,0 +1,4502 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_int64_mask.cpp -- Fills the mask_int lookup table to enable efficient + part-selection on 64-bit sc_ints and sc_uints. + + Original Author: Amit Rao, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc. + Description of Modification: - Resolved ambiguity with sc_(un)signed. + - Merged the code for 64- and 32-bit versions + via the constants in sc_nbdefs.h. + - Eliminated redundant file inclusions. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_int64_mask.cpp,v $ +// Revision 1.3 2011/02/18 20:19:14 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.2 2009/05/22 16:06:29 acg +// Andy Goodrich: process control updates. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:31 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef _32BIT_ + +#include "sysc/datatypes/int/sc_int_base.h" +#include "sysc/datatypes/int/sc_uint_base.h" + + +namespace sc_dt +{ + +#if !defined(_WIN32) || defined(__MINGW32__) + +const uint_type mask_int[SC_INTWIDTH][SC_INTWIDTH] = +{ +{ +0xfffffffffffffffeULL +}, +{ +0xfffffffffffffffcULL, +0xfffffffffffffffdULL +}, +{ +0xfffffffffffffff8ULL, +0xfffffffffffffff9ULL, +0xfffffffffffffffbULL +}, +{ +0xfffffffffffffff0ULL, +0xfffffffffffffff1ULL, +0xfffffffffffffff3ULL, +0xfffffffffffffff7ULL +}, +{ +0xffffffffffffffe0ULL, +0xffffffffffffffe1ULL, +0xffffffffffffffe3ULL, +0xffffffffffffffe7ULL, +0xffffffffffffffefULL +}, +{ +0xffffffffffffffc0ULL, +0xffffffffffffffc1ULL, +0xffffffffffffffc3ULL, +0xffffffffffffffc7ULL, +0xffffffffffffffcfULL, +0xffffffffffffffdfULL +}, +{ +0xffffffffffffff80ULL, +0xffffffffffffff81ULL, +0xffffffffffffff83ULL, +0xffffffffffffff87ULL, +0xffffffffffffff8fULL, +0xffffffffffffff9fULL, +0xffffffffffffffbfULL +}, +{ +0xffffffffffffff00ULL, +0xffffffffffffff01ULL, +0xffffffffffffff03ULL, +0xffffffffffffff07ULL, +0xffffffffffffff0fULL, +0xffffffffffffff1fULL, +0xffffffffffffff3fULL, +0xffffffffffffff7fULL +}, +{ +0xfffffffffffffe00ULL, +0xfffffffffffffe01ULL, +0xfffffffffffffe03ULL, +0xfffffffffffffe07ULL, +0xfffffffffffffe0fULL, +0xfffffffffffffe1fULL, +0xfffffffffffffe3fULL, +0xfffffffffffffe7fULL, +0xfffffffffffffeffULL +}, +{ +0xfffffffffffffc00ULL, +0xfffffffffffffc01ULL, +0xfffffffffffffc03ULL, +0xfffffffffffffc07ULL, +0xfffffffffffffc0fULL, +0xfffffffffffffc1fULL, +0xfffffffffffffc3fULL, +0xfffffffffffffc7fULL, +0xfffffffffffffcffULL, +0xfffffffffffffdffULL +}, +{ +0xfffffffffffff800ULL, +0xfffffffffffff801ULL, +0xfffffffffffff803ULL, +0xfffffffffffff807ULL, +0xfffffffffffff80fULL, +0xfffffffffffff81fULL, +0xfffffffffffff83fULL, +0xfffffffffffff87fULL, +0xfffffffffffff8ffULL, +0xfffffffffffff9ffULL, +0xfffffffffffffbffULL +}, +{ +0xfffffffffffff000ULL, +0xfffffffffffff001ULL, +0xfffffffffffff003ULL, +0xfffffffffffff007ULL, +0xfffffffffffff00fULL, +0xfffffffffffff01fULL, +0xfffffffffffff03fULL, +0xfffffffffffff07fULL, +0xfffffffffffff0ffULL, +0xfffffffffffff1ffULL, +0xfffffffffffff3ffULL, +0xfffffffffffff7ffULL +}, +{ +0xffffffffffffe000ULL, +0xffffffffffffe001ULL, +0xffffffffffffe003ULL, +0xffffffffffffe007ULL, +0xffffffffffffe00fULL, +0xffffffffffffe01fULL, +0xffffffffffffe03fULL, +0xffffffffffffe07fULL, +0xffffffffffffe0ffULL, +0xffffffffffffe1ffULL, +0xffffffffffffe3ffULL, +0xffffffffffffe7ffULL, +0xffffffffffffefffULL +}, +{ +0xffffffffffffc000ULL, +0xffffffffffffc001ULL, +0xffffffffffffc003ULL, +0xffffffffffffc007ULL, +0xffffffffffffc00fULL, +0xffffffffffffc01fULL, +0xffffffffffffc03fULL, +0xffffffffffffc07fULL, +0xffffffffffffc0ffULL, +0xffffffffffffc1ffULL, +0xffffffffffffc3ffULL, +0xffffffffffffc7ffULL, +0xffffffffffffcfffULL, +0xffffffffffffdfffULL +}, +{ +0xffffffffffff8000ULL, +0xffffffffffff8001ULL, +0xffffffffffff8003ULL, +0xffffffffffff8007ULL, +0xffffffffffff800fULL, +0xffffffffffff801fULL, +0xffffffffffff803fULL, +0xffffffffffff807fULL, +0xffffffffffff80ffULL, +0xffffffffffff81ffULL, +0xffffffffffff83ffULL, +0xffffffffffff87ffULL, +0xffffffffffff8fffULL, +0xffffffffffff9fffULL, +0xffffffffffffbfffULL +}, +{ +0xffffffffffff0000ULL, +0xffffffffffff0001ULL, +0xffffffffffff0003ULL, +0xffffffffffff0007ULL, +0xffffffffffff000fULL, +0xffffffffffff001fULL, +0xffffffffffff003fULL, +0xffffffffffff007fULL, +0xffffffffffff00ffULL, +0xffffffffffff01ffULL, +0xffffffffffff03ffULL, +0xffffffffffff07ffULL, +0xffffffffffff0fffULL, +0xffffffffffff1fffULL, +0xffffffffffff3fffULL, +0xffffffffffff7fffULL +}, +{ +0xfffffffffffe0000ULL, +0xfffffffffffe0001ULL, +0xfffffffffffe0003ULL, +0xfffffffffffe0007ULL, +0xfffffffffffe000fULL, +0xfffffffffffe001fULL, +0xfffffffffffe003fULL, +0xfffffffffffe007fULL, +0xfffffffffffe00ffULL, +0xfffffffffffe01ffULL, +0xfffffffffffe03ffULL, +0xfffffffffffe07ffULL, +0xfffffffffffe0fffULL, +0xfffffffffffe1fffULL, +0xfffffffffffe3fffULL, +0xfffffffffffe7fffULL, +0xfffffffffffeffffULL +}, +{ +0xfffffffffffc0000ULL, +0xfffffffffffc0001ULL, +0xfffffffffffc0003ULL, +0xfffffffffffc0007ULL, +0xfffffffffffc000fULL, +0xfffffffffffc001fULL, +0xfffffffffffc003fULL, +0xfffffffffffc007fULL, +0xfffffffffffc00ffULL, +0xfffffffffffc01ffULL, +0xfffffffffffc03ffULL, +0xfffffffffffc07ffULL, +0xfffffffffffc0fffULL, +0xfffffffffffc1fffULL, +0xfffffffffffc3fffULL, +0xfffffffffffc7fffULL, +0xfffffffffffcffffULL, +0xfffffffffffdffffULL +}, +{ +0xfffffffffff80000ULL, +0xfffffffffff80001ULL, +0xfffffffffff80003ULL, +0xfffffffffff80007ULL, +0xfffffffffff8000fULL, +0xfffffffffff8001fULL, +0xfffffffffff8003fULL, +0xfffffffffff8007fULL, +0xfffffffffff800ffULL, +0xfffffffffff801ffULL, +0xfffffffffff803ffULL, +0xfffffffffff807ffULL, +0xfffffffffff80fffULL, +0xfffffffffff81fffULL, +0xfffffffffff83fffULL, +0xfffffffffff87fffULL, +0xfffffffffff8ffffULL, +0xfffffffffff9ffffULL, +0xfffffffffffbffffULL +}, +{ +0xfffffffffff00000ULL, +0xfffffffffff00001ULL, +0xfffffffffff00003ULL, +0xfffffffffff00007ULL, +0xfffffffffff0000fULL, +0xfffffffffff0001fULL, +0xfffffffffff0003fULL, +0xfffffffffff0007fULL, +0xfffffffffff000ffULL, +0xfffffffffff001ffULL, +0xfffffffffff003ffULL, +0xfffffffffff007ffULL, +0xfffffffffff00fffULL, +0xfffffffffff01fffULL, +0xfffffffffff03fffULL, +0xfffffffffff07fffULL, +0xfffffffffff0ffffULL, +0xfffffffffff1ffffULL, +0xfffffffffff3ffffULL, +0xfffffffffff7ffffULL +}, +{ +0xffffffffffe00000ULL, +0xffffffffffe00001ULL, +0xffffffffffe00003ULL, +0xffffffffffe00007ULL, +0xffffffffffe0000fULL, +0xffffffffffe0001fULL, +0xffffffffffe0003fULL, +0xffffffffffe0007fULL, +0xffffffffffe000ffULL, +0xffffffffffe001ffULL, +0xffffffffffe003ffULL, +0xffffffffffe007ffULL, +0xffffffffffe00fffULL, +0xffffffffffe01fffULL, +0xffffffffffe03fffULL, +0xffffffffffe07fffULL, +0xffffffffffe0ffffULL, +0xffffffffffe1ffffULL, +0xffffffffffe3ffffULL, +0xffffffffffe7ffffULL, +0xffffffffffefffffULL +}, +{ +0xffffffffffc00000ULL, +0xffffffffffc00001ULL, +0xffffffffffc00003ULL, +0xffffffffffc00007ULL, +0xffffffffffc0000fULL, +0xffffffffffc0001fULL, +0xffffffffffc0003fULL, +0xffffffffffc0007fULL, +0xffffffffffc000ffULL, +0xffffffffffc001ffULL, +0xffffffffffc003ffULL, +0xffffffffffc007ffULL, +0xffffffffffc00fffULL, +0xffffffffffc01fffULL, +0xffffffffffc03fffULL, +0xffffffffffc07fffULL, +0xffffffffffc0ffffULL, +0xffffffffffc1ffffULL, +0xffffffffffc3ffffULL, +0xffffffffffc7ffffULL, +0xffffffffffcfffffULL, +0xffffffffffdfffffULL +}, +{ +0xffffffffff800000ULL, +0xffffffffff800001ULL, +0xffffffffff800003ULL, +0xffffffffff800007ULL, +0xffffffffff80000fULL, +0xffffffffff80001fULL, +0xffffffffff80003fULL, +0xffffffffff80007fULL, +0xffffffffff8000ffULL, +0xffffffffff8001ffULL, +0xffffffffff8003ffULL, +0xffffffffff8007ffULL, +0xffffffffff800fffULL, +0xffffffffff801fffULL, +0xffffffffff803fffULL, +0xffffffffff807fffULL, +0xffffffffff80ffffULL, +0xffffffffff81ffffULL, +0xffffffffff83ffffULL, +0xffffffffff87ffffULL, +0xffffffffff8fffffULL, +0xffffffffff9fffffULL, +0xffffffffffbfffffULL +}, +{ +0xffffffffff000000ULL, +0xffffffffff000001ULL, +0xffffffffff000003ULL, +0xffffffffff000007ULL, +0xffffffffff00000fULL, +0xffffffffff00001fULL, +0xffffffffff00003fULL, +0xffffffffff00007fULL, +0xffffffffff0000ffULL, +0xffffffffff0001ffULL, +0xffffffffff0003ffULL, +0xffffffffff0007ffULL, +0xffffffffff000fffULL, +0xffffffffff001fffULL, +0xffffffffff003fffULL, +0xffffffffff007fffULL, +0xffffffffff00ffffULL, +0xffffffffff01ffffULL, +0xffffffffff03ffffULL, +0xffffffffff07ffffULL, +0xffffffffff0fffffULL, +0xffffffffff1fffffULL, +0xffffffffff3fffffULL, +0xffffffffff7fffffULL +}, +{ +0xfffffffffe000000ULL, +0xfffffffffe000001ULL, +0xfffffffffe000003ULL, +0xfffffffffe000007ULL, +0xfffffffffe00000fULL, +0xfffffffffe00001fULL, +0xfffffffffe00003fULL, +0xfffffffffe00007fULL, +0xfffffffffe0000ffULL, +0xfffffffffe0001ffULL, +0xfffffffffe0003ffULL, +0xfffffffffe0007ffULL, +0xfffffffffe000fffULL, +0xfffffffffe001fffULL, +0xfffffffffe003fffULL, +0xfffffffffe007fffULL, +0xfffffffffe00ffffULL, +0xfffffffffe01ffffULL, +0xfffffffffe03ffffULL, +0xfffffffffe07ffffULL, +0xfffffffffe0fffffULL, +0xfffffffffe1fffffULL, +0xfffffffffe3fffffULL, +0xfffffffffe7fffffULL, +0xfffffffffeffffffULL +}, +{ +0xfffffffffc000000ULL, +0xfffffffffc000001ULL, +0xfffffffffc000003ULL, +0xfffffffffc000007ULL, +0xfffffffffc00000fULL, +0xfffffffffc00001fULL, +0xfffffffffc00003fULL, +0xfffffffffc00007fULL, +0xfffffffffc0000ffULL, +0xfffffffffc0001ffULL, +0xfffffffffc0003ffULL, +0xfffffffffc0007ffULL, +0xfffffffffc000fffULL, +0xfffffffffc001fffULL, +0xfffffffffc003fffULL, +0xfffffffffc007fffULL, +0xfffffffffc00ffffULL, +0xfffffffffc01ffffULL, +0xfffffffffc03ffffULL, +0xfffffffffc07ffffULL, +0xfffffffffc0fffffULL, +0xfffffffffc1fffffULL, +0xfffffffffc3fffffULL, +0xfffffffffc7fffffULL, +0xfffffffffcffffffULL, +0xfffffffffdffffffULL +}, +{ +0xfffffffff8000000ULL, +0xfffffffff8000001ULL, +0xfffffffff8000003ULL, +0xfffffffff8000007ULL, +0xfffffffff800000fULL, +0xfffffffff800001fULL, +0xfffffffff800003fULL, +0xfffffffff800007fULL, +0xfffffffff80000ffULL, +0xfffffffff80001ffULL, +0xfffffffff80003ffULL, +0xfffffffff80007ffULL, +0xfffffffff8000fffULL, +0xfffffffff8001fffULL, +0xfffffffff8003fffULL, +0xfffffffff8007fffULL, +0xfffffffff800ffffULL, +0xfffffffff801ffffULL, +0xfffffffff803ffffULL, +0xfffffffff807ffffULL, +0xfffffffff80fffffULL, +0xfffffffff81fffffULL, +0xfffffffff83fffffULL, +0xfffffffff87fffffULL, +0xfffffffff8ffffffULL, +0xfffffffff9ffffffULL, +0xfffffffffbffffffULL +}, +{ +0xfffffffff0000000ULL, +0xfffffffff0000001ULL, +0xfffffffff0000003ULL, +0xfffffffff0000007ULL, +0xfffffffff000000fULL, +0xfffffffff000001fULL, +0xfffffffff000003fULL, +0xfffffffff000007fULL, +0xfffffffff00000ffULL, +0xfffffffff00001ffULL, +0xfffffffff00003ffULL, +0xfffffffff00007ffULL, +0xfffffffff0000fffULL, +0xfffffffff0001fffULL, +0xfffffffff0003fffULL, +0xfffffffff0007fffULL, +0xfffffffff000ffffULL, +0xfffffffff001ffffULL, +0xfffffffff003ffffULL, +0xfffffffff007ffffULL, +0xfffffffff00fffffULL, +0xfffffffff01fffffULL, +0xfffffffff03fffffULL, +0xfffffffff07fffffULL, +0xfffffffff0ffffffULL, +0xfffffffff1ffffffULL, +0xfffffffff3ffffffULL, +0xfffffffff7ffffffULL +}, +{ +0xffffffffe0000000ULL, +0xffffffffe0000001ULL, +0xffffffffe0000003ULL, +0xffffffffe0000007ULL, +0xffffffffe000000fULL, +0xffffffffe000001fULL, +0xffffffffe000003fULL, +0xffffffffe000007fULL, +0xffffffffe00000ffULL, +0xffffffffe00001ffULL, +0xffffffffe00003ffULL, +0xffffffffe00007ffULL, +0xffffffffe0000fffULL, +0xffffffffe0001fffULL, +0xffffffffe0003fffULL, +0xffffffffe0007fffULL, +0xffffffffe000ffffULL, +0xffffffffe001ffffULL, +0xffffffffe003ffffULL, +0xffffffffe007ffffULL, +0xffffffffe00fffffULL, +0xffffffffe01fffffULL, +0xffffffffe03fffffULL, +0xffffffffe07fffffULL, +0xffffffffe0ffffffULL, +0xffffffffe1ffffffULL, +0xffffffffe3ffffffULL, +0xffffffffe7ffffffULL, +0xffffffffefffffffULL +}, +{ +0xffffffffc0000000ULL, +0xffffffffc0000001ULL, +0xffffffffc0000003ULL, +0xffffffffc0000007ULL, +0xffffffffc000000fULL, +0xffffffffc000001fULL, +0xffffffffc000003fULL, +0xffffffffc000007fULL, +0xffffffffc00000ffULL, +0xffffffffc00001ffULL, +0xffffffffc00003ffULL, +0xffffffffc00007ffULL, +0xffffffffc0000fffULL, +0xffffffffc0001fffULL, +0xffffffffc0003fffULL, +0xffffffffc0007fffULL, +0xffffffffc000ffffULL, +0xffffffffc001ffffULL, +0xffffffffc003ffffULL, +0xffffffffc007ffffULL, +0xffffffffc00fffffULL, +0xffffffffc01fffffULL, +0xffffffffc03fffffULL, +0xffffffffc07fffffULL, +0xffffffffc0ffffffULL, +0xffffffffc1ffffffULL, +0xffffffffc3ffffffULL, +0xffffffffc7ffffffULL, +0xffffffffcfffffffULL, +0xffffffffdfffffffULL +}, +{ +0xffffffff80000000ULL, +0xffffffff80000001ULL, +0xffffffff80000003ULL, +0xffffffff80000007ULL, +0xffffffff8000000fULL, +0xffffffff8000001fULL, +0xffffffff8000003fULL, +0xffffffff8000007fULL, +0xffffffff800000ffULL, +0xffffffff800001ffULL, +0xffffffff800003ffULL, +0xffffffff800007ffULL, +0xffffffff80000fffULL, +0xffffffff80001fffULL, +0xffffffff80003fffULL, +0xffffffff80007fffULL, +0xffffffff8000ffffULL, +0xffffffff8001ffffULL, +0xffffffff8003ffffULL, +0xffffffff8007ffffULL, +0xffffffff800fffffULL, +0xffffffff801fffffULL, +0xffffffff803fffffULL, +0xffffffff807fffffULL, +0xffffffff80ffffffULL, +0xffffffff81ffffffULL, +0xffffffff83ffffffULL, +0xffffffff87ffffffULL, +0xffffffff8fffffffULL, +0xffffffff9fffffffULL, +0xffffffffbfffffffULL +}, +{ +0xffffffff00000000ULL, +0xffffffff00000001ULL, +0xffffffff00000003ULL, +0xffffffff00000007ULL, +0xffffffff0000000fULL, +0xffffffff0000001fULL, +0xffffffff0000003fULL, +0xffffffff0000007fULL, +0xffffffff000000ffULL, +0xffffffff000001ffULL, +0xffffffff000003ffULL, +0xffffffff000007ffULL, +0xffffffff00000fffULL, +0xffffffff00001fffULL, +0xffffffff00003fffULL, +0xffffffff00007fffULL, +0xffffffff0000ffffULL, +0xffffffff0001ffffULL, +0xffffffff0003ffffULL, +0xffffffff0007ffffULL, +0xffffffff000fffffULL, +0xffffffff001fffffULL, +0xffffffff003fffffULL, +0xffffffff007fffffULL, +0xffffffff00ffffffULL, +0xffffffff01ffffffULL, +0xffffffff03ffffffULL, +0xffffffff07ffffffULL, +0xffffffff0fffffffULL, +0xffffffff1fffffffULL, +0xffffffff3fffffffULL, +0xffffffff7fffffffULL +}, +{ +0xfffffffe00000000ULL, +0xfffffffe00000001ULL, +0xfffffffe00000003ULL, +0xfffffffe00000007ULL, +0xfffffffe0000000fULL, +0xfffffffe0000001fULL, +0xfffffffe0000003fULL, +0xfffffffe0000007fULL, +0xfffffffe000000ffULL, +0xfffffffe000001ffULL, +0xfffffffe000003ffULL, +0xfffffffe000007ffULL, +0xfffffffe00000fffULL, +0xfffffffe00001fffULL, +0xfffffffe00003fffULL, +0xfffffffe00007fffULL, +0xfffffffe0000ffffULL, +0xfffffffe0001ffffULL, +0xfffffffe0003ffffULL, +0xfffffffe0007ffffULL, +0xfffffffe000fffffULL, +0xfffffffe001fffffULL, +0xfffffffe003fffffULL, +0xfffffffe007fffffULL, +0xfffffffe00ffffffULL, +0xfffffffe01ffffffULL, +0xfffffffe03ffffffULL, +0xfffffffe07ffffffULL, +0xfffffffe0fffffffULL, +0xfffffffe1fffffffULL, +0xfffffffe3fffffffULL, +0xfffffffe7fffffffULL, +0xfffffffeffffffffULL +}, +{ +0xfffffffc00000000ULL, +0xfffffffc00000001ULL, +0xfffffffc00000003ULL, +0xfffffffc00000007ULL, +0xfffffffc0000000fULL, +0xfffffffc0000001fULL, +0xfffffffc0000003fULL, +0xfffffffc0000007fULL, +0xfffffffc000000ffULL, +0xfffffffc000001ffULL, +0xfffffffc000003ffULL, +0xfffffffc000007ffULL, +0xfffffffc00000fffULL, +0xfffffffc00001fffULL, +0xfffffffc00003fffULL, +0xfffffffc00007fffULL, +0xfffffffc0000ffffULL, +0xfffffffc0001ffffULL, +0xfffffffc0003ffffULL, +0xfffffffc0007ffffULL, +0xfffffffc000fffffULL, +0xfffffffc001fffffULL, +0xfffffffc003fffffULL, +0xfffffffc007fffffULL, +0xfffffffc00ffffffULL, +0xfffffffc01ffffffULL, +0xfffffffc03ffffffULL, +0xfffffffc07ffffffULL, +0xfffffffc0fffffffULL, +0xfffffffc1fffffffULL, +0xfffffffc3fffffffULL, +0xfffffffc7fffffffULL, +0xfffffffcffffffffULL, +0xfffffffdffffffffULL +}, +{ +0xfffffff800000000ULL, +0xfffffff800000001ULL, +0xfffffff800000003ULL, +0xfffffff800000007ULL, +0xfffffff80000000fULL, +0xfffffff80000001fULL, +0xfffffff80000003fULL, +0xfffffff80000007fULL, +0xfffffff8000000ffULL, +0xfffffff8000001ffULL, +0xfffffff8000003ffULL, +0xfffffff8000007ffULL, +0xfffffff800000fffULL, +0xfffffff800001fffULL, +0xfffffff800003fffULL, +0xfffffff800007fffULL, +0xfffffff80000ffffULL, +0xfffffff80001ffffULL, +0xfffffff80003ffffULL, +0xfffffff80007ffffULL, +0xfffffff8000fffffULL, +0xfffffff8001fffffULL, +0xfffffff8003fffffULL, +0xfffffff8007fffffULL, +0xfffffff800ffffffULL, +0xfffffff801ffffffULL, +0xfffffff803ffffffULL, +0xfffffff807ffffffULL, +0xfffffff80fffffffULL, +0xfffffff81fffffffULL, +0xfffffff83fffffffULL, +0xfffffff87fffffffULL, +0xfffffff8ffffffffULL, +0xfffffff9ffffffffULL, +0xfffffffbffffffffULL +}, +{ +0xfffffff000000000ULL, +0xfffffff000000001ULL, +0xfffffff000000003ULL, +0xfffffff000000007ULL, +0xfffffff00000000fULL, +0xfffffff00000001fULL, +0xfffffff00000003fULL, +0xfffffff00000007fULL, +0xfffffff0000000ffULL, +0xfffffff0000001ffULL, +0xfffffff0000003ffULL, +0xfffffff0000007ffULL, +0xfffffff000000fffULL, +0xfffffff000001fffULL, +0xfffffff000003fffULL, +0xfffffff000007fffULL, +0xfffffff00000ffffULL, +0xfffffff00001ffffULL, +0xfffffff00003ffffULL, +0xfffffff00007ffffULL, +0xfffffff0000fffffULL, +0xfffffff0001fffffULL, +0xfffffff0003fffffULL, +0xfffffff0007fffffULL, +0xfffffff000ffffffULL, +0xfffffff001ffffffULL, +0xfffffff003ffffffULL, +0xfffffff007ffffffULL, +0xfffffff00fffffffULL, +0xfffffff01fffffffULL, +0xfffffff03fffffffULL, +0xfffffff07fffffffULL, +0xfffffff0ffffffffULL, +0xfffffff1ffffffffULL, +0xfffffff3ffffffffULL, +0xfffffff7ffffffffULL +}, +{ +0xffffffe000000000ULL, +0xffffffe000000001ULL, +0xffffffe000000003ULL, +0xffffffe000000007ULL, +0xffffffe00000000fULL, +0xffffffe00000001fULL, +0xffffffe00000003fULL, +0xffffffe00000007fULL, +0xffffffe0000000ffULL, +0xffffffe0000001ffULL, +0xffffffe0000003ffULL, +0xffffffe0000007ffULL, +0xffffffe000000fffULL, +0xffffffe000001fffULL, +0xffffffe000003fffULL, +0xffffffe000007fffULL, +0xffffffe00000ffffULL, +0xffffffe00001ffffULL, +0xffffffe00003ffffULL, +0xffffffe00007ffffULL, +0xffffffe0000fffffULL, +0xffffffe0001fffffULL, +0xffffffe0003fffffULL, +0xffffffe0007fffffULL, +0xffffffe000ffffffULL, +0xffffffe001ffffffULL, +0xffffffe003ffffffULL, +0xffffffe007ffffffULL, +0xffffffe00fffffffULL, +0xffffffe01fffffffULL, +0xffffffe03fffffffULL, +0xffffffe07fffffffULL, +0xffffffe0ffffffffULL, +0xffffffe1ffffffffULL, +0xffffffe3ffffffffULL, +0xffffffe7ffffffffULL, +0xffffffefffffffffULL +}, +{ +0xffffffc000000000ULL, +0xffffffc000000001ULL, +0xffffffc000000003ULL, +0xffffffc000000007ULL, +0xffffffc00000000fULL, +0xffffffc00000001fULL, +0xffffffc00000003fULL, +0xffffffc00000007fULL, +0xffffffc0000000ffULL, +0xffffffc0000001ffULL, +0xffffffc0000003ffULL, +0xffffffc0000007ffULL, +0xffffffc000000fffULL, +0xffffffc000001fffULL, +0xffffffc000003fffULL, +0xffffffc000007fffULL, +0xffffffc00000ffffULL, +0xffffffc00001ffffULL, +0xffffffc00003ffffULL, +0xffffffc00007ffffULL, +0xffffffc0000fffffULL, +0xffffffc0001fffffULL, +0xffffffc0003fffffULL, +0xffffffc0007fffffULL, +0xffffffc000ffffffULL, +0xffffffc001ffffffULL, +0xffffffc003ffffffULL, +0xffffffc007ffffffULL, +0xffffffc00fffffffULL, +0xffffffc01fffffffULL, +0xffffffc03fffffffULL, +0xffffffc07fffffffULL, +0xffffffc0ffffffffULL, +0xffffffc1ffffffffULL, +0xffffffc3ffffffffULL, +0xffffffc7ffffffffULL, +0xffffffcfffffffffULL, +0xffffffdfffffffffULL +}, +{ +0xffffff8000000000ULL, +0xffffff8000000001ULL, +0xffffff8000000003ULL, +0xffffff8000000007ULL, +0xffffff800000000fULL, +0xffffff800000001fULL, +0xffffff800000003fULL, +0xffffff800000007fULL, +0xffffff80000000ffULL, +0xffffff80000001ffULL, +0xffffff80000003ffULL, +0xffffff80000007ffULL, +0xffffff8000000fffULL, +0xffffff8000001fffULL, +0xffffff8000003fffULL, +0xffffff8000007fffULL, +0xffffff800000ffffULL, +0xffffff800001ffffULL, +0xffffff800003ffffULL, +0xffffff800007ffffULL, +0xffffff80000fffffULL, +0xffffff80001fffffULL, +0xffffff80003fffffULL, +0xffffff80007fffffULL, +0xffffff8000ffffffULL, +0xffffff8001ffffffULL, +0xffffff8003ffffffULL, +0xffffff8007ffffffULL, +0xffffff800fffffffULL, +0xffffff801fffffffULL, +0xffffff803fffffffULL, +0xffffff807fffffffULL, +0xffffff80ffffffffULL, +0xffffff81ffffffffULL, +0xffffff83ffffffffULL, +0xffffff87ffffffffULL, +0xffffff8fffffffffULL, +0xffffff9fffffffffULL, +0xffffffbfffffffffULL +}, +{ +0xffffff0000000000ULL, +0xffffff0000000001ULL, +0xffffff0000000003ULL, +0xffffff0000000007ULL, +0xffffff000000000fULL, +0xffffff000000001fULL, +0xffffff000000003fULL, +0xffffff000000007fULL, +0xffffff00000000ffULL, +0xffffff00000001ffULL, +0xffffff00000003ffULL, +0xffffff00000007ffULL, +0xffffff0000000fffULL, +0xffffff0000001fffULL, +0xffffff0000003fffULL, +0xffffff0000007fffULL, +0xffffff000000ffffULL, +0xffffff000001ffffULL, +0xffffff000003ffffULL, +0xffffff000007ffffULL, +0xffffff00000fffffULL, +0xffffff00001fffffULL, +0xffffff00003fffffULL, +0xffffff00007fffffULL, +0xffffff0000ffffffULL, +0xffffff0001ffffffULL, +0xffffff0003ffffffULL, +0xffffff0007ffffffULL, +0xffffff000fffffffULL, +0xffffff001fffffffULL, +0xffffff003fffffffULL, +0xffffff007fffffffULL, +0xffffff00ffffffffULL, +0xffffff01ffffffffULL, +0xffffff03ffffffffULL, +0xffffff07ffffffffULL, +0xffffff0fffffffffULL, +0xffffff1fffffffffULL, +0xffffff3fffffffffULL, +0xffffff7fffffffffULL +}, +{ +0xfffffe0000000000ULL, +0xfffffe0000000001ULL, +0xfffffe0000000003ULL, +0xfffffe0000000007ULL, +0xfffffe000000000fULL, +0xfffffe000000001fULL, +0xfffffe000000003fULL, +0xfffffe000000007fULL, +0xfffffe00000000ffULL, +0xfffffe00000001ffULL, +0xfffffe00000003ffULL, +0xfffffe00000007ffULL, +0xfffffe0000000fffULL, +0xfffffe0000001fffULL, +0xfffffe0000003fffULL, +0xfffffe0000007fffULL, +0xfffffe000000ffffULL, +0xfffffe000001ffffULL, +0xfffffe000003ffffULL, +0xfffffe000007ffffULL, +0xfffffe00000fffffULL, +0xfffffe00001fffffULL, +0xfffffe00003fffffULL, +0xfffffe00007fffffULL, +0xfffffe0000ffffffULL, +0xfffffe0001ffffffULL, +0xfffffe0003ffffffULL, +0xfffffe0007ffffffULL, +0xfffffe000fffffffULL, +0xfffffe001fffffffULL, +0xfffffe003fffffffULL, +0xfffffe007fffffffULL, +0xfffffe00ffffffffULL, +0xfffffe01ffffffffULL, +0xfffffe03ffffffffULL, +0xfffffe07ffffffffULL, +0xfffffe0fffffffffULL, +0xfffffe1fffffffffULL, +0xfffffe3fffffffffULL, +0xfffffe7fffffffffULL, +0xfffffeffffffffffULL +}, +{ +0xfffffc0000000000ULL, +0xfffffc0000000001ULL, +0xfffffc0000000003ULL, +0xfffffc0000000007ULL, +0xfffffc000000000fULL, +0xfffffc000000001fULL, +0xfffffc000000003fULL, +0xfffffc000000007fULL, +0xfffffc00000000ffULL, +0xfffffc00000001ffULL, +0xfffffc00000003ffULL, +0xfffffc00000007ffULL, +0xfffffc0000000fffULL, +0xfffffc0000001fffULL, +0xfffffc0000003fffULL, +0xfffffc0000007fffULL, +0xfffffc000000ffffULL, +0xfffffc000001ffffULL, +0xfffffc000003ffffULL, +0xfffffc000007ffffULL, +0xfffffc00000fffffULL, +0xfffffc00001fffffULL, +0xfffffc00003fffffULL, +0xfffffc00007fffffULL, +0xfffffc0000ffffffULL, +0xfffffc0001ffffffULL, +0xfffffc0003ffffffULL, +0xfffffc0007ffffffULL, +0xfffffc000fffffffULL, +0xfffffc001fffffffULL, +0xfffffc003fffffffULL, +0xfffffc007fffffffULL, +0xfffffc00ffffffffULL, +0xfffffc01ffffffffULL, +0xfffffc03ffffffffULL, +0xfffffc07ffffffffULL, +0xfffffc0fffffffffULL, +0xfffffc1fffffffffULL, +0xfffffc3fffffffffULL, +0xfffffc7fffffffffULL, +0xfffffcffffffffffULL, +0xfffffdffffffffffULL +}, +{ +0xfffff80000000000ULL, +0xfffff80000000001ULL, +0xfffff80000000003ULL, +0xfffff80000000007ULL, +0xfffff8000000000fULL, +0xfffff8000000001fULL, +0xfffff8000000003fULL, +0xfffff8000000007fULL, +0xfffff800000000ffULL, +0xfffff800000001ffULL, +0xfffff800000003ffULL, +0xfffff800000007ffULL, +0xfffff80000000fffULL, +0xfffff80000001fffULL, +0xfffff80000003fffULL, +0xfffff80000007fffULL, +0xfffff8000000ffffULL, +0xfffff8000001ffffULL, +0xfffff8000003ffffULL, +0xfffff8000007ffffULL, +0xfffff800000fffffULL, +0xfffff800001fffffULL, +0xfffff800003fffffULL, +0xfffff800007fffffULL, +0xfffff80000ffffffULL, +0xfffff80001ffffffULL, +0xfffff80003ffffffULL, +0xfffff80007ffffffULL, +0xfffff8000fffffffULL, +0xfffff8001fffffffULL, +0xfffff8003fffffffULL, +0xfffff8007fffffffULL, +0xfffff800ffffffffULL, +0xfffff801ffffffffULL, +0xfffff803ffffffffULL, +0xfffff807ffffffffULL, +0xfffff80fffffffffULL, +0xfffff81fffffffffULL, +0xfffff83fffffffffULL, +0xfffff87fffffffffULL, +0xfffff8ffffffffffULL, +0xfffff9ffffffffffULL, +0xfffffbffffffffffULL +}, +{ +0xfffff00000000000ULL, +0xfffff00000000001ULL, +0xfffff00000000003ULL, +0xfffff00000000007ULL, +0xfffff0000000000fULL, +0xfffff0000000001fULL, +0xfffff0000000003fULL, +0xfffff0000000007fULL, +0xfffff000000000ffULL, +0xfffff000000001ffULL, +0xfffff000000003ffULL, +0xfffff000000007ffULL, +0xfffff00000000fffULL, +0xfffff00000001fffULL, +0xfffff00000003fffULL, +0xfffff00000007fffULL, +0xfffff0000000ffffULL, +0xfffff0000001ffffULL, +0xfffff0000003ffffULL, +0xfffff0000007ffffULL, +0xfffff000000fffffULL, +0xfffff000001fffffULL, +0xfffff000003fffffULL, +0xfffff000007fffffULL, +0xfffff00000ffffffULL, +0xfffff00001ffffffULL, +0xfffff00003ffffffULL, +0xfffff00007ffffffULL, +0xfffff0000fffffffULL, +0xfffff0001fffffffULL, +0xfffff0003fffffffULL, +0xfffff0007fffffffULL, +0xfffff000ffffffffULL, +0xfffff001ffffffffULL, +0xfffff003ffffffffULL, +0xfffff007ffffffffULL, +0xfffff00fffffffffULL, +0xfffff01fffffffffULL, +0xfffff03fffffffffULL, +0xfffff07fffffffffULL, +0xfffff0ffffffffffULL, +0xfffff1ffffffffffULL, +0xfffff3ffffffffffULL, +0xfffff7ffffffffffULL +}, +{ +0xffffe00000000000ULL, +0xffffe00000000001ULL, +0xffffe00000000003ULL, +0xffffe00000000007ULL, +0xffffe0000000000fULL, +0xffffe0000000001fULL, +0xffffe0000000003fULL, +0xffffe0000000007fULL, +0xffffe000000000ffULL, +0xffffe000000001ffULL, +0xffffe000000003ffULL, +0xffffe000000007ffULL, +0xffffe00000000fffULL, +0xffffe00000001fffULL, +0xffffe00000003fffULL, +0xffffe00000007fffULL, +0xffffe0000000ffffULL, +0xffffe0000001ffffULL, +0xffffe0000003ffffULL, +0xffffe0000007ffffULL, +0xffffe000000fffffULL, +0xffffe000001fffffULL, +0xffffe000003fffffULL, +0xffffe000007fffffULL, +0xffffe00000ffffffULL, +0xffffe00001ffffffULL, +0xffffe00003ffffffULL, +0xffffe00007ffffffULL, +0xffffe0000fffffffULL, +0xffffe0001fffffffULL, +0xffffe0003fffffffULL, +0xffffe0007fffffffULL, +0xffffe000ffffffffULL, +0xffffe001ffffffffULL, +0xffffe003ffffffffULL, +0xffffe007ffffffffULL, +0xffffe00fffffffffULL, +0xffffe01fffffffffULL, +0xffffe03fffffffffULL, +0xffffe07fffffffffULL, +0xffffe0ffffffffffULL, +0xffffe1ffffffffffULL, +0xffffe3ffffffffffULL, +0xffffe7ffffffffffULL, +0xffffefffffffffffULL +}, +{ +0xffffc00000000000ULL, +0xffffc00000000001ULL, +0xffffc00000000003ULL, +0xffffc00000000007ULL, +0xffffc0000000000fULL, +0xffffc0000000001fULL, +0xffffc0000000003fULL, +0xffffc0000000007fULL, +0xffffc000000000ffULL, +0xffffc000000001ffULL, +0xffffc000000003ffULL, +0xffffc000000007ffULL, +0xffffc00000000fffULL, +0xffffc00000001fffULL, +0xffffc00000003fffULL, +0xffffc00000007fffULL, +0xffffc0000000ffffULL, +0xffffc0000001ffffULL, +0xffffc0000003ffffULL, +0xffffc0000007ffffULL, +0xffffc000000fffffULL, +0xffffc000001fffffULL, +0xffffc000003fffffULL, +0xffffc000007fffffULL, +0xffffc00000ffffffULL, +0xffffc00001ffffffULL, +0xffffc00003ffffffULL, +0xffffc00007ffffffULL, +0xffffc0000fffffffULL, +0xffffc0001fffffffULL, +0xffffc0003fffffffULL, +0xffffc0007fffffffULL, +0xffffc000ffffffffULL, +0xffffc001ffffffffULL, +0xffffc003ffffffffULL, +0xffffc007ffffffffULL, +0xffffc00fffffffffULL, +0xffffc01fffffffffULL, +0xffffc03fffffffffULL, +0xffffc07fffffffffULL, +0xffffc0ffffffffffULL, +0xffffc1ffffffffffULL, +0xffffc3ffffffffffULL, +0xffffc7ffffffffffULL, +0xffffcfffffffffffULL, +0xffffdfffffffffffULL +}, +{ +0xffff800000000000ULL, +0xffff800000000001ULL, +0xffff800000000003ULL, +0xffff800000000007ULL, +0xffff80000000000fULL, +0xffff80000000001fULL, +0xffff80000000003fULL, +0xffff80000000007fULL, +0xffff8000000000ffULL, +0xffff8000000001ffULL, +0xffff8000000003ffULL, +0xffff8000000007ffULL, +0xffff800000000fffULL, +0xffff800000001fffULL, +0xffff800000003fffULL, +0xffff800000007fffULL, +0xffff80000000ffffULL, +0xffff80000001ffffULL, +0xffff80000003ffffULL, +0xffff80000007ffffULL, +0xffff8000000fffffULL, +0xffff8000001fffffULL, +0xffff8000003fffffULL, +0xffff8000007fffffULL, +0xffff800000ffffffULL, +0xffff800001ffffffULL, +0xffff800003ffffffULL, +0xffff800007ffffffULL, +0xffff80000fffffffULL, +0xffff80001fffffffULL, +0xffff80003fffffffULL, +0xffff80007fffffffULL, +0xffff8000ffffffffULL, +0xffff8001ffffffffULL, +0xffff8003ffffffffULL, +0xffff8007ffffffffULL, +0xffff800fffffffffULL, +0xffff801fffffffffULL, +0xffff803fffffffffULL, +0xffff807fffffffffULL, +0xffff80ffffffffffULL, +0xffff81ffffffffffULL, +0xffff83ffffffffffULL, +0xffff87ffffffffffULL, +0xffff8fffffffffffULL, +0xffff9fffffffffffULL, +0xffffbfffffffffffULL +}, +{ +0xffff000000000000ULL, +0xffff000000000001ULL, +0xffff000000000003ULL, +0xffff000000000007ULL, +0xffff00000000000fULL, +0xffff00000000001fULL, +0xffff00000000003fULL, +0xffff00000000007fULL, +0xffff0000000000ffULL, +0xffff0000000001ffULL, +0xffff0000000003ffULL, +0xffff0000000007ffULL, +0xffff000000000fffULL, +0xffff000000001fffULL, +0xffff000000003fffULL, +0xffff000000007fffULL, +0xffff00000000ffffULL, +0xffff00000001ffffULL, +0xffff00000003ffffULL, +0xffff00000007ffffULL, +0xffff0000000fffffULL, +0xffff0000001fffffULL, +0xffff0000003fffffULL, +0xffff0000007fffffULL, +0xffff000000ffffffULL, +0xffff000001ffffffULL, +0xffff000003ffffffULL, +0xffff000007ffffffULL, +0xffff00000fffffffULL, +0xffff00001fffffffULL, +0xffff00003fffffffULL, +0xffff00007fffffffULL, +0xffff0000ffffffffULL, +0xffff0001ffffffffULL, +0xffff0003ffffffffULL, +0xffff0007ffffffffULL, +0xffff000fffffffffULL, +0xffff001fffffffffULL, +0xffff003fffffffffULL, +0xffff007fffffffffULL, +0xffff00ffffffffffULL, +0xffff01ffffffffffULL, +0xffff03ffffffffffULL, +0xffff07ffffffffffULL, +0xffff0fffffffffffULL, +0xffff1fffffffffffULL, +0xffff3fffffffffffULL, +0xffff7fffffffffffULL +}, +{ +0xfffe000000000000ULL, +0xfffe000000000001ULL, +0xfffe000000000003ULL, +0xfffe000000000007ULL, +0xfffe00000000000fULL, +0xfffe00000000001fULL, +0xfffe00000000003fULL, +0xfffe00000000007fULL, +0xfffe0000000000ffULL, +0xfffe0000000001ffULL, +0xfffe0000000003ffULL, +0xfffe0000000007ffULL, +0xfffe000000000fffULL, +0xfffe000000001fffULL, +0xfffe000000003fffULL, +0xfffe000000007fffULL, +0xfffe00000000ffffULL, +0xfffe00000001ffffULL, +0xfffe00000003ffffULL, +0xfffe00000007ffffULL, +0xfffe0000000fffffULL, +0xfffe0000001fffffULL, +0xfffe0000003fffffULL, +0xfffe0000007fffffULL, +0xfffe000000ffffffULL, +0xfffe000001ffffffULL, +0xfffe000003ffffffULL, +0xfffe000007ffffffULL, +0xfffe00000fffffffULL, +0xfffe00001fffffffULL, +0xfffe00003fffffffULL, +0xfffe00007fffffffULL, +0xfffe0000ffffffffULL, +0xfffe0001ffffffffULL, +0xfffe0003ffffffffULL, +0xfffe0007ffffffffULL, +0xfffe000fffffffffULL, +0xfffe001fffffffffULL, +0xfffe003fffffffffULL, +0xfffe007fffffffffULL, +0xfffe00ffffffffffULL, +0xfffe01ffffffffffULL, +0xfffe03ffffffffffULL, +0xfffe07ffffffffffULL, +0xfffe0fffffffffffULL, +0xfffe1fffffffffffULL, +0xfffe3fffffffffffULL, +0xfffe7fffffffffffULL, +0xfffeffffffffffffULL +}, +{ +0xfffc000000000000ULL, +0xfffc000000000001ULL, +0xfffc000000000003ULL, +0xfffc000000000007ULL, +0xfffc00000000000fULL, +0xfffc00000000001fULL, +0xfffc00000000003fULL, +0xfffc00000000007fULL, +0xfffc0000000000ffULL, +0xfffc0000000001ffULL, +0xfffc0000000003ffULL, +0xfffc0000000007ffULL, +0xfffc000000000fffULL, +0xfffc000000001fffULL, +0xfffc000000003fffULL, +0xfffc000000007fffULL, +0xfffc00000000ffffULL, +0xfffc00000001ffffULL, +0xfffc00000003ffffULL, +0xfffc00000007ffffULL, +0xfffc0000000fffffULL, +0xfffc0000001fffffULL, +0xfffc0000003fffffULL, +0xfffc0000007fffffULL, +0xfffc000000ffffffULL, +0xfffc000001ffffffULL, +0xfffc000003ffffffULL, +0xfffc000007ffffffULL, +0xfffc00000fffffffULL, +0xfffc00001fffffffULL, +0xfffc00003fffffffULL, +0xfffc00007fffffffULL, +0xfffc0000ffffffffULL, +0xfffc0001ffffffffULL, +0xfffc0003ffffffffULL, +0xfffc0007ffffffffULL, +0xfffc000fffffffffULL, +0xfffc001fffffffffULL, +0xfffc003fffffffffULL, +0xfffc007fffffffffULL, +0xfffc00ffffffffffULL, +0xfffc01ffffffffffULL, +0xfffc03ffffffffffULL, +0xfffc07ffffffffffULL, +0xfffc0fffffffffffULL, +0xfffc1fffffffffffULL, +0xfffc3fffffffffffULL, +0xfffc7fffffffffffULL, +0xfffcffffffffffffULL, +0xfffdffffffffffffULL +}, +{ +0xfff8000000000000ULL, +0xfff8000000000001ULL, +0xfff8000000000003ULL, +0xfff8000000000007ULL, +0xfff800000000000fULL, +0xfff800000000001fULL, +0xfff800000000003fULL, +0xfff800000000007fULL, +0xfff80000000000ffULL, +0xfff80000000001ffULL, +0xfff80000000003ffULL, +0xfff80000000007ffULL, +0xfff8000000000fffULL, +0xfff8000000001fffULL, +0xfff8000000003fffULL, +0xfff8000000007fffULL, +0xfff800000000ffffULL, +0xfff800000001ffffULL, +0xfff800000003ffffULL, +0xfff800000007ffffULL, +0xfff80000000fffffULL, +0xfff80000001fffffULL, +0xfff80000003fffffULL, +0xfff80000007fffffULL, +0xfff8000000ffffffULL, +0xfff8000001ffffffULL, +0xfff8000003ffffffULL, +0xfff8000007ffffffULL, +0xfff800000fffffffULL, +0xfff800001fffffffULL, +0xfff800003fffffffULL, +0xfff800007fffffffULL, +0xfff80000ffffffffULL, +0xfff80001ffffffffULL, +0xfff80003ffffffffULL, +0xfff80007ffffffffULL, +0xfff8000fffffffffULL, +0xfff8001fffffffffULL, +0xfff8003fffffffffULL, +0xfff8007fffffffffULL, +0xfff800ffffffffffULL, +0xfff801ffffffffffULL, +0xfff803ffffffffffULL, +0xfff807ffffffffffULL, +0xfff80fffffffffffULL, +0xfff81fffffffffffULL, +0xfff83fffffffffffULL, +0xfff87fffffffffffULL, +0xfff8ffffffffffffULL, +0xfff9ffffffffffffULL, +0xfffbffffffffffffULL +}, +{ +0xfff0000000000000ULL, +0xfff0000000000001ULL, +0xfff0000000000003ULL, +0xfff0000000000007ULL, +0xfff000000000000fULL, +0xfff000000000001fULL, +0xfff000000000003fULL, +0xfff000000000007fULL, +0xfff00000000000ffULL, +0xfff00000000001ffULL, +0xfff00000000003ffULL, +0xfff00000000007ffULL, +0xfff0000000000fffULL, +0xfff0000000001fffULL, +0xfff0000000003fffULL, +0xfff0000000007fffULL, +0xfff000000000ffffULL, +0xfff000000001ffffULL, +0xfff000000003ffffULL, +0xfff000000007ffffULL, +0xfff00000000fffffULL, +0xfff00000001fffffULL, +0xfff00000003fffffULL, +0xfff00000007fffffULL, +0xfff0000000ffffffULL, +0xfff0000001ffffffULL, +0xfff0000003ffffffULL, +0xfff0000007ffffffULL, +0xfff000000fffffffULL, +0xfff000001fffffffULL, +0xfff000003fffffffULL, +0xfff000007fffffffULL, +0xfff00000ffffffffULL, +0xfff00001ffffffffULL, +0xfff00003ffffffffULL, +0xfff00007ffffffffULL, +0xfff0000fffffffffULL, +0xfff0001fffffffffULL, +0xfff0003fffffffffULL, +0xfff0007fffffffffULL, +0xfff000ffffffffffULL, +0xfff001ffffffffffULL, +0xfff003ffffffffffULL, +0xfff007ffffffffffULL, +0xfff00fffffffffffULL, +0xfff01fffffffffffULL, +0xfff03fffffffffffULL, +0xfff07fffffffffffULL, +0xfff0ffffffffffffULL, +0xfff1ffffffffffffULL, +0xfff3ffffffffffffULL, +0xfff7ffffffffffffULL +}, +{ +0xffe0000000000000ULL, +0xffe0000000000001ULL, +0xffe0000000000003ULL, +0xffe0000000000007ULL, +0xffe000000000000fULL, +0xffe000000000001fULL, +0xffe000000000003fULL, +0xffe000000000007fULL, +0xffe00000000000ffULL, +0xffe00000000001ffULL, +0xffe00000000003ffULL, +0xffe00000000007ffULL, +0xffe0000000000fffULL, +0xffe0000000001fffULL, +0xffe0000000003fffULL, +0xffe0000000007fffULL, +0xffe000000000ffffULL, +0xffe000000001ffffULL, +0xffe000000003ffffULL, +0xffe000000007ffffULL, +0xffe00000000fffffULL, +0xffe00000001fffffULL, +0xffe00000003fffffULL, +0xffe00000007fffffULL, +0xffe0000000ffffffULL, +0xffe0000001ffffffULL, +0xffe0000003ffffffULL, +0xffe0000007ffffffULL, +0xffe000000fffffffULL, +0xffe000001fffffffULL, +0xffe000003fffffffULL, +0xffe000007fffffffULL, +0xffe00000ffffffffULL, +0xffe00001ffffffffULL, +0xffe00003ffffffffULL, +0xffe00007ffffffffULL, +0xffe0000fffffffffULL, +0xffe0001fffffffffULL, +0xffe0003fffffffffULL, +0xffe0007fffffffffULL, +0xffe000ffffffffffULL, +0xffe001ffffffffffULL, +0xffe003ffffffffffULL, +0xffe007ffffffffffULL, +0xffe00fffffffffffULL, +0xffe01fffffffffffULL, +0xffe03fffffffffffULL, +0xffe07fffffffffffULL, +0xffe0ffffffffffffULL, +0xffe1ffffffffffffULL, +0xffe3ffffffffffffULL, +0xffe7ffffffffffffULL, +0xffefffffffffffffULL +}, +{ +0xffc0000000000000ULL, +0xffc0000000000001ULL, +0xffc0000000000003ULL, +0xffc0000000000007ULL, +0xffc000000000000fULL, +0xffc000000000001fULL, +0xffc000000000003fULL, +0xffc000000000007fULL, +0xffc00000000000ffULL, +0xffc00000000001ffULL, +0xffc00000000003ffULL, +0xffc00000000007ffULL, +0xffc0000000000fffULL, +0xffc0000000001fffULL, +0xffc0000000003fffULL, +0xffc0000000007fffULL, +0xffc000000000ffffULL, +0xffc000000001ffffULL, +0xffc000000003ffffULL, +0xffc000000007ffffULL, +0xffc00000000fffffULL, +0xffc00000001fffffULL, +0xffc00000003fffffULL, +0xffc00000007fffffULL, +0xffc0000000ffffffULL, +0xffc0000001ffffffULL, +0xffc0000003ffffffULL, +0xffc0000007ffffffULL, +0xffc000000fffffffULL, +0xffc000001fffffffULL, +0xffc000003fffffffULL, +0xffc000007fffffffULL, +0xffc00000ffffffffULL, +0xffc00001ffffffffULL, +0xffc00003ffffffffULL, +0xffc00007ffffffffULL, +0xffc0000fffffffffULL, +0xffc0001fffffffffULL, +0xffc0003fffffffffULL, +0xffc0007fffffffffULL, +0xffc000ffffffffffULL, +0xffc001ffffffffffULL, +0xffc003ffffffffffULL, +0xffc007ffffffffffULL, +0xffc00fffffffffffULL, +0xffc01fffffffffffULL, +0xffc03fffffffffffULL, +0xffc07fffffffffffULL, +0xffc0ffffffffffffULL, +0xffc1ffffffffffffULL, +0xffc3ffffffffffffULL, +0xffc7ffffffffffffULL, +0xffcfffffffffffffULL, +0xffdfffffffffffffULL +}, +{ +0xff80000000000000ULL, +0xff80000000000001ULL, +0xff80000000000003ULL, +0xff80000000000007ULL, +0xff8000000000000fULL, +0xff8000000000001fULL, +0xff8000000000003fULL, +0xff8000000000007fULL, +0xff800000000000ffULL, +0xff800000000001ffULL, +0xff800000000003ffULL, +0xff800000000007ffULL, +0xff80000000000fffULL, +0xff80000000001fffULL, +0xff80000000003fffULL, +0xff80000000007fffULL, +0xff8000000000ffffULL, +0xff8000000001ffffULL, +0xff8000000003ffffULL, +0xff8000000007ffffULL, +0xff800000000fffffULL, +0xff800000001fffffULL, +0xff800000003fffffULL, +0xff800000007fffffULL, +0xff80000000ffffffULL, +0xff80000001ffffffULL, +0xff80000003ffffffULL, +0xff80000007ffffffULL, +0xff8000000fffffffULL, +0xff8000001fffffffULL, +0xff8000003fffffffULL, +0xff8000007fffffffULL, +0xff800000ffffffffULL, +0xff800001ffffffffULL, +0xff800003ffffffffULL, +0xff800007ffffffffULL, +0xff80000fffffffffULL, +0xff80001fffffffffULL, +0xff80003fffffffffULL, +0xff80007fffffffffULL, +0xff8000ffffffffffULL, +0xff8001ffffffffffULL, +0xff8003ffffffffffULL, +0xff8007ffffffffffULL, +0xff800fffffffffffULL, +0xff801fffffffffffULL, +0xff803fffffffffffULL, +0xff807fffffffffffULL, +0xff80ffffffffffffULL, +0xff81ffffffffffffULL, +0xff83ffffffffffffULL, +0xff87ffffffffffffULL, +0xff8fffffffffffffULL, +0xff9fffffffffffffULL, +0xffbfffffffffffffULL +}, +{ +0xff00000000000000ULL, +0xff00000000000001ULL, +0xff00000000000003ULL, +0xff00000000000007ULL, +0xff0000000000000fULL, +0xff0000000000001fULL, +0xff0000000000003fULL, +0xff0000000000007fULL, +0xff000000000000ffULL, +0xff000000000001ffULL, +0xff000000000003ffULL, +0xff000000000007ffULL, +0xff00000000000fffULL, +0xff00000000001fffULL, +0xff00000000003fffULL, +0xff00000000007fffULL, +0xff0000000000ffffULL, +0xff0000000001ffffULL, +0xff0000000003ffffULL, +0xff0000000007ffffULL, +0xff000000000fffffULL, +0xff000000001fffffULL, +0xff000000003fffffULL, +0xff000000007fffffULL, +0xff00000000ffffffULL, +0xff00000001ffffffULL, +0xff00000003ffffffULL, +0xff00000007ffffffULL, +0xff0000000fffffffULL, +0xff0000001fffffffULL, +0xff0000003fffffffULL, +0xff0000007fffffffULL, +0xff000000ffffffffULL, +0xff000001ffffffffULL, +0xff000003ffffffffULL, +0xff000007ffffffffULL, +0xff00000fffffffffULL, +0xff00001fffffffffULL, +0xff00003fffffffffULL, +0xff00007fffffffffULL, +0xff0000ffffffffffULL, +0xff0001ffffffffffULL, +0xff0003ffffffffffULL, +0xff0007ffffffffffULL, +0xff000fffffffffffULL, +0xff001fffffffffffULL, +0xff003fffffffffffULL, +0xff007fffffffffffULL, +0xff00ffffffffffffULL, +0xff01ffffffffffffULL, +0xff03ffffffffffffULL, +0xff07ffffffffffffULL, +0xff0fffffffffffffULL, +0xff1fffffffffffffULL, +0xff3fffffffffffffULL, +0xff7fffffffffffffULL +}, +{ +0xfe00000000000000ULL, +0xfe00000000000001ULL, +0xfe00000000000003ULL, +0xfe00000000000007ULL, +0xfe0000000000000fULL, +0xfe0000000000001fULL, +0xfe0000000000003fULL, +0xfe0000000000007fULL, +0xfe000000000000ffULL, +0xfe000000000001ffULL, +0xfe000000000003ffULL, +0xfe000000000007ffULL, +0xfe00000000000fffULL, +0xfe00000000001fffULL, +0xfe00000000003fffULL, +0xfe00000000007fffULL, +0xfe0000000000ffffULL, +0xfe0000000001ffffULL, +0xfe0000000003ffffULL, +0xfe0000000007ffffULL, +0xfe000000000fffffULL, +0xfe000000001fffffULL, +0xfe000000003fffffULL, +0xfe000000007fffffULL, +0xfe00000000ffffffULL, +0xfe00000001ffffffULL, +0xfe00000003ffffffULL, +0xfe00000007ffffffULL, +0xfe0000000fffffffULL, +0xfe0000001fffffffULL, +0xfe0000003fffffffULL, +0xfe0000007fffffffULL, +0xfe000000ffffffffULL, +0xfe000001ffffffffULL, +0xfe000003ffffffffULL, +0xfe000007ffffffffULL, +0xfe00000fffffffffULL, +0xfe00001fffffffffULL, +0xfe00003fffffffffULL, +0xfe00007fffffffffULL, +0xfe0000ffffffffffULL, +0xfe0001ffffffffffULL, +0xfe0003ffffffffffULL, +0xfe0007ffffffffffULL, +0xfe000fffffffffffULL, +0xfe001fffffffffffULL, +0xfe003fffffffffffULL, +0xfe007fffffffffffULL, +0xfe00ffffffffffffULL, +0xfe01ffffffffffffULL, +0xfe03ffffffffffffULL, +0xfe07ffffffffffffULL, +0xfe0fffffffffffffULL, +0xfe1fffffffffffffULL, +0xfe3fffffffffffffULL, +0xfe7fffffffffffffULL, +0xfeffffffffffffffULL +}, +{ +0xfc00000000000000ULL, +0xfc00000000000001ULL, +0xfc00000000000003ULL, +0xfc00000000000007ULL, +0xfc0000000000000fULL, +0xfc0000000000001fULL, +0xfc0000000000003fULL, +0xfc0000000000007fULL, +0xfc000000000000ffULL, +0xfc000000000001ffULL, +0xfc000000000003ffULL, +0xfc000000000007ffULL, +0xfc00000000000fffULL, +0xfc00000000001fffULL, +0xfc00000000003fffULL, +0xfc00000000007fffULL, +0xfc0000000000ffffULL, +0xfc0000000001ffffULL, +0xfc0000000003ffffULL, +0xfc0000000007ffffULL, +0xfc000000000fffffULL, +0xfc000000001fffffULL, +0xfc000000003fffffULL, +0xfc000000007fffffULL, +0xfc00000000ffffffULL, +0xfc00000001ffffffULL, +0xfc00000003ffffffULL, +0xfc00000007ffffffULL, +0xfc0000000fffffffULL, +0xfc0000001fffffffULL, +0xfc0000003fffffffULL, +0xfc0000007fffffffULL, +0xfc000000ffffffffULL, +0xfc000001ffffffffULL, +0xfc000003ffffffffULL, +0xfc000007ffffffffULL, +0xfc00000fffffffffULL, +0xfc00001fffffffffULL, +0xfc00003fffffffffULL, +0xfc00007fffffffffULL, +0xfc0000ffffffffffULL, +0xfc0001ffffffffffULL, +0xfc0003ffffffffffULL, +0xfc0007ffffffffffULL, +0xfc000fffffffffffULL, +0xfc001fffffffffffULL, +0xfc003fffffffffffULL, +0xfc007fffffffffffULL, +0xfc00ffffffffffffULL, +0xfc01ffffffffffffULL, +0xfc03ffffffffffffULL, +0xfc07ffffffffffffULL, +0xfc0fffffffffffffULL, +0xfc1fffffffffffffULL, +0xfc3fffffffffffffULL, +0xfc7fffffffffffffULL, +0xfcffffffffffffffULL, +0xfdffffffffffffffULL +}, +{ +0xf800000000000000ULL, +0xf800000000000001ULL, +0xf800000000000003ULL, +0xf800000000000007ULL, +0xf80000000000000fULL, +0xf80000000000001fULL, +0xf80000000000003fULL, +0xf80000000000007fULL, +0xf8000000000000ffULL, +0xf8000000000001ffULL, +0xf8000000000003ffULL, +0xf8000000000007ffULL, +0xf800000000000fffULL, +0xf800000000001fffULL, +0xf800000000003fffULL, +0xf800000000007fffULL, +0xf80000000000ffffULL, +0xf80000000001ffffULL, +0xf80000000003ffffULL, +0xf80000000007ffffULL, +0xf8000000000fffffULL, +0xf8000000001fffffULL, +0xf8000000003fffffULL, +0xf8000000007fffffULL, +0xf800000000ffffffULL, +0xf800000001ffffffULL, +0xf800000003ffffffULL, +0xf800000007ffffffULL, +0xf80000000fffffffULL, +0xf80000001fffffffULL, +0xf80000003fffffffULL, +0xf80000007fffffffULL, +0xf8000000ffffffffULL, +0xf8000001ffffffffULL, +0xf8000003ffffffffULL, +0xf8000007ffffffffULL, +0xf800000fffffffffULL, +0xf800001fffffffffULL, +0xf800003fffffffffULL, +0xf800007fffffffffULL, +0xf80000ffffffffffULL, +0xf80001ffffffffffULL, +0xf80003ffffffffffULL, +0xf80007ffffffffffULL, +0xf8000fffffffffffULL, +0xf8001fffffffffffULL, +0xf8003fffffffffffULL, +0xf8007fffffffffffULL, +0xf800ffffffffffffULL, +0xf801ffffffffffffULL, +0xf803ffffffffffffULL, +0xf807ffffffffffffULL, +0xf80fffffffffffffULL, +0xf81fffffffffffffULL, +0xf83fffffffffffffULL, +0xf87fffffffffffffULL, +0xf8ffffffffffffffULL, +0xf9ffffffffffffffULL, +0xfbffffffffffffffULL +}, +{ +0xf000000000000000ULL, +0xf000000000000001ULL, +0xf000000000000003ULL, +0xf000000000000007ULL, +0xf00000000000000fULL, +0xf00000000000001fULL, +0xf00000000000003fULL, +0xf00000000000007fULL, +0xf0000000000000ffULL, +0xf0000000000001ffULL, +0xf0000000000003ffULL, +0xf0000000000007ffULL, +0xf000000000000fffULL, +0xf000000000001fffULL, +0xf000000000003fffULL, +0xf000000000007fffULL, +0xf00000000000ffffULL, +0xf00000000001ffffULL, +0xf00000000003ffffULL, +0xf00000000007ffffULL, +0xf0000000000fffffULL, +0xf0000000001fffffULL, +0xf0000000003fffffULL, +0xf0000000007fffffULL, +0xf000000000ffffffULL, +0xf000000001ffffffULL, +0xf000000003ffffffULL, +0xf000000007ffffffULL, +0xf00000000fffffffULL, +0xf00000001fffffffULL, +0xf00000003fffffffULL, +0xf00000007fffffffULL, +0xf0000000ffffffffULL, +0xf0000001ffffffffULL, +0xf0000003ffffffffULL, +0xf0000007ffffffffULL, +0xf000000fffffffffULL, +0xf000001fffffffffULL, +0xf000003fffffffffULL, +0xf000007fffffffffULL, +0xf00000ffffffffffULL, +0xf00001ffffffffffULL, +0xf00003ffffffffffULL, +0xf00007ffffffffffULL, +0xf0000fffffffffffULL, +0xf0001fffffffffffULL, +0xf0003fffffffffffULL, +0xf0007fffffffffffULL, +0xf000ffffffffffffULL, +0xf001ffffffffffffULL, +0xf003ffffffffffffULL, +0xf007ffffffffffffULL, +0xf00fffffffffffffULL, +0xf01fffffffffffffULL, +0xf03fffffffffffffULL, +0xf07fffffffffffffULL, +0xf0ffffffffffffffULL, +0xf1ffffffffffffffULL, +0xf3ffffffffffffffULL, +0xf7ffffffffffffffULL +}, +{ +0xe000000000000000ULL, +0xe000000000000001ULL, +0xe000000000000003ULL, +0xe000000000000007ULL, +0xe00000000000000fULL, +0xe00000000000001fULL, +0xe00000000000003fULL, +0xe00000000000007fULL, +0xe0000000000000ffULL, +0xe0000000000001ffULL, +0xe0000000000003ffULL, +0xe0000000000007ffULL, +0xe000000000000fffULL, +0xe000000000001fffULL, +0xe000000000003fffULL, +0xe000000000007fffULL, +0xe00000000000ffffULL, +0xe00000000001ffffULL, +0xe00000000003ffffULL, +0xe00000000007ffffULL, +0xe0000000000fffffULL, +0xe0000000001fffffULL, +0xe0000000003fffffULL, +0xe0000000007fffffULL, +0xe000000000ffffffULL, +0xe000000001ffffffULL, +0xe000000003ffffffULL, +0xe000000007ffffffULL, +0xe00000000fffffffULL, +0xe00000001fffffffULL, +0xe00000003fffffffULL, +0xe00000007fffffffULL, +0xe0000000ffffffffULL, +0xe0000001ffffffffULL, +0xe0000003ffffffffULL, +0xe0000007ffffffffULL, +0xe000000fffffffffULL, +0xe000001fffffffffULL, +0xe000003fffffffffULL, +0xe000007fffffffffULL, +0xe00000ffffffffffULL, +0xe00001ffffffffffULL, +0xe00003ffffffffffULL, +0xe00007ffffffffffULL, +0xe0000fffffffffffULL, +0xe0001fffffffffffULL, +0xe0003fffffffffffULL, +0xe0007fffffffffffULL, +0xe000ffffffffffffULL, +0xe001ffffffffffffULL, +0xe003ffffffffffffULL, +0xe007ffffffffffffULL, +0xe00fffffffffffffULL, +0xe01fffffffffffffULL, +0xe03fffffffffffffULL, +0xe07fffffffffffffULL, +0xe0ffffffffffffffULL, +0xe1ffffffffffffffULL, +0xe3ffffffffffffffULL, +0xe7ffffffffffffffULL, +0xefffffffffffffffULL +}, +{ +0xc000000000000000ULL, +0xc000000000000001ULL, +0xc000000000000003ULL, +0xc000000000000007ULL, +0xc00000000000000fULL, +0xc00000000000001fULL, +0xc00000000000003fULL, +0xc00000000000007fULL, +0xc0000000000000ffULL, +0xc0000000000001ffULL, +0xc0000000000003ffULL, +0xc0000000000007ffULL, +0xc000000000000fffULL, +0xc000000000001fffULL, +0xc000000000003fffULL, +0xc000000000007fffULL, +0xc00000000000ffffULL, +0xc00000000001ffffULL, +0xc00000000003ffffULL, +0xc00000000007ffffULL, +0xc0000000000fffffULL, +0xc0000000001fffffULL, +0xc0000000003fffffULL, +0xc0000000007fffffULL, +0xc000000000ffffffULL, +0xc000000001ffffffULL, +0xc000000003ffffffULL, +0xc000000007ffffffULL, +0xc00000000fffffffULL, +0xc00000001fffffffULL, +0xc00000003fffffffULL, +0xc00000007fffffffULL, +0xc0000000ffffffffULL, +0xc0000001ffffffffULL, +0xc0000003ffffffffULL, +0xc0000007ffffffffULL, +0xc000000fffffffffULL, +0xc000001fffffffffULL, +0xc000003fffffffffULL, +0xc000007fffffffffULL, +0xc00000ffffffffffULL, +0xc00001ffffffffffULL, +0xc00003ffffffffffULL, +0xc00007ffffffffffULL, +0xc0000fffffffffffULL, +0xc0001fffffffffffULL, +0xc0003fffffffffffULL, +0xc0007fffffffffffULL, +0xc000ffffffffffffULL, +0xc001ffffffffffffULL, +0xc003ffffffffffffULL, +0xc007ffffffffffffULL, +0xc00fffffffffffffULL, +0xc01fffffffffffffULL, +0xc03fffffffffffffULL, +0xc07fffffffffffffULL, +0xc0ffffffffffffffULL, +0xc1ffffffffffffffULL, +0xc3ffffffffffffffULL, +0xc7ffffffffffffffULL, +0xcfffffffffffffffULL, +0xdfffffffffffffffULL +}, +{ +0x8000000000000000ULL, +0x8000000000000001ULL, +0x8000000000000003ULL, +0x8000000000000007ULL, +0x800000000000000fULL, +0x800000000000001fULL, +0x800000000000003fULL, +0x800000000000007fULL, +0x80000000000000ffULL, +0x80000000000001ffULL, +0x80000000000003ffULL, +0x80000000000007ffULL, +0x8000000000000fffULL, +0x8000000000001fffULL, +0x8000000000003fffULL, +0x8000000000007fffULL, +0x800000000000ffffULL, +0x800000000001ffffULL, +0x800000000003ffffULL, +0x800000000007ffffULL, +0x80000000000fffffULL, +0x80000000001fffffULL, +0x80000000003fffffULL, +0x80000000007fffffULL, +0x8000000000ffffffULL, +0x8000000001ffffffULL, +0x8000000003ffffffULL, +0x8000000007ffffffULL, +0x800000000fffffffULL, +0x800000001fffffffULL, +0x800000003fffffffULL, +0x800000007fffffffULL, +0x80000000ffffffffULL, +0x80000001ffffffffULL, +0x80000003ffffffffULL, +0x80000007ffffffffULL, +0x8000000fffffffffULL, +0x8000001fffffffffULL, +0x8000003fffffffffULL, +0x8000007fffffffffULL, +0x800000ffffffffffULL, +0x800001ffffffffffULL, +0x800003ffffffffffULL, +0x800007ffffffffffULL, +0x80000fffffffffffULL, +0x80001fffffffffffULL, +0x80003fffffffffffULL, +0x80007fffffffffffULL, +0x8000ffffffffffffULL, +0x8001ffffffffffffULL, +0x8003ffffffffffffULL, +0x8007ffffffffffffULL, +0x800fffffffffffffULL, +0x801fffffffffffffULL, +0x803fffffffffffffULL, +0x807fffffffffffffULL, +0x80ffffffffffffffULL, +0x81ffffffffffffffULL, +0x83ffffffffffffffULL, +0x87ffffffffffffffULL, +0x8fffffffffffffffULL, +0x9fffffffffffffffULL, +0xbfffffffffffffffULL +}, +{ +0x0ULL, +0x1ULL, +0x3ULL, +0x7ULL, +0xfULL, +0x1fULL, +0x3fULL, +0x7fULL, +0xffULL, +0x1ffULL, +0x3ffULL, +0x7ffULL, +0xfffULL, +0x1fffULL, +0x3fffULL, +0x7fffULL, +0xffffULL, +0x1ffffULL, +0x3ffffULL, +0x7ffffULL, +0xfffffULL, +0x1fffffULL, +0x3fffffULL, +0x7fffffULL, +0xffffffULL, +0x1ffffffULL, +0x3ffffffULL, +0x7ffffffULL, +0xfffffffULL, +0x1fffffffULL, +0x3fffffffULL, +0x7fffffffULL, +0xffffffffULL, +0x1ffffffffULL, +0x3ffffffffULL, +0x7ffffffffULL, +0xfffffffffULL, +0x1fffffffffULL, +0x3fffffffffULL, +0x7fffffffffULL, +0xffffffffffULL, +0x1ffffffffffULL, +0x3ffffffffffULL, +0x7ffffffffffULL, +0xfffffffffffULL, +0x1fffffffffffULL, +0x3fffffffffffULL, +0x7fffffffffffULL, +0xffffffffffffULL, +0x1ffffffffffffULL, +0x3ffffffffffffULL, +0x7ffffffffffffULL, +0xfffffffffffffULL, +0x1fffffffffffffULL, +0x3fffffffffffffULL, +0x7fffffffffffffULL, +0xffffffffffffffULL, +0x1ffffffffffffffULL, +0x3ffffffffffffffULL, +0x7ffffffffffffffULL, +0xfffffffffffffffULL, +0x1fffffffffffffffULL, +0x3fffffffffffffffULL, +0x7fffffffffffffffULL +} +}; + +#else //end of #ifndef WIN32 + +const uint_type mask_int[SC_INTWIDTH][SC_INTWIDTH] = +{ +{ +0xfffffffffffffffei64 +}, +{ +0xfffffffffffffffci64, +0xfffffffffffffffdi64 +}, +{ +0xfffffffffffffff8i64, +0xfffffffffffffff9i64, +0xfffffffffffffffbi64 +}, +{ +0xfffffffffffffff0i64, +0xfffffffffffffff1i64, +0xfffffffffffffff3i64, +0xfffffffffffffff7i64 +}, +{ +0xffffffffffffffe0i64, +0xffffffffffffffe1i64, +0xffffffffffffffe3i64, +0xffffffffffffffe7i64, +0xffffffffffffffefi64 +}, +{ +0xffffffffffffffc0i64, +0xffffffffffffffc1i64, +0xffffffffffffffc3i64, +0xffffffffffffffc7i64, +0xffffffffffffffcfi64, +0xffffffffffffffdfi64 +}, +{ +0xffffffffffffff80i64, +0xffffffffffffff81i64, +0xffffffffffffff83i64, +0xffffffffffffff87i64, +0xffffffffffffff8fi64, +0xffffffffffffff9fi64, +0xffffffffffffffbfi64 +}, +{ +0xffffffffffffff00i64, +0xffffffffffffff01i64, +0xffffffffffffff03i64, +0xffffffffffffff07i64, +0xffffffffffffff0fi64, +0xffffffffffffff1fi64, +0xffffffffffffff3fi64, +0xffffffffffffff7fi64 +}, +{ +0xfffffffffffffe00i64, +0xfffffffffffffe01i64, +0xfffffffffffffe03i64, +0xfffffffffffffe07i64, +0xfffffffffffffe0fi64, +0xfffffffffffffe1fi64, +0xfffffffffffffe3fi64, +0xfffffffffffffe7fi64, +0xfffffffffffffeffi64 +}, +{ +0xfffffffffffffc00i64, +0xfffffffffffffc01i64, +0xfffffffffffffc03i64, +0xfffffffffffffc07i64, +0xfffffffffffffc0fi64, +0xfffffffffffffc1fi64, +0xfffffffffffffc3fi64, +0xfffffffffffffc7fi64, +0xfffffffffffffcffi64, +0xfffffffffffffdffi64 +}, +{ +0xfffffffffffff800i64, +0xfffffffffffff801i64, +0xfffffffffffff803i64, +0xfffffffffffff807i64, +0xfffffffffffff80fi64, +0xfffffffffffff81fi64, +0xfffffffffffff83fi64, +0xfffffffffffff87fi64, +0xfffffffffffff8ffi64, +0xfffffffffffff9ffi64, +0xfffffffffffffbffi64 +}, +{ +0xfffffffffffff000i64, +0xfffffffffffff001i64, +0xfffffffffffff003i64, +0xfffffffffffff007i64, +0xfffffffffffff00fi64, +0xfffffffffffff01fi64, +0xfffffffffffff03fi64, +0xfffffffffffff07fi64, +0xfffffffffffff0ffi64, +0xfffffffffffff1ffi64, +0xfffffffffffff3ffi64, +0xfffffffffffff7ffi64 +}, +{ +0xffffffffffffe000i64, +0xffffffffffffe001i64, +0xffffffffffffe003i64, +0xffffffffffffe007i64, +0xffffffffffffe00fi64, +0xffffffffffffe01fi64, +0xffffffffffffe03fi64, +0xffffffffffffe07fi64, +0xffffffffffffe0ffi64, +0xffffffffffffe1ffi64, +0xffffffffffffe3ffi64, +0xffffffffffffe7ffi64, +0xffffffffffffefffi64 +}, +{ +0xffffffffffffc000i64, +0xffffffffffffc001i64, +0xffffffffffffc003i64, +0xffffffffffffc007i64, +0xffffffffffffc00fi64, +0xffffffffffffc01fi64, +0xffffffffffffc03fi64, +0xffffffffffffc07fi64, +0xffffffffffffc0ffi64, +0xffffffffffffc1ffi64, +0xffffffffffffc3ffi64, +0xffffffffffffc7ffi64, +0xffffffffffffcfffi64, +0xffffffffffffdfffi64 +}, +{ +0xffffffffffff8000i64, +0xffffffffffff8001i64, +0xffffffffffff8003i64, +0xffffffffffff8007i64, +0xffffffffffff800fi64, +0xffffffffffff801fi64, +0xffffffffffff803fi64, +0xffffffffffff807fi64, +0xffffffffffff80ffi64, +0xffffffffffff81ffi64, +0xffffffffffff83ffi64, +0xffffffffffff87ffi64, +0xffffffffffff8fffi64, +0xffffffffffff9fffi64, +0xffffffffffffbfffi64 +}, +{ +0xffffffffffff0000i64, +0xffffffffffff0001i64, +0xffffffffffff0003i64, +0xffffffffffff0007i64, +0xffffffffffff000fi64, +0xffffffffffff001fi64, +0xffffffffffff003fi64, +0xffffffffffff007fi64, +0xffffffffffff00ffi64, +0xffffffffffff01ffi64, +0xffffffffffff03ffi64, +0xffffffffffff07ffi64, +0xffffffffffff0fffi64, +0xffffffffffff1fffi64, +0xffffffffffff3fffi64, +0xffffffffffff7fffi64 +}, +{ +0xfffffffffffe0000i64, +0xfffffffffffe0001i64, +0xfffffffffffe0003i64, +0xfffffffffffe0007i64, +0xfffffffffffe000fi64, +0xfffffffffffe001fi64, +0xfffffffffffe003fi64, +0xfffffffffffe007fi64, +0xfffffffffffe00ffi64, +0xfffffffffffe01ffi64, +0xfffffffffffe03ffi64, +0xfffffffffffe07ffi64, +0xfffffffffffe0fffi64, +0xfffffffffffe1fffi64, +0xfffffffffffe3fffi64, +0xfffffffffffe7fffi64, +0xfffffffffffeffffi64 +}, +{ +0xfffffffffffc0000i64, +0xfffffffffffc0001i64, +0xfffffffffffc0003i64, +0xfffffffffffc0007i64, +0xfffffffffffc000fi64, +0xfffffffffffc001fi64, +0xfffffffffffc003fi64, +0xfffffffffffc007fi64, +0xfffffffffffc00ffi64, +0xfffffffffffc01ffi64, +0xfffffffffffc03ffi64, +0xfffffffffffc07ffi64, +0xfffffffffffc0fffi64, +0xfffffffffffc1fffi64, +0xfffffffffffc3fffi64, +0xfffffffffffc7fffi64, +0xfffffffffffcffffi64, +0xfffffffffffdffffi64 +}, +{ +0xfffffffffff80000i64, +0xfffffffffff80001i64, +0xfffffffffff80003i64, +0xfffffffffff80007i64, +0xfffffffffff8000fi64, +0xfffffffffff8001fi64, +0xfffffffffff8003fi64, +0xfffffffffff8007fi64, +0xfffffffffff800ffi64, +0xfffffffffff801ffi64, +0xfffffffffff803ffi64, +0xfffffffffff807ffi64, +0xfffffffffff80fffi64, +0xfffffffffff81fffi64, +0xfffffffffff83fffi64, +0xfffffffffff87fffi64, +0xfffffffffff8ffffi64, +0xfffffffffff9ffffi64, +0xfffffffffffbffffi64 +}, +{ +0xfffffffffff00000i64, +0xfffffffffff00001i64, +0xfffffffffff00003i64, +0xfffffffffff00007i64, +0xfffffffffff0000fi64, +0xfffffffffff0001fi64, +0xfffffffffff0003fi64, +0xfffffffffff0007fi64, +0xfffffffffff000ffi64, +0xfffffffffff001ffi64, +0xfffffffffff003ffi64, +0xfffffffffff007ffi64, +0xfffffffffff00fffi64, +0xfffffffffff01fffi64, +0xfffffffffff03fffi64, +0xfffffffffff07fffi64, +0xfffffffffff0ffffi64, +0xfffffffffff1ffffi64, +0xfffffffffff3ffffi64, +0xfffffffffff7ffffi64 +}, +{ +0xffffffffffe00000i64, +0xffffffffffe00001i64, +0xffffffffffe00003i64, +0xffffffffffe00007i64, +0xffffffffffe0000fi64, +0xffffffffffe0001fi64, +0xffffffffffe0003fi64, +0xffffffffffe0007fi64, +0xffffffffffe000ffi64, +0xffffffffffe001ffi64, +0xffffffffffe003ffi64, +0xffffffffffe007ffi64, +0xffffffffffe00fffi64, +0xffffffffffe01fffi64, +0xffffffffffe03fffi64, +0xffffffffffe07fffi64, +0xffffffffffe0ffffi64, +0xffffffffffe1ffffi64, +0xffffffffffe3ffffi64, +0xffffffffffe7ffffi64, +0xffffffffffefffffi64 +}, +{ +0xffffffffffc00000i64, +0xffffffffffc00001i64, +0xffffffffffc00003i64, +0xffffffffffc00007i64, +0xffffffffffc0000fi64, +0xffffffffffc0001fi64, +0xffffffffffc0003fi64, +0xffffffffffc0007fi64, +0xffffffffffc000ffi64, +0xffffffffffc001ffi64, +0xffffffffffc003ffi64, +0xffffffffffc007ffi64, +0xffffffffffc00fffi64, +0xffffffffffc01fffi64, +0xffffffffffc03fffi64, +0xffffffffffc07fffi64, +0xffffffffffc0ffffi64, +0xffffffffffc1ffffi64, +0xffffffffffc3ffffi64, +0xffffffffffc7ffffi64, +0xffffffffffcfffffi64, +0xffffffffffdfffffi64 +}, +{ +0xffffffffff800000i64, +0xffffffffff800001i64, +0xffffffffff800003i64, +0xffffffffff800007i64, +0xffffffffff80000fi64, +0xffffffffff80001fi64, +0xffffffffff80003fi64, +0xffffffffff80007fi64, +0xffffffffff8000ffi64, +0xffffffffff8001ffi64, +0xffffffffff8003ffi64, +0xffffffffff8007ffi64, +0xffffffffff800fffi64, +0xffffffffff801fffi64, +0xffffffffff803fffi64, +0xffffffffff807fffi64, +0xffffffffff80ffffi64, +0xffffffffff81ffffi64, +0xffffffffff83ffffi64, +0xffffffffff87ffffi64, +0xffffffffff8fffffi64, +0xffffffffff9fffffi64, +0xffffffffffbfffffi64 +}, +{ +0xffffffffff000000i64, +0xffffffffff000001i64, +0xffffffffff000003i64, +0xffffffffff000007i64, +0xffffffffff00000fi64, +0xffffffffff00001fi64, +0xffffffffff00003fi64, +0xffffffffff00007fi64, +0xffffffffff0000ffi64, +0xffffffffff0001ffi64, +0xffffffffff0003ffi64, +0xffffffffff0007ffi64, +0xffffffffff000fffi64, +0xffffffffff001fffi64, +0xffffffffff003fffi64, +0xffffffffff007fffi64, +0xffffffffff00ffffi64, +0xffffffffff01ffffi64, +0xffffffffff03ffffi64, +0xffffffffff07ffffi64, +0xffffffffff0fffffi64, +0xffffffffff1fffffi64, +0xffffffffff3fffffi64, +0xffffffffff7fffffi64 +}, +{ +0xfffffffffe000000i64, +0xfffffffffe000001i64, +0xfffffffffe000003i64, +0xfffffffffe000007i64, +0xfffffffffe00000fi64, +0xfffffffffe00001fi64, +0xfffffffffe00003fi64, +0xfffffffffe00007fi64, +0xfffffffffe0000ffi64, +0xfffffffffe0001ffi64, +0xfffffffffe0003ffi64, +0xfffffffffe0007ffi64, +0xfffffffffe000fffi64, +0xfffffffffe001fffi64, +0xfffffffffe003fffi64, +0xfffffffffe007fffi64, +0xfffffffffe00ffffi64, +0xfffffffffe01ffffi64, +0xfffffffffe03ffffi64, +0xfffffffffe07ffffi64, +0xfffffffffe0fffffi64, +0xfffffffffe1fffffi64, +0xfffffffffe3fffffi64, +0xfffffffffe7fffffi64, +0xfffffffffeffffffi64 +}, +{ +0xfffffffffc000000i64, +0xfffffffffc000001i64, +0xfffffffffc000003i64, +0xfffffffffc000007i64, +0xfffffffffc00000fi64, +0xfffffffffc00001fi64, +0xfffffffffc00003fi64, +0xfffffffffc00007fi64, +0xfffffffffc0000ffi64, +0xfffffffffc0001ffi64, +0xfffffffffc0003ffi64, +0xfffffffffc0007ffi64, +0xfffffffffc000fffi64, +0xfffffffffc001fffi64, +0xfffffffffc003fffi64, +0xfffffffffc007fffi64, +0xfffffffffc00ffffi64, +0xfffffffffc01ffffi64, +0xfffffffffc03ffffi64, +0xfffffffffc07ffffi64, +0xfffffffffc0fffffi64, +0xfffffffffc1fffffi64, +0xfffffffffc3fffffi64, +0xfffffffffc7fffffi64, +0xfffffffffcffffffi64, +0xfffffffffdffffffi64 +}, +{ +0xfffffffff8000000i64, +0xfffffffff8000001i64, +0xfffffffff8000003i64, +0xfffffffff8000007i64, +0xfffffffff800000fi64, +0xfffffffff800001fi64, +0xfffffffff800003fi64, +0xfffffffff800007fi64, +0xfffffffff80000ffi64, +0xfffffffff80001ffi64, +0xfffffffff80003ffi64, +0xfffffffff80007ffi64, +0xfffffffff8000fffi64, +0xfffffffff8001fffi64, +0xfffffffff8003fffi64, +0xfffffffff8007fffi64, +0xfffffffff800ffffi64, +0xfffffffff801ffffi64, +0xfffffffff803ffffi64, +0xfffffffff807ffffi64, +0xfffffffff80fffffi64, +0xfffffffff81fffffi64, +0xfffffffff83fffffi64, +0xfffffffff87fffffi64, +0xfffffffff8ffffffi64, +0xfffffffff9ffffffi64, +0xfffffffffbffffffi64 +}, +{ +0xfffffffff0000000i64, +0xfffffffff0000001i64, +0xfffffffff0000003i64, +0xfffffffff0000007i64, +0xfffffffff000000fi64, +0xfffffffff000001fi64, +0xfffffffff000003fi64, +0xfffffffff000007fi64, +0xfffffffff00000ffi64, +0xfffffffff00001ffi64, +0xfffffffff00003ffi64, +0xfffffffff00007ffi64, +0xfffffffff0000fffi64, +0xfffffffff0001fffi64, +0xfffffffff0003fffi64, +0xfffffffff0007fffi64, +0xfffffffff000ffffi64, +0xfffffffff001ffffi64, +0xfffffffff003ffffi64, +0xfffffffff007ffffi64, +0xfffffffff00fffffi64, +0xfffffffff01fffffi64, +0xfffffffff03fffffi64, +0xfffffffff07fffffi64, +0xfffffffff0ffffffi64, +0xfffffffff1ffffffi64, +0xfffffffff3ffffffi64, +0xfffffffff7ffffffi64 +}, +{ +0xffffffffe0000000i64, +0xffffffffe0000001i64, +0xffffffffe0000003i64, +0xffffffffe0000007i64, +0xffffffffe000000fi64, +0xffffffffe000001fi64, +0xffffffffe000003fi64, +0xffffffffe000007fi64, +0xffffffffe00000ffi64, +0xffffffffe00001ffi64, +0xffffffffe00003ffi64, +0xffffffffe00007ffi64, +0xffffffffe0000fffi64, +0xffffffffe0001fffi64, +0xffffffffe0003fffi64, +0xffffffffe0007fffi64, +0xffffffffe000ffffi64, +0xffffffffe001ffffi64, +0xffffffffe003ffffi64, +0xffffffffe007ffffi64, +0xffffffffe00fffffi64, +0xffffffffe01fffffi64, +0xffffffffe03fffffi64, +0xffffffffe07fffffi64, +0xffffffffe0ffffffi64, +0xffffffffe1ffffffi64, +0xffffffffe3ffffffi64, +0xffffffffe7ffffffi64, +0xffffffffefffffffi64 +}, +{ +0xffffffffc0000000i64, +0xffffffffc0000001i64, +0xffffffffc0000003i64, +0xffffffffc0000007i64, +0xffffffffc000000fi64, +0xffffffffc000001fi64, +0xffffffffc000003fi64, +0xffffffffc000007fi64, +0xffffffffc00000ffi64, +0xffffffffc00001ffi64, +0xffffffffc00003ffi64, +0xffffffffc00007ffi64, +0xffffffffc0000fffi64, +0xffffffffc0001fffi64, +0xffffffffc0003fffi64, +0xffffffffc0007fffi64, +0xffffffffc000ffffi64, +0xffffffffc001ffffi64, +0xffffffffc003ffffi64, +0xffffffffc007ffffi64, +0xffffffffc00fffffi64, +0xffffffffc01fffffi64, +0xffffffffc03fffffi64, +0xffffffffc07fffffi64, +0xffffffffc0ffffffi64, +0xffffffffc1ffffffi64, +0xffffffffc3ffffffi64, +0xffffffffc7ffffffi64, +0xffffffffcfffffffi64, +0xffffffffdfffffffi64 +}, +{ +0xffffffff80000000i64, +0xffffffff80000001i64, +0xffffffff80000003i64, +0xffffffff80000007i64, +0xffffffff8000000fi64, +0xffffffff8000001fi64, +0xffffffff8000003fi64, +0xffffffff8000007fi64, +0xffffffff800000ffi64, +0xffffffff800001ffi64, +0xffffffff800003ffi64, +0xffffffff800007ffi64, +0xffffffff80000fffi64, +0xffffffff80001fffi64, +0xffffffff80003fffi64, +0xffffffff80007fffi64, +0xffffffff8000ffffi64, +0xffffffff8001ffffi64, +0xffffffff8003ffffi64, +0xffffffff8007ffffi64, +0xffffffff800fffffi64, +0xffffffff801fffffi64, +0xffffffff803fffffi64, +0xffffffff807fffffi64, +0xffffffff80ffffffi64, +0xffffffff81ffffffi64, +0xffffffff83ffffffi64, +0xffffffff87ffffffi64, +0xffffffff8fffffffi64, +0xffffffff9fffffffi64, +0xffffffffbfffffffi64 +}, +{ +0xffffffff00000000i64, +0xffffffff00000001i64, +0xffffffff00000003i64, +0xffffffff00000007i64, +0xffffffff0000000fi64, +0xffffffff0000001fi64, +0xffffffff0000003fi64, +0xffffffff0000007fi64, +0xffffffff000000ffi64, +0xffffffff000001ffi64, +0xffffffff000003ffi64, +0xffffffff000007ffi64, +0xffffffff00000fffi64, +0xffffffff00001fffi64, +0xffffffff00003fffi64, +0xffffffff00007fffi64, +0xffffffff0000ffffi64, +0xffffffff0001ffffi64, +0xffffffff0003ffffi64, +0xffffffff0007ffffi64, +0xffffffff000fffffi64, +0xffffffff001fffffi64, +0xffffffff003fffffi64, +0xffffffff007fffffi64, +0xffffffff00ffffffi64, +0xffffffff01ffffffi64, +0xffffffff03ffffffi64, +0xffffffff07ffffffi64, +0xffffffff0fffffffi64, +0xffffffff1fffffffi64, +0xffffffff3fffffffi64, +0xffffffff7fffffffi64 +}, +{ +0xfffffffe00000000i64, +0xfffffffe00000001i64, +0xfffffffe00000003i64, +0xfffffffe00000007i64, +0xfffffffe0000000fi64, +0xfffffffe0000001fi64, +0xfffffffe0000003fi64, +0xfffffffe0000007fi64, +0xfffffffe000000ffi64, +0xfffffffe000001ffi64, +0xfffffffe000003ffi64, +0xfffffffe000007ffi64, +0xfffffffe00000fffi64, +0xfffffffe00001fffi64, +0xfffffffe00003fffi64, +0xfffffffe00007fffi64, +0xfffffffe0000ffffi64, +0xfffffffe0001ffffi64, +0xfffffffe0003ffffi64, +0xfffffffe0007ffffi64, +0xfffffffe000fffffi64, +0xfffffffe001fffffi64, +0xfffffffe003fffffi64, +0xfffffffe007fffffi64, +0xfffffffe00ffffffi64, +0xfffffffe01ffffffi64, +0xfffffffe03ffffffi64, +0xfffffffe07ffffffi64, +0xfffffffe0fffffffi64, +0xfffffffe1fffffffi64, +0xfffffffe3fffffffi64, +0xfffffffe7fffffffi64, +0xfffffffeffffffffi64 +}, +{ +0xfffffffc00000000i64, +0xfffffffc00000001i64, +0xfffffffc00000003i64, +0xfffffffc00000007i64, +0xfffffffc0000000fi64, +0xfffffffc0000001fi64, +0xfffffffc0000003fi64, +0xfffffffc0000007fi64, +0xfffffffc000000ffi64, +0xfffffffc000001ffi64, +0xfffffffc000003ffi64, +0xfffffffc000007ffi64, +0xfffffffc00000fffi64, +0xfffffffc00001fffi64, +0xfffffffc00003fffi64, +0xfffffffc00007fffi64, +0xfffffffc0000ffffi64, +0xfffffffc0001ffffi64, +0xfffffffc0003ffffi64, +0xfffffffc0007ffffi64, +0xfffffffc000fffffi64, +0xfffffffc001fffffi64, +0xfffffffc003fffffi64, +0xfffffffc007fffffi64, +0xfffffffc00ffffffi64, +0xfffffffc01ffffffi64, +0xfffffffc03ffffffi64, +0xfffffffc07ffffffi64, +0xfffffffc0fffffffi64, +0xfffffffc1fffffffi64, +0xfffffffc3fffffffi64, +0xfffffffc7fffffffi64, +0xfffffffcffffffffi64, +0xfffffffdffffffffi64 +}, +{ +0xfffffff800000000i64, +0xfffffff800000001i64, +0xfffffff800000003i64, +0xfffffff800000007i64, +0xfffffff80000000fi64, +0xfffffff80000001fi64, +0xfffffff80000003fi64, +0xfffffff80000007fi64, +0xfffffff8000000ffi64, +0xfffffff8000001ffi64, +0xfffffff8000003ffi64, +0xfffffff8000007ffi64, +0xfffffff800000fffi64, +0xfffffff800001fffi64, +0xfffffff800003fffi64, +0xfffffff800007fffi64, +0xfffffff80000ffffi64, +0xfffffff80001ffffi64, +0xfffffff80003ffffi64, +0xfffffff80007ffffi64, +0xfffffff8000fffffi64, +0xfffffff8001fffffi64, +0xfffffff8003fffffi64, +0xfffffff8007fffffi64, +0xfffffff800ffffffi64, +0xfffffff801ffffffi64, +0xfffffff803ffffffi64, +0xfffffff807ffffffi64, +0xfffffff80fffffffi64, +0xfffffff81fffffffi64, +0xfffffff83fffffffi64, +0xfffffff87fffffffi64, +0xfffffff8ffffffffi64, +0xfffffff9ffffffffi64, +0xfffffffbffffffffi64 +}, +{ +0xfffffff000000000i64, +0xfffffff000000001i64, +0xfffffff000000003i64, +0xfffffff000000007i64, +0xfffffff00000000fi64, +0xfffffff00000001fi64, +0xfffffff00000003fi64, +0xfffffff00000007fi64, +0xfffffff0000000ffi64, +0xfffffff0000001ffi64, +0xfffffff0000003ffi64, +0xfffffff0000007ffi64, +0xfffffff000000fffi64, +0xfffffff000001fffi64, +0xfffffff000003fffi64, +0xfffffff000007fffi64, +0xfffffff00000ffffi64, +0xfffffff00001ffffi64, +0xfffffff00003ffffi64, +0xfffffff00007ffffi64, +0xfffffff0000fffffi64, +0xfffffff0001fffffi64, +0xfffffff0003fffffi64, +0xfffffff0007fffffi64, +0xfffffff000ffffffi64, +0xfffffff001ffffffi64, +0xfffffff003ffffffi64, +0xfffffff007ffffffi64, +0xfffffff00fffffffi64, +0xfffffff01fffffffi64, +0xfffffff03fffffffi64, +0xfffffff07fffffffi64, +0xfffffff0ffffffffi64, +0xfffffff1ffffffffi64, +0xfffffff3ffffffffi64, +0xfffffff7ffffffffi64 +}, +{ +0xffffffe000000000i64, +0xffffffe000000001i64, +0xffffffe000000003i64, +0xffffffe000000007i64, +0xffffffe00000000fi64, +0xffffffe00000001fi64, +0xffffffe00000003fi64, +0xffffffe00000007fi64, +0xffffffe0000000ffi64, +0xffffffe0000001ffi64, +0xffffffe0000003ffi64, +0xffffffe0000007ffi64, +0xffffffe000000fffi64, +0xffffffe000001fffi64, +0xffffffe000003fffi64, +0xffffffe000007fffi64, +0xffffffe00000ffffi64, +0xffffffe00001ffffi64, +0xffffffe00003ffffi64, +0xffffffe00007ffffi64, +0xffffffe0000fffffi64, +0xffffffe0001fffffi64, +0xffffffe0003fffffi64, +0xffffffe0007fffffi64, +0xffffffe000ffffffi64, +0xffffffe001ffffffi64, +0xffffffe003ffffffi64, +0xffffffe007ffffffi64, +0xffffffe00fffffffi64, +0xffffffe01fffffffi64, +0xffffffe03fffffffi64, +0xffffffe07fffffffi64, +0xffffffe0ffffffffi64, +0xffffffe1ffffffffi64, +0xffffffe3ffffffffi64, +0xffffffe7ffffffffi64, +0xffffffefffffffffi64 +}, +{ +0xffffffc000000000i64, +0xffffffc000000001i64, +0xffffffc000000003i64, +0xffffffc000000007i64, +0xffffffc00000000fi64, +0xffffffc00000001fi64, +0xffffffc00000003fi64, +0xffffffc00000007fi64, +0xffffffc0000000ffi64, +0xffffffc0000001ffi64, +0xffffffc0000003ffi64, +0xffffffc0000007ffi64, +0xffffffc000000fffi64, +0xffffffc000001fffi64, +0xffffffc000003fffi64, +0xffffffc000007fffi64, +0xffffffc00000ffffi64, +0xffffffc00001ffffi64, +0xffffffc00003ffffi64, +0xffffffc00007ffffi64, +0xffffffc0000fffffi64, +0xffffffc0001fffffi64, +0xffffffc0003fffffi64, +0xffffffc0007fffffi64, +0xffffffc000ffffffi64, +0xffffffc001ffffffi64, +0xffffffc003ffffffi64, +0xffffffc007ffffffi64, +0xffffffc00fffffffi64, +0xffffffc01fffffffi64, +0xffffffc03fffffffi64, +0xffffffc07fffffffi64, +0xffffffc0ffffffffi64, +0xffffffc1ffffffffi64, +0xffffffc3ffffffffi64, +0xffffffc7ffffffffi64, +0xffffffcfffffffffi64, +0xffffffdfffffffffi64 +}, +{ +0xffffff8000000000i64, +0xffffff8000000001i64, +0xffffff8000000003i64, +0xffffff8000000007i64, +0xffffff800000000fi64, +0xffffff800000001fi64, +0xffffff800000003fi64, +0xffffff800000007fi64, +0xffffff80000000ffi64, +0xffffff80000001ffi64, +0xffffff80000003ffi64, +0xffffff80000007ffi64, +0xffffff8000000fffi64, +0xffffff8000001fffi64, +0xffffff8000003fffi64, +0xffffff8000007fffi64, +0xffffff800000ffffi64, +0xffffff800001ffffi64, +0xffffff800003ffffi64, +0xffffff800007ffffi64, +0xffffff80000fffffi64, +0xffffff80001fffffi64, +0xffffff80003fffffi64, +0xffffff80007fffffi64, +0xffffff8000ffffffi64, +0xffffff8001ffffffi64, +0xffffff8003ffffffi64, +0xffffff8007ffffffi64, +0xffffff800fffffffi64, +0xffffff801fffffffi64, +0xffffff803fffffffi64, +0xffffff807fffffffi64, +0xffffff80ffffffffi64, +0xffffff81ffffffffi64, +0xffffff83ffffffffi64, +0xffffff87ffffffffi64, +0xffffff8fffffffffi64, +0xffffff9fffffffffi64, +0xffffffbfffffffffi64 +}, +{ +0xffffff0000000000i64, +0xffffff0000000001i64, +0xffffff0000000003i64, +0xffffff0000000007i64, +0xffffff000000000fi64, +0xffffff000000001fi64, +0xffffff000000003fi64, +0xffffff000000007fi64, +0xffffff00000000ffi64, +0xffffff00000001ffi64, +0xffffff00000003ffi64, +0xffffff00000007ffi64, +0xffffff0000000fffi64, +0xffffff0000001fffi64, +0xffffff0000003fffi64, +0xffffff0000007fffi64, +0xffffff000000ffffi64, +0xffffff000001ffffi64, +0xffffff000003ffffi64, +0xffffff000007ffffi64, +0xffffff00000fffffi64, +0xffffff00001fffffi64, +0xffffff00003fffffi64, +0xffffff00007fffffi64, +0xffffff0000ffffffi64, +0xffffff0001ffffffi64, +0xffffff0003ffffffi64, +0xffffff0007ffffffi64, +0xffffff000fffffffi64, +0xffffff001fffffffi64, +0xffffff003fffffffi64, +0xffffff007fffffffi64, +0xffffff00ffffffffi64, +0xffffff01ffffffffi64, +0xffffff03ffffffffi64, +0xffffff07ffffffffi64, +0xffffff0fffffffffi64, +0xffffff1fffffffffi64, +0xffffff3fffffffffi64, +0xffffff7fffffffffi64 +}, +{ +0xfffffe0000000000i64, +0xfffffe0000000001i64, +0xfffffe0000000003i64, +0xfffffe0000000007i64, +0xfffffe000000000fi64, +0xfffffe000000001fi64, +0xfffffe000000003fi64, +0xfffffe000000007fi64, +0xfffffe00000000ffi64, +0xfffffe00000001ffi64, +0xfffffe00000003ffi64, +0xfffffe00000007ffi64, +0xfffffe0000000fffi64, +0xfffffe0000001fffi64, +0xfffffe0000003fffi64, +0xfffffe0000007fffi64, +0xfffffe000000ffffi64, +0xfffffe000001ffffi64, +0xfffffe000003ffffi64, +0xfffffe000007ffffi64, +0xfffffe00000fffffi64, +0xfffffe00001fffffi64, +0xfffffe00003fffffi64, +0xfffffe00007fffffi64, +0xfffffe0000ffffffi64, +0xfffffe0001ffffffi64, +0xfffffe0003ffffffi64, +0xfffffe0007ffffffi64, +0xfffffe000fffffffi64, +0xfffffe001fffffffi64, +0xfffffe003fffffffi64, +0xfffffe007fffffffi64, +0xfffffe00ffffffffi64, +0xfffffe01ffffffffi64, +0xfffffe03ffffffffi64, +0xfffffe07ffffffffi64, +0xfffffe0fffffffffi64, +0xfffffe1fffffffffi64, +0xfffffe3fffffffffi64, +0xfffffe7fffffffffi64, +0xfffffeffffffffffi64 +}, +{ +0xfffffc0000000000i64, +0xfffffc0000000001i64, +0xfffffc0000000003i64, +0xfffffc0000000007i64, +0xfffffc000000000fi64, +0xfffffc000000001fi64, +0xfffffc000000003fi64, +0xfffffc000000007fi64, +0xfffffc00000000ffi64, +0xfffffc00000001ffi64, +0xfffffc00000003ffi64, +0xfffffc00000007ffi64, +0xfffffc0000000fffi64, +0xfffffc0000001fffi64, +0xfffffc0000003fffi64, +0xfffffc0000007fffi64, +0xfffffc000000ffffi64, +0xfffffc000001ffffi64, +0xfffffc000003ffffi64, +0xfffffc000007ffffi64, +0xfffffc00000fffffi64, +0xfffffc00001fffffi64, +0xfffffc00003fffffi64, +0xfffffc00007fffffi64, +0xfffffc0000ffffffi64, +0xfffffc0001ffffffi64, +0xfffffc0003ffffffi64, +0xfffffc0007ffffffi64, +0xfffffc000fffffffi64, +0xfffffc001fffffffi64, +0xfffffc003fffffffi64, +0xfffffc007fffffffi64, +0xfffffc00ffffffffi64, +0xfffffc01ffffffffi64, +0xfffffc03ffffffffi64, +0xfffffc07ffffffffi64, +0xfffffc0fffffffffi64, +0xfffffc1fffffffffi64, +0xfffffc3fffffffffi64, +0xfffffc7fffffffffi64, +0xfffffcffffffffffi64, +0xfffffdffffffffffi64 +}, +{ +0xfffff80000000000i64, +0xfffff80000000001i64, +0xfffff80000000003i64, +0xfffff80000000007i64, +0xfffff8000000000fi64, +0xfffff8000000001fi64, +0xfffff8000000003fi64, +0xfffff8000000007fi64, +0xfffff800000000ffi64, +0xfffff800000001ffi64, +0xfffff800000003ffi64, +0xfffff800000007ffi64, +0xfffff80000000fffi64, +0xfffff80000001fffi64, +0xfffff80000003fffi64, +0xfffff80000007fffi64, +0xfffff8000000ffffi64, +0xfffff8000001ffffi64, +0xfffff8000003ffffi64, +0xfffff8000007ffffi64, +0xfffff800000fffffi64, +0xfffff800001fffffi64, +0xfffff800003fffffi64, +0xfffff800007fffffi64, +0xfffff80000ffffffi64, +0xfffff80001ffffffi64, +0xfffff80003ffffffi64, +0xfffff80007ffffffi64, +0xfffff8000fffffffi64, +0xfffff8001fffffffi64, +0xfffff8003fffffffi64, +0xfffff8007fffffffi64, +0xfffff800ffffffffi64, +0xfffff801ffffffffi64, +0xfffff803ffffffffi64, +0xfffff807ffffffffi64, +0xfffff80fffffffffi64, +0xfffff81fffffffffi64, +0xfffff83fffffffffi64, +0xfffff87fffffffffi64, +0xfffff8ffffffffffi64, +0xfffff9ffffffffffi64, +0xfffffbffffffffffi64 +}, +{ +0xfffff00000000000i64, +0xfffff00000000001i64, +0xfffff00000000003i64, +0xfffff00000000007i64, +0xfffff0000000000fi64, +0xfffff0000000001fi64, +0xfffff0000000003fi64, +0xfffff0000000007fi64, +0xfffff000000000ffi64, +0xfffff000000001ffi64, +0xfffff000000003ffi64, +0xfffff000000007ffi64, +0xfffff00000000fffi64, +0xfffff00000001fffi64, +0xfffff00000003fffi64, +0xfffff00000007fffi64, +0xfffff0000000ffffi64, +0xfffff0000001ffffi64, +0xfffff0000003ffffi64, +0xfffff0000007ffffi64, +0xfffff000000fffffi64, +0xfffff000001fffffi64, +0xfffff000003fffffi64, +0xfffff000007fffffi64, +0xfffff00000ffffffi64, +0xfffff00001ffffffi64, +0xfffff00003ffffffi64, +0xfffff00007ffffffi64, +0xfffff0000fffffffi64, +0xfffff0001fffffffi64, +0xfffff0003fffffffi64, +0xfffff0007fffffffi64, +0xfffff000ffffffffi64, +0xfffff001ffffffffi64, +0xfffff003ffffffffi64, +0xfffff007ffffffffi64, +0xfffff00fffffffffi64, +0xfffff01fffffffffi64, +0xfffff03fffffffffi64, +0xfffff07fffffffffi64, +0xfffff0ffffffffffi64, +0xfffff1ffffffffffi64, +0xfffff3ffffffffffi64, +0xfffff7ffffffffffi64 +}, +{ +0xffffe00000000000i64, +0xffffe00000000001i64, +0xffffe00000000003i64, +0xffffe00000000007i64, +0xffffe0000000000fi64, +0xffffe0000000001fi64, +0xffffe0000000003fi64, +0xffffe0000000007fi64, +0xffffe000000000ffi64, +0xffffe000000001ffi64, +0xffffe000000003ffi64, +0xffffe000000007ffi64, +0xffffe00000000fffi64, +0xffffe00000001fffi64, +0xffffe00000003fffi64, +0xffffe00000007fffi64, +0xffffe0000000ffffi64, +0xffffe0000001ffffi64, +0xffffe0000003ffffi64, +0xffffe0000007ffffi64, +0xffffe000000fffffi64, +0xffffe000001fffffi64, +0xffffe000003fffffi64, +0xffffe000007fffffi64, +0xffffe00000ffffffi64, +0xffffe00001ffffffi64, +0xffffe00003ffffffi64, +0xffffe00007ffffffi64, +0xffffe0000fffffffi64, +0xffffe0001fffffffi64, +0xffffe0003fffffffi64, +0xffffe0007fffffffi64, +0xffffe000ffffffffi64, +0xffffe001ffffffffi64, +0xffffe003ffffffffi64, +0xffffe007ffffffffi64, +0xffffe00fffffffffi64, +0xffffe01fffffffffi64, +0xffffe03fffffffffi64, +0xffffe07fffffffffi64, +0xffffe0ffffffffffi64, +0xffffe1ffffffffffi64, +0xffffe3ffffffffffi64, +0xffffe7ffffffffffi64, +0xffffefffffffffffi64 +}, +{ +0xffffc00000000000i64, +0xffffc00000000001i64, +0xffffc00000000003i64, +0xffffc00000000007i64, +0xffffc0000000000fi64, +0xffffc0000000001fi64, +0xffffc0000000003fi64, +0xffffc0000000007fi64, +0xffffc000000000ffi64, +0xffffc000000001ffi64, +0xffffc000000003ffi64, +0xffffc000000007ffi64, +0xffffc00000000fffi64, +0xffffc00000001fffi64, +0xffffc00000003fffi64, +0xffffc00000007fffi64, +0xffffc0000000ffffi64, +0xffffc0000001ffffi64, +0xffffc0000003ffffi64, +0xffffc0000007ffffi64, +0xffffc000000fffffi64, +0xffffc000001fffffi64, +0xffffc000003fffffi64, +0xffffc000007fffffi64, +0xffffc00000ffffffi64, +0xffffc00001ffffffi64, +0xffffc00003ffffffi64, +0xffffc00007ffffffi64, +0xffffc0000fffffffi64, +0xffffc0001fffffffi64, +0xffffc0003fffffffi64, +0xffffc0007fffffffi64, +0xffffc000ffffffffi64, +0xffffc001ffffffffi64, +0xffffc003ffffffffi64, +0xffffc007ffffffffi64, +0xffffc00fffffffffi64, +0xffffc01fffffffffi64, +0xffffc03fffffffffi64, +0xffffc07fffffffffi64, +0xffffc0ffffffffffi64, +0xffffc1ffffffffffi64, +0xffffc3ffffffffffi64, +0xffffc7ffffffffffi64, +0xffffcfffffffffffi64, +0xffffdfffffffffffi64 +}, +{ +0xffff800000000000i64, +0xffff800000000001i64, +0xffff800000000003i64, +0xffff800000000007i64, +0xffff80000000000fi64, +0xffff80000000001fi64, +0xffff80000000003fi64, +0xffff80000000007fi64, +0xffff8000000000ffi64, +0xffff8000000001ffi64, +0xffff8000000003ffi64, +0xffff8000000007ffi64, +0xffff800000000fffi64, +0xffff800000001fffi64, +0xffff800000003fffi64, +0xffff800000007fffi64, +0xffff80000000ffffi64, +0xffff80000001ffffi64, +0xffff80000003ffffi64, +0xffff80000007ffffi64, +0xffff8000000fffffi64, +0xffff8000001fffffi64, +0xffff8000003fffffi64, +0xffff8000007fffffi64, +0xffff800000ffffffi64, +0xffff800001ffffffi64, +0xffff800003ffffffi64, +0xffff800007ffffffi64, +0xffff80000fffffffi64, +0xffff80001fffffffi64, +0xffff80003fffffffi64, +0xffff80007fffffffi64, +0xffff8000ffffffffi64, +0xffff8001ffffffffi64, +0xffff8003ffffffffi64, +0xffff8007ffffffffi64, +0xffff800fffffffffi64, +0xffff801fffffffffi64, +0xffff803fffffffffi64, +0xffff807fffffffffi64, +0xffff80ffffffffffi64, +0xffff81ffffffffffi64, +0xffff83ffffffffffi64, +0xffff87ffffffffffi64, +0xffff8fffffffffffi64, +0xffff9fffffffffffi64, +0xffffbfffffffffffi64 +}, +{ +0xffff000000000000i64, +0xffff000000000001i64, +0xffff000000000003i64, +0xffff000000000007i64, +0xffff00000000000fi64, +0xffff00000000001fi64, +0xffff00000000003fi64, +0xffff00000000007fi64, +0xffff0000000000ffi64, +0xffff0000000001ffi64, +0xffff0000000003ffi64, +0xffff0000000007ffi64, +0xffff000000000fffi64, +0xffff000000001fffi64, +0xffff000000003fffi64, +0xffff000000007fffi64, +0xffff00000000ffffi64, +0xffff00000001ffffi64, +0xffff00000003ffffi64, +0xffff00000007ffffi64, +0xffff0000000fffffi64, +0xffff0000001fffffi64, +0xffff0000003fffffi64, +0xffff0000007fffffi64, +0xffff000000ffffffi64, +0xffff000001ffffffi64, +0xffff000003ffffffi64, +0xffff000007ffffffi64, +0xffff00000fffffffi64, +0xffff00001fffffffi64, +0xffff00003fffffffi64, +0xffff00007fffffffi64, +0xffff0000ffffffffi64, +0xffff0001ffffffffi64, +0xffff0003ffffffffi64, +0xffff0007ffffffffi64, +0xffff000fffffffffi64, +0xffff001fffffffffi64, +0xffff003fffffffffi64, +0xffff007fffffffffi64, +0xffff00ffffffffffi64, +0xffff01ffffffffffi64, +0xffff03ffffffffffi64, +0xffff07ffffffffffi64, +0xffff0fffffffffffi64, +0xffff1fffffffffffi64, +0xffff3fffffffffffi64, +0xffff7fffffffffffi64 +}, +{ +0xfffe000000000000i64, +0xfffe000000000001i64, +0xfffe000000000003i64, +0xfffe000000000007i64, +0xfffe00000000000fi64, +0xfffe00000000001fi64, +0xfffe00000000003fi64, +0xfffe00000000007fi64, +0xfffe0000000000ffi64, +0xfffe0000000001ffi64, +0xfffe0000000003ffi64, +0xfffe0000000007ffi64, +0xfffe000000000fffi64, +0xfffe000000001fffi64, +0xfffe000000003fffi64, +0xfffe000000007fffi64, +0xfffe00000000ffffi64, +0xfffe00000001ffffi64, +0xfffe00000003ffffi64, +0xfffe00000007ffffi64, +0xfffe0000000fffffi64, +0xfffe0000001fffffi64, +0xfffe0000003fffffi64, +0xfffe0000007fffffi64, +0xfffe000000ffffffi64, +0xfffe000001ffffffi64, +0xfffe000003ffffffi64, +0xfffe000007ffffffi64, +0xfffe00000fffffffi64, +0xfffe00001fffffffi64, +0xfffe00003fffffffi64, +0xfffe00007fffffffi64, +0xfffe0000ffffffffi64, +0xfffe0001ffffffffi64, +0xfffe0003ffffffffi64, +0xfffe0007ffffffffi64, +0xfffe000fffffffffi64, +0xfffe001fffffffffi64, +0xfffe003fffffffffi64, +0xfffe007fffffffffi64, +0xfffe00ffffffffffi64, +0xfffe01ffffffffffi64, +0xfffe03ffffffffffi64, +0xfffe07ffffffffffi64, +0xfffe0fffffffffffi64, +0xfffe1fffffffffffi64, +0xfffe3fffffffffffi64, +0xfffe7fffffffffffi64, +0xfffeffffffffffffi64 +}, +{ +0xfffc000000000000i64, +0xfffc000000000001i64, +0xfffc000000000003i64, +0xfffc000000000007i64, +0xfffc00000000000fi64, +0xfffc00000000001fi64, +0xfffc00000000003fi64, +0xfffc00000000007fi64, +0xfffc0000000000ffi64, +0xfffc0000000001ffi64, +0xfffc0000000003ffi64, +0xfffc0000000007ffi64, +0xfffc000000000fffi64, +0xfffc000000001fffi64, +0xfffc000000003fffi64, +0xfffc000000007fffi64, +0xfffc00000000ffffi64, +0xfffc00000001ffffi64, +0xfffc00000003ffffi64, +0xfffc00000007ffffi64, +0xfffc0000000fffffi64, +0xfffc0000001fffffi64, +0xfffc0000003fffffi64, +0xfffc0000007fffffi64, +0xfffc000000ffffffi64, +0xfffc000001ffffffi64, +0xfffc000003ffffffi64, +0xfffc000007ffffffi64, +0xfffc00000fffffffi64, +0xfffc00001fffffffi64, +0xfffc00003fffffffi64, +0xfffc00007fffffffi64, +0xfffc0000ffffffffi64, +0xfffc0001ffffffffi64, +0xfffc0003ffffffffi64, +0xfffc0007ffffffffi64, +0xfffc000fffffffffi64, +0xfffc001fffffffffi64, +0xfffc003fffffffffi64, +0xfffc007fffffffffi64, +0xfffc00ffffffffffi64, +0xfffc01ffffffffffi64, +0xfffc03ffffffffffi64, +0xfffc07ffffffffffi64, +0xfffc0fffffffffffi64, +0xfffc1fffffffffffi64, +0xfffc3fffffffffffi64, +0xfffc7fffffffffffi64, +0xfffcffffffffffffi64, +0xfffdffffffffffffi64 +}, +{ +0xfff8000000000000i64, +0xfff8000000000001i64, +0xfff8000000000003i64, +0xfff8000000000007i64, +0xfff800000000000fi64, +0xfff800000000001fi64, +0xfff800000000003fi64, +0xfff800000000007fi64, +0xfff80000000000ffi64, +0xfff80000000001ffi64, +0xfff80000000003ffi64, +0xfff80000000007ffi64, +0xfff8000000000fffi64, +0xfff8000000001fffi64, +0xfff8000000003fffi64, +0xfff8000000007fffi64, +0xfff800000000ffffi64, +0xfff800000001ffffi64, +0xfff800000003ffffi64, +0xfff800000007ffffi64, +0xfff80000000fffffi64, +0xfff80000001fffffi64, +0xfff80000003fffffi64, +0xfff80000007fffffi64, +0xfff8000000ffffffi64, +0xfff8000001ffffffi64, +0xfff8000003ffffffi64, +0xfff8000007ffffffi64, +0xfff800000fffffffi64, +0xfff800001fffffffi64, +0xfff800003fffffffi64, +0xfff800007fffffffi64, +0xfff80000ffffffffi64, +0xfff80001ffffffffi64, +0xfff80003ffffffffi64, +0xfff80007ffffffffi64, +0xfff8000fffffffffi64, +0xfff8001fffffffffi64, +0xfff8003fffffffffi64, +0xfff8007fffffffffi64, +0xfff800ffffffffffi64, +0xfff801ffffffffffi64, +0xfff803ffffffffffi64, +0xfff807ffffffffffi64, +0xfff80fffffffffffi64, +0xfff81fffffffffffi64, +0xfff83fffffffffffi64, +0xfff87fffffffffffi64, +0xfff8ffffffffffffi64, +0xfff9ffffffffffffi64, +0xfffbffffffffffffi64 +}, +{ +0xfff0000000000000i64, +0xfff0000000000001i64, +0xfff0000000000003i64, +0xfff0000000000007i64, +0xfff000000000000fi64, +0xfff000000000001fi64, +0xfff000000000003fi64, +0xfff000000000007fi64, +0xfff00000000000ffi64, +0xfff00000000001ffi64, +0xfff00000000003ffi64, +0xfff00000000007ffi64, +0xfff0000000000fffi64, +0xfff0000000001fffi64, +0xfff0000000003fffi64, +0xfff0000000007fffi64, +0xfff000000000ffffi64, +0xfff000000001ffffi64, +0xfff000000003ffffi64, +0xfff000000007ffffi64, +0xfff00000000fffffi64, +0xfff00000001fffffi64, +0xfff00000003fffffi64, +0xfff00000007fffffi64, +0xfff0000000ffffffi64, +0xfff0000001ffffffi64, +0xfff0000003ffffffi64, +0xfff0000007ffffffi64, +0xfff000000fffffffi64, +0xfff000001fffffffi64, +0xfff000003fffffffi64, +0xfff000007fffffffi64, +0xfff00000ffffffffi64, +0xfff00001ffffffffi64, +0xfff00003ffffffffi64, +0xfff00007ffffffffi64, +0xfff0000fffffffffi64, +0xfff0001fffffffffi64, +0xfff0003fffffffffi64, +0xfff0007fffffffffi64, +0xfff000ffffffffffi64, +0xfff001ffffffffffi64, +0xfff003ffffffffffi64, +0xfff007ffffffffffi64, +0xfff00fffffffffffi64, +0xfff01fffffffffffi64, +0xfff03fffffffffffi64, +0xfff07fffffffffffi64, +0xfff0ffffffffffffi64, +0xfff1ffffffffffffi64, +0xfff3ffffffffffffi64, +0xfff7ffffffffffffi64 +}, +{ +0xffe0000000000000i64, +0xffe0000000000001i64, +0xffe0000000000003i64, +0xffe0000000000007i64, +0xffe000000000000fi64, +0xffe000000000001fi64, +0xffe000000000003fi64, +0xffe000000000007fi64, +0xffe00000000000ffi64, +0xffe00000000001ffi64, +0xffe00000000003ffi64, +0xffe00000000007ffi64, +0xffe0000000000fffi64, +0xffe0000000001fffi64, +0xffe0000000003fffi64, +0xffe0000000007fffi64, +0xffe000000000ffffi64, +0xffe000000001ffffi64, +0xffe000000003ffffi64, +0xffe000000007ffffi64, +0xffe00000000fffffi64, +0xffe00000001fffffi64, +0xffe00000003fffffi64, +0xffe00000007fffffi64, +0xffe0000000ffffffi64, +0xffe0000001ffffffi64, +0xffe0000003ffffffi64, +0xffe0000007ffffffi64, +0xffe000000fffffffi64, +0xffe000001fffffffi64, +0xffe000003fffffffi64, +0xffe000007fffffffi64, +0xffe00000ffffffffi64, +0xffe00001ffffffffi64, +0xffe00003ffffffffi64, +0xffe00007ffffffffi64, +0xffe0000fffffffffi64, +0xffe0001fffffffffi64, +0xffe0003fffffffffi64, +0xffe0007fffffffffi64, +0xffe000ffffffffffi64, +0xffe001ffffffffffi64, +0xffe003ffffffffffi64, +0xffe007ffffffffffi64, +0xffe00fffffffffffi64, +0xffe01fffffffffffi64, +0xffe03fffffffffffi64, +0xffe07fffffffffffi64, +0xffe0ffffffffffffi64, +0xffe1ffffffffffffi64, +0xffe3ffffffffffffi64, +0xffe7ffffffffffffi64, +0xffefffffffffffffi64 +}, +{ +0xffc0000000000000i64, +0xffc0000000000001i64, +0xffc0000000000003i64, +0xffc0000000000007i64, +0xffc000000000000fi64, +0xffc000000000001fi64, +0xffc000000000003fi64, +0xffc000000000007fi64, +0xffc00000000000ffi64, +0xffc00000000001ffi64, +0xffc00000000003ffi64, +0xffc00000000007ffi64, +0xffc0000000000fffi64, +0xffc0000000001fffi64, +0xffc0000000003fffi64, +0xffc0000000007fffi64, +0xffc000000000ffffi64, +0xffc000000001ffffi64, +0xffc000000003ffffi64, +0xffc000000007ffffi64, +0xffc00000000fffffi64, +0xffc00000001fffffi64, +0xffc00000003fffffi64, +0xffc00000007fffffi64, +0xffc0000000ffffffi64, +0xffc0000001ffffffi64, +0xffc0000003ffffffi64, +0xffc0000007ffffffi64, +0xffc000000fffffffi64, +0xffc000001fffffffi64, +0xffc000003fffffffi64, +0xffc000007fffffffi64, +0xffc00000ffffffffi64, +0xffc00001ffffffffi64, +0xffc00003ffffffffi64, +0xffc00007ffffffffi64, +0xffc0000fffffffffi64, +0xffc0001fffffffffi64, +0xffc0003fffffffffi64, +0xffc0007fffffffffi64, +0xffc000ffffffffffi64, +0xffc001ffffffffffi64, +0xffc003ffffffffffi64, +0xffc007ffffffffffi64, +0xffc00fffffffffffi64, +0xffc01fffffffffffi64, +0xffc03fffffffffffi64, +0xffc07fffffffffffi64, +0xffc0ffffffffffffi64, +0xffc1ffffffffffffi64, +0xffc3ffffffffffffi64, +0xffc7ffffffffffffi64, +0xffcfffffffffffffi64, +0xffdfffffffffffffi64 +}, +{ +0xff80000000000000i64, +0xff80000000000001i64, +0xff80000000000003i64, +0xff80000000000007i64, +0xff8000000000000fi64, +0xff8000000000001fi64, +0xff8000000000003fi64, +0xff8000000000007fi64, +0xff800000000000ffi64, +0xff800000000001ffi64, +0xff800000000003ffi64, +0xff800000000007ffi64, +0xff80000000000fffi64, +0xff80000000001fffi64, +0xff80000000003fffi64, +0xff80000000007fffi64, +0xff8000000000ffffi64, +0xff8000000001ffffi64, +0xff8000000003ffffi64, +0xff8000000007ffffi64, +0xff800000000fffffi64, +0xff800000001fffffi64, +0xff800000003fffffi64, +0xff800000007fffffi64, +0xff80000000ffffffi64, +0xff80000001ffffffi64, +0xff80000003ffffffi64, +0xff80000007ffffffi64, +0xff8000000fffffffi64, +0xff8000001fffffffi64, +0xff8000003fffffffi64, +0xff8000007fffffffi64, +0xff800000ffffffffi64, +0xff800001ffffffffi64, +0xff800003ffffffffi64, +0xff800007ffffffffi64, +0xff80000fffffffffi64, +0xff80001fffffffffi64, +0xff80003fffffffffi64, +0xff80007fffffffffi64, +0xff8000ffffffffffi64, +0xff8001ffffffffffi64, +0xff8003ffffffffffi64, +0xff8007ffffffffffi64, +0xff800fffffffffffi64, +0xff801fffffffffffi64, +0xff803fffffffffffi64, +0xff807fffffffffffi64, +0xff80ffffffffffffi64, +0xff81ffffffffffffi64, +0xff83ffffffffffffi64, +0xff87ffffffffffffi64, +0xff8fffffffffffffi64, +0xff9fffffffffffffi64, +0xffbfffffffffffffi64 +}, +{ +0xff00000000000000i64, +0xff00000000000001i64, +0xff00000000000003i64, +0xff00000000000007i64, +0xff0000000000000fi64, +0xff0000000000001fi64, +0xff0000000000003fi64, +0xff0000000000007fi64, +0xff000000000000ffi64, +0xff000000000001ffi64, +0xff000000000003ffi64, +0xff000000000007ffi64, +0xff00000000000fffi64, +0xff00000000001fffi64, +0xff00000000003fffi64, +0xff00000000007fffi64, +0xff0000000000ffffi64, +0xff0000000001ffffi64, +0xff0000000003ffffi64, +0xff0000000007ffffi64, +0xff000000000fffffi64, +0xff000000001fffffi64, +0xff000000003fffffi64, +0xff000000007fffffi64, +0xff00000000ffffffi64, +0xff00000001ffffffi64, +0xff00000003ffffffi64, +0xff00000007ffffffi64, +0xff0000000fffffffi64, +0xff0000001fffffffi64, +0xff0000003fffffffi64, +0xff0000007fffffffi64, +0xff000000ffffffffi64, +0xff000001ffffffffi64, +0xff000003ffffffffi64, +0xff000007ffffffffi64, +0xff00000fffffffffi64, +0xff00001fffffffffi64, +0xff00003fffffffffi64, +0xff00007fffffffffi64, +0xff0000ffffffffffi64, +0xff0001ffffffffffi64, +0xff0003ffffffffffi64, +0xff0007ffffffffffi64, +0xff000fffffffffffi64, +0xff001fffffffffffi64, +0xff003fffffffffffi64, +0xff007fffffffffffi64, +0xff00ffffffffffffi64, +0xff01ffffffffffffi64, +0xff03ffffffffffffi64, +0xff07ffffffffffffi64, +0xff0fffffffffffffi64, +0xff1fffffffffffffi64, +0xff3fffffffffffffi64, +0xff7fffffffffffffi64 +}, +{ +0xfe00000000000000i64, +0xfe00000000000001i64, +0xfe00000000000003i64, +0xfe00000000000007i64, +0xfe0000000000000fi64, +0xfe0000000000001fi64, +0xfe0000000000003fi64, +0xfe0000000000007fi64, +0xfe000000000000ffi64, +0xfe000000000001ffi64, +0xfe000000000003ffi64, +0xfe000000000007ffi64, +0xfe00000000000fffi64, +0xfe00000000001fffi64, +0xfe00000000003fffi64, +0xfe00000000007fffi64, +0xfe0000000000ffffi64, +0xfe0000000001ffffi64, +0xfe0000000003ffffi64, +0xfe0000000007ffffi64, +0xfe000000000fffffi64, +0xfe000000001fffffi64, +0xfe000000003fffffi64, +0xfe000000007fffffi64, +0xfe00000000ffffffi64, +0xfe00000001ffffffi64, +0xfe00000003ffffffi64, +0xfe00000007ffffffi64, +0xfe0000000fffffffi64, +0xfe0000001fffffffi64, +0xfe0000003fffffffi64, +0xfe0000007fffffffi64, +0xfe000000ffffffffi64, +0xfe000001ffffffffi64, +0xfe000003ffffffffi64, +0xfe000007ffffffffi64, +0xfe00000fffffffffi64, +0xfe00001fffffffffi64, +0xfe00003fffffffffi64, +0xfe00007fffffffffi64, +0xfe0000ffffffffffi64, +0xfe0001ffffffffffi64, +0xfe0003ffffffffffi64, +0xfe0007ffffffffffi64, +0xfe000fffffffffffi64, +0xfe001fffffffffffi64, +0xfe003fffffffffffi64, +0xfe007fffffffffffi64, +0xfe00ffffffffffffi64, +0xfe01ffffffffffffi64, +0xfe03ffffffffffffi64, +0xfe07ffffffffffffi64, +0xfe0fffffffffffffi64, +0xfe1fffffffffffffi64, +0xfe3fffffffffffffi64, +0xfe7fffffffffffffi64, +0xfeffffffffffffffi64 +}, +{ +0xfc00000000000000i64, +0xfc00000000000001i64, +0xfc00000000000003i64, +0xfc00000000000007i64, +0xfc0000000000000fi64, +0xfc0000000000001fi64, +0xfc0000000000003fi64, +0xfc0000000000007fi64, +0xfc000000000000ffi64, +0xfc000000000001ffi64, +0xfc000000000003ffi64, +0xfc000000000007ffi64, +0xfc00000000000fffi64, +0xfc00000000001fffi64, +0xfc00000000003fffi64, +0xfc00000000007fffi64, +0xfc0000000000ffffi64, +0xfc0000000001ffffi64, +0xfc0000000003ffffi64, +0xfc0000000007ffffi64, +0xfc000000000fffffi64, +0xfc000000001fffffi64, +0xfc000000003fffffi64, +0xfc000000007fffffi64, +0xfc00000000ffffffi64, +0xfc00000001ffffffi64, +0xfc00000003ffffffi64, +0xfc00000007ffffffi64, +0xfc0000000fffffffi64, +0xfc0000001fffffffi64, +0xfc0000003fffffffi64, +0xfc0000007fffffffi64, +0xfc000000ffffffffi64, +0xfc000001ffffffffi64, +0xfc000003ffffffffi64, +0xfc000007ffffffffi64, +0xfc00000fffffffffi64, +0xfc00001fffffffffi64, +0xfc00003fffffffffi64, +0xfc00007fffffffffi64, +0xfc0000ffffffffffi64, +0xfc0001ffffffffffi64, +0xfc0003ffffffffffi64, +0xfc0007ffffffffffi64, +0xfc000fffffffffffi64, +0xfc001fffffffffffi64, +0xfc003fffffffffffi64, +0xfc007fffffffffffi64, +0xfc00ffffffffffffi64, +0xfc01ffffffffffffi64, +0xfc03ffffffffffffi64, +0xfc07ffffffffffffi64, +0xfc0fffffffffffffi64, +0xfc1fffffffffffffi64, +0xfc3fffffffffffffi64, +0xfc7fffffffffffffi64, +0xfcffffffffffffffi64, +0xfdffffffffffffffi64 +}, +{ +0xf800000000000000i64, +0xf800000000000001i64, +0xf800000000000003i64, +0xf800000000000007i64, +0xf80000000000000fi64, +0xf80000000000001fi64, +0xf80000000000003fi64, +0xf80000000000007fi64, +0xf8000000000000ffi64, +0xf8000000000001ffi64, +0xf8000000000003ffi64, +0xf8000000000007ffi64, +0xf800000000000fffi64, +0xf800000000001fffi64, +0xf800000000003fffi64, +0xf800000000007fffi64, +0xf80000000000ffffi64, +0xf80000000001ffffi64, +0xf80000000003ffffi64, +0xf80000000007ffffi64, +0xf8000000000fffffi64, +0xf8000000001fffffi64, +0xf8000000003fffffi64, +0xf8000000007fffffi64, +0xf800000000ffffffi64, +0xf800000001ffffffi64, +0xf800000003ffffffi64, +0xf800000007ffffffi64, +0xf80000000fffffffi64, +0xf80000001fffffffi64, +0xf80000003fffffffi64, +0xf80000007fffffffi64, +0xf8000000ffffffffi64, +0xf8000001ffffffffi64, +0xf8000003ffffffffi64, +0xf8000007ffffffffi64, +0xf800000fffffffffi64, +0xf800001fffffffffi64, +0xf800003fffffffffi64, +0xf800007fffffffffi64, +0xf80000ffffffffffi64, +0xf80001ffffffffffi64, +0xf80003ffffffffffi64, +0xf80007ffffffffffi64, +0xf8000fffffffffffi64, +0xf8001fffffffffffi64, +0xf8003fffffffffffi64, +0xf8007fffffffffffi64, +0xf800ffffffffffffi64, +0xf801ffffffffffffi64, +0xf803ffffffffffffi64, +0xf807ffffffffffffi64, +0xf80fffffffffffffi64, +0xf81fffffffffffffi64, +0xf83fffffffffffffi64, +0xf87fffffffffffffi64, +0xf8ffffffffffffffi64, +0xf9ffffffffffffffi64, +0xfbffffffffffffffi64 +}, +{ +0xf000000000000000i64, +0xf000000000000001i64, +0xf000000000000003i64, +0xf000000000000007i64, +0xf00000000000000fi64, +0xf00000000000001fi64, +0xf00000000000003fi64, +0xf00000000000007fi64, +0xf0000000000000ffi64, +0xf0000000000001ffi64, +0xf0000000000003ffi64, +0xf0000000000007ffi64, +0xf000000000000fffi64, +0xf000000000001fffi64, +0xf000000000003fffi64, +0xf000000000007fffi64, +0xf00000000000ffffi64, +0xf00000000001ffffi64, +0xf00000000003ffffi64, +0xf00000000007ffffi64, +0xf0000000000fffffi64, +0xf0000000001fffffi64, +0xf0000000003fffffi64, +0xf0000000007fffffi64, +0xf000000000ffffffi64, +0xf000000001ffffffi64, +0xf000000003ffffffi64, +0xf000000007ffffffi64, +0xf00000000fffffffi64, +0xf00000001fffffffi64, +0xf00000003fffffffi64, +0xf00000007fffffffi64, +0xf0000000ffffffffi64, +0xf0000001ffffffffi64, +0xf0000003ffffffffi64, +0xf0000007ffffffffi64, +0xf000000fffffffffi64, +0xf000001fffffffffi64, +0xf000003fffffffffi64, +0xf000007fffffffffi64, +0xf00000ffffffffffi64, +0xf00001ffffffffffi64, +0xf00003ffffffffffi64, +0xf00007ffffffffffi64, +0xf0000fffffffffffi64, +0xf0001fffffffffffi64, +0xf0003fffffffffffi64, +0xf0007fffffffffffi64, +0xf000ffffffffffffi64, +0xf001ffffffffffffi64, +0xf003ffffffffffffi64, +0xf007ffffffffffffi64, +0xf00fffffffffffffi64, +0xf01fffffffffffffi64, +0xf03fffffffffffffi64, +0xf07fffffffffffffi64, +0xf0ffffffffffffffi64, +0xf1ffffffffffffffi64, +0xf3ffffffffffffffi64, +0xf7ffffffffffffffi64 +}, +{ +0xe000000000000000i64, +0xe000000000000001i64, +0xe000000000000003i64, +0xe000000000000007i64, +0xe00000000000000fi64, +0xe00000000000001fi64, +0xe00000000000003fi64, +0xe00000000000007fi64, +0xe0000000000000ffi64, +0xe0000000000001ffi64, +0xe0000000000003ffi64, +0xe0000000000007ffi64, +0xe000000000000fffi64, +0xe000000000001fffi64, +0xe000000000003fffi64, +0xe000000000007fffi64, +0xe00000000000ffffi64, +0xe00000000001ffffi64, +0xe00000000003ffffi64, +0xe00000000007ffffi64, +0xe0000000000fffffi64, +0xe0000000001fffffi64, +0xe0000000003fffffi64, +0xe0000000007fffffi64, +0xe000000000ffffffi64, +0xe000000001ffffffi64, +0xe000000003ffffffi64, +0xe000000007ffffffi64, +0xe00000000fffffffi64, +0xe00000001fffffffi64, +0xe00000003fffffffi64, +0xe00000007fffffffi64, +0xe0000000ffffffffi64, +0xe0000001ffffffffi64, +0xe0000003ffffffffi64, +0xe0000007ffffffffi64, +0xe000000fffffffffi64, +0xe000001fffffffffi64, +0xe000003fffffffffi64, +0xe000007fffffffffi64, +0xe00000ffffffffffi64, +0xe00001ffffffffffi64, +0xe00003ffffffffffi64, +0xe00007ffffffffffi64, +0xe0000fffffffffffi64, +0xe0001fffffffffffi64, +0xe0003fffffffffffi64, +0xe0007fffffffffffi64, +0xe000ffffffffffffi64, +0xe001ffffffffffffi64, +0xe003ffffffffffffi64, +0xe007ffffffffffffi64, +0xe00fffffffffffffi64, +0xe01fffffffffffffi64, +0xe03fffffffffffffi64, +0xe07fffffffffffffi64, +0xe0ffffffffffffffi64, +0xe1ffffffffffffffi64, +0xe3ffffffffffffffi64, +0xe7ffffffffffffffi64, +0xefffffffffffffffi64 +}, +{ +0xc000000000000000i64, +0xc000000000000001i64, +0xc000000000000003i64, +0xc000000000000007i64, +0xc00000000000000fi64, +0xc00000000000001fi64, +0xc00000000000003fi64, +0xc00000000000007fi64, +0xc0000000000000ffi64, +0xc0000000000001ffi64, +0xc0000000000003ffi64, +0xc0000000000007ffi64, +0xc000000000000fffi64, +0xc000000000001fffi64, +0xc000000000003fffi64, +0xc000000000007fffi64, +0xc00000000000ffffi64, +0xc00000000001ffffi64, +0xc00000000003ffffi64, +0xc00000000007ffffi64, +0xc0000000000fffffi64, +0xc0000000001fffffi64, +0xc0000000003fffffi64, +0xc0000000007fffffi64, +0xc000000000ffffffi64, +0xc000000001ffffffi64, +0xc000000003ffffffi64, +0xc000000007ffffffi64, +0xc00000000fffffffi64, +0xc00000001fffffffi64, +0xc00000003fffffffi64, +0xc00000007fffffffi64, +0xc0000000ffffffffi64, +0xc0000001ffffffffi64, +0xc0000003ffffffffi64, +0xc0000007ffffffffi64, +0xc000000fffffffffi64, +0xc000001fffffffffi64, +0xc000003fffffffffi64, +0xc000007fffffffffi64, +0xc00000ffffffffffi64, +0xc00001ffffffffffi64, +0xc00003ffffffffffi64, +0xc00007ffffffffffi64, +0xc0000fffffffffffi64, +0xc0001fffffffffffi64, +0xc0003fffffffffffi64, +0xc0007fffffffffffi64, +0xc000ffffffffffffi64, +0xc001ffffffffffffi64, +0xc003ffffffffffffi64, +0xc007ffffffffffffi64, +0xc00fffffffffffffi64, +0xc01fffffffffffffi64, +0xc03fffffffffffffi64, +0xc07fffffffffffffi64, +0xc0ffffffffffffffi64, +0xc1ffffffffffffffi64, +0xc3ffffffffffffffi64, +0xc7ffffffffffffffi64, +0xcfffffffffffffffi64, +0xdfffffffffffffffi64 +}, +{ +0x8000000000000000i64, +0x8000000000000001i64, +0x8000000000000003i64, +0x8000000000000007i64, +0x800000000000000fi64, +0x800000000000001fi64, +0x800000000000003fi64, +0x800000000000007fi64, +0x80000000000000ffi64, +0x80000000000001ffi64, +0x80000000000003ffi64, +0x80000000000007ffi64, +0x8000000000000fffi64, +0x8000000000001fffi64, +0x8000000000003fffi64, +0x8000000000007fffi64, +0x800000000000ffffi64, +0x800000000001ffffi64, +0x800000000003ffffi64, +0x800000000007ffffi64, +0x80000000000fffffi64, +0x80000000001fffffi64, +0x80000000003fffffi64, +0x80000000007fffffi64, +0x8000000000ffffffi64, +0x8000000001ffffffi64, +0x8000000003ffffffi64, +0x8000000007ffffffi64, +0x800000000fffffffi64, +0x800000001fffffffi64, +0x800000003fffffffi64, +0x800000007fffffffi64, +0x80000000ffffffffi64, +0x80000001ffffffffi64, +0x80000003ffffffffi64, +0x80000007ffffffffi64, +0x8000000fffffffffi64, +0x8000001fffffffffi64, +0x8000003fffffffffi64, +0x8000007fffffffffi64, +0x800000ffffffffffi64, +0x800001ffffffffffi64, +0x800003ffffffffffi64, +0x800007ffffffffffi64, +0x80000fffffffffffi64, +0x80001fffffffffffi64, +0x80003fffffffffffi64, +0x80007fffffffffffi64, +0x8000ffffffffffffi64, +0x8001ffffffffffffi64, +0x8003ffffffffffffi64, +0x8007ffffffffffffi64, +0x800fffffffffffffi64, +0x801fffffffffffffi64, +0x803fffffffffffffi64, +0x807fffffffffffffi64, +0x80ffffffffffffffi64, +0x81ffffffffffffffi64, +0x83ffffffffffffffi64, +0x87ffffffffffffffi64, +0x8fffffffffffffffi64, +0x9fffffffffffffffi64, +0xbfffffffffffffffi64 +}, +{ +0x0i64, +0x1i64, +0x3i64, +0x7i64, +0xfi64, +0x1fi64, +0x3fi64, +0x7fi64, +0xffi64, +0x1ffi64, +0x3ffi64, +0x7ffi64, +0xfffi64, +0x1fffi64, +0x3fffi64, +0x7fffi64, +0xffffi64, +0x1ffffi64, +0x3ffffi64, +0x7ffffi64, +0xfffffi64, +0x1fffffi64, +0x3fffffi64, +0x7fffffi64, +0xffffffi64, +0x1ffffffi64, +0x3ffffffi64, +0x7ffffffi64, +0xfffffffi64, +0x1fffffffi64, +0x3fffffffi64, +0x7fffffffi64, +0xffffffffi64, +0x1ffffffffi64, +0x3ffffffffi64, +0x7ffffffffi64, +0xfffffffffi64, +0x1fffffffffi64, +0x3fffffffffi64, +0x7fffffffffi64, +0xffffffffffi64, +0x1ffffffffffi64, +0x3ffffffffffi64, +0x7ffffffffffi64, +0xfffffffffffi64, +0x1fffffffffffi64, +0x3fffffffffffi64, +0x7fffffffffffi64, +0xffffffffffffi64, +0x1ffffffffffffi64, +0x3ffffffffffffi64, +0x7ffffffffffffi64, +0xfffffffffffffi64, +0x1fffffffffffffi64, +0x3fffffffffffffi64, +0x7fffffffffffffi64, +0xffffffffffffffi64, +0x1ffffffffffffffi64, +0x3ffffffffffffffi64, +0x7ffffffffffffffi64, +0xfffffffffffffffi64, +0x1fffffffffffffffi64, +0x3fffffffffffffffi64, +0x7fffffffffffffffi64 +} +}; + +#endif // end of #ifndef WIN32 + +} // namespace sc_dt + +#endif diff --git a/ext/systemc/src/sysc/datatypes/int/sc_int_base.cpp b/ext/systemc/src/sysc/datatypes/int/sc_int_base.cpp new file mode 100644 index 000000000..fb28d44a2 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_int_base.cpp @@ -0,0 +1,749 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_int_base.cpp -- contains interface definitions between sc_int and + sc_signed, sc_unsigned, and definitions for sc_int_subref. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_int_base.cpp,v $ +// Revision 1.5 2011/02/18 20:19:14 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.4 2010/02/04 22:23:29 acg +// Andy Goodrich: fixed bug in concatenation reads for part selections, +// the mask being used was 32 bits and should have been 64 bits. +// +// Revision 1.3 2008/06/19 17:47:56 acg +// Andy Goodrich: fixes for bugs. See 2.2.1 RELEASENOTES. +// +// Revision 1.2 2007/11/04 21:27:00 acg +// Andy Goodrich: changes to make sure the proper value is returned from +// concat_get_data(). +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:31 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#include "sysc/kernel/sc_macros.h" +#include "sysc/datatypes/int/sc_signed.h" +#include "sysc/datatypes/int/sc_unsigned.h" +#include "sysc/datatypes/int/sc_int_base.h" +#include "sysc/datatypes/int/sc_uint_base.h" +#include "sysc/datatypes/int/sc_signed.h" +#include "sysc/datatypes/int/sc_int_ids.h" +#include "sysc/datatypes/bit/sc_bv_base.h" +#include "sysc/datatypes/bit/sc_lv_base.h" +#include "sysc/datatypes/misc/sc_concatref.h" +#include "sysc/datatypes/fx/sc_fix.h" +#include "sysc/datatypes/fx/scfx_other_defs.h" + + +namespace sc_dt +{ + +// to avoid code bloat in sc_int_concref<T1,T2> + +void +sc_int_concref_invalid_length( int length ) +{ + char msg[BUFSIZ]; + std::sprintf( msg, + "sc_int_concref<T1,T2> initialization: length = %d " + "violates 1 <= length <= %d", + length, SC_INTWIDTH ); + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_bitref +// +// Proxy class for sc_int bit selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +sc_core::sc_vpool<sc_int_bitref> sc_int_bitref::m_pool(9); + +// concatenation methods: + +// #### OPTIMIZE +void sc_int_bitref::concat_set(int64 src, int low_i) +{ + sc_int_base aa( 1 ); + *this = aa = (low_i < 64) ? src >> low_i : src >> 63; +} + +void sc_int_bitref::concat_set(const sc_signed& src, int low_i) +{ + sc_int_base aa( 1 ); + if ( low_i < src.length() ) + *this = aa = 1 & (src >> low_i); + else + *this = aa = (src < 0) ? (int_type)-1 : 0; +} + +void sc_int_bitref::concat_set(const sc_unsigned& src, int low_i) +{ + sc_int_base aa( 1 ); + if ( low_i < src.length() ) + *this = aa = 1 & (src >> low_i); + else + *this = aa = 0; +} + +void sc_int_bitref::concat_set(uint64 src, int low_i) +{ + sc_int_base aa( 1 ); + *this = aa = (low_i < 64) ? src >> low_i : 0; +} + + +// other methods + +void +sc_int_bitref::scan( ::std::istream& is ) +{ + bool b; + is >> b; + *this = b; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_subref_r +// +// Proxy class for sc_int part selection (l-value). +// ---------------------------------------------------------------------------- + +bool sc_int_subref_r::concat_get_ctrl( sc_digit* dst_p, int low_i ) const +{ + int dst_i; // Word in dst_p now processing. + int end_i; // Highest order word in dst_p to process. + int high_i; // Index of high order bit in dst_p to set. + uint_type mask; // Mask for bits to extract or keep. + + dst_i = low_i / BITS_PER_DIGIT; + high_i = low_i + (m_left-m_right); + end_i = high_i / BITS_PER_DIGIT; + mask = ~mask_int[m_left][m_right]; + + + // PROCESS THE FIRST WORD: + + dst_p[dst_i] = (sc_digit)(dst_p[dst_i] & mask); + switch ( end_i - dst_i ) + { + // BITS ARE ACROSS TWO WORDS: + + case 1: + dst_i++; + dst_p[dst_i] = 0; + break; + + // BITS ARE ACROSS THREE WORDS: + + case 2: + dst_i++; + dst_p[dst_i++] = 0; + dst_p[dst_i] = 0; + break; + + // BITS ARE ACROSS FOUR WORDS: + + case 3: + dst_i++; + dst_p[dst_i++] = 0; + dst_p[dst_i++] = 0; + dst_p[dst_i] = 0; + break; + } + return false; +} + + +bool sc_int_subref_r::concat_get_data( sc_digit* dst_p, int low_i ) const +{ + int dst_i; // Word in dst_p now processing. + int end_i; // Highest order word in dst_p to process. + int high_i; // Index of high order bit in dst_p to set. + int left_shift; // Left shift for val. + uint_type mask; // Mask for bits to extract or keep. + bool non_zero; // True if value inserted is non-zero. + uint_type val; // Selection value extracted from m_obj_p. + + dst_i = low_i / BITS_PER_DIGIT; + left_shift = low_i % BITS_PER_DIGIT; + high_i = low_i + (m_left-m_right); + end_i = high_i / BITS_PER_DIGIT; + mask = ~mask_int[m_left][m_right]; + val = (m_obj_p->m_val & mask) >> m_right; + non_zero = val != 0; + + + // PROCESS THE FIRST WORD: + + mask = ~(-1 << left_shift); + dst_p[dst_i] = (sc_digit)((dst_p[dst_i] & mask) | + ((val << left_shift) & DIGIT_MASK)); + + switch ( end_i - dst_i ) + { + // BITS ARE ACROSS TWO WORDS: + + case 1: + dst_i++; + val >>= (BITS_PER_DIGIT-left_shift); + dst_p[dst_i] = (sc_digit)(val & DIGIT_MASK); + break; + + // BITS ARE ACROSS THREE WORDS: + + case 2: + dst_i++; + val >>= (BITS_PER_DIGIT-left_shift); + dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK); + val >>= BITS_PER_DIGIT; + dst_p[dst_i] = (sc_digit)val; + break; + + // BITS ARE ACROSS FOUR WORDS: + + case 3: + dst_i++; + val >>= (BITS_PER_DIGIT-left_shift); + dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK); + val >>= BITS_PER_DIGIT; + dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK); + val >>= BITS_PER_DIGIT; + dst_p[dst_i] = (sc_digit)val; + break; + } + return non_zero; +} + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_subref +// +// Proxy class for sc_int part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +sc_core::sc_vpool<sc_int_subref> sc_int_subref::m_pool(9); + +// assignment operators + +sc_int_subref& +sc_int_subref::operator = ( int_type v ) +{ + int_type val = m_obj_p->m_val; + uint_type mask = mask_int[m_left][m_right]; + val &= mask; + val |= (v << m_right) & ~mask; + m_obj_p->m_val = val; + m_obj_p->extend_sign(); + return *this; +} + +sc_int_subref& +sc_int_subref::operator = ( const sc_signed& a ) +{ + sc_int_base aa( length() ); + return ( *this = aa = a ); +} + +sc_int_subref& +sc_int_subref::operator = ( const sc_unsigned& a ) +{ + sc_int_base aa( length() ); + return ( *this = aa = a ); +} + +sc_int_subref& +sc_int_subref::operator = ( const sc_bv_base& a ) +{ + sc_int_base aa( length() ); + return ( *this = aa = a ); +} + +sc_int_subref& +sc_int_subref::operator = ( const sc_lv_base& a ) +{ + sc_int_base aa( length() ); + return ( *this = aa = a ); +} + + +// concatenation methods: + +// #### OPTIMIZE +void sc_int_subref::concat_set(int64 src, int low_i) +{ + sc_int_base aa ( length() ); + *this = aa = (low_i < 64) ? src >> low_i : src >> 63; +} + +void sc_int_subref::concat_set(const sc_signed& src, int low_i) +{ + sc_int_base aa( length() ); + if ( low_i < src.length() ) + *this = aa = src >> low_i; + else + *this = (src < 0) ? (int_type)-1 : 0; +} + +void sc_int_subref::concat_set(const sc_unsigned& src, int low_i) +{ + sc_int_base aa( length() ); + if ( low_i < src.length() ) + *this = aa = src >> low_i; + else + *this = 0; +} + +void sc_int_subref::concat_set(uint64 src, int low_i) +{ + sc_int_base aa ( length() ); + *this = aa = (low_i < 64) ? src >> low_i : 0; +} + + +// other methods + +void +sc_int_subref::scan( ::std::istream& is ) +{ + std::string s; + is >> s; + *this = s.c_str(); +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_base +// +// Base class for sc_int. +// ---------------------------------------------------------------------------- + +// support methods + +void +sc_int_base::invalid_length() const +{ + char msg[BUFSIZ]; + std::sprintf( msg, + "sc_int[_base] initialization: length = %d violates " + "1 <= length <= %d", + m_len, SC_INTWIDTH ); + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); +} + +void +sc_int_base::invalid_index( int i ) const +{ + char msg[BUFSIZ]; + std::sprintf( msg, + "sc_int[_base] bit selection: index = %d violates " + "0 <= index <= %d", + i, m_len - 1 ); + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); +} + +void +sc_int_base::invalid_range( int l, int r ) const +{ + char msg[BUFSIZ]; + std::sprintf( msg, + "sc_int[_base] part selection: left = %d, right = %d violates " + "%d >= left >= right >= 0", + l, r, m_len - 1 ); + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); +} + + +void +sc_int_base::check_value() const +{ + int_type limit = (int_type) 1 << ( m_len - 1 ); + if( m_val < -limit || m_val >= limit ) { + char msg[BUFSIZ]; + std::sprintf( msg, "sc_int[_base]: value does not fit into a length of %d", + m_len ); + SC_REPORT_WARNING( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); + } +} + + +// constructors +sc_int_base::sc_int_base( const sc_bv_base& v ) + : m_val(0), m_len( v.length() ), m_ulen( SC_INTWIDTH - m_len ) +{ + check_length(); + *this = v; +} +sc_int_base::sc_int_base( const sc_lv_base& v ) + : m_val(0), m_len( v.length() ), m_ulen( SC_INTWIDTH - m_len ) +{ + check_length(); + *this = v; +} +sc_int_base::sc_int_base( const sc_uint_subref_r& v ) + : m_val(0), m_len( v.length() ), m_ulen( SC_INTWIDTH - m_len ) +{ + check_length(); + *this = v.to_uint64(); +} +sc_int_base::sc_int_base( const sc_signed_subref_r& v ) + : m_val(0), m_len( v.length() ), m_ulen( SC_INTWIDTH - m_len ) +{ + check_length(); + *this = v.to_uint64(); +} +sc_int_base::sc_int_base( const sc_unsigned_subref_r& v ) + : m_val(0), m_len( v.length() ), m_ulen( SC_INTWIDTH - m_len ) +{ + check_length(); + *this = v.to_uint64(); +} + +sc_int_base::sc_int_base( const sc_signed& a ) + : m_val( 0 ), m_len( a.length() ), m_ulen( SC_INTWIDTH - m_len ) +{ + check_length(); +#if 0 + for( int i = m_len - 1; i >= 0; -- i ) { + set( i, a.test( i ) ); + } + extend_sign(); +#else + *this = a.to_int64(); +#endif +} + +sc_int_base::sc_int_base( const sc_unsigned& a ) + : m_val( 0 ), m_len( a.length() ), m_ulen( SC_INTWIDTH - m_len ) +{ + check_length(); +#if 0 + for( int i = m_len - 1; i >= 0; -- i ) { + set( i, a.test( i ) ); + } + extend_sign(); +#else + *this = a.to_int64(); +#endif +} + + +// assignment operators + +sc_int_base& +sc_int_base::operator = ( const sc_signed& a ) +{ + int minlen = sc_min( m_len, a.length() ); + int i = 0; + for( ; i < minlen; ++ i ) { + set( i, a.test( i ) ); + } + bool sgn = a.sign(); + for( ; i < m_len; ++ i ) { + // sign extension + set( i, sgn ); + } + extend_sign(); + return *this; +} + +sc_int_base& +sc_int_base::operator = ( const sc_unsigned& a ) +{ + int minlen = sc_min( m_len, a.length() ); + int i = 0; + for( ; i < minlen; ++ i ) { + set( i, a.test( i ) ); + } + for( ; i < m_len; ++ i ) { + // zero extension + set( i, 0 ); + } + extend_sign(); + return *this; +} + + +sc_int_base& +sc_int_base::operator = ( const sc_bv_base& a ) +{ + int minlen = sc_min( m_len, a.length() ); + int i = 0; + for( ; i < minlen; ++ i ) { + set( i, a.get_bit( i ) ); + } + for( ; i < m_len; ++ i ) { + // zero extension + set( i, 0 ); + } + extend_sign(); + return *this; +} + +sc_int_base& +sc_int_base::operator = ( const sc_lv_base& a ) +{ + int minlen = sc_min( m_len, a.length() ); + int i = 0; + for( ; i < minlen; ++ i ) { + set( i, sc_logic( a.get_bit( i ) ).to_bool() ); + } + for( ; i < m_len; ++ i ) { + // zero extension + set( i, 0 ); + } + extend_sign(); + return *this; +} + +sc_int_base& +sc_int_base::operator = ( const char* a ) +{ + if( a == 0 ) { + SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, + "character string is zero" ); + } + if( *a == 0 ) { + SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, + "character string is empty" ); + } + try { + int len = m_len; + sc_fix aa( a, len, len, SC_TRN, SC_WRAP, 0, SC_ON ); + return this->operator = ( aa ); + } catch( sc_core::sc_report ) { + char msg[BUFSIZ]; + std::sprintf( msg, "character string '%s' is not valid", a ); + SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg ); + // never reached + return *this; + } +} + +// explicit conversion to character string + +const std::string +sc_int_base::to_string( sc_numrep numrep ) const +{ + int len = m_len; + sc_fix aa( *this, len, len, SC_TRN, SC_WRAP, 0, SC_ON ); + return aa.to_string( numrep ); +} + +const std::string +sc_int_base::to_string( sc_numrep numrep, bool w_prefix ) const +{ + int len = m_len; + sc_fix aa( *this, len, len, SC_TRN, SC_WRAP, 0, SC_ON ); + return aa.to_string( numrep, w_prefix ); +} + + +// reduce methods + +bool +sc_int_base::and_reduce() const +{ + return ( m_val == int_type( -1 ) ); +} + +bool +sc_int_base::or_reduce() const +{ + return ( m_val != int_type( 0 ) ); +} + +bool +sc_int_base::xor_reduce() const +{ + uint_type mask = ~UINT_ZERO; + uint_type val = m_val & (mask >> m_ulen); + int n = SC_INTWIDTH; + do { + n >>= 1; + mask >>= n; + val = ((val & (mask << n)) >> n) ^ (val & mask); + } while( n != 1 ); + return ( val != uint_type( 0 ) ); +} + + +bool sc_int_base::concat_get_ctrl( sc_digit* dst_p, int low_i ) const +{ + int dst_i; // Word in dst_p now processing. + int end_i; // Highest order word in dst_p to process. + int left_shift; // Left shift for val. + uint_type mask; // Mask for bits to extract or keep. + + dst_i = low_i / BITS_PER_DIGIT; + left_shift = low_i % BITS_PER_DIGIT; + end_i = (low_i + (m_len-1)) / BITS_PER_DIGIT; + + mask = ~(-1 << left_shift); + dst_p[dst_i] = (sc_digit)(dst_p[dst_i] & mask); + dst_i++; + for ( ; dst_i <= end_i; dst_i++ ) dst_p[dst_i] = 0; + return false; +} + +//------------------------------------------------------------------------------ +//"sc_int_base::concat_get_data" +// +// This method transfers the value of this object instance to the supplied +// array of sc_unsigned digits starting with the bit specified by low_i within +// the array of digits. +// +// Notes: +// (1) we don't worry about masking the high order data we transfer since +// concat_get_data() is called from low order bit to high order bit. So +// the bits above where we place ours will be filled in by someone else. +// +// dst_p -> array of sc_unsigned digits to be filled in. +// low_i = first bit within dst_p to be set. +//------------------------------------------------------------------------------ +bool sc_int_base::concat_get_data( sc_digit* dst_p, int low_i ) const +{ + int dst_i; // Word in dst_p now processing. + int end_i; // Highest order word in dst_p to process. + int high_i; // Index of high order bit in dst_p to set. + int left_shift; // Left shift for val. + uint_type mask; // Mask for bits to extract or keep. + bool non_zero; // True if value inserted is non-zero. + uint_type val; // Value for this object. + + dst_i = low_i / BITS_PER_DIGIT; + left_shift = low_i % BITS_PER_DIGIT; + high_i = low_i + (m_len-1); + end_i = high_i / BITS_PER_DIGIT; + val = m_val; + non_zero = val != 0; + + // MASK OFF DATA TO BE TRANSFERRED BASED ON WIDTH: + + if ( m_len < 64 ) + { + mask = ~((uint_type)-1 << m_len); + val &= mask; + } + + // PROCESS THE FIRST WORD: + + mask = (-1 << left_shift); + dst_p[dst_i] = (sc_digit)((dst_p[dst_i] & ~mask) | + ((val <<left_shift) & DIGIT_MASK)); + switch ( end_i - dst_i ) + { + // BITS ARE ACROSS TWO WORDS: + + case 1: + dst_i++; + val >>= (BITS_PER_DIGIT-left_shift); + dst_p[dst_i] = (sc_digit)val; + break; + + // BITS ARE ACROSS THREE WORDS: + + case 2: + dst_i++; + val >>= (BITS_PER_DIGIT-left_shift); + dst_p[dst_i++] = ((sc_digit)val) & DIGIT_MASK; + val >>= BITS_PER_DIGIT; + dst_p[dst_i] = (sc_digit)val; + break; + + // BITS ARE ACROSS FOUR WORDS: + + case 3: + dst_i++; + val >>= (BITS_PER_DIGIT-left_shift); + dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK); + val >>= BITS_PER_DIGIT; + dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK); + val >>= BITS_PER_DIGIT; + dst_p[dst_i] = (sc_digit)val; + break; + } + return non_zero; +} + +// #### OPTIMIZE +void sc_int_base::concat_set(int64 src, int low_i) +{ + *this = (low_i < 64) ? src >> low_i : src >> 63; +} + +void sc_int_base::concat_set(const sc_signed& src, int low_i) +{ + if ( low_i < src.length() ) + *this = src >> low_i; + else + *this = (src < 0) ? (int_type)-1 : 0; +} + +void sc_int_base::concat_set(const sc_unsigned& src, int low_i) +{ + if ( low_i < src.length() ) + *this = src >> low_i; + else + *this = 0; +} + +void sc_int_base::concat_set(uint64 src, int low_i) +{ + *this = (low_i < 64) ? src >> low_i : 0; +} + +// other methods + +void +sc_int_base::scan( ::std::istream& is ) +{ + std::string s; + is >> s; + *this = s.c_str(); +} + +} // namespace sc_dt; + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/int/sc_int_base.h b/ext/systemc/src/sysc/datatypes/int/sc_int_base.h new file mode 100644 index 000000000..a9b8a6457 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_int_base.h @@ -0,0 +1,1382 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_int_base.h -- A sc_int is a signed integer whose length is less than the + machine's native integer length. We provide two implementations + (i) sc_int with length between 1 - 64, and (ii) sc_int with + length between 1 - 32. Implementation (i) is the default + implementation, while implementation (ii) can be used only if + the class library is compiled with -D_32BIT_. Unlike arbitrary + precision, arithmetic and bitwise operations are performed + using the native types (hence capped at 32/64 bits). The sc_int + integer is useful when the user does not need arbitrary + precision and the performance is superior to + sc_bigint/sc_biguint. + + Original Author: Amit Rao, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc. + Description of Modification: - Resolved ambiguity with sc_(un)signed. + - Merged the code for 64- and 32-bit versions + via the constants in sc_nbdefs.h. + - Eliminated redundant file inclusions. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_int_base.h,v $ +// Revision 1.3 2011/08/24 22:05:45 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.2 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.4 2006/05/08 17:50:01 acg +// Andy Goodrich: Added David Long's declarations for friend operators, +// functions, and methods, to keep the Microsoft compiler happy. +// +// Revision 1.3 2006/01/13 18:49:31 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef SC_INT_BASE_H +#define SC_INT_BASE_H + +#include "sysc/kernel/sc_object.h" +#include "sysc/datatypes/misc/sc_value_base.h" +#include "sysc/datatypes/int/sc_int_ids.h" +#include "sysc/datatypes/int/sc_length_param.h" +#include "sysc/datatypes/int/sc_nbdefs.h" +#include "sysc/datatypes/int/sc_uint_base.h" +#include "sysc/utils/sc_iostream.h" +#include "sysc/utils/sc_temporary.h" + + +namespace sc_dt +{ + +class sc_concatref; + +// classes defined in this module +class sc_int_bitref_r; +class sc_int_bitref; +class sc_int_subref_r; +class sc_int_subref; +class sc_int_base; +class sc_signed_subref_r; +class sc_unsigned_subref_r; + +// forward class declarations +class sc_bv_base; +class sc_lv_base; +class sc_signed; +class sc_unsigned; +class sc_fxval; +class sc_fxval_fast; +class sc_fxnum; +class sc_fxnum_fast; + + +extern const uint_type mask_int[SC_INTWIDTH][SC_INTWIDTH]; + +// friend operator declarations + // relational operators + + inline bool operator == ( const sc_int_base& a, const sc_int_base& b ); + + inline bool operator != ( const sc_int_base& a, const sc_int_base& b ); + + inline bool operator < ( const sc_int_base& a, const sc_int_base& b ); + + inline bool operator <= ( const sc_int_base& a, const sc_int_base& b ); + + inline bool operator > ( const sc_int_base& a, const sc_int_base& b ); + + inline bool operator >= ( const sc_int_base& a, const sc_int_base& b ); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_bitref_r +// +// Proxy class for sc_int bit selection (r-value only). +// ---------------------------------------------------------------------------- + +class sc_int_bitref_r : public sc_value_base +{ + friend class sc_int_base; + +protected: + + // constructor + + sc_int_bitref_r() : sc_value_base(), m_index(), m_obj_p() + {} + + // initializer for sc_core::sc_vpool: + + void initialize( const sc_int_base* obj_p, int index_ ) + { + m_obj_p = (sc_int_base*)obj_p; + m_index = index_; + } + +public: + + // copy constructor + + sc_int_bitref_r( const sc_int_bitref_r& a ) : + sc_value_base(a), m_index(a.m_index), m_obj_p(a.m_obj_p) + {} + + // destructor + + virtual ~sc_int_bitref_r() + {} + + // capacity + + int length() const + { return 1; } + +#ifdef SC_DT_DEPRECATED + int bitwidth() const + { return length(); } +#endif + + // concatenation support + + virtual int concat_length( bool *xz_present_p ) const + { if (xz_present_p) *xz_present_p = false; return 1; } + virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const + { + int bit_mask = 1 << (low_i % BITS_PER_DIGIT); + int word_i = low_i / BITS_PER_DIGIT; + + dst_p[word_i] &= ~bit_mask; + return false; + } + virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const + { + bool non_zero; + int bit_mask = 1 << (low_i % BITS_PER_DIGIT); + int word_i = low_i / BITS_PER_DIGIT; + + if ( operator uint64() ) + { + dst_p[word_i] |= bit_mask; + non_zero = true; + } + else + { + dst_p[word_i] &= ~bit_mask; + non_zero = false; + } + return non_zero; + } + virtual uint64 concat_get_uint64() const + { return operator uint64(); } + + + + + // implicit conversions + + operator uint64 () const; + bool operator ! () const; + bool operator ~ () const; + + + // explicit conversions + + uint64 value() const + { return operator uint64(); } + + bool to_bool() const + { return operator uint64(); } + + + // other methods + + void print( ::std::ostream& os = ::std::cout ) const + { os << to_bool(); } + +protected: + int m_index; + sc_int_base* m_obj_p; + +private: + + // disabled + sc_int_bitref_r& operator = ( const sc_int_bitref_r& ); +}; + + +inline +::std::ostream& +operator << ( ::std::ostream&, const sc_int_bitref_r& ); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_bitref +// +// Proxy class for sc_int bit selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +class sc_int_bitref + : public sc_int_bitref_r +{ + friend class sc_int_base; + friend class sc_core::sc_vpool<sc_int_bitref>; + + + // constructor + + sc_int_bitref() : sc_int_bitref_r() + {} + + +public: + + // copy constructor + + sc_int_bitref( const sc_int_bitref& a ) : sc_int_bitref_r( a ) + {} + + // assignment operators + + sc_int_bitref& operator = ( const sc_int_bitref_r& b ); + sc_int_bitref& operator = ( const sc_int_bitref& b ); + sc_int_bitref& operator = ( bool b ); + + sc_int_bitref& operator &= ( bool b ); + sc_int_bitref& operator |= ( bool b ); + sc_int_bitref& operator ^= ( bool b ); + + // concatenation methods + + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed& src, int low_i); + virtual void concat_set(const sc_unsigned& src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + + // other methods + + void scan( ::std::istream& is = ::std::cin ); + +public: + static sc_core::sc_vpool<sc_int_bitref> m_pool; + +}; + + + +inline +::std::istream& +operator >> ( ::std::istream&, sc_int_bitref& ); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_subref_r +// +// Proxy class for sc_int part selection (r-value only). +// ---------------------------------------------------------------------------- + +class sc_int_subref_r : public sc_value_base +{ + friend class sc_int_base; + friend class sc_int_signal; + friend class sc_int_subref; + +protected: + + // constructor + + sc_int_subref_r() : sc_value_base(), m_left(0), m_obj_p(0), m_right(0) + {} + + // initializer for sc_core::sc_vpool: + + void initialize( const sc_int_base* obj_p, int left_i, int right_i ) + { + m_obj_p = (sc_int_base*)obj_p; + m_left = left_i; + m_right = right_i; + } + + +public: + // copy constructor + + sc_int_subref_r( const sc_int_subref_r& a ) : + sc_value_base(a), m_left( a.m_left ), m_obj_p( a.m_obj_p ), + m_right( a.m_right ) + {} + + // destructor + + virtual ~sc_int_subref_r() + {} + + // capacity + + int length() const + { return ( m_left - m_right + 1 ); } + +#ifdef SC_DT_DEPRECATED + int bitwidth() const + { return length(); } +#endif + + // concatenation support + + virtual int concat_length(bool* xz_present_p) const + { if ( xz_present_p ) *xz_present_p = false; return length(); } + virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const; + virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const; + virtual uint64 concat_get_uint64() const + { + int len = length(); + uint64 val = operator uint_type(); + if ( len < 64 ) + return (uint64)(val & ~((uint_type)-1 << len)); + else + return (uint64)val; + } + + // reduce methods + + bool and_reduce() const; + + bool nand_reduce() const + { return ( ! and_reduce() ); } + + bool or_reduce() const; + + bool nor_reduce() const + { return ( ! or_reduce() ); } + + bool xor_reduce() const; + + bool xnor_reduce() const + { return ( ! xor_reduce() ); } + + + // implicit conversion to uint_type + + operator uint_type () const; + + + // explicit conversions + + uint_type value() const + { return operator uint_type(); } + + + int to_int() const; + unsigned int to_uint() const; + long to_long() const; + unsigned long to_ulong() const; + int64 to_int64() const; + uint64 to_uint64() const; + double to_double() const; + + + // explicit conversion to character string + + const std::string to_string( sc_numrep numrep = SC_DEC ) const; + const std::string to_string( sc_numrep numrep, bool w_prefix ) const; + + + // other methods + + void print( ::std::ostream& os = ::std::cout ) const + { os << to_string(sc_io_base(os,SC_DEC),sc_io_show_base(os)); } + +protected: + + int m_left; + sc_int_base* m_obj_p; + int m_right; + +private: + const sc_int_subref_r& operator = ( const sc_int_subref_r& ); +}; + + + +inline +::std::ostream& +operator << ( ::std::ostream&, const sc_int_subref_r& ); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_subref +// +// Proxy class for sc_int part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +class sc_int_subref + : public sc_int_subref_r +{ + friend class sc_int_base; + friend class sc_core::sc_vpool<sc_int_subref>; + + +protected: + + // constructor + sc_int_subref() : sc_int_subref_r() + {} + +public: + + // copy constructor + + sc_int_subref( const sc_int_subref& a ) : sc_int_subref_r( a ) + {} + + // assignment operators + + sc_int_subref& operator = ( int_type v ); + sc_int_subref& operator = ( const sc_int_base& a ); + + sc_int_subref& operator = ( const sc_int_subref_r& a ) + { return operator = ( a.operator uint_type() ); } + + sc_int_subref& operator = ( const sc_int_subref& a ) + { return operator = ( a.operator uint_type() ); } + + template< class T > + sc_int_subref& operator = ( const sc_generic_base<T>& a ) + { return operator = ( a->to_int64() ); } + + sc_int_subref& operator = ( const char* a ); + + sc_int_subref& operator = ( unsigned long a ) + { return operator = ( (int_type) a ); } + + sc_int_subref& operator = ( long a ) + { return operator = ( (int_type) a ); } + + sc_int_subref& operator = ( unsigned int a ) + { return operator = ( (int_type) a ); } + + sc_int_subref& operator = ( int a ) + { return operator = ( (int_type) a ); } + + sc_int_subref& operator = ( uint64 a ) + { return operator = ( (int_type) a ); } + + sc_int_subref& operator = ( double a ) + { return operator = ( (int_type) a ); } + + sc_int_subref& operator = ( const sc_signed& ); + sc_int_subref& operator = ( const sc_unsigned& ); + sc_int_subref& operator = ( const sc_bv_base& ); + sc_int_subref& operator = ( const sc_lv_base& ); + + // concatenation methods + + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed& src, int low_i); + virtual void concat_set(const sc_unsigned& src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + // other methods + + void scan( ::std::istream& is = ::std::cin ); + +public: + static sc_core::sc_vpool<sc_int_subref> m_pool; + +}; + + + +inline +::std::istream& +operator >> ( ::std::istream&, sc_int_subref& ); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_base +// +// Base class for sc_int. +// ---------------------------------------------------------------------------- + +class sc_int_base : public sc_value_base +{ + friend class sc_int_bitref_r; + friend class sc_int_bitref; + friend class sc_int_subref_r; + friend class sc_int_subref; + + + // support methods + + void invalid_length() const; + void invalid_index( int i ) const; + void invalid_range( int l, int r ) const; + + void check_length() const + { if( m_len <= 0 || m_len > SC_INTWIDTH ) { invalid_length(); } } + + void check_index( int i ) const + { if( i < 0 || i >= m_len ) { invalid_index( i ); } } + + void check_range( int l, int r ) const + { if( r < 0 || l >= m_len || l < r ) { invalid_range( l, r ); } } + + void check_value() const; + + void extend_sign() + { +#ifdef DEBUG_SYSTEMC + check_value(); +#endif + m_val = ( m_val << m_ulen >> m_ulen ); + } + +public: + + // constructors + + explicit sc_int_base( int w = sc_length_param().len() ) + : m_val( 0 ), m_len( w ), m_ulen( SC_INTWIDTH - m_len ) + { check_length(); } + + sc_int_base( int_type v, int w ) + : m_val( v ), m_len( w ), m_ulen( SC_INTWIDTH - m_len ) + { check_length(); extend_sign(); } + + sc_int_base( const sc_int_base& a ) + : sc_value_base(a), m_val( a.m_val ), m_len( a.m_len ), + m_ulen( a.m_ulen ) + {} + + explicit sc_int_base( const sc_int_subref_r& a ) + : m_val( a ), m_len( a.length() ), m_ulen( SC_INTWIDTH - m_len ) + { extend_sign(); } + + template< class T > + explicit sc_int_base( const sc_generic_base<T>& a ) : + m_val( a->to_int64() ), m_len( a->length() ), + m_ulen( SC_INTWIDTH - m_len ) + { check_length(); extend_sign(); } + + explicit sc_int_base( const sc_signed& a ); + explicit sc_int_base( const sc_unsigned& a ); + explicit sc_int_base( const sc_bv_base& v ); + explicit sc_int_base( const sc_lv_base& v ); + explicit sc_int_base( const sc_uint_subref_r& v ); + explicit sc_int_base( const sc_signed_subref_r& v ); + explicit sc_int_base( const sc_unsigned_subref_r& v ); + + + + // destructor + + virtual ~sc_int_base() + {} + + // assignment operators + + sc_int_base& operator = ( int_type v ) + { m_val = v; extend_sign(); return *this; } + + sc_int_base& operator = ( const sc_int_base& a ) + { m_val = a.m_val; extend_sign(); return *this; } + + sc_int_base& operator = ( const sc_int_subref_r& a ) + { m_val = a; extend_sign(); return *this; } + + template<class T> + sc_int_base& operator = ( const sc_generic_base<T>& a ) + { m_val = a->to_int64(); extend_sign(); return *this; } + + sc_int_base& operator = ( const sc_signed& a ); + sc_int_base& operator = ( const sc_unsigned& a ); + +#ifdef SC_INCLUDE_FX + sc_int_base& operator = ( const sc_fxval& a ); + sc_int_base& operator = ( const sc_fxval_fast& a ); + sc_int_base& operator = ( const sc_fxnum& a ); + sc_int_base& operator = ( const sc_fxnum_fast& a ); +#endif + + sc_int_base& operator = ( const sc_bv_base& a ); + sc_int_base& operator = ( const sc_lv_base& a ); + + sc_int_base& operator = ( const char* a ); + + sc_int_base& operator = ( unsigned long a ) + { m_val = a; extend_sign(); return *this; } + + sc_int_base& operator = ( long a ) + { m_val = a; extend_sign(); return *this; } + + sc_int_base& operator = ( unsigned int a ) + { m_val = a; extend_sign(); return *this; } + + sc_int_base& operator = ( int a ) + { m_val = a; extend_sign(); return *this; } + + sc_int_base& operator = ( uint64 a ) + { m_val = a; extend_sign(); return *this; } + + sc_int_base& operator = ( double a ) + { m_val = (int_type) a; extend_sign(); return *this; } + + + // arithmetic assignment operators + + sc_int_base& operator += ( int_type v ) + { m_val += v; extend_sign(); return *this; } + + sc_int_base& operator -= ( int_type v ) + { m_val -= v; extend_sign(); return *this; } + + sc_int_base& operator *= ( int_type v ) + { m_val *= v; extend_sign(); return *this; } + + sc_int_base& operator /= ( int_type v ) + { m_val /= v; extend_sign(); return *this; } + + sc_int_base& operator %= ( int_type v ) + { m_val %= v; extend_sign(); return *this; } + + + // bitwise assignment operators + + sc_int_base& operator &= ( int_type v ) + { m_val &= v; extend_sign(); return *this; } + + sc_int_base& operator |= ( int_type v ) + { m_val |= v; extend_sign(); return *this; } + + sc_int_base& operator ^= ( int_type v ) + { m_val ^= v; extend_sign(); return *this; } + + + sc_int_base& operator <<= ( int_type v ) + { m_val <<= v; extend_sign(); return *this; } + + sc_int_base& operator >>= ( int_type v ) + { m_val >>= v; /* no sign extension needed */ return *this; } + + + // prefix and postfix increment and decrement operators + + sc_int_base& operator ++ () // prefix + { ++ m_val; extend_sign(); return *this; } + + const sc_int_base operator ++ ( int ) // postfix + { sc_int_base tmp( *this ); ++ m_val; extend_sign(); return tmp; } + + sc_int_base& operator -- () // prefix + { -- m_val; extend_sign(); return *this; } + + const sc_int_base operator -- ( int ) // postfix + { sc_int_base tmp( *this ); -- m_val; extend_sign(); return tmp; } + + + // relational operators + + friend bool operator == ( const sc_int_base& a, const sc_int_base& b ) + { return a.m_val == b.m_val; } + + friend bool operator != ( const sc_int_base& a, const sc_int_base& b ) + { return a.m_val != b.m_val; } + + friend bool operator < ( const sc_int_base& a, const sc_int_base& b ) + { return a.m_val < b.m_val; } + + friend bool operator <= ( const sc_int_base& a, const sc_int_base& b ) + { return a.m_val <= b.m_val; } + + friend bool operator > ( const sc_int_base& a, const sc_int_base& b ) + { return a.m_val > b.m_val; } + + friend bool operator >= ( const sc_int_base& a, const sc_int_base& b ) + { return a.m_val >= b.m_val; } + + + // bit selection + + sc_int_bitref& operator [] ( int i ); + const sc_int_bitref_r& operator [] ( int i ) const; + + sc_int_bitref& bit( int i ); + const sc_int_bitref_r& bit( int i ) const; + + + // part selection + + sc_int_subref& operator () ( int left, int right ); + const sc_int_subref_r& operator () ( int left, int right ) const; + + sc_int_subref& range( int left, int right ); + const sc_int_subref_r& range( int left, int right ) const; + + + // bit access, without bounds checking or sign extension + + bool test( int i ) const + { return ( 0 != (m_val & (UINT_ONE << i)) ); } + + void set( int i ) + { m_val |= (UINT_ONE << i); } + + void set( int i, bool v ) + { v ? m_val |= (UINT_ONE << i) : m_val &= ~(UINT_ONE << i); } + + + // capacity + + int length() const + { return m_len; } + +#ifdef SC_DT_DEPRECATED + int bitwidth() const + { return length(); } +#endif + + // concatenation support + + virtual int concat_length(bool* xz_present_p) const + { if ( xz_present_p ) *xz_present_p = false; return length(); } + virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const; + virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const; + virtual uint64 concat_get_uint64() const + { + if ( m_len < 64 ) + return (uint64)(m_val & ~((uint_type)-1 << m_len)); + else + return (uint64)m_val; + } + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed& src, int low_i); + virtual void concat_set(const sc_unsigned& src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + + // reduce methods + + bool and_reduce() const; + + bool nand_reduce() const + { return ( ! and_reduce() ); } + + bool or_reduce() const; + + bool nor_reduce() const + { return ( ! or_reduce() ); } + + bool xor_reduce() const; + + bool xnor_reduce() const + { return ( ! xor_reduce() ); } + + + // implicit conversion to int_type + + operator int_type() const + { return m_val; } + + + // explicit conversions + + int_type value() const + { return operator int_type(); } + + + int to_int() const + { return (int) m_val; } + + unsigned int to_uint() const + { return (unsigned int) m_val; } + + long to_long() const + { return (long) m_val; } + + unsigned long to_ulong() const + { return (unsigned long) m_val; } + + int64 to_int64() const + { return (int64) m_val; } + + uint64 to_uint64() const + { return (uint64) m_val; } + + double to_double() const + { return (double) m_val; } + + +#ifndef _32BIT_ + long long_low() const + { return (long) (m_val & UINT64_32ONES); } + + long long_high() const + { return (long) ((m_val >> 32) & UINT64_32ONES); } +#endif + + + // explicit conversion to character string + + const std::string to_string( sc_numrep numrep = SC_DEC ) const; + const std::string to_string( sc_numrep numrep, bool w_prefix ) const; + + + // other methods + + void print( ::std::ostream& os = ::std::cout ) const + { os << to_string(sc_io_base(os,SC_DEC),sc_io_show_base(os)); } + + void scan( ::std::istream& is = ::std::cin ); + +protected: + + int_type m_val; // value + int m_len; // length + int m_ulen; // unused length +}; + + + +inline +::std::ostream& +operator << ( ::std::ostream&, const sc_int_base& ); + +inline +::std::istream& +operator >> ( ::std::istream&, sc_int_base& ); + + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_bitref_r +// +// Proxy class for sc_int bit selection (r-value only). +// ---------------------------------------------------------------------------- + +// implicit conversion to uint64 + +inline +sc_int_bitref_r::operator uint64 () const +{ + return m_obj_p->test( m_index ); +} + +inline +bool +sc_int_bitref_r::operator ! () const +{ + return ! m_obj_p->test( m_index ); +} + +inline +bool +sc_int_bitref_r::operator ~ () const +{ + return ! m_obj_p->test( m_index ); +} + + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_int_bitref_r& a ) +{ + a.print( os ); + return os; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_bitref +// +// Proxy class for sc_int bit selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +// assignment operators + +inline +sc_int_bitref& +sc_int_bitref::operator = ( const sc_int_bitref_r& b ) +{ + m_obj_p->set( m_index, (bool) b ); + m_obj_p->extend_sign(); + return *this; +} + +inline +sc_int_bitref& +sc_int_bitref::operator = ( const sc_int_bitref& b ) +{ + m_obj_p->set( m_index, (bool) b ); + m_obj_p->extend_sign(); + return *this; +} + +inline +sc_int_bitref& +sc_int_bitref::operator = ( bool b ) +{ + m_obj_p->set( m_index, b ); + m_obj_p->extend_sign(); + return *this; +} + + +inline +sc_int_bitref& +sc_int_bitref::operator &= ( bool b ) +{ + if( ! b ) { + m_obj_p->set( m_index, b ); + m_obj_p->extend_sign(); + } + return *this; +} + +inline +sc_int_bitref& +sc_int_bitref::operator |= ( bool b ) +{ + if( b ) { + m_obj_p->set( m_index, b ); + m_obj_p->extend_sign(); + } + return *this; +} + +inline +sc_int_bitref& +sc_int_bitref::operator ^= ( bool b ) +{ + if( b ) { + m_obj_p->m_val ^= (UINT_ONE << m_index); + m_obj_p->extend_sign(); + } + return *this; +} + + + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_int_bitref& a ) +{ + a.scan( is ); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_subref_r +// +// Proxy class for sc_int part selection (r-value only). +// ---------------------------------------------------------------------------- + +// implicit conversion to int_type + +inline +sc_int_subref_r::operator uint_type() const +{ + uint_type /*int_type*/ val = m_obj_p->m_val; + int uleft = SC_INTWIDTH - (m_left + 1); + int uright = uleft + m_right; + return ( val << uleft >> uright ); +} + + +// reduce methods + +inline +bool +sc_int_subref_r::and_reduce() const +{ + sc_int_base a( *this ); + return a.and_reduce(); +} + +inline +bool +sc_int_subref_r::or_reduce() const +{ + sc_int_base a( *this ); + return a.or_reduce(); +} + +inline +bool +sc_int_subref_r::xor_reduce() const +{ + sc_int_base a( *this ); + return a.xor_reduce(); +} + + +// explicit conversions + +inline +int +sc_int_subref_r::to_int() const +{ + int result = static_cast<int>(operator uint_type()); + return result; +} + +inline +unsigned int +sc_int_subref_r::to_uint() const +{ + unsigned int result = static_cast<unsigned int>(operator uint_type()); + return result; +} + +inline +long +sc_int_subref_r::to_long() const +{ + long result = static_cast<long>(operator uint_type()); + return result; +} + +inline +unsigned long +sc_int_subref_r::to_ulong() const +{ + unsigned long result = static_cast<unsigned long>(operator uint_type()); + return result; +} + +inline +int64 +sc_int_subref_r::to_int64() const +{ + int64 result = operator uint_type(); + return result; +} + +inline +uint64 +sc_int_subref_r::to_uint64() const +{ + uint64 result = operator uint_type(); + return result; +} + +inline +double +sc_int_subref_r::to_double() const +{ + double result = static_cast<double>(operator uint_type()); + return result; +} + + +// explicit conversion to character string + +inline +const std::string +sc_int_subref_r::to_string( sc_numrep numrep ) const +{ + sc_uint_base a(length()); + a = operator uint_type(); + return a.to_string( numrep ); +} + +inline +const std::string +sc_int_subref_r::to_string( sc_numrep numrep, bool w_prefix ) const +{ + sc_uint_base a(length()); + a = operator uint_type(); + return a.to_string( numrep, w_prefix ); +} + + +// functional notation for the reduce methods + +inline +bool +and_reduce( const sc_int_subref_r& a ) +{ + return a.and_reduce(); +} + +inline +bool +nand_reduce( const sc_int_subref_r& a ) +{ + return a.nand_reduce(); +} + +inline +bool +or_reduce( const sc_int_subref_r& a ) +{ + return a.or_reduce(); +} + +inline +bool +nor_reduce( const sc_int_subref_r& a ) +{ + return a.nor_reduce(); +} + +inline +bool +xor_reduce( const sc_int_subref_r& a ) +{ + return a.xor_reduce(); +} + +inline +bool +xnor_reduce( const sc_int_subref_r& a ) +{ + return a.xnor_reduce(); +} + + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_int_subref_r& a ) +{ + a.print( os ); + return os; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_subref +// +// Proxy class for sc_int part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +// assignment operators + +inline +sc_int_subref& +sc_int_subref::operator = ( const sc_int_base& a ) +{ + return operator = ( a.operator int_type() ); +} + +inline +sc_int_subref& +sc_int_subref::operator = ( const char* a ) +{ + sc_int_base aa( length() ); + return ( *this = aa = a ); +} + + + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_int_subref& a ) +{ + a.scan( is ); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_base +// +// Base class for sc_int. +// ---------------------------------------------------------------------------- + +// bit selection + +inline +sc_int_bitref& +sc_int_base::operator [] ( int i ) +{ + check_index( i ); + sc_int_bitref* result_p = sc_int_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; +} + +inline +const sc_int_bitref_r& +sc_int_base::operator [] ( int i ) const +{ + check_index( i ); + sc_int_bitref* result_p = sc_int_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; +} + + +inline +sc_int_bitref& +sc_int_base::bit( int i ) +{ + check_index( i ); + sc_int_bitref* result_p = sc_int_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; +} + +inline +const sc_int_bitref_r& +sc_int_base::bit( int i ) const +{ + check_index( i ); + sc_int_bitref* result_p = sc_int_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; +} + + +// part selection + +inline +sc_int_subref& +sc_int_base::operator () ( int left, int right ) +{ + check_range( left, right ); + sc_int_subref* result_p = sc_int_subref::m_pool.allocate(); + result_p->initialize(this, left, right); + return *result_p; +} + +inline +const sc_int_subref_r& +sc_int_base::operator () ( int left, int right ) const +{ + check_range( left, right ); + sc_int_subref* result_p = sc_int_subref::m_pool.allocate(); + result_p->initialize(this, left, right); + return *result_p; +} + + +inline +sc_int_subref& +sc_int_base::range( int left, int right ) +{ + check_range( left, right ); + sc_int_subref* result_p = sc_int_subref::m_pool.allocate(); + result_p->initialize(this, left, right); + return *result_p; +} + +inline +const sc_int_subref_r& +sc_int_base::range( int left, int right ) const +{ + check_range( left, right ); + sc_int_subref* result_p = sc_int_subref::m_pool.allocate(); + result_p->initialize(this, left, right); + return *result_p; +} + + +// functional notation for the reduce methods + +inline +bool +and_reduce( const sc_int_base& a ) +{ + return a.and_reduce(); +} + +inline +bool +nand_reduce( const sc_int_base& a ) +{ + return a.nand_reduce(); +} + +inline +bool +or_reduce( const sc_int_base& a ) +{ + return a.or_reduce(); +} + +inline +bool +nor_reduce( const sc_int_base& a ) +{ + return a.nor_reduce(); +} + +inline +bool +xor_reduce( const sc_int_base& a ) +{ + return a.xor_reduce(); +} + +inline +bool +xnor_reduce( const sc_int_base& a ) +{ + return a.xnor_reduce(); +} + + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_int_base& a ) +{ + a.print( os ); + return os; +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_int_base& a ) +{ + a.scan( is ); + return is; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/int/sc_int_ids.h b/ext/systemc/src/sysc/datatypes/int/sc_int_ids.h new file mode 100644 index 000000000..13b269590 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_int_ids.h @@ -0,0 +1,80 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_int_ids.h -- Report ids for the datatypes/int code. + + Original Author: Martin Janssen, Synopsys, Inc., 2002-01-17 + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_int_ids.h,v $ +// Revision 1.2 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:31 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef SC_INT_IDS_H +#define SC_INT_IDS_H + + +#include "sysc/utils/sc_report.h" + + +// ---------------------------------------------------------------------------- +// Report ids (datatypes/int) +// +// Report ids in the range of 400-499. +// ---------------------------------------------------------------------------- + +#ifndef SC_DEFINE_MESSAGE +#define SC_DEFINE_MESSAGE(id,unused1,unused2) \ + namespace sc_core { extern const char id[]; } +extern const char SC_ID_REGISTER_ID_FAILED_[]; // in sc_report_handler.cpp +#endif + + +SC_DEFINE_MESSAGE( SC_ID_INIT_FAILED_, 400, "initialization failed" ) +SC_DEFINE_MESSAGE( SC_ID_ASSIGNMENT_FAILED_, 401, "assignment failed" ) +SC_DEFINE_MESSAGE( SC_ID_OPERATION_FAILED_, 402, "operation failed" ) +SC_DEFINE_MESSAGE( SC_ID_CONVERSION_FAILED_, 403, "conversion failed" ) + + + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/int/sc_length_param.cpp b/ext/systemc/src/sysc/datatypes/int/sc_length_param.cpp new file mode 100644 index 000000000..c0ba66b6b --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_length_param.cpp @@ -0,0 +1,97 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_length_param.cpp - + + Original Author: Martin Janssen, Synopsys, Inc., 2002-03-19 + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_length_param.cpp,v $ +// Revision 1.2 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:32 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#include "sysc/datatypes/int/sc_length_param.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// CLASS : sc_length_param +// +// Length parameter type. +// ---------------------------------------------------------------------------- + +const std::string +sc_length_param::to_string() const +{ + std::string s; + + char buf[BUFSIZ]; + + s += "("; + std::sprintf( buf, "%d", m_len ); + s += buf; + s += ")"; + + return s; +} + + +void +sc_length_param::print( ::std::ostream& os ) const +{ + os << to_string(); +} + +void +sc_length_param::dump( ::std::ostream& os ) const +{ + os << "sc_length_param" << ::std::endl; + os << "(" << ::std::endl; + os << "len = " << m_len << ::std::endl; + os << ")" << ::std::endl; +} + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/int/sc_length_param.h b/ext/systemc/src/sysc/datatypes/int/sc_length_param.h new file mode 100644 index 000000000..aadb52bda --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_length_param.h @@ -0,0 +1,203 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_length_param.h - + + Original Author: Martin Janssen, Synopsys, Inc., 2002-03-19 + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_length_param.h,v $ +// Revision 1.3 2011/08/24 22:05:46 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.2 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.4 2006/05/08 17:50:01 acg +// Andy Goodrich: Added David Long's declarations for friend operators, +// functions, and methods, to keep the Microsoft compiler happy. +// +// Revision 1.3 2006/01/13 18:49:32 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef SC_LENGTH_PARAM_H +#define SC_LENGTH_PARAM_H + + +#include "sysc/datatypes/fx/sc_context.h" + + +namespace sc_dt +{ + +// classes defined in this module +class sc_length_param; + +// friend operator declarations + bool operator == ( const sc_length_param&, + const sc_length_param& ); + bool operator != ( const sc_length_param&, + const sc_length_param& ); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_length_param +// +// Length parameter type. +// ---------------------------------------------------------------------------- + +class sc_length_param +{ +public: + + sc_length_param(); + sc_length_param( int ); + sc_length_param( const sc_length_param& ); + explicit sc_length_param( sc_without_context ); + + sc_length_param& operator = ( const sc_length_param& ); + + friend bool operator == ( const sc_length_param&, + const sc_length_param& ); + friend bool operator != ( const sc_length_param&, + const sc_length_param& ); + + int len() const; + void len( int ); + + const std::string to_string() const; + + void print( ::std::ostream& = ::std::cout ) const; + void dump( ::std::ostream& = ::std::cout ) const; + +private: + + int m_len; +}; + + +// ---------------------------------------------------------------------------- +// TYPEDEF : sc_length_context +// +// Context type for the length parameter type. +// ---------------------------------------------------------------------------- + +typedef sc_context<sc_length_param> sc_length_context; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +inline +sc_length_param::sc_length_param() : m_len() +{ + *this = sc_length_context::default_value(); +} + +inline +sc_length_param::sc_length_param( int len_ ) : m_len(len_) +{ + SC_CHECK_WL_( len_ ); +} + +inline +sc_length_param::sc_length_param( const sc_length_param& a ) + : m_len( a.m_len ) +{} + +inline +sc_length_param::sc_length_param( sc_without_context ) + : m_len( SC_DEFAULT_WL_ ) +{} + + +inline +sc_length_param& +sc_length_param::operator = ( const sc_length_param& a ) +{ + if( &a != this ) + { + m_len = a.m_len; + } + return *this; +} + + +inline +bool +operator == ( const sc_length_param& a, const sc_length_param& b ) +{ + return ( a.m_len == b.m_len ); +} + +inline +bool +operator != ( const sc_length_param& a, const sc_length_param& b ) +{ + return ( a.m_len != b.m_len ); +} + + +inline +int +sc_length_param::len() const +{ + return m_len; +} + +inline +void +sc_length_param::len( int len_ ) +{ + SC_CHECK_WL_( len_ ); + m_len = len_; +} + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_length_param& a ) +{ + a.print( os ); + return os; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/int/sc_nbcommon.inc b/ext/systemc/src/sysc/datatypes/int/sc_nbcommon.inc new file mode 100644 index 000000000..89fc4ba83 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_nbcommon.inc @@ -0,0 +1,2989 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_nbcommon.cpp -- Functions common to both sc_signed and sc_unsigned. + This file is included in sc_signed.cpp and + sc_unsigned.cpp after the macros are defined accordingly. + For example, sc_signed.cpp will first define CLASS_TYPE + as sc_signed before including this file. This file like + sc_nbfriends.cpp and sc_nbexterns.cpp is created in order + to ensure only one version of each function, regardless + of the class that they interface to. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// ---------------------------------------------------------------------------- +// SECTION : Public members +// ---------------------------------------------------------------------------- + +// Create a CLASS_TYPE number with nb bits. +CLASS_TYPE::CLASS_TYPE( int nb ) : + sc_value_base(), sgn(), nbits(), ndigits(), digit() +{ + sgn = default_sign(); + if( nb > 0 ) { + nbits = num_bits( nb ); + } else { + char msg[BUFSIZ]; + std::sprintf( msg, "%s::%s( int nb ) : nb = %d is not valid", + CLASS_TYPE_STR, CLASS_TYPE_STR, nb ); + SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg ); + } + ndigits = DIV_CEIL(nbits); +#ifdef SC_MAX_NBITS + test_bound(nb); +#else + digit = new sc_digit[ndigits]; +#endif + makezero(); +} + + +// Create a copy of v with sgn s. v is of the same type. +CLASS_TYPE::CLASS_TYPE(const CLASS_TYPE& v) : + sc_value_base(v), sgn(v.sgn), nbits(v.nbits), ndigits(v.ndigits), digit() +{ +#ifndef SC_MAX_NBITS + digit = new sc_digit[ndigits]; +#endif + + vec_copy(ndigits, digit, v.digit); +} + + +// Create a copy of v where v is of the different type. +CLASS_TYPE::CLASS_TYPE(const OTHER_CLASS_TYPE& v) : + sc_value_base(v), sgn(v.sgn), nbits(num_bits(v.nbits)), ndigits(), digit() +{ +#if (IF_SC_SIGNED == 1) + ndigits = v.ndigits; +#else + ndigits = DIV_CEIL(nbits); +#endif + +#ifndef SC_MAX_NBITS + digit = new sc_digit[ndigits]; +#endif + + copy_digits(v.nbits, v.ndigits, v.digit); +} + +// Create a copy of v where v is an sign-less instance. +CLASS_TYPE::CLASS_TYPE(const sc_bv_base& v) : + sc_value_base(), sgn(), nbits(), ndigits(), digit() +{ + int nb = v.length(); + sgn = default_sign(); + if( nb > 0 ) { + nbits = num_bits( nb ); + } else { + char msg[BUFSIZ]; + std::sprintf( msg, "%s::%s( sc_bv_base ) : nb = %d is not valid", + CLASS_TYPE_STR, CLASS_TYPE_STR, nb ); + SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg ); + } + ndigits = DIV_CEIL(nbits); +# ifdef SC_MAX_NBITS + test_bound(nb); +# else + digit = new sc_digit[ndigits]; +# endif + makezero(); + *this = v; +} + +CLASS_TYPE::CLASS_TYPE(const sc_lv_base& v) : + sc_value_base(), sgn(), nbits(), ndigits(), digit() +{ + int nb = v.length(); + sgn = default_sign(); + if( nb > 0 ) { + nbits = num_bits( nb ); + } else { + char msg[BUFSIZ]; + std::sprintf( msg, "%s::%s( sc_lv_base ) : nb = %d is not valid", + CLASS_TYPE_STR, CLASS_TYPE_STR, nb ); + SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg ); + } + ndigits = DIV_CEIL(nbits); +# ifdef SC_MAX_NBITS + test_bound(nb); +# else + digit = new sc_digit[ndigits]; +# endif + makezero(); + *this = v; +} + +CLASS_TYPE::CLASS_TYPE(const sc_int_subref_r& v) : + sc_value_base(v), sgn(), nbits(), ndigits(), digit() +{ + int nb = v.length(); + sgn = default_sign(); + if( nb > 0 ) { + nbits = num_bits( nb ); + } else { + char msg[BUFSIZ]; + std::sprintf( msg, "%s::%s( sc_int_subref ) : nb = %d is not valid", + CLASS_TYPE_STR, CLASS_TYPE_STR, nb ); + SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg ); + } + ndigits = DIV_CEIL(nbits); +# ifdef SC_MAX_NBITS + test_bound(nb); +# else + digit = new sc_digit[ndigits]; +# endif + makezero(); + *this = v.to_uint64(); +} + +CLASS_TYPE::CLASS_TYPE(const sc_uint_subref_r& v) : + sc_value_base(v), sgn(), nbits(), ndigits(), digit() +{ + int nb = v.length(); + sgn = default_sign(); + if( nb > 0 ) { + nbits = num_bits( nb ); + } else { + char msg[BUFSIZ]; + std::sprintf( msg, "%s::%s( sc_uint_subref ) : nb = %d is not valid", + CLASS_TYPE_STR, CLASS_TYPE_STR, nb ); + SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg ); + } + ndigits = DIV_CEIL(nbits); +# ifdef SC_MAX_NBITS + test_bound(nb); +# else + digit = new sc_digit[ndigits]; +# endif + makezero(); + *this = v.to_uint64(); +} + +CLASS_TYPE::CLASS_TYPE(const sc_signed_subref_r& v) : + sc_value_base(v), sgn(), nbits(), ndigits(), digit() +{ + int nb = v.length(); + sgn = default_sign(); + if( nb > 0 ) { + nbits = num_bits( nb ); + } else { + char msg[BUFSIZ]; + std::sprintf( msg, "%s::%s( sc_signed_subref ) : nb = %d is not valid", + CLASS_TYPE_STR, CLASS_TYPE_STR, nb ); + SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg ); + } + ndigits = DIV_CEIL(nbits); +# ifdef SC_MAX_NBITS + test_bound(nb); +# else + digit = new sc_digit[ndigits]; +# endif + makezero(); + *this = sc_unsigned(v.m_obj_p, v.m_left, v.m_right); +} + +CLASS_TYPE::CLASS_TYPE(const sc_unsigned_subref_r& v) : + sc_value_base(v), sgn(), nbits(), ndigits(), digit() +{ + int nb = v.length(); + sgn = default_sign(); + if( nb > 0 ) { + nbits = num_bits( nb ); + } else { + char msg[BUFSIZ]; + std::sprintf( msg, "%s::%s( sc_unsigned_subref ) : nb = %d is not valid", + CLASS_TYPE_STR, CLASS_TYPE_STR, nb ); + SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg ); + } + ndigits = DIV_CEIL(nbits); +# ifdef SC_MAX_NBITS + test_bound(nb); +# else + digit = new sc_digit[ndigits]; +# endif + makezero(); + *this = sc_unsigned(v.m_obj_p, v.m_left, v.m_right); +} + +// ---------------------------------------------------------------------------- +// SECTION: Public members - Concatenation support. +// ---------------------------------------------------------------------------- + + +// ---------------------------------------------------------------------------- +// SECTION: Public members - Assignment operators. +// ---------------------------------------------------------------------------- + +// Assignment from v of the same type. +const CLASS_TYPE& +CLASS_TYPE::operator=(const CLASS_TYPE& v) +{ + if (this != &v) { + + sgn = v.sgn; + + if (sgn == SC_ZERO) + vec_zero(ndigits, digit); + + else + copy_digits(v.nbits, v.ndigits, v.digit); + + } + + return *this; +} + + +// Assignment from v of the different type. +const CLASS_TYPE& +CLASS_TYPE::operator=(const OTHER_CLASS_TYPE& v) +{ + sgn = v.sgn; + + if (sgn == SC_ZERO) + vec_zero(ndigits, digit); + + else + copy_digits(v.nbits, v.ndigits, v.digit); + + return *this; +} + + +// Assignment from an sc_unsigned_subref_r +const CLASS_TYPE& +CLASS_TYPE::operator=(const sc_unsigned_subref_r& v) +{ + return operator=(sc_unsigned(v)); +} + + +// Assignment from an sc_signed_subref_r +const CLASS_TYPE& +CLASS_TYPE::operator=(const sc_signed_subref_r& v) +{ + return operator=(sc_unsigned(v)); +} + + +// ---------------------------------------------------------------------------- +// SECTION: Input and output operators +// ---------------------------------------------------------------------------- + +void +CLASS_TYPE::scan( ::std::istream& is ) +{ + std::string s; + is >> s; + *this = s.c_str(); +} + + +// ---------------------------------------------------------------------------- +// SECTION: PLUS operators: +, +=, ++ +// ---------------------------------------------------------------------------- + +// Cases to consider when computing u + v: +// 1. 0 + v = v +// 2. u + 0 = u +// 3. if sgn(u) == sgn(v) +// 3.1 u + v = +(u + v) = sgn(u) * (u + v) +// 3.2 (-u) + (-v) = -(u + v) = sgn(u) * (u + v) +// 4. if sgn(u) != sgn(v) +// 4.1 u + (-v) = u - v = sgn(u) * (u - v) +// 4.2 (-u) + v = -(u - v) ==> sgn(u) * (u - v) +// +// Specialization of above cases for computing ++u or u++: +// 1. 0 + 1 = 1 +// 3. u + 1 = u + 1 = sgn(u) * (u + 1) +// 4. (-u) + 1 = -(u - 1) = sgn(u) * (u - 1) + +const CLASS_TYPE& +CLASS_TYPE::operator+=(const CLASS_TYPE& v) +{ + // u = *this + + if (sgn == SC_ZERO) // case 1 + return (*this = v); + + if (v.sgn == SC_ZERO) // case 2 + return *this; + + // cases 3 and 4 + add_on_help(sgn, nbits, ndigits, digit, + v.sgn, v.nbits, v.ndigits, v.digit); + + convert_SM_to_2C_to_SM(); + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator+=(const OTHER_CLASS_TYPE& v) +{ + // u = *this + + if (sgn == SC_ZERO) // case 1 + return (*this = v); + + if (v.sgn == SC_ZERO) // case 2 + return *this; + + // cases 3 and 4 + add_on_help(sgn, nbits, ndigits, digit, + v.sgn, v.nbits, v.ndigits, v.digit); + + convert_SM_to_2C_to_SM(); + + return *this; +} + + +CLASS_TYPE& +CLASS_TYPE::operator++() // prefix +{ + *this = *this + 1; + return *this; +} + + +const CLASS_TYPE +CLASS_TYPE::operator++(int) // postfix +{ + // Copy digit into d. + +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS]; +#else + sc_digit *d = new sc_digit[ndigits]; +#endif + + small_type s = sgn; + + vec_copy(ndigits, d, digit); + + *this = *this + 1; + + return CLASS_TYPE(s, nbits, ndigits, d); +} + + +const CLASS_TYPE& +CLASS_TYPE::operator+=(int64 v) +{ + // u = *this + + if (sgn == SC_ZERO) // case 1 + return (*this = v); + + if (v == 0) // case 2 + return *this; + + CONVERT_INT64(v); + + // cases 3 and 4 + add_on_help(sgn, nbits, ndigits, digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + + convert_SM_to_2C_to_SM(); + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator+=(uint64 v) +{ + // u = *this + + if (sgn == SC_ZERO) // case 1 + return (*this = v); + + if (v == 0) // case 2 + return *this; + + CONVERT_INT64(v); + + // cases 3 and 4 + add_on_help(sgn, nbits, ndigits, digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + + convert_SM_to_2C_to_SM(); + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator+=(long v) +{ + // u = *this + + if (sgn == SC_ZERO) // case 1 + return (*this = v); + + if (v == 0) // case 2 + return *this; + + CONVERT_LONG(v); + + // cases 3 and 4 + add_on_help(sgn, nbits, ndigits, digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + + convert_SM_to_2C_to_SM(); + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator+=(unsigned long v) +{ + // u = *this + + if (sgn == SC_ZERO) // case 1 + return (*this = v); + + if (v == 0) // case 2 + return *this; + + CONVERT_LONG(v); + + // cases 3 and 4 + add_on_help(sgn, nbits, ndigits, digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + + convert_SM_to_2C_to_SM(); + + return *this; +} + + +// ---------------------------------------------------------------------------- +// SECTION: MINUS operators: -, -=, -- +// ---------------------------------------------------------------------------- + +// Cases to consider when computing u + v: +// 1. u - 0 = u +// 2. 0 - v = -v +// 3. if sgn(u) != sgn(v) +// 3.1 u - (-v) = u + v = sgn(u) * (u + v) +// 3.2 (-u) - v = -(u + v) ==> sgn(u) * (u + v) +// 4. if sgn(u) == sgn(v) +// 4.1 u - v = +(u - v) = sgn(u) * (u - v) +// 4.2 (-u) - (-v) = -(u - v) = sgn(u) * (u - v) +// +// Specialization of above cases for computing --u or u--: +// 1. 0 - 1 = -1 +// 3. (-u) - 1 = -(u + 1) = sgn(u) * (u + 1) +// 4. u - 1 = u - 1 = sgn(u) * (u - 1) + +const CLASS_TYPE& +CLASS_TYPE::operator-=(const CLASS_TYPE& v) +{ + // u = *this + + if (v.sgn == SC_ZERO) // case 1 + return *this; + + if (sgn == SC_ZERO) { // case 2 + + sgn = -v.sgn; + copy_digits(v.nbits, v.ndigits, v.digit); + + } + else { + + // cases 3 and 4 + add_on_help(sgn, nbits, ndigits, digit, + -v.sgn, v.nbits, v.ndigits, v.digit); + + convert_SM_to_2C_to_SM(); + + } + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator-=(const OTHER_CLASS_TYPE& v) +{ + // u = *this + + if (v.sgn == SC_ZERO) // case 1 + return *this; + + if (sgn == SC_ZERO) { // case 2 + + sgn = -v.sgn; + copy_digits(v.nbits, v.ndigits, v.digit); + + } + else { + + // cases 3 and 4 + add_on_help(sgn, nbits, ndigits, digit, + -v.sgn, v.nbits, v.ndigits, v.digit); + + convert_SM_to_2C_to_SM(); + + } + + return *this; +} + + +CLASS_TYPE& +CLASS_TYPE::operator--() // prefix +{ + *this = *this - 1; + return *this; +} + + +const CLASS_TYPE +CLASS_TYPE::operator--(int) // postfix +{ + // Copy digit into d. + +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS]; +#else + sc_digit *d = new sc_digit[ndigits]; +#endif + + small_type s = sgn; + + vec_copy(ndigits, d, digit); + + *this = *this - 1; + + return CLASS_TYPE(s, nbits, ndigits, d); +} + + +const CLASS_TYPE& +CLASS_TYPE::operator-=(int64 v) +{ + // u = *this + + if (v == 0) // case 1 + return *this; + + if (sgn == SC_ZERO) // case 2 + return (*this = -v); + + CONVERT_INT64(v); + + // cases 3 and 4 + add_on_help(sgn, nbits, ndigits, digit, + -vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + + convert_SM_to_2C_to_SM(); + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator-=(uint64 v) +{ + // u = *this + + if (v == 0) // case 1 + return *this; + + int64 v2 = (int64) v; + + if (sgn == SC_ZERO) // case 2 + return (*this = -v2); + + CONVERT_INT64(v); + + // cases 3 and 4 + add_on_help(sgn, nbits, ndigits, digit, + -vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + + convert_SM_to_2C_to_SM(); + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator-=(long v) +{ + // u = *this + + if (v == 0) // case 1 + return *this; + + if (sgn == SC_ZERO) // case 2 + return (*this = -v); + + CONVERT_LONG(v); + + // cases 3 and 4 + add_on_help(sgn, nbits, ndigits, digit, + -vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + + convert_SM_to_2C_to_SM(); + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator-=(unsigned long v) +{ + // u = *this + + if (v == 0) // case 1 + return *this; + + long v2 = (long) v; + + if (sgn == SC_ZERO) // case 2 + return (*this = -v2); + + CONVERT_LONG(v); + + // cases 3 and 4 + add_on_help(sgn, nbits, ndigits, digit, + -vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + + convert_SM_to_2C_to_SM(); + + return *this; +} + + +// ---------------------------------------------------------------------------- +// SECTION: MULTIPLICATION operators: *, *= +// ---------------------------------------------------------------------------- + +// Cases to consider when computing u * v: +// 1. u * 0 = 0 * v = 0 +// 2. 1 * v = v and -1 * v = -v +// 3. u * 1 = u and u * -1 = -u +// 4. u * v = u * v + +const CLASS_TYPE& +CLASS_TYPE::operator*=(const CLASS_TYPE& v) +{ + // u = *this + + sgn = mul_signs(sgn, v.sgn); + + if (sgn == SC_ZERO) // case 1 + vec_zero(ndigits, digit); + + else + // cases 2-4 + MUL_ON_HELPER(sgn, nbits, ndigits, digit, + v.nbits, v.ndigits, v.digit); + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator*=(const OTHER_CLASS_TYPE& v) +{ + // u = *this + + sgn = mul_signs(sgn, v.sgn); + + if (sgn == SC_ZERO) // case 1 + vec_zero(ndigits, digit); + + else + // cases 2-4 + MUL_ON_HELPER(sgn, nbits, ndigits, digit, + v.nbits, v.ndigits, v.digit); + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator*=(int64 v) +{ + // u = *this + + sgn = mul_signs(sgn, get_sign(v)); + + if (sgn == SC_ZERO) // case 1 + vec_zero(ndigits, digit); + + else { // cases 2-4 + + CONVERT_INT64_2(v); + + MUL_ON_HELPER(sgn, nbits, ndigits, digit, + BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + + } + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator*=(uint64 v) +{ + // u = *this + + sgn = mul_signs(sgn, get_sign(v)); + + if (sgn == SC_ZERO) // case 1 + vec_zero(ndigits, digit); + + else { // cases 2-4 + + CONVERT_INT64_2(v); + + MUL_ON_HELPER(sgn, nbits, ndigits, digit, + BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + + } + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator*=(long v) +{ + // u = *this + + sgn = mul_signs(sgn, get_sign(v)); + + if (sgn == SC_ZERO) // case 1 + vec_zero(ndigits, digit); + + else { // cases 2-4 + + CONVERT_LONG_2(v); + + MUL_ON_HELPER(sgn, nbits, ndigits, digit, + BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + + } + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator*=(unsigned long v) +{ + // u = *this + + sgn = mul_signs(sgn, get_sign(v)); + + if (sgn == SC_ZERO) // case 1 + vec_zero(ndigits, digit); + + else { // cases 2-4 + + CONVERT_LONG_2(v); + + MUL_ON_HELPER(sgn, nbits, ndigits, digit, + BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + + } + + return *this; +} + + +// ---------------------------------------------------------------------------- +// SECTION: DIVISION operators: /, /= +// ---------------------------------------------------------------------------- + +// Cases to consider when finding the quotient q = floor(u/v): +// Note that u = q * v + r for r < q. +// 1. 0 / 0 or u / 0 => error +// 2. 0 / v => 0 = 0 * v + 0 +// 3. u / v && u = v => u = 1 * u + 0 - u or v can be 1 or -1 +// 4. u / v && u < v => u = 0 * v + u - u can be 1 or -1 +// 5. u / v && u > v => u = q * v + r - v can be 1 or -1 + +const CLASS_TYPE& +CLASS_TYPE::operator/=(const CLASS_TYPE& v) +{ + sgn = mul_signs(sgn, v.sgn); + + if (sgn == SC_ZERO) { + + div_by_zero(v.sgn); // case 1 + vec_zero(ndigits, digit); // case 2 + + } + else // other cases + DIV_ON_HELPER(sgn, nbits, ndigits, digit, + v.nbits, v.ndigits, v.digit); + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator/=(const OTHER_CLASS_TYPE& v) +{ + sgn = mul_signs(sgn, v.sgn); + + if (sgn == SC_ZERO) { + + div_by_zero(v.sgn); // case 1 + vec_zero(ndigits, digit); // case 2 + + } + else // other cases + DIV_ON_HELPER(sgn, nbits, ndigits, digit, + v.nbits, v.ndigits, v.digit); + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator/=(int64 v) +{ + // u = *this + + sgn = mul_signs(sgn, get_sign(v)); + + if (sgn == SC_ZERO) { + + div_by_zero(v); // case 1 + vec_zero(ndigits, digit); // case 2 + + } + else { + + CONVERT_INT64_2(v); + + // other cases + DIV_ON_HELPER(sgn, nbits, ndigits, digit, + BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + + } + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator/=(uint64 v) +{ + // u = *this + + sgn = mul_signs(sgn, get_sign(v)); + + if (sgn == SC_ZERO) { + + div_by_zero(v); // case 1 + vec_zero(ndigits, digit); // case 2 + + } + else { + + CONVERT_INT64_2(v); + + // other cases + DIV_ON_HELPER(sgn, nbits, ndigits, digit, + BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + + } + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator/=(long v) +{ + // u = *this + + sgn = mul_signs(sgn, get_sign(v)); + + if (sgn == SC_ZERO) { + + div_by_zero(v); // case 1 + vec_zero(ndigits, digit); // case 2 + + } + else { + + CONVERT_LONG_2(v); + + // other cases + DIV_ON_HELPER(sgn, nbits, ndigits, digit, + BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + + } + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator/=(unsigned long v) +{ + // u = *this + + sgn = mul_signs(sgn, get_sign(v)); + + if (sgn == SC_ZERO) { + + div_by_zero(v); // case 1 + vec_zero(ndigits, digit); // case 2 + + } + else { + + CONVERT_LONG_2(v); + + // other cases + DIV_ON_HELPER(sgn, nbits, ndigits, digit, + BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + + } + + return *this; +} + + +// ---------------------------------------------------------------------------- +// SECTION: MOD operators: %, %=. +// ---------------------------------------------------------------------------- + +// Cases to consider when finding the remainder r = u % v: +// Note that u = q * v + r for r < q. +// 1. 0 % 0 or u % 0 => error +// 2. 0 % v => 0 = 0 * v + 0 +// 3. u % v && u = v => u = 1 * u + 0 - u or v can be 1 or -1 +// 4. u % v && u < v => u = 0 * v + u - u can be 1 or -1 +// 5. u % v && u > v => u = q * v + r - v can be 1 or -1 + +const CLASS_TYPE& +CLASS_TYPE::operator%=(const CLASS_TYPE& v) +{ + if ((sgn == SC_ZERO) || (v.sgn == SC_ZERO)) { + + div_by_zero(v.sgn); // case 1 + vec_zero(ndigits, digit); // case 2 + + } + else // other cases + MOD_ON_HELPER(sgn, nbits, ndigits, digit, + v.nbits, v.ndigits, v.digit); + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator%=(const OTHER_CLASS_TYPE& v) +{ + if ((sgn == SC_ZERO) || (v.sgn == SC_ZERO)) { + + div_by_zero(v.sgn); // case 1 + vec_zero(ndigits, digit); // case 2 + + } + else // other cases + MOD_ON_HELPER(sgn, nbits, ndigits, digit, + v.nbits, v.ndigits, v.digit); + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator%=(int64 v) +{ + small_type vs = get_sign(v); + + if ((sgn == SC_ZERO) || (vs == SC_ZERO)) { + + div_by_zero(v); // case 1 + vec_zero(ndigits, digit); // case 2 + + } + else { + + CONVERT_INT64_2(v); + + // other cases + MOD_ON_HELPER(sgn, nbits, ndigits, digit, + BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + + } + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator%=(uint64 v) +{ + if ((sgn == SC_ZERO) || (v == 0)) { + + div_by_zero(v); // case 1 + vec_zero(ndigits, digit); // case 2 + + } + else { + + CONVERT_INT64_2(v); + + // other cases + MOD_ON_HELPER(sgn, nbits, ndigits, digit, + BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + + } + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator%=(long v) +{ + small_type vs = get_sign(v); + + if ((sgn == SC_ZERO) || (vs == SC_ZERO)) { + + div_by_zero(v); // case 1 + vec_zero(ndigits, digit); // case 2 + + } + else { + + CONVERT_LONG_2(v); + + // other cases + MOD_ON_HELPER(sgn, nbits, ndigits, digit, + BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + + } + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator%=(unsigned long v) +{ + if ((sgn == SC_ZERO) || (v == 0)) { + + div_by_zero(v); // case 1 + vec_zero(ndigits, digit); // case 2 + + } + else { + + CONVERT_LONG_2(v); + + // other cases + MOD_ON_HELPER(sgn, nbits, ndigits, digit, + BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + + } + + return *this; +} + + +// ---------------------------------------------------------------------------- +// SECTION: Bitwise AND operators: &, &= +// ---------------------------------------------------------------------------- + +// Cases to consider when computing u & v: +// 1. u & 0 = 0 & v = 0 +// 2. u & v => sgn = + +// 3. (-u) & (-v) => sgn = - +// 4. u & (-v) => sgn = + +// 5. (-u) & v => sgn = + + +const CLASS_TYPE& +CLASS_TYPE::operator&=(const CLASS_TYPE& v) +{ + // u = *this + + if ((sgn == SC_ZERO) || (v.sgn == SC_ZERO)) // case 1 + makezero(); + + else { // other cases + + and_on_help(sgn, nbits, ndigits, digit, + v.sgn, v.nbits, v.ndigits, v.digit); + + convert_2C_to_SM(); + + } + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator&=(const OTHER_CLASS_TYPE& v) +{ + // u = *this + + if ((sgn == SC_ZERO) || (v.sgn == SC_ZERO)) // case 1 + makezero(); + + else { // other cases + + and_on_help(sgn, nbits, ndigits, digit, + v.sgn, v.nbits, v.ndigits, v.digit); + + convert_2C_to_SM(); + + } + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator&=(int64 v) +{ + // u = *this + + if ((sgn == SC_ZERO) || (v == 0)) // case 1 + makezero(); + + else { // other cases + + CONVERT_INT64(v); + + and_on_help(sgn, nbits, ndigits, digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + + convert_2C_to_SM(); + + } + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator&=(uint64 v) +{ + // u = *this + + if ((sgn == SC_ZERO) || (v == 0)) // case 1 + makezero(); + + else { // other cases + + CONVERT_INT64(v); + + and_on_help(sgn, nbits, ndigits, digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + + convert_2C_to_SM(); + + } + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator&=(long v) +{ + // u = *this + + if ((sgn == SC_ZERO) || (v == 0)) // case 1 + makezero(); + + else { // other cases + + CONVERT_LONG(v); + + and_on_help(sgn, nbits, ndigits, digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + + convert_2C_to_SM(); + + } + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator&=(unsigned long v) +{ + // u = *this + + if ((sgn == SC_ZERO) || (v == 0)) // case 1 + makezero(); + + else { // other cases + + CONVERT_LONG(v); + + and_on_help(sgn, nbits, ndigits, digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + + convert_2C_to_SM(); + + } + + return *this; +} + + +// ---------------------------------------------------------------------------- +// SECTION: Bitwise OR operators: |, |= +// ---------------------------------------------------------------------------- + +// Cases to consider when computing u | v: +// 1. u | 0 = u +// 2. 0 | v = v +// 3. u | v => sgn = + +// 4. (-u) | (-v) => sgn = - +// 5. u | (-v) => sgn = - +// 6. (-u) | v => sgn = - + +const CLASS_TYPE& +CLASS_TYPE::operator|=(const CLASS_TYPE& v) +{ + if (v.sgn == SC_ZERO) // case 1 + return *this; + + if (sgn == SC_ZERO) // case 2 + return (*this = v); + + // other cases + or_on_help(sgn, nbits, ndigits, digit, + v.sgn, v.nbits, v.ndigits, v.digit); + + convert_2C_to_SM(); + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator|=(const OTHER_CLASS_TYPE& v) +{ + if (v.sgn == SC_ZERO) // case 1 + return *this; + + if (sgn == SC_ZERO) // case 2 + return (*this = v); + + // other cases + or_on_help(sgn, nbits, ndigits, digit, + v.sgn, v.nbits, v.ndigits, v.digit); + + convert_2C_to_SM(); + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator|=(int64 v) +{ + if (v == 0) // case 1 + return *this; + + if (sgn == SC_ZERO) // case 2 + return (*this = v); + + // other cases + + CONVERT_INT64(v); + + or_on_help(sgn, nbits, ndigits, digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + + convert_2C_to_SM(); + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator|=(uint64 v) +{ + if (v == 0) // case 1 + return *this; + + if (sgn == SC_ZERO) // case 2 + return (*this = v); + + // other cases + + CONVERT_INT64(v); + + or_on_help(sgn, nbits, ndigits, digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + + convert_2C_to_SM(); + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator|=(long v) +{ + if (v == 0) // case 1 + return *this; + + if (sgn == SC_ZERO) // case 2 + return (*this = v); + + // other cases + + CONVERT_LONG(v); + + or_on_help(sgn, nbits, ndigits, digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + + convert_2C_to_SM(); + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator|=(unsigned long v) +{ + if (v == 0) // case 1 + return *this; + + if (sgn == SC_ZERO) // case 2 + return (*this = v); + + // other cases + + CONVERT_LONG(v); + + or_on_help(sgn, nbits, ndigits, digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + + convert_2C_to_SM(); + + return *this; +} + + +// ---------------------------------------------------------------------------- +// SECTION: Bitwise XOR operators: ^, ^= +// ---------------------------------------------------------------------------- + +// Cases to consider when computing u ^ v: +// Note that u ^ v = (~u & v) | (u & ~v). +// 1. u ^ 0 = u +// 2. 0 ^ v = v +// 3. u ^ v => sgn = + +// 4. (-u) ^ (-v) => sgn = - +// 5. u ^ (-v) => sgn = - +// 6. (-u) ^ v => sgn = + + +const CLASS_TYPE& +CLASS_TYPE::operator^=(const CLASS_TYPE& v) +{ + // u = *this + + if (v.sgn == SC_ZERO) // case 1 + return *this; + + if (sgn == SC_ZERO) // case 2 + return (*this = v); + + // other cases + xor_on_help(sgn, nbits, ndigits, digit, + v.sgn, v.nbits, v.ndigits, v.digit); + + convert_2C_to_SM(); + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator^=(const OTHER_CLASS_TYPE& v) +{ + // u = *this + + if (v.sgn == SC_ZERO) // case 1 + return *this; + + if (sgn == SC_ZERO) // case 2 + return (*this = v); + + // other cases + xor_on_help(sgn, nbits, ndigits, digit, + v.sgn, v.nbits, v.ndigits, v.digit); + + convert_2C_to_SM(); + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator^=(int64 v) +{ + if (v == 0) // case 1 + return *this; + + if (sgn == SC_ZERO) // case 2 + return (*this = v); + + // other cases + + CONVERT_INT64(v); + + xor_on_help(sgn, nbits, ndigits, digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + + convert_2C_to_SM(); + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator^=(uint64 v) +{ + if (v == 0) // case 1 + return *this; + + if (sgn == SC_ZERO) // case 2 + return (*this = v); + + // other cases + + CONVERT_INT64(v); + + xor_on_help(sgn, nbits, ndigits, digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + + convert_2C_to_SM(); + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator^=(long v) +{ + if (v == 0) // case 1 + return *this; + + if (sgn == SC_ZERO) // case 2 + return (*this = v); + + // other cases + + CONVERT_LONG(v); + + xor_on_help(sgn, nbits, ndigits, digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + + convert_2C_to_SM(); + + return *this; +} + + +const CLASS_TYPE& +CLASS_TYPE::operator^=(unsigned long v) +{ + if (v == 0) // case 1 + return *this; + + if (sgn == SC_ZERO) // case 2 + return (*this = v); + + // other cases + + CONVERT_LONG(v); + + xor_on_help(sgn, nbits, ndigits, digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + + convert_2C_to_SM(); + + return *this; +} + + +// ---------------------------------------------------------------------------- +// SECTION: Bitwise NOT operator: ~ +// ---------------------------------------------------------------------------- + +CLASS_TYPE +operator~(const CLASS_TYPE& u) +{ + small_type s = u.sgn; + + if (s == SC_ZERO) { + + sc_digit d = 1; + return CLASS_TYPE(SC_NEG, u.nbits, 1, &d, false); + + } + + int nd = u.ndigits; + +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS]; +#else + sc_digit *d = new sc_digit[nd]; +#endif + + vec_copy(nd, d, u.digit); + + if (s == SC_POS) { + + s = SC_NEG; + vec_add_small_on(nd, d, 1); + + } + else { + + s = SC_POS; + vec_sub_small_on(nd, d, 1); + + if (check_for_zero(nd, d)) + s = SC_ZERO; + + } + + return CLASS_TYPE(s, u.nbits, nd, d); +} + + +// ---------------------------------------------------------------------------- +// SECTION: LEFT SHIFT operators: <<, <<= +// ---------------------------------------------------------------------------- + +CLASS_TYPE +operator<<(const CLASS_TYPE& u, const CLASS_TYPE& v) +{ + if (v.sgn == SC_ZERO) + return CLASS_TYPE(u); + +#ifdef SC_SIGNED + if (v.sgn == SC_NEG) + return CLASS_TYPE(u); +#endif + + return operator<<(u, v.to_ulong()); +} + + +const CLASS_TYPE& +CLASS_TYPE::operator<<=(const CLASS_TYPE& v) +{ + if (v.sgn == SC_ZERO) + return *this; + +#ifdef SC_SIGNED + if (v.sgn == SC_NEG) + return *this; +#endif + + return operator<<=(v.to_ulong()); +} + + +const CLASS_TYPE& +CLASS_TYPE::operator<<=(const OTHER_CLASS_TYPE& v) +{ + if (v.sgn == SC_ZERO) + return *this; + +#ifdef SC_UNSIGNED + if (v.sgn == SC_NEG) + return *this; +#endif + + return operator<<=(v.to_ulong()); +} + + +CLASS_TYPE +operator<<(const CLASS_TYPE& u, int64 v) +{ + if (v <= 0) + return CLASS_TYPE(u); + + return operator<<(u, (unsigned long) v); +} + + +CLASS_TYPE +operator<<(const CLASS_TYPE& u, uint64 v) +{ + if (v == 0) + return CLASS_TYPE(u); + + return operator<<(u, (unsigned long) v); +} + + +const CLASS_TYPE& +CLASS_TYPE::operator<<=(int64 v) +{ + if (v <= 0) + return *this; + + return operator<<=((unsigned long) v); +} + + +const CLASS_TYPE& +CLASS_TYPE::operator<<=(uint64 v) +{ + if (v == 0) + return *this; + + return operator<<=((unsigned long) v); +} + + +CLASS_TYPE +operator<<(const CLASS_TYPE& u, long v) +{ + if (v <= 0) + return CLASS_TYPE(u); + + return operator<<(u, (unsigned long) v); +} + +CLASS_TYPE +operator<<(const CLASS_TYPE& u, unsigned long v) +{ + if (v == 0) + return CLASS_TYPE(u); + + if (u.sgn == SC_ZERO) + return CLASS_TYPE(u); + + int nb = u.nbits + v; + int nd = DIV_CEIL(nb); + +#ifdef SC_MAX_NBITS + test_bound(nb); + sc_digit d[MAX_NDIGITS]; +#else + sc_digit *d = new sc_digit[nd]; +#endif + + vec_copy_and_zero(nd, d, u.ndigits, u.digit); + + convert_SM_to_2C(u.sgn, nd, d); + + vec_shift_left(nd, d, v); + + small_type s = convert_signed_2C_to_SM(nb, nd, d); + + return CLASS_TYPE(s, nb, nd, d); +} + + +const CLASS_TYPE& +CLASS_TYPE::operator<<=(long v) +{ + if (v <= 0) + return *this; + + return operator<<=((unsigned long) v); +} + + +const CLASS_TYPE& +CLASS_TYPE::operator<<=(unsigned long v) +{ + if (v == 0) + return *this; + + if (sgn == SC_ZERO) + return *this; + + convert_SM_to_2C(); + + vec_shift_left(ndigits, digit, v); + + convert_2C_to_SM(); + + return *this; +} + + +// ---------------------------------------------------------------------------- +// SECTION: RIGHT SHIFT operators: >>, >>= +// ---------------------------------------------------------------------------- + +CLASS_TYPE +operator>>(const CLASS_TYPE& u, const CLASS_TYPE& v) +{ + if (v.sgn == SC_ZERO) + return CLASS_TYPE(u); + +#ifdef SC_SIGNED + if (v.sgn == SC_NEG) + return CLASS_TYPE(u); +#endif + + return operator>>(u, v.to_long()); +} + + +const CLASS_TYPE& +CLASS_TYPE::operator>>=(const CLASS_TYPE& v) +{ + if (v.sgn == SC_ZERO) + return *this; + +#ifdef SC_SIGNED + if (v.sgn == SC_NEG) + return *this; +#endif + + return operator>>=(v.to_long()); +} + + +const CLASS_TYPE& +CLASS_TYPE::operator>>=(const OTHER_CLASS_TYPE& v) +{ + if (v.sgn == SC_ZERO) + return *this; + +#ifdef SC_UNSIGNED + if (v.sgn == SC_NEG) + return *this; +#endif + + return operator>>=(v.to_ulong()); +} + + +CLASS_TYPE +operator>>(const CLASS_TYPE& u, int64 v) +{ + if (v <= 0) + return CLASS_TYPE(u); + + return operator>>(u, (unsigned long) v); +} + + +CLASS_TYPE +operator>>(const CLASS_TYPE& u, uint64 v) +{ + if (v == 0) + return CLASS_TYPE(u); + + return operator>>(u, (unsigned long) v); +} + +const CLASS_TYPE& +CLASS_TYPE::operator>>=(int64 v) +{ + if (v <= 0) + return *this; + + return operator>>=((unsigned long) v); +} + + +const CLASS_TYPE& +CLASS_TYPE::operator>>=(uint64 v) +{ + if (v == 0) + return *this; + + return operator>>=((unsigned long) v); +} + + +CLASS_TYPE +operator>>(const CLASS_TYPE& u, long v) +{ + if (v <= 0) + return CLASS_TYPE(u); + + return operator>>(u, (unsigned long) v); +} + + +CLASS_TYPE +operator>>(const CLASS_TYPE& u, unsigned long v) +{ + if (v == 0) + return CLASS_TYPE(u); + + if (u.sgn == SC_ZERO) + return CLASS_TYPE(u); + + int nb = u.nbits; + int nd = u.ndigits; + +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS]; +#else + sc_digit *d = new sc_digit[nd]; +#endif + + vec_copy(nd, d, u.digit); + + convert_SM_to_2C(u.sgn, nd, d); + + if (u.sgn == SC_NEG) + vec_shift_right(nd, d, v, DIGIT_MASK); + else + vec_shift_right(nd, d, v, 0); + + small_type s = convert_signed_2C_to_SM(nb, nd, d); + + return CLASS_TYPE(s, nb, nd, d); +} + + +const CLASS_TYPE& +CLASS_TYPE::operator>>=(long v) +{ + if (v <= 0) + return *this; + + return operator>>=((unsigned long) v); +} + + +const CLASS_TYPE& +CLASS_TYPE::operator>>=(unsigned long v) +{ + if (v == 0) + return *this; + + if (sgn == SC_ZERO) + return *this; + + convert_SM_to_2C(); + + if (sgn == SC_NEG) + vec_shift_right(ndigits, digit, v, DIGIT_MASK); + else + vec_shift_right(ndigits, digit, v, 0); + + convert_2C_to_SM(); + + return *this; +} + + +// ---------------------------------------------------------------------------- +// SECTION: EQUAL TO operator: == +// ---------------------------------------------------------------------------- + +// Defined in the sc_signed.cpp and sc_unsigned.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: NOT_EQUAL operator: != +// ---------------------------------------------------------------------------- + +bool +operator!=(const CLASS_TYPE& u, const CLASS_TYPE& v) +{ + return (! operator==(u, v)); +} + + +bool +operator!=(const CLASS_TYPE& u, int64 v) +{ + return (! operator==(u, v)); +} + + +bool +operator!=(int64 u, const CLASS_TYPE& v) +{ + return (! operator==(u, v)); +} + + +bool +operator!=(const CLASS_TYPE& u, uint64 v) +{ + return (! operator==(u, v)); +} + + +bool +operator!=(uint64 u, const CLASS_TYPE& v) +{ + return (! operator==(u, v)); +} + + +bool +operator!=(const CLASS_TYPE& u, long v) +{ + return (! operator==(u, v)); +} + + +bool +operator!=(long u, const CLASS_TYPE& v) +{ + return (! operator==(u, v)); +} + + +bool +operator!=(const CLASS_TYPE& u, unsigned long v) +{ + return (! operator==(u, v)); +} + + +bool +operator!=(unsigned long u, const CLASS_TYPE& v) +{ + return (! operator==(u, v)); +} + + +// ---------------------------------------------------------------------------- +// SECTION: LESS THAN operator: < +// ---------------------------------------------------------------------------- + +// Defined in the sc_signed.cpp and sc_unsigned.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: LESS THAN or EQUAL operator: <= +// ---------------------------------------------------------------------------- + +bool +operator<=(const CLASS_TYPE& u, const CLASS_TYPE& v) +{ + return (operator<(u, v) || operator==(u, v)); +} + + +bool +operator<=(const CLASS_TYPE& u, int64 v) +{ + return (operator<(u, v) || operator==(u, v)); +} + + +bool +operator<=(int64 u, const CLASS_TYPE& v) +{ + return (operator<(u, v) || operator==(u, v)); +} + + +bool +operator<=(const CLASS_TYPE& u, uint64 v) +{ + return (operator<(u, v) || operator==(u, v)); +} + + +bool +operator<=(uint64 u, const CLASS_TYPE& v) +{ + return (operator<(u, v) || operator==(u, v)); +} + + +bool +operator<=(const CLASS_TYPE& u, long v) +{ + return (operator<(u, v) || operator==(u, v)); +} + + +bool +operator<=(long u, const CLASS_TYPE& v) +{ + return (operator<(u, v) || operator==(u, v)); +} + + +bool +operator<=(const CLASS_TYPE& u, unsigned long v) +{ + return (operator<(u, v) || operator==(u, v)); +} + + +bool +operator<=(unsigned long u, const CLASS_TYPE& v) +{ + return (operator<(u, v) || operator==(u, v)); +} + + +// ---------------------------------------------------------------------------- +// SECTION: GREATER THAN operator: > +// ---------------------------------------------------------------------------- + +bool +operator>(const CLASS_TYPE& u, const CLASS_TYPE& v) +{ + return (! (operator<=(u, v))); +} + + +bool +operator>(const CLASS_TYPE& u, int64 v) +{ + return (! (operator<=(u, v))); +} + + +bool +operator>(int64 u, const CLASS_TYPE& v) +{ + return (! (operator<=(u, v))); +} + + +bool +operator>(const CLASS_TYPE& u, uint64 v) +{ + return (! (operator<=(u, v))); +} + + +bool +operator>(uint64 u, const CLASS_TYPE& v) +{ + return (! (operator<=(u, v))); +} + + +bool +operator>(const CLASS_TYPE& u, long v) +{ + return (! (operator<=(u, v))); +} + + +bool +operator>(long u, const CLASS_TYPE& v) +{ + return (! (operator<=(u, v))); +} + + +bool +operator>(const CLASS_TYPE& u, unsigned long v) +{ + return (! (operator<=(u, v))); +} + + +bool +operator>(unsigned long u, const CLASS_TYPE& v) +{ + return (! (operator<=(u, v))); +} + + +// ---------------------------------------------------------------------------- +// SECTION: GREATER THAN or EQUAL operator: >= +// ---------------------------------------------------------------------------- + +bool +operator>=(const CLASS_TYPE& u, const CLASS_TYPE& v) +{ + return (! (operator<(u, v))); +} + + +bool +operator>=(const CLASS_TYPE& u, int64 v) +{ + return (! (operator<(u, v))); +} + + +bool +operator>=(int64 u, const CLASS_TYPE& v) +{ + return (! (operator<(u, v))); +} + + +bool +operator>=(const CLASS_TYPE& u, uint64 v) +{ + return (! (operator<(u, v))); +} + + +bool +operator>=(uint64 u, const CLASS_TYPE& v) +{ + return (! (operator<(u, v))); +} + + +bool +operator>=(const CLASS_TYPE& u, long v) +{ + return (! (operator<(u, v))); +} + + +bool +operator>=(long u, const CLASS_TYPE& v) +{ + return (! (operator<(u, v))); +} + + +bool +operator>=(const CLASS_TYPE& u, unsigned long v) +{ + return (! (operator<(u, v))); +} + + +bool +operator>=(unsigned long u, const CLASS_TYPE& v) +{ + return (! (operator<(u, v))); +} + + +// ---------------------------------------------------------------------------- +// SECTION: Public members - Other utils. +// ---------------------------------------------------------------------------- + +// Convert to int64, long, or int. +#define TO_INTX(RET_TYPE, UP_RET_TYPE) \ + \ +if (sgn == SC_ZERO) \ +return 0; \ + \ +int vnd = sc_min((int)DIGITS_PER_ ## UP_RET_TYPE, ndigits); \ + \ +RET_TYPE v = 0; \ +while (--vnd >= 0) \ +v = (v << BITS_PER_DIGIT) + digit[vnd]; \ + \ +if (sgn == SC_NEG) \ +return -v; \ +else \ +return v; + + +int64 +CLASS_TYPE::to_int64() const +{ + TO_INTX(int64, INT64); +} + + +long +CLASS_TYPE::to_long() const +{ + TO_INTX(long, LONG); +} + + +int +CLASS_TYPE::to_int() const +{ + TO_INTX(int, INT); +} + + +// Convert to unsigned int64, unsigned long or unsigned +// int. to_uint64, to_ulong, and to_uint have the same body except for +// the type of v defined inside. +uint64 +CLASS_TYPE::to_uint64() const +{ + if (sgn == SC_ZERO) + return 0; + + int vnd = sc_min((int)DIGITS_PER_INT64, ndigits); + + uint64 v = 0; + + if (sgn == SC_NEG) { + +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS]; +#else + sc_digit *d = new sc_digit[ndigits]; +#endif + + vec_copy(ndigits, d, digit); + + convert_SM_to_2C_trimmed(IF_SC_SIGNED, sgn, nbits, ndigits, d); + + while (--vnd >= 0) + v = (v << BITS_PER_DIGIT) + d[vnd]; + +#ifndef SC_MAX_NBITS + delete [] d; +#endif + + } + else { + + while (--vnd >= 0) + v = (v << BITS_PER_DIGIT) + digit[vnd]; + + } + + return v; +} + + +unsigned long +CLASS_TYPE::to_ulong() const +{ + if (sgn == SC_ZERO) + return 0; + + int vnd = sc_min((int)DIGITS_PER_LONG, ndigits); + + unsigned long v = 0; + + if (sgn == SC_NEG) { + +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS]; +#else + sc_digit *d = new sc_digit[ndigits]; +#endif + + vec_copy(ndigits, d, digit); + + convert_SM_to_2C_trimmed(IF_SC_SIGNED, sgn, nbits, ndigits, d); + + while (--vnd >= 0) + v = (v << BITS_PER_DIGIT) + d[vnd]; + +#ifndef SC_MAX_NBITS + delete [] d; +#endif + + } + else { + + while (--vnd >= 0) + v = (v << BITS_PER_DIGIT) + digit[vnd]; + + } + + return v; +} + + +unsigned int +CLASS_TYPE::to_uint() const +{ + if (sgn == SC_ZERO) + return 0; + + int vnd = sc_min((int)DIGITS_PER_INT, ndigits); + + unsigned int v = 0; + + if (sgn == SC_NEG) { + +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS]; +#else + sc_digit *d = new sc_digit[ndigits]; +#endif + + vec_copy(ndigits, d, digit); + + convert_SM_to_2C_trimmed(IF_SC_SIGNED, sgn, nbits, ndigits, d); + + while (--vnd >= 0) + v = (v << BITS_PER_DIGIT) + d[vnd]; + +#ifndef SC_MAX_NBITS + delete [] d; +#endif + + } + else { + + while (--vnd >= 0) + v = (v << BITS_PER_DIGIT) + digit[vnd]; + + } + + return v; +} + + +// Convert to double. +double +CLASS_TYPE::to_double() const +{ + if (sgn == SC_ZERO) + return (double) 0.0; + + int vnd = ndigits; + + double v = 0.0; + while (--vnd >= 0) + v = v * DIGIT_RADIX + digit[vnd]; + + if (sgn == SC_NEG) + return -v; + else + return v; +} + + +// Return true if the bit i is 1, false otherwise. If i is outside the +// bounds, return 1/0 according to the sign of the number by assuming +// that the number has infinite length. + +bool +CLASS_TYPE::test(int i) const +{ +#ifdef SC_SIGNED + if (check_if_outside(i)) { + if (sgn == SC_NEG) + return 1; + else + return 0; + } +#else + if (check_if_outside(i)) + return 0; +#endif + + int bit_num = bit_ord(i); + int digit_num = digit_ord(i); + + if (sgn == SC_NEG) { + +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS]; +#else + sc_digit *d = new sc_digit[ndigits]; +#endif + + vec_copy(ndigits, d, digit); + vec_complement(ndigits, d); + bool val = ((d[digit_num] & one_and_zeros(bit_num)) != 0); + +#ifndef SC_MAX_NBITS + delete [] d; +#endif + + return val; + + } + else + return ((digit[digit_num] & one_and_zeros(bit_num)) != 0); +} + + +// Set the ith bit with 1. +void +CLASS_TYPE::set(int i) +{ + if (check_if_outside(i)) + return; + + int bit_num = bit_ord(i); + int digit_num = digit_ord(i); + + convert_SM_to_2C(); + digit[digit_num] |= one_and_zeros(bit_num); + digit[digit_num] &= DIGIT_MASK; // Needed to zero the overflow bits. + convert_2C_to_SM(); +} + + +// Set the ith bit with 0, i.e., clear the ith bit. +void +CLASS_TYPE::clear(int i) +{ + if (check_if_outside(i)) + return; + + int bit_num = bit_ord(i); + int digit_num = digit_ord(i); + + convert_SM_to_2C(); + digit[digit_num] &= ~(one_and_zeros(bit_num)); + digit[digit_num] &= DIGIT_MASK; // Needed to zero the overflow bits. + convert_2C_to_SM(); +} + + +// Create a mirror image of the number. +void +CLASS_TYPE::reverse() +{ + convert_SM_to_2C(); + vec_reverse(length(), ndigits, digit, length() - 1); + convert_2C_to_SM(); +} + + +// Get a packed bit representation of the number. +void +CLASS_TYPE::get_packed_rep(sc_digit *buf) const +{ + int buf_ndigits = (length() - 1) / BITS_PER_DIGIT_TYPE + 1; + + // Initialize buf to zero. + vec_zero(buf_ndigits, buf); + + if (sgn == SC_ZERO) + return; + + const sc_digit *digit_or_d; +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS]; +#else + sc_digit *d = new sc_digit[ndigits]; +#endif + + if (sgn == SC_POS) + digit_or_d = digit; + + else + { + // If sgn is negative, we have to convert digit to its 2's + // complement. Since this function is const, we can not do it on + // digit. Since buf doesn't have overflow bits, we cannot also do + // it on buf. Thus, we have to do the complementation on a copy of + // digit, i.e., on d. + + vec_copy(ndigits, d, digit); + vec_complement(ndigits, d); + + buf[buf_ndigits - 1] = ~((sc_digit) 0); + + digit_or_d = d; + + } + + // Copy the bits from digit to buf. The division and mod operations + // below can be converted to addition/subtraction and comparison + // operations at the expense of complicating the code. We can do it + // if we see any performance problems. + + for (int i = length() - 1; i >= 0; --i) { + + if ((digit_or_d[digit_ord(i)] & one_and_zeros(bit_ord(i))) != 0) // Test. + + buf[i / BITS_PER_DIGIT_TYPE] |= + one_and_zeros(i % BITS_PER_DIGIT_TYPE); // Set. + + else + + buf[i / BITS_PER_DIGIT_TYPE] &= + ~(one_and_zeros(i % BITS_PER_DIGIT_TYPE)); // Clear. + + } + +#ifndef SC_MAX_NBITS + delete[] d; +#endif +} + + +// Set a packed bit representation of the number. +void +CLASS_TYPE::set_packed_rep(sc_digit *buf) +{ + // Initialize digit to zero. + vec_zero(ndigits, digit); + + // Copy the bits from buf to digit. + for (int i = length() - 1; i >= 0; --i) { + + if ((buf[i / BITS_PER_DIGIT_TYPE] & + one_and_zeros(i % BITS_PER_DIGIT_TYPE)) != 0) // Test. + + digit[digit_ord(i)] |= one_and_zeros(bit_ord(i)); // Set. + + else + + digit[digit_ord(i)] &= ~(one_and_zeros(bit_ord(i))); // Clear + + } + + convert_2C_to_SM(); +} + + +// ---------------------------------------------------------------------------- +// SECTION: Private members. +// ---------------------------------------------------------------------------- + +// Create a copy of v with sgn s. +CLASS_TYPE::CLASS_TYPE(const CLASS_TYPE& v, small_type s) : + sc_value_base(v), sgn(s), nbits(v.nbits), ndigits(v.ndigits), digit() +{ +#ifndef SC_MAX_NBITS + digit = new sc_digit[ndigits]; +#endif + + vec_copy(ndigits, digit, v.digit); +} + + +// Create a copy of v where v is of the different type. +CLASS_TYPE::CLASS_TYPE(const OTHER_CLASS_TYPE& v, small_type s) : + sc_value_base(v), sgn(s), nbits(num_bits(v.nbits)), ndigits(), digit() +{ +#if (IF_SC_SIGNED == 1) + ndigits = v.ndigits; +#else + ndigits = DIV_CEIL(nbits); +#endif + +#ifndef SC_MAX_NBITS + digit = new sc_digit[ndigits]; +#endif + + copy_digits(v.nbits, v.ndigits, v.digit); +} + + +// Create a signed number with (s, nb, nd, d) as its attributes (as +// defined in class CLASS_TYPE). If alloc is set, delete d. +CLASS_TYPE::CLASS_TYPE(small_type s, int nb, + int nd, sc_digit *d, + bool alloc) : + sc_value_base(), sgn(s), nbits(num_bits(nb)), ndigits(), digit() +{ + ndigits = DIV_CEIL(nbits); + +#ifndef SC_MAX_NBITS + digit = new sc_digit[ndigits]; +#endif + + if (ndigits <= nd) + vec_copy(ndigits, digit, d); + else + vec_copy_and_zero(ndigits, digit, nd, d); + +#ifndef SC_MAX_NBITS + if (alloc) + delete [] d; +#endif +} + +// This constructor is mainly used in finding a "range" of bits from a +// number of type CLASS_TYPE. The function range(l, r) can have +// arbitrary precedence between l and r. If l is smaller than r, then +// the output is the reverse of range(r, l). +CLASS_TYPE::CLASS_TYPE(const CLASS_TYPE* u, int l, int r) : + sc_value_base(), sgn(), nbits(), ndigits(), digit() +{ + bool reversed = false; + + if( l < r ) { + reversed = true; + int tmp = l; + l = r; + r = tmp; + } + + // at this point, l >= r + + // make sure that l and r point to the bits of u + r = sc_max( r, 0 ); + l = sc_min( l, u->nbits - 1 ); + + nbits = num_bits( l - r + 1 ); + + // nbits can still be <= 0 because l and r have just been updated + // with the bounds of u. + + // if u == 0 or the range is out of bounds, return 0 + if( u->sgn == SC_ZERO || nbits <= num_bits( 0 ) ) { + sgn = SC_ZERO; + if( nbits <= num_bits( 0 ) ) { + nbits = 1; + } + ndigits = DIV_CEIL( nbits ); +#ifndef SC_MAX_NBITS + digit = new sc_digit[ndigits]; +#endif + vec_zero( ndigits, digit ); + return; + } + + // The rest will be executed if u is not zero. + + ndigits = DIV_CEIL(nbits); + + // The number of bits up to and including l and r, respectively. + int nl = l + 1; + int nr = r + 1; + + // The indices of the digits that have lth and rth bits, respectively. + int left_digit = DIV_CEIL(nl) - 1; + int right_digit = DIV_CEIL(nr) - 1; + + int nd; + + // The range is performed on the 2's complement representation, so + // first get the indices for that. + if (u->sgn == SC_NEG) + nd = left_digit + 1; + else + nd = left_digit - right_digit + 1; + + // Allocate memory for the range. +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS]; +#else + digit = new sc_digit[ndigits]; + sc_digit *d = new sc_digit[nd]; +#endif + + // Getting the range on the 2's complement representation. + if (u->sgn == SC_NEG) { + + vec_copy(nd, d, u->digit); + vec_complement(nd, d); // d = -d; + vec_shift_right(nd, d, r, DIGIT_MASK); + + } + else { + + for (int i = right_digit; i <= left_digit; ++i) + d[i - right_digit] = u->digit[i]; + + vec_shift_right(nd, d, r - right_digit * BITS_PER_DIGIT, 0); + + } + + vec_zero(ndigits, digit); + + if (! reversed) + vec_copy(sc_min(nd, ndigits), digit, d); + + else { + + // If l < r, i.e., reversed is set, reverse the bits of digit. d + // will be used as a temporary store. The following code tries to + // minimize the use of bit_ord and digit_ord, which use mod and + // div operators. Since these operators are function calls to + // standard library routines, they are slow. The main idea in + // reversing is "read bits out of d from left to right and push + // them into digit using right shifting." + + // Take care of the last digit. + int nd_less_1 = nd - 1; + + // Deletions will start from the left end and move one position + // after each deletion. + sc_digit del_mask = one_and_zeros(bit_ord(l - r)); + + while (del_mask) { + vec_shift_right(ndigits, digit, 1, ((d[nd_less_1] & del_mask) != 0)); + del_mask >>= 1; + } + + // Take care of the other digits if any. + + // Insertion to digit will always occur at the left end. + sc_digit ins_mask = one_and_zeros(BITS_PER_DIGIT - 1); + + for (int j = nd - 2; j >= 0; --j) { // j = nd - 2 + + // Deletions will start from the left end and move one position + // after each deletion. + del_mask = ins_mask; + + while (del_mask) { + vec_shift_right(ndigits, digit, 1, ((d[j] & del_mask) != 0)); + del_mask >>= 1; + } + } + + if (u->sgn == SC_NEG) + vec_shift_right(ndigits, digit, + ndigits * BITS_PER_DIGIT - length(), DIGIT_MASK); + else + vec_shift_right(ndigits, digit, + ndigits * BITS_PER_DIGIT - length(), 0); + + + } // if reversed. + + convert_2C_to_SM(); + +#ifndef SC_MAX_NBITS + delete [] d; +#endif +} + +// This constructor is mainly used in finding a "range" of bits from a +// number of type OTHER_CLASS_TYPE. The function range(l, r) can have +// arbitrary precedence between l and r. If l is smaller than r, then +// the output is the reverse of range(r, l). +CLASS_TYPE::CLASS_TYPE(const OTHER_CLASS_TYPE* u, int l, int r) : + sc_value_base(), sgn(), nbits(), ndigits(), digit() +{ + bool reversed = false; + + if( l < r ) { + reversed = true; + int tmp = l; + l = r; + r = tmp; + } + + // at this point, l >= r + + // make sure that l and r point to the bits of u + r = sc_max( r, 0 ); + l = sc_min( l, u->nbits - 1 ); + + nbits = num_bits( l - r + 1 ); + + // nbits can still be <= 0 because l and r have just been updated + // with the bounds of u. + + // if u == 0 or the range is out of bounds, return 0 + if( u->sgn == SC_ZERO || nbits <= num_bits( 0 ) ) { + sgn = SC_ZERO; + if( nbits <= num_bits( 0 ) ) { + nbits = 1; + } + ndigits = DIV_CEIL( nbits ); +#ifndef SC_MAX_NBITS + digit = new sc_digit[ndigits]; +#endif + vec_zero( ndigits, digit ); + return; + } + + // The rest will be executed if u is not zero. + + ndigits = DIV_CEIL(nbits); + + // The number of bits up to and including l and r, respectively. + int nl = l + 1; + int nr = r + 1; + + // The indices of the digits that have lth and rth bits, respectively. + int left_digit = DIV_CEIL(nl) - 1; + int right_digit = DIV_CEIL(nr) - 1; + + int nd; + + // The range is performed on the 2's complement representation, so + // first get the indices for that. + if (u->sgn == SC_NEG) + nd = left_digit + 1; + else + nd = left_digit - right_digit + 1; + + // Allocate memory for the range. +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS]; +#else + digit = new sc_digit[ndigits]; + sc_digit *d = new sc_digit[nd]; +#endif + + // Getting the range on the 2's complement representation. + if (u->sgn == SC_NEG) { + + vec_copy(nd, d, u->digit); + vec_complement(nd, d); // d = -d; + vec_shift_right(nd, d, r, DIGIT_MASK); + + } + else { + + for (int i = right_digit; i <= left_digit; ++i) + d[i - right_digit] = u->digit[i]; + + vec_shift_right(nd, d, r - right_digit * BITS_PER_DIGIT, 0); + + } + + vec_zero(ndigits, digit); + + if (! reversed) + vec_copy(sc_min(nd, ndigits), digit, d); + + else { + + // If l < r, i.e., reversed is set, reverse the bits of digit. d + // will be used as a temporary store. The following code tries to + // minimize the use of bit_ord and digit_ord, which use mod and + // div operators. Since these operators are function calls to + // standard library routines, they are slow. The main idea in + // reversing is "read bits out of d from left to right and push + // them into digit using right shifting." + + // Take care of the last digit. + int nd_less_1 = nd - 1; + + // Deletions will start from the left end and move one position + // after each deletion. + sc_digit del_mask = one_and_zeros(bit_ord(l - r)); + + while (del_mask) { + vec_shift_right(ndigits, digit, 1, ((d[nd_less_1] & del_mask) != 0)); + del_mask >>= 1; + } + + // Take care of the other digits if any. + + // Insertion to digit will always occur at the left end. + sc_digit ins_mask = one_and_zeros(BITS_PER_DIGIT - 1); + + for (int j = nd - 2; j >= 0; --j) { // j = nd - 2 + + // Deletions will start from the left end and move one position + // after each deletion. + del_mask = ins_mask; + + while (del_mask) { + vec_shift_right(ndigits, digit, 1, ((d[j] & del_mask) != 0)); + del_mask >>= 1; + } + } + + if (u->sgn == SC_NEG) + vec_shift_right(ndigits, digit, + ndigits * BITS_PER_DIGIT - length(), DIGIT_MASK); + else + vec_shift_right(ndigits, digit, + ndigits * BITS_PER_DIGIT - length(), 0); + + + } // if reversed. + + convert_2C_to_SM(); + +#ifndef SC_MAX_NBITS + delete [] d; +#endif +} + + +// Print out all the physical attributes. +void +CLASS_TYPE::dump(::std::ostream& os) const +{ + // Save the current setting, and set the base to decimal. +#if defined(__MINGW32__) + std::_Ios_Fmtflags old_flags = os.setf(::std::ios::dec,::std::ios::basefield); +#else + fmtflags old_flags = os.setf(::std::ios::dec, ::std::ios::basefield); +#endif + + os << "width = " << length() << ::std::endl; + os << "value = " << *this << ::std::endl; + os << "bits = "; + + int len = length(); + + for (int i = len - 1; i >= 0; --i) { + + os << "01"[test(i)]; + if (--len % 4 == 0) + os << " "; + + } + + os << ::std::endl; + + // Restore old_flags. + os.setf(old_flags, ::std::ios::basefield); +} + + +// Checks to see if bit_num is out of bounds. +bool +CLASS_TYPE::check_if_outside(int bit_num) const +{ + if ((bit_num < 0) || (num_bits(bit_num) >= nbits)) { + +#ifdef DEBUG_SYSTEMC + if( bit_num < 0 || bit_num >= nbits ) { + char msg[BUFSIZ]; + std::sprintf( msg, "%s::check_if_outside( int bit_num ) : " + "bit_num = %d is out of bounds", + CLASS_TYPE_STR, bit_num ); + SC_REPORT_WARNING( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); + } +#endif + + return true; + } + + return false; +} + +// End of file. diff --git a/ext/systemc/src/sysc/datatypes/int/sc_nbdefs.cpp b/ext/systemc/src/sysc/datatypes/int/sc_nbdefs.cpp new file mode 100644 index 000000000..48f2d39de --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_nbdefs.cpp @@ -0,0 +1,93 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_nbdefs.h -- Top level header file for arbitrary precision signed/unsigned + arithmetic. This file defines all the constants needed. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_nbdefs.cpp,v $ +// Revision 1.3 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.2 2009/05/22 16:06:29 acg +// Andy Goodrich: process control updates. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:32 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#include "sysc/datatypes/int/sc_nbdefs.h" + + +namespace sc_dt +{ + +#ifdef SC_MAX_NBITS +const int MAX_NDIGITS = DIV_CEIL(SC_MAX_NBITS) + 2; +// Consider a number with x bits another with y bits. The maximum +// number of bits happens when we multiply them. The result will have +// (x + y) bits. Assume that x + y <= SC_MAX_NBITS. Then, DIV_CEIL(x) + +// DIV_CEIL(y) <= DIV_CEIL(SC_MAX_NBITS) + 2. This is the reason for +2 +// above. With this change, MAX_NDIGITS must be enough to hold the +// result of any operation. +#endif + +// Support for the long long type. This type is not in the standard +// but is usually supported by compilers. +#if !defined(_WIN32) || defined(__MINGW32__) +const uint64 UINT64_ZERO = 0ULL; +const uint64 UINT64_ONE = 1ULL; +const uint64 UINT64_32ONES = 0x00000000ffffffffULL; +#else +const uint64 UINT64_ZERO = 0i64; +const uint64 UINT64_ONE = 1i64; +const uint64 UINT64_32ONES = 0x00000000ffffffffi64; +#endif + +const small_type NB_DEFAULT_BASE = SC_DEC; + +#ifndef _32BIT_ +const uint64 UINT_ZERO = UINT64_ZERO; +const uint64 UINT_ONE = UINT64_ONE; +#else +const unsigned int UINT_ZERO = 0U; +const unsigned int UINT_ONE = 1U; +#endif + +} // namespace sc_dt diff --git a/ext/systemc/src/sysc/datatypes/int/sc_nbdefs.h b/ext/systemc/src/sysc/datatypes/int/sc_nbdefs.h new file mode 100644 index 000000000..0d70b74ea --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_nbdefs.h @@ -0,0 +1,282 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_nbdefs.h -- Top level header file for arbitrary precision signed/unsigned + arithmetic. This file defines all the constants needed. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_nbdefs.h,v $ +// Revision 1.7 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.6 2011/02/18 20:09:34 acg +// Philipp A. Hartmann: added alternative #define for Windows to guard. +// +// Revision 1.5 2011/01/20 16:52:20 acg +// Andy Goodrich: changes for IEEE 1666 2011. +// +// Revision 1.4 2010/02/08 18:35:55 acg +// Andy Goodrich: Philipp Hartmann's changes for Solaris and Linux 64. +// +// Revision 1.2 2009/05/22 16:06:29 acg +// Andy Goodrich: process control updates. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:32 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef SC_NBDEFS_H +#define SC_NBDEFS_H + + +#include "sysc/kernel/sc_cmnhdr.h" + +#include <climits> + +#if defined(__sun) || defined(__sun__) +# include <inttypes.h> +#elif !defined(WIN32) && !defined(_WIN32) +# include <stdint.h> +#endif + +#include "sysc/utils/sc_iostream.h" +#include "sysc/kernel/sc_constants.h" // For SC_MAX_NBITS + +// Activate support mixed operands for concatenation via the comma operator +#define SC_DT_MIXED_COMMA_OPERATORS + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// ENUM : sc_numrep +// +// Enumeration of number representations for character string conversion. +// ---------------------------------------------------------------------------- + +enum sc_numrep +{ + SC_NOBASE = 0, + SC_BIN = 2, + SC_OCT = 8, + SC_DEC = 10, + SC_HEX = 16, + SC_BIN_US, + SC_BIN_SM, + SC_OCT_US, + SC_OCT_SM, + SC_HEX_US, + SC_HEX_SM, + SC_CSD +}; + + +// Sign of a number: +#define SC_NEG -1 // Negative number +#define SC_ZERO 0 // Zero +#define SC_POS 1 // Positive number +#define SC_NOSIGN 2 // Uninitialized sc_signed number + +typedef unsigned char uchar; + +// A small_type number is at least a char. Defining an int is probably +// better for alignment. +typedef int small_type; + +// Attributes of a byte. +#define BITS_PER_BYTE 8 +#define BYTE_RADIX 256 +#define BYTE_MASK 255 + +// LOG2_BITS_PER_BYTE = log2(BITS_PER_BYTE), assuming that +// BITS_PER_BYTE is a power of 2. +#define LOG2_BITS_PER_BYTE 3 + +// Attributes of the unsigned long. These definitions are used mainly in +// the functions that are aware of the internal representation of +// digits, e.g., get/set_packed_rep(). +#define BYTES_PER_DIGIT_TYPE 4 +#define BITS_PER_DIGIT_TYPE 32 + +// Attributes of a digit, i.e., unsigned long less the overflow bits. +#define BYTES_PER_DIGIT 4 +#define BITS_PER_DIGIT 30 +#define DIGIT_RADIX (1ul << BITS_PER_DIGIT) +#define DIGIT_MASK (DIGIT_RADIX - 1) +// Make sure that BYTES_PER_DIGIT = ceil(BITS_PER_DIGIT / BITS_PER_BYTE). + +// Similar attributes for the half of a digit. Note that +// HALF_DIGIT_RADIX is equal to the square root of DIGIT_RADIX. These +// definitions are used mainly in the multiplication routines. +#define BITS_PER_HALF_DIGIT (BITS_PER_DIGIT / 2) +#define HALF_DIGIT_RADIX (1ul << BITS_PER_HALF_DIGIT) +#define HALF_DIGIT_MASK (HALF_DIGIT_RADIX - 1) + +// DIV_CEIL2(x, y) = ceil(x / y). x and y are positive numbers. +#define DIV_CEIL2(x, y) (((x) - 1) / (y) + 1) + +// DIV_CEIL(x) = ceil(x / BITS_PER_DIGIT) = the number of digits to +// store x bits. x is a positive number. +#define DIV_CEIL(x) DIV_CEIL2(x, BITS_PER_DIGIT) + +#ifdef SC_MAX_NBITS +extern const int MAX_NDIGITS; +// Consider a number with x bits another with y bits. The maximum +// number of bits happens when we multiply them. The result will have +// (x + y) bits. Assume that x + y <= SC_MAX_NBITS. Then, DIV_CEIL(x) + +// DIV_CEIL(y) <= DIV_CEIL(SC_MAX_NBITS) + 2. This is the reason for +2 +// above. With this change, MAX_NDIGITS must be enough to hold the +// result of any operation. +#endif + +// Support for "digit" vectors used to hold the values of sc_signed, +// sc_unsigned, sc_bv_base, and sc_lv_base data types. This type is also used +// in the concatenation support. An sc_digit is currently an unsigned 32-bit +// quantity. The typedef used is an unsigned int, rather than an unsigned long, +// since the unsigned long data type varies in size between 32-bit and 64-bit +// machines. + +typedef unsigned int sc_digit; // 32-bit unsigned integer + +// Support for the long long type. This type is not in the standard +// but is usually supported by compilers. +#ifndef _WIN32 +# if defined(__x86_64__) + typedef long long int64; + typedef unsigned long long uint64; +# else + typedef int64_t int64; + typedef uint64_t uint64; +# endif + extern const uint64 UINT64_ZERO; + extern const uint64 UINT64_ONE; + extern const uint64 UINT64_32ONES; +#else + typedef __int64 int64; + typedef unsigned __int64 uint64; + extern const uint64 UINT64_ZERO; + extern const uint64 UINT64_ONE; + extern const uint64 UINT64_32ONES; +#endif + + +// Bits per ... +// will be deleted in the future. Use numeric_limits instead +#define BITS_PER_CHAR 8 +#define BITS_PER_INT (sizeof(int) * BITS_PER_CHAR) +#define BITS_PER_LONG (sizeof(long) * BITS_PER_CHAR) +#define BITS_PER_INT64 (sizeof(::sc_dt::int64) * BITS_PER_CHAR) +#define BITS_PER_UINT (sizeof(unsigned int) * BITS_PER_CHAR) +#define BITS_PER_ULONG (sizeof(unsigned long) * BITS_PER_CHAR) +#define BITS_PER_UINT64 (sizeof(::sc_dt::uint64) * BITS_PER_CHAR) + +// Digits per ... +#define DIGITS_PER_CHAR 1 +#define DIGITS_PER_INT ((BITS_PER_INT+29)/30) +#define DIGITS_PER_LONG ((BITS_PER_LONG+29)/30) +#define DIGITS_PER_INT64 ((BITS_PER_INT64+29)/30) +#define DIGITS_PER_UINT ((BITS_PER_UINT+29)/30) +#define DIGITS_PER_ULONG ((BITS_PER_ULONG+29)/30) +#define DIGITS_PER_UINT64 ((BITS_PER_UINT64+29)/30) + +// Above, BITS_PER_X is mainly used for sc_signed, and BITS_PER_UX is +// mainly used for sc_unsigned. + +#if defined( _WIN32 ) || defined( __HP_aCC ) +typedef unsigned long fmtflags; +#else +typedef ::std::ios::fmtflags fmtflags; +#endif + +extern const small_type NB_DEFAULT_BASE ; + +// For sc_int code: +#define LLWIDTH BITS_PER_INT64 +#define INTWIDTH BITS_PER_INT + +#ifndef _32BIT_ + +typedef int64 int_type; +typedef uint64 uint_type; +#define SC_INTWIDTH 64 +extern const uint64 UINT_ZERO; +extern const uint64 UINT_ONE; + +#else + +typedef int int_type; +typedef unsigned int uint_type; +#define SC_INTWIDTH 32 +extern const unsigned int UINT_ZERO; +extern const unsigned int UINT_ONE; + +#endif + + +#if defined(_MSC_VER) && ( _MSC_VER < 1300 ) + // VC++6 bug + ::std::ostream& operator << ( ::std::ostream&, int64 ); + ::std::ostream& operator << ( ::std::ostream&, uint64 ); +#endif + +} // namespace sc_dt + + +#if defined(_MSC_VER) && ( _MSC_VER < 1300 ) + + inline + ::std::ostream& + operator << ( ::std::ostream& os, sc_dt::int64 a ) + { + sc_dt::operator << ( os, a ); + return os; + } + + inline + ::std::ostream& + operator << ( ::std::ostream& os, sc_dt::uint64 a ) + { + sc_dt::operator << ( os, a ); + return os; + } + +#endif + + +#endif diff --git a/ext/systemc/src/sysc/datatypes/int/sc_nbexterns.cpp b/ext/systemc/src/sysc/datatypes/int/sc_nbexterns.cpp new file mode 100644 index 000000000..245df73b8 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_nbexterns.cpp @@ -0,0 +1,894 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_nbexterns.cpp -- External functions for both sc_signed and sc_unsigned + classes. These functions work on two parameters u and + v, and copy the result to the first parameter u. This + is also the reason that they are suffixed with _on_help. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_nbexterns.cpp,v $ +// Revision 1.2 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:32 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#include "sysc/datatypes/int/sc_nbexterns.h" +#include "sysc/kernel/sc_macros.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// SECTION: External functions for PLUS operators. +// ---------------------------------------------------------------------------- + +// Handles the cases 3 and 4 and returns the result in u. +void +add_on_help(small_type &us, int /* unb */, int und, + sc_digit *ud, + small_type vs, int /* vnb */, int vnd, + const sc_digit *vd) +{ + + vnd = vec_skip_leading_zeros(vnd, vd); + + if (us == vs) { // case 3 + + if (und >= vnd) + vec_add_on(und, ud, vnd, vd); + else + vec_add_on2(und, ud, vnd, vd); + + } + else { // case 4 + + // vec_cmp expects that und is the number of non-zero digits in ud. + int new_und = vec_skip_leading_zeros(und, ud); + int cmp_res = vec_cmp(new_und, ud, vnd, vd); + + if (cmp_res == 0) { // u == v + us = SC_ZERO; + vec_zero(und, ud); + return; + } + + if (cmp_res > 0) // u > v + vec_sub_on(und, ud, vnd, vd); + + else { // u < v + us = -us; + vec_sub_on2(und, ud, vnd, vd); + } + + } +} + + +// ---------------------------------------------------------------------------- + +/* + +mul_on_help_signed and mul_on_help_unsigned have the same body except +that CONVERT_SM_to_2C_to_SM and COPY_DIGITS are defined for signed and +unsigned, respectively. This comment also applies to the +signed/unsigned versions of div_on_help and mod_on_help. It is +possible to take COPY_DIGITS out of these functions and create a +single version of each of these helper functions; however, this will +impose an onverhead on performance. In the versions below, any change +in the signed version of a helper function must be carried to a +corresponding change in the unsigned verion of the same function or +vice versa. + +*/ + + +// ---------------------------------------------------------------------------- +// SECTION: External functions of MULTIPLICATION operators. +// ---------------------------------------------------------------------------- + +void +mul_on_help_signed(small_type &us, + int unb, int und, + sc_digit *ud, + int vnb, int vnd, + const sc_digit *vd) +{ +#define CONVERT_SM_to_2C_to_SM convert_signed_SM_to_2C_to_SM +#define COPY_DIGITS copy_digits_signed + + { // Body of mul_on_help + + int old_und = und; + + und = vec_skip_leading_zeros(und, ud); + vnd = vec_skip_leading_zeros(vnd, vd); + + sc_digit ud0 = (*ud); + sc_digit vd0 = (*vd); + + if ((vnd == 1) && (vd0 == 1)) { + us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud); + return; + } + + if ((und == 1) && (ud0 == 1)) { + COPY_DIGITS(us, unb, old_und, ud, vnb, vnd, vd); + return; + } + + if ((und == 1) && (vnd == 1) && + (ud0 < HALF_DIGIT_RADIX) && (vd0 < HALF_DIGIT_RADIX)) { + + sc_digit d = ud0 * vd0; + COPY_DIGITS(us, unb, old_und, ud, unb + vnb, 1, &d); + return; + + } + + int nd = und + vnd; + +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS]; +#else + sc_digit *d = new sc_digit[nd]; +#endif + + vec_zero(nd, d); + + if ((und == 1) && (ud0 < HALF_DIGIT_RADIX)) + vec_mul_small(vnd, vd, ud0, d); + + else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) + vec_mul_small(und, ud, vd0, d); + + else if (vnd < und) + vec_mul(und, ud, vnd, vd, d); + + else + vec_mul(vnd, vd, und, ud, d); + + COPY_DIGITS(us, unb, old_und, ud, unb + vnb, nd, d); + +#ifndef SC_MAX_NBITS + delete [] d; +#endif + + } + +#undef COPY_DIGITS +#undef CONVERT_SM_to_2C_to_SM + +} + + +void +mul_on_help_unsigned(small_type &us, + int unb, int und, + sc_digit *ud, + int vnb, int vnd, + const sc_digit *vd) +{ +#define CONVERT_SM_to_2C_to_SM convert_unsigned_SM_to_2C_to_SM +#define COPY_DIGITS copy_digits_unsigned + + { // Body of mul_on_help + + int old_und = und; + + und = vec_skip_leading_zeros(und, ud); + vnd = vec_skip_leading_zeros(vnd, vd); + + sc_digit ud0 = (*ud); + sc_digit vd0 = (*vd); + + if ((vnd == 1) && (vd0 == 1)) { + us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud); + return; + } + + if ((und == 1) && (ud0 == 1)) { + COPY_DIGITS(us, unb, old_und, ud, vnb, vnd, vd); + return; + } + + if ((und == 1) && (vnd == 1) && + (ud0 < HALF_DIGIT_RADIX) && (vd0 < HALF_DIGIT_RADIX)) { + + sc_digit d = ud0 * vd0; + COPY_DIGITS(us, unb, old_und, ud, unb + vnb, 1, &d); + return; + + } + + int nd = und + vnd; + +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS]; +#else + sc_digit *d = new sc_digit[nd]; +#endif + + vec_zero(nd, d); + + if ((und == 1) && (ud0 < HALF_DIGIT_RADIX)) + vec_mul_small(vnd, vd, ud0, d); + + else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) + vec_mul_small(und, ud, vd0, d); + + else if (vnd < und) + vec_mul(und, ud, vnd, vd, d); + + else + vec_mul(vnd, vd, und, ud, d); + + COPY_DIGITS(us, unb, old_und, ud, unb + vnb, nd, d); + +#ifndef SC_MAX_NBITS + delete [] d; +#endif + + } + +#undef COPY_DIGITS +#undef CONVERT_SM_to_2C_to_SM + +} + + +// ---------------------------------------------------------------------------- +// SECTION: External functions for DIVISION operators. +// ---------------------------------------------------------------------------- + +void +div_on_help_signed(small_type &us, + int unb, int und, + sc_digit *ud, + int vnb, int vnd, + const sc_digit *vd) +{ +#define CONVERT_SM_to_2C_to_SM convert_signed_SM_to_2C_to_SM +#define COPY_DIGITS copy_digits_signed + + { // Body of div_on_help + + int old_und = und; + + und = vec_skip_leading_zeros(und, ud); + vnd = vec_skip_leading_zeros(vnd, vd); + + int cmp_res = vec_cmp(und, ud, vnd, vd); + + if (cmp_res < 0) { // u < v => u / v = 0 - case 4 + us = SC_ZERO; + vec_zero(old_und, ud); + return; + } + + sc_digit vd0 = (*vd); + + if ((cmp_res > 0) && (vnd == 1) && (vd0 == 1)) { + us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud); + return; + } + + // One extra digit for d is allocated to simplify vec_div_*(). + int nd = sc_max(und, vnd) + 1; + +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS + 1]; +#else + sc_digit *d = new sc_digit[nd]; +#endif + + vec_zero(nd, d); + + // u = v => u / v = 1 - case 3 + if (cmp_res == 0) + d[0] = 1; + + else if ((vnd == 1) && (und == 1)) + d[0] = (*ud) / vd0; + + else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) + vec_div_small(und, ud, vd0, d); + + else + vec_div_large(und, ud, vnd, vd, d); + + COPY_DIGITS(us, unb, old_und, ud, sc_max(unb, vnb), nd - 1, d); + +#ifndef SC_MAX_NBITS + delete [] d; +#endif + + } + +#undef COPY_DIGITS +#undef CONVERT_SM_to_2C_to_SM + +} + + +void +div_on_help_unsigned(small_type &us, + int unb, int und, + sc_digit *ud, + int vnb, int vnd, + const sc_digit *vd) +{ +#define CONVERT_SM_to_2C_to_SM convert_unsigned_SM_to_2C_to_SM +#define COPY_DIGITS copy_digits_unsigned + + { // Body of div_on_help + + int old_und = und; + + und = vec_skip_leading_zeros(und, ud); + vnd = vec_skip_leading_zeros(vnd, vd); + + int cmp_res = vec_cmp(und, ud, vnd, vd); + + if (cmp_res < 0) { // u < v => u / v = 0 - case 4 + us = SC_ZERO; + vec_zero(old_und, ud); + return; + } + + sc_digit vd0 = (*vd); + + if ((cmp_res > 0) && (vnd == 1) && (vd0 == 1)) { + us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud); + return; + } + + // One extra digit for d is allocated to simplify vec_div_*(). + int nd = sc_max(und, vnd) + 1; + +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS + 1]; +#else + sc_digit *d = new sc_digit[nd]; +#endif + + vec_zero(nd, d); + + // u = v => u / v = 1 - case 3 + if (cmp_res == 0) + d[0] = 1; + + else if ((vnd == 1) && (und == 1)) + d[0] = (*ud) / vd0; + + else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) + vec_div_small(und, ud, vd0, d); + + else + vec_div_large(und, ud, vnd, vd, d); + + COPY_DIGITS(us, unb, old_und, ud, sc_max(unb, vnb), nd - 1, d); + +#ifndef SC_MAX_NBITS + delete [] d; +#endif + + } + +#undef COPY_DIGITS +#undef CONVERT_SM_to_2C_to_SM + +} + + +// ---------------------------------------------------------------------------- +// SECTION: External functions for MOD operators. +// ---------------------------------------------------------------------------- + +void +mod_on_help_signed(small_type &us, + int unb, int und, + sc_digit *ud, + int /* vnb */, int vnd, + const sc_digit *vd) +{ + +#define COPY_DIGITS copy_digits_signed + + { // Body of mod_on_help + + int old_und = und; + + und = vec_skip_leading_zeros(und, ud); + vnd = vec_skip_leading_zeros(vnd, vd); + + int cmp_res = vec_cmp(und, ud, vnd, vd); + + // u < v => u % v = u - case 4 + if (cmp_res < 0) + return; + + // u = v => u % v = 0 - case 3 + if (cmp_res == 0) { + us = SC_ZERO; + vec_zero(old_und, ud); + return; + } + + // else if u > v - case 5 + + sc_digit vd0 = (*vd); + + if ((vnd == 1) && (vd0 == 1)) { + us = SC_ZERO; + vec_zero(old_und, ud); + return; + } + + // One extra digit for d is allocated to simplify vec_div_*(). + int nd = sc_max(und, vnd) + 1; + +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS + 1]; +#else + sc_digit *d = new sc_digit[nd]; +#endif + + vec_zero(nd, d); + + if ((vnd == 1) && (und == 1)) + d[0] = (*ud) % vd0; + + if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) + d[0] = vec_rem_small(und, ud, vd0); + + else + vec_rem_large(und, ud, vnd, vd, d); + + us = check_for_zero(us, nd - 1, d); + + if (us == SC_ZERO) + vec_zero(old_und, ud); + else + COPY_DIGITS(us, unb, old_und, ud, sc_min(unb, vnd), nd - 1, d); + +#ifndef SC_MAX_NBITS + delete [] d; +#endif + + } + +#undef COPY_DIGITS + +} + + +void +mod_on_help_unsigned(small_type &us, + int unb, int und, + sc_digit *ud, + int /* vnb */, int vnd, + const sc_digit *vd) +{ + +#define COPY_DIGITS copy_digits_unsigned + + { // Body of mod_on_help + + int old_und = und; + + und = vec_skip_leading_zeros(und, ud); + vnd = vec_skip_leading_zeros(vnd, vd); + + int cmp_res = vec_cmp(und, ud, vnd, vd); + + // u < v => u % v = u - case 4 + if (cmp_res < 0) + return; + + // u = v => u % v = 0 - case 3 + if (cmp_res == 0) { + us = SC_ZERO; + vec_zero(old_und, ud); + return; + } + + // else if u > v - case 5 + + sc_digit vd0 = (*vd); + + if ((vnd == 1) && (vd0 == 1)) { + us = SC_ZERO; + vec_zero(old_und, ud); + return; + } + + // One extra digit for d is allocated to simplify vec_div_*(). + int nd = sc_max(und, vnd) + 1; + +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS + 1]; +#else + sc_digit *d = new sc_digit[nd]; +#endif + + vec_zero(nd, d); + + if ((vnd == 1) && (und == 1)) + d[0] = (*ud) % vd0; + + if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) + d[0] = vec_rem_small(und, ud, vd0); + + else + vec_rem_large(und, ud, vnd, vd, d); + + us = check_for_zero(us, nd - 1, d); + + if (us == SC_ZERO) + vec_zero(old_und, ud); + else + COPY_DIGITS(us, unb, old_und, ud, sc_min(unb, vnd), nd - 1, d); + +#ifndef SC_MAX_NBITS + delete [] d; +#endif + + } + +#undef COPY_DIGITS + +} + + +// ---------------------------------------------------------------------------- +// SECTION: External functions for AND operators. +// ---------------------------------------------------------------------------- + +// Handles the cases 2-5 and returns the result in u. +void +and_on_help(small_type us, + int /* unb */, int und, + sc_digit *ud, + small_type vs, + int /* vnb */, int vnd, + const sc_digit *vd) +{ + + sc_digit *x = ud; + const sc_digit *y = vd; + int xnd = und; + int ynd = vnd; + + // Truncate y. + if (xnd < ynd) + ynd = xnd; + + const sc_digit *xend = (x + xnd); + const sc_digit *yend = (y + ynd); + + // x is longer than y. + + small_type s = mul_signs(us, vs); + + if (s > 0) { + + if (us > 0) { // case 2 + + while (y < yend) + (*x++) &= (*y++); + + while (x < xend) + (*x++) = 0; + + } + else { // case 3 + + sc_digit xcarry = 1; + sc_digit ycarry = 1; + + while (y < yend) { + xcarry += (~(*x) & DIGIT_MASK); + ycarry += (~(*y++) & DIGIT_MASK); + (*x++) = (xcarry & ycarry) & DIGIT_MASK; + xcarry >>= BITS_PER_DIGIT; + ycarry >>= BITS_PER_DIGIT; + } + + while (x < xend) { + xcarry += (~(*x) & DIGIT_MASK); + ycarry += DIGIT_MASK; + (*x++) = (xcarry & ycarry) & DIGIT_MASK; + xcarry >>= BITS_PER_DIGIT; + ycarry >>= BITS_PER_DIGIT; + } + + } + } + else { + + if (us > 0) { // case 4 + + sc_digit ycarry = 1; + + while (y < yend) { + ycarry += (~(*y++) & DIGIT_MASK); + (*x++) &= ycarry & DIGIT_MASK; + ycarry >>= BITS_PER_DIGIT; + } + + while (x < xend) { + ycarry += DIGIT_MASK; + (*x++) &= ycarry & DIGIT_MASK; + ycarry >>= BITS_PER_DIGIT; + } + + } + else { // case 5 + + sc_digit xcarry = 1; + + while (y < yend) { + xcarry += (~(*x) & DIGIT_MASK); + (*x++) = (xcarry & (*y++)) & DIGIT_MASK; + xcarry >>= BITS_PER_DIGIT; + } + + while (x < xend) + (*x++) = 0; + + } + } +} + + +// ---------------------------------------------------------------------------- +// SECTION: External functions for OR operators. +// ---------------------------------------------------------------------------- + +// Handles the cases 3-5 and returns the result in u. +void +or_on_help(small_type us, + int /* unb */, int und, + sc_digit *ud, + small_type vs, + int /* vnb */, int vnd, + const sc_digit *vd) +{ + + sc_digit *x = ud; + const sc_digit *y = vd; + int xnd = und; + int ynd = vnd; + + if (xnd < ynd) + ynd = xnd; + + const sc_digit *xend = (x + xnd); + const sc_digit *yend = (y + ynd); + + // x is longer than y. + + small_type s = mul_signs(us, vs); + + if (s > 0) { + + if (us > 0) { // case 3 + + while (y < yend) + (*x++) |= (*y++); + + // No change for the rest of x. + + } + else { // case 4 + + sc_digit xcarry = 1; + sc_digit ycarry = 1; + + while (y < yend) { + xcarry += (~(*x) & DIGIT_MASK); + ycarry += (~(*y++) & DIGIT_MASK); + (*x++) = (xcarry | ycarry) & DIGIT_MASK; + xcarry >>= BITS_PER_DIGIT; + ycarry >>= BITS_PER_DIGIT; + } + + while (x < xend) { + xcarry += (~(*x) & DIGIT_MASK); + ycarry += DIGIT_MASK; + (*x++) = (xcarry | ycarry) & DIGIT_MASK; + xcarry >>= BITS_PER_DIGIT; + ycarry >>= BITS_PER_DIGIT; + } + } + + } + else { + + if (us > 0) { // case 5 + + sc_digit ycarry = 1; + + while (y < yend) { + ycarry += (~(*y++) & DIGIT_MASK); + (*x) = ((*x) | ycarry) & DIGIT_MASK; + x++; + ycarry >>= BITS_PER_DIGIT; + } + + while (x < xend) { + ycarry += DIGIT_MASK; + (*x) = ((*x) | ycarry) & DIGIT_MASK; + x++; + ycarry >>= BITS_PER_DIGIT; + } + + } + else { // case 6 + + sc_digit xcarry = 1; + + while (y < yend) { + xcarry += (~(*x) & DIGIT_MASK); + (*x++) = (xcarry | (*y++)) & DIGIT_MASK; + xcarry >>= BITS_PER_DIGIT; + } + + while (x < xend) { + xcarry += (~(*x) & DIGIT_MASK); + (*x++) = xcarry & DIGIT_MASK; + xcarry >>= BITS_PER_DIGIT; + } + } + } +} + + +// ---------------------------------------------------------------------------- +// SECTION: External functions for XOR operators. +// ---------------------------------------------------------------------------- + +// Handles the cases 3-5 and returns the result in u. +void +xor_on_help(small_type us, + int /* unb */, int und, + sc_digit *ud, + small_type vs, + int /* vnb */, int vnd, + const sc_digit *vd) +{ + + sc_digit *x = ud; + const sc_digit *y = vd; + int xnd = und; + int ynd = vnd; + + if (xnd < ynd) + ynd = xnd; + + const sc_digit *xend = (x + xnd); + const sc_digit *yend = (y + ynd); + + // x is longer than y. + + small_type s = mul_signs(us, vs); + + if (s > 0) { + + if (us > 0) { // case 3 + + while (y < yend) { + (*x) = ((*x) ^ (*y)) & DIGIT_MASK; + x++; + y++; + } + + // No change for the rest of x. + + } + else { // case 4 + + sc_digit xcarry = 1; + sc_digit ycarry = 1; + + while (y < yend) { + xcarry += (~(*x) & DIGIT_MASK); + ycarry += (~(*y++) & DIGIT_MASK); + (*x++) = (xcarry ^ ycarry) & DIGIT_MASK; + xcarry >>= BITS_PER_DIGIT; + ycarry >>= BITS_PER_DIGIT; + } + + while (x < xend) { + xcarry += (~(*x) & DIGIT_MASK); + ycarry += DIGIT_MASK; + (*x++) = (xcarry ^ ycarry) & DIGIT_MASK; + xcarry >>= BITS_PER_DIGIT; + ycarry >>= BITS_PER_DIGIT; + } + } + } + else { + + if (us > 0) { // case 5 + + sc_digit ycarry = 1; + + while (y < yend) { + ycarry += (~(*y++) & DIGIT_MASK); + (*x) = ((*x) ^ ycarry) & DIGIT_MASK; + x++; + ycarry >>= BITS_PER_DIGIT; + } + + while (x < xend) { + ycarry += DIGIT_MASK; + (*x) = ((*x) ^ ycarry) & DIGIT_MASK; + x++; + ycarry >>= BITS_PER_DIGIT; + } + + } + else { // case 6 + + sc_digit xcarry = 1; + + while (y < yend) { + xcarry += (~(*x) & DIGIT_MASK); + (*x++) = (xcarry ^ (*y++)) & DIGIT_MASK; + xcarry >>= BITS_PER_DIGIT; + } + + while (x < xend) { + xcarry += (~(*x) & DIGIT_MASK); + (*x++) = xcarry & DIGIT_MASK; + xcarry >>= BITS_PER_DIGIT; + } + } + } +} + +} // namespace sc_dt + + +// End of file diff --git a/ext/systemc/src/sysc/datatypes/int/sc_nbexterns.h b/ext/systemc/src/sysc/datatypes/int/sc_nbexterns.h new file mode 100644 index 000000000..98f5cda91 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_nbexterns.h @@ -0,0 +1,123 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_nbexterns.h -- External functions for both sc_signed and sc_unsigned + classes. These functions work on two parameters u and + v, and copy the result to the first parameter u. This + is also the reason that they are suffixed with _on_help. + + The vec_* functions are called through either these + functions or those in sc_nbfriends.cpp. The functions in + sc_nbfriends.cpp perform their work on two inputs u and v, + and return the result object. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_nbexterns.h,v $ +// Revision 1.2 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:32 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef SC_NBEXTERNS_H +#define SC_NBEXTERNS_H + + +#include "sysc/datatypes/int/sc_nbutils.h" + + +namespace sc_dt +{ + +extern +void add_on_help(small_type &us, + int unb, int und, sc_digit *ud, + small_type vs, + int vnb, int vnd, const sc_digit *vd); + +extern +void mul_on_help_signed(small_type &us, + int unb, int und, sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + +void div_on_help_signed(small_type &us, + int unb, int und, sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + +extern +void mod_on_help_signed(small_type &us, + int unb, int und, sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + +extern +void mul_on_help_unsigned(small_type &us, + int unb, int und, sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + +void div_on_help_unsigned(small_type &us, + int unb, int und, sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + +extern +void mod_on_help_unsigned(small_type &us, + int unb, int und, sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + +extern +void and_on_help(small_type us, + int unb, int und, sc_digit *ud, + small_type vs, + int vnb, int vnd, const sc_digit *vd); + +extern +void or_on_help(small_type us, + int unb, int und, sc_digit *ud, + small_type vs, + int vnb, int vnd, const sc_digit *vd); + +extern +void xor_on_help(small_type us, + int unb, int und, sc_digit *ud, + small_type vs, + int vnb, int vnd, const sc_digit *vd); + +} // namespace sc_dt + + +#endif diff --git a/ext/systemc/src/sysc/datatypes/int/sc_nbfriends.inc b/ext/systemc/src/sysc/datatypes/int/sc_nbfriends.inc new file mode 100644 index 000000000..5d67939e5 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_nbfriends.inc @@ -0,0 +1,727 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_nbfriends.inc -- Friend functions for both sc_signed and sc_unsigned + classes. The vec_* functions are called through either + these functions or those in sc_nbexterns.cpp. These + functions perform their work on two inputs u and v, and + return the result object. The functions in + sc_nbexterns.cpp perform their work on one of their + inputs. + + The functions here try to use faster algorithms in case + the input numbers are small. The bitwise functions (and, + or, and xor) need the 2's complement representations of + their inputs. Instead of complementing their inputs + first and then processing, they complement their inputs + while processing without allocating extra temporary + memory. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// ---------------------------------------------------------------------------- +// Naming conventions: +// For sc_signed or sc_unsigned number u: +// us : u's sign, unb : u's number of bits, +// und : u's number of digits, ud : u's digits array. +// ---------------------------------------------------------------------------- + +// ---------------------------------------------------------------------------- +// SECTION: Friend functions for PLUS operators. +// ---------------------------------------------------------------------------- + +// Handles cases 3 and 4 and returns the result. +CLASS_TYPE +ADD_HELPER(small_type us, int unb, int und, + const sc_digit *ud, + small_type vs, int vnb, int vnd, + const sc_digit *vd) +{ + + und = vec_skip_leading_zeros(und, ud); + vnd = vec_skip_leading_zeros(vnd, vd); + + int nb = sc_max(unb, vnb); + int nd = sc_max(und, vnd) + 1; + +#ifdef SC_MAX_NBITS + test_bound(nb); + sc_digit d[MAX_NDIGITS]; +#else + sc_digit *d = new sc_digit[nd]; +#endif + + d[nd - 1] = d[nd - 2] = 0; + + // case 3 + if (us == vs) { + + ++nb; + + if ((und == 1) && (vnd == 1)) { + sc_digit carry = (*ud) + (*vd); + d[0] = carry & DIGIT_MASK; + d[1] = carry >> BITS_PER_DIGIT; + } + + else if (und >= vnd) + vec_add(und, ud, vnd, vd, d); + + else + vec_add(vnd, vd, und, ud, d); + + } + + // case 4 + else { + + int cmp_res = vec_cmp(und, ud, vnd, vd); + + if (cmp_res == 0) { // u == v +#ifndef SC_MAX_NBITS + delete[] d; +#endif + return CLASS_TYPE(); + } + + if (cmp_res > 0) { // u > v + + if ((und == 1) && (vnd == 1)) + d[0] = (*ud) - (*vd); + else + vec_sub(und, ud, vnd, vd, d); + + } + else { // u < v + + us = -us; + + if ((und == 1) && (vnd == 1)) + d[0] = (*vd) - (*ud); + else + vec_sub(vnd, vd, und, ud, d); + + } + } + + return CLASS_TYPE(us, nb, nd, d); + +} + + +// ---------------------------------------------------------------------------- +// SECTION: Friend functions of MULTIPLICATION operators. +// ---------------------------------------------------------------------------- + +// Handles the case 4 and returns the result. +CLASS_TYPE +MUL_HELPER(small_type s, + int unb, int und, + const sc_digit *ud, + int vnb, int vnd, + const sc_digit *vd) +{ + + und = vec_skip_leading_zeros(und, ud); + vnd = vec_skip_leading_zeros(vnd, vd); + + int nb = unb + vnb; + int nd = und + vnd; + +#ifdef SC_MAX_NBITS + test_bound(nb); + sc_digit d[MAX_NDIGITS]; +#else + sc_digit *d = new sc_digit[nd]; +#endif + + vec_zero(nd, d); + + sc_digit ud0 = (*ud); + sc_digit vd0 = (*vd); + + if ((vnd == 1) && (vd0 == 1)) + vec_copy(und, d, ud); + + else if ((und == 1) && (ud0 == 1)) + vec_copy(vnd, d, vd); + + else if ((und == 1) && (vnd == 1) && + (ud0 < HALF_DIGIT_RADIX) && (vd0 < HALF_DIGIT_RADIX)) + d[0] = ud0 * vd0; + + else if ((und == 1) && (ud0 < HALF_DIGIT_RADIX)) + vec_mul_small(vnd, vd, ud0, d); + + else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) + vec_mul_small(und, ud, vd0, d); + + else if (vnd < und) + vec_mul(und, ud, vnd, vd, d); + + else + vec_mul(vnd, vd, und, ud, d); + + return CLASS_TYPE(s, nb, nd, d); + +} + + +// ---------------------------------------------------------------------------- +// SECTION: Friend functions for DIVISION operators. +// ---------------------------------------------------------------------------- + +// Handles the cases 3-4 and returns the result. +CLASS_TYPE +DIV_HELPER(small_type s, + int unb, int und, + const sc_digit *ud, + int vnb, int vnd, + const sc_digit *vd) +{ + + und = vec_skip_leading_zeros(und, ud); + vnd = vec_skip_leading_zeros(vnd, vd); + + int cmp_res = vec_cmp(und, ud, vnd, vd); + + // u < v => u / v = 0 - case 4 + if (cmp_res < 0) + return CLASS_TYPE(); + + // One extra digit for d is allocated to simplify vec_div_*(). + int nd = sc_max(und, vnd) + 1; + +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS + 1]; +#else + sc_digit *d = new sc_digit[nd]; +#endif + + vec_zero(nd, d); + + sc_digit vd0 = (*vd); + + // u = v => u / v = 1 - case 3 + if (cmp_res == 0) + d[0] = 1; + + // else if u > v - case 5 + + else if ((vnd == 1) && (vd0 == 1)) + vec_copy(und, d, ud); + + else if ((vnd == 1) && (und == 1)) + d[0] = (*ud) / vd0; + + else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) + vec_div_small(und, ud, vd0, d); + + else + vec_div_large(und, ud, vnd, vd, d); + + return CLASS_TYPE(s, sc_max(unb, vnb), nd - 1, d); + +} + + +// ---------------------------------------------------------------------------- +// SECTION: Friend functions for MOD operators. +// ---------------------------------------------------------------------------- + +// Handles the cases 3-4 and returns the result. +CLASS_TYPE +MOD_HELPER(small_type us, + int unb, int und, + const sc_digit *ud, + int vnb, int vnd, + const sc_digit *vd) +{ + + und = vec_skip_leading_zeros(und, ud); + vnd = vec_skip_leading_zeros(vnd, vd); + + int cmp_res = vec_cmp(und, ud, vnd, vd); + + // u = v => u % v = 0 - case 3 + if (cmp_res == 0) + return CLASS_TYPE(); + + sc_digit vd0 = (*vd); + + if ((cmp_res > 0) && (vnd == 1) && (vd0 == 1)) + return CLASS_TYPE(); + + // One extra digit for d is allocated to simplify vec_div_*(). + int nd = sc_max(und, vnd) + 1; + +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS + 1]; +#else + sc_digit *d = new sc_digit[nd]; +#endif + + vec_zero(nd, d); + + // u < v => u % v = u - case 4 + if (cmp_res < 0) + vec_copy(und, d, ud); + + // else if u > v - case 5 + + else if ((vnd == 1) && (und == 1)) + d[0] = (*ud) % vd0; + + else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) + d[0] = vec_rem_small(und, ud, vd0); + + else + vec_rem_large(und, ud, vnd, vd, d); + + us = check_for_zero(us, nd - 1, d); + + if (us == SC_ZERO) { +#ifndef SC_MAX_NBITS + delete[] d; +#endif + return CLASS_TYPE(); + } else + return CLASS_TYPE(us, sc_min(unb, vnb), nd - 1, d); + +} + + +// ---------------------------------------------------------------------------- +// SECTION: Friend functions for AND operators. +// ---------------------------------------------------------------------------- + +// Handles the cases 2-5 and returns the result. +CLASS_TYPE +AND_HELPER(small_type us, + int unb, int und, + const sc_digit *ud, + small_type vs, + int vnb, int vnd, + const sc_digit *vd) +{ + + int nb = sc_max(unb, vnb); + int nd = sc_max(und, vnd); + +#ifdef SC_MAX_NBITS + sc_digit dbegin[MAX_NDIGITS]; +#else + sc_digit *dbegin = new sc_digit[nd]; +#endif + + sc_digit *d = dbegin; + + const sc_digit *x; + const sc_digit *y; + int xnd; + int ynd; + small_type xs; + small_type ys; + + if (und >= vnd) { + x = ud; + y = vd; + xnd = und; + ynd = vnd; + xs = us; + ys = vs; + } + else { + y = ud; + x = vd; + ynd = und; + xnd = vnd; + ys = us; + xs = vs; + } + + const sc_digit *xend = (x + xnd); + const sc_digit *yend = (y + ynd); + + // x is longer than y. + + small_type s = mul_signs(xs, ys); + + if (s > 0) { + + if (xs > 0) { // case 2 + + while (y < yend) + (*d++) = (*x++) & (*y++); + + while (x++ < xend) + (*d++) = 0; + + } + else { // case 3 + + sc_digit xcarry = 1; + sc_digit ycarry = 1; + + while (y < yend) { + xcarry += (~(*x++) & DIGIT_MASK); + ycarry += (~(*y++) & DIGIT_MASK); + (*d++) = (xcarry & ycarry) & DIGIT_MASK; + xcarry >>= BITS_PER_DIGIT; + ycarry >>= BITS_PER_DIGIT; + } + + while (x < xend) { + xcarry += (~(*x++) & DIGIT_MASK); + ycarry += DIGIT_MASK; + (*d++) = (xcarry & ycarry) & DIGIT_MASK; + xcarry >>= BITS_PER_DIGIT; + ycarry >>= BITS_PER_DIGIT; + } + + } + } + else { + + if (xs > 0) { // case 4 + + sc_digit ycarry = 1; + + while (y < yend) { + ycarry += (~(*y++) & DIGIT_MASK); + (*d++) = ((*x++) & ycarry) & DIGIT_MASK; + ycarry >>= BITS_PER_DIGIT; + } + + while (x < xend) { + ycarry += DIGIT_MASK; + (*d++) = ((*x++) & ycarry) & DIGIT_MASK; + ycarry >>= BITS_PER_DIGIT; + } + + } + else { // case 5 + + sc_digit xcarry = 1; + + while (y < yend) { + xcarry += (~(*x++) & DIGIT_MASK); + (*d++) = (xcarry & (*y++)) & DIGIT_MASK; + xcarry >>= BITS_PER_DIGIT; + } + + while (x++ < xend) + (*d++) = 0; + + } + } + + s = convert_signed_2C_to_SM(nb, nd, dbegin); + + return CLASS_TYPE(s, nb, nd, dbegin); + +} + + +// ---------------------------------------------------------------------------- +// SECTION: Friend functions for OR operators. +// ---------------------------------------------------------------------------- + +// Handles the cases 3-5 and returns the result. +CLASS_TYPE +OR_HELPER(small_type us, + int unb, int und, + const sc_digit *ud, + small_type vs, + int vnb, int vnd, + const sc_digit *vd) +{ + + int nb = sc_max(unb, vnb); + int nd = sc_max(und, vnd); + +#ifdef SC_MAX_NBITS + sc_digit dbegin[MAX_NDIGITS]; +#else + sc_digit *dbegin = new sc_digit[nd]; +#endif + + sc_digit *d = dbegin; + + const sc_digit *x; + const sc_digit *y; + int xnd; + int ynd; + small_type xs; + small_type ys; + + if (und >= vnd) { + x = ud; + y = vd; + xnd = und; + ynd = vnd; + xs = us; + ys = vs; + } + else { + y = ud; + x = vd; + ynd = und; + xnd = vnd; + ys = us; + xs = vs; + } + + const sc_digit *xend = (x + xnd); + const sc_digit *yend = (y + ynd); + + // x is longer than y. + + small_type s = mul_signs(xs, ys); + + if (s > 0) { + + if (xs > 0) { // case 3 + + while (y < yend) + (*d++) = (*x++) | (*y++); + + while (x < xend) + (*d++) = (*x++); + + } + else { // case 4 + + sc_digit xcarry = 1; + sc_digit ycarry = 1; + + while (y < yend) { + xcarry += (~(*x++) & DIGIT_MASK); + ycarry += (~(*y++) & DIGIT_MASK); + (*d++) = (xcarry | ycarry) & DIGIT_MASK; + xcarry >>= BITS_PER_DIGIT; + ycarry >>= BITS_PER_DIGIT; + } + + while (x < xend) { + xcarry += (~(*x++) & DIGIT_MASK); + ycarry += DIGIT_MASK; + (*d++) = (xcarry | ycarry) & DIGIT_MASK; + xcarry >>= BITS_PER_DIGIT; + ycarry >>= BITS_PER_DIGIT; + } + + } + + } + else { + + if (xs > 0) { // case 5 + + sc_digit ycarry = 1; + + while (y < yend) { + ycarry += (~(*y++) & DIGIT_MASK); + (*d++) = ((*x++) | ycarry) & DIGIT_MASK; + ycarry >>= BITS_PER_DIGIT; + } + + while (x < xend) { + ycarry += DIGIT_MASK; + (*d++) = ((*x++) | ycarry) & DIGIT_MASK; + ycarry >>= BITS_PER_DIGIT; + } + + } + else { // case 6 + + sc_digit xcarry = 1; + + while (y < yend) { + xcarry += (~(*x++) & DIGIT_MASK); + (*d++) = (xcarry | (*y++)) & DIGIT_MASK; + xcarry >>= BITS_PER_DIGIT; + } + + while (x < xend) { + xcarry += (~(*x++) & DIGIT_MASK); + (*d++) = xcarry & DIGIT_MASK; + xcarry >>= BITS_PER_DIGIT; + } + } + + } + + s = convert_signed_2C_to_SM(nb, nd, dbegin); + + return CLASS_TYPE(s, nb, nd, dbegin); + +} + + +// ---------------------------------------------------------------------------- +// SECTION: Friend functions for XOR operators. +// ---------------------------------------------------------------------------- + +// Handles the cases 3-5 and returns the result. +CLASS_TYPE +XOR_HELPER(small_type us, + int unb, int und, + const sc_digit *ud, + small_type vs, + int vnb, int vnd, + const sc_digit *vd) +{ + + int nb = sc_max(unb, vnb); + int nd = sc_max(und, vnd); + +#ifdef SC_MAX_NBITS + sc_digit dbegin[MAX_NDIGITS]; +#else + sc_digit *dbegin = new sc_digit[nd]; +#endif + + sc_digit *d = dbegin; + + const sc_digit *x; + const sc_digit *y; + int xnd; + int ynd; + small_type xs; + small_type ys; + + if (und >= vnd) { + x = ud; + y = vd; + xnd = und; + ynd = vnd; + xs = us; + ys = vs; + } + else { + y = ud; + x = vd; + ynd = und; + xnd = vnd; + ys = us; + xs = vs; + } + + const sc_digit *xend = (x + xnd); + const sc_digit *yend = (y + ynd); + + // x is longer than y. + + small_type s = mul_signs(xs, ys); + + if (s > 0) { + + if (xs > 0) { // case 3 + + while (y < yend) + (*d++) = ((*x++) ^ (*y++)) & DIGIT_MASK; + + while (x < xend) + (*d++) = (*x++); + + } + else { // case 4 + + sc_digit xcarry = 1; + sc_digit ycarry = 1; + + while (y < yend) { + xcarry += (~(*x++) & DIGIT_MASK); + ycarry += (~(*y++) & DIGIT_MASK); + (*d++) = (xcarry ^ ycarry) & DIGIT_MASK; + xcarry >>= BITS_PER_DIGIT; + ycarry >>= BITS_PER_DIGIT; + } + + while (x < xend) { + xcarry += (~(*x++) & DIGIT_MASK); + ycarry += DIGIT_MASK; + (*d++) = (xcarry ^ ycarry) & DIGIT_MASK; + xcarry >>= BITS_PER_DIGIT; + ycarry >>= BITS_PER_DIGIT; + } + + } + } + else { + + if (xs > 0) { // case 5 + + sc_digit ycarry = 1; + + while (y < yend) { + ycarry += (~(*y++) & DIGIT_MASK); + (*d++) = ((*x++) ^ ycarry) & DIGIT_MASK; + ycarry >>= BITS_PER_DIGIT; + } + + while (x < xend) { + ycarry += DIGIT_MASK; + (*d++) = ((*x++) ^ ycarry) & DIGIT_MASK; + ycarry >>= BITS_PER_DIGIT; + } + + } + else { // case 6 + + sc_digit xcarry = 1; + + while (y < yend) { + xcarry += (~(*x++) & DIGIT_MASK); + (*d++) = (xcarry ^ (*y++)) & DIGIT_MASK; + xcarry >>= BITS_PER_DIGIT; + } + + while (x < xend) { + xcarry += (~(*x++) & DIGIT_MASK); + (*d++) = xcarry & DIGIT_MASK; + xcarry >>= BITS_PER_DIGIT; + } + } + } + + s = convert_signed_2C_to_SM(nb, nd, dbegin); + + return CLASS_TYPE(s, nb, nd, dbegin); + +} + +// End of file. + diff --git a/ext/systemc/src/sysc/datatypes/int/sc_nbutils.cpp b/ext/systemc/src/sysc/datatypes/int/sc_nbutils.cpp new file mode 100644 index 000000000..385502aa6 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_nbutils.cpp @@ -0,0 +1,1892 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_nbutils.cpp -- External and friend functions for both sc_signed and + sc_unsigned classes. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_nbutils.cpp,v $ +// Revision 1.4 2011/08/24 22:05:46 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.3 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.2 2007/11/04 21:26:40 acg +// Andy Goodrich: added a buffer to the allocation of the q array to address +// an issue with references outside the array by 1 byte detected by valgrind. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:32 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#include <ctype.h> +#include <cstdio> +#include <string.h> + +#include "sysc/datatypes/int/sc_int_ids.h" +#include "sysc/datatypes/int/sc_nbutils.h" +#include "sysc/kernel/sc_macros.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// ENUM : sc_numrep +// +// Enumeration of number representations for character string conversion. +// ---------------------------------------------------------------------------- + +const std::string +to_string( sc_numrep numrep ) +{ + switch( numrep ) + { +# define CASE_ENUM2STR( Value ) \ + case Value: return #Value + + CASE_ENUM2STR(SC_DEC); + + CASE_ENUM2STR(SC_BIN); + CASE_ENUM2STR(SC_BIN_US); + CASE_ENUM2STR(SC_BIN_SM); + + CASE_ENUM2STR(SC_OCT); + CASE_ENUM2STR(SC_OCT_US); + CASE_ENUM2STR(SC_OCT_SM); + + CASE_ENUM2STR(SC_HEX); + CASE_ENUM2STR(SC_HEX_US); + CASE_ENUM2STR(SC_HEX_SM); + + CASE_ENUM2STR(SC_CSD); + +# undef CASE_ENUM2STR + + default: + return "unknown"; + } +} + +// ---------------------------------------------------------------------------- +// SECTION: General utility functions. +// ---------------------------------------------------------------------------- + +// Return the number of characters to advance the source of c. This +// function implements one move of the FSM to parse the following +// regular expressions. Error checking is done in the caller. + +small_type +fsm_move(char c, small_type &b, small_type &s, small_type &state) +{ + + // Possible regular expressions (REs): + // Let N = any digit depending on the base. + // 1. [0|1|..|9]N* + // 2. [+|-][0|1|..|9]N* + // 3. 0[b|B|d|D|o|O|x|X][0|1|..|F]N* + // 4. [+|-]?0[b|B|d|D|o|O|x|X][0|1|..|F]N* + // + // The finite state machine (FMS) to parse these regular expressions + // has 4 states, 0 to 3. 0 is the initial state and 3 is the final + // state. + // + // Default sign = SC_POS, default base = NB_DEFAULT_BASE. + + switch (state) { + + case 0: // The initial state. + switch (c) { + case '0': s = SC_POS; state = 1; return 0; // RE 1 or 3 + case '+': s = SC_POS; state = 2; return 1; // RE 2 + case '-': s = SC_NEG; state = 2; return 1; // RE 2 + default: s = SC_POS; b = NB_DEFAULT_BASE; state = 3; return 0; // RE 1 + } + // break; //unreachable code + case 1: // 0... + switch (c) { + case 'x': case 'X': b = SC_HEX; state = 3; return 2; // RE 3 or 4 + case 'd': case 'D': b = SC_DEC; state = 3; return 2; // RE 3 or 4 + case 'o': case 'O': b = SC_OCT; state = 3; return 2; // RE 3 or 4 + case 'b': case 'B': b = SC_BIN; state = 3; return 2; // RE 3 or 4 + default: b = NB_DEFAULT_BASE; state = 3; return 0; // RE 1 + } + // break; //unreachable code + case 2: // +... or -... + switch (c) { + case '0': state = 1; return 0; // RE 2 or 4 + default: b = NB_DEFAULT_BASE; state = 3; return 0; // RE 2 + } + // break; //unreachable code + case 3: // The final state. + break; + + default: + // Any other state is not possible. + assert((0 <= state) && (state <= 3)); + + } // switch + + return 0; + +} + + +// Get base b and sign s of the number in the char string v. Return a +// pointer to the first char after the point where b and s are +// determined or where the end of v is reached. The input string v has +// to be null terminated. +const char +*get_base_and_sign(const char *v, small_type &b, small_type &s) +{ + +#ifdef DEBUG_SYSTEMC + assert(v != NULL); +#endif + + const small_type STATE_START = 0; + const small_type STATE_FINISH = 3; + + // Default sign = SC_POS, default base = 10. + s = SC_POS; + b = NB_DEFAULT_BASE; + + small_type state = STATE_START; + small_type nskip = 0; // Skip that many chars. + const char *u = v; + + while (*u) { + if (isspace(*u)) // Skip white space. + ++u; + else { + nskip += fsm_move(*u, b, s, state); + if (state == STATE_FINISH) + break; + else + ++u; + } + } + +#ifdef DEBUG_SYSTEMC + // Test to see if the above loop executed more than it should + // have. The max number of skipped chars is equal to the length of + // the longest format specifier, e.g., "-0x". + assert(nskip <= 3); +#endif + + v += nskip; + + // Handles empty strings or strings without any digits after the + // base or base and sign specifier. + if (*v == '\0') { + char msg[BUFSIZ]; + std::sprintf( msg, + "get_base_and_sign( const char* v, small_type&, small_type& ) : " + "v = \"\" is not valid" ); + SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg ); + } + + return v; + +} + +//------------------------------------------------------------------------------ +//"parse_binary_bits" +// +// This function parses the supplied string into the supplied vector as a +// right justified bit value. +// src_p -> character string representing the bits to be parsed. +// dst_n = number of words in data_p and ctrl_p. +// data_p -> words w/BITS_PER_DIGIT bits to receive the value's data bits. +// ctrl_p -> words w/BITS_PER_DIGIT bits to receive the value's control bits, +// or zero. +// Result is true if value was non-zero. +//------------------------------------------------------------------------------ +void parse_binary_bits( + const char* src_p, int dst_n, sc_digit* data_p, sc_digit* ctrl_p ) +{ + int bit_i; // Number of bit now processing. + sc_digit ctrl; // Control word now assembling. + sc_digit data; // Data word now assembling. + int delta_n; // src_n - dst_n*BITS_PER_DIGIT. + int src_i; // Index in src_p now accessing (left to right). + int src_n; // Length of source that is left in bits. + int word_i; // Bit within word now accessing (left to right). + + // MAKE SURE WE HAVE A STRING TO PARSE: + + if( src_p == 0 ) { + SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, + "character string is zero" ); + } + if( *src_p == 0 ) { + SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, + "character string is empty" ); + } + + + // INDEX INTO THE SOURCE TO A DEPTH THAT WILL ACCOMODATE OUR SIZE: + // + // If the source is smaller than our value initialize our value to zero. + + src_n = strlen(src_p); + delta_n = src_n - (dst_n*BITS_PER_DIGIT); + if ( delta_n > 0 ) + { + src_p = &src_p[delta_n]; + src_n -= delta_n; + } + else + { + for ( word_i = 0; word_i < dst_n; word_i++ ) data_p[word_i] = 0; + if ( ctrl_p ) + for ( word_i = 0; word_i < dst_n; word_i++ ) ctrl_p[word_i] = 0; + } + + + // LOOP OVER THE SOURCE ASSEMBLING WORDS AND PLACING THEM IN OUR VALUE: + // + // We stride right to left through the source in BITS_PER_DIGIT chunks. + // Each of those chunks is processed from left to right a bit at a time. + // We process the high order word specially, since there are less bits. + + src_n = src_n - BITS_PER_DIGIT; + for (word_i=0; word_i < dst_n; word_i++) + { + src_i = src_n; + + + // PARTIAL LAST WORD TO ASSEMBLE: + + if ( src_i < 0 ) + { + src_n += BITS_PER_DIGIT; + src_i = 0; + data = 0; + ctrl = 0; + for ( src_i = 0; src_i < src_n; src_i++ ) + { + ctrl = ctrl << 1; + data = data << 1; + switch( src_p[src_i] ) + { + case 'X': + case 'x': ctrl = ctrl | 1; data = data | 1; break; + case '1': data = data | 1; break; + case 'Z': + case 'z': ctrl = ctrl | 1; break; + case '0': break; + default: + { + char msg[BUFSIZ]; + std::sprintf( msg, "character string '%s' is not valid", + src_p ); + SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_, msg); + } + break; + } + } + if ( ctrl_p ) ctrl_p[word_i] = ctrl; + data_p[word_i] = data; + break; + } + + + // FULL WORD TO BE ASSEMBLED: + + ctrl = 0; + data = 0; + for ( bit_i = 0; bit_i < BITS_PER_DIGIT; bit_i++ ) + { + ctrl = ctrl << 1; + data = data << 1; + switch( src_p[src_i++] ) + { + case 'X': + case 'x': ctrl = ctrl | 1; data = data | 1; break; + case '1': data = data | 1; break; + case 'Z': + case 'z': ctrl = ctrl | 1; break; + case '0': break; + default: + { + char msg[BUFSIZ]; + std::sprintf( msg, "character string '%s' is not valid", + src_p ); + SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg ); + } + break; + } + } + if ( ctrl_p ) ctrl_p[word_i] = ctrl; + data_p[word_i] = data; + src_n = src_n - BITS_PER_DIGIT; + } +} + + +//------------------------------------------------------------------------------ +//"parse_hex_bits" +// +// This function parses the supplied string into the supplied vector as a +// right justified bit value. +// src_p -> character string representing the bits to be parsed. +// dst_n = number of words in data_p and ctrl_p. +// data_p -> words w/32 bits to receive the value's data bits. +// ctrl_p -> words w/32 bits to receive the value's control bits, +// or zero. +// Result is true if value was non-zero. +//------------------------------------------------------------------------------ +void parse_hex_bits( + const char* src_p, int dst_n, sc_digit* data_p, sc_digit* ctrl_p ) +{ + sc_digit ctrl; // Control word now assembling. + sc_digit data; // Data word now assembling. + int delta_n; // src_n - dst_n*BITS_PER_DIGIT. + int digit_i; // Number of digit now processing. + int src_i; // Index in src_p now accessing (left to right). + int src_n; // Length of source that is left in bits. + int word_i; // Bit within word now accessing (left to right). + + // MAKE SURE WE HAVE A STRING TO PARSE: + + if( src_p == 0 ) { + SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, + "character string is zero" ); + } + if( *src_p == 0 ) { + SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, + "character string is empty" ); + } + + + // INDEX INTO THE SOURCE TO A DEPTH THAT WILL ACCOMODATE OUR SIZE: + // + // If the source is smaller than our value initialize our value to zero. + + src_n = strlen(src_p); + delta_n = src_n - (dst_n*8); + if ( delta_n > 0 ) + { + src_p = &src_p[delta_n]; + src_n -= delta_n; + } + else + { + for ( word_i = 0; word_i < dst_n; word_i++ ) data_p[word_i] = 0; + if ( ctrl_p ) + for ( word_i = 0; word_i < dst_n; word_i++ ) ctrl_p[word_i] = 0; + } + + + // LOOP OVER THE SOURCE ASSEMBLING WORDS AND PLACING THEM IN OUR VALUE: + // + // We stride right to left through the source in BITS_PER_DIGIT chunks. + // Each of those chunks is processed from left to right a bit at a time. + // We process the high order word specially, since there are less bits. + + src_n = src_n - 8; + for (word_i=0; word_i < dst_n; word_i++) + { + src_i = src_n; + + + // PARTIAL LAST WORD TO ASSEMBLE: + + if ( src_i < 0 ) + { + src_n += 8; + src_i = 0; + data = 0; + ctrl = 0; + for ( src_i = 0; src_i < src_n; src_i++ ) + { + ctrl = ctrl << 4; + data = data << 4; + switch( src_p[src_i] ) + { + case 'X': + case 'x': ctrl = ctrl | 15; data = data | 15; break; + case 'F': + case 'f': data = data | 15; break; + case 'E': + case 'e': data = data | 14; break; + case 'D': + case 'd': data = data | 13; break; + case 'C': + case 'c': data = data | 12; break; + case 'B': + case 'b': data = data | 11; break; + case 'A': + case 'a': data = data | 10; break; + case '9': data = data | 9; break; + case '8': data = data | 8; break; + case '7': data = data | 7; break; + case '6': data = data | 6; break; + case '5': data = data | 5; break; + case '4': data = data | 4; break; + case '3': data = data | 3; break; + case '2': data = data | 2; break; + case '1': data = data | 1; break; + case '0': break; + case 'Z': + case 'z': ctrl = ctrl | 15; break; + default: + { + char msg[BUFSIZ]; + std::sprintf( msg, "character string '%s' is not valid", + src_p ); + SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_, msg); + } + break; + } + } + if ( ctrl_p ) ctrl_p[word_i] = ctrl; + data_p[word_i] = data; + break; + } + + + // FULL WORD TO BE ASSEMBLED: + + ctrl = 0; + data = 0; + for ( digit_i = 0; digit_i < 8; digit_i++ ) + { + ctrl = ctrl << 4; + data = data << 4; + switch( src_p[src_i++] ) + { + case 'X': + case 'x': ctrl = ctrl | 15; data = data | 15; break; + case 'F': + case 'f': data = data | 15; break; + case 'E': + case 'e': data = data | 14; break; + case 'D': + case 'd': data = data | 13; break; + case 'C': + case 'c': data = data | 12; break; + case 'B': + case 'b': data = data | 11; break; + case 'A': + case 'a': data = data | 10; break; + case '9': data = data | 9; break; + case '8': data = data | 8; break; + case '7': data = data | 7; break; + case '6': data = data | 6; break; + case '5': data = data | 5; break; + case '4': data = data | 4; break; + case '3': data = data | 3; break; + case '2': data = data | 2; break; + case '1': data = data | 1; break; + case '0': break; + case 'Z': + case 'z': ctrl = ctrl | 15; break; + default: + { + char msg[BUFSIZ]; + std::sprintf( msg, "character string '%s' is not valid", + src_p ); + SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg ); + } + break; + } + } + if ( ctrl_p ) ctrl_p[word_i] = ctrl; + data_p[word_i] = data; + src_n = src_n - BITS_PER_DIGIT; + } +} + + + +// ---------------------------------------------------------------------------- +// SECTION: Utility functions involving unsigned vectors. +// ---------------------------------------------------------------------------- + +// Read u from a null terminated char string v. Note that operator>> +// in sc_nbcommon.cpp is similar to this function. +small_type +vec_from_str(int unb, int und, sc_digit *u, + const char *v, sc_numrep base) +{ + +#ifdef DEBUG_SYSTEMC + assert((unb > 0) && (und > 0) && (u != NULL)); + assert(v != NULL); +#endif + + is_valid_base(base); + + small_type b, s; // base and sign. + + v = get_base_and_sign(v, b, s); + + if (base != SC_NOBASE) { + if (b == NB_DEFAULT_BASE) + b = base; + else { + char msg[BUFSIZ]; + std::sprintf( msg, + "vec_from_str( int, int, sc_digit*, const char*, sc_numrep base ) : " + "base = %s does not match the default base", + to_string( base ).c_str() ); + SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg ); + } + } + + vec_zero(und, u); + + char c; + + for ( ; (c = *v); ++v) { + + if (isalnum(c)) { + + small_type val; // Numeric value of a char. + + if (isalpha(c)) // Hex digit. + val = toupper(c) - 'A' + 10; + else + val = c - '0'; + + if (val >= b) { + char msg[BUFSIZ]; + std::sprintf( msg, + "vec_from_str( int, int, sc_digit*, const char*, sc_numrep base ) : " + "'%c' is not a valid digit in base %d", + *v, b ); + SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg ); + } + + // digit = digit * b + val; + vec_mul_small_on(und, u, b); + + if (val) + vec_add_small_on(und, u, val); + + } + else { + char msg[BUFSIZ]; + std::sprintf( msg, + "vec_from_str( int, int, sc_digit*, const char*, sc_numrep base ) : " + "'%c' is not a valid digit in base %d", + *v, b ); + SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg ); + } + } + + return convert_signed_SM_to_2C_to_SM(s, unb, und, u); +} + + +// All vec_ functions assume that the vector to hold the result, +// called w, has sufficient length to hold the result. For efficiency +// reasons, we do not test whether or not we are out of bounds. + +// Compute w = u + v, where w, u, and v are vectors. +// - ulen >= vlen +// - wlen >= sc_max(ulen, vlen) + 1 +void +vec_add(int ulen, const sc_digit *u, + int vlen, const sc_digit *v, + sc_digit *w) +{ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (u != NULL)); + assert((vlen > 0) && (v != NULL)); + assert(w != NULL); + assert(ulen >= vlen); +#endif + + const sc_digit *uend = (u + ulen); + const sc_digit *vend = (v + vlen); + + sc_digit carry = 0; // Also used as sum to save space. + + // Add along the shorter v. + while (v < vend) { + carry += (*u++) + (*v++); + (*w++) = carry & DIGIT_MASK; + carry >>= BITS_PER_DIGIT; + } + + // Propagate the carry. + while (carry && (u < uend)) { + carry = (*u++) + 1; + (*w++) = carry & DIGIT_MASK; + carry >>= BITS_PER_DIGIT; + } + + // Copy the rest of u to the result. + while (u < uend) + (*w++) = (*u++); + + // Propagate the carry if it is still 1. + if (carry) + (*w) = 1; + +} + + +// Compute u += v, where u and v are vectors. +// - ulen >= vlen +void +vec_add_on(int ulen, sc_digit *ubegin, + int vlen, const sc_digit *v) +{ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (ubegin != NULL)); + assert((vlen > 0) && (v != NULL)); + assert(ulen >= vlen); +#endif + + sc_digit *u = ubegin; + const sc_digit *uend = (u + ulen); + const sc_digit *vend = (v + vlen); + + sc_digit carry = 0; // Also used as sum to save space. + + // Add along the shorter v. + while (v < vend) { + carry += (*u) + (*v++); + (*u++) = carry & DIGIT_MASK; + carry >>= BITS_PER_DIGIT; + } + + // Propagate the carry. + while (carry && (u < uend)) { + carry = (*u) + 1; + (*u++) = carry & DIGIT_MASK; + carry >>= BITS_PER_DIGIT; + } + +#ifdef DEBUG_SYSTEMC + if( carry != 0 ) { + SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_, + "vec_add_on( int, sc_digit*, int, const " + "sc_digit* ) : " + "result of addition is wrapped around" ); + } +#endif + +} + + +// Compute u += v, where u and v are vectors. +// - ulen < vlen +void +vec_add_on2(int ulen, sc_digit *ubegin, + int +#ifdef DEBUG_SYSTEMC + vlen +#endif + , const sc_digit *v) +{ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (ubegin != NULL)); + assert((vlen > 0) && (v != NULL)); + assert(ulen < vlen); +#endif + + sc_digit *u = ubegin; + const sc_digit *uend = (u + ulen); + + sc_digit carry = 0; // Also used as sum to save space. + + // Add along the shorter u. + while (u < uend) { + carry += (*u) + (*v++); + (*u++) = carry & DIGIT_MASK; + carry >>= BITS_PER_DIGIT; + } + +#ifdef DEBUG_SYSTEMC + if( carry != 0 ) { + SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_, + "vec_add_on2( int, sc_digit*, int, const " + "sc_digit* ) : " + "result of addition is wrapped around" ); + } +#endif +} + + +// Compute w = u + v, where w and u are vectors, and v is a scalar. +void +vec_add_small(int ulen, const sc_digit *u, + sc_digit v, + sc_digit *w) +{ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (u != NULL)); + assert(w != NULL); +#endif + + const sc_digit *uend = (u + ulen); + + // Add along the shorter v. + sc_digit carry = (*u++) + v; + (*w++) = carry & DIGIT_MASK; + carry >>= BITS_PER_DIGIT; + + // Propagate the carry. + while (carry && (u < uend)) { + carry = (*u++) + 1; + (*w++) = carry & DIGIT_MASK; + carry >>= BITS_PER_DIGIT; + } + + // Copy the rest of u to the result. + while (u < uend) + (*w++) = (*u++); + + // Propagate the carry if it is still 1. + if (carry) + (*w) = 1; + +} + +// Compute u += v, where u is vectors, and v is a scalar. +void +vec_add_small_on(int ulen, sc_digit *u, sc_digit v) +{ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (u != NULL)); +#endif + + int i = 0; + + while (v && (i < ulen)) { + v += u[i]; + u[i++] = v & DIGIT_MASK; + v >>= BITS_PER_DIGIT; + } + +#ifdef DEBUG_SYSTEMC + if( v != 0 ) { + SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_, + "vec_add_small_on( int, sc_digit*, unsigned " + "long ) : " + "result of addition is wrapped around" ); + } +#endif + +} + +// Compute w = u - v, where w, u, and v are vectors. +// - ulen >= vlen +// - wlen >= sc_max(ulen, vlen) +void +vec_sub(int ulen, const sc_digit *u, + int vlen, const sc_digit *v, + sc_digit *w) +{ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (u != NULL)); + assert((vlen > 0) && (v != NULL)); + assert(w != NULL); + assert(ulen >= vlen); +#endif + + const sc_digit *uend = (u + ulen); + const sc_digit *vend = (v + vlen); + + sc_digit borrow = 0; // Also used as diff to save space. + + // Subtract along the shorter v. + while (v < vend) { + borrow = ((*u++) + DIGIT_RADIX) - (*v++) - borrow; + (*w++) = borrow & DIGIT_MASK; + borrow = 1 - (borrow >> BITS_PER_DIGIT); + } + + // Propagate the borrow. + while (borrow && (u < uend)) { + borrow = ((*u++) + DIGIT_RADIX) - 1; + (*w++) = borrow & DIGIT_MASK; + borrow = 1 - (borrow >> BITS_PER_DIGIT); + } + +#ifdef DEBUG_SYSTEMC + assert(borrow == 0); +#endif + + // Copy the rest of u to the result. + while (u < uend) + (*w++) = (*u++); + +} + +// Compute u = u - v, where u and v are vectors. +// - u > v +// - ulen >= vlen +void +vec_sub_on(int ulen, sc_digit *ubegin, + int vlen, const sc_digit *v) +{ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (ubegin != NULL)); + assert((vlen > 0) && (v != NULL)); + assert(ulen >= vlen); +#endif + + sc_digit *u = ubegin; + const sc_digit *uend = (u + ulen); + const sc_digit *vend = (v + vlen); + + sc_digit borrow = 0; // Also used as diff to save space. + + // Subtract along the shorter v. + while (v < vend) { + borrow = ((*u) + DIGIT_RADIX) - (*v++) - borrow; + (*u++) = borrow & DIGIT_MASK; + borrow = 1 - (borrow >> BITS_PER_DIGIT); + } + + // Propagate the borrow. + while (borrow && (u < uend)) { + borrow = ((*u) + DIGIT_RADIX) - 1; + (*u++) = borrow & DIGIT_MASK; + borrow = 1 - (borrow >> BITS_PER_DIGIT); + } + +#ifdef DEBUG_SYSTEMC + assert(borrow == 0); +#endif + +} + +// Compute u = v - u, where u and v are vectors. +// - v > u +// - ulen <= vlen or ulen > ulen +void +vec_sub_on2(int ulen, sc_digit *ubegin, + int vlen, const sc_digit *v) +{ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (ubegin != NULL)); + assert((vlen > 0) && (v != NULL)); +#endif + + sc_digit *u = ubegin; + const sc_digit *uend = (u + sc_min(ulen, vlen)); + + sc_digit borrow = 0; // Also used as diff to save space. + + // Subtract along the shorter u. + while (u < uend) { + borrow = ((*v++) + DIGIT_RADIX) - (*u) - borrow; + (*u++) = borrow & DIGIT_MASK; + borrow = 1 - (borrow >> BITS_PER_DIGIT); + } + +#ifdef DEBUG_SYSTEMC + if( borrow != 0 ) { + SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_, + "vec_sub_on2( int, sc_digit*, int, const " + "sc_digit* ) : " + "result of subtraction is wrapped around" ); + } +#endif +} + +// Compute w = u - v, where w and u are vectors, and v is a scalar. +void +vec_sub_small(int ulen, const sc_digit *u, + sc_digit v, + sc_digit *w) +{ + +#ifdef DEBUG_SYSTEMC + assert(ulen > 0); + assert(u != NULL); +#endif + + const sc_digit *uend = (u + ulen); + + // Add along the shorter v. + sc_digit borrow = ((*u++) + DIGIT_RADIX) - v; + (*w++) = borrow & DIGIT_MASK; + borrow = 1 - (borrow >> BITS_PER_DIGIT); + + // Propagate the borrow. + while (borrow && (u < uend)) { + borrow = ((*u++) + DIGIT_RADIX) - 1; + (*w++) = borrow & DIGIT_MASK; + borrow = 1 - (borrow >> BITS_PER_DIGIT); + } + +#ifdef DEBUG_SYSTEMC + assert(borrow == 0); +#endif + + // Copy the rest of u to the result. + while (u < uend) + (*w++) = (*u++); + +} + + +// Compute u -= v, where u is vectors, and v is a scalar. +void +vec_sub_small_on(int ulen, sc_digit *u, sc_digit v) +{ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (u != NULL)); +#endif + + for (int i = 0; i < ulen; ++i) { + v = (u[i] + DIGIT_RADIX) - v; + u[i] = v & DIGIT_MASK; + v = 1 - (v >> BITS_PER_DIGIT); + } + +#ifdef DEBUG_SYSTEMC + assert(v == 0); +#endif + +} + +// Compute w = u * v, where w, u, and v are vectors. +void +vec_mul(int ulen, const sc_digit *u, + int vlen, const sc_digit *vbegin, + sc_digit *wbegin) +{ + + /* Consider u = Ax + B and v = Cx + D where x is equal to + HALF_DIGIT_RADIX. In other words, A is the higher half of u and + B is the lower half of u. The interpretation for v is + similar. Then, we have the following picture: + + u_h u_l + u: -------- -------- + A B + + v_h v_l + v: -------- -------- + C D + + result (d): + carry_before: -------- -------- + carry_h carry_l + result_before: -------- -------- -------- -------- + R1_h R1_l R0_h R0_l + -------- -------- + BD_h BD_l + -------- -------- + AD_h AD_l + -------- -------- + BC_h BC_l + -------- -------- + AC_h AC_l + result_after: -------- -------- -------- -------- + R1_h' R1_l' R0_h' R0_l' + + prod_l = R0_h|R0_l + B * D + 0|carry_l + = R0_h|R0_l + BD_h|BD_l + 0|carry_l + + prod_h = A * D + B * C + high_half(prod_l) + carry_h + = AD_h|AD_l + BC_h|BC_l + high_half(prod_l) + 0|carry_h + + carry = A * C + high_half(prod_h) + = AC_h|AC_l + high_half(prod_h) + + R0_l' = low_half(prod_l) + + R0_h' = low_half(prod_h) + + R0 = high_half(prod_h)|low_half(prod_l) + + where '|' is the concatenation operation and the suffixes 0 and 1 + show the iteration number, i.e., 0 is the current iteration and 1 + is the next iteration. + + NOTE: sc_max(prod_l, prod_h, carry) <= 2 * x^2 - 1, so any + of these numbers can be stored in a digit. + + NOTE: low_half(u) returns the lower BITS_PER_HALF_DIGIT of u, + whereas high_half(u) returns the rest of the bits, which may + contain more bits than BITS_PER_HALF_DIGIT. + */ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (u != NULL)); + assert((vlen > 0) && (vbegin != NULL)); + assert(wbegin != NULL); +#endif + +#define prod_h carry + + const sc_digit *uend = (u + ulen); + const sc_digit *vend = (vbegin + vlen); + + while (u < uend) { + + sc_digit u_h = (*u++); // A|B + sc_digit u_l = low_half(u_h); // B + u_h = high_half(u_h); // A + +#ifdef DEBUG_SYSTEMC + // The overflow bits must be zero. + assert(u_h == (u_h & HALF_DIGIT_MASK)); +#endif + + sc_digit carry = 0; + + sc_digit *w = (wbegin++); + + const sc_digit *v = vbegin; + + while (v < vend) { + + sc_digit v_h = (*v++); // C|D + sc_digit v_l = low_half(v_h); // D + + v_h = high_half(v_h); // C + +#ifdef DEBUG_SYSTEMC + // The overflow bits must be zero. + assert(v_h == (v_h & HALF_DIGIT_MASK)); +#endif + + sc_digit prod_l = (*w) + u_l * v_l + low_half(carry); + + prod_h = u_h * v_l + u_l * v_h + high_half(prod_l) + high_half(carry); + + (*w++) = concat(low_half(prod_h), low_half(prod_l)); + + carry = u_h * v_h + high_half(prod_h); + + } + + (*w) = carry; + + } + +#undef prod_h + +} + +// Compute w = u * v, where w and u are vectors, and v is a scalar. +// - 0 < v < HALF_DIGIT_RADIX. +void +vec_mul_small(int ulen, const sc_digit *u, + sc_digit v, sc_digit *w) +{ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (u != NULL)); + assert(w != NULL); + assert((0 < v) && (v < HALF_DIGIT_RADIX)); +#endif + +#define prod_h carry + + const sc_digit *uend = (u + ulen); + + sc_digit carry = 0; + + while (u < uend) { + + sc_digit u_AB = (*u++); + +#ifdef DEBUG_SYSTEMC + // The overflow bits must be zero. + assert(high_half(u_AB) == high_half_masked(u_AB)); +#endif + + sc_digit prod_l = v * low_half(u_AB) + low_half(carry); + + prod_h = v * high_half(u_AB) + high_half(prod_l) + high_half(carry); + + (*w++) = concat(low_half(prod_h), low_half(prod_l)); + + carry = high_half(prod_h); + + } + + (*w) = carry; + +#undef prod_h + +} + +// Compute u = u * v, where u is a vector, and v is a scalar. +// - 0 < v < HALF_DIGIT_RADIX. +void +vec_mul_small_on(int ulen, sc_digit *u, sc_digit v) +{ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (u != NULL)); + assert((0 < v) && (v < HALF_DIGIT_RADIX)); +#endif + +#define prod_h carry + + sc_digit carry = 0; + + for (int i = 0; i < ulen; ++i) { + +#ifdef DEBUG_SYSTEMC + // The overflow bits must be zero. + assert(high_half(u[i]) == high_half_masked(u[i])); +#endif + + sc_digit prod_l = v * low_half(u[i]) + low_half(carry); + + prod_h = v * high_half(u[i]) + high_half(prod_l) + high_half(carry); + + u[i] = concat(low_half(prod_h), low_half(prod_l)); + + carry = high_half(prod_h); + + } + +#undef prod_h + +#ifdef DEBUG_SYSTEMC + if( carry != 0 ) { + SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_, + "vec_mul_small_on( int, sc_digit*, unsigned " + "long ) : " + "result of multiplication is wrapped around" ); + } +#endif +} + +// Compute w = u / v, where w, u, and v are vectors. +// - u and v are assumed to have at least two digits as uchars. +void +vec_div_large(int ulen, const sc_digit *u, + int vlen, const sc_digit *v, + sc_digit *w) +{ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (u != NULL)); + assert((vlen > 0) && (v != NULL)); + assert(w != NULL); + assert(BITS_PER_DIGIT >= 3 * BITS_PER_BYTE); +#endif + + // We will compute q = x / y where x = u and y = v. The reason for + // using x and y is that x and y are BYTE_RADIX copies of u and v, + // respectively. The use of BYTE_RADIX radix greatly simplifies the + // complexity of the division operation. These copies are also + // needed even when we use DIGIT_RADIX representation. + + int xlen = BYTES_PER_DIGIT * ulen + 1; + int ylen = BYTES_PER_DIGIT * vlen; + +#ifdef SC_MAX_NBITS + uchar x[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)]; + uchar y[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)]; + uchar q[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)]; +#else + uchar *x = new uchar[xlen]; + uchar *y = new uchar[ylen]; + // valgrind complains about us accessing too far to so leave a buffer. + uchar *q = new uchar[(xlen - ylen) + 10]; +#endif + + // q corresponds to w. + + // Set (uchar) x = (sc_digit) u. + xlen = vec_to_char(ulen, u, xlen, x); + + // Skip all the leading zeros in x. + while ((--xlen >= 0) && (! x[xlen])) continue; + xlen++; + + // Set (uchar) y = (sc_digit) v. + ylen = vec_to_char(vlen, v, ylen, y); + + // Skip all the leading zeros in y. + while ((--ylen >= 0) && (! y[ylen])) continue; + ylen++; + +#ifdef DEBUG_SYSTEMC + assert(xlen > 1); + assert(ylen > 1); +#endif + + // At this point, all the leading zeros are eliminated from x and y. + + // Zero the last digit of x. + x[xlen] = 0; + + // The first two digits of y. + sc_digit y2 = (y[ylen - 1] << BITS_PER_BYTE) + y[ylen - 2]; + + const sc_digit DOUBLE_BITS_PER_BYTE = 2 * BITS_PER_BYTE; + + // Find each q[k]. + for (int k = (xlen - ylen); k >= 0; --k) { + + // qk is a guess for q[k] such that q[k] = qk or qk - 1. + sc_digit qk; + + // Find qk by just using 2 digits of y and 3 digits of x. The + // following code assumes that sizeof(sc_digit) >= 3 BYTEs. + int k2 = k + ylen; + + qk = ((x[k2] << DOUBLE_BITS_PER_BYTE) + + (x[k2 - 1] << BITS_PER_BYTE) + x[k2 - 2]) / y2; + + if (qk >= BYTE_RADIX) // qk cannot be larger than the largest + qk = BYTE_RADIX - 1; // digit in BYTE_RADIX. + + // q[k] = qk or qk - 1. The following if-statement determines which: + if (qk) { + + uchar *xk = (x + k); // A shortcut for x[k]. + + // x = x - y * qk : + sc_digit carry = 0; + + for (int i = 0; i < ylen; ++i) { + carry += y[i] * qk; + sc_digit diff = (xk[i] + BYTE_RADIX) - (carry & BYTE_MASK); + xk[i] = (uchar)(diff & BYTE_MASK); + carry = (carry >> BITS_PER_BYTE) + (1 - (diff >> BITS_PER_BYTE)); + } + + // If carry, qk may be one too large. + if (carry) { + + // 2's complement the last digit. + carry = (xk[ylen] + BYTE_RADIX) - carry; + xk[ylen] = (uchar)(carry & BYTE_MASK); + carry = 1 - (carry >> BITS_PER_BYTE); + + if (carry) { + + // qk was one too large, so decrement it. + --qk; + + // Since qk was decreased by one, y must be added to x: + // That is, x = x - y * (qk - 1) = x - y * qk + y = x_above + y. + carry = 0; + + for (int i = 0; i < ylen; ++i) { + carry += xk[i] + y[i]; + xk[i] = (uchar)(carry & BYTE_MASK); + carry >>= BITS_PER_BYTE; + } + + if (carry) + xk[ylen] = (uchar)((xk[ylen] + 1) & BYTE_MASK); + + } // second if carry + } // first if carry + } // if qk + + q[k] = (uchar)qk; + + } // for k + + // Set (sc_digit) w = (uchar) q. + vec_from_char(xlen - ylen + 1, q, ulen, w); + +#ifndef SC_MAX_NBITS + delete [] x; + delete [] y; + delete [] q; +#endif + +} + +// Compute w = u / v, where u and w are vectors, and v is a scalar. +// - 0 < v < HALF_DIGIT_RADIX. Below, we rename w to q. +void +vec_div_small(int ulen, const sc_digit *u, + sc_digit v, sc_digit *q) +{ + + // Given (u = u_1u_2...u_n)_b = (q = q_1q_2...q_n) * v + r, where b + // is the base, and 0 <= r < v. Then, the algorithm is as follows: + // + // r = 0; + // for (j = 1; j <= n; j++) { + // q_j = (r * b + u_j) / v; + // r = (r * b + u_j) % v; + // } + // + // In our case, b = DIGIT_RADIX, and u = Ax + B and q = Cx + D where + // x = HALF_DIGIT_RADIX. Note that r < v < x and b = x^2. Then, a + // typical situation is as follows: + // + // ---- ---- + // 0 r + // ---- ---- + // A B + // ---- ---- ---- + // r A B = r * b + u + // + // Hence, C = (r|A) / v. + // D = (((r|A) % v)|B) / v + // r = (((r|A) % v)|B) % v + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (u != NULL)); + assert(q != NULL); + assert((0 < v) && (v < HALF_DIGIT_RADIX)); +#endif + +#define q_h r + + sc_digit r = 0; + const sc_digit *ubegin = u; + + u += ulen; + q += ulen; + + while (ubegin < u) { + + sc_digit u_AB = (*--u); // A|B + +#ifdef DEBUG_SYSTEMC + // The overflow bits must be zero. + assert(high_half(u_AB) == high_half_masked(u_AB)); +#endif + + sc_digit num = concat(r, high_half(u_AB)); // num = r|A + q_h = num / v; // C + num = concat((num % v), low_half(u_AB)); // num = (((r|A) % v)|B) + (*--q) = concat(q_h, num / v); // q = C|D + r = num % v; + + } + +#undef q_h + +} + +// Compute w = u % v, where w, u, and v are vectors. +// - u and v are assumed to have at least two digits as uchars. +void +vec_rem_large(int ulen, const sc_digit *u, + int vlen, const sc_digit *v, + sc_digit *w) +{ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (u != NULL)); + assert((vlen > 0) && (v != NULL)); + assert(w != NULL); + assert(BITS_PER_DIGIT >= 3 * BITS_PER_BYTE); +#endif + + // This function is adapted from vec_div_large. + + int xlen = BYTES_PER_DIGIT * ulen + 1; + int ylen = BYTES_PER_DIGIT * vlen; + +#ifdef SC_MAX_NBITS + uchar x[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)]; + uchar y[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)]; +#else + uchar *x = new uchar[xlen]; + uchar *y = new uchar[ylen]; +#endif + + // r corresponds to w. + + // Set (uchar) x = (sc_digit) u. + xlen = vec_to_char(ulen, u, xlen, x); + + // Skip all the leading zeros in x. + while ((--xlen >= 0) && (! x[xlen])) continue; + xlen++; + + // Set (uchar) y = (sc_digit) v. + ylen = vec_to_char(vlen, v, ylen, y); + + // Skip all the leading zeros in y. + while ((--ylen >= 0) && (! y[ylen])) continue; + ylen++; + +#ifdef DEBUG_SYSTEMC + assert(xlen > 1); + assert(ylen > 1); +#endif + + // At this point, all the leading zeros are eliminated from x and y. + + // Zero the last digit of x. + x[xlen] = 0; + + // The first two digits of y. + sc_digit y2 = (y[ylen - 1] << BITS_PER_BYTE) + y[ylen - 2]; + + const sc_digit DOUBLE_BITS_PER_BYTE = 2 * BITS_PER_BYTE; + + // Find each q[k]. + for (int k = xlen - ylen; k >= 0; --k) { + + // qk is a guess for q[k] such that q[k] = qk or qk - 1. + sc_digit qk; + + // Find qk by just using 2 digits of y and 3 digits of x. The + // following code assumes that sizeof(sc_digit) >= 3 BYTEs. + int k2 = k + ylen; + + qk = ((x[k2] << DOUBLE_BITS_PER_BYTE) + + (x[k2 - 1] << BITS_PER_BYTE) + x[k2 - 2]) / y2; + + if (qk >= BYTE_RADIX) // qk cannot be larger than the largest + qk = BYTE_RADIX - 1; // digit in BYTE_RADIX. + + // q[k] = qk or qk - 1. The following if-statement determines which. + if (qk) { + + uchar *xk = (x + k); // A shortcut for x[k]. + + // x = x - y * qk; + sc_digit carry = 0; + + for (int i = 0; i < ylen; ++i) { + carry += y[i] * qk; + sc_digit diff = (xk[i] + BYTE_RADIX) - (carry & BYTE_MASK); + xk[i] = (uchar)(diff & BYTE_MASK); + carry = (carry >> BITS_PER_BYTE) + (1 - (diff >> BITS_PER_BYTE)); + } + + if (carry) { + + // 2's complement the last digit. + carry = (xk[ylen] + BYTE_RADIX) - carry; + xk[ylen] = (uchar)(carry & BYTE_MASK); + carry = 1 - (carry >> BITS_PER_BYTE); + + if (carry) { + + // qk was one too large, so decrement it. + // --qk; + + // x = x - y * (qk - 1) = x - y * qk + y = x_above + y. + carry = 0; + + for (int i = 0; i < ylen; ++i) { + carry += xk[i] + y[i]; + xk[i] = (uchar)(carry & BYTE_MASK); + carry >>= BITS_PER_BYTE; + } + + if (carry) + xk[ylen] = (uchar)((xk[ylen] + 1) & BYTE_MASK); + + } // second if carry + } // first if carry + } // if qk + } // for k + + // Set (sc_digit) w = (uchar) x for the remainder. + vec_from_char(ylen, x, ulen, w); + +#ifndef SC_MAX_NBITS + delete [] x; + delete [] y; +#endif + +} + +// Compute r = u % v, where u is a vector, and r and v are scalars. +// - 0 < v < HALF_DIGIT_RADIX. +// - The remainder r is returned. +sc_digit +vec_rem_small(int ulen, const sc_digit *u, sc_digit v) +{ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (u != NULL)); + assert((0 < v) && (v < HALF_DIGIT_RADIX)); +#endif + + // This function is adapted from vec_div_small(). + + sc_digit r = 0; + const sc_digit *ubegin = u; + + u += ulen; + + while (ubegin < u) { + sc_digit u_AB = (*--u); // A|B + +#ifdef DEBUG_SYSTEMC + // The overflow bits must be zero. + assert(high_half(u_AB) == high_half_masked(u_AB)); +#endif + + // r = (((r|A) % v)|B) % v + r = (concat(((concat(r, high_half(u_AB))) % v), low_half(u_AB))) % v; + } + + return r; + +} + +// u = u / v, r = u % v. +sc_digit +vec_rem_on_small(int ulen, sc_digit *u, sc_digit v) +{ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (u != NULL)); + assert(v > 0); +#endif + +#define q_h r + + sc_digit r = 0; + const sc_digit *ubegin = u; + + u += ulen; + + while (ubegin < u) { + + sc_digit u_AB = (*--u); // A|B + +#ifdef DEBUG_SYSTEMC + // The overflow bits must be zero. + assert(high_half(u_AB) == high_half_masked(u_AB)); +#endif + + sc_digit num = concat(r, high_half(u_AB)); // num = r|A + q_h = num / v; // C + num = concat((num % v), low_half(u_AB)); // num = (((r|A) % v)|B) + (*u) = concat(q_h, num / v); // q = C|D + r = num % v; + + } + +#undef q_h + + return r; + +} + +// Set (uchar) v = (sc_digit) u. Return the new vlen. +int +vec_to_char(int ulen, const sc_digit *u, + int vlen, uchar *v) +{ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (u != NULL)); + assert((vlen > 0) && (v != NULL)); +#endif + + int nbits = ulen * BITS_PER_DIGIT; + + int right = 0; + int left = right + BITS_PER_BYTE - 1; + + vlen = 0; + + while (nbits > 0) { + + int left_digit = left / BITS_PER_DIGIT; + int right_digit = right / BITS_PER_DIGIT; + + int nsr = ((vlen << LOG2_BITS_PER_BYTE) % BITS_PER_DIGIT); + + int d = u[right_digit] >> nsr; + + if (left_digit != right_digit) { + + if (left_digit < ulen) + d |= u[left_digit] << (BITS_PER_DIGIT - nsr); + + } + + v[vlen++] = (uchar)(d & BYTE_MASK); + + left += BITS_PER_BYTE; + right += BITS_PER_BYTE; + nbits -= BITS_PER_BYTE; + + } + + return vlen; + +} + +// Set (sc_digit) v = (uchar) u. +// - sizeof(uchar) <= sizeof(sc_digit), +void +vec_from_char(int ulen, const uchar *u, + int vlen, sc_digit *v) +{ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (u != NULL)); + assert((vlen > 0) && (v != NULL)); + assert(sizeof(uchar) <= sizeof(sc_digit)); +#endif + + sc_digit *vend = (v + vlen); + + const int nsr = BITS_PER_DIGIT - BITS_PER_BYTE; + const sc_digit mask = one_and_ones(nsr); + + (*v) = (sc_digit) u[ulen - 1]; + + for (int i = ulen - 2; i >= 0; --i) { + + // Manual inlining of vec_shift_left(). + + sc_digit *viter = v; + + sc_digit carry = 0; + + while (viter < vend) { + sc_digit vval = (*viter); + (*viter++) = (((vval & mask) << BITS_PER_BYTE) | carry); + carry = vval >> nsr; + } + + if (viter < vend) + (*viter) = carry; + + (*v) |= (sc_digit) u[i]; + + } + +} + +// Set u <<= nsl. +// If nsl is negative, it is ignored. +void +vec_shift_left(int ulen, sc_digit *u, int nsl) +{ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (u != NULL)); +#endif + + if (nsl <= 0) + return; + + // Shift left whole digits if nsl is large enough. + if (nsl >= (int) BITS_PER_DIGIT) { + + int nd; + + if (nsl % BITS_PER_DIGIT == 0) { + nd = nsl / BITS_PER_DIGIT; // No need to use DIV_CEIL(nsl). + nsl = 0; + } + else { + nd = DIV_CEIL(nsl) - 1; + nsl -= nd * BITS_PER_DIGIT; + } + + if (nd) { + + // Shift left for nd digits. + for (int j = ulen - 1; j >= nd; --j) + u[j] = u[j - nd]; + + vec_zero( sc_min( nd, ulen ), u ); + + } + + if (nsl == 0) + return; + + } + + // Shift left if nsl < BITS_PER_DIGIT. + sc_digit *uiter = u; + sc_digit *uend = uiter + ulen; + + int nsr = BITS_PER_DIGIT - nsl; + sc_digit mask = one_and_ones(nsr); + + sc_digit carry = 0; + + while (uiter < uend) { + sc_digit uval = (*uiter); + (*uiter++) = (((uval & mask) << nsl) | carry); + carry = uval >> nsr; + } + + if (uiter < uend) + (*uiter) = carry; + +} + +// Set u >>= nsr. +// If nsr is negative, it is ignored. +void +vec_shift_right(int ulen, sc_digit *u, int nsr, sc_digit fill) +{ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (u != NULL)); +#endif + + // fill is usually either 0 or DIGIT_MASK; it can be any value. + + if (nsr <= 0) + return; + + // Shift right whole digits if nsr is large enough. + if (nsr >= (int) BITS_PER_DIGIT) { + + int nd; + + if (nsr % BITS_PER_DIGIT == 0) { + nd = nsr / BITS_PER_DIGIT; + nsr = 0; + } + else { + nd = DIV_CEIL(nsr) - 1; + nsr -= nd * BITS_PER_DIGIT; + } + + if (nd) { + + // Shift right for nd digits. + for (int j = 0; j < (ulen - nd); ++j) + u[j] = u[j + nd]; + + if (fill) { + for (int j = ulen - sc_min( nd, ulen ); j < ulen; ++j) + u[j] = fill; + } + else + vec_zero(ulen - sc_min( nd, ulen ), ulen, u); + + } + + if (nsr == 0) + return; + + } + + // Shift right if nsr < BITS_PER_DIGIT. + sc_digit *ubegin = u; + sc_digit *uiter = (ubegin + ulen); + + int nsl = BITS_PER_DIGIT - nsr; + sc_digit mask = one_and_ones(nsr); + + sc_digit carry = (fill & mask) << nsl; + + while (ubegin < uiter) { + sc_digit uval = (*--uiter); + (*uiter) = (uval >> nsr) | carry; + carry = (uval & mask) << nsl; + } + +} + + +// Let u[l..r], where l and r are left and right bit positions +// respectively, be equal to its mirror image. +void +vec_reverse(int unb, int und, sc_digit *ud, + int l, int r) +{ + +#ifdef DEBUG_SYSTEMC + assert((unb > 0) && (und > 0) && (ud != NULL)); + assert((0 <= r) && (r <= l) && (l < unb)); +#endif + + if (l < r) { + char msg[BUFSIZ]; + std::sprintf( msg, "vec_reverse( int, int, sc_digit*, int l, int r ) : " + "l = %d < r = %d is not valid", + l, r ); + SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg ); + } + + // Make sure that l and r are within bounds. + r = sc_max(r, 0); + l = sc_min(l, unb - 1); + + // Allocate memory for processing. +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS]; +#else + sc_digit *d = new sc_digit[und]; +#endif + + // d is a copy of ud. + vec_copy(und, d, ud); + + // Based on the value of the ith in d, find the value of the jth bit + // in ud. + + for (int i = l, j = r; i >= r; --i, ++j) { + + if ((d[digit_ord(i)] & one_and_zeros(bit_ord(i))) != 0) // Test. + ud[digit_ord(j)] |= one_and_zeros(bit_ord(j)); // Set. + else + ud[digit_ord(j)] &= ~(one_and_zeros(bit_ord(j))); // Clear. + + } + +#ifndef SC_MAX_NBITS + delete [] d; +#endif + +} + +} // namespace sc_dt + + +// End of file. diff --git a/ext/systemc/src/sysc/datatypes/int/sc_nbutils.h b/ext/systemc/src/sysc/datatypes/int/sc_nbutils.h new file mode 100644 index 000000000..0bd4b4b03 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_nbutils.h @@ -0,0 +1,1051 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_nbutils.h -- External and friend functions for both sc_signed and + sc_unsigned classes. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_nbutils.h,v $ +// Revision 1.6 2011/09/08 16:12:15 acg +// Philipp A. Hartmann: fix issue with Sun machines wrt real math libraries. +// +// Revision 1.5 2011/08/26 23:00:01 acg +// Torsten Maehne: remove use of ieeefp.h. +// +// Revision 1.4 2011/08/15 16:43:24 acg +// Torsten Maehne: changes to remove unused argument warnings. +// +// Revision 1.3 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.2 2010/09/06 16:35:48 acg +// Andy Goodrich: changed i386 to __i386__ in ifdef's. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:32 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef SC_NBUTILS_H +#define SC_NBUTILS_H + +#include <cmath> +#include <limits> + +#include "sysc/datatypes/bit/sc_bit_ids.h" +#include "sysc/datatypes/int/sc_int_ids.h" +#include "sysc/datatypes/int/sc_nbdefs.h" +#include "sysc/utils/sc_report.h" + + +namespace sc_dt +{ + +//----------------------------------------------------------------------------- +//"sc_io_base" +// +// This inline function returns the type of an i/o stream's base as a SystemC +// base designator. +// stream_object = reference to the i/o stream whose base is to be returned. +// +//"sc_io_show_base" +// +// This inline function returns true if the base should be shown when a SystemC +// value is displayed via the supplied stream operator. +// stream_object = reference to the i/o stream to return showbase value for. +//----------------------------------------------------------------------------- +#if defined(__GNUC__) || defined(_MSC_VER) || defined(__SUNPRO_CC) + inline sc_numrep + sc_io_base( systemc_ostream& os, sc_numrep def_base ) + { + std::ios::fmtflags flags = os.flags() & std::ios::basefield; + if ( flags & ::std::ios::dec ) return SC_DEC; + if ( flags & ::std::ios::hex ) return SC_HEX; + if ( flags & ::std::ios::oct ) return SC_OCT; + return def_base; + } + + inline bool + sc_io_show_base( systemc_ostream& os ) + { + return (os.flags() & ::std::ios::showbase) != 0 ; + } +#else // Other + inline sc_numrep + sc_io_base( systemc_ostream& /*unused*/, sc_numrep /*unused*/ ) + { + return SC_DEC; + } + inline bool + sc_io_show_base( systemc_ostream& /*unused*/ ) + { + return false; + } +#endif + +const std::string to_string( sc_numrep ); + +inline +systemc_ostream& +operator << ( systemc_ostream& os, sc_numrep numrep ) +{ + os << to_string( numrep ); + return os; +} + +// only used within vec_from_str (non-standard, deprecated) +inline void +is_valid_base(sc_numrep base) +{ + switch (base) { + case SC_NOBASE: case SC_BIN: + case SC_OCT: case SC_DEC: + case SC_HEX: + break; + case SC_BIN_US: case SC_BIN_SM: + case SC_OCT_US: case SC_OCT_SM: + case SC_HEX_US: case SC_HEX_SM: + case SC_CSD: + SC_REPORT_ERROR( sc_core::SC_ID_NOT_IMPLEMENTED_, + "is_valid_base( sc_numrep base ) : " + "bases SC_CSD, or ending in _US and _SM are not supported" ); + break; + default: + char msg[BUFSIZ]; + std::sprintf( msg, "is_valid_base( sc_numrep base ) : " + "base = %s is not valid", + to_string( base ).c_str() ); + SC_REPORT_ERROR( sc_core::SC_ID_VALUE_NOT_VALID_, msg ); + } +} + +// ---------------------------------------------------------------------------- + +// One transition of the FSM to find base and sign of a number. +extern +small_type +fsm_move(char c, small_type &b, small_type &s, small_type &state); + +// Parse a character string into its equivalent binary bits. +extern +void parse_binary_bits( + const char* src_p, int dst_n, sc_digit* data_p, sc_digit* ctrl_p=0 +); + + +// Parse a character string into its equivalent hexadecimal bits. +extern +void parse_hex_bits( + const char* src_p, int dst_n, sc_digit* data_p, sc_digit* ctrl_p=0 +); + + +// Find the base and sign of a number in v. +extern +const char * +get_base_and_sign(const char *v, small_type &base, small_type &sign); + +// Create a number out of v in base. +extern +small_type +vec_from_str(int unb, int und, sc_digit *u, + const char *v, sc_numrep base = SC_NOBASE) ; + + +// ---------------------------------------------------------------------------- +// Naming convention for the vec_ functions below: +// vec_OP(u, v, w) : computes w = u OP v. +// vec_OP_on(u, v) : computes u = u OP v if u has more digits than v. +// vec_OP_on2(u, v) : computes u = u OP v if u has fewer digits than v. +// _large : parameters are vectors. +// _small : one of the parameters is a single digit. +// Xlen : the number of digits in X. +// ---------------------------------------------------------------------------- + +// ---------------------------------------------------------------------------- +// Functions for vector addition: w = u + v or u += v. +// ---------------------------------------------------------------------------- + +extern +void +vec_add(int ulen, const sc_digit *u, + int vlen, const sc_digit *v, sc_digit *w); + +extern +void +vec_add_on(int ulen, sc_digit *u, + int vlen, const sc_digit *v); + +extern +void +vec_add_on2(int ulen, sc_digit *u, + int vlen, const sc_digit *v); + +extern +void +vec_add_small(int ulen, const sc_digit *u, + sc_digit v, sc_digit *w); + +extern +void +vec_add_small_on(int ulen, sc_digit *u, sc_digit v); + + +// ---------------------------------------------------------------------------- +// Functions for vector subtraction: w = u - v, u -= v, or u = v - u. +// ---------------------------------------------------------------------------- + +extern +void +vec_sub(int ulen, const sc_digit *u, + int vlen, const sc_digit *v, sc_digit *w); + +extern +void +vec_sub_on(int ulen, sc_digit *u, + int vlen, const sc_digit *v); + +extern +void +vec_sub_on2(int ulen, sc_digit *u, + int vlen, const sc_digit *v); + +extern +void +vec_sub_small(int ulen, const sc_digit *u, + sc_digit v, sc_digit *w); + +extern +void +vec_sub_small_on(int ulen, sc_digit *u, sc_digit v); + + +// ---------------------------------------------------------------------------- +// Functions for vector multiplication: w = u * v or u *= v. +// ---------------------------------------------------------------------------- + +extern +void +vec_mul(int ulen, const sc_digit *u, + int vlen, const sc_digit *v, sc_digit *w); + +extern +void +vec_mul_small(int ulen, const sc_digit *u, + sc_digit v, sc_digit *w); + +extern +void +vec_mul_small_on(int ulen, sc_digit *u, sc_digit v); + + +// ---------------------------------------------------------------------------- +// Functions for vector division: w = u / v. +// ---------------------------------------------------------------------------- + +extern +void +vec_div_large(int ulen, const sc_digit *u, + int vlen, const sc_digit *v, sc_digit *w); + +extern +void +vec_div_small(int ulen, const sc_digit *u, + sc_digit v, sc_digit *w); + + +// ---------------------------------------------------------------------------- +// Functions for vector remainder: w = u % v or u %= v. +// ---------------------------------------------------------------------------- + +extern +void +vec_rem_large(int ulen, const sc_digit *u, + int vlen, const sc_digit *v, sc_digit *w); + +extern +sc_digit +vec_rem_small(int ulen, const sc_digit *u, sc_digit v); + +extern +sc_digit +vec_rem_on_small(int ulen, sc_digit *u, sc_digit v); + + +// ---------------------------------------------------------------------------- +// Functions to convert between vectors of char and sc_digit. +// ---------------------------------------------------------------------------- + +extern +int +vec_to_char(int ulen, const sc_digit *u, + int vlen, uchar *v); + +extern +void +vec_from_char(int ulen, const uchar *u, + int vlen, sc_digit *v); + + +// ---------------------------------------------------------------------------- +// Functions to shift left or right, or to create a mirror image of vectors. +// ---------------------------------------------------------------------------- + +extern +void +vec_shift_left(int ulen, sc_digit *u, int nsl); + +extern +void +vec_shift_right(int vlen, sc_digit *u, int nsr, sc_digit fill = 0); + +extern +void +vec_reverse(int unb, int und, sc_digit *ud, + int l, int r = 0); + + +// ---------------------------------------------------------------------------- +// Various utility functions. +// ---------------------------------------------------------------------------- + +// Return the low half part of d. +inline +sc_digit +low_half(sc_digit d) +{ + return (d & HALF_DIGIT_MASK); +} + +// Return the high half part of d. The high part of the digit may have +// more bits than BITS_PER_HALF_DIGIT due to, e.g., overflow in the +// multiplication. Hence, in other functions that use high_half(), +// make sure that the result contains BITS_PER_HALF_DIGIT if +// necessary. This is done by high_half_masked(). +inline +sc_digit +high_half(sc_digit d) +{ + return (d >> BITS_PER_HALF_DIGIT); +} + +inline +sc_digit +high_half_masked(sc_digit d) +{ + return (high_half(d) & HALF_DIGIT_MASK); +} + +// Concatenate the high part h and low part l. Assumes that h and l +// are less than or equal to HALF_DIGIT_MASK; +inline +sc_digit +concat(sc_digit h, sc_digit l) +{ + return ((h << BITS_PER_HALF_DIGIT) | l); +} + +// Create a number with n 1's. +inline +sc_digit +one_and_ones(int n) +{ + return (((sc_digit) 1 << n) - 1); +} + +// Create a number with one 1 and n 0's. +inline +sc_digit +one_and_zeros(int n) +{ + return ((sc_digit) 1 << n); +} + + +// ---------------------------------------------------------------------------- + +// Find the digit that bit i is in. +inline +int +digit_ord(int i) +{ + return (i / BITS_PER_DIGIT); +} + +// Find the bit in digit_ord(i) that bit i corressponds to. +inline +int +bit_ord(int i) +{ + return (i % BITS_PER_DIGIT); +} + + +// ---------------------------------------------------------------------------- +// Functions to compare, zero, complement vector(s). +// ---------------------------------------------------------------------------- + +// Compare u and v and return r +// r = 0 if u == v +// r < 0 if u < v +// r > 0 if u > v +// - Assume that all the leading zero digits are already skipped. +// - ulen and/or vlen can be zero. +// - Every digit is less than or equal to DIGIT_MASK; +inline +int +vec_cmp(int ulen, const sc_digit *u, + int vlen, const sc_digit *v) +{ + +#ifdef DEBUG_SYSTEMC + // assert((ulen <= 0) || (u != NULL)); + // assert((vlen <= 0) || (v != NULL)); + + // ulen and vlen can be equal to 0 because vec_cmp can be called + // after vec_skip_leading_zeros. + assert((ulen >= 0) && (u != NULL)); + assert((vlen >= 0) && (v != NULL)); + // If ulen > 0, then the leading digit of u must be non-zero. + assert((ulen <= 0) || (u[ulen - 1] != 0)); + assert((vlen <= 0) || (v[vlen - 1] != 0)); +#endif + + if (ulen != vlen) + return (ulen - vlen); + + // ulen == vlen >= 1 + while ((--ulen >= 0) && (u[ulen] == v[ulen])) + ; + + if (ulen < 0) + return 0; + +#ifdef DEBUG_SYSTEMC + // Test to see if the result is wrong due to the presence of + // overflow bits. + assert((u[ulen] & DIGIT_MASK) != (v[ulen] & DIGIT_MASK)); +#endif + + return (int) (u[ulen] - v[ulen]); + +} + +// Find the index of the first non-zero digit. +// - ulen (before) = the number of digits in u. +// - the returned value = the index of the first non-zero digit. +// A negative value of -1 indicates that every digit in u is zero. +inline +int +vec_find_first_nonzero(int ulen, const sc_digit *u) +{ + +#ifdef DEBUG_SYSTEMC + // assert((ulen <= 0) || (u != NULL)); + assert((ulen > 0) && (u != NULL)); +#endif + + while ((--ulen >= 0) && (! u[ulen])) + ; + + return ulen; + +} + +// Skip all the leading zero digits. +// - ulen (before) = the number of digits in u. +// - the returned value = the number of non-zero digits in u. +// - the returned value is non-negative. +inline +int +vec_skip_leading_zeros(int ulen, const sc_digit *u) +{ + +#ifdef DEBUG_SYSTEMC + // assert((ulen <= 0) || (u != NULL)); + assert((ulen > 0) && (u != NULL)); +#endif + + return (1 + vec_find_first_nonzero(ulen, u)); + +} + +// Compare u and v and return r +// r = 0 if u == v +// r < 0 if u < v +// r > 0 if u > v +inline +int +vec_skip_and_cmp(int ulen, const sc_digit *u, + int vlen, const sc_digit *v) +{ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (u != NULL)); + assert((vlen > 0) && (v != NULL)); +#endif + + ulen = vec_skip_leading_zeros(ulen, u); + vlen = vec_skip_leading_zeros(vlen, v); + // ulen and/or vlen can be equal to zero here. + return vec_cmp(ulen, u, vlen, v); + +} + +// Set u[i] = 0 where i = from ... (ulen - 1). +inline +void +vec_zero(int from, int ulen, sc_digit *u) +{ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (u != NULL)); +#endif + + for(int i = from; i < ulen; i++) + u[i] = 0; + +} + +// Set u[i] = 0 where i = 0 .. (ulen - 1). +inline +void +vec_zero(int ulen, sc_digit *u) +{ + vec_zero(0, ulen, u); +} + +// Copy n digits from v to u. +inline +void +vec_copy(int n, sc_digit *u, const sc_digit *v) +{ + +#ifdef DEBUG_SYSTEMC + assert((n > 0) && (u != NULL) && (v != NULL)); +#endif + + for (int i = 0; i < n; ++i) + u[i] = v[i]; +} + +// Copy v to u, where ulen >= vlen, and zero the rest of the digits in u. +inline +void +vec_copy_and_zero(int ulen, sc_digit *u, + int vlen, const sc_digit *v) +{ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (u != NULL)); + assert((vlen > 0) && (v != NULL)); + assert(ulen >= vlen); +#endif + + vec_copy(vlen, u, v); + vec_zero(vlen, ulen, u); + +} + +// 2's-complement the digits in u. +inline +void +vec_complement(int ulen, sc_digit *u) +{ + +#ifdef DEBUG_SYSTEMC + assert((ulen > 0) && (u != NULL)); +#endif + + sc_digit carry = 1; + + for (int i = 0; i < ulen; ++i) { + carry += (~u[i] & DIGIT_MASK); + u[i] = carry & DIGIT_MASK; + carry >>= BITS_PER_DIGIT; + } + +} + + +// ---------------------------------------------------------------------------- +// Functions to handle built-in types or signs. +// ---------------------------------------------------------------------------- + +// u = v +// - v is an unsigned long or uint64, and positive integer. +template< class Type > +inline +void +from_uint(int ulen, sc_digit *u, Type v) +{ + +#ifdef DEBUG_SYSTEMC + // assert((ulen <= 0) || (u != NULL)); + assert((ulen > 0) && (u != NULL)); + assert(v >= 0); +#endif + + int i = 0; + + while (v && (i < ulen)) { +#ifndef _WIN32 + u[i++] = static_cast<sc_digit>( v & DIGIT_MASK ); +#else + u[i++] = ((sc_digit) v) & DIGIT_MASK; +#endif + v >>= BITS_PER_DIGIT; + } + + vec_zero(i, ulen, u); + +} + + +// Get u's sign and return its absolute value. +// u can be long, unsigned long, int64, or uint64. +template< class Type > +inline +small_type +get_sign(Type &u) +{ + if (u > 0) + return SC_POS; + + if (u == 0) + return SC_ZERO; + + // no positive number representable for minimum value, + // leave as is to avoid Undefined Behaviour + if( SC_LIKELY_( u > (std::numeric_limits<Type>::min)() ) ) + u = -u; + + return SC_NEG; +} + + +// Return us * vs: +// - Return SC_ZERO if either sign is SC_ZERO. +// - Return SC_POS if us == vs +// - Return SC_NEG if us != vs. +inline +small_type +mul_signs(small_type us, small_type vs) +{ + if ((us == SC_ZERO) || (vs == SC_ZERO)) + return SC_ZERO; + + if (us == vs) + return SC_POS; + + return SC_NEG; +} + + +// ---------------------------------------------------------------------------- +// Functions to test for errors and print out error messages. +// ---------------------------------------------------------------------------- + +#ifdef SC_MAX_NBITS + +inline +void +test_bound(int nb) +{ + if (nb > SC_MAX_NBITS) { + char msg[BUFSIZ]; + std::sprintf( msg, "test_bound( int nb ) : " + "nb = %d > SC_MAX_NBITS = %d is not valid", + nb, SC_MAX_NBITS ); + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); + } +} + +#endif + +template< class Type > +inline +void +div_by_zero(Type s) +{ + if (s == 0) { + SC_REPORT_ERROR( sc_core::SC_ID_OPERATION_FAILED_, + "div_by_zero<Type>( Type ) : division by zero" ); + } +} + + +// ---------------------------------------------------------------------------- +// Functions to check if a given vector is zero or make one. +// ---------------------------------------------------------------------------- + +// If u[i] is zero for every i = 0,..., ulen - 1, return SC_ZERO, +// else return s. +inline +small_type +check_for_zero(small_type s, int ulen, const sc_digit *u) +{ + +#ifdef DEBUG_SYSTEMC + // assert(ulen >= 0); + assert((ulen > 0) && (u != NULL)); +#endif + + if (vec_find_first_nonzero(ulen, u) < 0) + return SC_ZERO; + + return s; + +} + +// If u[i] is zero for every i = 0,..., ulen - 1, return true, +// else return false. +inline +bool +check_for_zero(int ulen, const sc_digit *u) +{ + +#ifdef DEBUG_SYSTEMC + // assert(ulen >= 0); + assert((ulen > 0) && (u != NULL)); +#endif + + if (vec_find_first_nonzero(ulen, u) < 0) + return true; + + return false; + +} + +inline +small_type +make_zero(int nd, sc_digit *d) +{ + vec_zero(nd, d); + return SC_ZERO; +} + + +// ---------------------------------------------------------------------------- +// Functions for both signed and unsigned numbers to convert sign-magnitude +// (SM) and 2's complement (2C) representations. +// added = 1 => for signed. +// added = 0 => for unsigned. +// IF_SC_SIGNED can be used as 'added'. +// ---------------------------------------------------------------------------- + +// Trim the extra leading bits of a signed or unsigned number. +inline +void +trim(small_type added, int nb, int nd, sc_digit *d) +{ +#ifdef DEBUG_SYSTEMC + assert((nb > 0) && (nd > 0) && (d != NULL)); +#endif + + d[nd - 1] &= one_and_ones(bit_ord(nb - 1) + added); +} + +// Convert an (un)signed number from sign-magnitude representation to +// 2's complement representation and trim the extra bits. +inline +void +convert_SM_to_2C_trimmed(small_type added, + small_type s, int nb, int nd, sc_digit *d) +{ + if (s == SC_NEG) { + vec_complement(nd, d); + trim(added, nb, nd, d); + } +} + +// Convert an (un)signed number from sign-magnitude representation to +// 2's complement representation but do not trim the extra bits. +inline +void +convert_SM_to_2C(small_type s, int nd, sc_digit *d) +{ + if (s == SC_NEG) + vec_complement(nd, d); +} + + +// ---------------------------------------------------------------------------- +// Functions to convert between sign-magnitude (SM) and 2's complement +// (2C) representations of signed numbers. +// ---------------------------------------------------------------------------- + +// Trim the extra leading bits off a signed number. +inline +void +trim_signed(int nb, int nd, sc_digit *d) +{ +#ifdef DEBUG_SYSTEMC + assert((nb > 0) && (nd > 0) && (d != NULL)); +#endif + + d[nd - 1] &= one_and_ones(bit_ord(nb - 1) + 1); +} + +// Convert a signed number from 2's complement representation to +// sign-magnitude representation, and return its sign. nd is d's +// actual size, without zeros eliminated. +inline +small_type +convert_signed_2C_to_SM(int nb, int nd, sc_digit *d) +{ + +#ifdef DEBUG_SYSTEMC + assert((nb > 0) && (nd > 0) && (d != NULL)); +#endif + + small_type s; + + int xnb = bit_ord(nb - 1) + 1; + + // Test the sign bit. + if (d[nd - 1] & one_and_zeros(xnb - 1)) { + s = SC_NEG; + vec_complement(nd, d); + } + else + s = SC_POS; + + // Trim the last digit. + d[nd - 1] &= one_and_ones(xnb); + + // Check if the new number is zero. + if (s == SC_POS) + return check_for_zero(s, nd, d); + + return s; + +} + +// Convert a signed number from sign-magnitude representation to 2's +// complement representation, get its sign, convert back to +// sign-magnitude representation, and return its sign. nd is d's +// actual size, without zeros eliminated. +inline +small_type +convert_signed_SM_to_2C_to_SM(small_type s, int nb, int nd, sc_digit *d) +{ + convert_SM_to_2C(s, nd, d); + return convert_signed_2C_to_SM(nb, nd, d); +} + +// Convert a signed number from sign-magnitude representation to 2's +// complement representation and trim the extra bits. +inline +void +convert_signed_SM_to_2C_trimmed(small_type s, int nb, int nd, sc_digit *d) +{ + convert_SM_to_2C_trimmed(1, s, nb, nd, d); +} + +// Convert a signed number from sign-magnitude representation to 2's +// complement representation but do not trim the extra bits. +inline +void +convert_signed_SM_to_2C(small_type s, int nd, sc_digit *d) +{ + convert_SM_to_2C(s, nd, d); +} + + +// ---------------------------------------------------------------------------- +// Functions to convert between sign-magnitude (SM) and 2's complement +// (2C) representations of unsigned numbers. +// ---------------------------------------------------------------------------- + +// Trim the extra leading bits off an unsigned number. +inline +void +trim_unsigned(int nb, int nd, sc_digit *d) +{ +#ifdef DEBUG_SYSTEMC + assert((nb > 0) && (nd > 0) && (d != NULL)); +#endif + + d[nd - 1] &= one_and_ones(bit_ord(nb - 1)); +} + +// Convert an unsigned number from 2's complement representation to +// sign-magnitude representation, and return its sign. nd is d's +// actual size, without zeros eliminated. +inline +small_type +convert_unsigned_2C_to_SM(int nb, int nd, sc_digit *d) +{ + trim_unsigned(nb, nd, d); + return check_for_zero(SC_POS, nd, d); +} + +// Convert an unsigned number from sign-magnitude representation to +// 2's complement representation, get its sign, convert back to +// sign-magnitude representation, and return its sign. nd is d's +// actual size, without zeros eliminated. +inline +small_type +convert_unsigned_SM_to_2C_to_SM(small_type s, int nb, int nd, sc_digit *d) +{ + convert_SM_to_2C(s, nd, d); + return convert_unsigned_2C_to_SM(nb, nd, d); +} + +// Convert an unsigned number from sign-magnitude representation to +// 2's complement representation and trim the extra bits. +inline +void +convert_unsigned_SM_to_2C_trimmed(small_type s, int nb, int nd, sc_digit *d) +{ + convert_SM_to_2C_trimmed(0, s, nb, nd, d); +} + +// Convert an unsigned number from sign-magnitude representation to +// 2's complement representation but do not trim the extra bits. +inline +void +convert_unsigned_SM_to_2C(small_type s, int nd, sc_digit *d) +{ + convert_SM_to_2C(s, nd, d); +} + + +// ---------------------------------------------------------------------------- +// Functions to copy one (un)signed number to another. +// ---------------------------------------------------------------------------- + +// Copy v to u. +inline +void +copy_digits_signed(small_type &us, + int unb, int und, sc_digit *ud, + int vnb, int vnd, const sc_digit *vd) +{ + + if (und <= vnd) { + + vec_copy(und, ud, vd); + + if (unb <= vnb) + us = convert_signed_SM_to_2C_to_SM(us, unb, und, ud); + + } + else // und > vnd + vec_copy_and_zero(und, ud, vnd, vd); + +} + +// Copy v to u. +inline +void +copy_digits_unsigned(small_type &us, + int unb, int und, sc_digit *ud, + int /* vnb */, int vnd, const sc_digit *vd) +{ + + if (und <= vnd) + vec_copy(und, ud, vd); + + else // und > vnd + vec_copy_and_zero(und, ud, vnd, vd); + + us = convert_unsigned_SM_to_2C_to_SM(us, unb, und, ud); + +} + + +// ---------------------------------------------------------------------------- +// Faster set(i, v), without bound checking. +// ---------------------------------------------------------------------------- + +// A version of set(i, v) without bound checking. +inline +void +safe_set(int i, bool v, sc_digit *d) +{ + +#ifdef DEBUG_SYSTEMC + assert((i >= 0) && (d != NULL)); +#endif + + int bit_num = bit_ord(i); + int digit_num = digit_ord(i); + + if (v) + d[digit_num] |= one_and_zeros(bit_num); + else + d[digit_num] &= ~(one_and_zeros(bit_num)); + +} + + +// ---------------------------------------------------------------------------- +// Function to check if a double number is bad (NaN or infinite). +// ---------------------------------------------------------------------------- + +inline +bool +is_nan( double v ) +{ + return std::numeric_limits<double>::has_quiet_NaN && (v != v); +} + +inline +bool +is_inf( double v ) +{ + return v == std::numeric_limits<double>::infinity() + || v == -std::numeric_limits<double>::infinity(); +} + +inline +void +is_bad_double(double v) +{ +// Windows throws exception. + if( is_nan(v) || is_inf(v) ) + SC_REPORT_ERROR( sc_core::SC_ID_VALUE_NOT_VALID_, + "is_bad_double( double v ) : " + "v is not finite - NaN or Inf" ); +} + +} // namespace sc_dt + + +#endif diff --git a/ext/systemc/src/sysc/datatypes/int/sc_signed.cpp b/ext/systemc/src/sysc/datatypes/int/sc_signed.cpp new file mode 100644 index 000000000..7e5cfacff --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_signed.cpp @@ -0,0 +1,4134 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_signed.cpp -- Arbitrary precision signed arithmetic. + + This file includes the definitions of sc_signed_bitref, + sc_signed_subref, and sc_signed classes. The first two + classes are proxy classes to reference one bit and a range + of bits of a sc_signed number, respectively. This file also + includes sc_nbcommon.cpp and sc_nbfriends.cpp, which + contain the definitions shared by sc_unsigned. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_signed.cpp,v $ +// Revision 1.6 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.5 2008/12/10 20:38:45 acg +// Andy Goodrich: fixed conversion of double values to the digits vector. +// The bits above the radix were not being masked off. +// +// Revision 1.4 2008/06/19 17:47:56 acg +// Andy Goodrich: fixes for bugs. See 2.2.1 RELEASENOTES. +// +// Revision 1.3 2008/04/29 21:20:41 acg +// Andy Goodrich: added mask to first word transferred when processing +// a negative sc_signed value in sc_signed::concat_get_data(). +// +// Revision 1.2 2007/11/04 21:27:00 acg +// Andy Goodrich: changes to make sure the proper value is returned from +// concat_get_data(). +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.5 2006/10/23 19:32:47 acg +// Andy Goodrich: further fix for incorrect value being returned from +// concat_get_data. This one is in the non-aligned value code. +// +// Revision 1.3 2006/01/13 18:49:32 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#include <ctype.h> +#include <math.h> + +#include "sysc/kernel/sc_cmnhdr.h" +#include "sysc/kernel/sc_macros.h" +#include "sysc/datatypes/int/sc_signed.h" +#include "sysc/datatypes/int/sc_unsigned.h" +#include "sysc/datatypes/int/sc_int_base.h" +#include "sysc/datatypes/int/sc_uint_base.h" +#include "sysc/datatypes/int/sc_int_ids.h" +#include "sysc/datatypes/bit/sc_bv_base.h" +#include "sysc/datatypes/bit/sc_lv_base.h" +#include "sysc/datatypes/misc/sc_concatref.h" +#include "sysc/datatypes/fx/sc_fix.h" +#include "sysc/datatypes/fx/scfx_other_defs.h" + + +namespace sc_dt +{ + +// Pool of temporary instances: + +sc_core::sc_vpool<sc_signed_bitref> sc_signed_bitref::m_pool(9); +sc_core::sc_vpool<sc_signed_subref> sc_signed_subref::m_pool(9); + +// ----------------------------------------------------------------------------- +// SECTION: Public members - Invalid selections. +// ----------------------------------------------------------------------------- + +void +sc_signed::invalid_index( int i ) const +{ + char msg[BUFSIZ]; + std::sprintf( msg, + "sc_bigint bit selection: index = %d violates " + "0 <= index <= %d", i, nbits - 1 ); + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); +} + +void +sc_signed::invalid_range( int l, int r ) const +{ + char msg[BUFSIZ]; + std::sprintf( msg, + "sc_bigint part selection: left = %d, right = %d \n" + " violates either (%d >= left >= 0) or (%d >= right >= 0)", + l, r, nbits-1, nbits-1 ); + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); +} + + +// ---------------------------------------------------------------------------- + +// ---------------------------------------------------------------------------- +// SECTION: Public members. +// ---------------------------------------------------------------------------- + +// Most public members are included from sc_nbcommon.inc. However, some +// concatenation support appears here to optimize between the signed and +// unsigned cases. + +// Insert this object's value at the specified place in a vector of biguint +// style values. + +bool sc_signed::concat_get_ctrl( sc_digit* dst_p, int low_i ) const +{ + int dst_i; // Index to next word to set in dst_p. + int end_i; // Index of high order word to set. + int left_shift; // Amount to shift value left. + sc_digit mask; // Mask for partial word sets. + + + // CALCULATE METRICS FOR DATA MOVEMENT: + + dst_i = low_i / BITS_PER_DIGIT; + end_i = (low_i + nbits - 1) / BITS_PER_DIGIT; + left_shift = low_i % BITS_PER_DIGIT; + + + // ALL DATA TO BE MOVED IS IN A SINGLE WORD: + + mask = ~(-1 << left_shift); + dst_p[dst_i] = ( dst_p[dst_i] & ~mask ); + dst_i++; + + for ( ; dst_i <= end_i; dst_i++ ) dst_p[dst_i] = 0; + + return false; +} + +bool sc_signed::concat_get_data( sc_digit* dst_p, int low_i ) const +{ + sc_digit carry; // Carry bit for complements. + int dst_i; // Index to next word to set in dst_p. + int end_i; // Index of high order word to set. + int high_i; // Index w/in word of high order bit. + int left_shift; // Amount to shift value left. + sc_digit left_word; // High word component for set. + sc_digit mask; // Mask for partial word sets. + bool result; // True if inserted non-zero data. + int right_shift; // Amount to shift value right. + sc_digit right_word; // Low word component for set. + int src_i; // Index to next word to get from digit. + + + + // CALCULATE METRICS FOR DATA MOVEMENT: + + dst_i = low_i / BITS_PER_DIGIT; + high_i = low_i + nbits - 1; + end_i = high_i / BITS_PER_DIGIT; + left_shift = low_i % BITS_PER_DIGIT; + + switch ( sgn ) + { + // POSITIVE SOURCE VALUE: + + case SC_POS: + + result = true; + + // ALL DATA TO BE MOVED IS IN A SINGLE WORD: + + if ( dst_i == end_i ) + { + mask = ~(-1 << left_shift); + dst_p[dst_i] = ( ( dst_p[dst_i] & mask ) | + (digit[0] << left_shift) ) & DIGIT_MASK; + } + + + // DATA IS IN MORE THAN ONE WORD, BUT IS WORD ALIGNED: + + else if ( left_shift == 0 ) + { + for ( src_i = 0; dst_i < end_i; dst_i++, src_i++ ) + { + dst_p[dst_i] = digit[src_i]; + } + high_i = high_i % BITS_PER_DIGIT; + mask = ~(-2 << high_i) & DIGIT_MASK; + dst_p[dst_i] = digit[src_i] & mask; + } + + + // DATA IS IN MORE THAN ONE WORD, AND NOT WORD ALIGNED: + + else + { + high_i = high_i % BITS_PER_DIGIT; + right_shift = BITS_PER_DIGIT - left_shift; + mask = ~(-1 << left_shift); + right_word = digit[0]; + dst_p[dst_i] = (dst_p[dst_i] & mask) | + ((right_word << left_shift) & DIGIT_MASK); + for ( src_i = 1, dst_i++; dst_i < end_i; dst_i++, src_i++ ) + { + left_word = digit[src_i]; + dst_p[dst_i] = ((left_word << left_shift)&DIGIT_MASK) | + (right_word >> right_shift); + right_word = left_word; + } + left_word = (src_i < ndigits) ? digit[src_i] : 0; + mask = ~(-2 << high_i) & DIGIT_MASK; + dst_p[dst_i] = ((left_word << left_shift) | + (right_word >> right_shift)) & mask; + } + break; + + + // SOURCE VALUE IS NEGATIVE: + + case SC_NEG: + + // ALL DATA TO BE MOVED IS IN A SINGLE WORD: + + result = true; + if ( dst_i == end_i ) + { + mask = ~(-1 << nbits); + right_word = ((digit[0] ^ DIGIT_MASK) + 1) & mask; + mask = ~(-1 << left_shift); + dst_p[dst_i] = ( ( dst_p[dst_i] & mask ) | + (right_word << left_shift) ) & DIGIT_MASK; + } + + + // DATA IS IN MORE THAN ONE WORD, BUT IS WORD ALIGNED: + + else if ( left_shift == 0 ) + { + carry = 1; + for ( src_i = 0; dst_i < end_i; dst_i++, src_i++ ) + { + right_word = (digit[src_i] ^ DIGIT_MASK) + carry; + dst_p[dst_i] = right_word & DIGIT_MASK; + carry = right_word >> BITS_PER_DIGIT; + } + high_i = high_i % BITS_PER_DIGIT; + mask = (~(-2 << high_i)) & DIGIT_MASK; + right_word = (src_i < ndigits) ? + (digit[src_i] ^ DIGIT_MASK) + carry : DIGIT_MASK + carry; + dst_p[dst_i] = right_word & mask; + } + + + // DATA IS IN MORE THAN ONE WORD, AND NOT WORD ALIGNED: + + else + { + high_i = high_i % BITS_PER_DIGIT; + right_shift = BITS_PER_DIGIT - left_shift; + mask = ~(-1 << left_shift); + carry = 1; + right_word = (digit[0] ^ DIGIT_MASK) + carry; + dst_p[dst_i] = (dst_p[dst_i] & mask) | + ((right_word << left_shift) & DIGIT_MASK); + carry = right_word >> BITS_PER_DIGIT; + right_word &= DIGIT_MASK; + for ( src_i = 1, dst_i++; dst_i < end_i; dst_i++, src_i++ ) + { + left_word = (digit[src_i] ^ DIGIT_MASK) + carry; + dst_p[dst_i] = ((left_word << left_shift)&DIGIT_MASK) | + (right_word >> right_shift); + carry = left_word >> BITS_PER_DIGIT; + right_word = left_word & DIGIT_MASK; + } + left_word = (src_i < ndigits) ? + (digit[src_i] ^ DIGIT_MASK) + carry : carry; + mask = ~(-2 << high_i) & DIGIT_MASK; + dst_p[dst_i] = ((left_word << left_shift) | + (right_word >> right_shift)) & mask; + } + break; + + + // VALUE IS ZERO: + + default: + result = false; + + + // ALL DATA TO BE MOVED IS IN A SINGLE WORD: + + if ( dst_i == end_i ) + { + mask = ~(-1 << nbits) << left_shift; + dst_p[dst_i] = dst_p[dst_i] & ~mask; + } + + + // DATA IS IN MORE THAN ONE WORD, BUT IS WORD ALIGNED: + + else if ( left_shift == 0 ) + { + carry = 1; + for ( src_i = 0; dst_i < end_i; dst_i++, src_i++ ) + { + dst_p[dst_i] = 0; + } + high_i = high_i % BITS_PER_DIGIT; + mask = ~(-2 << high_i) & DIGIT_MASK; + dst_p[dst_i] = 0; // #### digit[src_i] & mask; + } + + + // DATA IS IN MORE THAN ONE WORD, AND NOT WORD ALIGNED: + + else + { + high_i = high_i % BITS_PER_DIGIT; + right_shift = BITS_PER_DIGIT - left_shift; + mask = ~(-1 << left_shift); + dst_p[dst_i] = (dst_p[dst_i] & mask); + for ( dst_i++; dst_i <= end_i; dst_i++ ) + { + dst_p[dst_i] = 0; + } + } + break; + } + return result; +} + +// Return this object instance's bits as a uint64 without sign extension. + +uint64 sc_signed::concat_get_uint64() const +{ + uint64 result; + + switch ( sgn ) + { + case SC_POS: + result = 0; + if ( ndigits > 2 ) + result = digit[2]; + if ( ndigits > 1 ) + result = (result << BITS_PER_DIGIT) | digit[1]; + result = (result << BITS_PER_DIGIT) | digit[0]; + break; + case SC_NEG: + result = 0; + if ( ndigits > 2 ) + result = digit[2]; + if ( ndigits > 1 ) + result = (result << BITS_PER_DIGIT) | digit[1]; + result = (result << BITS_PER_DIGIT) | digit[0]; + result = -result; + if ( nbits < 64 ) + { + uint64 mask = ~0; + result = result & ~(mask << nbits); + } + break; + default: + result = 0; + break; + } + return result; +} + +// #### OPTIMIZE +void sc_signed::concat_set(int64 src, int low_i) +{ + *this = (low_i < 64) ? src >> low_i : src >> 63; +} + +void sc_signed::concat_set(const sc_signed& src, int low_i) +{ + if ( low_i < src.length() ) + *this = src >> low_i; + else + *this = (src<0) ? (int_type)-1 : 0; +} + +void sc_signed::concat_set(const sc_unsigned& src, int low_i) +{ + if ( low_i < src.length() ) + *this = src >> low_i; + else + *this = 0; +} + +void sc_signed::concat_set(uint64 src, int low_i) +{ + *this = (low_i < 64) ? src >> low_i : 0; +} + +// ---------------------------------------------------------------------------- +// SECTION: Public members - Reduction methods. +// ---------------------------------------------------------------------------- + +bool sc_signed::and_reduce() const +{ + sc_digit current; // Current digit examining. + int i; // Index of digit examining. + + if ( sgn == SC_NEG ) + { + current = (1 << BITS_PER_DIGIT); + for ( i = 0; i < ndigits-1; i++ ) + { + current = (current >> BITS_PER_DIGIT) + (digit[i]^DIGIT_MASK); + if ( (current & DIGIT_MASK) != DIGIT_MASK ) return false; + } + current = (current >> BITS_PER_DIGIT) + (digit[i]^DIGIT_MASK); + if ( (current & ~(-1 << (nbits % BITS_PER_DIGIT))) == + (sc_digit) ~(-1 << (nbits % BITS_PER_DIGIT)) ) + return true; + } + return false; +} + +bool sc_signed::or_reduce() const +{ + return sgn == SC_ZERO ? false : true; +} + +bool sc_signed::xor_reduce() const +{ + int i; // Digit examining. + int odd; // Flag for odd number of digits. + + odd = 0; + for ( i = 0; i < nbits; i++ ) + if ( test(i) ) odd = ~odd; + return odd ? true : false; +} + + + +// ---------------------------------------------------------------------------- +// SECTION: Public members - Assignment operators. +// ---------------------------------------------------------------------------- + +// assignment operators + +const sc_signed& +sc_signed::operator = ( const char* a ) +{ + if( a == 0 ) { + SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, + "character string is zero" ); + } + if( *a == 0 ) { + SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, + "character string is empty" ); + } + try { + int len = length(); + sc_fix aa( a, len, len, SC_TRN, SC_WRAP, 0, SC_ON ); + return this->operator = ( aa ); + } catch( sc_core::sc_report ) { + char msg[BUFSIZ]; + std::sprintf( msg, "character string '%s' is not valid", a ); + SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg ); + // never reached + } + return *this; +} + +const sc_signed& +sc_signed::operator=(int64 v) +{ + sgn = get_sign(v); + // v >= 0 now. + if (sgn == SC_ZERO) + vec_zero(ndigits, digit); + else { + from_uint(ndigits, digit, (uint64) v); + if (nbits <= (int)BITS_PER_INT64) + convert_SM_to_2C_to_SM(); + } + return *this; +} + +const sc_signed& +sc_signed::operator=(uint64 v) +{ + sgn = get_sign(v); + if (sgn == SC_ZERO) + vec_zero(ndigits, digit); + else { + from_uint(ndigits, digit, v); + if (nbits <= (int)BITS_PER_INT64) + convert_SM_to_2C_to_SM(); + } + return *this; +} + +const sc_signed& +sc_signed::operator=(long v) +{ + sgn = get_sign(v); + // v >= 0 now. + if (sgn == SC_ZERO) + vec_zero(ndigits, digit); + else { + from_uint(ndigits, digit, (unsigned long) v); + if (nbits <= (int)BITS_PER_LONG) + convert_SM_to_2C_to_SM(); + } + return *this; +} + +const sc_signed& +sc_signed::operator=(unsigned long v) +{ + sgn = get_sign(v); + if (sgn == SC_ZERO) + vec_zero(ndigits, digit); + else { + from_uint(ndigits, digit, v); + if (nbits <= (int)BITS_PER_LONG) + convert_SM_to_2C_to_SM(); + } + return *this; +} + +const sc_signed& +sc_signed::operator=(double v) +{ + is_bad_double(v); + if (v < 0) { + v = -v; + sgn = SC_NEG; + } + else + sgn = SC_POS; + int i = 0; + while (floor(v) && (i < ndigits)) { +#ifndef _WIN32 + digit[i++] = ((sc_digit)floor(remainder(v, DIGIT_RADIX))) & DIGIT_MASK; +#else + digit[i++] = ((sc_digit)floor(fmod(v, DIGIT_RADIX))) & DIGIT_MASK; +#endif + v /= DIGIT_RADIX; + } + vec_zero(i, ndigits, digit); + convert_SM_to_2C_to_SM(); + return *this; +} + + +// ---------------------------------------------------------------------------- + +const sc_signed& +sc_signed::operator = ( const sc_bv_base& v ) +{ + int minlen = sc_min( nbits, v.length() ); + int i = 0; + for( ; i < minlen; ++ i ) { + safe_set( i, v.get_bit( i ), digit ); + } + for( ; i < nbits; ++ i ) { + safe_set( i, 0, digit ); // zero-extend + } + convert_2C_to_SM(); + return *this; +} + +const sc_signed& +sc_signed::operator = ( const sc_lv_base& v ) +{ + int minlen = sc_min( nbits, v.length() ); + int i = 0; + for( ; i < minlen; ++ i ) { + safe_set( i, sc_logic( v.get_bit( i ) ).to_bool(), digit ); + } + for( ; i < nbits; ++ i ) { + safe_set( i, 0, digit ); // zero-extend + } + convert_2C_to_SM(); + return *this; +} + + +// explicit conversion to character string + +const std::string +sc_signed::to_string( sc_numrep numrep ) const +{ + int len = length(); + sc_fix aa( *this, len, len, SC_TRN, SC_WRAP, 0, SC_ON ); + return aa.to_string( numrep ); +} + +const std::string +sc_signed::to_string( sc_numrep numrep, bool w_prefix ) const +{ + int len = length(); + sc_fix aa( *this, len, len, SC_TRN, SC_WRAP, 0, SC_ON ); + return aa.to_string( numrep, w_prefix ); +} + + +// ---------------------------------------------------------------------------- +// SECTION: Interfacing with sc_int_base +// ---------------------------------------------------------------------------- + +const sc_signed& +sc_signed::operator = (const sc_int_base& v) +{ return operator=((int64) v); } + + +sc_signed +operator + ( const sc_unsigned& u, const sc_int_base& v ) +{ return operator + ( u, SCAST<int64>( v ) ); } + +sc_signed +operator + ( const sc_int_base& u, const sc_unsigned& v ) +{ return operator + ( SCAST<int64>( u ), v ); } + +sc_signed +operator + (const sc_signed& u, const sc_int_base& v) +{ return operator+(u, (int64) v); } + +sc_signed +operator + (const sc_int_base& u, const sc_signed& v) +{ return operator+((int64) u, v); } + +const sc_signed& +sc_signed::operator += (const sc_int_base& v) +{ return operator+=((int64) v); } + + +sc_signed +operator - (const sc_unsigned& u, const sc_int_base& v) +{ return operator-(u, (int64) v); } + +sc_signed +operator - (const sc_int_base& u, const sc_unsigned& v) +{ return operator-((int64) u, v); } + +sc_signed +operator-(const sc_signed& u, const sc_int_base& v) +{ return operator-(u, (int64) v); } + +sc_signed +operator - (const sc_int_base& u, const sc_signed& v) +{ return operator-((int64) u, v); } + +const sc_signed& +sc_signed::operator -= (const sc_int_base& v) +{ return operator-=((int64) v); } + + +sc_signed +operator * ( const sc_unsigned& u, const sc_int_base& v ) +{ return operator * ( u, SCAST<int64>( v ) ); } + +sc_signed +operator * ( const sc_int_base& u, const sc_unsigned& v ) +{ return operator * ( SCAST<int64>( u ), v ); } + +sc_signed +operator * (const sc_signed& u, const sc_int_base& v) +{ return operator*(u, (int64) v); } + +sc_signed +operator * (const sc_int_base& u, const sc_signed& v) +{ return operator*((int64) u, v); } + +const sc_signed& +sc_signed::operator *= (const sc_int_base& v) +{ return operator*=((int64) v); } + + +sc_signed +operator / ( const sc_unsigned& u, const sc_int_base& v ) +{ return operator / ( u, SCAST<int64>( v ) ); } + +sc_signed +operator / ( const sc_int_base& u, const sc_unsigned& v ) +{ return operator / ( SCAST<int64>( u ), v ); } + +sc_signed +operator / (const sc_signed& u, const sc_int_base& v) +{ return operator/(u, (int64) v); } + +sc_signed +operator / (const sc_int_base& u, const sc_signed& v) +{ return operator/((int64) u, v); } + +const sc_signed& +sc_signed::operator /= (const sc_int_base& v) +{ return operator/=((int64) v); } + + +sc_signed +operator % ( const sc_unsigned& u, const sc_int_base& v ) +{ return operator % ( u, SCAST<int64>( v ) ); } + +sc_signed +operator % ( const sc_int_base& u, const sc_unsigned& v ) +{ return operator % ( SCAST<int64>( u ), v ); } + +sc_signed +operator % (const sc_signed& u, const sc_int_base& v) +{ return operator%(u, (int64) v); } + +sc_signed +operator % (const sc_int_base& u, const sc_signed& v) +{ return operator%((int64) u, v); } + +const sc_signed& +sc_signed::operator %= (const sc_int_base& v) +{ return operator%=((int64) v); } + + +sc_signed +operator & ( const sc_unsigned& u, const sc_int_base& v ) +{ return operator & ( u, SCAST<int64>( v ) ); } + +sc_signed +operator & ( const sc_int_base& u, const sc_unsigned& v ) +{ return operator & ( SCAST<int64>( u ), v ); } + +sc_signed +operator & (const sc_signed& u, const sc_int_base& v) +{ return operator&(u, (int64) v); } + +sc_signed +operator & (const sc_int_base& u, const sc_signed& v) +{ return operator&((int64) u, v); } + +const sc_signed& +sc_signed::operator &= (const sc_int_base& v) +{ return operator&=((int64) v); } + + +sc_signed +operator | ( const sc_unsigned& u, const sc_int_base& v ) +{ return operator | ( u, SCAST<int64>( v ) ); } + +sc_signed +operator | ( const sc_int_base& u, const sc_unsigned& v ) +{ return operator | ( SCAST<int64>( u ), v ); } + +sc_signed +operator | (const sc_signed& u, const sc_int_base& v) +{ return operator|(u, (int64) v); } + +sc_signed +operator | (const sc_int_base& u, const sc_signed& v) +{ return operator|((int64) u, v); } + +const sc_signed& +sc_signed::operator |= (const sc_int_base& v) +{ return operator|=((int64) v); } + + +sc_signed +operator ^ ( const sc_unsigned& u, const sc_int_base& v ) +{ return operator ^ ( u, SCAST<int64>( v ) ); } + +sc_signed +operator ^ ( const sc_int_base& u, const sc_unsigned& v ) +{ return operator ^ ( SCAST<int64>( u ), v ); } + +sc_signed +operator ^ (const sc_signed& u, const sc_int_base& v) +{ return operator^(u, (int64) v); } + +sc_signed +operator ^ (const sc_int_base& u, const sc_signed& v) +{ return operator^((int64) u, v); } + +const sc_signed& +sc_signed::operator ^= (const sc_int_base& v) +{ return operator^=((int64) v); } + + +sc_signed +operator << (const sc_signed& u, const sc_int_base& v) +{ return operator<<(u, (int64) v); } + +const sc_signed& +sc_signed::operator <<= (const sc_int_base& v) +{ return operator<<=((int64) v); } + + +sc_signed +operator >> (const sc_signed& u, const sc_int_base& v) +{ return operator>>(u, (int64) v); } + +const sc_signed& +sc_signed::operator >>= (const sc_int_base& v) +{ return operator>>=((int64) v); } + + +bool +operator == (const sc_signed& u, const sc_int_base& v) +{ return operator==(u, (int64) v); } + +bool +operator == (const sc_int_base& u, const sc_signed& v) +{ return operator==((int64) u, v); } + + +bool +operator != (const sc_signed& u, const sc_int_base& v) +{ return operator!=(u, (int64) v); } + +bool +operator != (const sc_int_base& u, const sc_signed& v) +{ return operator!=((int64) u, v); } + + +bool +operator < (const sc_signed& u, const sc_int_base& v) +{ return operator<(u, (int64) v); } + +bool +operator < (const sc_int_base& u, const sc_signed& v) +{ return operator<((int64) u, v); } + + +bool +operator <= (const sc_signed& u, const sc_int_base& v) +{ return operator<=(u, (int64) v); } + +bool +operator <= (const sc_int_base& u, const sc_signed& v) +{ return operator<=((int64) u, v); } + + +bool +operator > (const sc_signed& u, const sc_int_base& v) +{ return operator>(u, (int64) v); } + +bool +operator > (const sc_int_base& u, const sc_signed& v) +{ return operator>((int64) u, v); } + + +bool +operator >= (const sc_signed& u, const sc_int_base& v) +{ return operator>=(u, (int64) v); } + +bool +operator >= (const sc_int_base& u, const sc_signed& v) +{ return operator>=((int64) u, v); } + + +// ---------------------------------------------------------------------------- +// SECTION: Interfacing with sc_uint_base +// ---------------------------------------------------------------------------- + +const sc_signed& +sc_signed::operator = (const sc_uint_base& v) +{ return operator=((uint64) v); } + + +sc_signed +operator + (const sc_signed& u, const sc_uint_base& v) +{ return operator+(u, (uint64) v); } + +sc_signed +operator + (const sc_uint_base& u, const sc_signed& v) +{ return operator+((uint64) u, v); } + +const sc_signed& +sc_signed::operator += (const sc_uint_base& v) +{ return operator+=((uint64) v); } + + +sc_signed +operator - (const sc_unsigned& u, const sc_uint_base& v) +{ return operator-(u, (uint64) v); } + +sc_signed +operator - (const sc_uint_base& u, const sc_unsigned& v) +{ return operator-((uint64) u, v); } + +sc_signed +operator - (const sc_signed& u, const sc_uint_base& v) +{ return operator-(u, (uint64) v); } + +sc_signed +operator - (const sc_uint_base& u, const sc_signed& v) +{ return operator-((uint64) u, v); } + +const sc_signed& +sc_signed::operator -= (const sc_uint_base& v) +{ return operator-=((uint64) v); } + + +sc_signed +operator * (const sc_signed& u, const sc_uint_base& v) +{ return operator*(u, (uint64) v); } + +sc_signed +operator * (const sc_uint_base& u, const sc_signed& v) +{ return operator*((uint64) u, v); } + +const sc_signed& +sc_signed::operator *= (const sc_uint_base& v) +{ return operator*=((uint64) v); } + + +sc_signed +operator / (const sc_signed& u, const sc_uint_base& v) +{ return operator/(u, (uint64) v); } + +sc_signed +operator / (const sc_uint_base& u, const sc_signed& v) +{ return operator/((uint64) u, v); } + +const sc_signed& +sc_signed::operator /= (const sc_uint_base& v) +{ return operator/=((uint64) v); } + + +sc_signed +operator % (const sc_signed& u, const sc_uint_base& v) +{ return operator%(u, (uint64) v); } + +sc_signed +operator % (const sc_uint_base& u, const sc_signed& v) +{ return operator%((uint64) u, v); } + +const sc_signed& +sc_signed::operator %= (const sc_uint_base& v) +{ return operator%=((uint64) v); } + + +sc_signed +operator & (const sc_signed& u, const sc_uint_base& v) +{ return operator&(u, (uint64) v); } + +sc_signed +operator & (const sc_uint_base& u, const sc_signed& v) +{ return operator&((uint64) u, v); } + +const sc_signed& +sc_signed::operator &= (const sc_uint_base& v) +{ return operator&=((uint64) v); } + + +sc_signed +operator | (const sc_signed& u, const sc_uint_base& v) +{ return operator|(u, (uint64) v); } + +sc_signed +operator | (const sc_uint_base& u, const sc_signed& v) +{ return operator|((uint64) u, v); } + +const sc_signed& +sc_signed::operator |= (const sc_uint_base& v) +{ return operator|=((uint64) v); } + + +sc_signed +operator ^ (const sc_signed& u, const sc_uint_base& v) +{ return operator^(u, (uint64) v); } + +sc_signed +operator ^ (const sc_uint_base& u, const sc_signed& v) +{ return operator^((uint64) u, v); } + +const sc_signed& +sc_signed::operator ^= (const sc_uint_base& v) +{ return operator^=((uint64) v); } + + +sc_signed +operator << (const sc_signed& u, const sc_uint_base& v) +{ return operator<<(u, (uint64) v); } + +const sc_signed& +sc_signed::operator <<= (const sc_uint_base& v) +{ return operator<<=((uint64) v); } + + +sc_signed +operator >> (const sc_signed& u, const sc_uint_base& v) +{ return operator>>(u, (uint64) v); } + +const sc_signed& +sc_signed::operator >>= (const sc_uint_base& v) +{ return operator>>=((uint64) v); } + + +bool +operator == (const sc_signed& u, const sc_uint_base& v) +{ return operator==(u, (uint64) v); } + +bool +operator == (const sc_uint_base& u, const sc_signed& v) +{ return operator==((uint64) u, v); } + + +bool +operator != (const sc_signed& u, const sc_uint_base& v) +{ return operator!=(u, (uint64) v); } + +bool +operator != (const sc_uint_base& u, const sc_signed& v) +{ return operator!=((uint64) u, v); } + + +bool +operator < (const sc_signed& u, const sc_uint_base& v) +{ return operator<(u, (uint64) v); } + +bool +operator < (const sc_uint_base& u, const sc_signed& v) +{ return operator<((uint64) u, v); } + + +bool +operator <= (const sc_signed& u, const sc_uint_base& v) +{ return operator<=(u, (uint64) v); } + +bool +operator <= (const sc_uint_base& u, const sc_signed& v) +{ return operator<=((uint64) u, v); } + + +bool +operator > (const sc_signed& u, const sc_uint_base& v) +{ return operator>(u, (uint64) v); } + +bool +operator > (const sc_uint_base& u, const sc_signed& v) +{ return operator>((uint64) u, v); } + + +bool +operator >= (const sc_signed& u, const sc_uint_base& v) +{ return operator>=(u, (uint64) v); } + +bool +operator >= (const sc_uint_base& u, const sc_signed& v) +{ return operator>=((uint64) u, v); } + + +// ---------------------------------------------------------------------------- +// SECTION: Input and output operators +// ---------------------------------------------------------------------------- + +// Operators in this section are included from sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: Operator macros. +// ---------------------------------------------------------------------------- + +#define CONVERT_LONG(u) \ +small_type u ## s = get_sign(u); \ +sc_digit u ## d[DIGITS_PER_ULONG]; \ +from_uint(DIGITS_PER_ULONG, u ## d, (unsigned long) u); + +#define CONVERT_LONG_2(u) \ +sc_digit u ## d[DIGITS_PER_ULONG]; \ +from_uint(DIGITS_PER_ULONG, u ## d, (unsigned long) u); + +#define CONVERT_INT(u) \ +small_type u ## s = get_sign(u); \ +sc_digit u ## d[DIGITS_PER_UINT]; \ +from_uint(DIGITS_PER_UINT, u ## d, (unsigned int) u); + +#define CONVERT_INT_2(u) \ +sc_digit u ## d[DIGITS_PER_UINT]; \ +from_uint(DIGITS_PER_UINT, u ## d, (unsigned int) u); + +#define CONVERT_INT64(u) \ +small_type u ## s = get_sign(u); \ +sc_digit u ## d[DIGITS_PER_UINT64]; \ +from_uint(DIGITS_PER_UINT64, u ## d, (uint64) u); + +#define CONVERT_INT64_2(u) \ +sc_digit u ## d[DIGITS_PER_UINT64]; \ +from_uint(DIGITS_PER_UINT64, u ## d, (uint64) u); + + +// ---------------------------------------------------------------------------- +// SECTION: PLUS operators: +, +=, ++ +// ---------------------------------------------------------------------------- + +// Cases to consider when computing u + v: +// 1. 0 + v = v +// 2. u + 0 = u +// 3. if sgn(u) == sgn(v) +// 3.1 u + v = +(u + v) = sgn(u) * (u + v) +// 3.2 (-u) + (-v) = -(u + v) = sgn(u) * (u + v) +// 4. if sgn(u) != sgn(v) +// 4.1 u + (-v) = u - v = sgn(u) * (u - v) +// 4.2 (-u) + v = -(u - v) ==> sgn(u) * (u - v) +// +// Specialization of above cases for computing ++u or u++: +// 1. 0 + 1 = 1 +// 3. u + 1 = u + 1 = sgn(u) * (u + 1) +// 4. (-u) + 1 = -(u - 1) = sgn(u) * (u - 1) + +sc_signed +operator+(const sc_unsigned& u, const sc_signed& v) +{ + + if (u.sgn == SC_ZERO) // case 1 + return sc_signed(v); + + if (v.sgn == SC_ZERO) // case 2 + return sc_signed(u); + + // cases 3 and 4 + return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator+(const sc_signed& u, const sc_unsigned& v) +{ + + if (u.sgn == SC_ZERO) // case 1 + return sc_signed(v); + + if (v.sgn == SC_ZERO) // case 2 + return sc_signed(u); + + // cases 3 and 4 + return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator+(const sc_signed& u, const sc_signed& v) +{ + + if (u.sgn == SC_ZERO) // case 1 + return sc_signed(v); + + if (v.sgn == SC_ZERO) // case 2 + return sc_signed(u); + + // cases 3 and 4 + return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator+(const sc_signed &u, int64 v) +{ + + if (v == 0) // case 2 + return sc_signed(u); + + CONVERT_INT64(v); + + if (u.sgn == SC_ZERO) // case 1 + return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false); + + // cases 3 and 4 + return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator+(int64 u, const sc_signed &v) +{ + + if (u == 0) // case 1 + return sc_signed(v); + + CONVERT_INT64(u); + + if (v.sgn == SC_ZERO) // case 2 + return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false); + + // cases 3 and 4 + + return add_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator+(const sc_unsigned &u, int64 v) +{ + + if (v == 0) // case 2 + return sc_signed(u); + + CONVERT_INT64(v); + + if (u.sgn == SC_ZERO) // case 1 + return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false); + + // cases 3 and 4 + return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator+(int64 u, const sc_unsigned &v) +{ + + if (u == 0) // case 1 + return sc_signed(v); + + CONVERT_INT64(u); + + if (v.sgn == SC_ZERO) // case 2 + return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false); + + // cases 3 and 4 + + return add_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator+(const sc_signed &u, uint64 v) +{ + + if (v == 0) // case 2 + return sc_signed(u); + + CONVERT_INT64(v); + + if (u.sgn == SC_ZERO) // case 1 + return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false); + + // cases 3 and 4 + return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator+(uint64 u, const sc_signed &v) +{ + + if (u == 0) // case 1 + return sc_signed(v); + + CONVERT_INT64(u); + + if (v.sgn == SC_ZERO) // case 2 + return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false); + + // cases 3 and 4 + + return add_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator+(const sc_signed &u, long v) +{ + + if (v == 0) // case 2 + return sc_signed(u); + + CONVERT_LONG(v); + + if (u.sgn == SC_ZERO) // case 1 + return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false); + + // cases 3 and 4 + return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_signed +operator+(long u, const sc_signed &v) +{ + + if (u == 0) // case 1 + return sc_signed(v); + + CONVERT_LONG(u); + + if (v.sgn == SC_ZERO) // case 2 + return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false); + + // cases 3 and 4 + return add_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator+(const sc_unsigned &u, long v) +{ + + if (v == 0) // case 2 + return sc_signed(u); + + CONVERT_LONG(v); + + if (u.sgn == SC_ZERO) // case 1 + return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false); + + // cases 3 and 4 + return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_signed +operator+(long u, const sc_unsigned &v) +{ + + if (u == 0) // case 1 + return sc_signed(v); + + CONVERT_LONG(u); + + if (v.sgn == SC_ZERO) // case 2 + return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false); + + // cases 3 and 4 + return add_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator+(const sc_signed &u, unsigned long v) +{ + + if (v == 0) // case 2 + return sc_signed(u); + + CONVERT_LONG(v); + + if (u.sgn == SC_ZERO) // case 1 + return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false); + + // cases 3 and 4 + return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_signed +operator+(unsigned long u, const sc_signed &v) +{ + + if (u == 0) // case 1 + return sc_signed(v); + + CONVERT_LONG(u); + + if (v.sgn == SC_ZERO) // case 2 + return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false); + + // cases 3 and 4 + return add_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + +// The rest of the operators in this section are included from +// sc_nbcommon.cpp. + +// ---------------------------------------------------------------------------- +// SECTION: MINUS operators: -, -=, -- +// ---------------------------------------------------------------------------- + +// Cases to consider when computing u + v: +// 1. u - 0 = u +// 2. 0 - v = -v +// 3. if sgn(u) != sgn(v) +// 3.1 u - (-v) = u + v = sgn(u) * (u + v) +// 3.2 (-u) - v = -(u + v) ==> sgn(u) * (u + v) +// 4. if sgn(u) == sgn(v) +// 4.1 u - v = +(u - v) = sgn(u) * (u - v) +// 4.2 (-u) - (-v) = -(u - v) = sgn(u) * (u - v) +// +// Specialization of above cases for computing --u or u--: +// 1. 0 - 1 = -1 +// 3. (-u) - 1 = -(u + 1) = sgn(u) * (u + 1) +// 4. u - 1 = u - 1 = sgn(u) * (u - 1) + +sc_signed +operator-(const sc_unsigned& u, const sc_unsigned& v) +{ + + if (v.sgn == SC_ZERO) // case 1 + return sc_signed(u); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(v, -v.sgn); + + // cases 3 and 4 + return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + -v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator-(const sc_unsigned& u, const sc_signed& v) +{ + + if (v.sgn == SC_ZERO) // case 1 + return sc_signed(u); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(v, -v.sgn); + + // cases 3 and 4 + return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + -v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator-(const sc_signed& u, const sc_unsigned& v) +{ + + if (v.sgn == SC_ZERO) // case 1 + return sc_signed(u); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(v, -v.sgn); + + // cases 3 and 4 + return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + -v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator-(const sc_signed& u, const sc_signed& v) +{ + + if (v.sgn == SC_ZERO) // case 1 + return sc_signed(u); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(v, -v.sgn); + + // cases 3 and 4 + return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + -v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator-(const sc_signed &u, int64 v) +{ + + if (v == 0) // case 1 + return sc_signed(u); + + CONVERT_INT64(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(-vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false); + + // cases 3 and 4 + return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + -vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator-(int64 u, const sc_signed& v) +{ + + if (u == 0) // case 1 + return sc_signed(v, -v.sgn); + + CONVERT_INT64(u); + + if (v.sgn == SC_ZERO) // case 2 + return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false); + + // cases 3 and 4 + + return add_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + -v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator-(const sc_unsigned &u, int64 v) +{ + + if (v == 0) // case 1 + return sc_signed(u); + + CONVERT_INT64(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(-vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false); + + // cases 3 and 4 + return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + -vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator-(int64 u, const sc_unsigned& v) +{ + + if (u == 0) // case 1 + return sc_signed(v, -v.sgn); + + CONVERT_INT64(u); + + if (v.sgn == SC_ZERO) // case 2 + return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false); + + // cases 3 and 4 + + return add_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + -v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator-(const sc_signed &u, uint64 v) +{ + + if (v == 0) // case 1 + return sc_signed(u); + + CONVERT_INT64(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(-vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false); + + // cases 3 and 4 + + return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + -vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator-(uint64 u, const sc_signed& v) +{ + + if (u == 0) // case 1 + return sc_signed(v, -v.sgn); + + CONVERT_INT64(u); + + if (v.sgn == SC_ZERO) // case 2 + return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false); + + // cases 3 and 4 + return add_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + -v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator-(const sc_unsigned &u, uint64 v) +{ + + if (v == 0) // case 1 + return sc_signed(u); + + CONVERT_INT64(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(-vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false); + + // cases 3 and 4 + + return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + -vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator-(uint64 u, const sc_unsigned& v) +{ + + if (u == 0) // case 1 + return sc_signed(v, -v.sgn); + + CONVERT_INT64(u); + + if (v.sgn == SC_ZERO) // case 2 + return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false); + + // cases 3 and 4 + return add_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + -v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator-(const sc_signed &u, long v) +{ + + if (v == 0) // case 1 + return sc_signed(u); + + CONVERT_LONG(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(-vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false); + + // cases 3 and 4 + return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + -vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_signed +operator-(long u, const sc_signed& v) +{ + + if (u == 0) // case 1 + return sc_signed(v, -v.sgn); + + CONVERT_LONG(u); + + if (v.sgn == SC_ZERO) // case 2 + return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false); + + // cases 3 and 4 + return add_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + -v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator-(const sc_unsigned &u, long v) +{ + + if (v == 0) // case 1 + return sc_signed(u); + + CONVERT_LONG(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(-vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false); + + // cases 3 and 4 + return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + -vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_signed +operator-(long u, const sc_unsigned& v) +{ + + if (u == 0) // case 1 + return sc_signed(v, -v.sgn); + + CONVERT_LONG(u); + + if (v.sgn == SC_ZERO) // case 2 + return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false); + + // cases 3 and 4 + return add_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + -v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator-(const sc_signed &u, unsigned long v) +{ + + if (v == 0) // case 1 + return sc_signed(u); + + CONVERT_LONG(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(-vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false); + + // cases 3 and 4 + return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + -vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_signed +operator-(unsigned long u, const sc_signed& v) +{ + if (u == 0) // case 1 + return sc_signed(v, -v.sgn); + + CONVERT_LONG(u); + + if (v.sgn == SC_ZERO) // case 2 + return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false); + + // cases 3 and 4 + return add_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + -v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator-(const sc_unsigned &u, unsigned long v) +{ + + if (v == 0) // case 1 + return sc_signed(u); + + CONVERT_LONG(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(-vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false); + + // cases 3 and 4 + return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + -vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_signed +operator-(unsigned long u, const sc_unsigned& v) +{ + if (u == 0) // case 1 + return sc_signed(v, -v.sgn); + + CONVERT_LONG(u); + + if (v.sgn == SC_ZERO) // case 2 + return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false); + + // cases 3 and 4 + return add_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + -v.sgn, v.nbits, v.ndigits, v.digit); + +} + +// The rest of the operators in this section are included from +// sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: MULTIPLICATION operators: *, *= +// ---------------------------------------------------------------------------- + +// Cases to consider when computing u * v: +// 1. u * 0 = 0 * v = 0 +// 2. 1 * v = v and -1 * v = -v +// 3. u * 1 = u and u * -1 = -u +// 4. u * v = u * v + +sc_signed +operator*(const sc_unsigned& u, const sc_signed& v) +{ + + small_type s = mul_signs(u.sgn, v.sgn); + + if (s == SC_ZERO) // case 1 + return sc_signed(); + + // cases 2-4 + return mul_signed_friend(s, u.nbits, u.ndigits, u.digit, + v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator*(const sc_signed& u, const sc_unsigned& v) +{ + + small_type s = mul_signs(u.sgn, v.sgn); + + if (s == SC_ZERO) // case 1 + return sc_signed(); + + // cases 2-4 + return mul_signed_friend(s, u.nbits, u.ndigits, u.digit, + v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator*(const sc_signed& u, const sc_signed& v) +{ + + small_type s = mul_signs(u.sgn, v.sgn); + + if (s == SC_ZERO) // case 1 + return sc_signed(); + + // cases 2-4 + return mul_signed_friend(s, u.nbits, u.ndigits, u.digit, + v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator*(const sc_signed& u, int64 v) +{ + + small_type s = mul_signs(u.sgn, get_sign(v)); + + if (s == SC_ZERO) // case 1 + return sc_signed(); + + CONVERT_INT64_2(v); + + // cases 2-4 + return mul_signed_friend(s, u.nbits, u.ndigits, u.digit, + BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator*(int64 u, const sc_signed& v) +{ + + small_type s = mul_signs(v.sgn, get_sign(u)); + + if (s == SC_ZERO) // case 1 + return sc_signed(); + + CONVERT_INT64_2(u); + + // cases 2-4 + return mul_signed_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator*(const sc_unsigned& u, int64 v) +{ + + small_type s = mul_signs(u.sgn, get_sign(v)); + + if (s == SC_ZERO) // case 1 + return sc_signed(); + + CONVERT_INT64_2(v); + + // cases 2-4 + return mul_signed_friend(s, u.nbits, u.ndigits, u.digit, + BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator*(int64 u, const sc_unsigned& v) +{ + + small_type s = mul_signs(v.sgn, get_sign(u)); + + if (s == SC_ZERO) // case 1 + return sc_signed(); + + CONVERT_INT64_2(u); + + // cases 2-4 + return mul_signed_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator*(const sc_signed& u, uint64 v) +{ + + small_type s = mul_signs(u.sgn, get_sign(v)); + + if (s == SC_ZERO) // case 1 + return sc_signed(); + + CONVERT_INT64_2(v); + + // cases 2-4 + return mul_signed_friend(s, u.nbits, u.ndigits, u.digit, + BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator*(uint64 u, const sc_signed& v) +{ + + small_type s = mul_signs(v.sgn, get_sign(u)); + + if (s == SC_ZERO) // case 1 + return sc_signed(); + + CONVERT_INT64_2(u); + + // cases 2-4 + return mul_signed_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator*(const sc_signed& u, long v) +{ + + small_type s = mul_signs(u.sgn, get_sign(v)); + + if (s == SC_ZERO) // case 1 + return sc_signed(); + + CONVERT_LONG_2(v); + + // cases 2-4 + return mul_signed_friend(s, u.nbits, u.ndigits, u.digit, + BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_signed +operator*(long u, const sc_signed& v) +{ + + small_type s = mul_signs(v.sgn, get_sign(u)); + + if (s == SC_ZERO) // case 1 + return sc_signed(); + + CONVERT_LONG_2(u); + + // cases 2-4 + return mul_signed_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator*(const sc_unsigned& u, long v) +{ + + small_type s = mul_signs(u.sgn, get_sign(v)); + + if (s == SC_ZERO) // case 1 + return sc_signed(); + + CONVERT_LONG_2(v); + + // cases 2-4 + return mul_signed_friend(s, u.nbits, u.ndigits, u.digit, + BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_signed +operator*(long u, const sc_unsigned& v) +{ + + small_type s = mul_signs(v.sgn, get_sign(u)); + + if (s == SC_ZERO) // case 1 + return sc_signed(); + + CONVERT_LONG_2(u); + + // cases 2-4 + return mul_signed_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator*(const sc_signed& u, unsigned long v) +{ + + small_type s = mul_signs(u.sgn, get_sign(v)); + + if (s == SC_ZERO) // case 1 + return sc_signed(); + + CONVERT_LONG_2(v); + + // else cases 2-4 + return mul_signed_friend(s, u.nbits, u.ndigits, u.digit, + BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + +sc_signed +operator*(unsigned long u, const sc_signed& v) +{ + + small_type s = mul_signs(v.sgn, get_sign(u)); + + if (s == SC_ZERO) // case 1 + return sc_signed(); + + CONVERT_LONG_2(u); + + // cases 2-4 + return mul_signed_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.nbits, v.ndigits, v.digit); + +} + +// The rest of the operators in this section are included from +// sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: DIVISION operators: /, /= +// ---------------------------------------------------------------------------- + +// Cases to consider when finding the quotient q = floor(u/v): +// Note that u = q * v + r for r < q. +// 1. 0 / 0 or u / 0 => error +// 2. 0 / v => 0 = 0 * v + 0 +// 3. u / v && u = v => u = 1 * u + 0 - u or v can be 1 or -1 +// 4. u / v && u < v => u = 0 * v + u - u can be 1 or -1 +// 5. u / v && u > v => u = q * v + r - v can be 1 or -1 + +sc_signed +operator/(const sc_unsigned& u, const sc_signed& v) +{ + + small_type s = mul_signs(u.sgn, v.sgn); + + if (s == SC_ZERO) { + div_by_zero(v.sgn); // case 1 + return sc_signed(); // case 2 + } + + // other cases + return div_signed_friend(s, u.nbits, u.ndigits, u.digit, + v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator/(const sc_signed& u, const sc_unsigned& v) +{ + + small_type s = mul_signs(u.sgn, v.sgn); + + if (s == SC_ZERO) { + div_by_zero(v.sgn); // case 1 + return sc_signed(); // case 2 + } + + // other cases + return div_signed_friend(s, u.nbits, u.ndigits, u.digit, + v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator/(const sc_signed& u, const sc_signed& v) +{ + + small_type s = mul_signs(u.sgn, v.sgn); + + if (s == SC_ZERO) { + div_by_zero(v.sgn); // case 1 + return sc_signed(); // case 2 + } + + // other cases + return div_signed_friend(s, u.nbits, u.ndigits, u.digit, + v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator/(const sc_signed& u, int64 v) +{ + + small_type s = mul_signs(u.sgn, get_sign(v)); + + if (s == SC_ZERO) { + div_by_zero(v); // case 1 + return sc_signed(); // case 2 + } + + CONVERT_INT64_2(v); + + // other cases + return div_signed_friend(s, u.nbits, u.ndigits, u.digit, + BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator/(int64 u, const sc_signed& v) +{ + + small_type s = mul_signs(v.sgn, get_sign(u)); + + if (s == SC_ZERO) { + div_by_zero(v.sgn); // case 1 + return sc_signed(); // case 2 + } + + CONVERT_INT64_2(u); + + // other cases + return div_signed_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator/(const sc_unsigned& u, int64 v) +{ + + small_type s = mul_signs(u.sgn, get_sign(v)); + + if (s == SC_ZERO) { + div_by_zero(v); // case 1 + return sc_signed(); // case 2 + } + + CONVERT_INT64_2(v); + + // other cases + return div_signed_friend(s, u.nbits, u.ndigits, u.digit, + BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator/(int64 u, const sc_unsigned& v) +{ + + small_type s = mul_signs(v.sgn, get_sign(u)); + + if (s == SC_ZERO) { + div_by_zero(v.sgn); // case 1 + return sc_signed(); // case 2 + } + + CONVERT_INT64_2(u); + + // other cases + return div_signed_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator/(const sc_signed& u, uint64 v) +{ + + small_type s = mul_signs(u.sgn, get_sign(v)); + + if (s == SC_ZERO) { + div_by_zero(v); // case 1 + return sc_signed(); // case 2 + } + + CONVERT_INT64_2(v); + + // other cases + return div_signed_friend(s, u.nbits, u.ndigits, u.digit, + BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator/(uint64 u, const sc_signed& v) +{ + + small_type s = mul_signs(v.sgn, get_sign(u)); + + if (s == SC_ZERO) { + div_by_zero(v.sgn); // case 1 + return sc_signed(); // case 2 + + } + + CONVERT_INT64_2(u); + + // other cases + return div_signed_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator/(const sc_signed& u, long v) +{ + + small_type s = mul_signs(u.sgn, get_sign(v)); + + if (s == SC_ZERO) { + div_by_zero(v); // case 1 + return sc_signed(); // case 2 + } + + CONVERT_LONG_2(v); + + // other cases + return div_signed_friend(s, u.nbits, u.ndigits, u.digit, + BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_signed +operator/(long u, const sc_signed& v) +{ + + small_type s = mul_signs(v.sgn, get_sign(u)); + + if (s == SC_ZERO) { + div_by_zero(v.sgn); // case 1 + return sc_signed(); // case 2 + } + + CONVERT_LONG_2(u); + + // other cases + return div_signed_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator/(const sc_unsigned& u, long v) +{ + + small_type s = mul_signs(u.sgn, get_sign(v)); + + if (s == SC_ZERO) { + div_by_zero(v); // case 1 + return sc_signed(); // case 2 + } + + CONVERT_LONG_2(v); + + // other cases + return div_signed_friend(s, u.nbits, u.ndigits, u.digit, + BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_signed +operator/(long u, const sc_unsigned& v) +{ + + small_type s = mul_signs(v.sgn, get_sign(u)); + + if (s == SC_ZERO) { + div_by_zero(v.sgn); // case 1 + return sc_signed(); // case 2 + } + + CONVERT_LONG_2(u); + + // other cases + return div_signed_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator/(const sc_signed& u, unsigned long v) +{ + + small_type s = mul_signs(u.sgn, get_sign(v)); + + if (s == SC_ZERO) { + div_by_zero(v); // case 1 + return sc_signed(); // case 2 + } + + CONVERT_LONG_2(v); + + // other cases + return div_signed_friend(s, u.nbits, u.ndigits, u.digit, + BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_signed +operator/(unsigned long u, const sc_signed& v) +{ + + small_type s = mul_signs(v.sgn, get_sign(u)); + + if (s == SC_ZERO) { + div_by_zero(v.sgn); // case 1 + return sc_signed(); // case 2 + + } + + CONVERT_LONG_2(u); + + // other cases + return div_signed_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.nbits, v.ndigits, v.digit); + +} + +// The rest of the operators in this section are included from +// sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: MOD operators: %, %=. +// ---------------------------------------------------------------------------- + +// Cases to consider when finding the remainder r = u % v: +// Note that u = q * v + r for r < q. +// 1. 0 % 0 or u % 0 => error +// 2. 0 % v => 0 = 0 * v + 0 +// 3. u % v && u = v => u = 1 * u + 0 - u or v can be 1 or -1 +// 4. u % v && u < v => u = 0 * v + u - u can be 1 or -1 +// 5. u % v && u > v => u = q * v + r - v can be 1 or -1 + +sc_signed +operator%(const sc_unsigned& u, const sc_signed& v) +{ + + if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) { + div_by_zero(v.sgn); // case 1 + return sc_signed(); // case 2 + } + + // other cases + return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + v.nbits, v.ndigits, v.digit); +} + + +sc_signed +operator%(const sc_signed& u, const sc_unsigned& v) +{ + + if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) { + div_by_zero(v.sgn); // case 1 + return sc_signed(); // case 2 + } + + // other cases + return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + v.nbits, v.ndigits, v.digit); +} + + +sc_signed +operator%(const sc_signed& u, const sc_signed& v) +{ + + if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) { + div_by_zero(v.sgn); // case 1 + return sc_signed(); // case 2 + } + + // other cases + return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + v.nbits, v.ndigits, v.digit); +} + + +sc_signed +operator%(const sc_signed& u, int64 v) +{ + + small_type vs = get_sign(v); + + if ((u.sgn == SC_ZERO) || (vs == SC_ZERO)) { + div_by_zero(v); // case 1 + return sc_signed(); // case 2 + } + + CONVERT_INT64_2(v); + + // other cases + return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator%(int64 u, const sc_signed& v) +{ + + small_type us = get_sign(u); + + if ((us == SC_ZERO) || (v.sgn == SC_ZERO)) { + div_by_zero(v.sgn); // case 1 + return sc_signed(); // case 2 + } + + CONVERT_INT64_2(u); + + // other cases + return mod_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator%(const sc_unsigned& u, int64 v) +{ + + small_type vs = get_sign(v); + + if ((u.sgn == SC_ZERO) || (vs == SC_ZERO)) { + div_by_zero(v); // case 1 + return sc_signed(); // case 2 + } + + CONVERT_INT64_2(v); + + // other cases + return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator%(int64 u, const sc_unsigned& v) +{ + + small_type us = get_sign(u); + + if ((us == SC_ZERO) || (v.sgn == SC_ZERO)) { + div_by_zero(v.sgn); // case 1 + return sc_signed(); // case 2 + } + + CONVERT_INT64_2(u); + + // other cases + return mod_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator%(const sc_signed& u, uint64 v) +{ + + if ((u.sgn == SC_ZERO) || (v == 0)) { + div_by_zero(v); // case 1 + return sc_signed(); // case 2 + } + + CONVERT_INT64_2(v); + + // other cases + return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator%(uint64 u, const sc_signed& v) +{ + + if ((u == 0) || (v.sgn == SC_ZERO)) { + div_by_zero(v.sgn); // case 1 + return sc_signed(); // case 2 + } + + CONVERT_INT64(u); + + // other cases + return mod_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator%(const sc_signed& u, long v) +{ + + small_type vs = get_sign(v); + + if ((u.sgn == SC_ZERO) || (vs == SC_ZERO)) { + div_by_zero(v); // case 1 + return sc_signed(); // case 2 + } + + CONVERT_LONG_2(v); + + // other cases + return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + BITS_PER_ULONG, DIGITS_PER_ULONG, vd); +} + + +sc_signed +operator%(long u, const sc_signed& v) +{ + + small_type us = get_sign(u); + + if ((us == SC_ZERO) || (v.sgn == SC_ZERO)) { + div_by_zero(v.sgn); // case 1 + return sc_signed(); // case 2 + } + + CONVERT_LONG_2(u); + + // other cases + return mod_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator%(const sc_unsigned& u, long v) +{ + + small_type vs = get_sign(v); + + if ((u.sgn == SC_ZERO) || (vs == SC_ZERO)) { + div_by_zero(v); // case 1 + return sc_signed(); // case 2 + } + + CONVERT_LONG_2(v); + + // other cases + return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + BITS_PER_ULONG, DIGITS_PER_ULONG, vd); +} + + +sc_signed +operator%(long u, const sc_unsigned& v) +{ + + small_type us = get_sign(u); + + if ((us == SC_ZERO) || (v.sgn == SC_ZERO)) { + div_by_zero(v.sgn); // case 1 + return sc_signed(); // case 2 + } + + CONVERT_LONG_2(u); + + // other cases + return mod_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator%(const sc_signed& u, unsigned long v) +{ + + if ((u.sgn == SC_ZERO) || (v == 0)) { + div_by_zero(v); // case 1 + return sc_signed(); // case 2 + } + + CONVERT_LONG_2(v); + + // other cases + return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_signed +operator%(unsigned long u, const sc_signed& v) +{ + + if ((u == 0) || (v.sgn == SC_ZERO)) { + div_by_zero(v.sgn); // case 1 + return sc_signed(); // case 2 + } + + CONVERT_LONG(u); + + // other cases + return mod_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.nbits, v.ndigits, v.digit); + +} + +// The rest of the operators in this section are included from +// sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: Bitwise AND operators: &, &= +// ---------------------------------------------------------------------------- + +// Cases to consider when computing u & v: +// 1. u & 0 = 0 & v = 0 +// 2. u & v => sgn = + +// 3. (-u) & (-v) => sgn = - +// 4. u & (-v) => sgn = + +// 5. (-u) & v => sgn = + + +sc_signed +operator&(const sc_unsigned& u, const sc_signed& v) +{ + + if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) // case 1 + return sc_signed(); + + // other cases + return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator&(const sc_signed& u, const sc_unsigned& v) +{ + + if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) // case 1 + return sc_signed(); + + // other cases + return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator&(const sc_signed& u, const sc_signed& v) +{ + + if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) // case 1 + return sc_signed(); + + // other cases + return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator&(const sc_signed& u, int64 v) +{ + + if ((u.sgn == SC_ZERO) || (v == 0)) // case 1 + return sc_signed(); + + CONVERT_INT64(v); + + // other cases + return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator&(int64 u, const sc_signed& v) +{ + + if ((u == 0) || (v.sgn == SC_ZERO)) // case 1 + return sc_signed(); + + CONVERT_INT64(u); + + // other cases + return and_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator&(const sc_unsigned& u, int64 v) +{ + + if ((u.sgn == SC_ZERO) || (v == 0)) // case 1 + return sc_signed(); + + CONVERT_INT64(v); + + // other cases + return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator&(int64 u, const sc_unsigned& v) +{ + + if ((u == 0) || (v.sgn == SC_ZERO)) // case 1 + return sc_signed(); + + CONVERT_INT64(u); + + // other cases + return and_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator&(const sc_signed& u, uint64 v) +{ + + if ((u.sgn == SC_ZERO) || (v == 0)) // case 1 + return sc_signed(); + + CONVERT_INT64(v); + + // other cases + return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator&(uint64 u, const sc_signed& v) +{ + + if ((u == 0) || (v.sgn == SC_ZERO)) // case 1 + return sc_signed(); + + CONVERT_INT64(u); + + // other cases + return and_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator&(const sc_signed& u, long v) +{ + + if ((u.sgn == SC_ZERO) || (v == 0)) // case 1 + return sc_signed(); + + CONVERT_LONG(v); + + // other cases + return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_signed +operator&(long u, const sc_signed& v) +{ + + if ((u == 0) || (v.sgn == SC_ZERO)) // case 1 + return sc_signed(); + + CONVERT_LONG(u); + + // other cases + return and_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator&(const sc_unsigned& u, long v) +{ + + if ((u.sgn == SC_ZERO) || (v == 0)) // case 1 + return sc_signed(); + + CONVERT_LONG(v); + + // other cases + return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_signed +operator&(long u, const sc_unsigned& v) +{ + + if ((u == 0) || (v.sgn == SC_ZERO)) // case 1 + return sc_signed(); + + CONVERT_LONG(u); + + // other cases + return and_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator&(const sc_signed& u, unsigned long v) +{ + + if ((u.sgn == SC_ZERO) || (v == 0)) // case 1 + return sc_signed(); + + CONVERT_LONG(v); + + // other cases + return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_signed +operator&(unsigned long u, const sc_signed& v) +{ + + if ((u == 0) || (v.sgn == SC_ZERO)) // case 1 + return sc_signed(); + + CONVERT_LONG(u); + + // other cases + return and_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + +// The rest of the operators in this section are included from +// sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: Bitwise OR operators: |, |= +// ---------------------------------------------------------------------------- + +// Cases to consider when computing u | v: +// 1. u | 0 = u +// 2. 0 | v = v +// 3. u | v => sgn = + +// 4. (-u) | (-v) => sgn = - +// 5. u | (-v) => sgn = - +// 6. (-u) | v => sgn = - + +sc_signed +operator|(const sc_unsigned& u, const sc_signed& v) +{ + + if (v.sgn == SC_ZERO) // case 1 + return sc_signed(u); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(v); + + // other cases + return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator|(const sc_signed& u, const sc_unsigned& v) +{ + + if (v.sgn == SC_ZERO) // case 1 + return sc_signed(u); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(v); + + // other cases + return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator|(const sc_signed& u, const sc_signed& v) +{ + + if (v.sgn == SC_ZERO) // case 1 + return sc_signed(u); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(v); + + // other cases + return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator|(const sc_signed& u, int64 v) +{ + + if (v == 0) // case 1 + return sc_signed(u); + + CONVERT_INT64(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false); + + // other cases + return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator|(int64 u, const sc_signed& v) +{ + + if (u == 0) + return sc_signed(v); + + CONVERT_INT64(u); + + if (v.sgn == SC_ZERO) + return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false); + + // other cases + return or_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator|(const sc_unsigned& u, int64 v) +{ + + if (v == 0) // case 1 + return sc_signed(u); + + CONVERT_INT64(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false); + + // other cases + return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator|(int64 u, const sc_unsigned& v) +{ + + if (u == 0) + return sc_signed(v); + + CONVERT_INT64(u); + + if (v.sgn == SC_ZERO) + return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false); + + // other cases + return or_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator|(const sc_signed& u, uint64 v) +{ + + if (v == 0) // case 1 + return sc_signed(u); + + CONVERT_INT64(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false); + + // other cases + return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator|(uint64 u, const sc_signed& v) +{ + + if (u == 0) + return sc_signed(v); + + CONVERT_INT64(u); + + if (v.sgn == SC_ZERO) + return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false); + + // other cases + return or_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator|(const sc_signed& u, long v) +{ + + if (v == 0) // case 1 + return sc_signed(u); + + CONVERT_LONG(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false); + + // other cases + return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_signed +operator|(long u, const sc_signed& v) +{ + + if (u == 0) + return sc_signed(v); + + CONVERT_LONG(u); + + if (v.sgn == SC_ZERO) + return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false); + + // other cases + return or_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator|(const sc_unsigned& u, long v) +{ + + if (v == 0) // case 1 + return sc_signed(u); + + CONVERT_LONG(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false); + + // other cases + return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_signed +operator|(long u, const sc_unsigned& v) +{ + + if (u == 0) + return sc_signed(v); + + CONVERT_LONG(u); + + if (v.sgn == SC_ZERO) + return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false); + + // other cases + return or_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator|(const sc_signed& u, unsigned long v) +{ + + if (v == 0) // case 1 + return sc_signed(u); + + CONVERT_LONG(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false); + + // other cases + return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_signed +operator|(unsigned long u, const sc_signed& v) +{ + + if (u == 0) + return sc_signed(v); + + CONVERT_LONG(u); + + if (v.sgn == SC_ZERO) + return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false); + + // other cases + return or_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + +// The rest of the operators in this section are included from +// sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: Bitwise XOR operators: ^, ^= +// ---------------------------------------------------------------------------- + +// Cases to consider when computing u ^ v: +// Note that u ^ v = (~u & v) | (u & ~v). +// 1. u ^ 0 = u +// 2. 0 ^ v = v +// 3. u ^ v => sgn = + +// 4. (-u) ^ (-v) => sgn = - +// 5. u ^ (-v) => sgn = - +// 6. (-u) ^ v => sgn = + + +sc_signed +operator^(const sc_unsigned& u, const sc_signed& v) +{ + + if (v.sgn == SC_ZERO) // case 1 + return sc_signed(u); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(v); + + // other cases + return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator^(const sc_signed& u, const sc_unsigned& v) +{ + + if (v.sgn == SC_ZERO) // case 1 + return sc_signed(u); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(v); + + // other cases + return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator^(const sc_signed& u, const sc_signed& v) +{ + + if (v.sgn == SC_ZERO) // case 1 + return sc_signed(u); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(v); + + // other cases + return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator^(const sc_signed& u, int64 v) +{ + + if (v == 0) // case 1 + return sc_signed(u); + + CONVERT_INT64(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false); + + // other cases + return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator^(int64 u, const sc_signed& v) +{ + + if (u == 0) + return sc_signed(v); + + CONVERT_INT64(u); + + if (v.sgn == SC_ZERO) + return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false); + + // other cases + return xor_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator^(const sc_unsigned& u, int64 v) +{ + + if (v == 0) // case 1 + return sc_signed(u); + + CONVERT_INT64(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false); + + // other cases + return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_signed +operator^(int64 u, const sc_unsigned& v) +{ + + if (u == 0) + return sc_signed(v); + + CONVERT_INT64(u); + + if (v.sgn == SC_ZERO) + return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false); + + // other cases + return xor_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator^(const sc_signed& u, uint64 v) +{ + + if (v == 0) // case 1 + return sc_signed(u); + + CONVERT_INT64(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false); + + // other cases + return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + +sc_signed +operator^(uint64 u, const sc_signed& v) +{ + if (u == 0) + return sc_signed(v); + + CONVERT_INT64(u); + + if (v.sgn == SC_ZERO) + return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false); + + // other cases + return xor_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator^(const sc_signed& u, long v) +{ + + if (v == 0) // case 1 + return sc_signed(u); + + CONVERT_LONG(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false); + + // other cases + return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_signed +operator^(long u, const sc_signed& v) +{ + + if (u == 0) + return sc_signed(v); + + CONVERT_LONG(u); + + if (v.sgn == SC_ZERO) + return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false); + + // other cases + return xor_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator^(const sc_unsigned& u, long v) +{ + + if (v == 0) // case 1 + return sc_signed(u); + + CONVERT_LONG(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false); + + // other cases + return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_signed +operator^(long u, const sc_unsigned& v) +{ + + if (u == 0) + return sc_signed(v); + + CONVERT_LONG(u); + + if (v.sgn == SC_ZERO) + return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false); + + // other cases + return xor_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_signed +operator^(const sc_signed& u, unsigned long v) +{ + + if (v == 0) // case 1 + return sc_signed(u); + + CONVERT_LONG(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false); + + // other cases + return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + +sc_signed +operator^(unsigned long u, const sc_signed& v) +{ + if (u == 0) + return sc_signed(v); + + CONVERT_LONG(u); + + if (v.sgn == SC_ZERO) + return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false); + + // other cases + return xor_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + +// The rest of the operators in this section are included from +// sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: Bitwise NOT operator: ~ +// ---------------------------------------------------------------------------- + +// Operators in this section are included from sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: LEFT SHIFT operators: <<, <<= +// ---------------------------------------------------------------------------- + +sc_signed +operator<<(const sc_signed& u, const sc_unsigned& v) +{ + if (v.sgn == SC_ZERO) + return sc_signed(u); + + return operator<<(u, v.to_ulong()); +} + +// The rest of the operators in this section are included from +// sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: RIGHT SHIFT operators: >>, >>= +// ---------------------------------------------------------------------------- + +sc_signed +operator>>(const sc_signed& u, const sc_unsigned& v) +{ + + if (v.sgn == SC_ZERO) + return sc_signed(u); + + return operator>>(u, v.to_ulong()); + +} + +// The rest of the operators in this section are included from +// sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: Unary arithmetic operators. +// ---------------------------------------------------------------------------- + +sc_signed +operator+(const sc_signed& u) +{ + return sc_signed(u); +} + +sc_signed +operator-(const sc_signed& u) +{ + return sc_signed(u, -u.sgn); +} + +sc_signed +operator-(const sc_unsigned& u) +{ + return sc_signed(u, -u.sgn); +} + + +// ---------------------------------------------------------------------------- +// SECTION: EQUAL operator: == +// ---------------------------------------------------------------------------- + +bool +operator==(const sc_signed& u, const sc_signed& v) +{ + + if (u.sgn != v.sgn) + return false; + + if (&u == &v) + return true; + + if (vec_skip_and_cmp(u.ndigits, u.digit, v.ndigits, v.digit) != 0) + return false; + + return true; + +} + + +bool +operator==(const sc_signed& u, int64 v) +{ + + CONVERT_INT64(v); + + if (u.sgn != vs) + return false; + + if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_INT64, vd) != 0) + return false; + + return true; + +} + + +bool +operator==(int64 u, const sc_signed& v) +{ + + CONVERT_INT64(u); + + if (us != v.sgn) + return false; + + if (vec_skip_and_cmp(DIGITS_PER_INT64, ud, v.ndigits, v.digit) != 0) + return false; + + return true; + +} + + +bool +operator==(const sc_signed& u, uint64 v) +{ + + CONVERT_INT64(v); + + if (u.sgn != vs) + return false; + + if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_INT64, vd) != 0) + return false; + + return true; + +} + + +bool +operator==(uint64 u, const sc_signed& v) +{ + + CONVERT_INT64(u); + + if (us != v.sgn) + return false; + + if (vec_skip_and_cmp(DIGITS_PER_INT64, ud, v.ndigits, v.digit) != 0) + return false; + + return true; + +} + + +bool +operator==(const sc_signed& u, long v) +{ + + CONVERT_LONG(v); + + if (u.sgn != vs) + return false; + + if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_LONG, vd) != 0) + return false; + + return true; + +} + + +bool +operator==(long u, const sc_signed& v) +{ + + CONVERT_LONG(u); + + if (us != v.sgn) + return false; + + if (vec_skip_and_cmp(DIGITS_PER_LONG, ud, v.ndigits, v.digit) != 0) + return false; + + return true; + +} + + +bool +operator==(const sc_signed& u, unsigned long v) +{ + + CONVERT_LONG(v); + + if (u.sgn != vs) + return false; + + if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_LONG, vd) != 0) + return false; + + return true; + +} + + +bool +operator==(unsigned long u, const sc_signed& v) +{ + + CONVERT_LONG(u); + + if (us != v.sgn) + return false; + + if (vec_skip_and_cmp(DIGITS_PER_LONG, ud, v.ndigits, v.digit) != 0) + return false; + + return true; + +} + + +// ---------------------------------------------------------------------------- +// SECTION: NOT_EQUAL operator: != +// ---------------------------------------------------------------------------- + +// Operators in this section are included from sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: LESS THAN operator: < +// ---------------------------------------------------------------------------- + +bool +operator<(const sc_signed& u, const sc_signed& v) +{ + + if (u.sgn < v.sgn) + return true; + + if (u.sgn > v.sgn) + return false; + + // u.sgn == v.sgn + + if (&u == &v) + return false; + + if (u.sgn == SC_POS) { + + if (vec_skip_and_cmp(u.ndigits, u.digit, v.ndigits, v.digit) < 0) + return true; + + } + else if (u.sgn == SC_NEG) { + + if (vec_skip_and_cmp(u.ndigits, u.digit, v.ndigits, v.digit) > 0) + return true; + + } + + return false; + +} + + +bool +operator<(const sc_signed& u, int64 v) +{ + + CONVERT_INT64(v); + + if (u.sgn < vs) + return true; + + if (u.sgn > vs) + return false; + + // u.sgn == vs + + if (vs == SC_POS) { + + if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_INT64, vd) < 0) + return true; + + } + else if (vs == SC_NEG) { + + if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_INT64, vd) > 0) + return true; + + } + + return false; + +} + + +bool +operator<(int64 u, const sc_signed& v) +{ + + CONVERT_INT64(u); + + if (us < v.sgn) + return true; + + if (us > v.sgn) + return false; + + // us == v.sgn + + if (us == SC_POS) { + + if (vec_skip_and_cmp(DIGITS_PER_INT64, ud, v.ndigits, v.digit) < 0) + return true; + + } + else if (us == SC_NEG) { + + if (vec_skip_and_cmp(DIGITS_PER_INT64, ud, v.ndigits, v.digit) > 0) + return true; + + } + + return false; + +} + + +bool +operator<(const sc_signed& u, uint64 v) +{ + + CONVERT_INT64(v); + + if (u.sgn < vs) + return true; + + if (u.sgn > vs) + return false; + + // u.sgn == vs + + if (vs == SC_POS) { + + if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_INT64, vd) < 0) + return true; + + } + + return false; + +} + + +bool +operator<(uint64 u, const sc_signed& v) +{ + + CONVERT_INT64(u); + + if (us < v.sgn) + return true; + + if (us > v.sgn) + return false; + + // us == v.sgn + + if (us == SC_POS) { + + if (vec_skip_and_cmp(DIGITS_PER_INT64, ud, v.ndigits, v.digit) < 0) + return true; + + } + + return false; + +} + + +bool +operator<(const sc_signed& u, long v) +{ + + CONVERT_LONG(v); + + if (u.sgn < vs) + return true; + + if (u.sgn > vs) + return false; + + // u.sgn == vs + + if (vs == SC_POS) { + + if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_LONG, vd) < 0) + return true; + + } + else if (vs == SC_NEG) { + + if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_LONG, vd) > 0) + return true; + + } + + return false; + +} + + +bool +operator<(long u, const sc_signed& v) +{ + CONVERT_LONG(u); + + if (us < v.sgn) + return true; + + if (us > v.sgn) + return false; + + // us == v.sgn + + if (us == SC_POS) { + + if (vec_skip_and_cmp(DIGITS_PER_LONG, ud, v.ndigits, v.digit) < 0) + return true; + + } + else if (us == SC_NEG) { + + if (vec_skip_and_cmp(DIGITS_PER_LONG, ud, v.ndigits, v.digit) > 0) + return true; + + } + + return false; +} + + +bool +operator<(const sc_signed& u, unsigned long v) +{ + CONVERT_LONG(v); + + if (u.sgn < vs) + return true; + + if (u.sgn > vs) + return false; + + // u.sgn == vs + + if (vs == SC_POS) { + + if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_LONG, vd) < 0) + return true; + + } + + return false; +} + + +bool +operator<(unsigned long u, const sc_signed& v) +{ + CONVERT_LONG(u); + + if (us < v.sgn) + return true; + + if (us > v.sgn) + return false; + + // us == v.sgn + + if (us == SC_POS) { + + if (vec_skip_and_cmp(DIGITS_PER_LONG, ud, v.ndigits, v.digit) < 0) + return true; + + } + + return false; +} + + +// --------------------------------------------------------------------------- +// SECTION: LESS THAN or EQUAL operator: <= +// --------------------------------------------------------------------------- + +// Operators in this section are included from sc_nbcommon.cpp. + + +// --------------------------------------------------------------------------- +// SECTION: GREATER THAN operator: > +// --------------------------------------------------------------------------- + +// Operators in this section are included from sc_nbcommon.cpp. + + +// --------------------------------------------------------------------------- +// SECTION: GREATER THAN or EQUAL operator: >= +// --------------------------------------------------------------------------- + +// Operators in this section are included from sc_nbcommon.cpp. + + +// --------------------------------------------------------------------------- +// SECTION: Public members - Other utils. +// --------------------------------------------------------------------------- + +bool +sc_signed::iszero() const +{ + if (sgn == SC_ZERO) + return true; + else if (sgn != SC_NOSIGN) + return false; + else + return check_for_zero(ndigits, digit); +} + + +bool +sc_signed::sign() const +{ + if (sgn == SC_NEG) + return 1; + else if (sgn != SC_NOSIGN) + return 0; + else + return ((digit[ndigits - 1] & one_and_zeros(bit_ord(nbits - 1))) != 0); +} + +// The rest of the utils in this section are included from sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: Private members. +// ---------------------------------------------------------------------------- + +// The private members in this section are included from sc_nbcommon.cpp. + +#define CLASS_TYPE sc_signed +#define CLASS_TYPE_STR "sc_signed" + +#define ADD_HELPER add_signed_friend +#define SUB_HELPER sub_signed_friend +#define MUL_HELPER mul_signed_friend +#define DIV_HELPER div_signed_friend +#define MOD_HELPER mod_signed_friend +#define AND_HELPER and_signed_friend +#define OR_HELPER or_signed_friend +#define XOR_HELPER xor_signed_friend + +#include "sc_nbfriends.inc" + +#undef SC_UNSIGNED +#define SC_SIGNED +#define IF_SC_SIGNED 1 // 1 = sc_signed +#define CLASS_TYPE_SUBREF sc_signed_subref_r +#define OTHER_CLASS_TYPE sc_unsigned +#define OTHER_CLASS_TYPE_SUBREF sc_unsigned_subref_r + +#define MUL_ON_HELPER mul_on_help_signed +#define DIV_ON_HELPER div_on_help_signed +#define MOD_ON_HELPER mod_on_help_signed + +#include "sc_nbcommon.inc" + +#undef MOD_ON_HELPER +#undef DIV_ON_HELPER +#undef MUL_ON_HELPER + +#undef OTHER_CLASS_TYPE_SUBREF +#undef OTHER_CLASS_TYPE +#undef CLASS_TYPE_SUBREF +#undef IF_SC_SIGNED +#undef SC_SIGNED + +#undef XOR_HELPER +#undef OR_HELPER +#undef AND_HELPER +#undef MOD_HELPER +#undef DIV_HELPER +#undef MUL_HELPER +#undef SUB_HELPER +#undef ADD_HELPER + +#undef CLASS_TYPE +#undef CLASS_TYPE_STR + +#include "sc_signed_bitref.inc" +#include "sc_signed_subref.inc" + +#undef CONVERT_LONG +#undef CONVERT_LONG_2 +#undef CONVERT_INT64 +#undef CONVERT_INT64_2 + +} // namespace sc_dt + + +// End of file. diff --git a/ext/systemc/src/sysc/datatypes/int/sc_signed.h b/ext/systemc/src/sysc/datatypes/int/sc_signed.h new file mode 100644 index 000000000..8e2d4f541 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_signed.h @@ -0,0 +1,2382 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_signed.h -- Arbitrary precision signed arithmetic. + + This file includes the definitions of sc_signed_bitref, + sc_signed_subref, and sc_signed classes. The first two classes are + proxy classes to reference one bit and a range of bits of a + sc_signed number, respectively. + + An sc_signed number has the sign-magnitude representation + internally. However, its interface guarantees a 2's-complement + representation. The sign-magnitude representation is chosen + because of its efficiency: The sc_signed and sc_unsigned types are + optimized for arithmetic rather than bitwise operations. For + arithmetic operations, the sign-magnitude representation performs + better. + + The implementations of sc_signed and sc_unsigned classes are + almost identical: Most of the member and friend functions are + defined in sc_nbcommon.cpp and sc_nbfriends.cpp so that they can + be shared by both of these classes. These functions are chosed by + defining a few macros before including them such as IF_SC_SIGNED + and CLASS_TYPE. Our implementation choices are mostly dictated by + performance considerations in that we tried to provide the most + efficient sc_signed and sc_unsigned types without compromising + their interface. + + For the behavior of operators, we have two semantics: the old and + new. The most important difference between these two semantics is + that the old semantics is closer to C/C++ semantics in that the + result type of a binary operator on unsigned and signed arguments + is unsigned; the new semantics, on the other hand, requires the + result type be signed. The new semantics is required by the VSIA + C/C++ data types standard. We have implemented the new semantics. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_signed.h,v $ +// Revision 1.3 2011/08/24 22:05:46 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.2 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.5 2006/05/08 17:50:01 acg +// Andy Goodrich: Added David Long's declarations for friend operators, +// functions, and methods, to keep the Microsoft compiler happy. +// +// Revision 1.4 2006/03/13 20:25:27 acg +// Andy Goodrich: Addition of function declarations, e.g., xor_signed_friend() +// to keep gcc 4.x happy. +// +// Revision 1.3 2006/01/13 18:49:32 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef SC_SIGNED_H +#define SC_SIGNED_H + + +#include "sysc/kernel/sc_object.h" +#include "sysc/datatypes/misc/sc_value_base.h" +#include "sysc/utils/sc_iostream.h" +#include "sysc/utils/sc_temporary.h" +#include "sysc/datatypes/int/sc_length_param.h" +#include "sysc/datatypes/int/sc_nbdefs.h" +#include "sysc/datatypes/int/sc_nbutils.h" +#include "sysc/datatypes/int/sc_nbexterns.h" +#include "sysc/datatypes/int/sc_unsigned.h" + + +namespace sc_dt +{ + +// classes defined in this module +class sc_signed_bitref_r; +class sc_signed_bitref; +class sc_signed_subref_r; +class sc_signed_subref; +class sc_concatref; +class sc_signed; + +// forward class declarations +class sc_bv_base; +class sc_lv_base; +class sc_int_base; +class sc_uint_base; +class sc_int_subref_r; +class sc_uint_subref_r; +class sc_signed; +class sc_unsigned; +class sc_unsigned_subref_r; +class sc_fxval; +class sc_fxval_fast; +class sc_fxnum; +class sc_fxnum_fast; + + +// Helper function declarations +sc_signed add_signed_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + small_type vs, + int vnb, + int vnd, + const sc_digit *vd); + +sc_signed sub_signed_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + small_type vs, + int vnb, + int vnd, + const sc_digit *vd); + +sc_signed mul_signed_friend(small_type s, + int unb, + int und, + const sc_digit *ud, + int vnb, + int vnd, + const sc_digit *vd); + +sc_signed div_signed_friend(small_type s, + int unb, + int und, + const sc_digit *ud, + int vnb, + int vnd, + const sc_digit *vd); + +sc_signed mod_signed_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + int vnb, + int vnd, + const sc_digit *vd); + +sc_signed and_signed_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + small_type vs, + int vnb, + int vnd, + const sc_digit *vd); + +sc_signed or_signed_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + small_type vs, + int vnb, + int vnd, + const sc_digit *vd); + +sc_signed xor_signed_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + small_type vs, + int vnb, + int vnd, + const sc_digit *vd); + + +// friend operator declarations + // ARITHMETIC OPERATORS: + + // ADDition operators: + + sc_signed operator + (const sc_unsigned& u, const sc_signed& v); + sc_signed operator + (const sc_signed& u, const sc_unsigned& v); + + sc_signed operator + (const sc_unsigned& u, int64 v); + sc_signed operator + (const sc_unsigned& u, long v); + inline sc_signed operator + (const sc_unsigned& u, int v); + + sc_signed operator + (int64 u, const sc_unsigned& v); + sc_signed operator + (long u, const sc_unsigned& v); + inline sc_signed operator + (int u, const sc_unsigned& v); + + sc_signed operator + (const sc_signed& u, const sc_signed& v); + sc_signed operator + (const sc_signed& u, int64 v); + sc_signed operator + (const sc_signed& u, uint64 v); + sc_signed operator + (const sc_signed& u, long v); + sc_signed operator + (const sc_signed& u, unsigned long v); + inline sc_signed operator + (const sc_signed& u, int v); + inline sc_signed operator + (const sc_signed& u, unsigned int v); + + sc_signed operator + (int64 u, const sc_signed& v); + sc_signed operator + (uint64 u, const sc_signed& v); + sc_signed operator + (long u, const sc_signed& v); + sc_signed operator + (unsigned long u, const sc_signed& v); + inline sc_signed operator + (int u, const sc_signed& v); + inline sc_signed operator + (unsigned int u, const sc_signed& v); + + sc_signed operator + (const sc_unsigned& u, const sc_int_base& v); + sc_signed operator + (const sc_int_base& u, const sc_unsigned& v); + sc_signed operator + (const sc_signed& u, const sc_int_base& v); + sc_signed operator + (const sc_signed& u, const sc_uint_base& v); + sc_signed operator + (const sc_int_base& u, const sc_signed& v); + sc_signed operator + (const sc_uint_base& u, const sc_signed& v); + + + + // SUBtraction operators: + + sc_signed operator - (const sc_unsigned& u, const sc_signed& v); + sc_signed operator - (const sc_signed& u, const sc_unsigned& v); + + sc_signed operator - (const sc_unsigned& u, const sc_unsigned& v); + sc_signed operator - (const sc_unsigned& u, int64 v); + sc_signed operator - (const sc_unsigned& u, uint64 v); + sc_signed operator - (const sc_unsigned& u, long v); + sc_signed operator - (const sc_unsigned& u, unsigned long v); + inline sc_signed operator - (const sc_unsigned& u, int v); + inline sc_signed operator - (const sc_unsigned& u, unsigned int v); + + sc_signed operator - (int64 u, const sc_unsigned& v); + sc_signed operator - (uint64 u, const sc_unsigned& v); + sc_signed operator - (long u, const sc_unsigned& v); + sc_signed operator - (unsigned long u, const sc_unsigned& v); + inline sc_signed operator - (int u, const sc_unsigned& v); + inline sc_signed operator - (unsigned int u, const sc_unsigned& v); + + sc_signed operator - (const sc_signed& u, const sc_signed& v); + sc_signed operator - (const sc_signed& u, int64 v); + sc_signed operator - (const sc_signed& u, uint64 v); + sc_signed operator - (const sc_signed& u, long v); + sc_signed operator - (const sc_signed& u, unsigned long v); + inline sc_signed operator - (const sc_signed& u, int v); + inline sc_signed operator - (const sc_signed& u, unsigned int v); + + sc_signed operator - (int64 u, const sc_signed& v); + sc_signed operator - (uint64 u, const sc_signed& v); + sc_signed operator - (long u, const sc_signed& v); + sc_signed operator - (unsigned long u, const sc_signed& v); + inline sc_signed operator - (int u, const sc_signed& v); + inline sc_signed operator - (unsigned int u, const sc_signed& v); + + + sc_signed operator - (const sc_unsigned& u, const sc_int_base& v); + sc_signed operator - (const sc_unsigned& u, const sc_uint_base& v); + sc_signed operator - (const sc_int_base& u, const sc_unsigned& v); + sc_signed operator - (const sc_uint_base& u, const sc_unsigned& v); + sc_signed operator - (const sc_signed& u, const sc_int_base& v); + sc_signed operator - (const sc_signed& u, const sc_uint_base& v); + sc_signed operator - (const sc_int_base& u, const sc_signed& v); + sc_signed operator - (const sc_uint_base& u, const sc_signed& v); + + + + // MULtiplication operators: + + sc_signed operator * (const sc_unsigned& u, const sc_signed& v); + sc_signed operator * (const sc_signed& u, const sc_unsigned& v); + + sc_signed operator * (const sc_unsigned& u, int64 v); + sc_signed operator * (const sc_unsigned& u, long v); + inline sc_signed operator * (const sc_unsigned& u, int v); + + sc_signed operator * (int64 u, const sc_unsigned& v); + sc_signed operator * (long u, const sc_unsigned& v); + inline sc_signed operator * (int u, const sc_unsigned& v); + + sc_signed operator * (const sc_signed& u, const sc_signed& v); + sc_signed operator * (const sc_signed& u, int64 v); + sc_signed operator * (const sc_signed& u, uint64 v); + sc_signed operator * (const sc_signed& u, long v); + sc_signed operator * (const sc_signed& u, unsigned long v); + inline sc_signed operator * (const sc_signed& u, int v); + inline sc_signed operator * (const sc_signed& u, unsigned int v); + + sc_signed operator * (int64 u, const sc_signed& v); + sc_signed operator * (uint64 u, const sc_signed& v); + sc_signed operator * (long u, const sc_signed& v); + sc_signed operator * (unsigned long u, const sc_signed& v); + inline sc_signed operator * (int u, const sc_signed& v); + inline sc_signed operator * (unsigned int u, const sc_signed& v); + + sc_signed operator * (const sc_unsigned& u, const sc_int_base& v); + sc_signed operator * (const sc_int_base& u, const sc_unsigned& v); + sc_signed operator * (const sc_signed& u, const sc_int_base& v); + sc_signed operator * (const sc_signed& u, const sc_uint_base& v); + sc_signed operator * (const sc_int_base& u, const sc_signed& v); + sc_signed operator * (const sc_uint_base& u, const sc_signed& v); + + + + // DIVision operators: + + sc_signed operator / (const sc_unsigned& u, const sc_signed& v); + sc_signed operator / (const sc_signed& u, const sc_unsigned& v); + + sc_signed operator / (const sc_unsigned& u, int64 v); + sc_signed operator / (const sc_unsigned& u, long v); + inline sc_signed operator / (const sc_unsigned& u, int v); + + sc_signed operator / (int64 u, const sc_unsigned& v); + sc_signed operator / (long u, const sc_unsigned& v); + inline sc_signed operator / (int u, const sc_unsigned& v); + + sc_signed operator / (const sc_signed& u, const sc_signed& v); + sc_signed operator / (const sc_signed& u, int64 v); + sc_signed operator / (const sc_signed& u, uint64 v); + sc_signed operator / (const sc_signed& u, long v); + sc_signed operator / (const sc_signed& u, unsigned long v); + inline sc_signed operator / (const sc_signed& u, int v); + inline sc_signed operator / (const sc_signed& u, unsigned int v); + + sc_signed operator / (int64 u, const sc_signed& v); + sc_signed operator / (uint64 u, const sc_signed& v); + sc_signed operator / (long u, const sc_signed& v); + sc_signed operator / (unsigned long u, const sc_signed& v); + inline sc_signed operator / (int u, const sc_signed& v); + inline sc_signed operator / (unsigned int u, const sc_signed& v); + + sc_signed operator / (const sc_unsigned& u, const sc_int_base& v); + sc_signed operator / (const sc_int_base& u, const sc_unsigned& v); + sc_signed operator / (const sc_signed& u, const sc_int_base& v); + sc_signed operator / (const sc_signed& u, const sc_uint_base& v); + sc_signed operator / (const sc_int_base& u, const sc_signed& v); + sc_signed operator / (const sc_uint_base& u, const sc_signed& v); + + + + // MODulo operators: + + sc_signed operator % (const sc_unsigned& u, const sc_signed& v); + sc_signed operator % (const sc_signed& u, const sc_unsigned& v); + + sc_signed operator % (const sc_unsigned& u, int64 v); + sc_signed operator % (const sc_unsigned& u, long v); + inline sc_signed operator % (const sc_unsigned& u, int v); + + sc_signed operator % (int64 u, const sc_unsigned& v); + sc_signed operator % (long u, const sc_unsigned& v); + inline sc_signed operator % (int u, const sc_unsigned& v); + + sc_signed operator % (const sc_signed& u, const sc_signed& v); + sc_signed operator % (const sc_signed& u, int64 v); + sc_signed operator % (const sc_signed& u, uint64 v); + sc_signed operator % (const sc_signed& u, long v); + sc_signed operator % (const sc_signed& u, unsigned long v); + inline sc_signed operator % (const sc_signed& u, int v); + inline sc_signed operator % (const sc_signed& u, unsigned int v); + + sc_signed operator % (int64 u, const sc_signed& v); + sc_signed operator % (uint64 u, const sc_signed& v); + sc_signed operator % (long u, const sc_signed& v); + sc_signed operator % (unsigned long u, const sc_signed& v); + inline sc_signed operator % (int u, const sc_signed& v); + inline sc_signed operator % (unsigned int u, const sc_signed& v); + + sc_signed operator % (const sc_unsigned& u, const sc_int_base& v); + sc_signed operator % (const sc_int_base& u, const sc_unsigned& v); + sc_signed operator % (const sc_signed& u, const sc_int_base& v); + sc_signed operator % (const sc_signed& u, const sc_uint_base& v); + sc_signed operator % (const sc_int_base& u, const sc_signed& v); + sc_signed operator % (const sc_uint_base& u, const sc_signed& v); + + + + // BITWISE OPERATORS: + + // Bitwise AND operators: + + sc_signed operator & (const sc_unsigned& u, const sc_signed& v); + sc_signed operator & (const sc_signed& u, const sc_unsigned& v); + + sc_signed operator & (const sc_unsigned& u, int64 v); + sc_signed operator & (const sc_unsigned& u, long v); + inline sc_signed operator & (const sc_unsigned& u, int v); + + sc_signed operator & (int64 u, const sc_unsigned& v); + sc_signed operator & (long u, const sc_unsigned& v); + inline sc_signed operator & (int u, const sc_unsigned& v); + + sc_signed operator & (const sc_signed& u, const sc_signed& v); + sc_signed operator & (const sc_signed& u, int64 v); + sc_signed operator & (const sc_signed& u, uint64 v); + sc_signed operator & (const sc_signed& u, long v); + sc_signed operator & (const sc_signed& u, unsigned long v); + inline sc_signed operator & (const sc_signed& u, int v); + inline sc_signed operator & (const sc_signed& u, unsigned int v); + + sc_signed operator & (int64 u, const sc_signed& v); + sc_signed operator & (uint64 u, const sc_signed& v); + sc_signed operator & (long u, const sc_signed& v); + sc_signed operator & (unsigned long u, const sc_signed& v); + inline sc_signed operator & (int u, const sc_signed& v); + inline sc_signed operator & (unsigned int u, const sc_signed& v); + + sc_signed operator & (const sc_unsigned& u, const sc_int_base& v); + sc_signed operator & (const sc_int_base& u, const sc_unsigned& v); + sc_signed operator & (const sc_signed& u, const sc_int_base& v); + sc_signed operator & (const sc_signed& u, const sc_uint_base& v); + sc_signed operator & (const sc_int_base& u, const sc_signed& v); + sc_signed operator & (const sc_uint_base& u, const sc_signed& v); + + + + // Bitwise OR operators: + + sc_signed operator | (const sc_unsigned& u, const sc_signed& v); + sc_signed operator | (const sc_signed& u, const sc_unsigned& v); + + sc_signed operator | (const sc_unsigned& u, int64 v); + sc_signed operator | (const sc_unsigned& u, long v); + inline sc_signed operator | (const sc_unsigned& u, int v); + + sc_signed operator | (int64 u, const sc_unsigned& v); + sc_signed operator | (long u, const sc_unsigned& v); + inline sc_signed operator | (int u, const sc_unsigned& v); + + sc_signed operator | (const sc_signed& u, const sc_signed& v); + sc_signed operator | (const sc_signed& u, int64 v); + sc_signed operator | (const sc_signed& u, uint64 v); + sc_signed operator | (const sc_signed& u, long v); + sc_signed operator | (const sc_signed& u, unsigned long v); + inline sc_signed operator | (const sc_signed& u, int v); + inline sc_signed operator | (const sc_signed& u, unsigned int v); + + sc_signed operator | (int64 u, const sc_signed& v); + sc_signed operator | (uint64 u, const sc_signed& v); + sc_signed operator | (long u, const sc_signed& v); + sc_signed operator | (unsigned long u, const sc_signed& v); + inline sc_signed operator | (int u, const sc_signed& v); + inline sc_signed operator | (unsigned int u, const sc_signed& v); + + sc_signed operator | (const sc_unsigned& u, const sc_int_base& v); + sc_signed operator | (const sc_int_base& u, const sc_unsigned& v); + sc_signed operator | (const sc_signed& u, const sc_int_base& v); + sc_signed operator | (const sc_signed& u, const sc_uint_base& v); + sc_signed operator | (const sc_int_base& u, const sc_signed& v); + sc_signed operator | (const sc_uint_base& u, const sc_signed& v); + + + + // Bitwise XOR operators: + + sc_signed operator ^ (const sc_unsigned& u, const sc_signed& v); + sc_signed operator ^ (const sc_signed& u, const sc_unsigned& v); + + sc_signed operator ^ (const sc_unsigned& u, int64 v); + sc_signed operator ^ (const sc_unsigned& u, long v); + inline sc_signed operator ^ (const sc_unsigned& u, int v); + + sc_signed operator ^ (int64 u, const sc_unsigned& v); + sc_signed operator ^ (long u, const sc_unsigned& v); + inline sc_signed operator ^ (int u, const sc_unsigned& v); + + sc_signed operator ^ (const sc_signed& u, const sc_signed& v); + sc_signed operator ^ (const sc_signed& u, int64 v); + sc_signed operator ^ (const sc_signed& u, uint64 v); + sc_signed operator ^ (const sc_signed& u, long v); + sc_signed operator ^ (const sc_signed& u, unsigned long v); + inline sc_signed operator ^ (const sc_signed& u, int v); + inline sc_signed operator ^ (const sc_signed& u, unsigned int v); + + sc_signed operator ^ (int64 u, const sc_signed& v); + sc_signed operator ^ (uint64 u, const sc_signed& v); + sc_signed operator ^ (long u, const sc_signed& v); + sc_signed operator ^ (unsigned long u, const sc_signed& v); + inline sc_signed operator ^ (int u, const sc_signed& v); + inline sc_signed operator ^ (unsigned int u, const sc_signed& v); + + sc_signed operator ^ (const sc_unsigned& u, const sc_int_base& v); + sc_signed operator ^ (const sc_int_base& u, const sc_unsigned& v); + sc_signed operator ^ (const sc_signed& u, const sc_int_base& v); + sc_signed operator ^ (const sc_signed& u, const sc_uint_base& v); + sc_signed operator ^ (const sc_int_base& u, const sc_signed& v); + sc_signed operator ^ (const sc_uint_base& u, const sc_signed& v); + + + + // SHIFT OPERATORS: + + // LEFT SHIFT operators: + + sc_unsigned operator << (const sc_unsigned& u, const sc_signed& v); + sc_signed operator << (const sc_signed& u, const sc_unsigned& v); + + sc_signed operator << (const sc_signed& u, const sc_signed& v); + sc_signed operator << (const sc_signed& u, int64 v); + sc_signed operator << (const sc_signed& u, uint64 v); + sc_signed operator << (const sc_signed& u, long v); + sc_signed operator << (const sc_signed& u, unsigned long v); + inline sc_signed operator << (const sc_signed& u, int v); + inline sc_signed operator << (const sc_signed& u, unsigned int v); + + sc_signed operator << (const sc_signed& u, const sc_int_base& v); + sc_signed operator << (const sc_signed& u, const sc_uint_base& v); + + + + // RIGHT SHIFT operators: + + sc_unsigned operator >> (const sc_unsigned& u, const sc_signed& v); + sc_signed operator >> (const sc_signed& u, const sc_unsigned& v); + + sc_signed operator >> (const sc_signed& u, const sc_signed& v); + sc_signed operator >> (const sc_signed& u, int64 v); + sc_signed operator >> (const sc_signed& u, uint64 v); + sc_signed operator >> (const sc_signed& u, long v); + sc_signed operator >> (const sc_signed& u, unsigned long v); + inline sc_signed operator >> (const sc_signed& u, int v); + inline sc_signed operator >> (const sc_signed& u, unsigned int v); + + sc_signed operator >> (const sc_signed& u, const sc_int_base& v); + sc_signed operator >> (const sc_signed& u, const sc_uint_base& v); + + + + // Unary arithmetic operators + sc_signed operator + (const sc_signed& u); + sc_signed operator - (const sc_signed& u); + sc_signed operator - (const sc_unsigned& u); + + // LOGICAL OPERATORS: + + // Logical EQUAL operators: + + bool operator == (const sc_unsigned& u, const sc_signed& v); + bool operator == (const sc_signed& u, const sc_unsigned& v); + + bool operator == (const sc_signed& u, const sc_signed& v); + bool operator == (const sc_signed& u, int64 v); + bool operator == (const sc_signed& u, uint64 v); + bool operator == (const sc_signed& u, long v); + bool operator == (const sc_signed& u, unsigned long v); + inline bool operator == (const sc_signed& u, int v); + inline bool operator == (const sc_signed& u, unsigned int v); + + bool operator == (int64 u, const sc_signed& v); + bool operator == (uint64 u, const sc_signed& v); + bool operator == (long u, const sc_signed& v); + bool operator == (unsigned long u, const sc_signed& v); + inline bool operator == (int u, const sc_signed& v); + inline bool operator == (unsigned int u, const sc_signed& v); + + bool operator == (const sc_signed& u, const sc_int_base& v); + bool operator == (const sc_signed& u, const sc_uint_base& v); + bool operator == (const sc_int_base& u, const sc_signed& v); + bool operator == (const sc_uint_base& u, const sc_signed& v); + + // Logical NOT_EQUAL operators: + + bool operator != (const sc_unsigned& u, const sc_signed& v); + bool operator != (const sc_signed& u, const sc_unsigned& v); + + bool operator != (const sc_signed& u, const sc_signed& v); + bool operator != (const sc_signed& u, int64 v); + bool operator != (const sc_signed& u, uint64 v); + bool operator != (const sc_signed& u, long v); + bool operator != (const sc_signed& u, unsigned long v); + inline bool operator != (const sc_signed& u, int v); + inline bool operator != (const sc_signed& u, unsigned int v); + + bool operator != (int64 u, const sc_signed& v); + bool operator != (uint64 u, const sc_signed& v); + bool operator != (long u, const sc_signed& v); + bool operator != (unsigned long u, const sc_signed& v); + inline bool operator != (int u, const sc_signed& v); + inline bool operator != (unsigned int u, const sc_signed& v); + + bool operator != (const sc_signed& u, const sc_int_base& v); + bool operator != (const sc_signed& u, const sc_uint_base& v); + bool operator != (const sc_int_base& u, const sc_signed& v); + bool operator != (const sc_uint_base& u, const sc_signed& v); + + // Logical LESS_THAN operators: + + bool operator < (const sc_unsigned& u, const sc_signed& v); + bool operator < (const sc_signed& u, const sc_unsigned& v); + + bool operator < (const sc_signed& u, const sc_signed& v); + bool operator < (const sc_signed& u, int64 v); + bool operator < (const sc_signed& u, uint64 v); + bool operator < (const sc_signed& u, long v); + bool operator < (const sc_signed& u, unsigned long v); + inline bool operator < (const sc_signed& u, int v); + inline bool operator < (const sc_signed& u, unsigned int v); + + bool operator < (int64 u, const sc_signed& v); + bool operator < (uint64 u, const sc_signed& v); + bool operator < (long u, const sc_signed& v); + bool operator < (unsigned long u, const sc_signed& v); + inline bool operator < (int u, const sc_signed& v); + inline bool operator < (unsigned int u, const sc_signed& v); + + bool operator < (const sc_signed& u, const sc_int_base& v); + bool operator < (const sc_signed& u, const sc_uint_base& v); + bool operator < (const sc_int_base& u, const sc_signed& v); + bool operator < (const sc_uint_base& u, const sc_signed& v); + + // Logical LESS_THAN_AND_EQUAL operators: + + bool operator <= (const sc_unsigned& u, const sc_signed& v); + bool operator <= (const sc_signed& u, const sc_unsigned& v); + + bool operator <= (const sc_signed& u, const sc_signed& v); + bool operator <= (const sc_signed& u, int64 v); + bool operator <= (const sc_signed& u, uint64 v); + bool operator <= (const sc_signed& u, long v); + bool operator <= (const sc_signed& u, unsigned long v); + inline bool operator <= (const sc_signed& u, int v); + inline bool operator <= (const sc_signed& u, unsigned int v); + + bool operator <= (int64 u, const sc_signed& v); + bool operator <= (uint64 u, const sc_signed& v); + bool operator <= (long u, const sc_signed& v); + bool operator <= (unsigned long u, const sc_signed& v); + inline bool operator <= (int u, const sc_signed& v); + inline bool operator <= (unsigned int u, const sc_signed& v); + + bool operator <= (const sc_signed& u, const sc_int_base& v); + bool operator <= (const sc_signed& u, const sc_uint_base& v); + bool operator <= (const sc_int_base& u, const sc_signed& v); + bool operator <= (const sc_uint_base& u, const sc_signed& v); + + // Logical GREATER_THAN operators: + + bool operator > (const sc_unsigned& u, const sc_signed& v); + bool operator > (const sc_signed& u, const sc_unsigned& v); + + bool operator > (const sc_signed& u, const sc_signed& v); + bool operator > (const sc_signed& u, int64 v); + bool operator > (const sc_signed& u, uint64 v); + bool operator > (const sc_signed& u, long v); + bool operator > (const sc_signed& u, unsigned long v); + inline bool operator > (const sc_signed& u, int v); + inline bool operator > (const sc_signed& u, unsigned int v); + + bool operator > (int64 u, const sc_signed& v); + bool operator > (uint64 u, const sc_signed& v); + bool operator > (long u, const sc_signed& v); + bool operator > (unsigned long u, const sc_signed& v); + inline bool operator > (int u, const sc_signed& v); + inline bool operator > (unsigned int u, const sc_signed& v); + + bool operator > (const sc_signed& u, const sc_int_base& v); + bool operator > (const sc_signed& u, const sc_uint_base& v); + bool operator > (const sc_int_base& u, const sc_signed& v); + bool operator > (const sc_uint_base& u, const sc_signed& v); + + // Logical GREATER_THAN_AND_EQUAL operators: + + bool operator >= (const sc_unsigned& u, const sc_signed& v); + bool operator >= (const sc_signed& u, const sc_unsigned& v); + + bool operator >= (const sc_signed& u, const sc_signed& v); + bool operator >= (const sc_signed& u, int64 v); + bool operator >= (const sc_signed& u, uint64 v); + bool operator >= (const sc_signed& u, long v); + bool operator >= (const sc_signed& u, unsigned long v); + inline bool operator >= (const sc_signed& u, int v); + inline bool operator >= (const sc_signed& u, unsigned int v); + + bool operator >= (int64 u, const sc_signed& v); + bool operator >= (uint64 u, const sc_signed& v); + bool operator >= (long u, const sc_signed& v); + bool operator >= (unsigned long u, const sc_signed& v); + inline bool operator >= (int u, const sc_signed& v); + inline bool operator >= (unsigned int u, const sc_signed& v); + + bool operator >= (const sc_signed& u, const sc_int_base& v); + bool operator >= (const sc_signed& u, const sc_uint_base& v); + bool operator >= (const sc_int_base& u, const sc_signed& v); + bool operator >= (const sc_uint_base& u, const sc_signed& v); + + // Bitwise NOT operator (unary). + sc_signed operator ~ (const sc_signed& u); + +// ---------------------------------------------------------------------------- +// CLASS : sc_signed_bitref_r +// +// Proxy class for sc_signed bit selection (r-value only). +// ---------------------------------------------------------------------------- + +class sc_signed_bitref_r : public sc_value_base +{ + friend class sc_signed; + +protected: + + // constructor + + sc_signed_bitref_r() : sc_value_base(), m_index(0), m_obj_p(0) + {} + + void initialize( const sc_signed* obj_p, int index_ ) + { + m_index = index_; + m_obj_p = ( CCAST<sc_signed*>( obj_p ) ); + } + +public: + + // destructor + + virtual ~sc_signed_bitref_r() + {} + + // copy constructor + + sc_signed_bitref_r( const sc_signed_bitref_r& a ) + : sc_value_base(a), m_index( a.m_index ), m_obj_p( a.m_obj_p ) + {} + + // capacity + + int length() const + { return 1; } + + + // implicit conversion to bool + + operator uint64 () const; + bool operator ! () const; + bool operator ~ () const; + + + // explicit conversions + + bool value() const + { return operator uint64(); } + + bool to_bool() const + { return operator uint64(); } + + // concatenation support + + virtual int concat_length(bool* xz_present_p) const + { if ( xz_present_p ) *xz_present_p = false; return 1; } + virtual uint64 concat_get_uint64() const + { return (uint64)operator uint64(); } + virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const + { + int bit_mask = 1 << (low_i % BITS_PER_DIGIT); + int word_i = low_i / BITS_PER_DIGIT; + dst_p[word_i] &= ~bit_mask; + return false; + } + virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const + { + int bit_mask = 1 << (low_i % BITS_PER_DIGIT); + bool result; // True if non-zero. + int word_i = low_i / BITS_PER_DIGIT; + if ( operator uint64() ) + { + dst_p[word_i] |= bit_mask; + result = true; + } + else + { + dst_p[word_i] &= ~bit_mask; + result = false; + } + return result; + } + + + // other methods + + void print( ::std::ostream& os = ::std::cout ) const + { os << to_bool(); } + +protected: + + int m_index; // Bit to be selected. + sc_signed* m_obj_p; // Target of this bit selection. + +private: + + // disabled + const sc_signed_bitref_r& operator = ( const sc_signed_bitref_r& ); +}; + + + +inline +::std::ostream& +operator << ( ::std::ostream&, const sc_signed_bitref_r& ); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_signed_bitref +// +// Proxy class for sc_signed bit selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +class sc_signed_bitref + : public sc_signed_bitref_r +{ + friend class sc_signed; + friend class sc_core::sc_vpool<sc_signed_bitref>; + + + // constructor + +protected: + + sc_signed_bitref() : sc_signed_bitref_r() + {} + +public: + + // copy constructor + + sc_signed_bitref( const sc_signed_bitref& a ) + : sc_signed_bitref_r( a ) + {} + + // assignment operators + + const sc_signed_bitref& operator = ( const sc_signed_bitref_r& ); + const sc_signed_bitref& operator = ( const sc_signed_bitref& ); + const sc_signed_bitref& operator = ( bool ); + + const sc_signed_bitref& operator &= ( bool ); + const sc_signed_bitref& operator |= ( bool ); + const sc_signed_bitref& operator ^= ( bool ); + + // concatenation methods + + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed& src, int low_i); + virtual void concat_set(const sc_unsigned& src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + + // other methods + + void scan( ::std::istream& is = ::std::cin ); + +protected: + static sc_core::sc_vpool<sc_signed_bitref> m_pool; +}; + + + +inline +::std::istream& +operator >> ( ::std::istream&, sc_signed_bitref& ); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_signed_subref_r +// +// Proxy class for sc_signed part selection (r-value only). +// ---------------------------------------------------------------------------- + +class sc_signed_subref_r : public sc_value_base +{ + friend class sc_signed; + friend class sc_signed_signal; + friend class sc_unsigned; + +protected: + + // constructor + + sc_signed_subref_r() : sc_value_base(), m_left(0), m_obj_p(0), m_right(0) + {} + + void initialize( const sc_signed* obj_p, int left_, int right_ ) + { + m_obj_p = ( CCAST<sc_signed*>( obj_p )); + m_left = left_; + m_right = right_; + } + + +public: + + // destructor + + virtual ~sc_signed_subref_r() + {} + + // copy constructor + + sc_signed_subref_r( const sc_signed_subref_r& a ) + : sc_value_base(a), m_left( a.m_left ), m_obj_p( a.m_obj_p ), + m_right( a.m_right ) + {} + + + // capacity + + int length() const + { return m_left >= m_right ? (m_left-m_right+1) : (m_right-m_left+1 ); } + + + // implicit conversion to sc_unsigned + + operator sc_unsigned () const; + + + // explicit conversions + + int to_int() const; + unsigned int to_uint() const; + long to_long() const; + unsigned long to_ulong() const; + int64 to_int64() const; + uint64 to_uint64() const; + double to_double() const; + + + // explicit conversion to character string + + const std::string to_string( sc_numrep numrep = SC_DEC ) const; + const std::string to_string( sc_numrep numrep, bool w_prefix ) const; + + // concatenation support + + virtual int concat_length(bool* xz_present_p) const + { + if ( xz_present_p ) *xz_present_p = false; + return m_left - m_right + 1; + } + virtual uint64 concat_get_uint64() const; + virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const; + virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const; + + // reduce methods + + bool and_reduce() const; + bool nand_reduce() const; + bool or_reduce() const; + bool nor_reduce() const; + bool xor_reduce() const ; + bool xnor_reduce() const; + + + // other methods + + void print( ::std::ostream& os = ::std::cout ) const + { os << to_string(sc_io_base(os,SC_DEC),sc_io_show_base(os)); } + +protected: + + int m_left; // Left-most bit in this part selection. + sc_signed* m_obj_p; // Target of this part selection. + int m_right; // Right-most bit in this part selection. + +private: + const sc_signed_subref_r& operator = ( const sc_signed_subref_r& ); + +}; + + + +inline +::std::ostream& +operator << ( ::std::ostream&, const sc_signed_subref_r& ); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_signed_subref +// +// Proxy class for sc_signed part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +class sc_signed_subref + : public sc_signed_subref_r +{ + friend class sc_signed; + friend class sc_core::sc_vpool<sc_signed_subref>; + + + // constructor + + sc_signed_subref() : sc_signed_subref_r() + {} + +public: + + // copy constructor + + sc_signed_subref( const sc_signed_subref& a ) + : sc_signed_subref_r( a ) + {} + + + // assignment operators + + const sc_signed_subref& operator = ( const sc_signed_subref_r& a ); + const sc_signed_subref& operator = ( const sc_signed_subref& a ); + const sc_signed_subref& operator = ( const sc_signed& a ); + + const sc_signed_subref& operator = ( const sc_unsigned_subref_r& a ); + const sc_signed_subref& operator = ( const sc_unsigned& a ); + + template< class T > + const sc_signed_subref& operator = ( const sc_generic_base<T>& a ) + { + sc_unsigned temp( length() ); + a->to_sc_unsigned(temp); + return operator = (temp); + } + + const sc_signed_subref& operator = ( const char* a ); + const sc_signed_subref& operator = ( unsigned long a ); + const sc_signed_subref& operator = ( long a ); + const sc_signed_subref& operator = ( unsigned int a ) + { return operator = ( (unsigned long) a ); } + + const sc_signed_subref& operator = ( int a ) + { return operator = ( (long) a ); } + + const sc_signed_subref& operator = ( uint64 a ); + const sc_signed_subref& operator = ( int64 a ); + const sc_signed_subref& operator = ( double a ); + const sc_signed_subref& operator = ( const sc_int_base& a ); + const sc_signed_subref& operator = ( const sc_uint_base& a ); + + // concatenation methods + + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed& src, int low_i); + virtual void concat_set(const sc_unsigned& src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + // other methods + + void scan( ::std::istream& is = ::std::cin ); + +protected: + static sc_core::sc_vpool<sc_signed_subref> m_pool; +}; + + + +inline +::std::istream& +operator >> ( ::std::istream&, sc_signed_subref& ); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_signed +// +// Arbitrary precision signed number. +// ---------------------------------------------------------------------------- + +class sc_signed : public sc_value_base +{ + friend class sc_concatref; + friend class sc_signed_bitref_r; + friend class sc_signed_bitref; + friend class sc_signed_subref_r; + friend class sc_signed_subref; + friend class sc_unsigned; + friend class sc_unsigned_subref; + + // Needed for types using sc_signed. + typedef bool elemtype; + +public: + + // constructors + + explicit sc_signed( int nb = sc_length_param().len() ); + sc_signed( const sc_signed& v ); + sc_signed( const sc_unsigned& v ); + template<class T> + explicit sc_signed( const sc_generic_base<T>& v ); + explicit sc_signed( const sc_bv_base& v ); + explicit sc_signed( const sc_lv_base& v ); + explicit sc_signed( const sc_int_subref_r& v ); + explicit sc_signed( const sc_uint_subref_r& v ); + explicit sc_signed( const sc_signed_subref_r& v ); + explicit sc_signed( const sc_unsigned_subref_r& v ); + + // assignment operators + + const sc_signed& operator = (const sc_signed& v); + const sc_signed& operator = (const sc_signed_subref_r& a ); + + template< class T > + const sc_signed& operator = ( const sc_generic_base<T>& a ) + { a->to_sc_signed(*this); return *this; } + + const sc_signed& operator = (const sc_unsigned& v); + const sc_signed& operator = (const sc_unsigned_subref_r& a ); + + const sc_signed& operator = (const char* v); + const sc_signed& operator = (int64 v); + const sc_signed& operator = (uint64 v); + const sc_signed& operator = (long v); + const sc_signed& operator = (unsigned long v); + + const sc_signed& operator = (int v) + { return operator=((long) v); } + + const sc_signed& operator = (unsigned int v) + { return operator=((unsigned long) v); } + + const sc_signed& operator = (double v); + const sc_signed& operator = (const sc_int_base& v); + const sc_signed& operator = (const sc_uint_base& v); + + const sc_signed& operator = ( const sc_bv_base& ); + const sc_signed& operator = ( const sc_lv_base& ); + +#ifdef SC_INCLUDE_FX + const sc_signed& operator = ( const sc_fxval& ); + const sc_signed& operator = ( const sc_fxval_fast& ); + const sc_signed& operator = ( const sc_fxnum& ); + const sc_signed& operator = ( const sc_fxnum_fast& ); +#endif + + + // destructor + + virtual ~sc_signed() + { +#ifndef SC_MAX_NBITS + delete [] digit; +#endif + } + + // Concatenation support: + + sc_digit* get_raw() const + { return digit; } + virtual int concat_length(bool* xz_present_p) const + { if ( xz_present_p ) *xz_present_p = false; return nbits; } + virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const; + virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const; + virtual uint64 concat_get_uint64() const; + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed& src, int low_i); + virtual void concat_set(const sc_unsigned& src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + + + // Increment operators. + sc_signed& operator ++ (); + const sc_signed operator ++ (int); + + // Decrement operators. + sc_signed& operator -- (); + const sc_signed operator -- (int); + + + // bit selection + + inline void check_index( int i ) const + { if ( i < 0 || i >= nbits ) invalid_index(i); } + + void invalid_index( int i ) const; + + sc_signed_bitref& operator [] ( int i ) + { + check_index(i); + sc_signed_bitref* result_p = + sc_signed_bitref::m_pool.allocate(); + result_p->initialize( this, i ); + return *result_p; + } + + const sc_signed_bitref_r& operator [] ( int i ) const + { + check_index(i); + sc_signed_bitref* result_p = + sc_signed_bitref::m_pool.allocate(); + result_p->initialize( this, i ); + return *result_p; + } + + sc_signed_bitref& bit( int i ) + { + check_index(i); + sc_signed_bitref* result_p = + sc_signed_bitref::m_pool.allocate(); + result_p->initialize( this, i ); + return *result_p; + } + + const sc_signed_bitref_r& bit( int i ) const + { + check_index(i); + sc_signed_bitref* result_p = + sc_signed_bitref::m_pool.allocate(); + result_p->initialize( this, i ); + return *result_p; + } + + + // part selection + + // Subref operators. Help access the range of bits from the ith to + // jth. These indices have arbitrary precedence with respect to each + // other, i.e., we can have i <= j or i > j. Note the equivalence + // between range(i, j) and operator(i, j). Also note that + // operator(i, i) returns a signed number that corresponds to the + // bit operator[i], so these two forms are not the same. + + inline void check_range( int l, int r ) const + { + if ( l < r ) + { + if ( l < 0 || r >= nbits ) invalid_range(l,r); + } + else + { + if ( r < 0 || l >= nbits ) invalid_range(l,r); + } + } + + void invalid_range( int l, int r ) const; + + sc_signed_subref& range( int i, int j ) + { + check_range( i, j ); + sc_signed_subref* result_p = + sc_signed_subref::m_pool.allocate(); + result_p->initialize( this, i, j ); + return *result_p; + } + + const sc_signed_subref_r& range( int i, int j ) const + { + check_range( i, j ); + sc_signed_subref* result_p = + sc_signed_subref::m_pool.allocate(); + result_p->initialize( this, i, j ); + return *result_p; + } + + sc_signed_subref& operator () ( int i, int j ) + { + check_range( i, j ); + sc_signed_subref* result_p = + sc_signed_subref::m_pool.allocate(); + result_p->initialize( this, i, j ); + return *result_p; + } + + const sc_signed_subref_r& operator () ( int i, int j ) const + { + check_range( i, j ); + sc_signed_subref* result_p = + sc_signed_subref::m_pool.allocate(); + result_p->initialize( this, i, j ); + return *result_p; + } + + + // explicit conversions + + int to_int() const; + unsigned int to_uint() const; + long to_long() const; + unsigned long to_ulong() const; + int64 to_int64() const; + uint64 to_uint64() const; + double to_double() const; + +#ifdef SC_DT_DEPRECATED + int to_signed() const + { return to_int(); } + + unsigned int to_unsigned() const + { return to_uint(); } +#endif + + // explicit conversion to character string + + const std::string to_string( sc_numrep numrep = SC_DEC ) const; + const std::string to_string( sc_numrep numrep, bool w_prefix ) const; + + + // Print functions. dump prints the internals of the class. + + void print( ::std::ostream& os = ::std::cout ) const + { os << to_string(sc_io_base(os,SC_DEC),sc_io_show_base(os)); } + + void scan( ::std::istream& is = ::std::cin ); + + void dump( ::std::ostream& os = ::std::cout ) const; + + + // Functions to find various properties. + int length() const { return nbits; } // Bit width. + bool iszero() const; // Is the number zero? + bool sign() const; // Sign. + + // reduce methods + + bool and_reduce() const; + + bool nand_reduce() const + { return ( ! and_reduce() ); } + + bool or_reduce() const; + + bool nor_reduce() const + { return ( ! or_reduce() ); } + + bool xor_reduce() const; + + bool xnor_reduce() const + { return ( ! xor_reduce() ); } + + // Functions to access individual bits. + bool test(int i) const; // Is the ith bit 0 or 1? + void set(int i); // Set the ith bit to 1. + void clear(int i); // Set the ith bit to 0. + void set(int i, bool v) // Set the ith bit to v. + { if (v) set(i); else clear(i); } + void invert(int i) // Negate the ith bit. + { if (test(i)) clear(i); else set(i); } + + // Make the number equal to its mirror image. + void reverse(); + + // Get/set a packed bit representation of the number. + void get_packed_rep(sc_digit *buf) const; + void set_packed_rep(sc_digit *buf); + + /* + The comparison of the old and new semantics are as follows: + + Let s = sc_signed, + u = sc_unsigned, + un = { uint64, unsigned long, unsigned int }, + sn = { int64, long, int, char* }, and + OP = { +, -, *, /, % }. + + Old semantics: New semantics: + u OP u -> u u OP u -> u + s OP u -> u s OP u -> s + u OP s -> u u OP s -> s + s OP s -> s s OP s -> s + + u OP un = un OP u -> u u OP un = un OP u -> u + u OP sn = sn OP u -> u u OP sn = sn OP u -> s + + s OP un = un OP s -> s s OP un = un OP s -> s + s OP sn = sn OP s -> s s OP sn = sn OP s -> s + + In the new semantics, the result is u if both operands are u; the + result is s otherwise. The only exception is subtraction. The result + of a subtraction is always s. + + The old semantics is like C/C++ semantics on integer types; the + new semantics is due to the VSIA C/C++ data types standard. + */ + + // ARITHMETIC OPERATORS: + + // ADDition operators: + + friend sc_signed operator + (const sc_unsigned& u, const sc_signed& v); + friend sc_signed operator + (const sc_signed& u, const sc_unsigned& v); + + friend sc_signed operator + (const sc_unsigned& u, int64 v); + friend sc_signed operator + (const sc_unsigned& u, long v); + friend sc_signed operator + (const sc_unsigned& u, int v) + { return operator+(u, (long) v); } + + friend sc_signed operator + (int64 u, const sc_unsigned& v); + friend sc_signed operator + (long u, const sc_unsigned& v); + friend sc_signed operator + (int u, const sc_unsigned& v) + { return operator+((long) u, v); } + + friend sc_signed operator + (const sc_signed& u, const sc_signed& v); + friend sc_signed operator + (const sc_signed& u, int64 v); + friend sc_signed operator + (const sc_signed& u, uint64 v); + friend sc_signed operator + (const sc_signed& u, long v); + friend sc_signed operator + (const sc_signed& u, unsigned long v); + friend sc_signed operator + (const sc_signed& u, int v) + { return operator+(u, (long) v); } + friend sc_signed operator + (const sc_signed& u, unsigned int v) + { return operator+(u, (unsigned long) v); } + + friend sc_signed operator + (int64 u, const sc_signed& v); + friend sc_signed operator + (uint64 u, const sc_signed& v); + friend sc_signed operator + (long u, const sc_signed& v); + friend sc_signed operator + (unsigned long u, const sc_signed& v); + friend sc_signed operator + (int u, const sc_signed& v) + { return operator+((long) u, v); } + friend sc_signed operator + (unsigned int u, const sc_signed& v) + { return operator+((unsigned long) u, v); } + + const sc_signed& operator += (const sc_signed& v); + const sc_signed& operator += (const sc_unsigned& v); + const sc_signed& operator += (int64 v); + const sc_signed& operator += (uint64 v); + const sc_signed& operator += (long v); + const sc_signed& operator += (unsigned long v); + const sc_signed& operator += (int v) + { return operator+=((long) v); } + const sc_signed& operator += (unsigned int v) + { return operator+=((unsigned long) v); } + + friend sc_signed operator + (const sc_unsigned& u, const sc_int_base& v); + friend sc_signed operator + (const sc_int_base& u, const sc_unsigned& v); + friend sc_signed operator + (const sc_signed& u, const sc_int_base& v); + friend sc_signed operator + (const sc_signed& u, const sc_uint_base& v); + friend sc_signed operator + (const sc_int_base& u, const sc_signed& v); + friend sc_signed operator + (const sc_uint_base& u, const sc_signed& v); + const sc_signed& operator += (const sc_int_base& v); + const sc_signed& operator += (const sc_uint_base& v); + + // SUBtraction operators: + + friend sc_signed operator - (const sc_unsigned& u, const sc_signed& v); + friend sc_signed operator - (const sc_signed& u, const sc_unsigned& v); + + friend sc_signed operator - (const sc_unsigned& u, const sc_unsigned& v); + friend sc_signed operator - (const sc_unsigned& u, int64 v); + friend sc_signed operator - (const sc_unsigned& u, uint64 v); + friend sc_signed operator - (const sc_unsigned& u, long v); + friend sc_signed operator - (const sc_unsigned& u, unsigned long v); + friend sc_signed operator - (const sc_unsigned& u, int v) + { return operator-(u, (long) v); } + friend sc_signed operator - (const sc_unsigned& u, unsigned int v) + { return operator-(u, (unsigned long) v); } + + friend sc_signed operator - (int64 u, const sc_unsigned& v); + friend sc_signed operator - (uint64 u, const sc_unsigned& v); + friend sc_signed operator - (long u, const sc_unsigned& v); + friend sc_signed operator - (unsigned long u, const sc_unsigned& v); + friend sc_signed operator - (int u, const sc_unsigned& v) + { return operator-((long) u, v); } + friend sc_signed operator - (unsigned int u, const sc_unsigned& v) + { return operator-((unsigned long) u, v); } + + friend sc_signed operator - (const sc_signed& u, const sc_signed& v); + friend sc_signed operator - (const sc_signed& u, int64 v); + friend sc_signed operator - (const sc_signed& u, uint64 v); + friend sc_signed operator - (const sc_signed& u, long v); + friend sc_signed operator - (const sc_signed& u, unsigned long v); + friend sc_signed operator - (const sc_signed& u, int v) + { return operator-(u, (long) v); } + friend sc_signed operator - (const sc_signed& u, unsigned int v) + { return operator-(u, (unsigned long) v); } + + friend sc_signed operator - (int64 u, const sc_signed& v); + friend sc_signed operator - (uint64 u, const sc_signed& v); + friend sc_signed operator - (long u, const sc_signed& v); + friend sc_signed operator - (unsigned long u, const sc_signed& v); + friend sc_signed operator - (int u, const sc_signed& v) + { return operator-((long) u, v); } + friend sc_signed operator - (unsigned int u, const sc_signed& v) + { return operator-((unsigned long) u, v); } + + const sc_signed& operator -= (const sc_signed& v); + const sc_signed& operator -= (const sc_unsigned& v); + const sc_signed& operator -= (int64 v); + const sc_signed& operator -= (uint64 v); + const sc_signed& operator -= (long v); + const sc_signed& operator -= (unsigned long v); + const sc_signed& operator -= (int v) + { return operator -= ((long) v); } + const sc_signed& operator -= (unsigned int v) + { return operator -= ((unsigned long) v); } + + friend sc_signed operator - (const sc_unsigned& u, const sc_int_base& v); + friend sc_signed operator - (const sc_unsigned& u, const sc_uint_base& v); + friend sc_signed operator - (const sc_int_base& u, const sc_unsigned& v); + friend sc_signed operator - (const sc_uint_base& u, const sc_unsigned& v); + friend sc_signed operator - (const sc_signed& u, const sc_int_base& v); + friend sc_signed operator - (const sc_signed& u, const sc_uint_base& v); + friend sc_signed operator - (const sc_int_base& u, const sc_signed& v); + friend sc_signed operator - (const sc_uint_base& u, const sc_signed& v); + const sc_signed& operator -= (const sc_int_base& v); + const sc_signed& operator -= (const sc_uint_base& v); + + // MULtiplication operators: + + friend sc_signed operator * (const sc_unsigned& u, const sc_signed& v); + friend sc_signed operator * (const sc_signed& u, const sc_unsigned& v); + + friend sc_signed operator * (const sc_unsigned& u, int64 v); + friend sc_signed operator * (const sc_unsigned& u, long v); + friend sc_signed operator * (const sc_unsigned& u, int v) + { return operator*(u, (long) v); } + + friend sc_signed operator * (int64 u, const sc_unsigned& v); + friend sc_signed operator * (long u, const sc_unsigned& v); + friend sc_signed operator * (int u, const sc_unsigned& v) + { return operator*((long) u, v); } + + friend sc_signed operator * (const sc_signed& u, const sc_signed& v); + friend sc_signed operator * (const sc_signed& u, int64 v); + friend sc_signed operator * (const sc_signed& u, uint64 v); + friend sc_signed operator * (const sc_signed& u, long v); + friend sc_signed operator * (const sc_signed& u, unsigned long v); + friend sc_signed operator * (const sc_signed& u, int v) + { return operator*(u, (long) v); } + friend sc_signed operator * (const sc_signed& u, unsigned int v) + { return operator*(u, (unsigned long) v); } + + friend sc_signed operator * (int64 u, const sc_signed& v); + friend sc_signed operator * (uint64 u, const sc_signed& v); + friend sc_signed operator * (long u, const sc_signed& v); + friend sc_signed operator * (unsigned long u, const sc_signed& v); + friend sc_signed operator * (int u, const sc_signed& v) + { return operator*((long) u, v); } + friend sc_signed operator * (unsigned int u, const sc_signed& v) + { return operator*((unsigned long) u, v); } + + const sc_signed& operator *= (const sc_signed& v); + const sc_signed& operator *= (const sc_unsigned& v); + const sc_signed& operator *= (int64 v); + const sc_signed& operator *= (uint64 v); + const sc_signed& operator *= (long v); + const sc_signed& operator *= (unsigned long v); + const sc_signed& operator *= (int v) + { return operator*=((long) v); } + const sc_signed& operator *= (unsigned int v) + { return operator*=((unsigned long) v); } + + friend sc_signed operator * (const sc_unsigned& u, const sc_int_base& v); + friend sc_signed operator * (const sc_int_base& u, const sc_unsigned& v); + friend sc_signed operator * (const sc_signed& u, const sc_int_base& v); + friend sc_signed operator * (const sc_signed& u, const sc_uint_base& v); + friend sc_signed operator * (const sc_int_base& u, const sc_signed& v); + friend sc_signed operator * (const sc_uint_base& u, const sc_signed& v); + const sc_signed& operator *= (const sc_int_base& v); + const sc_signed& operator *= (const sc_uint_base& v); + + // DIVision operators: + + friend sc_signed operator / (const sc_unsigned& u, const sc_signed& v); + friend sc_signed operator / (const sc_signed& u, const sc_unsigned& v); + + friend sc_signed operator / (const sc_unsigned& u, int64 v); + friend sc_signed operator / (const sc_unsigned& u, long v); + friend sc_signed operator / (const sc_unsigned& u, int v) + { return operator/(u, (long) v); } + + friend sc_signed operator / (int64 u, const sc_unsigned& v); + friend sc_signed operator / (long u, const sc_unsigned& v); + friend sc_signed operator / (int u, const sc_unsigned& v) + { return operator/((long) u, v); } + + friend sc_signed operator / (const sc_signed& u, const sc_signed& v); + friend sc_signed operator / (const sc_signed& u, int64 v); + friend sc_signed operator / (const sc_signed& u, uint64 v); + friend sc_signed operator / (const sc_signed& u, long v); + friend sc_signed operator / (const sc_signed& u, unsigned long v); + friend sc_signed operator / (const sc_signed& u, int v) + { return operator/(u, (long) v); } + friend sc_signed operator / (const sc_signed& u, unsigned int v) + { return operator/(u, (unsigned long) v); } + + friend sc_signed operator / (int64 u, const sc_signed& v); + friend sc_signed operator / (uint64 u, const sc_signed& v); + friend sc_signed operator / (long u, const sc_signed& v); + friend sc_signed operator / (unsigned long u, const sc_signed& v); + friend sc_signed operator / (int u, const sc_signed& v) + { return operator/((long) u, v); } + friend sc_signed operator / (unsigned int u, const sc_signed& v) + { return operator/((unsigned long) u, v); } + + const sc_signed& operator /= (const sc_signed& v); + const sc_signed& operator /= (const sc_unsigned& v); + const sc_signed& operator /= (int64 v); + const sc_signed& operator /= (uint64 v); + const sc_signed& operator /= (long v); + const sc_signed& operator /= (unsigned long v); + const sc_signed& operator /= (int v) + { return operator/=((long) v); } + const sc_signed& operator /= (unsigned int v) + { return operator/=((unsigned long) v); } + + friend sc_signed operator / (const sc_unsigned& u, const sc_int_base& v); + friend sc_signed operator / (const sc_int_base& u, const sc_unsigned& v); + friend sc_signed operator / (const sc_signed& u, const sc_int_base& v); + friend sc_signed operator / (const sc_signed& u, const sc_uint_base& v); + friend sc_signed operator / (const sc_int_base& u, const sc_signed& v); + friend sc_signed operator / (const sc_uint_base& u, const sc_signed& v); + const sc_signed& operator /= (const sc_int_base& v); + const sc_signed& operator /= (const sc_uint_base& v); + + // MODulo operators: + + friend sc_signed operator % (const sc_unsigned& u, const sc_signed& v); + friend sc_signed operator % (const sc_signed& u, const sc_unsigned& v); + + friend sc_signed operator % (const sc_unsigned& u, int64 v); + friend sc_signed operator % (const sc_unsigned& u, long v); + friend sc_signed operator % (const sc_unsigned& u, int v) + { return operator%(u, (long) v); } + + friend sc_signed operator % (int64 u, const sc_unsigned& v); + friend sc_signed operator % (long u, const sc_unsigned& v); + friend sc_signed operator % (int u, const sc_unsigned& v) + { return operator%((long) u, v); } + + friend sc_signed operator % (const sc_signed& u, const sc_signed& v); + friend sc_signed operator % (const sc_signed& u, int64 v); + friend sc_signed operator % (const sc_signed& u, uint64 v); + friend sc_signed operator % (const sc_signed& u, long v); + friend sc_signed operator % (const sc_signed& u, unsigned long v); + friend sc_signed operator % (const sc_signed& u, int v) + { return operator%(u, (long) v); } + friend sc_signed operator % (const sc_signed& u, unsigned int v) + { return operator%(u, (unsigned long) v); } + + friend sc_signed operator % (int64 u, const sc_signed& v); + friend sc_signed operator % (uint64 u, const sc_signed& v); + friend sc_signed operator % (long u, const sc_signed& v); + friend sc_signed operator % (unsigned long u, const sc_signed& v); + friend sc_signed operator % (int u, const sc_signed& v) + { return operator%((long) u, v); } + friend sc_signed operator % (unsigned int u, const sc_signed& v) + { return operator%((unsigned long) u, v); } + + const sc_signed& operator %= (const sc_signed& v); + const sc_signed& operator %= (const sc_unsigned& v); + const sc_signed& operator %= (int64 v); + const sc_signed& operator %= (uint64 v); + const sc_signed& operator %= (long v); + const sc_signed& operator %= (unsigned long v); + const sc_signed& operator %= (int v) + { return operator%=((long) v); } + const sc_signed& operator %= (unsigned int v) + { return operator%=((unsigned long) v); } + + friend sc_signed operator % (const sc_unsigned& u, const sc_int_base& v); + friend sc_signed operator % (const sc_int_base& u, const sc_unsigned& v); + friend sc_signed operator % (const sc_signed& u, const sc_int_base& v); + friend sc_signed operator % (const sc_signed& u, const sc_uint_base& v); + friend sc_signed operator % (const sc_int_base& u, const sc_signed& v); + friend sc_signed operator % (const sc_uint_base& u, const sc_signed& v); + const sc_signed& operator %= (const sc_int_base& v); + const sc_signed& operator %= (const sc_uint_base& v); + + // BITWISE OPERATORS: + + // Bitwise AND operators: + + friend sc_signed operator & (const sc_unsigned& u, const sc_signed& v); + friend sc_signed operator & (const sc_signed& u, const sc_unsigned& v); + + friend sc_signed operator & (const sc_unsigned& u, int64 v); + friend sc_signed operator & (const sc_unsigned& u, long v); + friend sc_signed operator & (const sc_unsigned& u, int v) + { return operator&(u, (long) v); } + + friend sc_signed operator & (int64 u, const sc_unsigned& v); + friend sc_signed operator & (long u, const sc_unsigned& v); + friend sc_signed operator & (int u, const sc_unsigned& v) + { return operator&((long) u, v); } + + friend sc_signed operator & (const sc_signed& u, const sc_signed& v); + friend sc_signed operator & (const sc_signed& u, int64 v); + friend sc_signed operator & (const sc_signed& u, uint64 v); + friend sc_signed operator & (const sc_signed& u, long v); + friend sc_signed operator & (const sc_signed& u, unsigned long v); + friend sc_signed operator & (const sc_signed& u, int v) + { return operator&(u, (long) v); } + friend sc_signed operator & (const sc_signed& u, unsigned int v) + { return operator&(u, (unsigned long) v); } + + friend sc_signed operator & (int64 u, const sc_signed& v); + friend sc_signed operator & (uint64 u, const sc_signed& v); + friend sc_signed operator & (long u, const sc_signed& v); + friend sc_signed operator & (unsigned long u, const sc_signed& v); + friend sc_signed operator & (int u, const sc_signed& v) + { return operator&((long) u, v); } + friend sc_signed operator & (unsigned int u, const sc_signed& v) + { return operator&((unsigned long) u, v); } + + const sc_signed& operator &= (const sc_signed& v); + const sc_signed& operator &= (const sc_unsigned& v); + const sc_signed& operator &= (int64 v); + const sc_signed& operator &= (uint64 v); + const sc_signed& operator &= (long v); + const sc_signed& operator &= (unsigned long v); + const sc_signed& operator &= (int v) + { return operator&=((long) v); } + const sc_signed& operator &= (unsigned int v) + { return operator&=((unsigned long) v); } + + friend sc_signed operator & (const sc_unsigned& u, const sc_int_base& v); + friend sc_signed operator & (const sc_int_base& u, const sc_unsigned& v); + friend sc_signed operator & (const sc_signed& u, const sc_int_base& v); + friend sc_signed operator & (const sc_signed& u, const sc_uint_base& v); + friend sc_signed operator & (const sc_int_base& u, const sc_signed& v); + friend sc_signed operator & (const sc_uint_base& u, const sc_signed& v); + const sc_signed& operator &= (const sc_int_base& v); + const sc_signed& operator &= (const sc_uint_base& v); + + // Bitwise OR operators: + + friend sc_signed operator | (const sc_unsigned& u, const sc_signed& v); + friend sc_signed operator | (const sc_signed& u, const sc_unsigned& v); + + friend sc_signed operator | (const sc_unsigned& u, int64 v); + friend sc_signed operator | (const sc_unsigned& u, long v); + friend sc_signed operator | (const sc_unsigned& u, int v) + { return operator|(u, (long) v); } + + friend sc_signed operator | (int64 u, const sc_unsigned& v); + friend sc_signed operator | (long u, const sc_unsigned& v); + friend sc_signed operator | (int u, const sc_unsigned& v) + { return operator|((long) u, v); } + + friend sc_signed operator | (const sc_signed& u, const sc_signed& v); + friend sc_signed operator | (const sc_signed& u, int64 v); + friend sc_signed operator | (const sc_signed& u, uint64 v); + friend sc_signed operator | (const sc_signed& u, long v); + friend sc_signed operator | (const sc_signed& u, unsigned long v); + friend sc_signed operator | (const sc_signed& u, int v) + { return operator|(u, (long) v); } + friend sc_signed operator | (const sc_signed& u, unsigned int v) + { return operator|(u, (unsigned long) v); } + + friend sc_signed operator | (int64 u, const sc_signed& v); + friend sc_signed operator | (uint64 u, const sc_signed& v); + friend sc_signed operator | (long u, const sc_signed& v); + friend sc_signed operator | (unsigned long u, const sc_signed& v); + friend sc_signed operator | (int u, const sc_signed& v) + { return operator|((long) u, v); } + friend sc_signed operator | (unsigned int u, const sc_signed& v) + { return operator|((unsigned long) u, v); } + + const sc_signed& operator |= (const sc_signed& v); + const sc_signed& operator |= (const sc_unsigned& v); + const sc_signed& operator |= (int64 v); + const sc_signed& operator |= (uint64 v); + const sc_signed& operator |= (long v); + const sc_signed& operator |= (unsigned long v); + const sc_signed& operator |= (int v) + { return operator|=((long) v); } + const sc_signed& operator |= (unsigned int v) + { return operator|=((unsigned long) v); } + + friend sc_signed operator | (const sc_unsigned& u, const sc_int_base& v); + friend sc_signed operator | (const sc_int_base& u, const sc_unsigned& v); + friend sc_signed operator | (const sc_signed& u, const sc_int_base& v); + friend sc_signed operator | (const sc_signed& u, const sc_uint_base& v); + friend sc_signed operator | (const sc_int_base& u, const sc_signed& v); + friend sc_signed operator | (const sc_uint_base& u, const sc_signed& v); + const sc_signed& operator |= (const sc_int_base& v); + const sc_signed& operator |= (const sc_uint_base& v); + + // Bitwise XOR operators: + + friend sc_signed operator ^ (const sc_unsigned& u, const sc_signed& v); + friend sc_signed operator ^ (const sc_signed& u, const sc_unsigned& v); + + friend sc_signed operator ^ (const sc_unsigned& u, int64 v); + friend sc_signed operator ^ (const sc_unsigned& u, long v); + friend sc_signed operator ^ (const sc_unsigned& u, int v) + { return operator^(u, (long) v); } + + friend sc_signed operator ^ (int64 u, const sc_unsigned& v); + friend sc_signed operator ^ (long u, const sc_unsigned& v); + friend sc_signed operator ^ (int u, const sc_unsigned& v) + { return operator^((long) u, v); } + + friend sc_signed operator ^ (const sc_signed& u, const sc_signed& v); + friend sc_signed operator ^ (const sc_signed& u, int64 v); + friend sc_signed operator ^ (const sc_signed& u, uint64 v); + friend sc_signed operator ^ (const sc_signed& u, long v); + friend sc_signed operator ^ (const sc_signed& u, unsigned long v); + friend sc_signed operator ^ (const sc_signed& u, int v) + { return operator^(u, (long) v); } + friend sc_signed operator ^ (const sc_signed& u, unsigned int v) + { return operator^(u, (unsigned long) v); } + + friend sc_signed operator ^ (int64 u, const sc_signed& v); + friend sc_signed operator ^ (uint64 u, const sc_signed& v); + friend sc_signed operator ^ (long u, const sc_signed& v); + friend sc_signed operator ^ (unsigned long u, const sc_signed& v); + friend sc_signed operator ^ (int u, const sc_signed& v) + { return operator^((long) u, v); } + friend sc_signed operator ^ (unsigned int u, const sc_signed& v) + { return operator^((unsigned long) u, v); } + + const sc_signed& operator ^= (const sc_signed& v); + const sc_signed& operator ^= (const sc_unsigned& v); + const sc_signed& operator ^= (int64 v); + const sc_signed& operator ^= (uint64 v); + const sc_signed& operator ^= (long v); + const sc_signed& operator ^= (unsigned long v); + const sc_signed& operator ^= (int v) + { return operator^=((long) v); } + const sc_signed& operator ^= (unsigned int v) + { return operator^=((unsigned long) v); } + + friend sc_signed operator ^ (const sc_unsigned& u, const sc_int_base& v); + friend sc_signed operator ^ (const sc_int_base& u, const sc_unsigned& v); + friend sc_signed operator ^ (const sc_signed& u, const sc_int_base& v); + friend sc_signed operator ^ (const sc_signed& u, const sc_uint_base& v); + friend sc_signed operator ^ (const sc_int_base& u, const sc_signed& v); + friend sc_signed operator ^ (const sc_uint_base& u, const sc_signed& v); + const sc_signed& operator ^= (const sc_int_base& v); + const sc_signed& operator ^= (const sc_uint_base& v); + + // SHIFT OPERATORS: + + // LEFT SHIFT operators: + + friend sc_unsigned operator << (const sc_unsigned& u, const sc_signed& v); + friend sc_signed operator << (const sc_signed& u, const sc_unsigned& v); + + friend sc_signed operator << (const sc_signed& u, const sc_signed& v); + friend sc_signed operator << (const sc_signed& u, int64 v); + friend sc_signed operator << (const sc_signed& u, uint64 v); + friend sc_signed operator << (const sc_signed& u, long v); + friend sc_signed operator << (const sc_signed& u, unsigned long v); + friend sc_signed operator << (const sc_signed& u, int v) + { return operator<<(u, (long) v); } + friend sc_signed operator << (const sc_signed& u, unsigned int v) + { return operator<<(u, (unsigned long) v); } + + const sc_signed& operator <<= (const sc_signed& v); + const sc_signed& operator <<= (const sc_unsigned& v); + const sc_signed& operator <<= (int64 v); + const sc_signed& operator <<= (uint64 v); + const sc_signed& operator <<= (long v); + const sc_signed& operator <<= (unsigned long v); + const sc_signed& operator <<= (int v) + { return operator<<=((long) v); } + const sc_signed& operator <<= (unsigned int v) + { return operator<<=((unsigned long) v); } + + friend sc_signed operator << (const sc_signed& u, const sc_int_base& v); + friend sc_signed operator << (const sc_signed& u, const sc_uint_base& v); + const sc_signed& operator <<= (const sc_int_base& v); + const sc_signed& operator <<= (const sc_uint_base& v); + + // RIGHT SHIFT operators: + + friend sc_unsigned operator >> (const sc_unsigned& u, const sc_signed& v); + friend sc_signed operator >> (const sc_signed& u, const sc_unsigned& v); + + friend sc_signed operator >> (const sc_signed& u, const sc_signed& v); + friend sc_signed operator >> (const sc_signed& u, int64 v); + friend sc_signed operator >> (const sc_signed& u, uint64 v); + friend sc_signed operator >> (const sc_signed& u, long v); + friend sc_signed operator >> (const sc_signed& u, unsigned long v); + friend sc_signed operator >> (const sc_signed& u, int v) + { return operator>>(u, (long) v); } + friend sc_signed operator >> (const sc_signed& u, unsigned int v) + { return operator>>(u, (unsigned long) v); } + + const sc_signed& operator >>= (const sc_signed& v); + const sc_signed& operator >>= (const sc_unsigned& v); + const sc_signed& operator >>= (int64 v); + const sc_signed& operator >>= (uint64 v); + const sc_signed& operator >>= (long v); + const sc_signed& operator >>= (unsigned long v); + const sc_signed& operator >>= (int v) + { return operator>>=((long) v); } + const sc_signed& operator >>= (unsigned int v) + { return operator>>=((unsigned long) v); } + + friend sc_signed operator >> (const sc_signed& u, const sc_int_base& v); + friend sc_signed operator >> (const sc_signed& u, const sc_uint_base& v); + const sc_signed& operator >>= (const sc_int_base& v); + const sc_signed& operator >>= (const sc_uint_base& v); + + // Unary arithmetic operators + friend sc_signed operator + (const sc_signed& u); + friend sc_signed operator - (const sc_signed& u); + friend sc_signed operator - (const sc_unsigned& u); + + // LOGICAL OPERATORS: + + // Logical EQUAL operators: + + friend bool operator == (const sc_unsigned& u, const sc_signed& v); + friend bool operator == (const sc_signed& u, const sc_unsigned& v); + + friend bool operator == (const sc_signed& u, const sc_signed& v); + friend bool operator == (const sc_signed& u, int64 v); + friend bool operator == (const sc_signed& u, uint64 v); + friend bool operator == (const sc_signed& u, long v); + friend bool operator == (const sc_signed& u, unsigned long v); + friend bool operator == (const sc_signed& u, int v) + { return operator==(u, (long) v); } + friend bool operator == (const sc_signed& u, unsigned int v) + { return operator==(u, (unsigned long) v); } + + friend bool operator == (int64 u, const sc_signed& v); + friend bool operator == (uint64 u, const sc_signed& v); + friend bool operator == (long u, const sc_signed& v); + friend bool operator == (unsigned long u, const sc_signed& v); + friend bool operator == (int u, const sc_signed& v) + { return operator==((long) u, v); } + friend bool operator == (unsigned int u, const sc_signed& v) + { return operator==((unsigned long) u, v); } + + friend bool operator == (const sc_signed& u, const sc_int_base& v); + friend bool operator == (const sc_signed& u, const sc_uint_base& v); + friend bool operator == (const sc_int_base& u, const sc_signed& v); + friend bool operator == (const sc_uint_base& u, const sc_signed& v); + + // Logical NOT_EQUAL operators: + + friend bool operator != (const sc_unsigned& u, const sc_signed& v); + friend bool operator != (const sc_signed& u, const sc_unsigned& v); + + friend bool operator != (const sc_signed& u, const sc_signed& v); + friend bool operator != (const sc_signed& u, int64 v); + friend bool operator != (const sc_signed& u, uint64 v); + friend bool operator != (const sc_signed& u, long v); + friend bool operator != (const sc_signed& u, unsigned long v); + friend bool operator != (const sc_signed& u, int v) + { return operator!=(u, (long) v); } + friend bool operator != (const sc_signed& u, unsigned int v) + { return operator!=(u, (unsigned long) v); } + + friend bool operator != (int64 u, const sc_signed& v); + friend bool operator != (uint64 u, const sc_signed& v); + friend bool operator != (long u, const sc_signed& v); + friend bool operator != (unsigned long u, const sc_signed& v); + friend bool operator != (int u, const sc_signed& v) + { return operator!=((long) u, v); } + friend bool operator != (unsigned int u, const sc_signed& v) + { return operator!=((unsigned long) u, v); } + + friend bool operator != (const sc_signed& u, const sc_int_base& v); + friend bool operator != (const sc_signed& u, const sc_uint_base& v); + friend bool operator != (const sc_int_base& u, const sc_signed& v); + friend bool operator != (const sc_uint_base& u, const sc_signed& v); + + // Logical LESS_THAN operators: + + friend bool operator < (const sc_unsigned& u, const sc_signed& v); + friend bool operator < (const sc_signed& u, const sc_unsigned& v); + + friend bool operator < (const sc_signed& u, const sc_signed& v); + friend bool operator < (const sc_signed& u, int64 v); + friend bool operator < (const sc_signed& u, uint64 v); + friend bool operator < (const sc_signed& u, long v); + friend bool operator < (const sc_signed& u, unsigned long v); + friend bool operator < (const sc_signed& u, int v) + { return operator<(u, (long) v); } + friend bool operator < (const sc_signed& u, unsigned int v) + { return operator<(u, (unsigned long) v); } + + friend bool operator < (int64 u, const sc_signed& v); + friend bool operator < (uint64 u, const sc_signed& v); + friend bool operator < (long u, const sc_signed& v); + friend bool operator < (unsigned long u, const sc_signed& v); + friend bool operator < (int u, const sc_signed& v) + { return operator<((long) u, v); } + friend bool operator < (unsigned int u, const sc_signed& v) + { return operator<((unsigned long) u, v); } + + friend bool operator < (const sc_signed& u, const sc_int_base& v); + friend bool operator < (const sc_signed& u, const sc_uint_base& v); + friend bool operator < (const sc_int_base& u, const sc_signed& v); + friend bool operator < (const sc_uint_base& u, const sc_signed& v); + + // Logical LESS_THAN_AND_EQUAL operators: + + friend bool operator <= (const sc_unsigned& u, const sc_signed& v); + friend bool operator <= (const sc_signed& u, const sc_unsigned& v); + + friend bool operator <= (const sc_signed& u, const sc_signed& v); + friend bool operator <= (const sc_signed& u, int64 v); + friend bool operator <= (const sc_signed& u, uint64 v); + friend bool operator <= (const sc_signed& u, long v); + friend bool operator <= (const sc_signed& u, unsigned long v); + friend bool operator <= (const sc_signed& u, int v) + { return operator<=(u, (long) v); } + friend bool operator <= (const sc_signed& u, unsigned int v) + { return operator<=(u, (unsigned long) v); } + + friend bool operator <= (int64 u, const sc_signed& v); + friend bool operator <= (uint64 u, const sc_signed& v); + friend bool operator <= (long u, const sc_signed& v); + friend bool operator <= (unsigned long u, const sc_signed& v); + friend bool operator <= (int u, const sc_signed& v) + { return operator<=((long) u, v); } + friend bool operator <= (unsigned int u, const sc_signed& v) + { return operator<=((unsigned long) u, v); } + + friend bool operator <= (const sc_signed& u, const sc_int_base& v); + friend bool operator <= (const sc_signed& u, const sc_uint_base& v); + friend bool operator <= (const sc_int_base& u, const sc_signed& v); + friend bool operator <= (const sc_uint_base& u, const sc_signed& v); + + // Logical GREATER_THAN operators: + + friend bool operator > (const sc_unsigned& u, const sc_signed& v); + friend bool operator > (const sc_signed& u, const sc_unsigned& v); + + friend bool operator > (const sc_signed& u, const sc_signed& v); + friend bool operator > (const sc_signed& u, int64 v); + friend bool operator > (const sc_signed& u, uint64 v); + friend bool operator > (const sc_signed& u, long v); + friend bool operator > (const sc_signed& u, unsigned long v); + friend bool operator > (const sc_signed& u, int v) + { return operator>(u, (long) v); } + friend bool operator > (const sc_signed& u, unsigned int v) + { return operator>(u, (unsigned long) v); } + + friend bool operator > (int64 u, const sc_signed& v); + friend bool operator > (uint64 u, const sc_signed& v); + friend bool operator > (long u, const sc_signed& v); + friend bool operator > (unsigned long u, const sc_signed& v); + friend bool operator > (int u, const sc_signed& v) + { return operator>((long) u, v); } + friend bool operator > (unsigned int u, const sc_signed& v) + { return operator>((unsigned long) u, v); } + + friend bool operator > (const sc_signed& u, const sc_int_base& v); + friend bool operator > (const sc_signed& u, const sc_uint_base& v); + friend bool operator > (const sc_int_base& u, const sc_signed& v); + friend bool operator > (const sc_uint_base& u, const sc_signed& v); + + // Logical GREATER_THAN_AND_EQUAL operators: + + friend bool operator >= (const sc_unsigned& u, const sc_signed& v); + friend bool operator >= (const sc_signed& u, const sc_unsigned& v); + + friend bool operator >= (const sc_signed& u, const sc_signed& v); + friend bool operator >= (const sc_signed& u, int64 v); + friend bool operator >= (const sc_signed& u, uint64 v); + friend bool operator >= (const sc_signed& u, long v); + friend bool operator >= (const sc_signed& u, unsigned long v); + friend bool operator >= (const sc_signed& u, int v) + { return operator>=(u, (long) v); } + friend bool operator >= (const sc_signed& u, unsigned int v) + { return operator>=(u, (unsigned long) v); } + + friend bool operator >= (int64 u, const sc_signed& v); + friend bool operator >= (uint64 u, const sc_signed& v); + friend bool operator >= (long u, const sc_signed& v); + friend bool operator >= (unsigned long u, const sc_signed& v); + friend bool operator >= (int u, const sc_signed& v) + { return operator>=((long) u, v); } + friend bool operator >= (unsigned int u, const sc_signed& v) + { return operator>=((unsigned long) u, v); } + + friend bool operator >= (const sc_signed& u, const sc_int_base& v); + friend bool operator >= (const sc_signed& u, const sc_uint_base& v); + friend bool operator >= (const sc_int_base& u, const sc_signed& v); + friend bool operator >= (const sc_uint_base& u, const sc_signed& v); + + // Bitwise NOT operator (unary). + friend sc_signed operator ~ (const sc_signed& u); + + // Helper functions. + friend sc_signed add_signed_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + small_type vs, + int vnb, + int vnd, + const sc_digit *vd); + + friend sc_signed sub_signed_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + small_type vs, + int vnb, + int vnd, + const sc_digit *vd); + + friend sc_signed mul_signed_friend(small_type s, + int unb, + int und, + const sc_digit *ud, + int vnb, + int vnd, + const sc_digit *vd); + + friend sc_signed div_signed_friend(small_type s, + int unb, + int und, + const sc_digit *ud, + int vnb, + int vnd, + const sc_digit *vd); + + friend sc_signed mod_signed_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + int vnb, + int vnd, + const sc_digit *vd); + + friend sc_signed and_signed_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + small_type vs, + int vnb, + int vnd, + const sc_digit *vd); + + friend sc_signed or_signed_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + small_type vs, + int vnb, + int vnd, + const sc_digit *vd); + + friend sc_signed xor_signed_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + small_type vs, + int vnb, + int vnd, + const sc_digit *vd); + +private: + + small_type sgn; // Shortened as s. + int nbits; // Shortened as nb. + int ndigits; // Shortened as nd. + +#ifdef SC_MAX_NBITS + sc_digit digit[DIV_CEIL(SC_MAX_NBITS)]; // Shortened as d. +#else + sc_digit *digit; // Shortened as d. +#endif + + // Private constructors: + + // Create a copy of v with sign s. + sc_signed(const sc_signed& v, small_type s); + sc_signed(const sc_unsigned& v, small_type s); + + // Create a signed number with the given attributes. + sc_signed(small_type s, int nb, int nd, + sc_digit *d, bool alloc = true); + + // Create an unsigned number using the bits u[l..r]. + sc_signed(const sc_signed* u, int l, int r); + sc_signed(const sc_unsigned* u, int l, int r); + + // Private member functions. The called functions are inline functions. + + small_type default_sign() const + { return SC_NOSIGN; } + + int num_bits(int nb) const { return nb; } + + bool check_if_outside(int bit_num) const; + + void copy_digits(int nb, int nd, const sc_digit *d) + { copy_digits_signed(sgn, nbits, ndigits, digit, nb, nd, d); } + + void makezero() + { sgn = make_zero(ndigits, digit); } + + // Conversion functions between 2's complement (2C) and + // sign-magnitude (SM): + void convert_2C_to_SM() + { sgn = convert_signed_2C_to_SM(nbits, ndigits, digit); } + + void convert_SM_to_2C_to_SM() + { sgn = convert_signed_SM_to_2C_to_SM(sgn, nbits, ndigits, digit); } + + void convert_SM_to_2C() + { convert_signed_SM_to_2C(sgn, ndigits, digit); } + +}; + + + +inline +::std::ostream& +operator << ( ::std::ostream&, const sc_signed& ); + +inline +::std::istream& +operator >> ( ::std::istream&, sc_signed& ); + + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_signed_bitref_r& a ) +{ + a.print( os ); + return os; +} + + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_signed_bitref& a ) +{ + a.scan( is ); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_signed_subref_r +// +// Proxy class for sc_signed part selection (r-value only). +// ---------------------------------------------------------------------------- + + +// reduce methods + +inline bool sc_signed_subref_r::and_reduce() const +{ + const sc_signed* target_p = m_obj_p; + for ( int i = m_right; i <= m_left; i++ ) + if ( !target_p->test(i) ) return false; + return true; +} + +inline bool sc_signed_subref_r::nand_reduce() const +{ + return !and_reduce(); +} + +inline bool sc_signed_subref_r::or_reduce() const +{ + const sc_signed* target_p = m_obj_p; + for ( int i = m_right; i <= m_left; i++ ) + if ( target_p->test(i) ) return true; + return false; +} + +inline bool sc_signed_subref_r::nor_reduce() const +{ + return !or_reduce(); +} + +inline bool sc_signed_subref_r::xor_reduce() const +{ + int odd; + const sc_signed* target_p = m_obj_p; + odd = 0; + for ( int i = m_right; i <= m_left; i++ ) + if ( target_p->test(i) ) odd = ~odd; + return odd ? true : false; +} + +inline bool sc_signed_subref_r::xnor_reduce() const +{ + return !xor_reduce(); +} + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_signed_subref_r& a ) +{ + a.print( os ); + return os; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_signed_subref +// +// Proxy class for sc_signed part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +// assignment operators + +inline +const sc_signed_subref& +sc_signed_subref::operator = ( const char* a ) +{ + sc_signed aa( length() ); + return ( *this = aa = a ); +} + + + + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_signed_subref& a ) +{ + a.scan( is ); + return is; +} + + + +// ---------------------------------------------------------------------------- +// CLASS : sc_signed +// +// Arbitrary precision signed number. +// ---------------------------------------------------------------------------- + +template<class T> +sc_signed::sc_signed( const sc_generic_base<T>& v ) +{ + int nb = v->length(); + sgn = default_sign(); + if( nb > 0 ) { + nbits = num_bits( nb ); + } else { + char msg[BUFSIZ]; + std::sprintf( msg, + "sc_unsigned( sc_generic_base<T> ) : nb = %d is not valid", nb); + SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg ); + } + ndigits = DIV_CEIL(nbits); +# ifdef SC_MAX_NBITS + test_bound(nb); +# else + digit = new sc_digit[ndigits]; +# endif + makezero(); + v->to_sc_signed(*this); +} + + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_signed& a ) +{ + a.print( os ); + return os; +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_signed& a ) +{ + a.scan( is ); + return is; +} + + +} // namespace sc_dt + + +#endif diff --git a/ext/systemc/src/sysc/datatypes/int/sc_signed_bitref.inc b/ext/systemc/src/sysc/datatypes/int/sc_signed_bitref.inc new file mode 100644 index 000000000..46d347d94 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_signed_bitref.inc @@ -0,0 +1,163 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_signed_bitref.h -- Proxy class that is declared in sc_signed.h. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// ---------------------------------------------------------------------------- +// CLASS : sc_signed_bitref_r +// +// Proxy class for sc_signed bit selection (r-value only). +// ---------------------------------------------------------------------------- + +// implicit conversion to uint64 + +sc_signed_bitref_r::operator uint64 () const +{ + return m_obj_p->test( m_index ); +} + +bool +sc_signed_bitref_r::operator ! () const +{ + return ( ! m_obj_p->test( m_index ) ); +} + +bool +sc_signed_bitref_r::operator ~ () const +{ + return ( ! m_obj_p->test( m_index ) ); +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_signed_bitref +// +// Proxy class for sc_signed bit selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +// assignment operators + +const sc_signed_bitref& +sc_signed_bitref::operator = ( const sc_signed_bitref_r& b ) +{ + m_obj_p->set( m_index, (bool) b ); + return *this; +} + +const sc_signed_bitref& +sc_signed_bitref::operator = ( const sc_signed_bitref& b ) +{ + m_obj_p->set( m_index, (bool) b ); + return *this; +} + +const sc_signed_bitref& +sc_signed_bitref::operator = ( bool b ) +{ + m_obj_p->set( m_index, b ); + return *this; +} + + +const sc_signed_bitref& +sc_signed_bitref::operator &= ( bool b ) +{ + if( ! b ) { + m_obj_p->clear( m_index ); + } + return *this; +} + +const sc_signed_bitref& +sc_signed_bitref::operator |= ( bool b ) +{ + if( b ) { + m_obj_p->set( m_index ); + } + return *this; +} + +const sc_signed_bitref& +sc_signed_bitref::operator ^= ( bool b ) +{ + if( b ) { + m_obj_p->invert( m_index ); + } + return *this; +} + +// #### OPTIMIZE +void sc_signed_bitref::concat_set(int64 src, int low_i) +{ + bool value = 1 & ((low_i < 64) ? (src >> low_i) : (src >> 63)); + m_obj_p->set(low_i, value); +} + +void sc_signed_bitref::concat_set(const sc_signed& src, int low_i) +{ + if ( low_i < src.length() ) + m_obj_p->set(low_i, src.test(low_i)); + else + m_obj_p->set(low_i, src<0); +} + +void sc_signed_bitref::concat_set(const sc_unsigned& src, int low_i) +{ + if ( low_i < src.length() ) + m_obj_p->set(low_i, src.test(low_i)); + else + m_obj_p->set(low_i, 0); +} + +void sc_signed_bitref::concat_set(uint64 src, int low_i) +{ + bool value = 1 & ((low_i < 64) ? (src >> low_i) : 0); + m_obj_p->set(low_i, value); +} + + +// other methods + +void +sc_signed_bitref::scan( ::std::istream& is ) +{ + bool b; + is >> b; + *this = b; +} + + +// End of file diff --git a/ext/systemc/src/sysc/datatypes/int/sc_signed_subref.inc b/ext/systemc/src/sysc/datatypes/int/sc_signed_subref.inc new file mode 100644 index 000000000..3f50210a7 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_signed_subref.inc @@ -0,0 +1,408 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_signed_subref.h -- Proxy class that is declared in sc_signed.h. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// ---------------------------------------------------------------------------- +// CLASS : sc_signed_subref_r +// +// Proxy class for sc_signed part selection (r-value only). +// ---------------------------------------------------------------------------- + +// concatenation support + +uint64 sc_signed_subref_r::concat_get_uint64() const +{ + sc_unsigned a( m_obj_p, m_left, m_right ); + return a.to_uint64(); +} + + +bool sc_signed_subref_r::concat_get_ctrl(sc_digit* dst_p, int low_i ) const +{ + sc_unsigned a( m_obj_p, m_left, m_right ); + return a.concat_get_ctrl( dst_p, low_i ); +} + + +bool sc_signed_subref_r::concat_get_data(sc_digit* dst_p, int low_i ) const +{ + sc_unsigned a( m_obj_p, m_left, m_right ); + return a.concat_get_data( dst_p, low_i ); +} + + +// implicit conversion to sc_signed + +sc_signed_subref_r::operator sc_unsigned () const +{ + return sc_unsigned( m_obj_p, m_left, m_right ); +} + + +// explicit conversions + +int +sc_signed_subref_r::to_int() const +{ + sc_unsigned a( m_obj_p, m_left, m_right ); + return a.to_int(); +} + +unsigned int +sc_signed_subref_r::to_uint() const +{ + sc_unsigned a( m_obj_p, m_left, m_right ); + return a.to_uint(); +} + +long +sc_signed_subref_r::to_long() const +{ + sc_unsigned a( m_obj_p, m_left, m_right ); + return a.to_long(); +} + +unsigned long +sc_signed_subref_r::to_ulong() const +{ + sc_unsigned a( m_obj_p, m_left, m_right ); + return a.to_ulong(); +} + +int64 +sc_signed_subref_r::to_int64() const +{ + sc_unsigned a( m_obj_p, m_left, m_right ); + return a.to_int64(); +} + +uint64 +sc_signed_subref_r::to_uint64() const +{ + sc_unsigned a( m_obj_p, m_left, m_right ); + return a.to_uint64(); +} + +double +sc_signed_subref_r::to_double() const +{ + sc_unsigned a( m_obj_p, m_left, m_right ); + return a.to_double(); +} + + +// explicit conversion to character string + +const std::string +sc_signed_subref_r::to_string( sc_numrep numrep ) const +{ + sc_unsigned a( length() ); + a = *this; + return a.to_string( numrep ); +} + +const std::string +sc_signed_subref_r::to_string( sc_numrep numrep, bool w_prefix ) const +{ + sc_unsigned a( length() ); + a = *this; + return a.to_string( numrep, w_prefix ); +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_signed_subref +// +// Proxy class for sc_signed part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +// assignment operators + +const sc_signed_subref& +sc_signed_subref::operator = ( const sc_signed_subref_r& a ) +{ + return operator = ( (sc_unsigned)( a ) ); +} + +const sc_signed_subref& +sc_signed_subref::operator = ( const sc_signed_subref& v ) +{ + if( this == &v ) { + return *this; + } + return operator = ( (sc_unsigned)( v ) ); +} + +const sc_signed_subref& +sc_signed_subref::operator = ( const sc_signed& v ) +{ + int i; + int l = sc_min( m_left, v.nbits - 1 + m_right ); + + for( i = m_right; i <= l; ++ i ) m_obj_p->set( i, v.test( i - m_right ) ); + for ( ; i <= m_left; i++ ) m_obj_p->set( i, v.test( l ) ); + + return *this; +} + +const sc_signed_subref& +sc_signed_subref::operator = ( const sc_unsigned_subref_r& v ) +{ + return operator = ( (sc_unsigned)( v ) ); +} + +const sc_signed_subref& +sc_signed_subref::operator = ( const sc_unsigned& v ) +{ + int i; + int l = sc_min( m_left, v.nbits - 1 + m_right ); + + for( i = m_right; i <= l; ++ i ) m_obj_p->set( i, v.test( i - m_right ) ); + for ( ; i <= m_left; i++ ) m_obj_p->set( i, 0 ); + return *this; +} + +const sc_signed_subref& +sc_signed_subref::operator = ( unsigned long v ) +{ + for( int i = m_right; i <= m_left; ++ i ) { + m_obj_p->set( i, static_cast<bool>( v & 1 ) ); + v >>= 1; + } + return *this; +} + +const sc_signed_subref& +sc_signed_subref::operator = ( long v ) +{ + unsigned long v2 = (unsigned long) v; + for( int i = m_right; i <= m_left; ++ i ) { + m_obj_p->set( i, static_cast<bool>( v2 & 1 ) ); + v2 >>= 1; + } + return *this; +} + +const sc_signed_subref& +sc_signed_subref::operator = ( uint64 v ) +{ + for( int i = m_right; i <= m_left; ++ i ) { + m_obj_p->set( i, static_cast<bool>( v & 1 ) ); + v >>= 1; + } + return *this; +} + +const sc_signed_subref& +sc_signed_subref::operator = ( int64 v ) +{ + uint64 v2 = (uint64) v; + for( int i = m_right; i <= m_left; ++ i ) { + m_obj_p->set( i, static_cast<bool>( v2 & 1 ) ); + v2 >>= 1; + } + return *this; +} + +const sc_signed_subref& +sc_signed_subref::operator = ( double v ) +{ + is_bad_double(v); + + int nb = m_left - m_right + 1; + int nd = DIV_CEIL(nb); + +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS]; +#else + sc_digit *d = new sc_digit[nd]; +#endif + + if (v < 0) + v = -v; + + int i = 0; + + while (floor(v) && (i < nd)) { +#ifndef _WIN32 + d[i++] = (sc_digit) floor(remainder(v, DIGIT_RADIX)); +#else + d[i++] = (sc_digit) floor(fmod(v, DIGIT_RADIX)); +#endif + v /= DIGIT_RADIX; + } + + vec_zero(i, nd, d); + + sc_digit val = 1; // Bit value. + int j = 0; // Current digit in d. + + i = 0; // Current bit in d. + + while (i < nb) { + + m_obj_p->set(i + m_right, (bool) (d[j] & val)); + + ++i; + + if (i % BITS_PER_DIGIT == 0) { + val = 1; + ++j; + } + else + val <<= 1; + } + +#ifndef SC_MAX_NBITS + delete [] d; +#endif + + return *this; +} + +const sc_signed_subref& +sc_signed_subref::operator = ( const sc_int_base& a ) +{ + return operator = ( (int64) a ); +} + +const sc_signed_subref& +sc_signed_subref::operator = ( const sc_uint_base& a ) +{ + return operator = ( (uint64) a ); +} + +// concatenation methods + + +void sc_signed_subref::concat_set( int64 src, int low_i ) +{ + int i; + int l; + bool sign = src < 0; + + if ( low_i < 64 ) + { + src = src >> low_i; + l = sc_min( m_left, (63-low_i) + m_right ); + for( i = m_right; i <= l; ++ i ) { + m_obj_p->set( i, src & 1 ); + src = src >> 1; + } + for ( ; i <= m_left; i++ ) m_obj_p->set(i, sign); + } + else + { + for( i = m_right; i <= m_left; ++ i ) m_obj_p->set(i, sign); + } +} + +void sc_signed_subref::concat_set( const sc_signed& src, int low_i ) +{ + int i; + int l; + int src_i; + bool sign = src.test(src.nbits-1); + l = src.nbits - (low_i+1); + if ( l >= 0 ) + { + l = sc_min( m_left, l + m_right ); + src_i = low_i; + for( i = m_right; i <= l; ++ i, src_i++ ) { + m_obj_p->set( i, src.test( src_i ) ); + } + for ( ; i <= m_left; i++ ) m_obj_p->set(i, sign); + } + else + { + for( i = m_right; i <= m_left; ++ i ) m_obj_p->set(i, sign); + } +} + +void sc_signed_subref::concat_set( const sc_unsigned& src, int low_i ) +{ + int i; + int l; + int src_i; + l = src.nbits - (low_i+2); + if ( l >= 0 ) + { + l = sc_min( m_left, l + m_right ); + src_i = low_i; + for( i = m_right; i <= l; ++ i, src_i++ ) { + m_obj_p->set( i, src.test( src_i ) ); + } + for ( ; i <= m_left; i++ ) m_obj_p->set(false); + } + else + { + for( i = m_right; i <= m_left; ++ i ) m_obj_p->set(false); + } +} + +void sc_signed_subref::concat_set( uint64 src, int low_i ) +{ + int i; + int l; + + if ( low_i < 64 ) + { + src = src >> low_i; + l = sc_min( m_left, (63-low_i) + m_right ); + for( i = m_right; i <= l; ++ i ) { + m_obj_p->set( i, src & 1 ); + src = src >> 1; + } + for ( ; i <= m_left; i++ ) m_obj_p->set(false); + } + else + { + for( i = m_right; i <= m_left; ++ i ) m_obj_p->set(false); + } +} +// other methods + +void +sc_signed_subref::scan( ::std::istream& is ) +{ + std::string s; + is >> s; + *this = s.c_str(); +} + + +// End of file diff --git a/ext/systemc/src/sysc/datatypes/int/sc_uint.h b/ext/systemc/src/sysc/datatypes/int/sc_uint.h new file mode 100644 index 000000000..90ebd7f97 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_uint.h @@ -0,0 +1,312 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_uint.h -- A sc_uint is an unsigned integer whose length is less than the + machine's native integer length. We provide two implementations + (i) sc_uint with length between 1 - 64, and (ii) sc_uint with + length between 1 - 32. Implementation (i) is the default + implementation, while implementation (ii) can be used only if + compiled with -D_32BIT_. Unlike arbitrary precision, arithmetic + and bitwise operations are performed using the native types + (hence capped at 32/64 bits). The sc_uint integer is useful + when the user does not need arbitrary precision and the + performance is superior to sc_bigint/sc_biguint. + + Original Author: Amit Rao, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc. + Description of Modification: - Resolved ambiguity with sc_(un)signed. + - Merged the code for 64- and 32-bit versions + via the constants in sc_nbdefs.h. + - Eliminated redundant file inclusions. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_uint.h,v $ +// Revision 1.2 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:32 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef SC_UINT_H +#define SC_UINT_H + + +#include "sysc/datatypes/int/sc_uint_base.h" + + +namespace sc_dt +{ + +// classes defined in this module +template <int W> class sc_uint; + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_uint<W> +// +// Template class sc_uint<W> is the interface that the user sees. It +// is derived from sc_uint_base and most of its methods are just +// wrappers that call the corresponding method in the parent +// class. Note that the length of sc_uint datatype is specified as a +// template parameter. +// ---------------------------------------------------------------------------- + +template <int W> +class sc_uint + : public sc_uint_base +{ +public: + + // constructors + + sc_uint() + : sc_uint_base( W ) + {} + + sc_uint( uint_type v ) + : sc_uint_base( v, W ) + {} + + sc_uint( const sc_uint<W>& a ) + : sc_uint_base( a ) + {} + + sc_uint( const sc_uint_base& a ) + : sc_uint_base( W ) + { sc_uint_base::operator = ( a ); } + + sc_uint( const sc_uint_subref_r& a ) + : sc_uint_base( W ) + { sc_uint_base::operator = ( a ); } + + template< class T > + sc_uint( const sc_generic_base<T>& a ) + : sc_uint_base( W ) + { sc_uint_base::operator = ( a ); } + + sc_uint( const sc_signed& a ) + : sc_uint_base( W ) + { sc_uint_base::operator = ( a ); } + + sc_uint( const sc_unsigned& a ) + : sc_uint_base( W ) + { sc_uint_base::operator = ( a ); } + +#ifdef SC_INCLUDE_FX + + explicit sc_uint( const sc_fxval& a ) + : sc_uint_base( W ) + { sc_uint_base::operator = ( a ); } + + explicit sc_uint( const sc_fxval_fast& a ) + : sc_uint_base( W ) + { sc_uint_base::operator = ( a ); } + + explicit sc_uint( const sc_fxnum& a ) + : sc_uint_base( W ) + { sc_uint_base::operator = ( a ); } + + explicit sc_uint( const sc_fxnum_fast& a ) + : sc_uint_base( W ) + { sc_uint_base::operator = ( a ); } + +#endif + + sc_uint( const sc_bv_base& a ) + : sc_uint_base( W ) + { sc_uint_base::operator = ( a ); } + + sc_uint( const sc_lv_base& a ) + : sc_uint_base( W ) + { sc_uint_base::operator = ( a ); } + + sc_uint( const char* a ) + : sc_uint_base( W ) + { sc_uint_base::operator = ( a ); } + + sc_uint( unsigned long a ) + : sc_uint_base( W ) + { sc_uint_base::operator = ( a ); } + + sc_uint( long a ) + : sc_uint_base( W ) + { sc_uint_base::operator = ( a ); } + + sc_uint( unsigned int a ) + : sc_uint_base( W ) + { sc_uint_base::operator = ( a ); } + + sc_uint( int a ) + : sc_uint_base( W ) + { sc_uint_base::operator = ( a ); } + + sc_uint( int64 a ) + : sc_uint_base( W ) + { sc_uint_base::operator = ( a ); } + + sc_uint( double a ) + : sc_uint_base( W ) + { sc_uint_base::operator = ( a ); } + + + // assignment operators + + sc_uint<W>& operator = ( uint_type v ) + { sc_uint_base::operator = ( v ); return *this; } + + sc_uint<W>& operator = ( const sc_uint_base& a ) + { sc_uint_base::operator = ( a ); return *this; } + + sc_uint<W>& operator = ( const sc_uint_subref_r& a ) + { sc_uint_base::operator = ( a ); return *this; } + + sc_uint<W>& operator = ( const sc_uint<W>& a ) + { m_val = a.m_val; return *this; } + + template<class T> + sc_uint<W>& operator = ( const sc_generic_base<T>& a ) + { sc_uint_base::operator = ( a ); return *this; } + + sc_uint<W>& operator = ( const sc_signed& a ) + { sc_uint_base::operator = ( a ); return *this; } + + sc_uint<W>& operator = ( const sc_unsigned& a ) + { sc_uint_base::operator = ( a ); return *this; } + +#ifdef SC_INCLUDE_FX + + sc_uint<W>& operator = ( const sc_fxval& a ) + { sc_uint_base::operator = ( a ); return *this; } + + sc_uint<W>& operator = ( const sc_fxval_fast& a ) + { sc_uint_base::operator = ( a ); return *this; } + + sc_uint<W>& operator = ( const sc_fxnum& a ) + { sc_uint_base::operator = ( a ); return *this; } + + sc_uint<W>& operator = ( const sc_fxnum_fast& a ) + { sc_uint_base::operator = ( a ); return *this; } + +#endif + + sc_uint<W>& operator = ( const sc_bv_base& a ) + { sc_uint_base::operator = ( a ); return *this; } + + sc_uint<W>& operator = ( const sc_lv_base& a ) + { sc_uint_base::operator = ( a ); return *this; } + + sc_uint<W>& operator = ( const char* a ) + { sc_uint_base::operator = ( a ); return *this; } + + sc_uint<W>& operator = ( unsigned long a ) + { sc_uint_base::operator = ( a ); return *this; } + + sc_uint<W>& operator = ( long a ) + { sc_uint_base::operator = ( a ); return *this; } + + sc_uint<W>& operator = ( unsigned int a ) + { sc_uint_base::operator = ( a ); return *this; } + + sc_uint<W>& operator = ( int a ) + { sc_uint_base::operator = ( a ); return *this; } + + sc_uint<W>& operator = ( int64 a ) + { sc_uint_base::operator = ( a ); return *this; } + + sc_uint<W>& operator = ( double a ) + { sc_uint_base::operator = ( a ); return *this; } + + + // arithmetic assignment operators + + sc_uint<W>& operator += ( uint_type v ) + { sc_uint_base::operator += ( v ); return *this; } + + sc_uint<W>& operator -= ( uint_type v ) + { sc_uint_base::operator -= ( v ); return *this; } + + sc_uint<W>& operator *= ( uint_type v ) + { sc_uint_base::operator *= ( v ); return *this; } + + sc_uint<W>& operator /= ( uint_type v ) + { sc_uint_base::operator /= ( v ); return *this; } + + sc_uint<W>& operator %= ( uint_type v ) + { sc_uint_base::operator %= ( v ); return *this; } + + + // bitwise assignment operators + + sc_uint<W>& operator &= ( uint_type v ) + { sc_uint_base::operator &= ( v ); return *this; } + + sc_uint<W>& operator |= ( uint_type v ) + { sc_uint_base::operator |= ( v ); return *this; } + + sc_uint<W>& operator ^= ( uint_type v ) + { sc_uint_base::operator ^= ( v ); return *this; } + + + sc_uint<W>& operator <<= ( uint_type v ) + { sc_uint_base::operator <<= ( v ); return *this; } + + sc_uint<W>& operator >>= ( uint_type v ) + { sc_uint_base::operator >>= ( v ); return *this; } + + + // prefix and postfix increment and decrement operators + + sc_uint<W>& operator ++ () // prefix + { sc_uint_base::operator ++ (); return *this; } + + const sc_uint<W> operator ++ ( int ) // postfix + { return sc_uint<W>( sc_uint_base::operator ++ ( 0 ) ); } + + sc_uint<W>& operator -- () // prefix + { sc_uint_base::operator -- (); return *this; } + + const sc_uint<W> operator -- ( int ) // postfix + { return sc_uint<W>( sc_uint_base::operator -- ( 0 ) ); } +}; + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/int/sc_uint_base.cpp b/ext/systemc/src/sysc/datatypes/int/sc_uint_base.cpp new file mode 100644 index 000000000..e3a12e4e0 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_uint_base.cpp @@ -0,0 +1,727 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_uint_base.cpp -- contains interface definitions between sc_uint and + sc_signed, sc_unsigned, and definitions for sc_uint_subref. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_uint_base.cpp,v $ +// Revision 1.5 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.4 2010/02/04 22:23:29 acg +// Andy Goodrich: fixed bug in concatenation reads for part selections, +// the mask being used was 32 bits and should have been 64 bits. +// +// Revision 1.3 2008/06/19 17:47:57 acg +// Andy Goodrich: fixes for bugs. See 2.2.1 RELEASENOTES. +// +// Revision 1.2 2007/11/04 21:27:00 acg +// Andy Goodrich: changes to make sure the proper value is returned from +// concat_get_data(). +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:32 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#include "sysc/kernel/sc_macros.h" +#include "sysc/datatypes/int/sc_signed.h" +#include "sysc/datatypes/int/sc_unsigned.h" +#include "sysc/datatypes/int/sc_uint_base.h" +#include "sysc/datatypes/int/sc_int_ids.h" +#include "sysc/datatypes/bit/sc_bv_base.h" +#include "sysc/datatypes/bit/sc_lv_base.h" +#include "sysc/datatypes/misc/sc_concatref.h" +#include "sysc/datatypes/fx/sc_ufix.h" +#include "sysc/datatypes/fx/scfx_other_defs.h" + + +namespace sc_dt +{ + +// to avoid code bloat in sc_uint_concat<T1,T2> + +void +sc_uint_concref_invalid_length( int length ) +{ + char msg[BUFSIZ]; + std::sprintf( msg, + "sc_uint_concref<T1,T2> initialization: length = %d " + "violates 1 <= length <= %d", + length, SC_INTWIDTH ); + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); +} + + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_bitref +// +// Proxy class for sc_uint bit selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +sc_core::sc_vpool<sc_uint_bitref> sc_uint_bitref::m_pool(9); + +// concatenation methods: + +// #### OPTIMIZE +void sc_uint_bitref::concat_set(int64 src, int low_i) +{ + sc_uint_base aa( 1 ); + *this = aa = (low_i < 64) ? src >> low_i : src >> 63; +} + +void sc_uint_bitref::concat_set(const sc_signed& src, int low_i) +{ + sc_uint_base aa( 1 ); + if ( low_i < src.length() ) + *this = aa = 1 & (src >> low_i); + else + *this = aa = (src < 0) ? (int_type)-1 : 0; +} + +void sc_uint_bitref::concat_set(const sc_unsigned& src, int low_i) +{ + sc_uint_base aa( 1 ); + if ( low_i < src.length() ) + *this = aa = 1 & (src >> low_i); + else + *this = aa = 0; +} + +void sc_uint_bitref::concat_set(uint64 src, int low_i) +{ + sc_uint_base aa( 1 ); + *this = aa = (low_i < 64) ? src >> low_i : 0; +} + + +// other methods + +void +sc_uint_bitref::scan( ::std::istream& is ) +{ + bool b; + is >> b; + *this = b; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_subref_r +// +// Proxy class for sc_uint part selection (l-value). +// ---------------------------------------------------------------------------- + +bool sc_uint_subref_r::concat_get_ctrl( sc_digit* dst_p, int low_i ) const +{ + int dst_i; // Word in dst_p now processing. + int end_i; // Highest order word in dst_p to process. + int left_shift; // Left shift for val. + uint_type mask; // Mask for bits to extract or keep. + + dst_i = low_i / BITS_PER_DIGIT; + left_shift = low_i % BITS_PER_DIGIT; + end_i = (low_i + (m_left-m_right)) / BITS_PER_DIGIT; + + mask = ~(-1 << left_shift); + dst_p[dst_i] = (sc_digit)((dst_p[dst_i] & mask)); + + dst_i++; + for ( ; dst_i <= end_i; dst_i++ ) dst_p[dst_i] = 0; + + return false; +} + +bool sc_uint_subref_r::concat_get_data( sc_digit* dst_p, int low_i ) const +{ + int dst_i; // Word in dst_p now processing. + int end_i; // Highest order word in dst_p to process. + int high_i; // Index of high order bit in dst_p to set. + int left_shift; // Left shift for val. + uint_type mask; // Mask for bits to extract or keep. + bool result; // True if inserting non-zero value. + uint_type val; // Selection value extracted from m_obj_p. + + dst_i = low_i / BITS_PER_DIGIT; + left_shift = low_i % BITS_PER_DIGIT; + high_i = low_i + (m_left-m_right); + end_i = high_i / BITS_PER_DIGIT; + mask = ~mask_int[m_left][m_right]; + val = (m_obj_p->m_val & mask) >> m_right; + result = val != 0; + + + // PROCESS THE FIRST WORD: + + mask = ~(-1 << left_shift); + dst_p[dst_i] = (sc_digit)(((dst_p[dst_i] & mask)) | + ((val << left_shift) & DIGIT_MASK)); + + switch ( end_i - dst_i ) + { + // BITS ARE ACROSS TWO WORDS: + + case 1: + dst_i++; + val >>= (BITS_PER_DIGIT-left_shift); + dst_p[dst_i] = (sc_digit)val; + break; + + // BITS ARE ACROSS THREE WORDS: + + case 2: + dst_i++; + val >>= (BITS_PER_DIGIT-left_shift); + dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK); + val >>= BITS_PER_DIGIT; + dst_p[dst_i] = (sc_digit)val; + break; + + // BITS ARE ACROSS THREE WORDS: + + case 3: + dst_i++; + val >>= (BITS_PER_DIGIT-left_shift); + dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK); + val >>= BITS_PER_DIGIT; + dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK); + val >>= BITS_PER_DIGIT; + dst_p[dst_i] = (sc_digit)val; + break; + } + return result; +} + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_subref +// +// Proxy class for sc_uint part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +sc_core::sc_vpool<sc_uint_subref> sc_uint_subref::m_pool(9); + +// assignment operators + +sc_uint_subref& +sc_uint_subref::operator = ( uint_type v ) +{ + uint_type val = m_obj_p->m_val; + uint_type mask = mask_int[m_left][m_right]; + val &= mask; + val |= (v << m_right) & ~mask; + m_obj_p->m_val = val; + m_obj_p->extend_sign(); + return *this; +} + +sc_uint_subref& +sc_uint_subref::operator = ( const sc_signed& a ) +{ + sc_uint_base aa( length() ); + return ( *this = aa = a ); +} + +sc_uint_subref& +sc_uint_subref::operator = ( const sc_unsigned& a ) +{ + sc_uint_base aa( length() ); + return ( *this = aa = a ); +} + +sc_uint_subref& +sc_uint_subref::operator = ( const sc_bv_base& a ) +{ + sc_uint_base aa( length() ); + return ( *this = aa = a ); +} + +sc_uint_subref& +sc_uint_subref::operator = ( const sc_lv_base& a ) +{ + sc_uint_base aa( length() ); + return ( *this = aa = a ); +} + +// concatenation methods: + +// #### OPTIMIZE +void sc_uint_subref::concat_set(int64 src, int low_i) +{ + sc_uint_base aa( length() ); + *this = aa = (low_i < 64) ? src >> low_i : src >> 63; +} + +void sc_uint_subref::concat_set(const sc_signed& src, int low_i) +{ + sc_uint_base aa( length() ); + if ( low_i < src.length() ) + *this = aa = src >> low_i; + else + *this = aa = (src < 0) ? (int_type)-1 : 0; +} + +void sc_uint_subref::concat_set(const sc_unsigned& src, int low_i) +{ + sc_uint_base aa( length() ); + if ( low_i < src.length() ) + *this = aa = src >> low_i; + else + *this = aa = 0; +} + +void sc_uint_subref::concat_set(uint64 src, int low_i) +{ + sc_uint_base aa( length() ); + *this = aa = (low_i < 64) ? src >> low_i : 0; +} + +// other methods + +void +sc_uint_subref::scan( ::std::istream& is ) +{ + std::string s; + is >> s; + *this = s.c_str(); +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_base +// +// Base class for sc_uint. +// ---------------------------------------------------------------------------- + +// support methods + +void +sc_uint_base::invalid_length() const +{ + char msg[BUFSIZ]; + std::sprintf( msg, + "sc_uint[_base] initialization: length = %d violates " + "1 <= length <= %d", + m_len, SC_INTWIDTH ); + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); +} + +void +sc_uint_base::invalid_index( int i ) const +{ + char msg[BUFSIZ]; + std::sprintf( msg, + "sc_uint[_base] bit selection: index = %d violates " + "0 <= index <= %d", + i, m_len - 1 ); + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); +} + +void +sc_uint_base::invalid_range( int l, int r ) const +{ + char msg[BUFSIZ]; + std::sprintf( msg, + "sc_uint[_base] part selection: left = %d, right = %d violates " + "%d >= left >= right >= 0", + l, r, m_len - 1 ); + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); +} + + +void +sc_uint_base::check_value() const +{ + uint_type limit = (~UINT_ZERO >> m_ulen); + if( m_val > limit ) { + char msg[BUFSIZ]; + std::sprintf( msg, "sc_uint[_base]: value does not fit into a length of %d", + m_len ); + SC_REPORT_WARNING( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); + } +} + + +// constructors + +sc_uint_base::sc_uint_base( const sc_bv_base& v ) + : m_val(0), m_len( v.length() ), m_ulen( SC_INTWIDTH - m_len ) +{ + check_length(); + *this = v; +} +sc_uint_base::sc_uint_base( const sc_lv_base& v ) + : m_val(0), m_len( v.length() ), m_ulen( SC_INTWIDTH - m_len ) +{ + check_length(); + *this = v; +} +sc_uint_base::sc_uint_base( const sc_int_subref_r& v ) + : m_val(0), m_len( v.length() ), m_ulen( SC_INTWIDTH - m_len ) +{ + check_length(); + *this = v.to_uint64(); +} +sc_uint_base::sc_uint_base( const sc_signed_subref_r& v ) + : m_val(0), m_len( v.length() ), m_ulen( SC_INTWIDTH - m_len ) +{ + check_length(); + *this = v.to_uint64(); +} +sc_uint_base::sc_uint_base( const sc_unsigned_subref_r& v ) + : m_val(0), m_len( v.length() ), m_ulen( SC_INTWIDTH - m_len ) +{ + check_length(); + *this = v.to_uint64(); +} + +sc_uint_base::sc_uint_base( const sc_signed& a ) + : m_val( 0 ), m_len( a.length() ), m_ulen( SC_INTWIDTH - m_len ) +{ + check_length(); +#if 0 + for( int i = m_len - 1; i >= 0; -- i ) { + set( i, a.test( i ) ); + } + extend_sign(); +#else + *this = a.to_uint64(); +#endif +} + +sc_uint_base::sc_uint_base( const sc_unsigned& a ) + : m_val( 0 ), m_len( a.length() ), m_ulen( SC_INTWIDTH - m_len ) +{ + check_length(); +#if 0 + for( int i = m_len - 1; i >= 0; -- i ) { + set( i, a.test( i ) ); + } + extend_sign(); +#else + *this = a.to_uint64(); +#endif +} + +// assignment operators + +sc_uint_base& +sc_uint_base::operator = ( const sc_signed& a ) +{ + int minlen = sc_min( m_len, a.length() ); + int i = 0; + for( ; i < minlen; ++ i ) { + set( i, a.test( i ) ); + } + bool sgn = a.sign(); + for( ; i < m_len; ++ i ) { + // sign extension + set( i, sgn ); + } + extend_sign(); + return *this; +} + +sc_uint_base& +sc_uint_base::operator = ( const sc_unsigned& a ) +{ + int minlen = sc_min( m_len, a.length() ); + int i = 0; + for( ; i < minlen; ++ i ) { + set( i, a.test( i ) ); + } + for( ; i < m_len; ++ i ) { + // zero extension + set( i, 0 ); + } + extend_sign(); + return *this; +} + + +sc_uint_base& +sc_uint_base::operator = ( const sc_bv_base& a ) +{ + int minlen = sc_min( m_len, a.length() ); + int i = 0; + for( ; i < minlen; ++ i ) { + set( i, a.get_bit( i ) ); + } + for( ; i < m_len; ++ i ) { + // zero extension + set( i, 0 ); + } + extend_sign(); + return *this; +} + +sc_uint_base& +sc_uint_base::operator = ( const sc_lv_base& a ) +{ + int minlen = sc_min( m_len, a.length() ); + int i = 0; + for( ; i < minlen; ++ i ) { + set( i, sc_logic( a.get_bit( i ) ).to_bool() ); + } + for( ; i < m_len; ++ i ) { + // zero extension + set( i, 0 ); + } + extend_sign(); + return *this; +} + +sc_uint_base& +sc_uint_base::operator = ( const char* a ) +{ + if( a == 0 ) { + SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, + "character string is zero" ); + } + if( *a == 0 ) { + SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, + "character string is empty" ); + } + try { + int len = m_len; + sc_ufix aa( a, len, len, SC_TRN, SC_WRAP, 0, SC_ON ); + return this->operator = ( aa ); + } catch( sc_core::sc_report ) { + char msg[BUFSIZ]; + std::sprintf( msg, "character string '%s' is not valid", a ); + SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg ); + // never reached + return *this; + } +} + + +// explicit conversion to character string + +const std::string +sc_uint_base::to_string( sc_numrep numrep ) const +{ + int len = m_len; + sc_ufix aa( *this, len, len, SC_TRN, SC_WRAP, 0, SC_ON ); + return aa.to_string( numrep ); +} + +const std::string +sc_uint_base::to_string( sc_numrep numrep, bool w_prefix ) const +{ + int len = m_len; + sc_ufix aa( *this, len, len, SC_TRN, SC_WRAP, 0, SC_ON ); + return aa.to_string( numrep, w_prefix ); +} + + +// reduce methods + +bool +sc_uint_base::and_reduce() const +{ + return ( m_val == (~UINT_ZERO >> m_ulen) ); +} + +bool +sc_uint_base::or_reduce() const +{ + return ( m_val != uint_type( 0 ) ); +} + +bool +sc_uint_base::xor_reduce() const +{ + uint_type mask = ~UINT_ZERO; + uint_type val = m_val; + int n = SC_INTWIDTH; + do { + n >>= 1; + mask >>= n; + val = ((val & (mask << n)) >> n) ^ (val & mask); + } while( n != 1 ); + return ( val != uint_type( 0 ) ); +} + + +bool sc_uint_base::concat_get_ctrl( sc_digit* dst_p, int low_i ) const +{ + int dst_i; // Word in dst_p now processing. + int end_i; // Highest order word in dst_p to process. + int left_shift; // Left shift for val. + uint_type mask; // Mask for bits to extract or keep. + + dst_i = low_i / BITS_PER_DIGIT; + left_shift = low_i % BITS_PER_DIGIT; + end_i = (low_i + (m_len-1)) / BITS_PER_DIGIT; + + // PROCESS THE FIRST WORD: + + mask = ~((uint_type)-1 << left_shift); + dst_p[dst_i] = (sc_digit)((dst_p[dst_i] & mask)); + + dst_i++; + for ( ; dst_i <= end_i; dst_i++ ) dst_p[dst_i] = 0; + return false; +} + +//------------------------------------------------------------------------------ +//"sc_uint_base::concat_get_data" +// +// This method transfers the value of this object instance to the supplied +// array of sc_unsigned digits starting with the bit specified by low_i within +// the array of digits. +// +// Notes: +// (1) we don't worry about masking the high order data we transfer since +// concat_get_data() is called from low order bit to high order bit. So +// the bits above where we place ours will be filled in by someone else. +// +// dst_p -> array of sc_unsigned digits to be filled in. +// low_i = first bit within dst_p to be set. +//------------------------------------------------------------------------------ +bool sc_uint_base::concat_get_data( sc_digit* dst_p, int low_i ) const +{ + int dst_i; // Word in dst_p now processing. + int end_i; // Highest order word in dst_p to process. + int high_i; // Index of high order bit in dst_p to set. + int left_shift; // Left shift for val. + uint_type mask; // Mask for bits to extract or keep. + bool result; // True if inserting non-zero value. + uint_type val; // Value for this object. + + dst_i = low_i / BITS_PER_DIGIT; + left_shift = low_i % BITS_PER_DIGIT; + high_i = low_i + (m_len-1); + end_i = high_i / BITS_PER_DIGIT; + val = m_val; + result = val != 0; + + // MASK OFF DATA TO BE TRANSFERRED BASE ON WIDTH: + + if ( m_len < 64 ) + { + mask = ~((uint_type)-1 << m_len); + val &= mask; + } + + // PROCESS THE FIRST WORD: + + mask = ~((uint_type)-1 << left_shift); + dst_p[dst_i] = (sc_digit)(((dst_p[dst_i] & mask)) | + ((val << left_shift) & DIGIT_MASK)); + + switch ( end_i - dst_i ) + { + // BITS ARE ACROSS TWO WORDS: + + case 1: + dst_i++; + val >>= (BITS_PER_DIGIT-left_shift); + dst_p[dst_i] = (sc_digit)val; + break; + + // BITS ARE ACROSS THREE WORDS: + + case 2: + dst_i++; + val >>= (BITS_PER_DIGIT-left_shift); + dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK); + val >>= BITS_PER_DIGIT; + dst_p[dst_i] = (sc_digit)val; + break; + + // BITS ARE ACROSS FOUR WORDS: + + case 3: + dst_i++; + val >>= (BITS_PER_DIGIT-left_shift); + dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK); + val >>= BITS_PER_DIGIT; + dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK); + val >>= BITS_PER_DIGIT; + dst_p[dst_i] = (sc_digit)val; + break; + + } + return result; +} + +// #### OPTIMIZE +void sc_uint_base::concat_set(int64 src, int low_i) +{ + *this = (low_i < 64) ? src >> low_i : src >> 63; +} + +void sc_uint_base::concat_set(const sc_signed& src, int low_i) +{ + if ( low_i < src.length() ) + *this = src >> low_i; + else + *this = (src < 0) ? (int_type)-1 : 0; +} + +void sc_uint_base::concat_set(const sc_unsigned& src, int low_i) +{ + if ( low_i < src.length() ) + *this = src >> low_i; + else + *this = 0; +} + +void sc_uint_base::concat_set(uint64 src, int low_i) +{ + *this = (low_i < 64) ? src >> low_i : 0; +} + + +// other methods + +void +sc_uint_base::scan( ::std::istream& is ) +{ + std::string s; + is >> s; + *this = s.c_str(); +} + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/int/sc_uint_base.h b/ext/systemc/src/sysc/datatypes/int/sc_uint_base.h new file mode 100644 index 000000000..87fd92bc0 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_uint_base.h @@ -0,0 +1,1352 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_uint_base.h -- A sc_uint is an unsigned integer whose length is less than + the machine's native integer length. We provide two + implementations (i) sc_uint with length between 1 - 64, and (ii) + sc_uint with length between 1 - 32. Implementation (i) is the + default implementation, while implementation (ii) can be used + only if compiled with -D_32BIT_. Unlike arbitrary precision, + arithmetic and bitwise operations are performed using the native + types (hence capped at 32/64 bits). The sc_uint integer is + useful when the user does not need arbitrary precision and the + performance is superior to sc_bigint/sc_biguint. + + Original Author: Amit Rao, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc. + Description of Modification: - Resolved ambiguity with sc_(un)signed. + - Merged the code for 64- and 32-bit versions + via the constants in sc_nbdefs.h. + - Eliminated redundant file inclusions. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_uint_base.h,v $ +// Revision 1.3 2011/08/24 22:05:46 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.2 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.4 2006/05/08 17:50:02 acg +// Andy Goodrich: Added David Long's declarations for friend operators, +// functions, and methods, to keep the Microsoft compiler happy. +// +// Revision 1.3 2006/01/13 18:49:32 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef SC_UINT_BASE_H +#define SC_UINT_BASE_H + + +#include "sysc/kernel/sc_object.h" +#include "sysc/datatypes/misc/sc_value_base.h" +#include "sysc/datatypes/int/sc_int_ids.h" +#include "sysc/datatypes/int/sc_length_param.h" +#include "sysc/datatypes/int/sc_nbdefs.h" +#include "sysc/datatypes/fx/scfx_ieee.h" +#include "sysc/utils/sc_iostream.h" +#include "sysc/utils/sc_temporary.h" + + +namespace sc_dt +{ + +class sc_concatref; + +// classes defined in this module +class sc_uint_bitref_r; +class sc_uint_bitref; +class sc_uint_subref_r; +class sc_uint_subref; +class sc_uint_base; + +// forward class declarations +class sc_bv_base; +class sc_lv_base; +class sc_int_subref_r; +class sc_signed_subref_r; +class sc_unsigned_subref_r; +class sc_signed; +class sc_unsigned; +class sc_fxval; +class sc_fxval_fast; +class sc_fxnum; +class sc_fxnum_fast; + + +extern const uint_type mask_int[SC_INTWIDTH][SC_INTWIDTH]; + +// friend operator declarations + inline bool operator == ( const sc_uint_base& a, const sc_uint_base& b ); + inline bool operator != ( const sc_uint_base& a, const sc_uint_base& b ); + inline bool operator < ( const sc_uint_base& a, const sc_uint_base& b ); + inline bool operator <= ( const sc_uint_base& a, const sc_uint_base& b ); + inline bool operator > ( const sc_uint_base& a, const sc_uint_base& b ); + inline bool operator >= ( const sc_uint_base& a, const sc_uint_base& b ); + + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_bitref_r +// +// Proxy class for sc_uint bit selection (r-value only). +// ---------------------------------------------------------------------------- + +class sc_uint_bitref_r : public sc_value_base +{ + friend class sc_uint_base; + friend class sc_uint_signal; + + + // constructors + +public: + sc_uint_bitref_r( const sc_uint_bitref_r& init ) : + sc_value_base(init), m_index(init.m_index), m_obj_p(init.m_obj_p) + {} + +protected: + sc_uint_bitref_r() : sc_value_base(), m_index(0), m_obj_p(0) + {} + + // initializer for sc_core::sc_vpool: + + void initialize( const sc_uint_base* obj_p, int index_ ) + { + m_obj_p = (sc_uint_base*)obj_p; + m_index = index_; + } + +public: + + // destructor + + virtual ~sc_uint_bitref_r() + {} + + // concatenation support + + virtual int concat_length(bool* xz_present_p) const + { if ( xz_present_p ) *xz_present_p = false; return 1; } + virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const + { + int bit_mask = 1 << (low_i % BITS_PER_DIGIT); + int word_i = low_i / BITS_PER_DIGIT; + + dst_p[word_i] &= ~bit_mask; + return false; + } + virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const + { + int bit_mask = 1 << (low_i % BITS_PER_DIGIT); + bool result; // True is non-zero. + int word_i = low_i / BITS_PER_DIGIT; + + if ( operator uint64() ) + { + dst_p[word_i] |= bit_mask; + result = true; + } + else + { + dst_p[word_i] &= ~bit_mask; + result = false; + } + return result; + } + virtual uint64 concat_get_uint64() const + { return operator uint64(); } + + // capacity + + int length() const + { return 1; } + +#ifdef SC_DT_DEPRECATED + int bitwidth() const + { return length(); } +#endif + + + // implicit conversion to uint64 + + operator uint64 () const; + bool operator ! () const; + bool operator ~ () const; + + + // explicit conversions + + uint64 value() const + { return operator uint64 (); } + + bool to_bool() const + { return operator uint64 (); } + + + // other methods + + void print( ::std::ostream& os = ::std::cout ) const + { os << to_bool(); } + +protected: + + int m_index; + sc_uint_base* m_obj_p; + +private: + + // disabled + sc_uint_bitref_r& operator = ( const sc_uint_bitref_r& ); +}; + + + +inline +::std::ostream& +operator << ( ::std::ostream&, const sc_uint_bitref_r& ); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_bitref +// +// Proxy class for sc_uint bit selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +class sc_uint_bitref + : public sc_uint_bitref_r +{ + friend class sc_uint_base; + friend class sc_core::sc_vpool<sc_uint_bitref>; + + + // constructors + +protected: + sc_uint_bitref() : sc_uint_bitref_r() + {} +public: + sc_uint_bitref( const sc_uint_bitref& init ) : sc_uint_bitref_r(init) + {} + +public: + + // assignment operators + + sc_uint_bitref& operator = ( const sc_uint_bitref_r& b ); + sc_uint_bitref& operator = ( const sc_uint_bitref& b ); + sc_uint_bitref& operator = ( bool b ); + + sc_uint_bitref& operator &= ( bool b ); + sc_uint_bitref& operator |= ( bool b ); + sc_uint_bitref& operator ^= ( bool b ); + + // concatenation methods + + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed& src, int low_i); + virtual void concat_set(const sc_unsigned& src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + // other methods + + void scan( ::std::istream& is = ::std::cin ); + +protected: + static sc_core::sc_vpool<sc_uint_bitref> m_pool; + +}; + + + +inline +::std::istream& +operator >> ( ::std::istream&, sc_uint_bitref& ); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_subref_r +// +// Proxy class for sc_uint part selection (r-value only). +// ---------------------------------------------------------------------------- + +class sc_uint_subref_r : public sc_value_base +{ + friend class sc_uint_base; + friend class sc_uint_subref; + + + // constructors + +public: + sc_uint_subref_r( const sc_uint_subref_r& init ) : + sc_value_base(init), m_left(init.m_left), m_obj_p(init.m_obj_p), + m_right(init.m_right) + {} + +protected: + sc_uint_subref_r() : sc_value_base(), m_left(0), m_obj_p(0), m_right(0) + {} + + // initializer for sc_core::sc_vpool: + + void initialize( const sc_uint_base* obj_p, int left_i, int right_i ) + { + m_obj_p = (sc_uint_base*)obj_p; + m_left = left_i; + m_right = right_i; + } + +public: + + // destructor + + virtual ~sc_uint_subref_r() + {} + + // capacity + + int length() const + { return ( m_left - m_right + 1 ); } + +#ifdef SC_DT_DEPRECATED + int bitwidth() const + { return length(); } +#endif + + // concatenation support + + virtual int concat_length(bool* xz_present_p) const + { if ( xz_present_p ) *xz_present_p = false; return length(); } + virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const; + virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const; + virtual uint64 concat_get_uint64() const + { return (uint64)operator uint_type(); } + + + // reduce methods + + bool and_reduce() const; + + bool nand_reduce() const + { return ( ! and_reduce() ); } + + bool or_reduce() const; + + bool nor_reduce() const + { return ( ! or_reduce() ); } + + bool xor_reduce() const; + + bool xnor_reduce() const + { return ( ! xor_reduce() ); } + + + // implicit conversion to uint_type + + operator uint_type() const; + + + // explicit conversions + + uint_type value() const + { return operator uint_type(); } + + + int to_int() const; + unsigned int to_uint() const; + long to_long() const; + unsigned long to_ulong() const; + int64 to_int64() const; + uint64 to_uint64() const; + double to_double() const; + + + // explicit conversion to character string + + const std::string to_string( sc_numrep numrep = SC_DEC ) const; + const std::string to_string( sc_numrep numrep, bool w_prefix ) const; + + + // other methods + + void print( ::std::ostream& os = ::std::cout ) const + { os << to_string(sc_io_base(os,SC_DEC),sc_io_show_base(os)); } + +protected: + + int m_left; + sc_uint_base* m_obj_p; + int m_right; + +private: + + // disabled + sc_uint_subref_r& operator = ( const sc_uint_subref_r& ); +}; + + + +inline +::std::ostream& +operator << ( ::std::ostream&, const sc_uint_subref_r& ); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_subref +// +// Proxy class for sc_uint part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +class sc_uint_subref + : public sc_uint_subref_r +{ + friend class sc_uint_base; + friend class sc_core::sc_vpool<sc_uint_subref>; + + + // constructors + +protected: + sc_uint_subref() : sc_uint_subref_r() + {} + +public: + sc_uint_subref( const sc_uint_subref& init ) : sc_uint_subref_r(init) + {} + +public: + + // assignment operators + + sc_uint_subref& operator = ( uint_type v ); + + sc_uint_subref& operator = ( const sc_uint_base& a ); + + sc_uint_subref& operator = ( const sc_uint_subref_r& a ) + { return operator = ( a.operator uint_type() ); } + + sc_uint_subref& operator = ( const sc_uint_subref& a ) + { return operator = ( a.operator uint_type() ); } + + template<class T> + sc_uint_subref& operator = ( const sc_generic_base<T>& a ) + { return operator = ( a->to_uint64() ); } + + sc_uint_subref& operator = ( const char* a ); + + sc_uint_subref& operator = ( unsigned long a ) + { return operator = ( (uint_type) a ); } + + sc_uint_subref& operator = ( long a ) + { return operator = ( (uint_type) a ); } + + sc_uint_subref& operator = ( unsigned int a ) + { return operator = ( (uint_type) a ); } + + sc_uint_subref& operator = ( int a ) + { return operator = ( (uint_type) a ); } + + sc_uint_subref& operator = ( int64 a ) + { return operator = ( (uint_type) a ); } + + sc_uint_subref& operator = ( double a ) + { return operator = ( (uint_type) a ); } + + sc_uint_subref& operator = ( const sc_signed& ); + sc_uint_subref& operator = ( const sc_unsigned& ); + sc_uint_subref& operator = ( const sc_bv_base& ); + sc_uint_subref& operator = ( const sc_lv_base& ); + + // concatenation methods + + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed& src, int low_i); + virtual void concat_set(const sc_unsigned& src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + // other methods + + void scan( ::std::istream& is = ::std::cin ); + +protected: + static sc_core::sc_vpool<sc_uint_subref> m_pool; + +}; + + + +inline +::std::istream& +operator >> ( ::std::istream&, sc_uint_subref& ); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_base +// +// Base class for sc_uint. +// ---------------------------------------------------------------------------- + +class sc_uint_base : public sc_value_base +{ + friend class sc_uint_bitref_r; + friend class sc_uint_bitref; + friend class sc_uint_subref_r; + friend class sc_uint_subref; + + + // support methods + + void invalid_length() const; + void invalid_index( int i ) const; + void invalid_range( int l, int r ) const; + + void check_length() const + { if( m_len <= 0 || m_len > SC_INTWIDTH ) { invalid_length(); } } + + void check_index( int i ) const + { if( i < 0 || i >= m_len ) { invalid_index( i ); } } + + void check_range( int l, int r ) const + { if( r < 0 || l >= m_len || l < r ) { invalid_range( l, r ); } } + + void check_value() const; + + void extend_sign() + { +#ifdef DEBUG_SYSTEMC + check_value(); +#endif + m_val &= ( ~UINT_ZERO >> m_ulen ); + } + +public: + + // constructors + + explicit sc_uint_base( int w = sc_length_param().len() ) + : m_val( 0 ), m_len( w ), m_ulen( SC_INTWIDTH - m_len ) + { check_length(); } + + sc_uint_base( uint_type v, int w ) + : m_val( v ), m_len( w ), m_ulen( SC_INTWIDTH - m_len ) + { check_length(); extend_sign(); } + + sc_uint_base( const sc_uint_base& a ) + : sc_value_base(a), m_val(a.m_val), m_len(a.m_len), m_ulen(a.m_ulen) + {} + + explicit sc_uint_base( const sc_uint_subref_r& a ) + : m_val( a ), m_len( a.length() ), m_ulen( SC_INTWIDTH - m_len ) + { extend_sign(); } + + template<class T> + explicit sc_uint_base( const sc_generic_base<T>& a ) + : m_val( a->to_uint64() ), m_len( a->length() ), + m_ulen( SC_INTWIDTH - m_len ) + { check_length(); extend_sign(); } + + explicit sc_uint_base( const sc_bv_base& v ); + explicit sc_uint_base( const sc_lv_base& v ); + explicit sc_uint_base( const sc_int_subref_r& v ); + explicit sc_uint_base( const sc_signed_subref_r& v ); + explicit sc_uint_base( const sc_unsigned_subref_r& v ); + explicit sc_uint_base( const sc_signed& a ); + explicit sc_uint_base( const sc_unsigned& a ); + + + // destructor + + virtual ~sc_uint_base() + {} + + + // assignment operators + + sc_uint_base& operator = ( uint_type v ) + { m_val = v; extend_sign(); return *this; } + + sc_uint_base& operator = ( const sc_uint_base& a ) + { m_val = a.m_val; extend_sign(); return *this; } + + sc_uint_base& operator = ( const sc_uint_subref_r& a ) + { m_val = a; extend_sign(); return *this; } + + template<class T> + sc_uint_base& operator = ( const sc_generic_base<T>& a ) + { m_val = a->to_uint64(); extend_sign(); return *this; } + + sc_uint_base& operator = ( const sc_signed& a ); + sc_uint_base& operator = ( const sc_unsigned& a ); + +#ifdef SC_INCLUDE_FX + sc_uint_base& operator = ( const sc_fxval& a ); + sc_uint_base& operator = ( const sc_fxval_fast& a ); + sc_uint_base& operator = ( const sc_fxnum& a ); + sc_uint_base& operator = ( const sc_fxnum_fast& a ); +#endif + + sc_uint_base& operator = ( const sc_bv_base& a ); + sc_uint_base& operator = ( const sc_lv_base& a ); + + sc_uint_base& operator = ( const char* a ); + + sc_uint_base& operator = ( unsigned long a ) + { m_val = a; extend_sign(); return *this; } + + sc_uint_base& operator = ( long a ) + { m_val = a; extend_sign(); return *this; } + + sc_uint_base& operator = ( unsigned int a ) + { m_val = a; extend_sign(); return *this; } + + sc_uint_base& operator = ( int a ) + { m_val = a; extend_sign(); return *this; } + + sc_uint_base& operator = ( int64 a ) + { m_val = a; extend_sign(); return *this; } + + sc_uint_base& operator = ( double a ) + { m_val = (uint_type) a; extend_sign(); return *this; } + + + // arithmetic assignment operators + + sc_uint_base& operator += ( uint_type v ) + { m_val += v; extend_sign(); return *this; } + + sc_uint_base& operator -= ( uint_type v ) + { m_val -= v; extend_sign(); return *this; } + + sc_uint_base& operator *= ( uint_type v ) + { m_val *= v; extend_sign(); return *this; } + + sc_uint_base& operator /= ( uint_type v ) + { m_val /= v; extend_sign(); return *this; } + + sc_uint_base& operator %= ( uint_type v ) + { m_val %= v; extend_sign(); return *this; } + + + // bitwise assignment operators + + sc_uint_base& operator &= ( uint_type v ) + { m_val &= v; extend_sign(); return *this; } + + sc_uint_base& operator |= ( uint_type v ) + { m_val |= v; extend_sign(); return *this; } + + sc_uint_base& operator ^= ( uint_type v ) + { m_val ^= v; extend_sign(); return *this; } + + + sc_uint_base& operator <<= ( uint_type v ) + { m_val <<= v; extend_sign(); return *this; } + + sc_uint_base& operator >>= ( uint_type v ) + { m_val >>= v; /* no sign extension needed */ return *this; } + + + // prefix and postfix increment and decrement operators + + sc_uint_base& operator ++ () // prefix + { ++ m_val; extend_sign(); return *this; } + + const sc_uint_base operator ++ ( int ) // postfix + { sc_uint_base tmp( *this ); ++ m_val; extend_sign(); return tmp; } + + sc_uint_base& operator -- () // prefix + { -- m_val; extend_sign(); return *this; } + + const sc_uint_base operator -- ( int ) // postfix + { sc_uint_base tmp( *this ); -- m_val; extend_sign(); return tmp; } + + + // relational operators + + friend bool operator == ( const sc_uint_base& a, const sc_uint_base& b ) + { return a.m_val == b.m_val; } + + friend bool operator != ( const sc_uint_base& a, const sc_uint_base& b ) + { return a.m_val != b.m_val; } + + friend bool operator < ( const sc_uint_base& a, const sc_uint_base& b ) + { return a.m_val < b.m_val; } + + friend bool operator <= ( const sc_uint_base& a, const sc_uint_base& b ) + { return a.m_val <= b.m_val; } + + friend bool operator > ( const sc_uint_base& a, const sc_uint_base& b ) + { return a.m_val > b.m_val; } + + friend bool operator >= ( const sc_uint_base& a, const sc_uint_base& b ) + { return a.m_val >= b.m_val; } + + + // bit selection + + sc_uint_bitref& operator [] ( int i ); + const sc_uint_bitref_r& operator [] ( int i ) const; + + sc_uint_bitref& bit( int i ); + const sc_uint_bitref_r& bit( int i ) const; + + + // part selection + + sc_uint_subref& operator () ( int left, int right ); + const sc_uint_subref_r& operator () ( int left, int right ) const; + + sc_uint_subref& range( int left, int right ); + const sc_uint_subref_r& range( int left, int right ) const; + + + // bit access, without bounds checking or sign extension + + bool test( int i ) const + { return ( 0 != (m_val & (UINT_ONE << i)) ); } + + void set( int i ) + { m_val |= (UINT_ONE << i); } + + void set( int i, bool v ) + { v ? m_val |= (UINT_ONE << i) : m_val &= ~(UINT_ONE << i); } + + + // capacity + + int length() const + { return m_len; } + +#ifdef SC_DT_DEPRECATED + int bitwidth() const + { return length(); } +#endif + + // concatenation support + + virtual int concat_length(bool* xz_present_p) const + { if ( xz_present_p ) *xz_present_p = false; return length(); } + virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const; + virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const; + virtual uint64 concat_get_uint64() const + { return m_val; } + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed& src, int low_i); + virtual void concat_set(const sc_unsigned& src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + + // reduce methods + + bool and_reduce() const; + + bool nand_reduce() const + { return ( ! and_reduce() ); } + + bool or_reduce() const; + + bool nor_reduce() const + { return ( ! or_reduce() ); } + + bool xor_reduce() const; + + bool xnor_reduce() const + { return ( ! xor_reduce() ); } + + + // implicit conversion to uint_type + + operator uint_type() const + { return m_val; } + + + // explicit conversions + + uint_type value() const + { return operator uint_type(); } + + + int to_int() const + { return (int) m_val; } + + unsigned int to_uint() const + { return (unsigned int) m_val; } + + long to_long() const + { return (long) m_val; } + + unsigned long to_ulong() const + { return (unsigned long) m_val; } + + int64 to_int64() const + { return (int64) m_val; } + + uint64 to_uint64() const + { return (uint64) m_val; } + + double to_double() const + { return uint64_to_double( m_val ); } + + +#ifndef _32BIT_ + long long_low() const + { return (long) (m_val & UINT64_32ONES); } + + long long_high() const + { return (long) ((m_val >> 32) & UINT64_32ONES); } +#endif + + // explicit conversion to character string + + const std::string to_string( sc_numrep numrep = SC_DEC ) const; + const std::string to_string( sc_numrep numrep, bool w_prefix ) const; + + + // other methods + + void print( ::std::ostream& os = ::std::cout ) const + { os << to_string(sc_io_base(os,SC_DEC),sc_io_show_base(os)); } + + void scan( ::std::istream& is = ::std::cin ); + +protected: + + uint_type m_val; // value + int m_len; // length + int m_ulen; // unused length +}; + + + +inline +::std::ostream& +operator << ( ::std::ostream&, const sc_uint_base& ); + +inline +::std::istream& +operator >> ( ::std::istream&, sc_uint_base& ); + + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_bitref_r +// +// Proxy class for sc_uint bit selection (r-value only). +// ---------------------------------------------------------------------------- + +// implicit conversion to bool + +inline +sc_uint_bitref_r::operator uint64 () const +{ + return m_obj_p->test( m_index ); +} + +inline +bool +sc_uint_bitref_r::operator ! () const +{ + return ! m_obj_p->test( m_index ); +} + +inline +bool +sc_uint_bitref_r::operator ~ () const +{ + return ! m_obj_p->test( m_index ); +} + + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_uint_bitref_r& a ) +{ + a.print( os ); + return os; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_bitref +// +// Proxy class for sc_uint bit selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +// assignment operators + +inline +sc_uint_bitref& +sc_uint_bitref::operator = ( const sc_uint_bitref_r& b ) +{ + m_obj_p->set( m_index, b.to_bool() ); + return *this; +} + +inline +sc_uint_bitref& +sc_uint_bitref::operator = ( const sc_uint_bitref& b ) +{ + m_obj_p->set( m_index, b.to_bool() ); + return *this; +} + +inline +sc_uint_bitref& +sc_uint_bitref::operator = ( bool b ) +{ + m_obj_p->set( m_index, b ); + return *this; +} + + +inline +sc_uint_bitref& +sc_uint_bitref::operator &= ( bool b ) +{ + if( ! b ) { + m_obj_p->set( m_index, b ); + } + return *this; +} + +inline +sc_uint_bitref& +sc_uint_bitref::operator |= ( bool b ) +{ + if( b ) { + m_obj_p->set( m_index, b ); + } + return *this; +} + +inline +sc_uint_bitref& +sc_uint_bitref::operator ^= ( bool b ) +{ + if( b ) { + m_obj_p->m_val ^= (UINT_ONE << m_index); + } + return *this; +} + + + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_uint_bitref& a ) +{ + a.scan( is ); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_subref_r +// +// Proxy class for sc_uint part selection (r-value only). +// ---------------------------------------------------------------------------- + +// implicit conversion to uint_type + +inline +sc_uint_subref_r::operator uint_type() const +{ + uint_type val = m_obj_p->m_val; + int uleft = SC_INTWIDTH - (m_left + 1); + return ( (val & (~UINT_ZERO >> uleft)) >> m_right ); +} + + +// reduce methods + +inline +bool +sc_uint_subref_r::and_reduce() const +{ + sc_uint_base a( *this ); + return a.and_reduce(); +} + +inline +bool +sc_uint_subref_r::or_reduce() const +{ + sc_uint_base a( *this ); + return a.or_reduce(); +} + +inline +bool +sc_uint_subref_r::xor_reduce() const +{ + sc_uint_base a( *this ); + return a.xor_reduce(); +} + + +// explicit conversions + +inline +int +sc_uint_subref_r::to_int() const +{ + sc_uint_base a( *this ); + return a.to_int(); +} + +inline +unsigned int +sc_uint_subref_r::to_uint() const +{ + sc_uint_base a( *this ); + return a.to_uint(); +} + +inline +long +sc_uint_subref_r::to_long() const +{ + sc_uint_base a( *this ); + return a.to_long(); +} + +inline +unsigned long +sc_uint_subref_r::to_ulong() const +{ + sc_uint_base a( *this ); + return a.to_ulong(); +} + +inline +int64 +sc_uint_subref_r::to_int64() const +{ + sc_uint_base a( *this ); + return a.to_int64(); +} + +inline +uint64 +sc_uint_subref_r::to_uint64() const +{ + sc_uint_base a( *this ); + return a.to_uint64(); +} + +inline +double +sc_uint_subref_r::to_double() const +{ + sc_uint_base a( *this ); + return a.to_double(); +} + + +// explicit conversion to character string + +inline +const std::string +sc_uint_subref_r::to_string( sc_numrep numrep ) const +{ + sc_uint_base a( *this ); + return a.to_string( numrep ); +} + +inline +const std::string +sc_uint_subref_r::to_string( sc_numrep numrep, bool w_prefix ) const +{ + sc_uint_base a( *this ); + return a.to_string( numrep, w_prefix ); +} + + +// functional notation for the reduce methods + +inline +bool +and_reduce( const sc_uint_subref_r& a ) +{ + return a.and_reduce(); +} + +inline +bool +nand_reduce( const sc_uint_subref_r& a ) +{ + return a.nand_reduce(); +} + +inline +bool +or_reduce( const sc_uint_subref_r& a ) +{ + return a.or_reduce(); +} + +inline +bool +nor_reduce( const sc_uint_subref_r& a ) +{ + return a.nor_reduce(); +} + +inline +bool +xor_reduce( const sc_uint_subref_r& a ) +{ + return a.xor_reduce(); +} + +inline +bool +xnor_reduce( const sc_uint_subref_r& a ) +{ + return a.xnor_reduce(); +} + + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_uint_subref_r& a ) +{ + a.print( os ); + return os; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_subref +// +// Proxy class for sc_uint part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +// assignment operators + +inline +sc_uint_subref& +sc_uint_subref::operator = ( const sc_uint_base& a ) +{ + return operator = ( a.operator uint_type() ); +} + +inline +sc_uint_subref& +sc_uint_subref::operator = ( const char* a ) +{ + sc_uint_base aa( length() ); + return ( *this = aa = a ); +} + + + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_uint_subref& a ) +{ + a.scan( is ); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_base +// +// Base class for sc_uint. +// ---------------------------------------------------------------------------- + +// bit selection + +inline +sc_uint_bitref& +sc_uint_base::operator [] ( int i ) +{ + check_index( i ); + sc_uint_bitref* result_p = sc_uint_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; +} + +inline +const sc_uint_bitref_r& +sc_uint_base::operator [] ( int i ) const +{ + check_index( i ); + sc_uint_bitref* result_p = sc_uint_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; +} + + +inline +sc_uint_bitref& +sc_uint_base::bit( int i ) +{ + check_index( i ); + sc_uint_bitref* result_p = sc_uint_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; +} + +inline +const sc_uint_bitref_r& +sc_uint_base::bit( int i ) const +{ + check_index( i ); + sc_uint_bitref* result_p = sc_uint_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; +} + + +// part selection + +inline +sc_uint_subref& +sc_uint_base::operator () ( int left, int right ) +{ + check_range( left, right ); + sc_uint_subref* result_p = sc_uint_subref::m_pool.allocate(); + result_p->initialize(this, left, right); + return *result_p; +} + +inline +const sc_uint_subref_r& +sc_uint_base::operator () ( int left, int right ) const +{ + check_range( left, right ); + sc_uint_subref* result_p = sc_uint_subref::m_pool.allocate(); + result_p->initialize(this, left, right); + return *result_p; +} + + +inline +sc_uint_subref& +sc_uint_base::range( int left, int right ) +{ + check_range( left, right ); + sc_uint_subref* result_p = sc_uint_subref::m_pool.allocate(); + result_p->initialize(this, left, right); + return *result_p; +} + +inline +const sc_uint_subref_r& +sc_uint_base::range( int left, int right ) const +{ + check_range( left, right ); + sc_uint_subref* result_p = sc_uint_subref::m_pool.allocate(); + result_p->initialize(this, left, right); + return *result_p; +} + + +// functional notation for the reduce methods + +inline +bool +and_reduce( const sc_uint_base& a ) +{ + return a.and_reduce(); +} + +inline +bool +nand_reduce( const sc_uint_base& a ) +{ + return a.nand_reduce(); +} + +inline +bool +or_reduce( const sc_uint_base& a ) +{ + return a.or_reduce(); +} + +inline +bool +nor_reduce( const sc_uint_base& a ) +{ + return a.nor_reduce(); +} + +inline +bool +xor_reduce( const sc_uint_base& a ) +{ + return a.xor_reduce(); +} + +inline +bool +xnor_reduce( const sc_uint_base& a ) +{ + return a.xnor_reduce(); +} + + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_uint_base& a ) +{ + a.print( os ); + return os; +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_uint_base& a ) +{ + a.scan( is ); + return is; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/int/sc_unsigned.cpp b/ext/systemc/src/sysc/datatypes/int/sc_unsigned.cpp new file mode 100644 index 000000000..75af69deb --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_unsigned.cpp @@ -0,0 +1,2240 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_unsigned.cpp -- Arbitrary precision signed arithmetic. + + This file includes the definitions of sc_unsigned_bitref, + sc_unsigned_subref, and sc_unsigned classes. The first two classes + are proxy classes to reference one bit and a range of bits of a + sc_unsigned number, respectively. This file also includes + sc_nbcommon.cpp and sc_nbfriends.cpp, which contain the + definitions shared by sc_unsigned. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_unsigned.cpp,v $ +// Revision 1.7 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.6 2008/12/10 20:38:45 acg +// Andy Goodrich: fixed conversion of double values to the digits vector. +// The bits above the radix were not being masked off. +// +// Revision 1.5 2008/06/19 17:47:57 acg +// Andy Goodrich: fixes for bugs. See 2.2.1 RELEASENOTES. +// +// Revision 1.4 2008/06/19 16:57:57 acg +// Andy Goodrich: added case for negative unsigned values to the support in +// concate_get_data(). +// +// Revision 1.3 2007/11/04 21:27:00 acg +// Andy Goodrich: changes to make sure the proper value is returned from +// concat_get_data(). +// +// Revision 1.2 2007/02/22 21:35:05 acg +// Andy Goodrich: cleaned up comments in concat_get_ctrl and concat_get_data. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.4 2006/08/29 23:36:54 acg +// Andy Goodrich: fixed and_reduce and optimized or_reduce. +// +// Revision 1.3 2006/01/13 18:49:32 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#include <ctype.h> +#include <math.h> + +#include "sysc/kernel/sc_cmnhdr.h" +#include "sysc/kernel/sc_macros.h" +#include "sysc/datatypes/int/sc_unsigned.h" +#include "sysc/datatypes/int/sc_signed.h" +#include "sysc/datatypes/int/sc_int_base.h" +#include "sysc/datatypes/int/sc_uint_base.h" +#include "sysc/datatypes/int/sc_int_ids.h" +#include "sysc/datatypes/bit/sc_bv_base.h" +#include "sysc/datatypes/bit/sc_lv_base.h" +#include "sysc/datatypes/misc/sc_concatref.h" +#include "sysc/datatypes/fx/sc_ufix.h" +#include "sysc/datatypes/fx/scfx_other_defs.h" + +namespace sc_dt +{ + +// Pool of temporary instances: +// The sc_unsigned pool is used by the concatenation support. +// The bit and part reference pools allow references to be returned. + +sc_core::sc_vpool<sc_unsigned> sc_unsigned::m_pool(8); +sc_core::sc_vpool<sc_unsigned_bitref> sc_unsigned_bitref::m_pool(9); +sc_core::sc_vpool<sc_unsigned_subref> sc_unsigned_subref::m_pool(9); + +// ----------------------------------------------------------------------------- +// SECTION: Public members - Invalid selections. +// ----------------------------------------------------------------------------- + +void +sc_unsigned::invalid_index( int i ) const +{ + char msg[BUFSIZ]; + std::sprintf( msg, + "sc_biguint bit selection: index = %d violates " + "0 <= index <= %d", + i, nbits - 2 ); + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); +} + +void +sc_unsigned::invalid_range( int l, int r ) const +{ + char msg[BUFSIZ]; + std::sprintf( msg, + "sc_biguint part selection: left = %d, right = %d \n" + " violates either (%d >= left >= 0) or (%d >= right >= 0)", + l, r, nbits-2, nbits-2 ); + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); +} + +// ---------------------------------------------------------------------------- +// SECTION: Public members - Concatenation support. +// ---------------------------------------------------------------------------- + +// Most public members are included from sc_nbcommon.inc. However, some +// concatenation support appears here to optimize between the signed and +// unsigned cases. + + + +// Insert this object's value at the specified place in a vector of big style +// values. + +bool sc_unsigned::concat_get_ctrl( sc_digit* dst_p, int low_i ) const +{ + int dst_i; // Index to next word to set in dst_p. + int end_i; // Index of high order word to set. + int left_shift; // Amount to shift value left. + sc_digit mask; // Mask for partial word sets. + + + // CALCULATE METRICS FOR DATA MOVEMENT: + + dst_i = low_i / BITS_PER_DIGIT; + end_i = (low_i + nbits - 2) / BITS_PER_DIGIT; + left_shift = low_i % BITS_PER_DIGIT; + + + // MOVE FIRST WORD (IT MAY BE PARTIAL) AND THEN ANY OTHERS: + // + // We may "clobber" upper bits, but they will be written at some point + // anyway. + + mask = ~(-1 << left_shift); + dst_p[dst_i] = ( dst_p[dst_i] & ~mask ); + dst_i++; + + for ( ; dst_i <= end_i; dst_i++ ) dst_p[dst_i] = 0; + + return false; +} + +bool sc_unsigned::concat_get_data( sc_digit* dst_p, int low_i ) const +{ + sc_digit carry; // Carry for negating value. + int dst_i; // Index to next word to set in dst_p. + int end_i; // Index of high order word to set. + int high_i; // Index w/in word of high order bit. + int left_shift; // Amount to shift value left. + sc_digit left_word; // High word component for set. + sc_digit mask; // Mask for partial word sets. + bool result; // True if inserting non-zero data. + int right_shift; // Amount to shift value right. + sc_digit right_word; // Low word component for set. + int real_bits; // nbits - 1. + int src_i; // Index to next word to get from digit. + + + // CALCULATE METRICS FOR DATA MOVEMENT: + + real_bits = nbits - 1; // Remove that extra sign bit. + dst_i = low_i / BITS_PER_DIGIT; + high_i = low_i + real_bits - 1; + end_i = high_i / BITS_PER_DIGIT; + left_shift = low_i % BITS_PER_DIGIT; + + + switch ( sgn ) + { + + // POSITIVE SOURCE VALUE: + + case SC_POS: + result = true; + + // ALL DATA TO BE MOVED IS IN A SINGLE WORD: + + if ( dst_i == end_i ) + { + mask = ~(-1 << left_shift); + dst_p[dst_i] = ( ( dst_p[dst_i] & mask ) | + (digit[0] << left_shift) ) & DIGIT_MASK; + } + + + // DATA IS IN MORE THAN ONE WORD, BUT IS WORD ALIGNED: + + else if ( left_shift == 0 ) + { + for ( src_i = 0; dst_i < end_i; dst_i++, src_i++ ) + { + dst_p[dst_i] = digit[src_i]; + } + high_i = high_i % BITS_PER_DIGIT; + mask = ~(-2 << high_i) & DIGIT_MASK; + dst_p[dst_i] = digit[src_i] & mask; + } + + + // DATA IS IN MORE THAN ONE WORD, AND NOT WORD ALIGNED: + + else + { + high_i = high_i % BITS_PER_DIGIT; + right_shift = BITS_PER_DIGIT - left_shift; + mask = ~(-1 << left_shift); + right_word = digit[0]; + dst_p[dst_i] = (dst_p[dst_i] & mask) | + ((right_word << left_shift) & DIGIT_MASK); + for ( src_i = 1, dst_i++; dst_i < end_i; dst_i++, src_i++ ) + { + left_word = digit[src_i]; + dst_p[dst_i] = ((left_word << left_shift)&DIGIT_MASK) | + (right_word >> right_shift); + right_word = left_word; + } + left_word = (src_i < ndigits) ? digit[src_i] : 0; + mask = ~(-2 << high_i) & DIGIT_MASK; + dst_p[dst_i] = ((left_word << left_shift) | + (right_word >> right_shift)) & mask; + } + break; + + // SOURCE VALUE IS NEGATIVE: + + case SC_NEG: + + // ALL DATA TO BE MOVED IS IN A SINGLE WORD: + + result = true; + if ( dst_i == end_i ) + { + mask = ~(-1 << nbits); + right_word = ((digit[0] ^ DIGIT_MASK) + 1) & mask; + mask = ~(-1 << left_shift); + dst_p[dst_i] = ( ( dst_p[dst_i] & mask ) | + (right_word << left_shift) ) & DIGIT_MASK; + } + + + // DATA IS IN MORE THAN ONE WORD, BUT IS WORD ALIGNED: + + else if ( left_shift == 0 ) + { + carry = 1; + for ( src_i = 0; dst_i < end_i; dst_i++, src_i++ ) + { + right_word = (digit[src_i] ^ DIGIT_MASK) + carry; + dst_p[dst_i] = right_word & DIGIT_MASK; + carry = right_word >> BITS_PER_DIGIT; + } + high_i = high_i % BITS_PER_DIGIT; + mask = (~(-2 << high_i)) & DIGIT_MASK; + right_word = (src_i < ndigits) ? + (digit[src_i] ^ DIGIT_MASK) + carry : DIGIT_MASK + carry; + dst_p[dst_i] = right_word & mask; + } + + + // DATA IS IN MORE THAN ONE WORD, AND NOT WORD ALIGNED: + + else + { + high_i = high_i % BITS_PER_DIGIT; + right_shift = BITS_PER_DIGIT - left_shift; + mask = ~(-1 << left_shift); + carry = 1; + right_word = (digit[0] ^ DIGIT_MASK) + carry; + dst_p[dst_i] = (dst_p[dst_i] & mask) | + ((right_word << left_shift) & DIGIT_MASK); + carry = right_word >> BITS_PER_DIGIT; + right_word &= DIGIT_MASK; + for ( src_i = 1, dst_i++; dst_i < end_i; dst_i++, src_i++ ) + { + left_word = (digit[src_i] ^ DIGIT_MASK) + carry; + dst_p[dst_i] = ((left_word << left_shift)&DIGIT_MASK) | + (right_word >> right_shift); + carry = left_word >> BITS_PER_DIGIT; + right_word = left_word & DIGIT_MASK; + } + left_word = (src_i < ndigits) ? + (digit[src_i] ^ DIGIT_MASK) + carry : carry; + mask = ~(-2 << high_i) & DIGIT_MASK; + dst_p[dst_i] = ((left_word << left_shift) | + (right_word >> right_shift)) & mask; + } + break; + + + // VALUE IS ZERO: + + default: + result = false; + + // ALL DATA TO BE MOVED IS IN A SINGLE WORD: + + if ( dst_i == end_i ) + { + mask = ~(-1 << real_bits) << left_shift; + dst_p[dst_i] = dst_p[dst_i] & ~mask; + } + + + // DATA IS IN MORE THAN ONE WORD, BUT IS WORD ALIGNED: + + else if ( left_shift == 0 ) + { + for ( src_i = 0; dst_i < end_i; dst_i++, src_i++ ) + { + dst_p[dst_i] = 0; + } + high_i = high_i % BITS_PER_DIGIT; + mask = ~(-2 << high_i) & DIGIT_MASK; + dst_p[dst_i] = 0; + } + + + // DATA IS IN MORE THAN ONE WORD, AND NOT WORD ALIGNED: + + else + { + high_i = high_i % BITS_PER_DIGIT; + right_shift = BITS_PER_DIGIT - left_shift; + mask = ~(-1 << left_shift); + dst_p[dst_i] = (dst_p[dst_i] & mask); + for ( dst_i++; dst_i <= end_i; dst_i++ ) + { + dst_p[dst_i] = 0; + } + } + break; + } + return result; +} + +// Return this object instance's bits as a uint64 without sign extension. + +uint64 sc_unsigned::concat_get_uint64() const +{ + uint64 result; + + switch ( sgn ) + { + case SC_POS: + result = 0; + if ( ndigits > 2 ) + result = digit[2]; + if ( ndigits > 1 ) + result = (result << BITS_PER_DIGIT) | digit[1]; + result = (result << BITS_PER_DIGIT) | digit[0]; + break; + default: + result = 0; + break; + } + return result; +} + +// #### OPTIMIZE +void sc_unsigned::concat_set(int64 src, int low_i) +{ + *this = (low_i < 64) ? src >> low_i : src >> 63; +} + +void sc_unsigned::concat_set(const sc_signed& src, int low_i) +{ + if ( low_i < src.length() ) + *this = src >> low_i; + else + *this = (src<0) ? (int_type)-1 : 0; +} + +void sc_unsigned::concat_set(const sc_unsigned& src, int low_i) +{ + if ( low_i < src.length() ) + *this = src >> low_i; + else + *this = 0; +} + +void sc_unsigned::concat_set(uint64 src, int low_i) +{ + *this = (low_i < 64) ? src >> low_i : 0; +} + + +// ---------------------------------------------------------------------------- +// SECTION: Public members - Reduction methods. +// ---------------------------------------------------------------------------- + +bool sc_unsigned::and_reduce() const +{ + int i; // Digit examining. + + if ( sgn == SC_ZERO ) return false; + for ( i = 0; i < ndigits-1; i++ ) + if ( (digit[i] & DIGIT_MASK) != DIGIT_MASK ) return false; + if ( (digit[i] & ~(-1 << ((nbits-1) % BITS_PER_DIGIT))) == + (sc_digit)~(-1 << ((nbits-1) % BITS_PER_DIGIT))) + return true; + return false; +} + +bool sc_unsigned::or_reduce() const +{ + return ( sgn == SC_ZERO ) ? false : true; +} + +bool sc_unsigned::xor_reduce() const +{ + int i; // Digit examining. + int odd; // Flag for odd number of digits. + + odd = 0; + for ( i = 0; i < nbits-1; i++ ) + if ( test(i) ) odd = ~odd; + return odd ? true : false; +} + + +// ---------------------------------------------------------------------------- +// SECTION: Public members - Assignment operators. +// ---------------------------------------------------------------------------- + +// assignment operators + +const sc_unsigned& +sc_unsigned::operator = ( const char* a ) +{ + if( a == 0 ) { + SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, + "character string is zero" ); + } + if( *a == 0 ) { + SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, + "character string is empty" ); + } + try { + int len = length(); + sc_ufix aa( a, len, len, SC_TRN, SC_WRAP, 0, SC_ON ); + return this->operator = ( aa ); + } catch( sc_core::sc_report ) { + char msg[BUFSIZ]; + std::sprintf( msg, "character string '%s' is not valid", a ); + SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg ); + // never reached + } + return *this; +} + +const sc_unsigned& +sc_unsigned::operator=(int64 v) +{ + sgn = get_sign(v); + if ( sgn == SC_ZERO ) { + vec_zero(ndigits, digit); + } + else { + from_uint(ndigits, digit, (uint64) v); + convert_SM_to_2C_to_SM(); + } + return *this; +} + +const sc_unsigned& +sc_unsigned::operator=(uint64 v) +{ + if (v == 0) { + sgn = SC_ZERO; + vec_zero(ndigits, digit); + } + else { + sgn = SC_POS; + from_uint(ndigits, digit, v); + convert_SM_to_2C_to_SM(); + } + return *this; +} + +const sc_unsigned& +sc_unsigned::operator=(long v) +{ + sgn = get_sign(v); + if ( sgn == SC_ZERO ) { + vec_zero(ndigits, digit); + } + else { + from_uint(ndigits, digit, (unsigned long) v); + convert_SM_to_2C_to_SM(); + } + return *this; +} + +const sc_unsigned& +sc_unsigned::operator=(unsigned long v) +{ + if (v == 0) { + sgn = SC_ZERO; + vec_zero(ndigits, digit); + } + else { + sgn = SC_POS; + from_uint(ndigits, digit, v); + convert_SM_to_2C_to_SM(); + } + return *this; +} + +const sc_unsigned& +sc_unsigned::operator=(double v) +{ + is_bad_double(v); + sgn = SC_POS; + int i = 0; + while (floor(v) && (i < ndigits)) { +#ifndef _WIN32 + digit[i++] = ((sc_digit)floor(remainder(v, DIGIT_RADIX))) & DIGIT_MASK; +#else + digit[i++] = ((sc_digit)floor(fmod(v, DIGIT_RADIX))) & DIGIT_MASK; +#endif + v /= DIGIT_RADIX; + } + vec_zero(i, ndigits, digit); + convert_SM_to_2C_to_SM(); + return *this; +} + + +// ---------------------------------------------------------------------------- + +const sc_unsigned& +sc_unsigned::operator = ( const sc_bv_base& v ) +{ + int minlen = sc_min( nbits, v.length() ); + int i = 0; + for( ; i < minlen; ++ i ) { + safe_set( i, v.get_bit( i ), digit ); + } + for( ; i < nbits; ++ i ) { + safe_set( i, 0, digit ); // zero-extend + } + convert_2C_to_SM(); + return *this; +} + +const sc_unsigned& +sc_unsigned::operator = ( const sc_lv_base& v ) +{ + int minlen = sc_min( nbits, v.length() ); + int i = 0; + for( ; i < minlen; ++ i ) { + safe_set( i, sc_logic( v.get_bit( i ) ).to_bool(), digit ); + } + for( ; i < nbits; ++ i ) { + safe_set( i, 0, digit ); // zero-extend + } + convert_2C_to_SM(); + return *this; +} + + +// explicit conversion to character string + +const std::string +sc_unsigned::to_string( sc_numrep numrep ) const +{ + int len = length(); + sc_ufix aa( *this, len, len, SC_TRN, SC_WRAP, 0, SC_ON ); + return aa.to_string( numrep ); +} + +const std::string +sc_unsigned::to_string( sc_numrep numrep, bool w_prefix ) const +{ + int len = length(); + sc_ufix aa( *this, len, len, SC_TRN, SC_WRAP, 0, SC_ON ); + return aa.to_string( numrep, w_prefix ); +} + + +// ---------------------------------------------------------------------------- +// SECTION: Interfacing with sc_int_base +// ---------------------------------------------------------------------------- + +const sc_unsigned& +sc_unsigned::operator= (const sc_int_base& v) +{ return operator=((int64) v); } + +const sc_unsigned& +sc_unsigned::operator+=(const sc_int_base& v) +{ return operator+=((int64) v); } + +const sc_unsigned& +sc_unsigned::operator-=(const sc_int_base& v) +{ return operator-=((int64) v); } + +const sc_unsigned& +sc_unsigned::operator*=(const sc_int_base& v) +{ return operator*=((int64) v); } + +const sc_unsigned& +sc_unsigned::operator/=(const sc_int_base& v) +{ return operator/=((int64) v); } + +const sc_unsigned& +sc_unsigned::operator%=(const sc_int_base& v) +{ return operator%=((int64) v); } + +const sc_unsigned& +sc_unsigned::operator&=(const sc_int_base& v) +{ return operator&=((int64) v); } + +const sc_unsigned& +sc_unsigned::operator|=(const sc_int_base& v) +{ return operator|=((int64) v); } + +const sc_unsigned& +sc_unsigned::operator^=(const sc_int_base& v) +{ return operator^=((int64) v); } + +sc_unsigned +operator<<(const sc_unsigned& u, const sc_int_base& v) +{ return operator<<(u, (int64) v); } +const sc_unsigned& +sc_unsigned::operator<<=(const sc_int_base& v) +{ return operator<<=((int64) v); } + +sc_unsigned +operator>>(const sc_unsigned& u, const sc_int_base& v) +{ return operator>>(u, (int64) v); } +const sc_unsigned& +sc_unsigned::operator>>=(const sc_int_base& v) +{ return operator>>=((int64) v); } + +bool +operator==(const sc_unsigned& u, const sc_int_base& v) +{ return operator==(u, (int64) v); } +bool +operator==(const sc_int_base& u, const sc_unsigned& v) +{ return operator==((int64) u, v); } + +bool +operator!=(const sc_unsigned& u, const sc_int_base& v) +{ return operator!=(u, (int64) v); } +bool +operator!=(const sc_int_base& u, const sc_unsigned& v) +{ return operator!=((int64) u, v); } + +bool +operator<(const sc_unsigned& u, const sc_int_base& v) +{ return operator<(u, (int64) v); } +bool +operator<(const sc_int_base& u, const sc_unsigned& v) +{ return operator<((int64) u, v); } + +bool +operator<=(const sc_unsigned& u, const sc_int_base& v) +{ return operator<=(u, (int64) v); } +bool +operator<=(const sc_int_base& u, const sc_unsigned& v) +{ return operator<=((int64) u, v); } + +bool +operator>(const sc_unsigned& u, const sc_int_base& v) +{ return operator>(u, (int64) v); } +bool +operator>(const sc_int_base& u, const sc_unsigned& v) +{ return operator>((int64) u, v); } + +bool +operator>=(const sc_unsigned& u, const sc_int_base& v) +{ return operator>=(u, (int64) v); } +bool +operator>=(const sc_int_base& u, const sc_unsigned& v) +{ return operator>=((int64) u, v); } + + +// ---------------------------------------------------------------------------- +// SECTION: Interfacing with sc_uint_base +// ---------------------------------------------------------------------------- + +const sc_unsigned& +sc_unsigned::operator= (const sc_uint_base& v) +{ return operator=((uint64) v); } + +sc_unsigned +operator+(const sc_unsigned& u, const sc_uint_base& v) +{ return operator+(u, (uint64) v); } +sc_unsigned +operator+(const sc_uint_base& u, const sc_unsigned& v) +{ return operator+((uint64) u, v); } +const sc_unsigned& +sc_unsigned::operator+=(const sc_uint_base& v) +{ return operator+=((uint64) v); } + +const sc_unsigned& +sc_unsigned::operator-=(const sc_uint_base& v) +{ return operator-=((uint64) v); } + +sc_unsigned +operator*(const sc_unsigned& u, const sc_uint_base& v) +{ return operator*(u, (uint64) v); } +sc_unsigned +operator*(const sc_uint_base& u, const sc_unsigned& v) +{ return operator*((uint64) u, v); } +const sc_unsigned& +sc_unsigned::operator*=(const sc_uint_base& v) +{ return operator*=((uint64) v); } + +sc_unsigned +operator/(const sc_unsigned& u, const sc_uint_base& v) +{ return operator/(u, (uint64) v); } +sc_unsigned +operator/(const sc_uint_base& u, const sc_unsigned& v) +{ return operator/((uint64) u, v); } +const sc_unsigned& +sc_unsigned::operator/=(const sc_uint_base& v) +{ return operator/=((uint64) v); } + +sc_unsigned +operator%(const sc_unsigned& u, const sc_uint_base& v) +{ return operator%(u, (uint64) v); } +sc_unsigned +operator%(const sc_uint_base& u, const sc_unsigned& v) +{ return operator%((uint64) u, v); } +const sc_unsigned& +sc_unsigned::operator%=(const sc_uint_base& v) +{ return operator%=((uint64) v); } + +sc_unsigned +operator&(const sc_unsigned& u, const sc_uint_base& v) +{ return operator&(u, (uint64) v); } +sc_unsigned +operator&(const sc_uint_base& u, const sc_unsigned& v) +{ return operator&((uint64) u, v); } +const sc_unsigned& +sc_unsigned::operator&=(const sc_uint_base& v) +{ return operator&=((uint64) v); } + +sc_unsigned +operator|(const sc_unsigned& u, const sc_uint_base& v) +{ return operator|(u, (uint64) v); } +sc_unsigned +operator|(const sc_uint_base& u, const sc_unsigned& v) +{ return operator|((uint64) u, v); } +const sc_unsigned& +sc_unsigned::operator|=(const sc_uint_base& v) +{ return operator|=((uint64) v); } + +sc_unsigned +operator^(const sc_unsigned& u, const sc_uint_base& v) +{ return operator^(u, (uint64) v); } +sc_unsigned +operator^(const sc_uint_base& u, const sc_unsigned& v) +{ return operator^((uint64) u, v); } +const sc_unsigned& +sc_unsigned::operator^=(const sc_uint_base& v) +{ return operator^=((uint64) v); } + +sc_unsigned +operator<<(const sc_unsigned& u, const sc_uint_base& v) +{ return operator<<(u, (uint64) v); } +const sc_unsigned& +sc_unsigned::operator<<=(const sc_uint_base& v) +{ return operator<<=((uint64) v); } + +sc_unsigned +operator>>(const sc_unsigned& u, const sc_uint_base& v) +{ return operator>>(u, (uint64) v); } +const sc_unsigned& +sc_unsigned::operator>>=(const sc_uint_base& v) +{ return operator>>=((uint64) v); } + +bool +operator==(const sc_unsigned& u, const sc_uint_base& v) +{ return operator==(u, (uint64) v); } +bool +operator==(const sc_uint_base& u, const sc_unsigned& v) +{ return operator==((uint64) u, v); } + +bool +operator!=(const sc_unsigned& u, const sc_uint_base& v) +{ return operator!=(u, (uint64) v); } +bool +operator!=(const sc_uint_base& u, const sc_unsigned& v) +{ return operator!=((uint64) u, v); } + +bool +operator<(const sc_unsigned& u, const sc_uint_base& v) +{ return operator<(u, (uint64) v); } +bool +operator<(const sc_uint_base& u, const sc_unsigned& v) +{ return operator<((uint64) u, v); } + +bool +operator<=(const sc_unsigned& u, const sc_uint_base& v) +{ return operator<=(u, (uint64) v); } +bool +operator<=(const sc_uint_base& u, const sc_unsigned& v) +{ return operator<=((uint64) u, v); } + +bool +operator>(const sc_unsigned& u, const sc_uint_base& v) +{ return operator>(u, (uint64) v); } +bool +operator>(const sc_uint_base& u, const sc_unsigned& v) +{ return operator>((uint64) u, v); } + +bool +operator>=(const sc_unsigned& u, const sc_uint_base& v) +{ return operator>=(u, (uint64) v); } +bool +operator>=(const sc_uint_base& u, const sc_unsigned& v) +{ return operator>=((uint64) u, v); } + + +// ---------------------------------------------------------------------------- +// SECTION: Input and output operators +// ---------------------------------------------------------------------------- + +// The operators in this section are included from sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: Operator macros. +// ---------------------------------------------------------------------------- + +#define CONVERT_LONG(u) \ +small_type u ## s = get_sign(u); \ +sc_digit u ## d[DIGITS_PER_ULONG]; \ +from_uint(DIGITS_PER_ULONG, u ## d, (unsigned long) u); + +#define CONVERT_LONG_2(u) \ +sc_digit u ## d[DIGITS_PER_ULONG]; \ +from_uint(DIGITS_PER_ULONG, u ## d, (unsigned long) u); + +#define CONVERT_INT(u) \ +small_type u ## s = get_sign(u); \ +sc_digit u ## d[DIGITS_PER_UINT]; \ +from_uint(DIGITS_PER_UINT, u ## d, (unsigned int) u); + +#define CONVERT_INT_2(u) \ +sc_digit u ## d[DIGITS_PER_UINT]; \ +from_uint(DIGITS_PER_UINT, u ## d, (unsigned int) u); + +#define CONVERT_INT64(u) \ +small_type u ## s = get_sign(u); \ +sc_digit u ## d[DIGITS_PER_UINT64]; \ +from_uint(DIGITS_PER_UINT64, u ## d, (uint64) u); + +#define CONVERT_INT64_2(u) \ +sc_digit u ## d[DIGITS_PER_UINT64]; \ +from_uint(DIGITS_PER_UINT64, u ## d, (uint64) u); + + +// ---------------------------------------------------------------------------- +// SECTION: PLUS operators: +, +=, ++ +// ---------------------------------------------------------------------------- + +// Cases to consider when computing u + v: +// 1. 0 + v = v +// 2. u + 0 = u +// 3. if sgn(u) == sgn(v) +// 3.1 u + v = +(u + v) = sgn(u) * (u + v) +// 3.2 (-u) + (-v) = -(u + v) = sgn(u) * (u + v) +// 4. if sgn(u) != sgn(v) +// 4.1 u + (-v) = u - v = sgn(u) * (u - v) +// 4.2 (-u) + v = -(u - v) ==> sgn(u) * (u - v) +// +// Specialization of above cases for computing ++u or u++: +// 1. 0 + 1 = 1 +// 3. u + 1 = u + 1 = sgn(u) * (u + 1) +// 4. (-u) + 1 = -(u - 1) = sgn(u) * (u - 1) + +sc_unsigned +operator+(const sc_unsigned& u, const sc_unsigned& v) +{ + + if (u.sgn == SC_ZERO) // case 1 + return sc_unsigned(v); + + if (v.sgn == SC_ZERO) // case 2 + return sc_unsigned(u); + + // cases 3 and 4 + return add_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_unsigned +operator+(const sc_unsigned &u, uint64 v) +{ + + if (v == 0) // case 2 + return sc_unsigned(u); + + CONVERT_INT64(v); + + if (u.sgn == SC_ZERO) // case 1 + return sc_unsigned(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false); + + // cases 3 and 4 + return add_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_unsigned +operator+(uint64 u, const sc_unsigned &v) +{ + + if (u == 0) // case 1 + return sc_unsigned(v); + + CONVERT_INT64(u); + + if (v.sgn == SC_ZERO) // case 2 + return sc_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false); + + // cases 3 and 4 + + return add_unsigned_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_unsigned +operator+(const sc_unsigned &u, unsigned long v) +{ + + if (v == 0) // case 2 + return sc_unsigned(u); + + CONVERT_LONG(v); + + if (u.sgn == SC_ZERO) // case 1 + return sc_unsigned(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false); + + // cases 3 and 4 + return add_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_unsigned +operator+(unsigned long u, const sc_unsigned &v) +{ + + if (u == 0) // case 1 + return sc_unsigned(v); + + CONVERT_LONG(u); + + if (v.sgn == SC_ZERO) // case 2 + return sc_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false); + + // cases 3 and 4 + return add_unsigned_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + +// The rest of the operators in this section are included from +// sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: MINUS operators: -, -=, -- +// ---------------------------------------------------------------------------- + +// Cases to consider when computing u + v: +// 1. u - 0 = u +// 2. 0 - v = -v +// 3. if sgn(u) != sgn(v) +// 3.1 u - (-v) = u + v = sgn(u) * (u + v) +// 3.2 (-u) - v = -(u + v) ==> sgn(u) * (u + v) +// 4. if sgn(u) == sgn(v) +// 4.1 u - v = +(u - v) = sgn(u) * (u - v) +// 4.2 (-u) - (-v) = -(u - v) = sgn(u) * (u - v) +// +// Specialization of above cases for computing --u or u--: +// 1. 0 - 1 = -1 +// 3. (-u) - 1 = -(u + 1) = sgn(u) * (u + 1) +// 4. u - 1 = u - 1 = sgn(u) * (u - 1) + +// The operators in this section are included from sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: MULTIPLICATION operators: *, *= +// ---------------------------------------------------------------------------- + +// Cases to consider when computing u * v: +// 1. u * 0 = 0 * v = 0 +// 2. 1 * v = v and -1 * v = -v +// 3. u * 1 = u and u * -1 = -u +// 4. u * v = u * v + +sc_unsigned +operator*(const sc_unsigned& u, const sc_unsigned& v) +{ + + small_type s = mul_signs(u.sgn, v.sgn); + + if (s == SC_ZERO) // case 1 + return sc_unsigned(); + + // cases 2-4 + return mul_unsigned_friend(s, u.nbits, u.ndigits, u.digit, + v.nbits, v.ndigits, v.digit); + +} + + +sc_unsigned +operator*(const sc_unsigned& u, uint64 v) +{ + + small_type s = mul_signs(u.sgn, get_sign(v)); + + if (s == SC_ZERO) // case 1 + return sc_unsigned(); + + CONVERT_INT64_2(v); + + // cases 2-4 + return mul_unsigned_friend(s, u.nbits, u.ndigits, u.digit, + BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_unsigned +operator*(uint64 u, const sc_unsigned& v) +{ + + small_type s = mul_signs(v.sgn, get_sign(u)); + + if (s == SC_ZERO) // case 1 + return sc_unsigned(); + + CONVERT_INT64_2(u); + + // cases 2-4 + return mul_unsigned_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.nbits, v.ndigits, v.digit); + +} + + +sc_unsigned +operator*(const sc_unsigned& u, unsigned long v) +{ + + small_type s = mul_signs(u.sgn, get_sign(v)); + + if (s == SC_ZERO) // case 1 + return sc_unsigned(); + + CONVERT_LONG_2(v); + + // else cases 2-4 + return mul_unsigned_friend(s, u.nbits, u.ndigits, u.digit, + BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + +sc_unsigned +operator*(unsigned long u, const sc_unsigned& v) +{ + + small_type s = mul_signs(v.sgn, get_sign(u)); + + if (s == SC_ZERO) // case 1 + return sc_unsigned(); + + CONVERT_LONG_2(u); + + // cases 2-4 + return mul_unsigned_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.nbits, v.ndigits, v.digit); + +} + +// The rest of the operators in this section are included from +// sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: DIVISION operators: /, /= +// ---------------------------------------------------------------------------- + +// Cases to consider when finding the quotient q = floor(u/v): +// Note that u = q * v + r for r < q. +// 1. 0 / 0 or u / 0 => error +// 2. 0 / v => 0 = 0 * v + 0 +// 3. u / v && u = v => u = 1 * u + 0 - u or v can be 1 or -1 +// 4. u / v && u < v => u = 0 * v + u - u can be 1 or -1 +// 5. u / v && u > v => u = q * v + r - v can be 1 or -1 + +sc_unsigned +operator/(const sc_unsigned& u, const sc_unsigned& v) +{ + + small_type s = mul_signs(u.sgn, v.sgn); + + if (s == SC_ZERO) { + div_by_zero(v.sgn); // case 1 + return sc_unsigned(); // case 2 + } + + // other cases + return div_unsigned_friend(s, u.nbits, u.ndigits, u.digit, + v.nbits, v.ndigits, v.digit); + +} + + +sc_unsigned +operator/(const sc_unsigned& u, uint64 v) +{ + + small_type s = mul_signs(u.sgn, get_sign(v)); + + if (s == SC_ZERO) { + div_by_zero(v); // case 1 + return sc_unsigned(); // case 2 + } + + CONVERT_INT64_2(v); + + // other cases + return div_unsigned_friend(s, u.nbits, u.ndigits, u.digit, + BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_unsigned +operator/(uint64 u, const sc_unsigned& v) +{ + + small_type s = mul_signs(v.sgn, get_sign(u)); + + if (s == SC_ZERO) { + div_by_zero(v.sgn); // case 1 + return sc_unsigned(); // case 2 + + } + + CONVERT_INT64_2(u); + + // other cases + return div_unsigned_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.nbits, v.ndigits, v.digit); + +} + + +sc_unsigned +operator/(const sc_unsigned& u, unsigned long v) +{ + + small_type s = mul_signs(u.sgn, get_sign(v)); + + if (s == SC_ZERO) { + div_by_zero(v); // case 1 + return sc_unsigned(); // case 2 + } + + CONVERT_LONG_2(v); + + // other cases + return div_unsigned_friend(s, u.nbits, u.ndigits, u.digit, + BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_unsigned +operator/(unsigned long u, const sc_unsigned& v) +{ + + small_type s = mul_signs(v.sgn, get_sign(u)); + + if (s == SC_ZERO) { + div_by_zero(v.sgn); // case 1 + return sc_unsigned(); // case 2 + + } + + CONVERT_LONG_2(u); + + // other cases + return div_unsigned_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.nbits, v.ndigits, v.digit); + +} + +// The rest of the operators in this section are included from +// sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: MOD operators: %, %=. +// ---------------------------------------------------------------------------- + +// Cases to consider when finding the remainder r = u % v: +// Note that u = q * v + r for r < q. +// 1. 0 % 0 or u % 0 => error +// 2. 0 % v => 0 = 0 * v + 0 +// 3. u % v && u = v => u = 1 * u + 0 - u or v can be 1 or -1 +// 4. u % v && u < v => u = 0 * v + u - u can be 1 or -1 +// 5. u % v && u > v => u = q * v + r - v can be 1 or -1 + +sc_unsigned +operator%(const sc_unsigned& u, const sc_unsigned& v) +{ + + if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) { + div_by_zero(v.sgn); // case 1 + return sc_unsigned(); // case 2 + } + + // other cases + return mod_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit, + v.nbits, v.ndigits, v.digit); +} + + +sc_unsigned +operator%(const sc_unsigned& u, uint64 v) +{ + + if ((u.sgn == SC_ZERO) || (v == 0)) { + div_by_zero(v); // case 1 + return sc_unsigned(); // case 2 + } + + CONVERT_INT64_2(v); + + // other cases + return mod_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit, + BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_unsigned +operator%(uint64 u, const sc_unsigned& v) +{ + + if ((u == 0) || (v.sgn == SC_ZERO)) { + div_by_zero(v.sgn); // case 1 + return sc_unsigned(); // case 2 + } + + CONVERT_INT64(u); + + // other cases + return mod_unsigned_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.nbits, v.ndigits, v.digit); + +} + + +sc_unsigned +operator%(const sc_unsigned& u, unsigned long v) +{ + + if ((u.sgn == SC_ZERO) || (v == 0)) { + div_by_zero(v); // case 1 + return sc_unsigned(); // case 2 + } + + CONVERT_LONG_2(v); + + // other cases + return mod_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit, + BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_unsigned +operator%(unsigned long u, const sc_unsigned& v) +{ + + if ((u == 0) || (v.sgn == SC_ZERO)) { + div_by_zero(v.sgn); // case 1 + return sc_unsigned(); // case 2 + } + + CONVERT_LONG(u); + + // other cases + return mod_unsigned_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.nbits, v.ndigits, v.digit); + +} + +// The rest of the operators in this section are included from +// sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: Bitwise AND operators: &, &= +// ---------------------------------------------------------------------------- + +// Cases to consider when computing u & v: +// 1. u & 0 = 0 & v = 0 +// 2. u & v => sgn = + +// 3. (-u) & (-v) => sgn = - +// 4. u & (-v) => sgn = + +// 5. (-u) & v => sgn = + + +sc_unsigned +operator&(const sc_unsigned& u, const sc_unsigned& v) +{ + + if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) // case 1 + return sc_unsigned(); + + // other cases + return and_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_unsigned +operator&(const sc_unsigned& u, uint64 v) +{ + + if ((u.sgn == SC_ZERO) || (v == 0)) // case 1 + return sc_unsigned(); + + CONVERT_INT64(v); + + // other cases + return and_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_unsigned +operator&(uint64 u, const sc_unsigned& v) +{ + + if ((u == 0) || (v.sgn == SC_ZERO)) // case 1 + return sc_unsigned(); + + CONVERT_INT64(u); + + // other cases + return and_unsigned_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_unsigned +operator&(const sc_unsigned& u, unsigned long v) +{ + + if ((u.sgn == SC_ZERO) || (v == 0)) // case 1 + return sc_unsigned(); + + CONVERT_LONG(v); + + // other cases + return and_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_unsigned +operator&(unsigned long u, const sc_unsigned& v) +{ + + if ((u == 0) || (v.sgn == SC_ZERO)) // case 1 + return sc_unsigned(); + + CONVERT_LONG(u); + + // other cases + return and_unsigned_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + +// The rest of the operators in this section are included from +// sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: Bitwise OR operators: |, |= +// ---------------------------------------------------------------------------- + +// Cases to consider when computing u | v: +// 1. u | 0 = u +// 2. 0 | v = v +// 3. u | v => sgn = + +// 4. (-u) | (-v) => sgn = - +// 5. u | (-v) => sgn = - +// 6. (-u) | v => sgn = - + +sc_unsigned +operator|(const sc_unsigned& u, const sc_unsigned& v) +{ + + if (v.sgn == SC_ZERO) // case 1 + return sc_unsigned(u); + + if (u.sgn == SC_ZERO) // case 2 + return sc_unsigned(v); + + // other cases + return or_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_unsigned +operator|(const sc_unsigned& u, uint64 v) +{ + + if (v == 0) // case 1 + return sc_unsigned(u); + + CONVERT_INT64(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_unsigned(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false); + + // other cases + return or_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + + +sc_unsigned +operator|(uint64 u, const sc_unsigned& v) +{ + + if (u == 0) + return sc_unsigned(v); + + CONVERT_INT64(u); + + if (v.sgn == SC_ZERO) + return sc_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false); + + // other cases + return or_unsigned_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_unsigned +operator|(const sc_unsigned& u, unsigned long v) +{ + + if (v == 0) // case 1 + return sc_unsigned(u); + + CONVERT_LONG(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_unsigned(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false); + + // other cases + return or_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + + +sc_unsigned +operator|(unsigned long u, const sc_unsigned& v) +{ + + if (u == 0) + return sc_unsigned(v); + + CONVERT_LONG(u); + + if (v.sgn == SC_ZERO) + return sc_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false); + + // other cases + return or_unsigned_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + +// The rest of the operators in this section are included from +// sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: Bitwise XOR operators: ^, ^= +// ---------------------------------------------------------------------------- + +// Cases to consider when computing u ^ v: +// Note that u ^ v = (~u & v) | (u & ~v). +// 1. u ^ 0 = u +// 2. 0 ^ v = v +// 3. u ^ v => sgn = + +// 4. (-u) ^ (-v) => sgn = - +// 5. u ^ (-v) => sgn = - +// 6. (-u) ^ v => sgn = + + +sc_unsigned +operator^(const sc_unsigned& u, const sc_unsigned& v) +{ + + if (v.sgn == SC_ZERO) // case 1 + return sc_unsigned(u); + + if (u.sgn == SC_ZERO) // case 2 + return sc_unsigned(v); + + // other cases + return xor_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_unsigned +operator^(const sc_unsigned& u, uint64 v) +{ + + if (v == 0) // case 1 + return sc_unsigned(u); + + CONVERT_INT64(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_unsigned(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false); + + // other cases + return xor_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); + +} + +sc_unsigned +operator^(uint64 u, const sc_unsigned& v) +{ + if (u == 0) + return sc_unsigned(v); + + CONVERT_INT64(u); + + if (v.sgn == SC_ZERO) + return sc_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false); + + // other cases + return xor_unsigned_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + + +sc_unsigned +operator^(const sc_unsigned& u, unsigned long v) +{ + + if (v == 0) // case 1 + return sc_unsigned(u); + + CONVERT_LONG(v); + + if (u.sgn == SC_ZERO) // case 2 + return sc_unsigned(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false); + + // other cases + return xor_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); + +} + +sc_unsigned +operator^(unsigned long u, const sc_unsigned& v) +{ + if (u == 0) + return sc_unsigned(v); + + CONVERT_LONG(u); + + if (v.sgn == SC_ZERO) + return sc_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false); + + // other cases + return xor_unsigned_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.sgn, v.nbits, v.ndigits, v.digit); + +} + +// The rest of the operators in this section are included from +// sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: Bitwise NOT operator: ~ +// ---------------------------------------------------------------------------- + +// Operators in this section are included from sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: LEFT SHIFT operators: <<, <<= +// ---------------------------------------------------------------------------- + +sc_unsigned +operator<<(const sc_unsigned& u, const sc_signed& v) +{ + if ((v.sgn == SC_ZERO) || (v.sgn == SC_NEG)) + return sc_unsigned(u); + + return operator<<(u, v.to_ulong()); +} + +// The rest of the operators in this section are included from +// sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: RIGHT SHIFT operators: >>, >>= +// ---------------------------------------------------------------------------- + +sc_unsigned +operator>>(const sc_unsigned& u, const sc_signed& v) +{ + + if ((v.sgn == SC_ZERO) || (v.sgn == SC_NEG)) + return sc_unsigned(u); + + return operator>>(u, v.to_long()); + +} + +// The rest of the operators in this section are included from +// sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: Unary arithmetic operators. +// ---------------------------------------------------------------------------- + +sc_unsigned +operator+(const sc_unsigned& u) +{ + return sc_unsigned(u); +} + + +// ---------------------------------------------------------------------------- +// SECTION: EQUAL operator: == +// ---------------------------------------------------------------------------- + +bool +operator==(const sc_unsigned& u, const sc_unsigned& v) +{ + if (&u == &v) + return true; + if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit, + v.sgn, v.nbits, v.ndigits, v.digit) != 0) + return false; + return true; +} + + +bool +operator==(const sc_unsigned& u, const sc_signed& v) +{ + if (v.sgn == SC_NEG) + return false; + if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit, + v.sgn, v.nbits, v.ndigits, v.digit, 0, 1) != 0) + return false; + return true; +} + + +bool +operator==(const sc_signed& u, const sc_unsigned& v) +{ + if (u.sgn == SC_NEG) + return false; + if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit, + v.sgn, v.nbits, v.ndigits, v.digit, 1, 0) != 0) + return false; + return true; +} + + +bool +operator==(const sc_unsigned& u, int64 v) +{ + if (v < 0) + return false; + CONVERT_INT64(v); + if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd) != 0) + return false; + return true; +} + + +bool +operator==(int64 u, const sc_unsigned& v) +{ + if (u < 0) + return false; + CONVERT_INT64(u); + if (compare_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.sgn, v.nbits, v.ndigits, v.digit) != 0) + return false; + return true; +} + + +bool +operator==(const sc_unsigned& u, uint64 v) +{ + CONVERT_INT64(v); + if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd) != 0) + return false; + return true; +} + + +bool +operator==(uint64 u, const sc_unsigned& v) +{ + CONVERT_INT64(u); + if (compare_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.sgn, v.nbits, v.ndigits, v.digit) != 0) + return false; + return true; +} + + +bool +operator==(const sc_unsigned& u, long v) +{ + if (v < 0) + return false; + CONVERT_LONG(v); + if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd) != 0) + return false; + return true; +} + + +bool +operator==(long u, const sc_unsigned& v) +{ + if (u < 0) + return false; + CONVERT_LONG(u); + if (compare_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.sgn, v.nbits, v.ndigits, v.digit) != 0) + return false; + return true; +} + + +bool +operator==(const sc_unsigned& u, unsigned long v) +{ + CONVERT_LONG(v); + if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd) != 0) + return false; + return true; +} + + +bool +operator==(unsigned long u, const sc_unsigned& v) +{ + CONVERT_LONG(u); + if (compare_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.sgn, v.nbits, v.ndigits, v.digit) != 0) + return false; + return true; +} + + +// ---------------------------------------------------------------------------- +// SECTION: NOT_EQUAL operator: != +// ---------------------------------------------------------------------------- + +bool +operator!=(const sc_unsigned& u, const sc_signed& v) +{ + return (! operator==(u, v)); +} + + +bool +operator!=(const sc_signed& u, const sc_unsigned& v) +{ + return (! operator==(u, v)); +} + +// The rest of the operators in this section are included from sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: LESS THAN operator: < +// ---------------------------------------------------------------------------- + +bool +operator<(const sc_unsigned& u, const sc_unsigned& v) +{ + if (&u == &v) + return false; + if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit, + v.sgn, v.nbits, v.ndigits, v.digit) < 0) + return true; + return false; +} + + +bool +operator<(const sc_unsigned& u, const sc_signed& v) +{ + if (v.sgn == SC_NEG) + return false; + if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit, + v.sgn, v.nbits, v.ndigits, v.digit, 0, 1) < 0) + return true; + return false; +} + + +bool +operator<(const sc_signed& u, const sc_unsigned& v) +{ + if (u.sgn == SC_NEG) + return true; + if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit, + v.sgn, v.nbits, v.ndigits, v.digit, 1, 0) < 0) + return true; + return false; +} + + +bool +operator<(const sc_unsigned& u, int64 v) +{ + if (v < 0) + return false; + CONVERT_INT64(v); + if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd) < 0) + return true; + return false; +} + + +bool +operator<(int64 u, const sc_unsigned& v) +{ + if (u < 0) + return true; + CONVERT_INT64(u); + if (compare_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.sgn, v.nbits, v.ndigits, v.digit) < 0) + return true; + return false; +} + + +bool +operator<(const sc_unsigned& u, uint64 v) +{ + CONVERT_INT64(v); + if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd) < 0) + return true; + return false; +} + + +bool +operator<(uint64 u, const sc_unsigned& v) +{ + CONVERT_INT64(u); + if (compare_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, + v.sgn, v.nbits, v.ndigits, v.digit) < 0) + return true; + return false; +} + + +bool +operator<(const sc_unsigned& u, long v) +{ + if (v < 0) + return false; + CONVERT_LONG(v); + if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd) < 0) + return true; + return false; +} + + +bool +operator<(long u, const sc_unsigned& v) +{ + if (u < 0) + return true; + CONVERT_LONG(u); + if (compare_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.sgn, v.nbits, v.ndigits, v.digit) < 0) + return true; + return false; +} + + +bool +operator<(const sc_unsigned& u, unsigned long v) +{ + CONVERT_LONG(v); + if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit, + vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd) < 0) + return true; + return false; +} + + +bool +operator<(unsigned long u, const sc_unsigned& v) +{ + CONVERT_LONG(u); + if (compare_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, + v.sgn, v.nbits, v.ndigits, v.digit) < 0) + return true; + return false; +} + + +// ---------------------------------------------------------------------------- +// SECTION: LESS THAN or EQUAL operator: <= +// ---------------------------------------------------------------------------- + +bool +operator<=(const sc_unsigned& u, const sc_signed& v) +{ + return (operator<(u, v) || operator==(u, v)); +} + + +bool +operator<=(const sc_signed& u, const sc_unsigned& v) +{ + return (operator<(u, v) || operator==(u, v)); +} + +// The rest of the operators in this section are included from sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: GREATER THAN operator: > +// ---------------------------------------------------------------------------- + +bool +operator>(const sc_unsigned& u, const sc_signed& v) +{ + return (! (operator<=(u, v))); +} + + +bool +operator>(const sc_signed& u, const sc_unsigned& v) +{ + return (! (operator<=(u, v))); +} + +// The rest of the operators in this section are included from sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: GREATER THAN or EQUAL operator: >= +// ---------------------------------------------------------------------------- + +bool +operator>=(const sc_unsigned& u, const sc_signed& v) +{ + return (! (operator<(u, v))); +} + + +bool +operator>=(const sc_signed& u, const sc_unsigned& v) +{ + return (! (operator<(u, v))); +} + +// The rest of the operators in this section are included from sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: Friends +// ---------------------------------------------------------------------------- + +// Compare u and v as unsigned and return r +// r = 0 if u == v +// r < 0 if u < v +// r > 0 if u > v + +int +compare_unsigned(small_type us, + int unb, int und, const sc_digit *ud, + small_type vs, + int vnb, int vnd, const sc_digit *vd, + small_type if_u_signed, + small_type if_v_signed) +{ + + if (us == vs) { + + if (us == SC_ZERO) + return 0; + + else { + + int cmp_res = vec_skip_and_cmp(und, ud, vnd, vd); + + if (us == SC_POS) + return cmp_res; + else + return -cmp_res; + + } + } + else { + + if (us == SC_ZERO) + return -vs; + + if (vs == SC_ZERO) + return us; + + int cmp_res; + + int nd = (us == SC_NEG ? und : vnd); + +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS]; +#else + sc_digit *d = new sc_digit[nd]; +#endif + + if (us == SC_NEG) { + + vec_copy(nd, d, ud); + vec_complement(nd, d); + trim(if_u_signed, unb, nd, d); + cmp_res = vec_skip_and_cmp(nd, d, vnd, vd); + + } + else { + + vec_copy(nd, d, vd); + vec_complement(nd, d); + trim(if_v_signed, vnb, nd, d); + cmp_res = vec_skip_and_cmp(und, ud, nd, d); + + } + +#ifndef SC_MAX_NBITS + delete [] d; +#endif + + return cmp_res; + + } +} + + +// ---------------------------------------------------------------------------- +// SECTION: Public members - Other utils. +// ---------------------------------------------------------------------------- + +bool +sc_unsigned::iszero() const +{ + if (sgn == SC_ZERO) + return true; + + else if (sgn == SC_NEG) { + + // A negative unsigned number can be zero, e.g., -16 in 4 bits, so + // check that. + +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS]; +#else + sc_digit *d = new sc_digit[ndigits]; +#endif + + vec_copy(ndigits, d, digit); + vec_complement(ndigits, d); + trim_unsigned(nbits, ndigits, d); + + bool res = check_for_zero(ndigits, d); + +#ifndef SC_MAX_NBITS + delete [] d; +#endif + + return res; + + } + else + return false; +} + +// The rest of the utils in this section are included from sc_nbcommon.cpp. + + +// ---------------------------------------------------------------------------- +// SECTION: Private members. +// ---------------------------------------------------------------------------- + +// The private members in this section are included from +// sc_nbcommon.cpp. + +#define CLASS_TYPE sc_unsigned +#define CLASS_TYPE_STR "sc_unsigned" + +#define ADD_HELPER add_unsigned_friend +#define SUB_HELPER sub_unsigned_friend +#define MUL_HELPER mul_unsigned_friend +#define DIV_HELPER div_unsigned_friend +#define MOD_HELPER mod_unsigned_friend +#define AND_HELPER and_unsigned_friend +#define OR_HELPER or_unsigned_friend +#define XOR_HELPER xor_unsigned_friend + +#include "sc_nbfriends.inc" + +#undef SC_SIGNED +#define SC_UNSIGNED +#define IF_SC_SIGNED 0 // 0 = sc_unsigned +#define CLASS_TYPE_SUBREF sc_unsigned_subref_r +#define OTHER_CLASS_TYPE sc_signed +#define OTHER_CLASS_TYPE_SUBREF sc_signed_subref_r + +#define MUL_ON_HELPER mul_on_help_unsigned +#define DIV_ON_HELPER div_on_help_unsigned +#define MOD_ON_HELPER mod_on_help_unsigned + +#include "sc_nbcommon.inc" + +#undef MOD_ON_HELPER +#undef DIV_ON_HELPER +#undef MUL_ON_HELPER + +#undef OTHER_CLASS_TYPE_SUBREF +#undef OTHER_CLASS_TYPE +#undef CLASS_TYPE_SUBREF +#undef IF_SC_SIGNED +#undef SC_UNSIGNED + +#undef XOR_HELPER +#undef OR_HELPER +#undef AND_HELPER +#undef MOD_HELPER +#undef DIV_HELPER +#undef MUL_HELPER +#undef SUB_HELPER +#undef ADD_HELPER + +#undef CLASS_TYPE +#undef CLASS_TYPE_STR + +#include "sc_unsigned_bitref.inc" +#include "sc_unsigned_subref.inc" + +#undef CONVERT_LONG +#undef CONVERT_LONG_2 +#undef CONVERT_INT64 +#undef CONVERT_INT64_2 + +} // namespace sc_dt + + +// End of file. diff --git a/ext/systemc/src/sysc/datatypes/int/sc_unsigned.h b/ext/systemc/src/sysc/datatypes/int/sc_unsigned.h new file mode 100644 index 000000000..4260542a3 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_unsigned.h @@ -0,0 +1,2191 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_unsigned.h -- Arbitrary precision unsigned arithmetic. + + This file includes the definitions of sc_unsigned_bitref, + sc_unsigned_subref, and sc_unsigned classes. The first two classes + are proxy classes to reference one bit and a range of bits of a + sc_unsigned number, respectively. + + An sc_signed number has the sign-magnitude representation + internally. However, its interface guarantees a 2's-complement + representation. The sign-magnitude representation is chosen + because of its efficiency: The sc_signed and sc_unsigned types are + optimized for arithmetic rather than bitwise operations. For + arithmetic operations, the sign-magnitude representation performs + better. + + It is also important to note that an sc_unsigned number with n + bits is equivalent to an sc_signed non-negative number with n + 1 + bits. + + The implementations of sc_signed and sc_unsigned classes are + almost identical: Most of the member and friend functions are + defined in sc_nbcommon.cpp and sc_nbfriends.cpp so that they can + be shared by both of these classes. These functions are chosed by + defining a few macros before including them such as IF_SC_SIGNED + and CLASS_TYPE. Our implementation choices are mostly dictated by + performance considerations in that we tried to provide the most + efficient sc_signed and sc_unsigned types without compromising + their interface. + + For the behavior of operators, we have two semantics: the old and + new. The most important difference between these two semantics is + that the old semantics is closer to C/C++ semantics in that the + result type of a binary operator on unsigned and signed arguments + is unsigned; the new semantics, on the other hand, requires the + result type be signed. The new semantics is required by the VSIA + C/C++ data types standard. We have implemented the new semantics. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_unsigned.h,v $ +// Revision 1.4 2011/08/24 22:05:46 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.3 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.2 2009/02/28 00:26:26 acg +// Andy Goodrich: bug fixes. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.5 2006/05/08 17:50:02 acg +// Andy Goodrich: Added David Long's declarations for friend operators, +// functions, and methods, to keep the Microsoft compiler happy. +// +// Revision 1.4 2006/03/13 20:25:27 acg +// Andy Goodrich: Addition of function declarations, e.g., xor_signed_friend() +// to keep gcc 4.x happy. +// +// Revision 1.3 2006/01/13 18:49:32 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef SC_UNSIGNED_H +#define SC_UNSIGNED_H + + +#include "sysc/kernel/sc_object.h" +#include "sysc/datatypes/misc/sc_value_base.h" +#include "sysc/utils/sc_iostream.h" +#include "sysc/utils/sc_temporary.h" +#include "sysc/datatypes/int/sc_length_param.h" +#include "sysc/datatypes/int/sc_nbdefs.h" +#include "sysc/datatypes/int/sc_nbutils.h" +#include "sysc/datatypes/int/sc_nbexterns.h" +#include "sysc/utils/sc_temporary.h" + + +namespace sc_dt +{ + +// classes defined in this module +class sc_unsigned_bitref_r; +class sc_unsigned_bitref; +class sc_unsigned_subref_r; +class sc_unsigned_subref; +class sc_concatref; +class sc_unsigned; + +// forward class declarations +class sc_bv_base; +class sc_lv_base; +class sc_int_base; +class sc_uint_base; +class sc_int_subref_r; +class sc_uint_subref_r; +class sc_signed; +class sc_signed_subref_r; +class sc_fxval; +class sc_fxval_fast; +class sc_fxnum; +class sc_fxnum_fast; + +// Helper function declarions +int compare_unsigned(small_type us, + int unb, + int und, + const sc_digit *ud, + small_type vs, + int vnb, + int vnd, + const sc_digit *vd, + small_type if_u_signed=0, + small_type if_v_signed=0); + +sc_unsigned add_unsigned_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + small_type vs, + int vnb, + int vnd, + const sc_digit *vd); + +sc_unsigned sub_unsigned_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + small_type vs, + int vnb, + int vnd, + const sc_digit *vd); + +sc_unsigned mul_unsigned_friend(small_type s, + int unb, + int und, + const sc_digit *ud, + int vnb, + int vnd, + const sc_digit *vd); + +sc_unsigned div_unsigned_friend(small_type s, + int unb, + int und, + const sc_digit *ud, + int vnb, + int vnd, + const sc_digit *vd); + +sc_unsigned mod_unsigned_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + int vnb, + int vnd, + const sc_digit *vd); + +sc_unsigned and_unsigned_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + small_type vs, + int vnb, + int vnd, + const sc_digit *vd); + + +sc_unsigned or_unsigned_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + small_type vs, + int vnb, + int vnd, + const sc_digit *vd); + +sc_unsigned xor_unsigned_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + small_type vs, + int vnb, + int vnd, + const sc_digit *vd); + +// friend operator declarations + // ARITHMETIC OPERATORS: + + // ADDition operators: + + sc_signed operator + (const sc_unsigned& u, const sc_signed& v); + sc_signed operator + (const sc_signed& u, const sc_unsigned& v); + + sc_unsigned operator + (const sc_unsigned& u, const sc_unsigned& v); + sc_signed operator + (const sc_unsigned& u, int64 v); + sc_unsigned operator + (const sc_unsigned& u, uint64 v); + sc_signed operator + (const sc_unsigned& u, long v); + sc_unsigned operator + (const sc_unsigned& u, unsigned long v); + sc_signed operator + (const sc_unsigned& u, int v); + inline sc_unsigned operator + (const sc_unsigned& u, unsigned int v); + + sc_signed operator + (int64 u, const sc_unsigned& v); + sc_unsigned operator + (uint64 u, const sc_unsigned& v); + sc_signed operator + (long u, const sc_unsigned& v); + sc_unsigned operator + (unsigned long u, const sc_unsigned& v); + sc_signed operator + (int u, const sc_unsigned& v); + inline sc_unsigned operator + (unsigned int u, const sc_unsigned& v); + + sc_unsigned operator + (const sc_unsigned& u, const sc_uint_base& v); + sc_signed operator + (const sc_unsigned& u, const sc_int_base& v); + sc_unsigned operator + (const sc_uint_base& u, const sc_unsigned& v); + sc_signed operator + (const sc_int_base& u, const sc_unsigned& v); + + // SUBtraction operators: + + sc_signed operator - (const sc_unsigned& u, const sc_signed& v); + sc_signed operator - (const sc_signed& u, const sc_unsigned& v); + + sc_signed operator - (const sc_unsigned& u, const sc_unsigned& v); + sc_signed operator - (const sc_unsigned& u, int64 v); + sc_signed operator - (const sc_unsigned& u, uint64 v); + sc_signed operator - (const sc_unsigned& u, long v); + sc_signed operator - (const sc_unsigned& u, unsigned long v); + sc_signed operator - (const sc_unsigned& u, int v); + sc_signed operator - (const sc_unsigned& u, unsigned int v); + + sc_signed operator - (int64 u, const sc_unsigned& v); + sc_signed operator - (uint64 u, const sc_unsigned& v); + sc_signed operator - (long u, const sc_unsigned& v); + sc_signed operator - (unsigned long u, const sc_unsigned& v); + sc_signed operator - (int u, const sc_unsigned& v); + sc_signed operator - (unsigned int u, const sc_unsigned& v); + + sc_signed operator - (const sc_unsigned& u, const sc_uint_base& v); + sc_signed operator - (const sc_unsigned& u, const sc_int_base& v); + sc_signed operator - (const sc_uint_base& u, const sc_unsigned& v); + sc_signed operator - (const sc_int_base& u, const sc_unsigned& v); + + // MULtiplication operators: + + sc_signed operator * (const sc_unsigned& u, const sc_signed& v); + sc_signed operator * (const sc_signed& u, const sc_unsigned& v); + + sc_unsigned operator * (const sc_unsigned& u, const sc_unsigned& v); + sc_signed operator * (const sc_unsigned& u, int64 v); + sc_unsigned operator * (const sc_unsigned& u, uint64 v); + sc_signed operator * (const sc_unsigned& u, long v); + sc_unsigned operator * (const sc_unsigned& u, unsigned long v); + sc_signed operator * (const sc_unsigned& u, int v); + inline sc_unsigned operator * (const sc_unsigned& u, unsigned int v); + + sc_signed operator * (int64 u, const sc_unsigned& v); + sc_unsigned operator * (uint64 u, const sc_unsigned& v); + sc_signed operator * (long u, const sc_unsigned& v); + sc_unsigned operator * (unsigned long u, const sc_unsigned& v); + sc_signed operator * (int u, const sc_unsigned& v); + inline sc_unsigned operator * (unsigned int u, const sc_unsigned& v); + + sc_unsigned operator * (const sc_unsigned& u, const sc_uint_base& v); + sc_signed operator * (const sc_unsigned& u, const sc_int_base& v); + sc_unsigned operator * (const sc_uint_base& u, const sc_unsigned& v); + sc_signed operator * (const sc_int_base& u, const sc_unsigned& v); + + // DIVision operators: + + sc_signed operator / (const sc_unsigned& u, const sc_signed& v); + sc_signed operator / (const sc_signed& u, const sc_unsigned& v); + + sc_unsigned operator / (const sc_unsigned& u, const sc_unsigned& v); + sc_signed operator / (const sc_unsigned& u, int64 v); + sc_unsigned operator / (const sc_unsigned& u, uint64 v); + sc_signed operator / (const sc_unsigned& u, long v); + sc_unsigned operator / (const sc_unsigned& u, unsigned long v); + sc_signed operator / (const sc_unsigned& u, int v); + inline sc_unsigned operator / (const sc_unsigned& u, unsigned int v); + + sc_signed operator / (int64 u, const sc_unsigned& v); + sc_unsigned operator / (uint64 u, const sc_unsigned& v); + sc_signed operator / (long u, const sc_unsigned& v); + sc_unsigned operator / (unsigned long u, const sc_unsigned& v); + sc_signed operator / (int u, const sc_unsigned& v); + inline sc_unsigned operator / (unsigned int u, const sc_unsigned& v); + + sc_unsigned operator / (const sc_unsigned& u, const sc_uint_base& v); + sc_signed operator / (const sc_unsigned& u, const sc_int_base& v); + sc_unsigned operator / (const sc_uint_base& u, const sc_unsigned& v); + sc_signed operator / (const sc_int_base& u, const sc_unsigned& v); + + // MODulo operators: + + sc_signed operator % (const sc_unsigned& u, const sc_signed& v); + sc_signed operator % (const sc_signed& u, const sc_unsigned& v); + + sc_unsigned operator % (const sc_unsigned& u, const sc_unsigned& v); + sc_signed operator % (const sc_unsigned& u, int64 v); + sc_unsigned operator % (const sc_unsigned& u, uint64 v); + sc_signed operator % (const sc_unsigned& u, long v); + sc_unsigned operator % (const sc_unsigned& u, unsigned long v); + sc_signed operator % (const sc_unsigned& u, int v); + inline sc_unsigned operator % (const sc_unsigned& u, unsigned int v); + + sc_signed operator % (int64 u, const sc_unsigned& v); + sc_unsigned operator % (uint64 u, const sc_unsigned& v); + sc_signed operator % (long u, const sc_unsigned& v); + sc_unsigned operator % (unsigned long u, const sc_unsigned& v); + sc_signed operator % (int u, const sc_unsigned& v); + inline sc_unsigned operator % (unsigned int u, const sc_unsigned& v); + + sc_unsigned operator % (const sc_unsigned& u, const sc_uint_base& v); + sc_signed operator % (const sc_unsigned& u, const sc_int_base& v); + sc_unsigned operator % (const sc_uint_base& u, const sc_unsigned& v); + sc_signed operator % (const sc_int_base& u, const sc_unsigned& v); + + // BITWISE OPERATORS: + + // Bitwise AND operators: + + sc_signed operator & (const sc_unsigned& u, const sc_signed& v); + sc_signed operator & (const sc_signed& u, const sc_unsigned& v); + + sc_unsigned operator & (const sc_unsigned& u, const sc_unsigned& v); + sc_signed operator & (const sc_unsigned& u, int64 v); + sc_unsigned operator & (const sc_unsigned& u, uint64 v); + sc_signed operator & (const sc_unsigned& u, long v); + sc_unsigned operator & (const sc_unsigned& u, unsigned long v); + sc_signed operator & (const sc_unsigned& u, int v); + inline sc_unsigned operator & (const sc_unsigned& u, unsigned int v); + + sc_signed operator & (int64 u, const sc_unsigned& v); + sc_unsigned operator & (uint64 u, const sc_unsigned& v); + sc_signed operator & (long u, const sc_unsigned& v); + sc_unsigned operator & (unsigned long u, const sc_unsigned& v); + sc_signed operator & (int u, const sc_unsigned& v); + inline sc_unsigned operator & (unsigned int u, const sc_unsigned& v); + + sc_unsigned operator & (const sc_unsigned& u, const sc_uint_base& v); + sc_signed operator & (const sc_unsigned& u, const sc_int_base& v); + sc_unsigned operator & (const sc_uint_base& u, const sc_unsigned& v); + sc_signed operator & (const sc_int_base& u, const sc_unsigned& v); + + // Bitwise OR operators: + + sc_signed operator | (const sc_unsigned& u, const sc_signed& v); + sc_signed operator | (const sc_signed& u, const sc_unsigned& v); + + sc_unsigned operator | (const sc_unsigned& u, const sc_unsigned& v); + sc_signed operator | (const sc_unsigned& u, int64 v); + sc_unsigned operator | (const sc_unsigned& u, uint64 v); + sc_signed operator | (const sc_unsigned& u, long v); + sc_unsigned operator | (const sc_unsigned& u, unsigned long v); + sc_signed operator | (const sc_unsigned& u, int v); + inline sc_unsigned operator | (const sc_unsigned& u, unsigned int v); + + sc_signed operator | (int64 u, const sc_unsigned& v); + sc_unsigned operator | (uint64 u, const sc_unsigned& v); + sc_signed operator | (long u, const sc_unsigned& v); + sc_unsigned operator | (unsigned long u, const sc_unsigned& v); + sc_signed operator | (int u, const sc_unsigned& v); + inline sc_unsigned operator | (unsigned int u, const sc_unsigned& v); + + sc_unsigned operator | (const sc_unsigned& u, const sc_uint_base& v); + sc_signed operator | (const sc_unsigned& u, const sc_int_base& v); + sc_unsigned operator | (const sc_uint_base& u, const sc_unsigned& v); + sc_signed operator | (const sc_int_base& u, const sc_unsigned& v); + + // Bitwise XOR operators: + + sc_signed operator ^ (const sc_unsigned& u, const sc_signed& v); + sc_signed operator ^ (const sc_signed& u, const sc_unsigned& v); + + sc_unsigned operator ^ (const sc_unsigned& u, const sc_unsigned& v); + sc_signed operator ^ (const sc_unsigned& u, int64 v); + sc_unsigned operator ^ (const sc_unsigned& u, uint64 v); + sc_signed operator ^ (const sc_unsigned& u, long v); + sc_unsigned operator ^ (const sc_unsigned& u, unsigned long v); + sc_signed operator ^ (const sc_unsigned& u, int v); + inline sc_unsigned operator ^ (const sc_unsigned& u, unsigned int v); + + sc_signed operator ^ (int64 u, const sc_unsigned& v); + sc_unsigned operator ^ (uint64 u, const sc_unsigned& v); + sc_signed operator ^ (long u, const sc_unsigned& v); + sc_unsigned operator ^ (unsigned long u, const sc_unsigned& v); + sc_signed operator ^ (int u, const sc_unsigned& v); + inline sc_unsigned operator ^ (unsigned int u, const sc_unsigned& v); + + sc_unsigned operator ^ (const sc_unsigned& u, const sc_uint_base& v); + sc_signed operator ^ (const sc_unsigned& u, const sc_int_base& v); + sc_unsigned operator ^ (const sc_uint_base& u, const sc_unsigned& v); + sc_signed operator ^ (const sc_int_base& u, const sc_unsigned& v); + + // SHIFT OPERATORS: + + // LEFT SHIFT operators: + + sc_unsigned operator << (const sc_unsigned& u, const sc_signed& v); + sc_signed operator << (const sc_signed& u, const sc_unsigned& v); + + sc_unsigned operator << (const sc_unsigned& u, const sc_unsigned& v); + sc_unsigned operator << (const sc_unsigned& u, int64 v); + sc_unsigned operator << (const sc_unsigned& u, uint64 v); + sc_unsigned operator << (const sc_unsigned& u, long v); + sc_unsigned operator << (const sc_unsigned& u, unsigned long v); + inline sc_unsigned operator << (const sc_unsigned& u, int v); + inline sc_unsigned operator << (const sc_unsigned& u, unsigned int v); + + sc_unsigned operator << (const sc_unsigned& u, const sc_uint_base& v); + sc_unsigned operator << (const sc_unsigned& u, const sc_int_base& v); + + // RIGHT SHIFT operators: + + sc_unsigned operator >> (const sc_unsigned& u, const sc_signed& v); + sc_signed operator >> (const sc_signed& u, const sc_unsigned& v); + + sc_unsigned operator >> (const sc_unsigned& u, const sc_unsigned& v); + sc_unsigned operator >> (const sc_unsigned& u, int64 v); + sc_unsigned operator >> (const sc_unsigned& u, uint64 v); + sc_unsigned operator >> (const sc_unsigned& u, long v); + sc_unsigned operator >> (const sc_unsigned& u, unsigned long v); + inline sc_unsigned operator >> (const sc_unsigned& u, int v); + inline sc_unsigned operator >> (const sc_unsigned& u, unsigned int v); + + sc_unsigned operator >> ( const sc_unsigned& , const sc_uint_base& ); + sc_unsigned operator >> ( const sc_unsigned&, const sc_int_base& ); + + // Unary arithmetic operators + sc_unsigned operator + (const sc_unsigned& u); + sc_signed operator - (const sc_unsigned& u); + + // LOGICAL OPERATORS: + + // Logical EQUAL operators: + + bool operator == (const sc_unsigned& u, const sc_signed& v); + bool operator == (const sc_signed& u, const sc_unsigned& v); + + bool operator == (const sc_unsigned& u, const sc_unsigned& v); + bool operator == (const sc_unsigned& u, int64 v); + bool operator == (const sc_unsigned& u, uint64 v); + bool operator == (const sc_unsigned& u, long v); + bool operator == (const sc_unsigned& u, unsigned long v); + inline bool operator == (const sc_unsigned& u, int v); + inline bool operator == (const sc_unsigned& u, unsigned int v); + + bool operator == (int64 u, const sc_unsigned& v); + bool operator == (uint64 u, const sc_unsigned& v); + bool operator == (long u, const sc_unsigned& v); + bool operator == (unsigned long u, const sc_unsigned& v); + inline bool operator == (int u, const sc_unsigned& v); + inline bool operator == (unsigned int u, const sc_unsigned& v) ; + + bool operator == (const sc_unsigned& u, const sc_uint_base& v); + bool operator == (const sc_unsigned& u, const sc_int_base& v); + bool operator == (const sc_uint_base& u, const sc_unsigned& v); + bool operator == (const sc_int_base& u, const sc_unsigned& v); + + // Logical NOT_EQUAL operators: + + bool operator != (const sc_unsigned& u, const sc_signed& v); + bool operator != (const sc_signed& u, const sc_unsigned& v); + + bool operator != (const sc_unsigned& u, const sc_unsigned& v); + bool operator != (const sc_unsigned& u, int64 v); + bool operator != (const sc_unsigned& u, uint64 v); + bool operator != (const sc_unsigned& u, long v); + bool operator != (const sc_unsigned& u, unsigned long v); + inline bool operator != (const sc_unsigned& u, int v); + inline bool operator != (const sc_unsigned& u, unsigned int v); + + bool operator != (int64 u, const sc_unsigned& v); + bool operator != (uint64 u, const sc_unsigned& v); + bool operator != (long u, const sc_unsigned& v); + bool operator != (unsigned long u, const sc_unsigned& v); + inline bool operator != (int u, const sc_unsigned& v); + inline bool operator != (unsigned int u, const sc_unsigned& v); + + bool operator != (const sc_unsigned& u, const sc_uint_base& v); + bool operator != (const sc_unsigned& u, const sc_int_base& v); + bool operator != (const sc_uint_base& u, const sc_unsigned& v); + bool operator != (const sc_int_base& u, const sc_unsigned& v); + + // Logical LESS_THAN operators: + + bool operator < (const sc_unsigned& u, const sc_signed& v); + bool operator < (const sc_signed& u, const sc_unsigned& v); + + bool operator < (const sc_unsigned& u, const sc_unsigned& v); + bool operator < (const sc_unsigned& u, int64 v); + bool operator < (const sc_unsigned& u, uint64 v); + bool operator < (const sc_unsigned& u, long v); + bool operator < (const sc_unsigned& u, unsigned long v); + inline bool operator < (const sc_unsigned& u, int v); + inline bool operator < (const sc_unsigned& u, unsigned int v); + + bool operator < (int64 u, const sc_unsigned& v); + bool operator < (uint64 u, const sc_unsigned& v); + bool operator < (long u, const sc_unsigned& v); + bool operator < (unsigned long u, const sc_unsigned& v); + inline bool operator < (int u, const sc_unsigned& v); + inline bool operator < (unsigned int u, const sc_unsigned& v); + + bool operator < (const sc_unsigned& u, const sc_uint_base& v); + bool operator < (const sc_unsigned& u, const sc_int_base& v); + bool operator < (const sc_uint_base& u, const sc_unsigned& v); + bool operator < (const sc_int_base& u, const sc_unsigned& v); + + // Logical LESS_THAN_AND_EQUAL operators: + + bool operator <= (const sc_unsigned& u, const sc_signed& v); + bool operator <= (const sc_signed& u, const sc_unsigned& v); + + bool operator <= (const sc_unsigned& u, const sc_unsigned& v); + bool operator <= (const sc_unsigned& u, int64 v); + bool operator <= (const sc_unsigned& u, uint64 v); + bool operator <= (const sc_unsigned& u, long v); + bool operator <= (const sc_unsigned& u, unsigned long v); + inline bool operator <= (const sc_unsigned& u, int v); + inline bool operator <= (const sc_unsigned& u, unsigned int v); + + bool operator <= (int64 u, const sc_unsigned& v); + bool operator <= (uint64 u, const sc_unsigned& v); + bool operator <= (long u, const sc_unsigned& v); + bool operator <= (unsigned long u, const sc_unsigned& v); + inline bool operator <= (int u, const sc_unsigned& v); + inline bool operator <= (unsigned int u, const sc_unsigned& v); + + bool operator <= (const sc_unsigned& u, const sc_uint_base& v); + bool operator <= (const sc_unsigned& u, const sc_int_base& v); + bool operator <= (const sc_uint_base& u, const sc_unsigned& v); + bool operator <= (const sc_int_base& u, const sc_unsigned& v); + + // Logical GREATER_THAN operators: + + bool operator > (const sc_unsigned& u, const sc_signed& v); + bool operator > (const sc_signed& u, const sc_unsigned& v); + + bool operator > (const sc_unsigned& u, const sc_unsigned& v); + bool operator > (const sc_unsigned& u, int64 v); + bool operator > (const sc_unsigned& u, uint64 v); + bool operator > (const sc_unsigned& u, long v); + bool operator > (const sc_unsigned& u, unsigned long v); + inline bool operator > (const sc_unsigned& u, int v); + inline bool operator > (const sc_unsigned& u, unsigned int v); + + bool operator > (int64 u, const sc_unsigned& v); + bool operator > (uint64 u, const sc_unsigned& v); + bool operator > (long u, const sc_unsigned& v); + bool operator > (unsigned long u, const sc_unsigned& v); + inline bool operator > (int u, const sc_unsigned& v); + inline bool operator > (unsigned int u, const sc_unsigned& v); + + bool operator > (const sc_unsigned& u, const sc_uint_base& v); + bool operator > (const sc_unsigned& u, const sc_int_base& v); + bool operator > (const sc_uint_base& u, const sc_unsigned& v); + bool operator > (const sc_int_base& u, const sc_unsigned& v); + + // Logical GREATER_THAN_AND_EQUAL operators: + + bool operator >= (const sc_unsigned& u, const sc_signed& v); + bool operator >= (const sc_signed& u, const sc_unsigned& v); + + bool operator >= (const sc_unsigned& u, const sc_unsigned& v); + bool operator >= (const sc_unsigned& u, int64 v); + bool operator >= (const sc_unsigned& u, uint64 v); + bool operator >= (const sc_unsigned& u, long v); + bool operator >= (const sc_unsigned& u, unsigned long v); + inline bool operator >= (const sc_unsigned& u, int v); + inline bool operator >= (const sc_unsigned& u, unsigned int v); + + bool operator >= (int64 u, const sc_unsigned& v); + bool operator >= (uint64 u, const sc_unsigned& v); + bool operator >= (long u, const sc_unsigned& v); + bool operator >= (unsigned long u, const sc_unsigned& v); + inline bool operator >= (int u, const sc_unsigned& v); + inline bool operator >= (unsigned int u, const sc_unsigned& v); + + bool operator >= (const sc_unsigned& u, const sc_uint_base& v); + bool operator >= (const sc_unsigned& u, const sc_int_base& v); + bool operator >= (const sc_uint_base& u, const sc_unsigned& v); + bool operator >= (const sc_int_base& u, const sc_unsigned& v); + + // Bitwise NOT operator (unary). + sc_unsigned operator ~ (const sc_unsigned& u); + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned_bitref_r +// +// Proxy class for sc_unsigned bit selection (r-value only). +// ---------------------------------------------------------------------------- + +class sc_unsigned_bitref_r : public sc_value_base +{ + friend class sc_unsigned; + +protected: + + // construction and initialization: + + sc_unsigned_bitref_r() : sc_value_base(), m_index(0), m_obj_p(0) + {} + + void initialize( const sc_unsigned* obj_p, int index_ ) + { + m_obj_p = CCAST<sc_unsigned*>( obj_p ); + m_index = index_; + } + +public: + + // destructor + + virtual ~sc_unsigned_bitref_r() + {} + + // copy constructor + + sc_unsigned_bitref_r( const sc_unsigned_bitref_r& a ) + : sc_value_base(a), m_index( a.m_index ), m_obj_p( a.m_obj_p ) + {} + + // capacity + + int length() const + { return 1; } + + + // implicit conversion to bool + + operator uint64 () const; + bool operator ! () const; + bool operator ~ () const; + + + // explicit conversions + + uint64 value() const + { return operator uint64(); } + + bool to_bool() const + { return operator uint64(); } + + + // concatenation support + + virtual int concat_length(bool* xz_present_p) const + { if ( xz_present_p ) *xz_present_p = false; return 1; } + virtual uint64 concat_get_uint64() const + { return (uint64)operator uint64(); } + virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const + { + int bit_mask = 1 << (low_i % BITS_PER_DIGIT); + int word_i = low_i / BITS_PER_DIGIT; + dst_p[word_i] &= ~bit_mask; + return false; + } + virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const + { + int bit_mask = 1 << (low_i % BITS_PER_DIGIT); + bool result; // True if non-zero. + int word_i = low_i / BITS_PER_DIGIT; + if ( operator uint64() ) + { + dst_p[word_i] |= bit_mask; + result = true; + } + else + { + dst_p[word_i] &= ~bit_mask; + result = false; + } + return result; + } + + // other methods + + void print( ::std::ostream& os = ::std::cout ) const + { os << to_bool(); } + +protected: + + int m_index; + sc_unsigned* m_obj_p; + +private: + + // disabled + const sc_unsigned_bitref_r& operator = ( const sc_unsigned_bitref_r& ); +}; + + + +inline +::std::ostream& +operator << ( ::std::ostream&, const sc_unsigned_bitref_r& ); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned_bitref +// +// Proxy class for sc_unsigned bit selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +class sc_unsigned_bitref + : public sc_unsigned_bitref_r +{ + friend class sc_unsigned; + friend class sc_core::sc_vpool<sc_unsigned_bitref>; + + +protected: // construction + + sc_unsigned_bitref() : sc_unsigned_bitref_r() + {} + +public: + + // copy constructor + + sc_unsigned_bitref( const sc_unsigned_bitref& a ) + : sc_unsigned_bitref_r( a ) + {} + + + // assignment operators + + const sc_unsigned_bitref& operator = ( const sc_unsigned_bitref_r& ); + const sc_unsigned_bitref& operator = ( const sc_unsigned_bitref& ); + const sc_unsigned_bitref& operator = ( bool ); + + const sc_unsigned_bitref& operator &= ( bool ); + const sc_unsigned_bitref& operator |= ( bool ); + const sc_unsigned_bitref& operator ^= ( bool ); + + // concatenation methods + + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed& src, int low_i); + virtual void concat_set(const sc_unsigned& src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + + // other methods + + void scan( ::std::istream& is = ::std::cin ); + +protected: + static sc_core::sc_vpool<sc_unsigned_bitref> m_pool; +}; + + + +inline +::std::istream& +operator >> ( ::std::istream&, sc_unsigned_bitref& ); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned_subref_r +// +// Proxy class for sc_unsigned part selection (r-value only). +// ---------------------------------------------------------------------------- + +class sc_unsigned_subref_r : public sc_value_base +{ + friend class sc_signed; + friend class sc_unsigned; + friend class sc_unsigned_signal; + +protected: + + // constructor + + sc_unsigned_subref_r() : sc_value_base(), m_left(0), m_obj_p(0), m_right(0) + {} + + void initialize( const sc_unsigned* obj_p, int left_, int right_ ) + { + m_obj_p = CCAST<sc_unsigned*>( obj_p ); + m_left = left_; + m_right = right_; + } + +public: + + // destructor + + virtual ~sc_unsigned_subref_r() + {} + + + // copy constructor + + sc_unsigned_subref_r( const sc_unsigned_subref_r& a ) + : sc_value_base(a), m_left( a.m_left ), m_obj_p( a.m_obj_p ), + m_right( a.m_right ) + {} + + + // capacity + + int length() const + { return m_left >= m_right ? (m_left-m_right+1) : (m_right-m_left+1 ); } + + + // implicit conversion to sc_unsigned + + operator sc_unsigned () const; + + + // explicit conversions + + int to_int() const; + unsigned int to_uint() const; + long to_long() const; + unsigned long to_ulong() const; + int64 to_int64() const; + uint64 to_uint64() const; + double to_double() const; + + + // explicit conversion to character string + + const std::string to_string( sc_numrep numrep = SC_DEC ) const; + const std::string to_string( sc_numrep numrep, bool w_prefix ) const; + + + // concatenation support + + virtual int concat_length(bool* xz_present_p) const + { + if ( xz_present_p ) *xz_present_p = false; + return m_left - m_right + 1; + } + virtual uint64 concat_get_uint64() const; + virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const; + virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const; + + // reduce methods + + bool and_reduce() const; + bool nand_reduce() const; + bool or_reduce() const; + bool nor_reduce() const; + bool xor_reduce() const ; + bool xnor_reduce() const; + + // other methods + + void print( ::std::ostream& os = ::std::cout ) const + { os << to_string(sc_io_base(os,SC_DEC),sc_io_show_base(os)); } + +protected: + + int m_left; // Left-most bit in this part selection. + sc_unsigned* m_obj_p; // Target of this part selection. + int m_right; // Right-most bit in this part selection. + +private: + + // disabled + const sc_unsigned_subref_r& operator = ( const sc_unsigned_subref_r& ); +}; + + + +inline +::std::ostream& +operator << ( ::std::ostream&, const sc_unsigned_subref_r& ); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned_subref +// +// Proxy class for sc_unsigned part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +class sc_unsigned_subref + : public sc_unsigned_subref_r +{ + friend class sc_unsigned; + friend class sc_core::sc_vpool<sc_unsigned_subref>; + + + // constructor + +protected: + sc_unsigned_subref() : sc_unsigned_subref_r() + {} + +public: + + // copy constructor + + sc_unsigned_subref( const sc_unsigned_subref& a ) + : sc_unsigned_subref_r( a ) + {} + + // assignment operators + + const sc_unsigned_subref& operator = ( const sc_unsigned_subref_r& a ); + const sc_unsigned_subref& operator = ( const sc_unsigned_subref& a ); + const sc_unsigned_subref& operator = ( const sc_unsigned& a ); + + template<class T> + const sc_unsigned_subref& operator = ( const sc_generic_base<T>& a ); + const sc_unsigned_subref& operator = ( const sc_signed_subref_r& a ); + const sc_unsigned_subref& operator = ( const sc_signed& a ); + + const sc_unsigned_subref& operator = ( const char* a ); + const sc_unsigned_subref& operator = ( unsigned long a ); + const sc_unsigned_subref& operator = ( long a ); + + const sc_unsigned_subref& operator = ( unsigned int a ) + { return operator = ( (unsigned long) a ); } + + const sc_unsigned_subref& operator = ( int a ) + { return operator = ( (long) a ); } + + const sc_unsigned_subref& operator = ( uint64 a ); + const sc_unsigned_subref& operator = ( int64 a ); + const sc_unsigned_subref& operator = ( double a ); + const sc_unsigned_subref& operator = ( const sc_int_base& a ); + const sc_unsigned_subref& operator = ( const sc_uint_base& a ); + + // concatenation methods + + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed& src, int low_i); + virtual void concat_set(const sc_unsigned& src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + // other methods + + void scan( ::std::istream& is = ::std::cin ); + +protected: + static sc_core::sc_vpool<sc_unsigned_subref> m_pool; +}; + + + +inline +::std::istream& +operator >> ( ::std::istream&, sc_unsigned_subref& ); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned +// +// Arbitrary precision unsigned number. +// ---------------------------------------------------------------------------- + +class sc_unsigned : public sc_value_base +{ + friend class sc_concatref; + friend class sc_unsigned_bitref_r; + friend class sc_unsigned_bitref; + friend class sc_unsigned_subref_r; + friend class sc_unsigned_subref; + friend class sc_signed; + friend class sc_signed_subref; + friend class sc_signed_subref_r; + + // Needed for types using sc_unsigned. + typedef bool elemtype; + +public: + + // constructors + + explicit sc_unsigned( int nb = sc_length_param().len() ); + sc_unsigned( const sc_unsigned& v ); + sc_unsigned( const sc_signed& v ); + template<class T> + explicit sc_unsigned( const sc_generic_base<T>& v ); + explicit sc_unsigned( const sc_bv_base& v ); + explicit sc_unsigned( const sc_lv_base& v ); + explicit sc_unsigned( const sc_int_subref_r& v ); + explicit sc_unsigned( const sc_uint_subref_r& v ); + explicit sc_unsigned( const sc_signed_subref_r& v ); + explicit sc_unsigned( const sc_unsigned_subref_r& v ); + + + + // assignment operators + + const sc_unsigned& operator = (const sc_unsigned& v); + const sc_unsigned& operator = (const sc_unsigned_subref_r& a ); + + template<class T> + const sc_unsigned& operator = ( const sc_generic_base<T>& a ) + { a->to_sc_unsigned(*this); return *this; } + + const sc_unsigned& operator = (const sc_signed& v); + const sc_unsigned& operator = (const sc_signed_subref_r& a ); + + const sc_unsigned& operator = ( const char* v); + const sc_unsigned& operator = ( int64 v); + const sc_unsigned& operator = ( uint64 v); + const sc_unsigned& operator = ( long v); + const sc_unsigned& operator = ( unsigned long v); + + const sc_unsigned& operator = ( int v) + { return operator=((long) v); } + + const sc_unsigned& operator = ( unsigned int v) + { return operator=((unsigned long) v); } + + const sc_unsigned& operator = ( double v); + const sc_unsigned& operator = ( const sc_int_base& v); + const sc_unsigned& operator = ( const sc_uint_base& v); + + const sc_unsigned& operator = ( const sc_bv_base& ); + const sc_unsigned& operator = ( const sc_lv_base& ); + +#ifdef SC_INCLUDE_FX + const sc_unsigned& operator = ( const sc_fxval& ); + const sc_unsigned& operator = ( const sc_fxval_fast& ); + const sc_unsigned& operator = ( const sc_fxnum& ); + const sc_unsigned& operator = ( const sc_fxnum_fast& ); +#endif + + + // destructor + + virtual ~sc_unsigned() + { +# ifndef SC_MAX_NBITS + delete [] digit; +# endif + } + + // Concatenation support: + + sc_digit* get_raw() const { return digit; } + virtual int concat_length(bool* xz_present_p) const + { if ( xz_present_p ) *xz_present_p = false; return nbits-1; } + virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const; + virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const; + virtual uint64 concat_get_uint64() const; + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed& src, int low_i); + virtual void concat_set(const sc_unsigned& src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + // Increment operators. + + sc_unsigned& operator ++ (); + const sc_unsigned operator ++ (int); + + // Decrement operators. + + sc_unsigned& operator -- (); + const sc_unsigned operator -- (int); + + + // bit selection + + inline void check_index( int i ) const + { if ( (i < 0) || (i >= nbits-1) ) invalid_index(i); } + + void invalid_index( int i ) const; + + sc_unsigned_bitref& operator [] ( int i ) + { + check_index(i); + sc_unsigned_bitref* result_p = + sc_unsigned_bitref::m_pool.allocate(); + result_p->initialize( this, i ); + return *result_p; + } + + const sc_unsigned_bitref_r& operator [] ( int i ) const + { + check_index(i); + sc_unsigned_bitref* result_p = + sc_unsigned_bitref::m_pool.allocate(); + result_p->initialize( this, i ); + return *result_p; + } + + sc_unsigned_bitref& bit( int i ) + { + check_index(i); + sc_unsigned_bitref* result_p = + sc_unsigned_bitref::m_pool.allocate(); + result_p->initialize( this, i ); + return *result_p; + } + + const sc_unsigned_bitref_r& bit( int i ) const + { + check_index(i); + sc_unsigned_bitref* result_p = + sc_unsigned_bitref::m_pool.allocate(); + result_p->initialize( this, i ); + return *result_p; + } + + + // part selection + + // Subref operators. Help access the range of bits from the ith to + // jth. These indices have arbitrary precedence with respect to each + // other, i.e., we can have i <= j or i > j. Note the equivalence + // between range(i, j) and operator (i, j). Also note that + // operator (i, i) returns an unsigned number that corresponds to the + // bit operator [i], so these two forms are not the same. + + inline void check_range( int l, int r ) const + { + if ( l < r ) + { + if ( (l < 0) || (r >= nbits-1) ) invalid_range(l,r); + } + else + { + if ( (r < 0) || (l >= nbits-1) ) invalid_range(l,r); + } + } + + void invalid_range( int l, int r ) const; + + sc_unsigned_subref& range( int i, int j ) + { + check_range(i,j); + sc_unsigned_subref* result_p = + sc_unsigned_subref::m_pool.allocate(); + result_p->initialize( this, i, j ); + return *result_p; + } + + const sc_unsigned_subref_r& range( int i, int j ) const + { + check_range(i,j); + sc_unsigned_subref* result_p = + sc_unsigned_subref::m_pool.allocate(); + result_p->initialize( this, i, j ); + return *result_p; + } + + sc_unsigned_subref& operator () ( int i, int j ) + { + check_range(i,j); + sc_unsigned_subref* result_p = + sc_unsigned_subref::m_pool.allocate(); + result_p->initialize( this, i, j ); + return *result_p; + } + + const sc_unsigned_subref_r& operator () ( int i, int j ) const + { + check_range(i,j); + sc_unsigned_subref* result_p = + sc_unsigned_subref::m_pool.allocate(); + result_p->initialize( this, i, j ); + return *result_p; + } + + // explicit conversions + + int to_int() const; + unsigned int to_uint() const; + long to_long() const; + unsigned long to_ulong() const; + int64 to_int64() const; + uint64 to_uint64() const; + double to_double() const; + +#ifdef SC_DT_DEPRECATED + int to_signed() const + { return to_int(); } + + unsigned int to_unsigned() const + { return to_uint(); } +#endif + + // explicit conversion to character string + + const std::string to_string( sc_numrep numrep = SC_DEC ) const; + const std::string to_string( sc_numrep numrep, bool w_prefix ) const; + + // Print functions. dump prints the internals of the class. + + void print( ::std::ostream& os = ::std::cout ) const + { os << to_string(sc_io_base(os,SC_DEC),sc_io_show_base(os)); } + + void scan( ::std::istream& is = ::std::cin ); + + void dump( ::std::ostream& os = ::std::cout ) const; + + + // Functions to find various properties. + int length() const { return nbits - 1; } // Bit width. + bool iszero() const; // Is the number zero? + bool sign() const { return 0; } // Sign. + + // reduce methods + + bool and_reduce() const; + + bool nand_reduce() const + { return ( ! and_reduce() ); } + + bool or_reduce() const; + + bool nor_reduce() const + { return ( ! or_reduce() ); } + + bool xor_reduce() const; + + bool xnor_reduce() const + { return ( ! xor_reduce() ); } + + + // Functions to access individual bits. + bool test(int i) const; // Is the ith bit 0 or 1? + void set(int i); // Set the ith bit to 1. + void clear(int i); // Set the ith bit to 0. + void set(int i, bool v) // Set the ith bit to v. + { if (v) set(i); else clear(i); } + void invert(int i) // Negate the ith bit. + { if (test(i)) clear(i); else set(i); } + + // Make the number equal to its mirror image. + void reverse(); + + // Get/set a packed bit representation of the number. + void get_packed_rep(sc_digit *buf) const; + void set_packed_rep(sc_digit *buf); + + /* + The comparison of the old and new semantics are as follows: + + Let s = sc_signed, + u = sc_unsigned, + un = { uint64, unsigned long, unsigned int }, + sn = { int64, long, int, char* }, and + OP = { +, -, *, /, % }. + + Old semantics: New semantics: + u OP u -> u u OP u -> u + s OP u -> u s OP u -> s + u OP s -> u u OP s -> s + s OP s -> s s OP s -> s + + u OP un = un OP u -> u u OP un = un OP u -> u + u OP sn = sn OP u -> u u OP sn = sn OP u -> s + + s OP un = un OP s -> s s OP un = un OP s -> s + s OP sn = sn OP s -> s s OP sn = sn OP s -> s + + In the new semantics, the result is u if both operands are u; the + result is s otherwise. The only exception is subtraction. The result + of a subtraction is always s. + + The old semantics is like C/C++ semantics on integer types; the + new semantics is due to the VSIA C/C++ data types standard. + */ + + // ARITHMETIC OPERATORS: + + // ADDition operators: + + friend sc_signed operator + (const sc_unsigned& u, const sc_signed& v); + friend sc_signed operator + (const sc_signed& u, const sc_unsigned& v); + + friend sc_unsigned operator + (const sc_unsigned& u, const sc_unsigned& v); + friend sc_signed operator + (const sc_unsigned& u, int64 v); + friend sc_unsigned operator + (const sc_unsigned& u, uint64 v); + friend sc_signed operator + (const sc_unsigned& u, long v); + friend sc_unsigned operator + (const sc_unsigned& u, unsigned long v); + friend sc_signed operator + (const sc_unsigned& u, int v); + friend sc_unsigned operator + (const sc_unsigned& u, unsigned int v) + { return operator+(u, (unsigned long) v); } + + friend sc_signed operator + (int64 u, const sc_unsigned& v); + friend sc_unsigned operator + (uint64 u, const sc_unsigned& v); + friend sc_signed operator + (long u, const sc_unsigned& v); + friend sc_unsigned operator + (unsigned long u, const sc_unsigned& v); + friend sc_signed operator + (int u, const sc_unsigned& v); + friend sc_unsigned operator + (unsigned int u, const sc_unsigned& v) + { return operator+((unsigned long) u, v); } + + const sc_unsigned& operator += (const sc_signed& v); + const sc_unsigned& operator += (const sc_unsigned& v); + const sc_unsigned& operator += (int64 v); + const sc_unsigned& operator += (uint64 v); + const sc_unsigned& operator += (long v); + const sc_unsigned& operator += (unsigned long v); + const sc_unsigned& operator += (int v) + { return operator+=((long) v); } + const sc_unsigned& operator += (unsigned int v) + { return operator+=((unsigned long) v); } + + friend sc_unsigned operator + (const sc_unsigned& u, const sc_uint_base& v); + friend sc_signed operator + (const sc_unsigned& u, const sc_int_base& v); + friend sc_unsigned operator + (const sc_uint_base& u, const sc_unsigned& v); + friend sc_signed operator + (const sc_int_base& u, const sc_unsigned& v); + const sc_unsigned& operator += (const sc_int_base& v); + const sc_unsigned& operator += (const sc_uint_base& v); + + // SUBtraction operators: + + friend sc_signed operator - (const sc_unsigned& u, const sc_signed& v); + friend sc_signed operator - (const sc_signed& u, const sc_unsigned& v); + + friend sc_signed operator - (const sc_unsigned& u, const sc_unsigned& v); + friend sc_signed operator - (const sc_unsigned& u, int64 v); + friend sc_signed operator - (const sc_unsigned& u, uint64 v); + friend sc_signed operator - (const sc_unsigned& u, long v); + friend sc_signed operator - (const sc_unsigned& u, unsigned long v); + friend sc_signed operator - (const sc_unsigned& u, int v); + friend sc_signed operator - (const sc_unsigned& u, unsigned int v); + + friend sc_signed operator - (int64 u, const sc_unsigned& v); + friend sc_signed operator - (uint64 u, const sc_unsigned& v); + friend sc_signed operator - (long u, const sc_unsigned& v); + friend sc_signed operator - (unsigned long u, const sc_unsigned& v); + friend sc_signed operator - (int u, const sc_unsigned& v); + friend sc_signed operator - (unsigned int u, const sc_unsigned& v); + + const sc_unsigned& operator -= (const sc_signed& v); + const sc_unsigned& operator -= (const sc_unsigned& v); + const sc_unsigned& operator -= (int64 v); + const sc_unsigned& operator -= (uint64 v); + const sc_unsigned& operator -= (long v); + const sc_unsigned& operator -= (unsigned long v); + const sc_unsigned& operator -= (int v) + { return operator-=((long) v); } + const sc_unsigned& operator -= (unsigned int v) + { return operator-=((unsigned long) v); } + + friend sc_signed operator - (const sc_unsigned& u, const sc_uint_base& v); + friend sc_signed operator - (const sc_unsigned& u, const sc_int_base& v); + friend sc_signed operator - (const sc_uint_base& u, const sc_unsigned& v); + friend sc_signed operator - (const sc_int_base& u, const sc_unsigned& v); + const sc_unsigned& operator -= (const sc_int_base& v); + const sc_unsigned& operator -= (const sc_uint_base& v); + + // MULtiplication operators: + + friend sc_signed operator * (const sc_unsigned& u, const sc_signed& v); + friend sc_signed operator * (const sc_signed& u, const sc_unsigned& v); + + friend sc_unsigned operator * (const sc_unsigned& u, const sc_unsigned& v); + friend sc_signed operator * (const sc_unsigned& u, int64 v); + friend sc_unsigned operator * (const sc_unsigned& u, uint64 v); + friend sc_signed operator * (const sc_unsigned& u, long v); + friend sc_unsigned operator * (const sc_unsigned& u, unsigned long v); + friend sc_signed operator * (const sc_unsigned& u, int v); + friend sc_unsigned operator * (const sc_unsigned& u, unsigned int v) + { return operator*(u, (unsigned long) v); } + + friend sc_signed operator * (int64 u, const sc_unsigned& v); + friend sc_unsigned operator * (uint64 u, const sc_unsigned& v); + friend sc_signed operator * (long u, const sc_unsigned& v); + friend sc_unsigned operator * (unsigned long u, const sc_unsigned& v); + friend sc_signed operator * (int u, const sc_unsigned& v); + friend sc_unsigned operator * (unsigned int u, const sc_unsigned& v) + { return operator*((unsigned long) u, v); } + + const sc_unsigned& operator *= (const sc_signed& v); + const sc_unsigned& operator *= (const sc_unsigned& v); + const sc_unsigned& operator *= (int64 v); + const sc_unsigned& operator *= (uint64 v); + const sc_unsigned& operator *= (long v); + const sc_unsigned& operator *= (unsigned long v); + const sc_unsigned& operator *= (int v) + { return operator*=((long) v); } + const sc_unsigned& operator *= (unsigned int v) + { return operator*=((unsigned long) v); } + + friend sc_unsigned operator * (const sc_unsigned& u, const sc_uint_base& v); + friend sc_signed operator * (const sc_unsigned& u, const sc_int_base& v); + friend sc_unsigned operator * (const sc_uint_base& u, const sc_unsigned& v); + friend sc_signed operator * (const sc_int_base& u, const sc_unsigned& v); + const sc_unsigned& operator *= (const sc_int_base& v); + const sc_unsigned& operator *= (const sc_uint_base& v); + + // DIVision operators: + + friend sc_signed operator / (const sc_unsigned& u, const sc_signed& v); + friend sc_signed operator / (const sc_signed& u, const sc_unsigned& v); + + friend sc_unsigned operator / (const sc_unsigned& u, const sc_unsigned& v); + friend sc_signed operator / (const sc_unsigned& u, int64 v); + friend sc_unsigned operator / (const sc_unsigned& u, uint64 v); + friend sc_signed operator / (const sc_unsigned& u, long v); + friend sc_unsigned operator / (const sc_unsigned& u, unsigned long v); + friend sc_signed operator / (const sc_unsigned& u, int v); + friend sc_unsigned operator / (const sc_unsigned& u, unsigned int v) + { return operator/(u, (unsigned long) v); } + + friend sc_signed operator / (int64 u, const sc_unsigned& v); + friend sc_unsigned operator / (uint64 u, const sc_unsigned& v); + friend sc_signed operator / (long u, const sc_unsigned& v); + friend sc_unsigned operator / (unsigned long u, const sc_unsigned& v); + friend sc_signed operator / (int u, const sc_unsigned& v); + friend sc_unsigned operator / (unsigned int u, const sc_unsigned& v) + { return operator/((unsigned long) u, v); } + + const sc_unsigned& operator /= (const sc_signed& v); + const sc_unsigned& operator /= (const sc_unsigned& v); + const sc_unsigned& operator /= (int64 v); + const sc_unsigned& operator /= (uint64 v); + const sc_unsigned& operator /= (long v); + const sc_unsigned& operator /= (unsigned long v); + const sc_unsigned& operator /= (int v) + { return operator/=((long) v); } + const sc_unsigned& operator /= (unsigned int v) + { return operator/=((unsigned long) v); } + + friend sc_unsigned operator / (const sc_unsigned& u, const sc_uint_base& v); + friend sc_signed operator / (const sc_unsigned& u, const sc_int_base& v); + friend sc_unsigned operator / (const sc_uint_base& u, const sc_unsigned& v); + friend sc_signed operator / (const sc_int_base& u, const sc_unsigned& v); + const sc_unsigned& operator /= (const sc_int_base& v); + const sc_unsigned& operator /= (const sc_uint_base& v); + + // MODulo operators: + + friend sc_signed operator % (const sc_unsigned& u, const sc_signed& v); + friend sc_signed operator % (const sc_signed& u, const sc_unsigned& v); + + friend sc_unsigned operator % (const sc_unsigned& u, const sc_unsigned& v); + friend sc_signed operator % (const sc_unsigned& u, int64 v); + friend sc_unsigned operator % (const sc_unsigned& u, uint64 v); + friend sc_signed operator % (const sc_unsigned& u, long v); + friend sc_unsigned operator % (const sc_unsigned& u, unsigned long v); + friend sc_signed operator % (const sc_unsigned& u, int v); + friend sc_unsigned operator % (const sc_unsigned& u, unsigned int v) + { return operator%(u, (unsigned long) v); } + + friend sc_signed operator % (int64 u, const sc_unsigned& v); + friend sc_unsigned operator % (uint64 u, const sc_unsigned& v); + friend sc_signed operator % (long u, const sc_unsigned& v); + friend sc_unsigned operator % (unsigned long u, const sc_unsigned& v); + friend sc_signed operator % (int u, const sc_unsigned& v); + friend sc_unsigned operator % (unsigned int u, const sc_unsigned& v) + { return operator%((unsigned long) u, v); } + + const sc_unsigned& operator %= (const sc_signed& v); + const sc_unsigned& operator %= (const sc_unsigned& v); + const sc_unsigned& operator %= (int64 v); + const sc_unsigned& operator %= (uint64 v); + const sc_unsigned& operator %= (long v); + const sc_unsigned& operator %= (unsigned long v); + const sc_unsigned& operator %= (int v) + { return operator%=((long) v); } + const sc_unsigned& operator %= (unsigned int v) + { return operator%=((unsigned long) v); } + + friend sc_unsigned operator % (const sc_unsigned& u, const sc_uint_base& v); + friend sc_signed operator % (const sc_unsigned& u, const sc_int_base& v); + friend sc_unsigned operator % (const sc_uint_base& u, const sc_unsigned& v); + friend sc_signed operator % (const sc_int_base& u, const sc_unsigned& v); + const sc_unsigned& operator %= (const sc_int_base& v); + const sc_unsigned& operator %= (const sc_uint_base& v); + + // BITWISE OPERATORS: + + // Bitwise AND operators: + + friend sc_signed operator & (const sc_unsigned& u, const sc_signed& v); + friend sc_signed operator & (const sc_signed& u, const sc_unsigned& v); + + friend sc_unsigned operator & (const sc_unsigned& u, const sc_unsigned& v); + friend sc_signed operator & (const sc_unsigned& u, int64 v); + friend sc_unsigned operator & (const sc_unsigned& u, uint64 v); + friend sc_signed operator & (const sc_unsigned& u, long v); + friend sc_unsigned operator & (const sc_unsigned& u, unsigned long v); + friend sc_signed operator & (const sc_unsigned& u, int v); + friend sc_unsigned operator & (const sc_unsigned& u, unsigned int v) + { return operator&(u, (unsigned long) v); } + + friend sc_signed operator & (int64 u, const sc_unsigned& v); + friend sc_unsigned operator & (uint64 u, const sc_unsigned& v); + friend sc_signed operator & (long u, const sc_unsigned& v); + friend sc_unsigned operator & (unsigned long u, const sc_unsigned& v); + friend sc_signed operator & (int u, const sc_unsigned& v); + friend sc_unsigned operator & (unsigned int u, const sc_unsigned& v) + { return operator&((unsigned long) u, v); } + + const sc_unsigned& operator &= (const sc_signed& v); + const sc_unsigned& operator &= (const sc_unsigned& v); + const sc_unsigned& operator &= (int64 v); + const sc_unsigned& operator &= (uint64 v); + const sc_unsigned& operator &= (long v); + const sc_unsigned& operator &= (unsigned long v); + const sc_unsigned& operator &= (int v) + { return operator&=((long) v); } + const sc_unsigned& operator &= (unsigned int v) + { return operator&=((unsigned long) v); } + + friend sc_unsigned operator & (const sc_unsigned& u, const sc_uint_base& v); + friend sc_signed operator & (const sc_unsigned& u, const sc_int_base& v); + friend sc_unsigned operator & (const sc_uint_base& u, const sc_unsigned& v); + friend sc_signed operator & (const sc_int_base& u, const sc_unsigned& v); + const sc_unsigned& operator &= (const sc_int_base& v); + const sc_unsigned& operator &= (const sc_uint_base& v); + + // Bitwise OR operators: + + friend sc_signed operator | (const sc_unsigned& u, const sc_signed& v); + friend sc_signed operator | (const sc_signed& u, const sc_unsigned& v); + + friend sc_unsigned operator | (const sc_unsigned& u, const sc_unsigned& v); + friend sc_signed operator | (const sc_unsigned& u, int64 v); + friend sc_unsigned operator | (const sc_unsigned& u, uint64 v); + friend sc_signed operator | (const sc_unsigned& u, long v); + friend sc_unsigned operator | (const sc_unsigned& u, unsigned long v); + friend sc_signed operator | (const sc_unsigned& u, int v); + friend sc_unsigned operator | (const sc_unsigned& u, unsigned int v) + { return operator|(u, (unsigned long) v); } + + friend sc_signed operator | (int64 u, const sc_unsigned& v); + friend sc_unsigned operator | (uint64 u, const sc_unsigned& v); + friend sc_signed operator | (long u, const sc_unsigned& v); + friend sc_unsigned operator | (unsigned long u, const sc_unsigned& v); + friend sc_signed operator | (int u, const sc_unsigned& v); + friend sc_unsigned operator | (unsigned int u, const sc_unsigned& v) + { return operator|((unsigned long) u, v); } + + const sc_unsigned& operator |= (const sc_signed& v); + const sc_unsigned& operator |= (const sc_unsigned& v); + const sc_unsigned& operator |= (int64 v); + const sc_unsigned& operator |= (uint64 v); + const sc_unsigned& operator |= (long v); + const sc_unsigned& operator |= (unsigned long v); + const sc_unsigned& operator |= (int v) + { return operator|=((long) v); } + const sc_unsigned& operator |= (unsigned int v) + { return operator|=((unsigned long) v); } + + friend sc_unsigned operator | (const sc_unsigned& u, const sc_uint_base& v); + friend sc_signed operator | (const sc_unsigned& u, const sc_int_base& v); + friend sc_unsigned operator | (const sc_uint_base& u, const sc_unsigned& v); + friend sc_signed operator | (const sc_int_base& u, const sc_unsigned& v); + const sc_unsigned& operator |= (const sc_int_base& v); + const sc_unsigned& operator |= (const sc_uint_base& v); + + // Bitwise XOR operators: + + friend sc_signed operator ^ (const sc_unsigned& u, const sc_signed& v); + friend sc_signed operator ^ (const sc_signed& u, const sc_unsigned& v); + + friend sc_unsigned operator ^ (const sc_unsigned& u, const sc_unsigned& v); + friend sc_signed operator ^ (const sc_unsigned& u, int64 v); + friend sc_unsigned operator ^ (const sc_unsigned& u, uint64 v); + friend sc_signed operator ^ (const sc_unsigned& u, long v); + friend sc_unsigned operator ^ (const sc_unsigned& u, unsigned long v); + friend sc_signed operator ^ (const sc_unsigned& u, int v); + friend sc_unsigned operator ^ (const sc_unsigned& u, unsigned int v) + { return operator^(u, (unsigned long) v); } + + friend sc_signed operator ^ (int64 u, const sc_unsigned& v); + friend sc_unsigned operator ^ (uint64 u, const sc_unsigned& v); + friend sc_signed operator ^ (long u, const sc_unsigned& v); + friend sc_unsigned operator ^ (unsigned long u, const sc_unsigned& v); + friend sc_signed operator ^ (int u, const sc_unsigned& v); + friend sc_unsigned operator ^ (unsigned int u, const sc_unsigned& v) + { return operator^((unsigned long) u, v); } + + const sc_unsigned& operator ^= (const sc_signed& v); + const sc_unsigned& operator ^= (const sc_unsigned& v); + const sc_unsigned& operator ^= (int64 v); + const sc_unsigned& operator ^= (uint64 v); + const sc_unsigned& operator ^= (long v); + const sc_unsigned& operator ^= (unsigned long v); + const sc_unsigned& operator ^= (int v) + { return operator^=((long) v); } + const sc_unsigned& operator ^= (unsigned int v) + { return operator^=((unsigned long) v); } + + friend sc_unsigned operator ^ (const sc_unsigned& u, const sc_uint_base& v); + friend sc_signed operator ^ (const sc_unsigned& u, const sc_int_base& v); + friend sc_unsigned operator ^ (const sc_uint_base& u, const sc_unsigned& v); + friend sc_signed operator ^ (const sc_int_base& u, const sc_unsigned& v); + const sc_unsigned& operator ^= (const sc_int_base& v); + const sc_unsigned& operator ^= (const sc_uint_base& v); + + // SHIFT OPERATORS: + + // LEFT SHIFT operators: + + friend sc_unsigned operator << (const sc_unsigned& u, const sc_signed& v); + friend sc_signed operator << (const sc_signed& u, const sc_unsigned& v); + + friend sc_unsigned operator << (const sc_unsigned& u, const sc_unsigned& v); + friend sc_unsigned operator << (const sc_unsigned& u, int64 v); + friend sc_unsigned operator << (const sc_unsigned& u, uint64 v); + friend sc_unsigned operator << (const sc_unsigned& u, long v); + friend sc_unsigned operator << (const sc_unsigned& u, unsigned long v); + friend sc_unsigned operator << (const sc_unsigned& u, int v) + { return operator<<(u, (long) v); } + friend sc_unsigned operator << (const sc_unsigned& u, unsigned int v) + { return operator<<(u, (unsigned long) v); } + + const sc_unsigned& operator <<= (const sc_signed& v); + const sc_unsigned& operator <<= (const sc_unsigned& v); + const sc_unsigned& operator <<= (int64 v); + const sc_unsigned& operator <<= (uint64 v); + const sc_unsigned& operator <<= (long v); + const sc_unsigned& operator <<= (unsigned long v); + const sc_unsigned& operator <<= (int v) + { return operator<<=((long) v); } + const sc_unsigned& operator <<= (unsigned int v) + { return operator<<=((unsigned long) v); } + + friend sc_unsigned operator << (const sc_unsigned& u, const sc_uint_base& v); + friend sc_unsigned operator << (const sc_unsigned& u, const sc_int_base& v); + const sc_unsigned& operator <<= (const sc_int_base& v); + const sc_unsigned& operator <<= (const sc_uint_base& v); + + // RIGHT SHIFT operators: + + friend sc_unsigned operator >> (const sc_unsigned& u, const sc_signed& v); + friend sc_signed operator >> (const sc_signed& u, const sc_unsigned& v); + + friend sc_unsigned operator >> (const sc_unsigned& u, const sc_unsigned& v); + friend sc_unsigned operator >> (const sc_unsigned& u, int64 v); + friend sc_unsigned operator >> (const sc_unsigned& u, uint64 v); + friend sc_unsigned operator >> (const sc_unsigned& u, long v); + friend sc_unsigned operator >> (const sc_unsigned& u, unsigned long v); + friend sc_unsigned operator >> (const sc_unsigned& u, int v) + { return operator>>(u, (long) v); } + friend sc_unsigned operator >> (const sc_unsigned& u, unsigned int v) + { return operator>>(u, (unsigned long) v); } + + const sc_unsigned& operator >>= (const sc_signed& v); + const sc_unsigned& operator >>= (const sc_unsigned& v); + const sc_unsigned& operator >>= (int64 v); + const sc_unsigned& operator >>= (uint64 v); + const sc_unsigned& operator >>= (long v); + const sc_unsigned& operator >>= (unsigned long v); + const sc_unsigned& operator >>= (int v) + { return operator>>=((long) v); } + const sc_unsigned& operator >>= (unsigned int v) + { return operator>>=((unsigned long) v); } + + friend sc_unsigned operator >> ( const sc_unsigned& , const sc_uint_base& ); + friend sc_unsigned operator >> ( const sc_unsigned&, const sc_int_base& ); + const sc_unsigned& operator >>= (const sc_int_base& v); + const sc_unsigned& operator >>= (const sc_uint_base& v); + + // Unary arithmetic operators + friend sc_unsigned operator + (const sc_unsigned& u); + friend sc_signed operator - (const sc_unsigned& u); + + // LOGICAL OPERATORS: + + // Logical EQUAL operators: + + friend bool operator == (const sc_unsigned& u, const sc_signed& v); + friend bool operator == (const sc_signed& u, const sc_unsigned& v); + + friend bool operator == (const sc_unsigned& u, const sc_unsigned& v); + friend bool operator == (const sc_unsigned& u, int64 v); + friend bool operator == (const sc_unsigned& u, uint64 v); + friend bool operator == (const sc_unsigned& u, long v); + friend bool operator == (const sc_unsigned& u, unsigned long v); + friend bool operator == (const sc_unsigned& u, int v) + { return operator==(u, (long) v); } + friend bool operator == (const sc_unsigned& u, unsigned int v) + { return operator==(u, (unsigned long) v); } + + friend bool operator == (int64 u, const sc_unsigned& v); + friend bool operator == (uint64 u, const sc_unsigned& v); + friend bool operator == (long u, const sc_unsigned& v); + friend bool operator == (unsigned long u, const sc_unsigned& v); + friend bool operator == (int u, const sc_unsigned& v) + { return operator==((long) u, v); } + friend bool operator == (unsigned int u, const sc_unsigned& v) + { return operator==((unsigned long) u, v); } + + friend bool operator == (const sc_unsigned& u, const sc_uint_base& v); + friend bool operator == (const sc_unsigned& u, const sc_int_base& v); + friend bool operator == (const sc_uint_base& u, const sc_unsigned& v); + friend bool operator == (const sc_int_base& u, const sc_unsigned& v); + + // Logical NOT_EQUAL operators: + + friend bool operator != (const sc_unsigned& u, const sc_signed& v); + friend bool operator != (const sc_signed& u, const sc_unsigned& v); + + friend bool operator != (const sc_unsigned& u, const sc_unsigned& v); + friend bool operator != (const sc_unsigned& u, int64 v); + friend bool operator != (const sc_unsigned& u, uint64 v); + friend bool operator != (const sc_unsigned& u, long v); + friend bool operator != (const sc_unsigned& u, unsigned long v); + friend bool operator != (const sc_unsigned& u, int v) + { return operator!=(u, (long) v); } + friend bool operator != (const sc_unsigned& u, unsigned int v) + { return operator!=(u, (unsigned long) v); } + + friend bool operator != (int64 u, const sc_unsigned& v); + friend bool operator != (uint64 u, const sc_unsigned& v); + friend bool operator != (long u, const sc_unsigned& v); + friend bool operator != (unsigned long u, const sc_unsigned& v); + friend bool operator != (int u, const sc_unsigned& v) + { return operator!=((long) u, v); } + friend bool operator != (unsigned int u, const sc_unsigned& v) + { return operator!=((unsigned long) u, v); } + + friend bool operator != (const sc_unsigned& u, const sc_uint_base& v); + friend bool operator != (const sc_unsigned& u, const sc_int_base& v); + friend bool operator != (const sc_uint_base& u, const sc_unsigned& v); + friend bool operator != (const sc_int_base& u, const sc_unsigned& v); + + // Logical LESS_THAN operators: + + friend bool operator < (const sc_unsigned& u, const sc_signed& v); + friend bool operator < (const sc_signed& u, const sc_unsigned& v); + + friend bool operator < (const sc_unsigned& u, const sc_unsigned& v); + friend bool operator < (const sc_unsigned& u, int64 v); + friend bool operator < (const sc_unsigned& u, uint64 v); + friend bool operator < (const sc_unsigned& u, long v); + friend bool operator < (const sc_unsigned& u, unsigned long v); + friend bool operator < (const sc_unsigned& u, int v) + { return operator<(u, (long) v); } + friend bool operator < (const sc_unsigned& u, unsigned int v) + { return operator<(u, (unsigned long) v); } + + friend bool operator < (int64 u, const sc_unsigned& v); + friend bool operator < (uint64 u, const sc_unsigned& v); + friend bool operator < (long u, const sc_unsigned& v); + friend bool operator < (unsigned long u, const sc_unsigned& v); + friend bool operator < (int u, const sc_unsigned& v) + { return operator<((long) u, v); } + friend bool operator < (unsigned int u, const sc_unsigned& v) + { return operator<((unsigned long) u, v); } + + friend bool operator < (const sc_unsigned& u, const sc_uint_base& v); + friend bool operator < (const sc_unsigned& u, const sc_int_base& v); + friend bool operator < (const sc_uint_base& u, const sc_unsigned& v); + friend bool operator < (const sc_int_base& u, const sc_unsigned& v); + + // Logical LESS_THAN_AND_EQUAL operators: + + friend bool operator <= (const sc_unsigned& u, const sc_signed& v); + friend bool operator <= (const sc_signed& u, const sc_unsigned& v); + + friend bool operator <= (const sc_unsigned& u, const sc_unsigned& v); + friend bool operator <= (const sc_unsigned& u, int64 v); + friend bool operator <= (const sc_unsigned& u, uint64 v); + friend bool operator <= (const sc_unsigned& u, long v); + friend bool operator <= (const sc_unsigned& u, unsigned long v); + friend bool operator <= (const sc_unsigned& u, int v) + { return operator<=(u, (long) v); } + friend bool operator <= (const sc_unsigned& u, unsigned int v) + { return operator<=(u, (unsigned long) v); } + + friend bool operator <= (int64 u, const sc_unsigned& v); + friend bool operator <= (uint64 u, const sc_unsigned& v); + friend bool operator <= (long u, const sc_unsigned& v); + friend bool operator <= (unsigned long u, const sc_unsigned& v); + friend bool operator <= (int u, const sc_unsigned& v) + { return operator<=((long) u, v); } + friend bool operator <= (unsigned int u, const sc_unsigned& v) + { return operator<=((unsigned long) u, v); } + + friend bool operator <= (const sc_unsigned& u, const sc_uint_base& v); + friend bool operator <= (const sc_unsigned& u, const sc_int_base& v); + friend bool operator <= (const sc_uint_base& u, const sc_unsigned& v); + friend bool operator <= (const sc_int_base& u, const sc_unsigned& v); + + // Logical GREATER_THAN operators: + + friend bool operator > (const sc_unsigned& u, const sc_signed& v); + friend bool operator > (const sc_signed& u, const sc_unsigned& v); + + friend bool operator > (const sc_unsigned& u, const sc_unsigned& v); + friend bool operator > (const sc_unsigned& u, int64 v); + friend bool operator > (const sc_unsigned& u, uint64 v); + friend bool operator > (const sc_unsigned& u, long v); + friend bool operator > (const sc_unsigned& u, unsigned long v); + friend bool operator > (const sc_unsigned& u, int v) + { return operator>(u, (long) v); } + friend bool operator > (const sc_unsigned& u, unsigned int v) + { return operator>(u, (unsigned long) v); } + + friend bool operator > (int64 u, const sc_unsigned& v); + friend bool operator > (uint64 u, const sc_unsigned& v); + friend bool operator > (long u, const sc_unsigned& v); + friend bool operator > (unsigned long u, const sc_unsigned& v); + friend bool operator > (int u, const sc_unsigned& v) + { return operator>((long) u, v); } + friend bool operator > (unsigned int u, const sc_unsigned& v) + { return operator>((unsigned long) u, v); } + + friend bool operator > (const sc_unsigned& u, const sc_uint_base& v); + friend bool operator > (const sc_unsigned& u, const sc_int_base& v); + friend bool operator > (const sc_uint_base& u, const sc_unsigned& v); + friend bool operator > (const sc_int_base& u, const sc_unsigned& v); + + // Logical GREATER_THAN_AND_EQUAL operators: + + friend bool operator >= (const sc_unsigned& u, const sc_signed& v); + friend bool operator >= (const sc_signed& u, const sc_unsigned& v); + + friend bool operator >= (const sc_unsigned& u, const sc_unsigned& v); + friend bool operator >= (const sc_unsigned& u, int64 v); + friend bool operator >= (const sc_unsigned& u, uint64 v); + friend bool operator >= (const sc_unsigned& u, long v); + friend bool operator >= (const sc_unsigned& u, unsigned long v); + friend bool operator >= (const sc_unsigned& u, int v) + { return operator>=(u, (long) v); } + friend bool operator >= (const sc_unsigned& u, unsigned int v) + { return operator>=(u, (unsigned long) v); } + + friend bool operator >= (int64 u, const sc_unsigned& v); + friend bool operator >= (uint64 u, const sc_unsigned& v); + friend bool operator >= (long u, const sc_unsigned& v); + friend bool operator >= (unsigned long u, const sc_unsigned& v); + friend bool operator >= (int u, const sc_unsigned& v) + { return operator>=((long) u, v); } + friend bool operator >= (unsigned int u, const sc_unsigned& v) + { return operator>=((unsigned long) u, v); } + + friend bool operator >= (const sc_unsigned& u, const sc_uint_base& v); + friend bool operator >= (const sc_unsigned& u, const sc_int_base& v); + friend bool operator >= (const sc_uint_base& u, const sc_unsigned& v); + friend bool operator >= (const sc_int_base& u, const sc_unsigned& v); + + // Bitwise NOT operator (unary). + friend sc_unsigned operator ~ (const sc_unsigned& u); + + // Helper functions. + friend int compare_unsigned(small_type us, + int unb, + int und, + const sc_digit *ud, + small_type vs, + int vnb, + int vnd, + const sc_digit *vd, + small_type if_u_signed, + small_type if_v_signed); + + friend sc_unsigned add_unsigned_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + small_type vs, + int vnb, + int vnd, + const sc_digit *vd); + + friend sc_unsigned sub_unsigned_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + small_type vs, + int vnb, + int vnd, + const sc_digit *vd); + + friend sc_unsigned mul_unsigned_friend(small_type s, + int unb, + int und, + const sc_digit *ud, + int vnb, + int vnd, + const sc_digit *vd); + + friend sc_unsigned div_unsigned_friend(small_type s, + int unb, + int und, + const sc_digit *ud, + int vnb, + int vnd, + const sc_digit *vd); + + friend sc_unsigned mod_unsigned_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + int vnb, + int vnd, + const sc_digit *vd); + + friend sc_unsigned and_unsigned_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + small_type vs, + int vnb, + int vnd, + const sc_digit *vd); + + friend sc_unsigned or_unsigned_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + small_type vs, + int vnb, + int vnd, + const sc_digit *vd); + + friend sc_unsigned xor_unsigned_friend(small_type us, + int unb, + int und, + const sc_digit *ud, + small_type vs, + int vnb, + int vnd, + const sc_digit *vd); + +public: + static sc_core::sc_vpool<sc_unsigned> m_pool; + +private: + + small_type sgn; // Shortened as s. + int nbits; // Shortened as nb. + int ndigits; // Shortened as nd. + +#ifdef SC_MAX_NBITS + sc_digit digit[DIV_CEIL(SC_MAX_NBITS)]; // Shortened as d. +#else + sc_digit *digit; // Shortened as d. +#endif + + // Private constructors: + + // Create a copy of v with sign s. + sc_unsigned(const sc_unsigned& v, small_type s); + sc_unsigned(const sc_signed& v, small_type s); + + // Create an unsigned number with the given attributes. + sc_unsigned(small_type s, int nb, int nd, + sc_digit *d, bool alloc = true); + + // Create an unsigned number using the bits u[l..r]. + sc_unsigned(const sc_signed* u, int l, int r); + sc_unsigned(const sc_unsigned* u, int l, int r); + + // Private member functions. The called functions are inline functions. + + small_type default_sign() const + { return SC_POS; } + + int num_bits(int nb) const { return nb + 1; } + + bool check_if_outside(int bit_num) const; + + void copy_digits(int nb, int nd, const sc_digit *d) + { copy_digits_unsigned(sgn, nbits, ndigits, digit, nb, nd, d); } + + void makezero() + { sgn = make_zero(ndigits, digit); } + + // Conversion functions between 2's complement (2C) and + // sign-magnitude (SM): + void convert_2C_to_SM() + { sgn = convert_unsigned_2C_to_SM(nbits, ndigits, digit); } + + void convert_SM_to_2C_to_SM() + { sgn = convert_unsigned_SM_to_2C_to_SM(sgn, nbits, ndigits, digit); } + + void convert_SM_to_2C() + { convert_unsigned_SM_to_2C(sgn, ndigits, digit); } + +}; + + + +inline +::std::ostream& +operator << ( ::std::ostream&, const sc_unsigned& ); + +inline +::std::istream& +operator >> ( ::std::istream&, sc_unsigned& ); + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned_bitref_r +// +// Proxy class for sc_unsigned bit selection (r-value only). +// ---------------------------------------------------------------------------- + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_unsigned_bitref_r& a ) +{ + a.print( os ); + return os; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned_bitref +// +// Proxy class for sc_unsigned bit selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +template<class T> +inline const sc_unsigned_subref& sc_unsigned_subref::operator = ( + const sc_generic_base<T>& a ) +{ + sc_unsigned temp( length() ); + a->to_sc_unsigned(temp); + return *this = temp; +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_unsigned_bitref& a ) +{ + a.scan( is ); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned_subref_r +// +// Proxy class for sc_unsigned part selection (r-value only). +// ---------------------------------------------------------------------------- + +// reduce methods + +inline bool sc_unsigned_subref_r::and_reduce() const +{ + const sc_unsigned* target_p = m_obj_p; + for ( int i = m_right; i <= m_left; i++ ) + if ( !target_p->test(i) ) return false; + return true; +} + +inline bool sc_unsigned_subref_r::nand_reduce() const +{ + return !and_reduce(); +} + +inline bool sc_unsigned_subref_r::or_reduce() const +{ + const sc_unsigned* target_p = m_obj_p; + for ( int i = m_right; i <= m_left; i++ ) + if ( target_p->test(i) ) return true; + return false; +} + +inline bool sc_unsigned_subref_r::nor_reduce() const +{ + return !or_reduce(); +} + +inline bool sc_unsigned_subref_r::xor_reduce() const +{ + int odd; + const sc_unsigned* target_p = m_obj_p; + odd = 0; + for ( int i = m_right; i <= m_left; i++ ) + if ( target_p->test(i) ) odd = ~odd; + return odd ? true : false; +} + +inline bool sc_unsigned_subref_r::xnor_reduce() const +{ + return !xor_reduce(); +} + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_unsigned_subref_r& a ) +{ + a.print( os ); + return os; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned_subref +// +// Proxy class for sc_unsigned part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +// assignment operators + +inline +const sc_unsigned_subref& +sc_unsigned_subref::operator = ( const char* a ) +{ + sc_unsigned aa( length() ); + return ( *this = aa = a ); +} + + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_unsigned_subref& a ) +{ + a.scan( is ); + return is; +} + + + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned +// +// Arbitrary precision signed number. +// ---------------------------------------------------------------------------- + +template<class T> +sc_unsigned::sc_unsigned( const sc_generic_base<T>& v ) +{ + int nb = v->length(); + sgn = default_sign(); + if( nb > 0 ) { + nbits = num_bits( nb ); + } else { + char msg[BUFSIZ]; + std::sprintf( msg, + "sc_unsigned( sc_generic_base<T> ) : nb = %d is not valid", nb); + SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg ); + } + ndigits = DIV_CEIL(nbits); +# ifdef SC_MAX_NBITS + test_bound(nb); +# else + digit = new sc_digit[ndigits]; +# endif + makezero(); + v->to_sc_unsigned(*this); +} + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_unsigned& a ) +{ + a.print( os ); + return os; +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_unsigned& a ) +{ + a.scan( is ); + return is; +} + + +} // namespace sc_dt + + +#endif diff --git a/ext/systemc/src/sysc/datatypes/int/sc_unsigned_bitref.inc b/ext/systemc/src/sysc/datatypes/int/sc_unsigned_bitref.inc new file mode 100644 index 000000000..c1ad02662 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_unsigned_bitref.inc @@ -0,0 +1,162 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_unsigned_bitref.h -- Proxy class that is declared in sc_unsigned.h. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned_bitref_r +// +// Proxy class for sc_unsigned bit selection (r-value only). +// ---------------------------------------------------------------------------- + +// implicit conversion to uint64 + +sc_unsigned_bitref_r::operator uint64 () const +{ + return m_obj_p->test( m_index ); +} + +bool +sc_unsigned_bitref_r::operator ! () const +{ + return ( ! m_obj_p->test( m_index ) ); +} + +bool +sc_unsigned_bitref_r::operator ~ () const +{ + return ( ! m_obj_p->test( m_index ) ); +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned_bitref +// +// Proxy class for sc_unsigned bit selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +// assignment operators + +const sc_unsigned_bitref& +sc_unsigned_bitref::operator = ( const sc_unsigned_bitref_r& b ) +{ + m_obj_p->set( m_index, (bool) b ); + return *this; +} + +const sc_unsigned_bitref& +sc_unsigned_bitref::operator = ( const sc_unsigned_bitref& b ) +{ + m_obj_p->set( m_index, (bool) b ); + return *this; +} + +const sc_unsigned_bitref& +sc_unsigned_bitref::operator = ( bool b ) +{ + m_obj_p->set( m_index, b ); + return *this; +} + + +const sc_unsigned_bitref& +sc_unsigned_bitref::operator &= ( bool b ) +{ + if( ! b ) { + m_obj_p->clear( m_index ); + } + return *this; +} + +const sc_unsigned_bitref& +sc_unsigned_bitref::operator |= ( bool b ) +{ + if( b ) { + m_obj_p->set( m_index ); + } + return *this; +} + +const sc_unsigned_bitref& +sc_unsigned_bitref::operator ^= ( bool b ) +{ + if( b ) { + m_obj_p->invert( m_index ); + } + return *this; +} + +// #### OPTIMIZE +void sc_unsigned_bitref::concat_set(int64 src, int low_i) +{ + bool value = 1 & ((low_i < 64) ? (src >> low_i) : (src >> 63)); + m_obj_p->set(low_i, value); +} + +void sc_unsigned_bitref::concat_set(const sc_signed& src, int low_i) +{ + if ( low_i < src.length() ) + m_obj_p->set(low_i, src.test(low_i)); + else + m_obj_p->set(low_i, src<0); +} + +void sc_unsigned_bitref::concat_set(const sc_unsigned& src, int low_i) +{ + if ( low_i < src.nbits ) + m_obj_p->set(low_i, src.test(low_i)); + else + m_obj_p->set(low_i, 0); +} + +void sc_unsigned_bitref::concat_set(uint64 src, int low_i) +{ + bool value = ((low_i < 64) ? (src >> low_i)&1 : 0); + m_obj_p->set(low_i, value); +} + +// other methods + +void +sc_unsigned_bitref::scan( ::std::istream& is ) +{ + bool b; + is >> b; + *this = b; +} + + +// End of file diff --git a/ext/systemc/src/sysc/datatypes/int/sc_unsigned_subref.inc b/ext/systemc/src/sysc/datatypes/int/sc_unsigned_subref.inc new file mode 100644 index 000000000..142d6b2dc --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/int/sc_unsigned_subref.inc @@ -0,0 +1,407 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_unsigned_subref.h -- Proxy class that is declared in sc_unsigned.h. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned_subref_r +// +// Proxy class for sc_unsigned part selection (r-value only). +// ---------------------------------------------------------------------------- + +// concatenation support + +uint64 sc_unsigned_subref_r::concat_get_uint64() const // #### Speed up! +{ + sc_unsigned a( m_obj_p, m_left, m_right ); + return a.to_uint64(); +} + + +bool sc_unsigned_subref_r::concat_get_ctrl(sc_digit* dst_p, int low_i) const + // #### Speed up! +{ + sc_unsigned a( m_obj_p, m_left, m_right ); + return a.concat_get_ctrl( dst_p, low_i ); +} + +bool sc_unsigned_subref_r::concat_get_data(sc_digit* dst_p, int low_i) const + // #### Speed up! +{ + sc_unsigned a( m_obj_p, m_left, m_right ); + return a.concat_get_data( dst_p, low_i ); +} + + +// implicit conversion to sc_unsigned + +sc_unsigned_subref_r::operator sc_unsigned () const +{ + return sc_unsigned( m_obj_p, m_left, m_right ); +} + + +// explicit conversions + +int +sc_unsigned_subref_r::to_int() const +{ + sc_unsigned a( m_obj_p, m_left, m_right ); + return a.to_int(); +} + +unsigned int +sc_unsigned_subref_r::to_uint() const +{ + sc_unsigned a( m_obj_p, m_left, m_right ); + return a.to_uint(); +} + +long +sc_unsigned_subref_r::to_long() const +{ + sc_unsigned a( m_obj_p, m_left, m_right ); + return a.to_long(); +} + +unsigned long +sc_unsigned_subref_r::to_ulong() const +{ + sc_unsigned a( m_obj_p, m_left, m_right ); + return a.to_ulong(); +} + +int64 +sc_unsigned_subref_r::to_int64() const +{ + sc_unsigned a( m_obj_p, m_left, m_right ); + return a.to_int64(); +} + +uint64 +sc_unsigned_subref_r::to_uint64() const +{ + sc_unsigned a( m_obj_p, m_left, m_right ); + return a.to_uint64(); +} + +double +sc_unsigned_subref_r::to_double() const +{ + sc_unsigned a( m_obj_p, m_left, m_right ); + return a.to_double(); +} + + +// explicit conversion to character string + +const std::string +sc_unsigned_subref_r::to_string( sc_numrep numrep ) const +{ + sc_unsigned a( length() ); + a = *this; + return a.to_string( numrep ); +} + +const std::string +sc_unsigned_subref_r::to_string( sc_numrep numrep, bool w_prefix ) const +{ + sc_unsigned a( length() ); + a = *this; + return a.to_string( numrep, w_prefix ); +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned_subref +// +// Proxy class for sc_unsigned part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +// assignment operators + +const sc_unsigned_subref& +sc_unsigned_subref::operator = ( const sc_unsigned_subref_r& a ) +{ + return operator = ( (sc_unsigned)( a ) ); +} + +const sc_unsigned_subref& +sc_unsigned_subref::operator = ( const sc_unsigned_subref& a ) +{ + if( this == &a ) { + return *this; + } + return operator = ( (sc_unsigned)( a ) ); +} + +const sc_unsigned_subref& +sc_unsigned_subref::operator = ( const sc_unsigned& v ) +{ + int i; + int l = sc_min( m_left, v.nbits - 1 + m_right ); + + for( i = m_right; i <= l; ++ i ) m_obj_p->set( i, v.test( i - m_right ) ); + for ( ; i <= m_left; i++ ) m_obj_p->set( i, v.test( l ) ); + return *this; +} + +const sc_unsigned_subref& +sc_unsigned_subref::operator = ( const sc_signed_subref_r& v ) +{ + return operator = ( (sc_unsigned)( v ) ); +} + +const sc_unsigned_subref& +sc_unsigned_subref::operator = ( const sc_signed& v ) +{ + int i; + int l = sc_min( m_left, v.nbits - 1 + m_right ); + + for( i = m_right; i <= l; ++ i ) m_obj_p->set( i, v.test( i - m_right ) ); + for ( ; i <= m_left; i++ ) m_obj_p->set( i, 0 ); + return *this; +} + +const sc_unsigned_subref& +sc_unsigned_subref::operator = ( unsigned long v ) +{ + for( int i = m_right; i <= m_left; ++ i ) { + m_obj_p->set( i, static_cast<bool>( v & 1 ) ); + v >>= 1; + } + return *this; +} + +const sc_unsigned_subref& +sc_unsigned_subref::operator = ( long v ) +{ + unsigned long v2 = (unsigned long) v; + for( int i = m_right; i <= m_left; ++ i ) { + m_obj_p->set( i, static_cast<bool>( v2 & 1 ) ); + v2 >>= 1; + } + return *this; +} + +const sc_unsigned_subref& +sc_unsigned_subref::operator = ( uint64 v ) +{ + for( int i = m_right; i <= m_left; ++ i ) { + m_obj_p->set( i, static_cast<bool>( v & 1 ) ); + v >>= 1; + } + return *this; +} + +const sc_unsigned_subref& +sc_unsigned_subref::operator = ( int64 v ) +{ + uint64 v2 = (uint64) v; + for( int i = m_right; i <= m_left; ++ i ) { + m_obj_p->set( i, static_cast<bool>( v2 & 1 ) ); + v2 >>= 1; + } + return *this; +} + +const sc_unsigned_subref& +sc_unsigned_subref::operator = ( double v ) +{ + is_bad_double(v); + + int nb = m_left - m_right + 1; + int nd = DIV_CEIL(nb); + +#ifdef SC_MAX_NBITS + sc_digit d[MAX_NDIGITS]; +#else + sc_digit *d = new sc_digit[nd]; +#endif + + if (v < 0) + v = -v; + + int i = 0; + + while (floor(v) && (i < nd)) { +#ifndef _WIN32 + d[i++] = (sc_digit) floor(remainder(v, DIGIT_RADIX)); +#else + d[i++] = (sc_digit) floor(fmod(v, DIGIT_RADIX)); +#endif + v /= DIGIT_RADIX; + } + + vec_zero(i, nd, d); + + sc_digit val = 1; // Bit value. + int j = 0; // Current digit in d. + + i = 0; // Current bit in d. + + while (i < nb) { + + m_obj_p->set(i + m_right, (bool) (d[j] & val)); + + ++i; + + if (i % BITS_PER_DIGIT == 0) { + val = 1; + ++j; + } + else + val <<= 1; + } + +#ifndef SC_MAX_NBITS + delete [] d; +#endif + + return *this; +} + +const sc_unsigned_subref& +sc_unsigned_subref::operator = ( const sc_int_base& a ) +{ + return operator = ( (int64) a ); +} + +const sc_unsigned_subref& +sc_unsigned_subref::operator = ( const sc_uint_base& a ) +{ + return operator = ( (uint64) a ); +} + +// concatenation methods + +void sc_unsigned_subref::concat_set( int64 src, int low_i ) +{ + int i; + int l; + bool sign = src < 0; + + if ( low_i < 64 ) + { + src = src >> low_i; + l = sc_min( m_left, (63-low_i) + m_right ); + for( i = m_right; i <= l; ++ i ) { + m_obj_p->set( i, src & 1 ); + src = src >> 1; + } + for ( ; i <= m_left; i++ ) m_obj_p->set(sign); + } + else + { + for( i = m_right; i <= m_left; ++ i ) m_obj_p->set(sign); + } +} + +void sc_unsigned_subref::concat_set( const sc_signed& src, int low_i ) +{ + int i; + int l; + int src_i; + bool sign = src.test(src.nbits-1); + l = src.nbits - (low_i+1); + if ( l >= 0 ) + { + src_i = low_i; + l = sc_min( m_left, l + m_right ); + for( i = m_right; i <= l; ++ i, src_i++ ) { + m_obj_p->set( i, src.test( src_i ) ); + } + for ( ; i <= m_left; i++ ) m_obj_p->set(i, sign); + } + else + { + for( i = m_right; i <= m_left; ++ i ) m_obj_p->set(i, sign); + } +} + +void sc_unsigned_subref::concat_set( const sc_unsigned& src, int low_i ) +{ + int i; + int l; + int src_i; + l = src.nbits - (low_i+2); + if ( l >= 0 ) + { + src_i = low_i; + l = sc_min( m_left, l + m_right ); + for( i = m_right; i <= l; ++ i, src_i++ ) { + m_obj_p->set( i, src.test( src_i ) ); + } + for ( ; i <= m_left; i++ ) m_obj_p->set(i, false); + } + else + { + for( i = m_right; i <= m_left; ++ i ) m_obj_p->set(i, false); + } +} + +void sc_unsigned_subref::concat_set( uint64 src, int low_i ) +{ + int i; + int l; + + if ( low_i < 64 ) + { + src = src >> low_i; + l = sc_min( m_left, (63-low_i) + m_right ); + for( i = m_right; i <= l; ++ i ) { + m_obj_p->set( i, src & 1 ); + src = src >> 1; + } + for ( ; i <= m_left; i++ ) m_obj_p->set(false); + } + else + { + for( i = m_right; i <= m_left; ++ i ) m_obj_p->set(false); + } +} +// other methods + +void +sc_unsigned_subref::scan( ::std::istream& is ) +{ + std::string s; + is >> s; + *this = s.c_str(); +} + + +// End of file diff --git a/ext/systemc/src/sysc/datatypes/misc/sc_concatref.cpp b/ext/systemc/src/sysc/datatypes/misc/sc_concatref.cpp new file mode 100644 index 000000000..566bee234 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/misc/sc_concatref.cpp @@ -0,0 +1,59 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_concatref.cpp -- Concatenation support. + + Original Author: Andy Goodrich, Forte Design Systems, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_concatref.cpp,v $ +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:54:01 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#include "sysc/datatypes/misc/sc_concatref.h" +#include "sysc/utils/sc_temporary.h" + +// STORAGE POOLS USED BY sc_concatref: + +namespace sc_dt { + sc_core::sc_vpool<sc_concat_bool> sc_concat_bool::m_pool(9); + sc_core::sc_vpool<sc_concatref> sc_concatref::m_pool(9); +} // namespace sc_dt + +namespace sc_core { + sc_byte_heap sc_temp_heap(0x300000); +} // namespace sc_core diff --git a/ext/systemc/src/sysc/datatypes/misc/sc_concatref.h b/ext/systemc/src/sysc/datatypes/misc/sc_concatref.h new file mode 100644 index 000000000..92dcc18ec --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/misc/sc_concatref.h @@ -0,0 +1,855 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_concatref.h -- Concatenation support. + + Original Author: Andy Goodrich, Forte Design, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + Andy Goodrich, Forte Design Systems, 17 Nov 2002 + Creation of sc_concatref class by merging the capabilities of + sc_int_concref, sc_int_concref, sc_uint_concref, sc_uint_concref, + and implementing the capabilities of sc_signed_concref, sc_signed_concref, + sc_unsigned_concref, and sc_unsigned_concref. The resultant class allows + mixed mode concatenations on the left and right sides of an assignment. + + *****************************************************************************/ + +// $Log: sc_concatref.h,v $ +// Revision 1.6 2011/08/24 22:05:48 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.5 2009/11/17 19:58:15 acg +// Andy Goodrich: fix of shift rhs possibilities to include "int". +// +// Revision 1.4 2009/02/28 00:26:29 acg +// Andy Goodrich: bug fixes. +// +// Revision 1.3 2008/04/29 20:23:55 acg +// Andy Goodrich: fixed the code that assigns the value of a string to +// an sc_concatref instance. +// +// Revision 1.2 2008/02/14 20:57:26 acg +// Andy Goodrich: added casts to ~0 instances to keep MSVC compiler happy. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.4 2006/10/23 19:36:59 acg +// Andy Goodrich: changed casts for operations on concatenation values to +// mirror those of sc_unsigned. For instance, an sc_unsigned minus a value +// returns an sc_signed result, whereas an sc_concatref minus a value was +// returning an sc_unsigned result. Now both sc_unsigned and sc_concatref +// minus a value return an sc_signed result. +// +// Revision 1.3 2006/01/13 18:54:01 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_CONCATREF_H +#define SC_CONCATREF_H + +#include "sysc/kernel/sc_object.h" +#include "sysc/datatypes/misc/sc_value_base.h" +#include "sysc/utils/sc_temporary.h" +#include "sysc/datatypes/bit/sc_bv.h" +#include "sysc/datatypes/bit/sc_lv.h" +#include "sysc/datatypes/int/sc_int_base.h" +#include "sysc/datatypes/int/sc_uint_base.h" +#include "sysc/datatypes/int/sc_signed.h" +#include "sysc/datatypes/int/sc_unsigned.h" + +namespace sc_core { + extern sc_byte_heap sc_temp_heap; // Temporary storage. +} // namespace sc_core + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_concatref +// +// Proxy class for sized bit concatenation. +// ---------------------------------------------------------------------------- + +class sc_concatref : public sc_generic_base<sc_concatref>, public sc_value_base +{ +public: + friend class sc_core::sc_vpool<sc_concatref>; + + inline void initialize( + sc_value_base& left, sc_value_base& right ) + { + bool left_xz; // True if x's and/or z's found in left. + bool right_xz; // True if x's and/or z's found in right. + + m_left_p = (sc_value_base*)&left; + m_right_p = (sc_value_base*)&right; + m_len_r = right.concat_length(&right_xz); + m_len = left.concat_length(&left_xz) + m_len_r; + m_flags = ( left_xz || right_xz ) ? cf_xz_present : cf_none; + } + + + inline void initialize( + const sc_value_base& left, const sc_value_base& right ) + { + bool left_xz; // True if x's and/or z's found in left. + bool right_xz; // True if x's and/or z's found in right. + + m_left_p = (sc_value_base*)&left; + m_right_p = (sc_value_base*)&right; + m_len_r = right.concat_length(&right_xz); + m_len = left.concat_length(&left_xz) + m_len_r; + m_flags = ( left_xz || right_xz ) ? cf_xz_present : cf_none; + } + + // destructor + + virtual ~sc_concatref() + {} + + + // capacity + + unsigned int length() const + { return m_len; } + +#ifdef SC_DT_DEPRECATED + int bitwidth() const + { return length(); } +#endif + + // concatenation + + virtual int concat_length( bool* xz_present_p ) const + { + if ( xz_present_p ) + *xz_present_p = m_flags & cf_xz_present ? true : false; + return m_len; + } + + virtual void concat_clear_data( bool to_ones ) + { + m_left_p->concat_clear_data(to_ones); + m_right_p->concat_clear_data(to_ones); + } + + virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const + { + bool rnz = m_right_p->concat_get_ctrl( dst_p, low_i ); + bool lnz = m_left_p->concat_get_ctrl( dst_p, low_i+m_len_r ); + return rnz || lnz; + } + + virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const + { + bool rnz = m_right_p->concat_get_data( dst_p, low_i ); + bool lnz = m_left_p->concat_get_data( dst_p, low_i+m_len_r ); + return rnz || lnz; + } + + virtual uint64 concat_get_uint64() const + { + if ( m_len_r >= 64 ) + return m_right_p->concat_get_uint64(); + else + { + return (m_left_p->concat_get_uint64() << m_len_r) | + m_right_p->concat_get_uint64(); + } + } + + virtual void concat_set( int64 src, int low_i ) + { + m_right_p->concat_set( src, low_i ); + m_left_p->concat_set( src, low_i+m_len_r); + } + + virtual void concat_set( const sc_signed& src, int low_i ) + { + m_right_p->concat_set( src, low_i ); + m_left_p->concat_set( src, low_i+m_len_r); + } + + virtual void concat_set( const sc_unsigned& src, int low_i ) + { + m_right_p->concat_set( src, low_i ); + m_left_p->concat_set( src, low_i+m_len_r); + } + + virtual void concat_set( uint64 src, int low_i ) + { + m_right_p->concat_set( src, low_i ); + m_left_p->concat_set( src, low_i+m_len_r); + } + + + // explicit conversions + + uint64 to_uint64() const + { + uint64 mask; + uint64 result; + + result = m_right_p->concat_get_uint64(); + if ( m_len_r < 64 ) + { + mask = (uint64)~0; + result = (m_left_p->concat_get_uint64() << m_len_r) | + (result & ~(mask << m_len_r)); + } + if ( m_len < 64 ) + { + mask = (uint64)~0; + result = result & ~(mask << m_len); + } + return result; + } + + const sc_unsigned& value() const + { + bool left_non_zero; + sc_unsigned* result_p = sc_unsigned::m_pool.allocate(); + bool right_non_zero; + + result_p->nbits = result_p->num_bits(m_len); + result_p->ndigits = DIV_CEIL(result_p->nbits); + result_p->digit = (sc_digit*)sc_core::sc_temp_heap.allocate( + sizeof(sc_digit)*result_p->ndigits ); +#if defined(_MSC_VER) + // workaround spurious initialisation issue on MS Visual C++ + memset( result_p->digit, 0, sizeof(sc_digit)*result_p->ndigits ); +#else + result_p->digit[result_p->ndigits-1] = 0; +#endif + right_non_zero = m_right_p->concat_get_data( result_p->digit, 0 ); + left_non_zero = m_left_p->concat_get_data(result_p->digit, m_len_r); + if ( left_non_zero || right_non_zero ) + result_p->sgn = SC_POS; + else + result_p->sgn = SC_ZERO; + return *result_p; + } + + int64 to_int64() const + { + return (int64)to_uint64(); + } + int to_int() const + { return (int)to_int64(); } + unsigned int to_uint() const + { return (unsigned int)to_uint64(); } + long to_long() const + { return (long)to_int64(); } + unsigned long to_ulong() const + { return (unsigned long)to_uint64(); } + double to_double() const + { return value().to_double(); } + + void to_sc_signed( sc_signed& target ) const + { target = value(); } + + void to_sc_unsigned( sc_unsigned& target ) const + { target = value(); } + + // implicit conversions: + + operator uint64 () const + { return to_uint64(); } + + operator const sc_unsigned& () const + { return value(); } + + // unary operators: + + sc_unsigned operator + () const + { return value(); } + + sc_signed operator - () const + { return -value(); } + + sc_unsigned operator ~ () const + { return ~value(); } + + // explicit conversion to character string + + const std::string to_string( sc_numrep numrep = SC_DEC ) const + { return value().to_string(numrep); } + + const std::string to_string( sc_numrep numrep, bool w_prefix ) const + { return value().to_string(numrep,w_prefix); } + + + + // assignments + + inline const sc_concatref& operator = ( int v ) + { + m_right_p->concat_set((int64)v, 0); + m_left_p->concat_set((int64)v, m_len_r); + return *this; + } + + inline const sc_concatref& operator = ( long v ) + { + m_right_p->concat_set((int64)v, 0); + m_left_p->concat_set((int64)v, m_len_r); + return *this; + } + + inline const sc_concatref& operator = ( int64 v ) + { + m_right_p->concat_set(v, 0); + m_left_p->concat_set(v, m_len_r); + return *this; + } + + inline const sc_concatref& operator = ( unsigned int v ) + { + m_right_p->concat_set((uint64)v, 0); + m_left_p->concat_set((uint64)v, m_len_r); + return *this; + } + + inline const sc_concatref& operator = ( unsigned long v ) + { + m_right_p->concat_set((uint64)v, 0); + m_left_p->concat_set((uint64)v, m_len_r); + return *this; + } + + inline const sc_concatref& operator = ( uint64 v ) + { + m_right_p->concat_set(v, 0); + m_left_p->concat_set(v, m_len_r); + return *this; + } + + const sc_concatref& operator = ( const sc_concatref& v ) + { + sc_unsigned temp(v.length()); + temp = v.value(); + m_right_p->concat_set(temp, 0); + m_left_p->concat_set(temp, m_len_r); + return *this; + } + + const sc_concatref& operator = ( const sc_signed& v ) + { + m_right_p->concat_set(v, 0); + m_left_p->concat_set(v, m_len_r); + return *this; + } + + const sc_concatref& operator = ( const sc_unsigned& v ) + { + m_right_p->concat_set(v, 0); + m_left_p->concat_set(v, m_len_r); + return *this; + } + + const sc_concatref& operator = ( const char* v_p ) + { + sc_unsigned v(m_len); + v = v_p; + m_right_p->concat_set(v, 0); + m_left_p->concat_set(v, m_len_r); + return *this; + } + + const sc_concatref& operator = ( const sc_bv_base& v ) + { + sc_unsigned temp(v.length()); + temp = v; + m_right_p->concat_set(temp, 0); + m_left_p->concat_set(temp, m_len_r); + return *this; + } + + const sc_concatref& operator = ( const sc_lv_base& v ) + { + sc_unsigned data(v.length()); + data = v; + m_right_p->concat_set(data, 0); + m_left_p->concat_set(data, m_len_r); + return *this; + } + + + // reduce methods + + bool and_reduce() const + { return value().and_reduce(); } + + bool nand_reduce() const + { return value().nand_reduce(); } + + bool or_reduce() const + { return value().or_reduce(); } + + bool nor_reduce() const + { return value().nor_reduce(); } + + bool xor_reduce() const + { return value().xor_reduce(); } + + bool xnor_reduce() const + { return value().xnor_reduce(); } + + // other methods + + void print( ::std::ostream& os = ::std::cout ) const + { os << this->value(); } + + void scan( ::std::istream& is ) + { + std::string s; + is >> s; + *this = s.c_str(); + } + +public: + static sc_core::sc_vpool<sc_concatref> m_pool; // Pool of temporary objects. + +public: + enum concat_flags { + cf_none = 0, // Normal value. + cf_xz_present = 1 // X and/or Z values present. + }; + +protected: + sc_value_base* m_left_p; // Left hand operand of concatenation. + sc_value_base* m_right_p; // Right hand operand of concatenation. + int m_len; // Length of concatenation. + int m_len_r; // Length of m_rightt_p. + concat_flags m_flags; // Value is read only. + +private: + sc_concatref(const sc_concatref&); + sc_concatref() : m_left_p(0), m_right_p(0), m_len(0), m_len_r(0), m_flags() + {} +}; + + +// functional notation for the reduce methods + +inline +bool +and_reduce( const sc_concatref& a ) +{ + return a.and_reduce(); +} + +inline +bool +nand_reduce( const sc_concatref& a ) +{ + return a.nand_reduce(); +} + +inline +bool +or_reduce( const sc_concatref& a ) +{ + return a.or_reduce(); +} + +inline +bool +nor_reduce( const sc_concatref& a ) +{ + return a.nor_reduce(); +} + +inline +bool +xor_reduce( const sc_concatref& a ) +{ + return a.xor_reduce(); +} + +inline +bool +xnor_reduce( const sc_concatref& a ) +{ + return a.xnor_reduce(); +} + + +// SHIFT OPERATORS FOR sc_concatref OBJECT INSTANCES: +// +// Because sc_concatref has implicit casts to both uint64 and sc_unsigned +// it is necessary to disambiguate the use of the shift operators. We do +// this in favor of sc_unsigned so that precision is not lost. To get an +// integer-based result use a cast to uint64 before performing the shift. + +inline const sc_unsigned operator << (const sc_concatref& target, uint64 shift) +{ + return target.value() << (int)shift; +} + +inline const sc_unsigned operator << (const sc_concatref& target, int64 shift) +{ + return target.value() << (int)shift; +} + +inline const sc_unsigned operator << ( + const sc_concatref& target, unsigned long shift ) +{ + return target.value() << (int)shift; +} + +inline const sc_unsigned operator << ( + const sc_concatref& target, int shift ) +{ + return target.value() << shift; +} + +inline const sc_unsigned operator << ( + const sc_concatref& target, unsigned int shift ) +{ + return target.value() << (int)shift; +} + +inline const sc_unsigned operator << ( const sc_concatref& target, long shift ) +{ + return target.value() << (int)shift; +} + +inline const sc_unsigned operator >> (const sc_concatref& target, uint64 shift) +{ + return target.value() >> (int)shift; +} + +inline const sc_unsigned operator >> (const sc_concatref& target, int64 shift) +{ + return target.value() >> (int)shift; +} + +inline const sc_unsigned operator >> ( + const sc_concatref& target, unsigned long shift ) +{ + return target.value() >> (int)shift; +} + +inline const sc_unsigned operator >> ( + const sc_concatref& target, int shift ) +{ + return target.value() >> shift; +} + +inline const sc_unsigned operator >> ( + const sc_concatref& target, unsigned int shift ) +{ + return target.value() >> (int)shift; +} + +inline const sc_unsigned operator >> ( const sc_concatref& target, long shift ) +{ + return target.value() >> (int)shift; +} + + +// STREAM OPERATORS FOR sc_concatref OBJECT INSTANCES: + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_concatref& v ) +{ + return os << v.value(); +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_concatref& a ) +{ + sc_unsigned temp(a.concat_length(0)); + temp.scan( is ); + a = temp; + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_concat_bool +// +// Proxy class for read-only boolean values in concatenations. +// ---------------------------------------------------------------------------- + +class sc_concat_bool : public sc_value_base +{ + protected: + static sc_core::sc_vpool<sc_concat_bool> m_pool; // Temporaries pool. + bool m_value; // Value for this obj. + + public: + + // constructor: + + sc_concat_bool() + : sc_value_base(), m_value() + {} + + // destructor: + + virtual ~sc_concat_bool() + { } + + // allocation of temporary object: + + static inline sc_concat_bool* allocate( bool v ) + { + sc_concat_bool* result_p = m_pool.allocate(); + result_p->m_value = v; + return result_p; + } + + // concatenation: + + virtual int concat_length( bool* xz_present_p ) const + { + if ( xz_present_p ) *xz_present_p = false; + return 1; + } + + virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const + { + int bit = 1 << (low_i % BITS_PER_DIGIT); + int word_i = low_i / BITS_PER_DIGIT; + dst_p[word_i] &= ~bit; + return false; + } + + virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const + { + int bit = 1 << (low_i % BITS_PER_DIGIT); + int word_i = low_i / BITS_PER_DIGIT; + if ( m_value ) + dst_p[word_i] |= bit; + else + dst_p[word_i] &= ~bit; + return m_value; + } + + virtual uint64 concat_get_uint64() const + { + return m_value ? 1 : 0; + } +}; + + +// ---------------------------------------------------------------------------- +// ARITHMETIC AND LOGIC OPERATORS FOR sc_concatref +// ---------------------------------------------------------------------------- + +#define SC_CONCAT_OP_TYPE(RESULT,OP,OTHER_TYPE) \ + inline RESULT operator OP ( const sc_concatref& a, OTHER_TYPE b ) \ + { \ + return a.value() OP b; \ + } \ + inline RESULT operator OP ( OTHER_TYPE a, const sc_concatref& b ) \ + { \ + return a OP b.value(); \ + } + + +#define SC_CONCAT_OP(RESULT,OP) \ + inline RESULT operator OP ( const sc_concatref& a, const sc_concatref& b ) \ + { \ + return a.value() OP b.value(); \ + } \ + SC_CONCAT_OP_TYPE(const sc_signed,OP,int) \ + SC_CONCAT_OP_TYPE(const sc_signed,OP,long) \ + SC_CONCAT_OP_TYPE(const sc_signed,OP,int64) \ + SC_CONCAT_OP_TYPE(RESULT,OP,unsigned int) \ + SC_CONCAT_OP_TYPE(RESULT,OP,unsigned long) \ + SC_CONCAT_OP_TYPE(RESULT,OP,uint64) \ + SC_CONCAT_OP_TYPE(const sc_signed,OP,const sc_int_base&) \ + SC_CONCAT_OP_TYPE(RESULT,OP,const sc_uint_base&) \ + SC_CONCAT_OP_TYPE(const sc_signed,OP,const sc_signed&) \ + SC_CONCAT_OP_TYPE(RESULT,OP,const sc_unsigned&) \ + inline RESULT operator OP ( const sc_concatref& a, bool b ) \ + { \ + return a.value() OP (int)b; \ + } \ + inline RESULT operator OP ( bool a, const sc_concatref& b ) \ + { \ + return (int)a OP b.value(); \ + } + +#define SC_CONCAT_BOOL_OP(OP) \ + inline bool operator OP ( const sc_concatref& a, const sc_concatref& b ) \ + { \ + return a.value() OP b.value(); \ + } \ + SC_CONCAT_OP_TYPE(bool,OP,int) \ + SC_CONCAT_OP_TYPE(bool,OP,long) \ + SC_CONCAT_OP_TYPE(bool,OP,int64) \ + SC_CONCAT_OP_TYPE(bool,OP,unsigned int) \ + SC_CONCAT_OP_TYPE(bool,OP,unsigned long) \ + SC_CONCAT_OP_TYPE(bool,OP,uint64) \ + SC_CONCAT_OP_TYPE(bool,OP,const sc_int_base&) \ + SC_CONCAT_OP_TYPE(bool,OP,const sc_uint_base&) \ + SC_CONCAT_OP_TYPE(bool,OP,const sc_signed&) \ + SC_CONCAT_OP_TYPE(bool,OP,const sc_unsigned&) \ + inline bool operator OP ( const sc_concatref& a, bool b ) \ + { \ + return a.value() OP (int)b; \ + } \ + inline bool operator OP ( bool a, const sc_concatref& b ) \ + { \ + return (int)a OP b.value(); \ + } + +SC_CONCAT_OP(const sc_unsigned,+) +SC_CONCAT_OP(const sc_signed,-) +SC_CONCAT_OP(const sc_unsigned,*) +SC_CONCAT_OP(const sc_unsigned,/) +SC_CONCAT_OP(const sc_unsigned,%) +SC_CONCAT_OP(const sc_unsigned,&) +SC_CONCAT_OP(const sc_unsigned,|) +SC_CONCAT_OP(const sc_unsigned,^) +SC_CONCAT_BOOL_OP(==) +SC_CONCAT_BOOL_OP(<=) +SC_CONCAT_BOOL_OP(>=) +SC_CONCAT_BOOL_OP(!=) +SC_CONCAT_BOOL_OP(>) +SC_CONCAT_BOOL_OP(<) + +#undef SC_CONCAT_OP +#undef SC_CONCAT_OP_TYPE + + +// ---------------------------------------------------------------------------- +// CONCATENATION FUNCTION AND OPERATOR FOR STANDARD SYSTEM C DATA TYPES: +// ---------------------------------------------------------------------------- + +inline sc_dt::sc_concatref& concat( + sc_dt::sc_value_base& a, sc_dt::sc_value_base& b) +{ + sc_dt::sc_concatref* result_p; // Proxy for the concatenation. + + result_p = sc_dt::sc_concatref::m_pool.allocate(); + result_p->initialize( a, b ); + return *result_p; +} + +inline +const +sc_dt::sc_concatref& concat( + const sc_dt::sc_value_base& a, const sc_dt::sc_value_base& b) +{ + sc_dt::sc_concatref* result_p; // Proxy for the concatenation. + + result_p = sc_dt::sc_concatref::m_pool.allocate(); + result_p->initialize( a, b ); + return *result_p; +} + +inline +const +sc_dt::sc_concatref& concat(const sc_dt::sc_value_base& a, bool b) +{ + const sc_dt::sc_concat_bool* b_p; // Proxy for boolean value. + sc_dt::sc_concatref* result_p; // Proxy for the concatenation. + + b_p = sc_dt::sc_concat_bool::allocate(b); + result_p = sc_dt::sc_concatref::m_pool.allocate(); + result_p->initialize( a, *b_p ); + return *result_p; +} + +inline +const +sc_dt::sc_concatref& concat(bool a, const sc_dt::sc_value_base& b) +{ + const sc_dt::sc_concat_bool* a_p; // Proxy for boolean value. + sc_dt::sc_concatref* result_p; // Proxy for the concatenation. + + a_p = sc_dt::sc_concat_bool::allocate(a); + result_p = sc_dt::sc_concatref::m_pool.allocate(); + result_p->initialize( *a_p, b ); + return *result_p; +} + +inline sc_dt::sc_concatref& operator , ( + sc_dt::sc_value_base& a, sc_dt::sc_value_base& b) +{ + sc_dt::sc_concatref* result_p; // Proxy for the concatenation. + + result_p = sc_dt::sc_concatref::m_pool.allocate(); + result_p->initialize( a, b ); + return *result_p; +} + +inline +const +sc_dt::sc_concatref& operator , ( + const sc_dt::sc_value_base& a, const sc_dt::sc_value_base& b) +{ + sc_dt::sc_concatref* result_p; // Proxy for the concatenation. + + result_p = sc_dt::sc_concatref::m_pool.allocate(); + result_p->initialize( a, b ); + return *result_p; +} + +inline +const +sc_dt::sc_concatref& operator , (const sc_dt::sc_value_base& a, bool b) +{ + const sc_dt::sc_concat_bool* b_p; // Proxy for boolean value. + sc_dt::sc_concatref* result_p; // Proxy for the concatenation. + + b_p = sc_dt::sc_concat_bool::allocate(b); + result_p = sc_dt::sc_concatref::m_pool.allocate(); + result_p->initialize( a, *b_p ); + return *result_p; +} + +inline +const +sc_dt::sc_concatref& operator , (bool a, const sc_dt::sc_value_base& b) +{ + const sc_dt::sc_concat_bool* a_p; // Proxy for boolean value. + sc_dt::sc_concatref* result_p; // Proxy for the concatenation. + + a_p = sc_dt::sc_concat_bool::allocate(a); + result_p = sc_dt::sc_concatref::m_pool.allocate(); + result_p->initialize( *a_p, b ); + return *result_p; +} + +} // namespace sc_dt + +#endif // SC_CONCATREF_H + diff --git a/ext/systemc/src/sysc/datatypes/misc/sc_value_base.cpp b/ext/systemc/src/sysc/datatypes/misc/sc_value_base.cpp new file mode 100644 index 000000000..5f16341a7 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/misc/sc_value_base.cpp @@ -0,0 +1,138 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_value_base.cpp -- Base class for all SystemC data values. + + Original Author: Andy Goodrich, Forte Design Systems + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_value_base.cpp,v $ +// Revision 1.2 2011/08/15 16:43:24 acg +// Torsten Maehne: changes to remove unused argument warnings. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:54:01 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#include <cstdlib> +#include <assert.h> +#include <ctype.h> +#include <cstdio> + +#include "sysc/datatypes/int/sc_int_ids.h" +#include "sysc/datatypes/misc/sc_value_base.h" + +namespace sc_dt +{ + +void sc_value_base::concat_clear_data( bool /* to_ones */ ) +{ + char error_message[128]; + std::sprintf(error_message, + "concat_clear_data method not supported by this type"); + SC_REPORT_ERROR( sc_core::SC_ID_OPERATION_FAILED_, error_message ); +} + +bool sc_value_base::concat_get_ctrl( sc_digit* /*dst_p*/, int /*low_i*/ ) const +{ + char error_message[128]; + std::sprintf(error_message, + "concat_get_ctrl method not supported by this type"); + SC_REPORT_ERROR( sc_core::SC_ID_OPERATION_FAILED_, error_message ); + return false; +} + +bool sc_value_base::concat_get_data( sc_digit* /*dst_p*/, int /*low_i*/ ) const +{ + char error_message[128]; + std::sprintf(error_message, + "concat_get_data method not supported by this type"); + SC_REPORT_ERROR( sc_core::SC_ID_OPERATION_FAILED_, error_message ); + return false; +} + +sc_dt::uint64 sc_value_base::concat_get_uint64() const +{ + char error_message[128]; + std::sprintf(error_message, + "concat_get_uint64 method not supported by this type"); + SC_REPORT_ERROR( sc_core::SC_ID_OPERATION_FAILED_, error_message ); + return 0; +} + +int sc_value_base::concat_length(bool* /*xz_present_p*/) const +{ + char error_message[128]; + std::sprintf(error_message, + "concat_length method not supported by this type"); + SC_REPORT_ERROR( sc_core::SC_ID_OPERATION_FAILED_, error_message ); + return 0; +} + +void sc_value_base::concat_set( int64 /*src*/, int /*low_i*/ ) +{ + char error_message[128]; + std::sprintf(error_message, + "concat_set(int64) method not supported by this type"); + SC_REPORT_ERROR( sc_core::SC_ID_OPERATION_FAILED_, error_message ); +} + +void sc_value_base::concat_set( const sc_signed& /*src*/, int /*low_i*/ ) +{ + char error_message[128]; + std::sprintf(error_message, + "concat_set(sc_signed) method not supported by this type"); + SC_REPORT_ERROR( sc_core::SC_ID_OPERATION_FAILED_, error_message ); +} + +void sc_value_base::concat_set( const sc_unsigned& /*src*/, int /*low_i*/ ) +{ + char error_message[128]; + std::sprintf(error_message, + "concat_set(sc_unsigned) method not supported by this type"); + SC_REPORT_ERROR( sc_core::SC_ID_OPERATION_FAILED_, error_message ); +} + +void sc_value_base::concat_set( uint64 /*src*/, int /*low_i*/ ) +{ + char error_message[128]; + std::sprintf(error_message, + "concat_set(uint64) method not supported by this type"); + SC_REPORT_ERROR( sc_core::SC_ID_OPERATION_FAILED_, error_message ); +} + +} // namespace sc_dt diff --git a/ext/systemc/src/sysc/datatypes/misc/sc_value_base.h b/ext/systemc/src/sysc/datatypes/misc/sc_value_base.h new file mode 100644 index 000000000..1a2c73d42 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/misc/sc_value_base.h @@ -0,0 +1,129 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_value_base.h -- Base class for SystemC bit values. + + Original Author: Andy Goodrich, Forte Design Systems + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_value_base.h,v $ +// Revision 1.4 2011/08/29 18:04:32 acg +// Philipp A. Hartmann: miscellaneous clean ups. +// +// Revision 1.3 2011/08/24 22:05:48 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.2 2011/06/28 21:23:04 acg +// Andy Goodrich: merging of SCV tree. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:54:01 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_VALUE_BASE_H +#define SC_VALUE_BASE_H + + +#include "sysc/datatypes/int/sc_nbdefs.h" + +namespace sc_dt +{ + +class sc_signed; +class sc_unsigned; + +// ---------------------------------------------------------------------------- +// CLASS : sc_value_base +// +// Abstract base class of all SystemC native variables. It provides +// support for concatenation operations via a set of virtual methods. +// A general description of the methods appear with their default +// definitions in sc_object.cpp. +// ---------------------------------------------------------------------------- + +class sc_value_base +{ + friend class sc_concatref; + private: + virtual void concat_clear_data( bool to_ones=false ); + virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const; + virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const; + virtual uint64 concat_get_uint64() const; + virtual int concat_length(bool* xz_present_p=0) const; + virtual void concat_set( int64 src, int low_i ); + virtual void concat_set( const sc_signed& src, int low_i ); + virtual void concat_set( const sc_unsigned& src, int low_i ); + virtual void concat_set( uint64 src, int low_i ); + public: + virtual ~sc_value_base() {} +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_generic_base +// +// Proxy class for user-defined value classes and other classes that +// are defined outside of SystemC. +// The class is utilized as a base class for the arbitrary class: +// +// class my_class : public sc_generic_base<my_class> +// +// The purpose of the class is to allow to_XXXX methods defined within that +// class so that assignments and casts from the arbitrary class to native +// SystemC types are possible. To interact correctly with the SystemC library +// the class derived from sc_generic_base must implement the following +// methods: +// (1) uint64 to_uint64() const +// (2) int64 to_int64() const +// (3) void to_sc_unsigned( sc_unsigned& ) const +// (4) void to_sc_signed( sc_signed& ) const +// ---------------------------------------------------------------------------- +template< class T > +class sc_generic_base { + public: + inline const T* operator-> () const + { + return (const T*)this; + } + inline T* operator-> () + { + return (T*)this; + } +}; + +} // namespace sc_dt + +#endif |