diff options
Diffstat (limited to 'ext/systemc/src/sysc/datatypes/int')
30 files changed, 31244 insertions, 0 deletions
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 |