summaryrefslogtreecommitdiff
path: root/src/systemc/dt/int
diff options
context:
space:
mode:
Diffstat (limited to 'src/systemc/dt/int')
-rw-r--r--src/systemc/dt/int/SConscript38
-rw-r--r--src/systemc/dt/int/sc_int_base.cc706
-rw-r--r--src/systemc/dt/int/sc_int_mask.cc2268
-rw-r--r--src/systemc/dt/int/sc_length_param.cc91
-rw-r--r--src/systemc/dt/int/sc_nbcommon.inc2617
-rw-r--r--src/systemc/dt/int/sc_nbexterns.cc739
-rw-r--r--src/systemc/dt/int/sc_nbfriends.inc582
-rw-r--r--src/systemc/dt/int/sc_nbutils.cc1749
-rw-r--r--src/systemc/dt/int/sc_signed.cc3982
-rw-r--r--src/systemc/dt/int/sc_signed_bitref.inc163
-rw-r--r--src/systemc/dt/int/sc_signed_subref.inc402
-rw-r--r--src/systemc/dt/int/sc_uint_base.cc708
-rw-r--r--src/systemc/dt/int/sc_unsigned.cc2259
-rw-r--r--src/systemc/dt/int/sc_unsigned_bitref.inc162
-rw-r--r--src/systemc/dt/int/sc_unsigned_subref.inc394
15 files changed, 16860 insertions, 0 deletions
diff --git a/src/systemc/dt/int/SConscript b/src/systemc/dt/int/SConscript
new file mode 100644
index 000000000..93e01b243
--- /dev/null
+++ b/src/systemc/dt/int/SConscript
@@ -0,0 +1,38 @@
+# Copyright 2018 Google, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Gabe Black
+
+Import('*')
+
+if env['USE_SYSTEMC']:
+ Source('sc_int_base.cc')
+ Source('sc_int_mask.cc')
+ Source('sc_length_param.cc')
+ Source('sc_nbexterns.cc')
+ Source('sc_nbutils.cc')
+ Source('sc_signed.cc')
+ Source('sc_uint_base.cc')
+ Source('sc_unsigned.cc')
diff --git a/src/systemc/dt/int/sc_int_base.cc b/src/systemc/dt/int/sc_int_base.cc
new file mode 100644
index 000000000..d5b005b93
--- /dev/null
+++ b/src/systemc/dt/int/sc_int_base.cc
@@ -0,0 +1,706 @@
+/*****************************************************************************
+
+ 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 <sstream>
+
+#include "systemc/ext/dt/bit/sc_bv_base.hh"
+#include "systemc/ext/dt/bit/sc_lv_base.hh"
+#include "systemc/ext/dt/fx/sc_fix.hh"
+#include "systemc/ext/dt/fx/scfx_other_defs.hh"
+#include "systemc/ext/dt/int/sc_int_base.hh"
+#include "systemc/ext/dt/int/sc_signed.hh"
+#include "systemc/ext/dt/int/sc_uint_base.hh"
+#include "systemc/ext/dt/int/sc_unsigned.hh"
+#include "systemc/ext/dt/misc/sc_concatref.hh"
+
+// explicit template instantiations
+namespace sc_core
+{
+
+template class sc_vpool<sc_dt::sc_int_bitref>;
+template class sc_vpool<sc_dt::sc_int_subref>;
+
+} // namespace sc_core
+
+namespace sc_dt
+{
+
+// to avoid code bloat in sc_int_concref<T1,T2>
+
+void
+sc_int_concref_invalid_length(int length)
+{
+ std::stringstream msg;
+ msg << "sc_int_concref<T1,T2> initialization: length = " << length <<
+ "violates 1 <= length <= " << SC_INTWIDTH;
+ SC_REPORT_ERROR("out of bounds", msg.str().c_str());
+ sc_core::sc_abort(); // can't recover from here
+}
+
+
+// ----------------------------------------------------------------------------
+// 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 = ~(~UINT_ZERO << 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
+{
+ std::stringstream msg;
+ msg << "sc_int[_base] initialization: length = " << m_len <<
+ " violates 1 <= length <= " << SC_INTWIDTH;
+ SC_REPORT_ERROR("out of bounds", msg.str().c_str());
+ sc_core::sc_abort(); // can't recover from here
+}
+
+void
+sc_int_base::invalid_index(int i) const
+{
+ std::stringstream msg;
+ msg << "sc_int[_base] bit selection: index = " << i <<
+ " violates 0 <= index <= " << (m_len - 1);
+ SC_REPORT_ERROR("out of bounds", msg.str().c_str());
+ sc_core::sc_abort(); // can't recover from here
+}
+
+void
+sc_int_base::invalid_range(int l, int r) const
+{
+ std::stringstream msg;
+ msg << "sc_int[_base] part selection: " <<
+ "left = " << l << ", right = " << r << " violates " <<
+ (m_len-1) << " >= left >= right >= 0";
+ SC_REPORT_ERROR("out of bounds", msg.str().c_str());
+ sc_core::sc_abort(); // can't recover from here
+}
+
+void
+sc_int_base::check_value() const
+{
+ int_type limit = (int_type)1 << (m_len - 1);
+ if (m_val < -limit || m_val >= limit) {
+ std::stringstream msg;
+ msg << "sc_int[_base]: value does not fit into a length of " << m_len;
+ SC_REPORT_WARNING("out of bounds", msg.str().c_str());
+ }
+}
+
+
+// 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();
+ *this = a.to_int64();
+}
+
+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();
+ *this = a.to_int64();
+}
+
+
+// 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("conversion failed",
+ "character string is zero");
+ } else if (*a == 0) {
+ SC_REPORT_ERROR("conversion failed",
+ "character string is empty");
+ } else try {
+ int len = m_len;
+ sc_fix aa(a, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
+ return this->operator = (aa);
+ } catch(const sc_core::sc_report &) {
+ std::stringstream msg;
+ msg << "character string '" << a << "' is not valid";
+ SC_REPORT_ERROR("conversion failed", msg.str().c_str());
+ }
+ 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 = ~(~UINT_ZERO << 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_ZERO << m_len);
+ val &= mask;
+ }
+
+ // PROCESS THE FIRST WORD:
+ mask = (~UINT_ZERO << 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;
diff --git a/src/systemc/dt/int/sc_int_mask.cc b/src/systemc/dt/int/sc_int_mask.cc
new file mode 100644
index 000000000..85473bbea
--- /dev/null
+++ b/src/systemc/dt/int/sc_int_mask.cc
@@ -0,0 +1,2268 @@
+/*****************************************************************************
+
+ 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_mask.cpp -- Fills the mask_int lookup table to enable efficient
+ part-selection on 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: Philipp A Hartmann, Intel
+ Description of Modification: - drop specializations for Windows, 32-bit only
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+#include "systemc/ext/dt/int/sc_int_base.hh"
+#include "systemc/ext/dt/int/sc_uint_base.hh"
+
+#ifndef UINT64_C
+# define UINT64_C(v) v ## ULL
+#endif // UINT64_C
+
+namespace sc_dt {
+
+const uint_type mask_int[SC_INTWIDTH][SC_INTWIDTH] = {
+ {
+ UINT64_C(0xfffffffffffffffe)
+ },
+ {
+ UINT64_C(0xfffffffffffffffc),
+ UINT64_C(0xfffffffffffffffd)
+ },
+ {
+ UINT64_C(0xfffffffffffffff8),
+ UINT64_C(0xfffffffffffffff9),
+ UINT64_C(0xfffffffffffffffb)
+ },
+ {
+ UINT64_C(0xfffffffffffffff0),
+ UINT64_C(0xfffffffffffffff1),
+ UINT64_C(0xfffffffffffffff3),
+ UINT64_C(0xfffffffffffffff7)
+ },
+ {
+ UINT64_C(0xffffffffffffffe0),
+ UINT64_C(0xffffffffffffffe1),
+ UINT64_C(0xffffffffffffffe3),
+ UINT64_C(0xffffffffffffffe7),
+ UINT64_C(0xffffffffffffffef)
+ },
+ {
+ UINT64_C(0xffffffffffffffc0),
+ UINT64_C(0xffffffffffffffc1),
+ UINT64_C(0xffffffffffffffc3),
+ UINT64_C(0xffffffffffffffc7),
+ UINT64_C(0xffffffffffffffcf),
+ UINT64_C(0xffffffffffffffdf)
+ },
+ {
+ UINT64_C(0xffffffffffffff80),
+ UINT64_C(0xffffffffffffff81),
+ UINT64_C(0xffffffffffffff83),
+ UINT64_C(0xffffffffffffff87),
+ UINT64_C(0xffffffffffffff8f),
+ UINT64_C(0xffffffffffffff9f),
+ UINT64_C(0xffffffffffffffbf)
+ },
+ {
+ UINT64_C(0xffffffffffffff00),
+ UINT64_C(0xffffffffffffff01),
+ UINT64_C(0xffffffffffffff03),
+ UINT64_C(0xffffffffffffff07),
+ UINT64_C(0xffffffffffffff0f),
+ UINT64_C(0xffffffffffffff1f),
+ UINT64_C(0xffffffffffffff3f),
+ UINT64_C(0xffffffffffffff7f)
+ },
+ {
+ UINT64_C(0xfffffffffffffe00),
+ UINT64_C(0xfffffffffffffe01),
+ UINT64_C(0xfffffffffffffe03),
+ UINT64_C(0xfffffffffffffe07),
+ UINT64_C(0xfffffffffffffe0f),
+ UINT64_C(0xfffffffffffffe1f),
+ UINT64_C(0xfffffffffffffe3f),
+ UINT64_C(0xfffffffffffffe7f),
+ UINT64_C(0xfffffffffffffeff)
+ },
+ {
+ UINT64_C(0xfffffffffffffc00),
+ UINT64_C(0xfffffffffffffc01),
+ UINT64_C(0xfffffffffffffc03),
+ UINT64_C(0xfffffffffffffc07),
+ UINT64_C(0xfffffffffffffc0f),
+ UINT64_C(0xfffffffffffffc1f),
+ UINT64_C(0xfffffffffffffc3f),
+ UINT64_C(0xfffffffffffffc7f),
+ UINT64_C(0xfffffffffffffcff),
+ UINT64_C(0xfffffffffffffdff)
+ },
+ {
+ UINT64_C(0xfffffffffffff800),
+ UINT64_C(0xfffffffffffff801),
+ UINT64_C(0xfffffffffffff803),
+ UINT64_C(0xfffffffffffff807),
+ UINT64_C(0xfffffffffffff80f),
+ UINT64_C(0xfffffffffffff81f),
+ UINT64_C(0xfffffffffffff83f),
+ UINT64_C(0xfffffffffffff87f),
+ UINT64_C(0xfffffffffffff8ff),
+ UINT64_C(0xfffffffffffff9ff),
+ UINT64_C(0xfffffffffffffbff)
+ },
+ {
+ UINT64_C(0xfffffffffffff000),
+ UINT64_C(0xfffffffffffff001),
+ UINT64_C(0xfffffffffffff003),
+ UINT64_C(0xfffffffffffff007),
+ UINT64_C(0xfffffffffffff00f),
+ UINT64_C(0xfffffffffffff01f),
+ UINT64_C(0xfffffffffffff03f),
+ UINT64_C(0xfffffffffffff07f),
+ UINT64_C(0xfffffffffffff0ff),
+ UINT64_C(0xfffffffffffff1ff),
+ UINT64_C(0xfffffffffffff3ff),
+ UINT64_C(0xfffffffffffff7ff)
+ },
+ {
+ UINT64_C(0xffffffffffffe000),
+ UINT64_C(0xffffffffffffe001),
+ UINT64_C(0xffffffffffffe003),
+ UINT64_C(0xffffffffffffe007),
+ UINT64_C(0xffffffffffffe00f),
+ UINT64_C(0xffffffffffffe01f),
+ UINT64_C(0xffffffffffffe03f),
+ UINT64_C(0xffffffffffffe07f),
+ UINT64_C(0xffffffffffffe0ff),
+ UINT64_C(0xffffffffffffe1ff),
+ UINT64_C(0xffffffffffffe3ff),
+ UINT64_C(0xffffffffffffe7ff),
+ UINT64_C(0xffffffffffffefff)
+ },
+ {
+ UINT64_C(0xffffffffffffc000),
+ UINT64_C(0xffffffffffffc001),
+ UINT64_C(0xffffffffffffc003),
+ UINT64_C(0xffffffffffffc007),
+ UINT64_C(0xffffffffffffc00f),
+ UINT64_C(0xffffffffffffc01f),
+ UINT64_C(0xffffffffffffc03f),
+ UINT64_C(0xffffffffffffc07f),
+ UINT64_C(0xffffffffffffc0ff),
+ UINT64_C(0xffffffffffffc1ff),
+ UINT64_C(0xffffffffffffc3ff),
+ UINT64_C(0xffffffffffffc7ff),
+ UINT64_C(0xffffffffffffcfff),
+ UINT64_C(0xffffffffffffdfff)
+ },
+ {
+ UINT64_C(0xffffffffffff8000),
+ UINT64_C(0xffffffffffff8001),
+ UINT64_C(0xffffffffffff8003),
+ UINT64_C(0xffffffffffff8007),
+ UINT64_C(0xffffffffffff800f),
+ UINT64_C(0xffffffffffff801f),
+ UINT64_C(0xffffffffffff803f),
+ UINT64_C(0xffffffffffff807f),
+ UINT64_C(0xffffffffffff80ff),
+ UINT64_C(0xffffffffffff81ff),
+ UINT64_C(0xffffffffffff83ff),
+ UINT64_C(0xffffffffffff87ff),
+ UINT64_C(0xffffffffffff8fff),
+ UINT64_C(0xffffffffffff9fff),
+ UINT64_C(0xffffffffffffbfff)
+ },
+ {
+ UINT64_C(0xffffffffffff0000),
+ UINT64_C(0xffffffffffff0001),
+ UINT64_C(0xffffffffffff0003),
+ UINT64_C(0xffffffffffff0007),
+ UINT64_C(0xffffffffffff000f),
+ UINT64_C(0xffffffffffff001f),
+ UINT64_C(0xffffffffffff003f),
+ UINT64_C(0xffffffffffff007f),
+ UINT64_C(0xffffffffffff00ff),
+ UINT64_C(0xffffffffffff01ff),
+ UINT64_C(0xffffffffffff03ff),
+ UINT64_C(0xffffffffffff07ff),
+ UINT64_C(0xffffffffffff0fff),
+ UINT64_C(0xffffffffffff1fff),
+ UINT64_C(0xffffffffffff3fff),
+ UINT64_C(0xffffffffffff7fff)
+ },
+ {
+ UINT64_C(0xfffffffffffe0000),
+ UINT64_C(0xfffffffffffe0001),
+ UINT64_C(0xfffffffffffe0003),
+ UINT64_C(0xfffffffffffe0007),
+ UINT64_C(0xfffffffffffe000f),
+ UINT64_C(0xfffffffffffe001f),
+ UINT64_C(0xfffffffffffe003f),
+ UINT64_C(0xfffffffffffe007f),
+ UINT64_C(0xfffffffffffe00ff),
+ UINT64_C(0xfffffffffffe01ff),
+ UINT64_C(0xfffffffffffe03ff),
+ UINT64_C(0xfffffffffffe07ff),
+ UINT64_C(0xfffffffffffe0fff),
+ UINT64_C(0xfffffffffffe1fff),
+ UINT64_C(0xfffffffffffe3fff),
+ UINT64_C(0xfffffffffffe7fff),
+ UINT64_C(0xfffffffffffeffff)
+ },
+ {
+ UINT64_C(0xfffffffffffc0000),
+ UINT64_C(0xfffffffffffc0001),
+ UINT64_C(0xfffffffffffc0003),
+ UINT64_C(0xfffffffffffc0007),
+ UINT64_C(0xfffffffffffc000f),
+ UINT64_C(0xfffffffffffc001f),
+ UINT64_C(0xfffffffffffc003f),
+ UINT64_C(0xfffffffffffc007f),
+ UINT64_C(0xfffffffffffc00ff),
+ UINT64_C(0xfffffffffffc01ff),
+ UINT64_C(0xfffffffffffc03ff),
+ UINT64_C(0xfffffffffffc07ff),
+ UINT64_C(0xfffffffffffc0fff),
+ UINT64_C(0xfffffffffffc1fff),
+ UINT64_C(0xfffffffffffc3fff),
+ UINT64_C(0xfffffffffffc7fff),
+ UINT64_C(0xfffffffffffcffff),
+ UINT64_C(0xfffffffffffdffff)
+ },
+ {
+ UINT64_C(0xfffffffffff80000),
+ UINT64_C(0xfffffffffff80001),
+ UINT64_C(0xfffffffffff80003),
+ UINT64_C(0xfffffffffff80007),
+ UINT64_C(0xfffffffffff8000f),
+ UINT64_C(0xfffffffffff8001f),
+ UINT64_C(0xfffffffffff8003f),
+ UINT64_C(0xfffffffffff8007f),
+ UINT64_C(0xfffffffffff800ff),
+ UINT64_C(0xfffffffffff801ff),
+ UINT64_C(0xfffffffffff803ff),
+ UINT64_C(0xfffffffffff807ff),
+ UINT64_C(0xfffffffffff80fff),
+ UINT64_C(0xfffffffffff81fff),
+ UINT64_C(0xfffffffffff83fff),
+ UINT64_C(0xfffffffffff87fff),
+ UINT64_C(0xfffffffffff8ffff),
+ UINT64_C(0xfffffffffff9ffff),
+ UINT64_C(0xfffffffffffbffff)
+ },
+ {
+ UINT64_C(0xfffffffffff00000),
+ UINT64_C(0xfffffffffff00001),
+ UINT64_C(0xfffffffffff00003),
+ UINT64_C(0xfffffffffff00007),
+ UINT64_C(0xfffffffffff0000f),
+ UINT64_C(0xfffffffffff0001f),
+ UINT64_C(0xfffffffffff0003f),
+ UINT64_C(0xfffffffffff0007f),
+ UINT64_C(0xfffffffffff000ff),
+ UINT64_C(0xfffffffffff001ff),
+ UINT64_C(0xfffffffffff003ff),
+ UINT64_C(0xfffffffffff007ff),
+ UINT64_C(0xfffffffffff00fff),
+ UINT64_C(0xfffffffffff01fff),
+ UINT64_C(0xfffffffffff03fff),
+ UINT64_C(0xfffffffffff07fff),
+ UINT64_C(0xfffffffffff0ffff),
+ UINT64_C(0xfffffffffff1ffff),
+ UINT64_C(0xfffffffffff3ffff),
+ UINT64_C(0xfffffffffff7ffff)
+ },
+ {
+ UINT64_C(0xffffffffffe00000),
+ UINT64_C(0xffffffffffe00001),
+ UINT64_C(0xffffffffffe00003),
+ UINT64_C(0xffffffffffe00007),
+ UINT64_C(0xffffffffffe0000f),
+ UINT64_C(0xffffffffffe0001f),
+ UINT64_C(0xffffffffffe0003f),
+ UINT64_C(0xffffffffffe0007f),
+ UINT64_C(0xffffffffffe000ff),
+ UINT64_C(0xffffffffffe001ff),
+ UINT64_C(0xffffffffffe003ff),
+ UINT64_C(0xffffffffffe007ff),
+ UINT64_C(0xffffffffffe00fff),
+ UINT64_C(0xffffffffffe01fff),
+ UINT64_C(0xffffffffffe03fff),
+ UINT64_C(0xffffffffffe07fff),
+ UINT64_C(0xffffffffffe0ffff),
+ UINT64_C(0xffffffffffe1ffff),
+ UINT64_C(0xffffffffffe3ffff),
+ UINT64_C(0xffffffffffe7ffff),
+ UINT64_C(0xffffffffffefffff)
+ },
+ {
+ UINT64_C(0xffffffffffc00000),
+ UINT64_C(0xffffffffffc00001),
+ UINT64_C(0xffffffffffc00003),
+ UINT64_C(0xffffffffffc00007),
+ UINT64_C(0xffffffffffc0000f),
+ UINT64_C(0xffffffffffc0001f),
+ UINT64_C(0xffffffffffc0003f),
+ UINT64_C(0xffffffffffc0007f),
+ UINT64_C(0xffffffffffc000ff),
+ UINT64_C(0xffffffffffc001ff),
+ UINT64_C(0xffffffffffc003ff),
+ UINT64_C(0xffffffffffc007ff),
+ UINT64_C(0xffffffffffc00fff),
+ UINT64_C(0xffffffffffc01fff),
+ UINT64_C(0xffffffffffc03fff),
+ UINT64_C(0xffffffffffc07fff),
+ UINT64_C(0xffffffffffc0ffff),
+ UINT64_C(0xffffffffffc1ffff),
+ UINT64_C(0xffffffffffc3ffff),
+ UINT64_C(0xffffffffffc7ffff),
+ UINT64_C(0xffffffffffcfffff),
+ UINT64_C(0xffffffffffdfffff)
+ },
+ {
+ UINT64_C(0xffffffffff800000),
+ UINT64_C(0xffffffffff800001),
+ UINT64_C(0xffffffffff800003),
+ UINT64_C(0xffffffffff800007),
+ UINT64_C(0xffffffffff80000f),
+ UINT64_C(0xffffffffff80001f),
+ UINT64_C(0xffffffffff80003f),
+ UINT64_C(0xffffffffff80007f),
+ UINT64_C(0xffffffffff8000ff),
+ UINT64_C(0xffffffffff8001ff),
+ UINT64_C(0xffffffffff8003ff),
+ UINT64_C(0xffffffffff8007ff),
+ UINT64_C(0xffffffffff800fff),
+ UINT64_C(0xffffffffff801fff),
+ UINT64_C(0xffffffffff803fff),
+ UINT64_C(0xffffffffff807fff),
+ UINT64_C(0xffffffffff80ffff),
+ UINT64_C(0xffffffffff81ffff),
+ UINT64_C(0xffffffffff83ffff),
+ UINT64_C(0xffffffffff87ffff),
+ UINT64_C(0xffffffffff8fffff),
+ UINT64_C(0xffffffffff9fffff),
+ UINT64_C(0xffffffffffbfffff)
+ },
+ {
+ UINT64_C(0xffffffffff000000),
+ UINT64_C(0xffffffffff000001),
+ UINT64_C(0xffffffffff000003),
+ UINT64_C(0xffffffffff000007),
+ UINT64_C(0xffffffffff00000f),
+ UINT64_C(0xffffffffff00001f),
+ UINT64_C(0xffffffffff00003f),
+ UINT64_C(0xffffffffff00007f),
+ UINT64_C(0xffffffffff0000ff),
+ UINT64_C(0xffffffffff0001ff),
+ UINT64_C(0xffffffffff0003ff),
+ UINT64_C(0xffffffffff0007ff),
+ UINT64_C(0xffffffffff000fff),
+ UINT64_C(0xffffffffff001fff),
+ UINT64_C(0xffffffffff003fff),
+ UINT64_C(0xffffffffff007fff),
+ UINT64_C(0xffffffffff00ffff),
+ UINT64_C(0xffffffffff01ffff),
+ UINT64_C(0xffffffffff03ffff),
+ UINT64_C(0xffffffffff07ffff),
+ UINT64_C(0xffffffffff0fffff),
+ UINT64_C(0xffffffffff1fffff),
+ UINT64_C(0xffffffffff3fffff),
+ UINT64_C(0xffffffffff7fffff)
+ },
+ {
+ UINT64_C(0xfffffffffe000000),
+ UINT64_C(0xfffffffffe000001),
+ UINT64_C(0xfffffffffe000003),
+ UINT64_C(0xfffffffffe000007),
+ UINT64_C(0xfffffffffe00000f),
+ UINT64_C(0xfffffffffe00001f),
+ UINT64_C(0xfffffffffe00003f),
+ UINT64_C(0xfffffffffe00007f),
+ UINT64_C(0xfffffffffe0000ff),
+ UINT64_C(0xfffffffffe0001ff),
+ UINT64_C(0xfffffffffe0003ff),
+ UINT64_C(0xfffffffffe0007ff),
+ UINT64_C(0xfffffffffe000fff),
+ UINT64_C(0xfffffffffe001fff),
+ UINT64_C(0xfffffffffe003fff),
+ UINT64_C(0xfffffffffe007fff),
+ UINT64_C(0xfffffffffe00ffff),
+ UINT64_C(0xfffffffffe01ffff),
+ UINT64_C(0xfffffffffe03ffff),
+ UINT64_C(0xfffffffffe07ffff),
+ UINT64_C(0xfffffffffe0fffff),
+ UINT64_C(0xfffffffffe1fffff),
+ UINT64_C(0xfffffffffe3fffff),
+ UINT64_C(0xfffffffffe7fffff),
+ UINT64_C(0xfffffffffeffffff)
+ },
+ {
+ UINT64_C(0xfffffffffc000000),
+ UINT64_C(0xfffffffffc000001),
+ UINT64_C(0xfffffffffc000003),
+ UINT64_C(0xfffffffffc000007),
+ UINT64_C(0xfffffffffc00000f),
+ UINT64_C(0xfffffffffc00001f),
+ UINT64_C(0xfffffffffc00003f),
+ UINT64_C(0xfffffffffc00007f),
+ UINT64_C(0xfffffffffc0000ff),
+ UINT64_C(0xfffffffffc0001ff),
+ UINT64_C(0xfffffffffc0003ff),
+ UINT64_C(0xfffffffffc0007ff),
+ UINT64_C(0xfffffffffc000fff),
+ UINT64_C(0xfffffffffc001fff),
+ UINT64_C(0xfffffffffc003fff),
+ UINT64_C(0xfffffffffc007fff),
+ UINT64_C(0xfffffffffc00ffff),
+ UINT64_C(0xfffffffffc01ffff),
+ UINT64_C(0xfffffffffc03ffff),
+ UINT64_C(0xfffffffffc07ffff),
+ UINT64_C(0xfffffffffc0fffff),
+ UINT64_C(0xfffffffffc1fffff),
+ UINT64_C(0xfffffffffc3fffff),
+ UINT64_C(0xfffffffffc7fffff),
+ UINT64_C(0xfffffffffcffffff),
+ UINT64_C(0xfffffffffdffffff)
+ },
+ {
+ UINT64_C(0xfffffffff8000000),
+ UINT64_C(0xfffffffff8000001),
+ UINT64_C(0xfffffffff8000003),
+ UINT64_C(0xfffffffff8000007),
+ UINT64_C(0xfffffffff800000f),
+ UINT64_C(0xfffffffff800001f),
+ UINT64_C(0xfffffffff800003f),
+ UINT64_C(0xfffffffff800007f),
+ UINT64_C(0xfffffffff80000ff),
+ UINT64_C(0xfffffffff80001ff),
+ UINT64_C(0xfffffffff80003ff),
+ UINT64_C(0xfffffffff80007ff),
+ UINT64_C(0xfffffffff8000fff),
+ UINT64_C(0xfffffffff8001fff),
+ UINT64_C(0xfffffffff8003fff),
+ UINT64_C(0xfffffffff8007fff),
+ UINT64_C(0xfffffffff800ffff),
+ UINT64_C(0xfffffffff801ffff),
+ UINT64_C(0xfffffffff803ffff),
+ UINT64_C(0xfffffffff807ffff),
+ UINT64_C(0xfffffffff80fffff),
+ UINT64_C(0xfffffffff81fffff),
+ UINT64_C(0xfffffffff83fffff),
+ UINT64_C(0xfffffffff87fffff),
+ UINT64_C(0xfffffffff8ffffff),
+ UINT64_C(0xfffffffff9ffffff),
+ UINT64_C(0xfffffffffbffffff)
+ },
+ {
+ UINT64_C(0xfffffffff0000000),
+ UINT64_C(0xfffffffff0000001),
+ UINT64_C(0xfffffffff0000003),
+ UINT64_C(0xfffffffff0000007),
+ UINT64_C(0xfffffffff000000f),
+ UINT64_C(0xfffffffff000001f),
+ UINT64_C(0xfffffffff000003f),
+ UINT64_C(0xfffffffff000007f),
+ UINT64_C(0xfffffffff00000ff),
+ UINT64_C(0xfffffffff00001ff),
+ UINT64_C(0xfffffffff00003ff),
+ UINT64_C(0xfffffffff00007ff),
+ UINT64_C(0xfffffffff0000fff),
+ UINT64_C(0xfffffffff0001fff),
+ UINT64_C(0xfffffffff0003fff),
+ UINT64_C(0xfffffffff0007fff),
+ UINT64_C(0xfffffffff000ffff),
+ UINT64_C(0xfffffffff001ffff),
+ UINT64_C(0xfffffffff003ffff),
+ UINT64_C(0xfffffffff007ffff),
+ UINT64_C(0xfffffffff00fffff),
+ UINT64_C(0xfffffffff01fffff),
+ UINT64_C(0xfffffffff03fffff),
+ UINT64_C(0xfffffffff07fffff),
+ UINT64_C(0xfffffffff0ffffff),
+ UINT64_C(0xfffffffff1ffffff),
+ UINT64_C(0xfffffffff3ffffff),
+ UINT64_C(0xfffffffff7ffffff)
+ },
+ {
+ UINT64_C(0xffffffffe0000000),
+ UINT64_C(0xffffffffe0000001),
+ UINT64_C(0xffffffffe0000003),
+ UINT64_C(0xffffffffe0000007),
+ UINT64_C(0xffffffffe000000f),
+ UINT64_C(0xffffffffe000001f),
+ UINT64_C(0xffffffffe000003f),
+ UINT64_C(0xffffffffe000007f),
+ UINT64_C(0xffffffffe00000ff),
+ UINT64_C(0xffffffffe00001ff),
+ UINT64_C(0xffffffffe00003ff),
+ UINT64_C(0xffffffffe00007ff),
+ UINT64_C(0xffffffffe0000fff),
+ UINT64_C(0xffffffffe0001fff),
+ UINT64_C(0xffffffffe0003fff),
+ UINT64_C(0xffffffffe0007fff),
+ UINT64_C(0xffffffffe000ffff),
+ UINT64_C(0xffffffffe001ffff),
+ UINT64_C(0xffffffffe003ffff),
+ UINT64_C(0xffffffffe007ffff),
+ UINT64_C(0xffffffffe00fffff),
+ UINT64_C(0xffffffffe01fffff),
+ UINT64_C(0xffffffffe03fffff),
+ UINT64_C(0xffffffffe07fffff),
+ UINT64_C(0xffffffffe0ffffff),
+ UINT64_C(0xffffffffe1ffffff),
+ UINT64_C(0xffffffffe3ffffff),
+ UINT64_C(0xffffffffe7ffffff),
+ UINT64_C(0xffffffffefffffff)
+ },
+ {
+ UINT64_C(0xffffffffc0000000),
+ UINT64_C(0xffffffffc0000001),
+ UINT64_C(0xffffffffc0000003),
+ UINT64_C(0xffffffffc0000007),
+ UINT64_C(0xffffffffc000000f),
+ UINT64_C(0xffffffffc000001f),
+ UINT64_C(0xffffffffc000003f),
+ UINT64_C(0xffffffffc000007f),
+ UINT64_C(0xffffffffc00000ff),
+ UINT64_C(0xffffffffc00001ff),
+ UINT64_C(0xffffffffc00003ff),
+ UINT64_C(0xffffffffc00007ff),
+ UINT64_C(0xffffffffc0000fff),
+ UINT64_C(0xffffffffc0001fff),
+ UINT64_C(0xffffffffc0003fff),
+ UINT64_C(0xffffffffc0007fff),
+ UINT64_C(0xffffffffc000ffff),
+ UINT64_C(0xffffffffc001ffff),
+ UINT64_C(0xffffffffc003ffff),
+ UINT64_C(0xffffffffc007ffff),
+ UINT64_C(0xffffffffc00fffff),
+ UINT64_C(0xffffffffc01fffff),
+ UINT64_C(0xffffffffc03fffff),
+ UINT64_C(0xffffffffc07fffff),
+ UINT64_C(0xffffffffc0ffffff),
+ UINT64_C(0xffffffffc1ffffff),
+ UINT64_C(0xffffffffc3ffffff),
+ UINT64_C(0xffffffffc7ffffff),
+ UINT64_C(0xffffffffcfffffff),
+ UINT64_C(0xffffffffdfffffff)
+ },
+ {
+ UINT64_C(0xffffffff80000000),
+ UINT64_C(0xffffffff80000001),
+ UINT64_C(0xffffffff80000003),
+ UINT64_C(0xffffffff80000007),
+ UINT64_C(0xffffffff8000000f),
+ UINT64_C(0xffffffff8000001f),
+ UINT64_C(0xffffffff8000003f),
+ UINT64_C(0xffffffff8000007f),
+ UINT64_C(0xffffffff800000ff),
+ UINT64_C(0xffffffff800001ff),
+ UINT64_C(0xffffffff800003ff),
+ UINT64_C(0xffffffff800007ff),
+ UINT64_C(0xffffffff80000fff),
+ UINT64_C(0xffffffff80001fff),
+ UINT64_C(0xffffffff80003fff),
+ UINT64_C(0xffffffff80007fff),
+ UINT64_C(0xffffffff8000ffff),
+ UINT64_C(0xffffffff8001ffff),
+ UINT64_C(0xffffffff8003ffff),
+ UINT64_C(0xffffffff8007ffff),
+ UINT64_C(0xffffffff800fffff),
+ UINT64_C(0xffffffff801fffff),
+ UINT64_C(0xffffffff803fffff),
+ UINT64_C(0xffffffff807fffff),
+ UINT64_C(0xffffffff80ffffff),
+ UINT64_C(0xffffffff81ffffff),
+ UINT64_C(0xffffffff83ffffff),
+ UINT64_C(0xffffffff87ffffff),
+ UINT64_C(0xffffffff8fffffff),
+ UINT64_C(0xffffffff9fffffff),
+ UINT64_C(0xffffffffbfffffff)
+ },
+ {
+ UINT64_C(0xffffffff00000000),
+ UINT64_C(0xffffffff00000001),
+ UINT64_C(0xffffffff00000003),
+ UINT64_C(0xffffffff00000007),
+ UINT64_C(0xffffffff0000000f),
+ UINT64_C(0xffffffff0000001f),
+ UINT64_C(0xffffffff0000003f),
+ UINT64_C(0xffffffff0000007f),
+ UINT64_C(0xffffffff000000ff),
+ UINT64_C(0xffffffff000001ff),
+ UINT64_C(0xffffffff000003ff),
+ UINT64_C(0xffffffff000007ff),
+ UINT64_C(0xffffffff00000fff),
+ UINT64_C(0xffffffff00001fff),
+ UINT64_C(0xffffffff00003fff),
+ UINT64_C(0xffffffff00007fff),
+ UINT64_C(0xffffffff0000ffff),
+ UINT64_C(0xffffffff0001ffff),
+ UINT64_C(0xffffffff0003ffff),
+ UINT64_C(0xffffffff0007ffff),
+ UINT64_C(0xffffffff000fffff),
+ UINT64_C(0xffffffff001fffff),
+ UINT64_C(0xffffffff003fffff),
+ UINT64_C(0xffffffff007fffff),
+ UINT64_C(0xffffffff00ffffff),
+ UINT64_C(0xffffffff01ffffff),
+ UINT64_C(0xffffffff03ffffff),
+ UINT64_C(0xffffffff07ffffff),
+ UINT64_C(0xffffffff0fffffff),
+ UINT64_C(0xffffffff1fffffff),
+ UINT64_C(0xffffffff3fffffff),
+ UINT64_C(0xffffffff7fffffff)
+ },
+ {
+ UINT64_C(0xfffffffe00000000),
+ UINT64_C(0xfffffffe00000001),
+ UINT64_C(0xfffffffe00000003),
+ UINT64_C(0xfffffffe00000007),
+ UINT64_C(0xfffffffe0000000f),
+ UINT64_C(0xfffffffe0000001f),
+ UINT64_C(0xfffffffe0000003f),
+ UINT64_C(0xfffffffe0000007f),
+ UINT64_C(0xfffffffe000000ff),
+ UINT64_C(0xfffffffe000001ff),
+ UINT64_C(0xfffffffe000003ff),
+ UINT64_C(0xfffffffe000007ff),
+ UINT64_C(0xfffffffe00000fff),
+ UINT64_C(0xfffffffe00001fff),
+ UINT64_C(0xfffffffe00003fff),
+ UINT64_C(0xfffffffe00007fff),
+ UINT64_C(0xfffffffe0000ffff),
+ UINT64_C(0xfffffffe0001ffff),
+ UINT64_C(0xfffffffe0003ffff),
+ UINT64_C(0xfffffffe0007ffff),
+ UINT64_C(0xfffffffe000fffff),
+ UINT64_C(0xfffffffe001fffff),
+ UINT64_C(0xfffffffe003fffff),
+ UINT64_C(0xfffffffe007fffff),
+ UINT64_C(0xfffffffe00ffffff),
+ UINT64_C(0xfffffffe01ffffff),
+ UINT64_C(0xfffffffe03ffffff),
+ UINT64_C(0xfffffffe07ffffff),
+ UINT64_C(0xfffffffe0fffffff),
+ UINT64_C(0xfffffffe1fffffff),
+ UINT64_C(0xfffffffe3fffffff),
+ UINT64_C(0xfffffffe7fffffff),
+ UINT64_C(0xfffffffeffffffff)
+ },
+ {
+ UINT64_C(0xfffffffc00000000),
+ UINT64_C(0xfffffffc00000001),
+ UINT64_C(0xfffffffc00000003),
+ UINT64_C(0xfffffffc00000007),
+ UINT64_C(0xfffffffc0000000f),
+ UINT64_C(0xfffffffc0000001f),
+ UINT64_C(0xfffffffc0000003f),
+ UINT64_C(0xfffffffc0000007f),
+ UINT64_C(0xfffffffc000000ff),
+ UINT64_C(0xfffffffc000001ff),
+ UINT64_C(0xfffffffc000003ff),
+ UINT64_C(0xfffffffc000007ff),
+ UINT64_C(0xfffffffc00000fff),
+ UINT64_C(0xfffffffc00001fff),
+ UINT64_C(0xfffffffc00003fff),
+ UINT64_C(0xfffffffc00007fff),
+ UINT64_C(0xfffffffc0000ffff),
+ UINT64_C(0xfffffffc0001ffff),
+ UINT64_C(0xfffffffc0003ffff),
+ UINT64_C(0xfffffffc0007ffff),
+ UINT64_C(0xfffffffc000fffff),
+ UINT64_C(0xfffffffc001fffff),
+ UINT64_C(0xfffffffc003fffff),
+ UINT64_C(0xfffffffc007fffff),
+ UINT64_C(0xfffffffc00ffffff),
+ UINT64_C(0xfffffffc01ffffff),
+ UINT64_C(0xfffffffc03ffffff),
+ UINT64_C(0xfffffffc07ffffff),
+ UINT64_C(0xfffffffc0fffffff),
+ UINT64_C(0xfffffffc1fffffff),
+ UINT64_C(0xfffffffc3fffffff),
+ UINT64_C(0xfffffffc7fffffff),
+ UINT64_C(0xfffffffcffffffff),
+ UINT64_C(0xfffffffdffffffff)
+ },
+ {
+ UINT64_C(0xfffffff800000000),
+ UINT64_C(0xfffffff800000001),
+ UINT64_C(0xfffffff800000003),
+ UINT64_C(0xfffffff800000007),
+ UINT64_C(0xfffffff80000000f),
+ UINT64_C(0xfffffff80000001f),
+ UINT64_C(0xfffffff80000003f),
+ UINT64_C(0xfffffff80000007f),
+ UINT64_C(0xfffffff8000000ff),
+ UINT64_C(0xfffffff8000001ff),
+ UINT64_C(0xfffffff8000003ff),
+ UINT64_C(0xfffffff8000007ff),
+ UINT64_C(0xfffffff800000fff),
+ UINT64_C(0xfffffff800001fff),
+ UINT64_C(0xfffffff800003fff),
+ UINT64_C(0xfffffff800007fff),
+ UINT64_C(0xfffffff80000ffff),
+ UINT64_C(0xfffffff80001ffff),
+ UINT64_C(0xfffffff80003ffff),
+ UINT64_C(0xfffffff80007ffff),
+ UINT64_C(0xfffffff8000fffff),
+ UINT64_C(0xfffffff8001fffff),
+ UINT64_C(0xfffffff8003fffff),
+ UINT64_C(0xfffffff8007fffff),
+ UINT64_C(0xfffffff800ffffff),
+ UINT64_C(0xfffffff801ffffff),
+ UINT64_C(0xfffffff803ffffff),
+ UINT64_C(0xfffffff807ffffff),
+ UINT64_C(0xfffffff80fffffff),
+ UINT64_C(0xfffffff81fffffff),
+ UINT64_C(0xfffffff83fffffff),
+ UINT64_C(0xfffffff87fffffff),
+ UINT64_C(0xfffffff8ffffffff),
+ UINT64_C(0xfffffff9ffffffff),
+ UINT64_C(0xfffffffbffffffff)
+ },
+ {
+ UINT64_C(0xfffffff000000000),
+ UINT64_C(0xfffffff000000001),
+ UINT64_C(0xfffffff000000003),
+ UINT64_C(0xfffffff000000007),
+ UINT64_C(0xfffffff00000000f),
+ UINT64_C(0xfffffff00000001f),
+ UINT64_C(0xfffffff00000003f),
+ UINT64_C(0xfffffff00000007f),
+ UINT64_C(0xfffffff0000000ff),
+ UINT64_C(0xfffffff0000001ff),
+ UINT64_C(0xfffffff0000003ff),
+ UINT64_C(0xfffffff0000007ff),
+ UINT64_C(0xfffffff000000fff),
+ UINT64_C(0xfffffff000001fff),
+ UINT64_C(0xfffffff000003fff),
+ UINT64_C(0xfffffff000007fff),
+ UINT64_C(0xfffffff00000ffff),
+ UINT64_C(0xfffffff00001ffff),
+ UINT64_C(0xfffffff00003ffff),
+ UINT64_C(0xfffffff00007ffff),
+ UINT64_C(0xfffffff0000fffff),
+ UINT64_C(0xfffffff0001fffff),
+ UINT64_C(0xfffffff0003fffff),
+ UINT64_C(0xfffffff0007fffff),
+ UINT64_C(0xfffffff000ffffff),
+ UINT64_C(0xfffffff001ffffff),
+ UINT64_C(0xfffffff003ffffff),
+ UINT64_C(0xfffffff007ffffff),
+ UINT64_C(0xfffffff00fffffff),
+ UINT64_C(0xfffffff01fffffff),
+ UINT64_C(0xfffffff03fffffff),
+ UINT64_C(0xfffffff07fffffff),
+ UINT64_C(0xfffffff0ffffffff),
+ UINT64_C(0xfffffff1ffffffff),
+ UINT64_C(0xfffffff3ffffffff),
+ UINT64_C(0xfffffff7ffffffff)
+ },
+ {
+ UINT64_C(0xffffffe000000000),
+ UINT64_C(0xffffffe000000001),
+ UINT64_C(0xffffffe000000003),
+ UINT64_C(0xffffffe000000007),
+ UINT64_C(0xffffffe00000000f),
+ UINT64_C(0xffffffe00000001f),
+ UINT64_C(0xffffffe00000003f),
+ UINT64_C(0xffffffe00000007f),
+ UINT64_C(0xffffffe0000000ff),
+ UINT64_C(0xffffffe0000001ff),
+ UINT64_C(0xffffffe0000003ff),
+ UINT64_C(0xffffffe0000007ff),
+ UINT64_C(0xffffffe000000fff),
+ UINT64_C(0xffffffe000001fff),
+ UINT64_C(0xffffffe000003fff),
+ UINT64_C(0xffffffe000007fff),
+ UINT64_C(0xffffffe00000ffff),
+ UINT64_C(0xffffffe00001ffff),
+ UINT64_C(0xffffffe00003ffff),
+ UINT64_C(0xffffffe00007ffff),
+ UINT64_C(0xffffffe0000fffff),
+ UINT64_C(0xffffffe0001fffff),
+ UINT64_C(0xffffffe0003fffff),
+ UINT64_C(0xffffffe0007fffff),
+ UINT64_C(0xffffffe000ffffff),
+ UINT64_C(0xffffffe001ffffff),
+ UINT64_C(0xffffffe003ffffff),
+ UINT64_C(0xffffffe007ffffff),
+ UINT64_C(0xffffffe00fffffff),
+ UINT64_C(0xffffffe01fffffff),
+ UINT64_C(0xffffffe03fffffff),
+ UINT64_C(0xffffffe07fffffff),
+ UINT64_C(0xffffffe0ffffffff),
+ UINT64_C(0xffffffe1ffffffff),
+ UINT64_C(0xffffffe3ffffffff),
+ UINT64_C(0xffffffe7ffffffff),
+ UINT64_C(0xffffffefffffffff)
+ },
+ {
+ UINT64_C(0xffffffc000000000),
+ UINT64_C(0xffffffc000000001),
+ UINT64_C(0xffffffc000000003),
+ UINT64_C(0xffffffc000000007),
+ UINT64_C(0xffffffc00000000f),
+ UINT64_C(0xffffffc00000001f),
+ UINT64_C(0xffffffc00000003f),
+ UINT64_C(0xffffffc00000007f),
+ UINT64_C(0xffffffc0000000ff),
+ UINT64_C(0xffffffc0000001ff),
+ UINT64_C(0xffffffc0000003ff),
+ UINT64_C(0xffffffc0000007ff),
+ UINT64_C(0xffffffc000000fff),
+ UINT64_C(0xffffffc000001fff),
+ UINT64_C(0xffffffc000003fff),
+ UINT64_C(0xffffffc000007fff),
+ UINT64_C(0xffffffc00000ffff),
+ UINT64_C(0xffffffc00001ffff),
+ UINT64_C(0xffffffc00003ffff),
+ UINT64_C(0xffffffc00007ffff),
+ UINT64_C(0xffffffc0000fffff),
+ UINT64_C(0xffffffc0001fffff),
+ UINT64_C(0xffffffc0003fffff),
+ UINT64_C(0xffffffc0007fffff),
+ UINT64_C(0xffffffc000ffffff),
+ UINT64_C(0xffffffc001ffffff),
+ UINT64_C(0xffffffc003ffffff),
+ UINT64_C(0xffffffc007ffffff),
+ UINT64_C(0xffffffc00fffffff),
+ UINT64_C(0xffffffc01fffffff),
+ UINT64_C(0xffffffc03fffffff),
+ UINT64_C(0xffffffc07fffffff),
+ UINT64_C(0xffffffc0ffffffff),
+ UINT64_C(0xffffffc1ffffffff),
+ UINT64_C(0xffffffc3ffffffff),
+ UINT64_C(0xffffffc7ffffffff),
+ UINT64_C(0xffffffcfffffffff),
+ UINT64_C(0xffffffdfffffffff)
+ },
+ {
+ UINT64_C(0xffffff8000000000),
+ UINT64_C(0xffffff8000000001),
+ UINT64_C(0xffffff8000000003),
+ UINT64_C(0xffffff8000000007),
+ UINT64_C(0xffffff800000000f),
+ UINT64_C(0xffffff800000001f),
+ UINT64_C(0xffffff800000003f),
+ UINT64_C(0xffffff800000007f),
+ UINT64_C(0xffffff80000000ff),
+ UINT64_C(0xffffff80000001ff),
+ UINT64_C(0xffffff80000003ff),
+ UINT64_C(0xffffff80000007ff),
+ UINT64_C(0xffffff8000000fff),
+ UINT64_C(0xffffff8000001fff),
+ UINT64_C(0xffffff8000003fff),
+ UINT64_C(0xffffff8000007fff),
+ UINT64_C(0xffffff800000ffff),
+ UINT64_C(0xffffff800001ffff),
+ UINT64_C(0xffffff800003ffff),
+ UINT64_C(0xffffff800007ffff),
+ UINT64_C(0xffffff80000fffff),
+ UINT64_C(0xffffff80001fffff),
+ UINT64_C(0xffffff80003fffff),
+ UINT64_C(0xffffff80007fffff),
+ UINT64_C(0xffffff8000ffffff),
+ UINT64_C(0xffffff8001ffffff),
+ UINT64_C(0xffffff8003ffffff),
+ UINT64_C(0xffffff8007ffffff),
+ UINT64_C(0xffffff800fffffff),
+ UINT64_C(0xffffff801fffffff),
+ UINT64_C(0xffffff803fffffff),
+ UINT64_C(0xffffff807fffffff),
+ UINT64_C(0xffffff80ffffffff),
+ UINT64_C(0xffffff81ffffffff),
+ UINT64_C(0xffffff83ffffffff),
+ UINT64_C(0xffffff87ffffffff),
+ UINT64_C(0xffffff8fffffffff),
+ UINT64_C(0xffffff9fffffffff),
+ UINT64_C(0xffffffbfffffffff)
+ },
+ {
+ UINT64_C(0xffffff0000000000),
+ UINT64_C(0xffffff0000000001),
+ UINT64_C(0xffffff0000000003),
+ UINT64_C(0xffffff0000000007),
+ UINT64_C(0xffffff000000000f),
+ UINT64_C(0xffffff000000001f),
+ UINT64_C(0xffffff000000003f),
+ UINT64_C(0xffffff000000007f),
+ UINT64_C(0xffffff00000000ff),
+ UINT64_C(0xffffff00000001ff),
+ UINT64_C(0xffffff00000003ff),
+ UINT64_C(0xffffff00000007ff),
+ UINT64_C(0xffffff0000000fff),
+ UINT64_C(0xffffff0000001fff),
+ UINT64_C(0xffffff0000003fff),
+ UINT64_C(0xffffff0000007fff),
+ UINT64_C(0xffffff000000ffff),
+ UINT64_C(0xffffff000001ffff),
+ UINT64_C(0xffffff000003ffff),
+ UINT64_C(0xffffff000007ffff),
+ UINT64_C(0xffffff00000fffff),
+ UINT64_C(0xffffff00001fffff),
+ UINT64_C(0xffffff00003fffff),
+ UINT64_C(0xffffff00007fffff),
+ UINT64_C(0xffffff0000ffffff),
+ UINT64_C(0xffffff0001ffffff),
+ UINT64_C(0xffffff0003ffffff),
+ UINT64_C(0xffffff0007ffffff),
+ UINT64_C(0xffffff000fffffff),
+ UINT64_C(0xffffff001fffffff),
+ UINT64_C(0xffffff003fffffff),
+ UINT64_C(0xffffff007fffffff),
+ UINT64_C(0xffffff00ffffffff),
+ UINT64_C(0xffffff01ffffffff),
+ UINT64_C(0xffffff03ffffffff),
+ UINT64_C(0xffffff07ffffffff),
+ UINT64_C(0xffffff0fffffffff),
+ UINT64_C(0xffffff1fffffffff),
+ UINT64_C(0xffffff3fffffffff),
+ UINT64_C(0xffffff7fffffffff)
+ },
+ {
+ UINT64_C(0xfffffe0000000000),
+ UINT64_C(0xfffffe0000000001),
+ UINT64_C(0xfffffe0000000003),
+ UINT64_C(0xfffffe0000000007),
+ UINT64_C(0xfffffe000000000f),
+ UINT64_C(0xfffffe000000001f),
+ UINT64_C(0xfffffe000000003f),
+ UINT64_C(0xfffffe000000007f),
+ UINT64_C(0xfffffe00000000ff),
+ UINT64_C(0xfffffe00000001ff),
+ UINT64_C(0xfffffe00000003ff),
+ UINT64_C(0xfffffe00000007ff),
+ UINT64_C(0xfffffe0000000fff),
+ UINT64_C(0xfffffe0000001fff),
+ UINT64_C(0xfffffe0000003fff),
+ UINT64_C(0xfffffe0000007fff),
+ UINT64_C(0xfffffe000000ffff),
+ UINT64_C(0xfffffe000001ffff),
+ UINT64_C(0xfffffe000003ffff),
+ UINT64_C(0xfffffe000007ffff),
+ UINT64_C(0xfffffe00000fffff),
+ UINT64_C(0xfffffe00001fffff),
+ UINT64_C(0xfffffe00003fffff),
+ UINT64_C(0xfffffe00007fffff),
+ UINT64_C(0xfffffe0000ffffff),
+ UINT64_C(0xfffffe0001ffffff),
+ UINT64_C(0xfffffe0003ffffff),
+ UINT64_C(0xfffffe0007ffffff),
+ UINT64_C(0xfffffe000fffffff),
+ UINT64_C(0xfffffe001fffffff),
+ UINT64_C(0xfffffe003fffffff),
+ UINT64_C(0xfffffe007fffffff),
+ UINT64_C(0xfffffe00ffffffff),
+ UINT64_C(0xfffffe01ffffffff),
+ UINT64_C(0xfffffe03ffffffff),
+ UINT64_C(0xfffffe07ffffffff),
+ UINT64_C(0xfffffe0fffffffff),
+ UINT64_C(0xfffffe1fffffffff),
+ UINT64_C(0xfffffe3fffffffff),
+ UINT64_C(0xfffffe7fffffffff),
+ UINT64_C(0xfffffeffffffffff)
+ },
+ {
+ UINT64_C(0xfffffc0000000000),
+ UINT64_C(0xfffffc0000000001),
+ UINT64_C(0xfffffc0000000003),
+ UINT64_C(0xfffffc0000000007),
+ UINT64_C(0xfffffc000000000f),
+ UINT64_C(0xfffffc000000001f),
+ UINT64_C(0xfffffc000000003f),
+ UINT64_C(0xfffffc000000007f),
+ UINT64_C(0xfffffc00000000ff),
+ UINT64_C(0xfffffc00000001ff),
+ UINT64_C(0xfffffc00000003ff),
+ UINT64_C(0xfffffc00000007ff),
+ UINT64_C(0xfffffc0000000fff),
+ UINT64_C(0xfffffc0000001fff),
+ UINT64_C(0xfffffc0000003fff),
+ UINT64_C(0xfffffc0000007fff),
+ UINT64_C(0xfffffc000000ffff),
+ UINT64_C(0xfffffc000001ffff),
+ UINT64_C(0xfffffc000003ffff),
+ UINT64_C(0xfffffc000007ffff),
+ UINT64_C(0xfffffc00000fffff),
+ UINT64_C(0xfffffc00001fffff),
+ UINT64_C(0xfffffc00003fffff),
+ UINT64_C(0xfffffc00007fffff),
+ UINT64_C(0xfffffc0000ffffff),
+ UINT64_C(0xfffffc0001ffffff),
+ UINT64_C(0xfffffc0003ffffff),
+ UINT64_C(0xfffffc0007ffffff),
+ UINT64_C(0xfffffc000fffffff),
+ UINT64_C(0xfffffc001fffffff),
+ UINT64_C(0xfffffc003fffffff),
+ UINT64_C(0xfffffc007fffffff),
+ UINT64_C(0xfffffc00ffffffff),
+ UINT64_C(0xfffffc01ffffffff),
+ UINT64_C(0xfffffc03ffffffff),
+ UINT64_C(0xfffffc07ffffffff),
+ UINT64_C(0xfffffc0fffffffff),
+ UINT64_C(0xfffffc1fffffffff),
+ UINT64_C(0xfffffc3fffffffff),
+ UINT64_C(0xfffffc7fffffffff),
+ UINT64_C(0xfffffcffffffffff),
+ UINT64_C(0xfffffdffffffffff)
+ },
+ {
+ UINT64_C(0xfffff80000000000),
+ UINT64_C(0xfffff80000000001),
+ UINT64_C(0xfffff80000000003),
+ UINT64_C(0xfffff80000000007),
+ UINT64_C(0xfffff8000000000f),
+ UINT64_C(0xfffff8000000001f),
+ UINT64_C(0xfffff8000000003f),
+ UINT64_C(0xfffff8000000007f),
+ UINT64_C(0xfffff800000000ff),
+ UINT64_C(0xfffff800000001ff),
+ UINT64_C(0xfffff800000003ff),
+ UINT64_C(0xfffff800000007ff),
+ UINT64_C(0xfffff80000000fff),
+ UINT64_C(0xfffff80000001fff),
+ UINT64_C(0xfffff80000003fff),
+ UINT64_C(0xfffff80000007fff),
+ UINT64_C(0xfffff8000000ffff),
+ UINT64_C(0xfffff8000001ffff),
+ UINT64_C(0xfffff8000003ffff),
+ UINT64_C(0xfffff8000007ffff),
+ UINT64_C(0xfffff800000fffff),
+ UINT64_C(0xfffff800001fffff),
+ UINT64_C(0xfffff800003fffff),
+ UINT64_C(0xfffff800007fffff),
+ UINT64_C(0xfffff80000ffffff),
+ UINT64_C(0xfffff80001ffffff),
+ UINT64_C(0xfffff80003ffffff),
+ UINT64_C(0xfffff80007ffffff),
+ UINT64_C(0xfffff8000fffffff),
+ UINT64_C(0xfffff8001fffffff),
+ UINT64_C(0xfffff8003fffffff),
+ UINT64_C(0xfffff8007fffffff),
+ UINT64_C(0xfffff800ffffffff),
+ UINT64_C(0xfffff801ffffffff),
+ UINT64_C(0xfffff803ffffffff),
+ UINT64_C(0xfffff807ffffffff),
+ UINT64_C(0xfffff80fffffffff),
+ UINT64_C(0xfffff81fffffffff),
+ UINT64_C(0xfffff83fffffffff),
+ UINT64_C(0xfffff87fffffffff),
+ UINT64_C(0xfffff8ffffffffff),
+ UINT64_C(0xfffff9ffffffffff),
+ UINT64_C(0xfffffbffffffffff)
+ },
+ {
+ UINT64_C(0xfffff00000000000),
+ UINT64_C(0xfffff00000000001),
+ UINT64_C(0xfffff00000000003),
+ UINT64_C(0xfffff00000000007),
+ UINT64_C(0xfffff0000000000f),
+ UINT64_C(0xfffff0000000001f),
+ UINT64_C(0xfffff0000000003f),
+ UINT64_C(0xfffff0000000007f),
+ UINT64_C(0xfffff000000000ff),
+ UINT64_C(0xfffff000000001ff),
+ UINT64_C(0xfffff000000003ff),
+ UINT64_C(0xfffff000000007ff),
+ UINT64_C(0xfffff00000000fff),
+ UINT64_C(0xfffff00000001fff),
+ UINT64_C(0xfffff00000003fff),
+ UINT64_C(0xfffff00000007fff),
+ UINT64_C(0xfffff0000000ffff),
+ UINT64_C(0xfffff0000001ffff),
+ UINT64_C(0xfffff0000003ffff),
+ UINT64_C(0xfffff0000007ffff),
+ UINT64_C(0xfffff000000fffff),
+ UINT64_C(0xfffff000001fffff),
+ UINT64_C(0xfffff000003fffff),
+ UINT64_C(0xfffff000007fffff),
+ UINT64_C(0xfffff00000ffffff),
+ UINT64_C(0xfffff00001ffffff),
+ UINT64_C(0xfffff00003ffffff),
+ UINT64_C(0xfffff00007ffffff),
+ UINT64_C(0xfffff0000fffffff),
+ UINT64_C(0xfffff0001fffffff),
+ UINT64_C(0xfffff0003fffffff),
+ UINT64_C(0xfffff0007fffffff),
+ UINT64_C(0xfffff000ffffffff),
+ UINT64_C(0xfffff001ffffffff),
+ UINT64_C(0xfffff003ffffffff),
+ UINT64_C(0xfffff007ffffffff),
+ UINT64_C(0xfffff00fffffffff),
+ UINT64_C(0xfffff01fffffffff),
+ UINT64_C(0xfffff03fffffffff),
+ UINT64_C(0xfffff07fffffffff),
+ UINT64_C(0xfffff0ffffffffff),
+ UINT64_C(0xfffff1ffffffffff),
+ UINT64_C(0xfffff3ffffffffff),
+ UINT64_C(0xfffff7ffffffffff)
+ },
+ {
+ UINT64_C(0xffffe00000000000),
+ UINT64_C(0xffffe00000000001),
+ UINT64_C(0xffffe00000000003),
+ UINT64_C(0xffffe00000000007),
+ UINT64_C(0xffffe0000000000f),
+ UINT64_C(0xffffe0000000001f),
+ UINT64_C(0xffffe0000000003f),
+ UINT64_C(0xffffe0000000007f),
+ UINT64_C(0xffffe000000000ff),
+ UINT64_C(0xffffe000000001ff),
+ UINT64_C(0xffffe000000003ff),
+ UINT64_C(0xffffe000000007ff),
+ UINT64_C(0xffffe00000000fff),
+ UINT64_C(0xffffe00000001fff),
+ UINT64_C(0xffffe00000003fff),
+ UINT64_C(0xffffe00000007fff),
+ UINT64_C(0xffffe0000000ffff),
+ UINT64_C(0xffffe0000001ffff),
+ UINT64_C(0xffffe0000003ffff),
+ UINT64_C(0xffffe0000007ffff),
+ UINT64_C(0xffffe000000fffff),
+ UINT64_C(0xffffe000001fffff),
+ UINT64_C(0xffffe000003fffff),
+ UINT64_C(0xffffe000007fffff),
+ UINT64_C(0xffffe00000ffffff),
+ UINT64_C(0xffffe00001ffffff),
+ UINT64_C(0xffffe00003ffffff),
+ UINT64_C(0xffffe00007ffffff),
+ UINT64_C(0xffffe0000fffffff),
+ UINT64_C(0xffffe0001fffffff),
+ UINT64_C(0xffffe0003fffffff),
+ UINT64_C(0xffffe0007fffffff),
+ UINT64_C(0xffffe000ffffffff),
+ UINT64_C(0xffffe001ffffffff),
+ UINT64_C(0xffffe003ffffffff),
+ UINT64_C(0xffffe007ffffffff),
+ UINT64_C(0xffffe00fffffffff),
+ UINT64_C(0xffffe01fffffffff),
+ UINT64_C(0xffffe03fffffffff),
+ UINT64_C(0xffffe07fffffffff),
+ UINT64_C(0xffffe0ffffffffff),
+ UINT64_C(0xffffe1ffffffffff),
+ UINT64_C(0xffffe3ffffffffff),
+ UINT64_C(0xffffe7ffffffffff),
+ UINT64_C(0xffffefffffffffff)
+ },
+ {
+ UINT64_C(0xffffc00000000000),
+ UINT64_C(0xffffc00000000001),
+ UINT64_C(0xffffc00000000003),
+ UINT64_C(0xffffc00000000007),
+ UINT64_C(0xffffc0000000000f),
+ UINT64_C(0xffffc0000000001f),
+ UINT64_C(0xffffc0000000003f),
+ UINT64_C(0xffffc0000000007f),
+ UINT64_C(0xffffc000000000ff),
+ UINT64_C(0xffffc000000001ff),
+ UINT64_C(0xffffc000000003ff),
+ UINT64_C(0xffffc000000007ff),
+ UINT64_C(0xffffc00000000fff),
+ UINT64_C(0xffffc00000001fff),
+ UINT64_C(0xffffc00000003fff),
+ UINT64_C(0xffffc00000007fff),
+ UINT64_C(0xffffc0000000ffff),
+ UINT64_C(0xffffc0000001ffff),
+ UINT64_C(0xffffc0000003ffff),
+ UINT64_C(0xffffc0000007ffff),
+ UINT64_C(0xffffc000000fffff),
+ UINT64_C(0xffffc000001fffff),
+ UINT64_C(0xffffc000003fffff),
+ UINT64_C(0xffffc000007fffff),
+ UINT64_C(0xffffc00000ffffff),
+ UINT64_C(0xffffc00001ffffff),
+ UINT64_C(0xffffc00003ffffff),
+ UINT64_C(0xffffc00007ffffff),
+ UINT64_C(0xffffc0000fffffff),
+ UINT64_C(0xffffc0001fffffff),
+ UINT64_C(0xffffc0003fffffff),
+ UINT64_C(0xffffc0007fffffff),
+ UINT64_C(0xffffc000ffffffff),
+ UINT64_C(0xffffc001ffffffff),
+ UINT64_C(0xffffc003ffffffff),
+ UINT64_C(0xffffc007ffffffff),
+ UINT64_C(0xffffc00fffffffff),
+ UINT64_C(0xffffc01fffffffff),
+ UINT64_C(0xffffc03fffffffff),
+ UINT64_C(0xffffc07fffffffff),
+ UINT64_C(0xffffc0ffffffffff),
+ UINT64_C(0xffffc1ffffffffff),
+ UINT64_C(0xffffc3ffffffffff),
+ UINT64_C(0xffffc7ffffffffff),
+ UINT64_C(0xffffcfffffffffff),
+ UINT64_C(0xffffdfffffffffff)
+ },
+ {
+ UINT64_C(0xffff800000000000),
+ UINT64_C(0xffff800000000001),
+ UINT64_C(0xffff800000000003),
+ UINT64_C(0xffff800000000007),
+ UINT64_C(0xffff80000000000f),
+ UINT64_C(0xffff80000000001f),
+ UINT64_C(0xffff80000000003f),
+ UINT64_C(0xffff80000000007f),
+ UINT64_C(0xffff8000000000ff),
+ UINT64_C(0xffff8000000001ff),
+ UINT64_C(0xffff8000000003ff),
+ UINT64_C(0xffff8000000007ff),
+ UINT64_C(0xffff800000000fff),
+ UINT64_C(0xffff800000001fff),
+ UINT64_C(0xffff800000003fff),
+ UINT64_C(0xffff800000007fff),
+ UINT64_C(0xffff80000000ffff),
+ UINT64_C(0xffff80000001ffff),
+ UINT64_C(0xffff80000003ffff),
+ UINT64_C(0xffff80000007ffff),
+ UINT64_C(0xffff8000000fffff),
+ UINT64_C(0xffff8000001fffff),
+ UINT64_C(0xffff8000003fffff),
+ UINT64_C(0xffff8000007fffff),
+ UINT64_C(0xffff800000ffffff),
+ UINT64_C(0xffff800001ffffff),
+ UINT64_C(0xffff800003ffffff),
+ UINT64_C(0xffff800007ffffff),
+ UINT64_C(0xffff80000fffffff),
+ UINT64_C(0xffff80001fffffff),
+ UINT64_C(0xffff80003fffffff),
+ UINT64_C(0xffff80007fffffff),
+ UINT64_C(0xffff8000ffffffff),
+ UINT64_C(0xffff8001ffffffff),
+ UINT64_C(0xffff8003ffffffff),
+ UINT64_C(0xffff8007ffffffff),
+ UINT64_C(0xffff800fffffffff),
+ UINT64_C(0xffff801fffffffff),
+ UINT64_C(0xffff803fffffffff),
+ UINT64_C(0xffff807fffffffff),
+ UINT64_C(0xffff80ffffffffff),
+ UINT64_C(0xffff81ffffffffff),
+ UINT64_C(0xffff83ffffffffff),
+ UINT64_C(0xffff87ffffffffff),
+ UINT64_C(0xffff8fffffffffff),
+ UINT64_C(0xffff9fffffffffff),
+ UINT64_C(0xffffbfffffffffff)
+ },
+ {
+ UINT64_C(0xffff000000000000),
+ UINT64_C(0xffff000000000001),
+ UINT64_C(0xffff000000000003),
+ UINT64_C(0xffff000000000007),
+ UINT64_C(0xffff00000000000f),
+ UINT64_C(0xffff00000000001f),
+ UINT64_C(0xffff00000000003f),
+ UINT64_C(0xffff00000000007f),
+ UINT64_C(0xffff0000000000ff),
+ UINT64_C(0xffff0000000001ff),
+ UINT64_C(0xffff0000000003ff),
+ UINT64_C(0xffff0000000007ff),
+ UINT64_C(0xffff000000000fff),
+ UINT64_C(0xffff000000001fff),
+ UINT64_C(0xffff000000003fff),
+ UINT64_C(0xffff000000007fff),
+ UINT64_C(0xffff00000000ffff),
+ UINT64_C(0xffff00000001ffff),
+ UINT64_C(0xffff00000003ffff),
+ UINT64_C(0xffff00000007ffff),
+ UINT64_C(0xffff0000000fffff),
+ UINT64_C(0xffff0000001fffff),
+ UINT64_C(0xffff0000003fffff),
+ UINT64_C(0xffff0000007fffff),
+ UINT64_C(0xffff000000ffffff),
+ UINT64_C(0xffff000001ffffff),
+ UINT64_C(0xffff000003ffffff),
+ UINT64_C(0xffff000007ffffff),
+ UINT64_C(0xffff00000fffffff),
+ UINT64_C(0xffff00001fffffff),
+ UINT64_C(0xffff00003fffffff),
+ UINT64_C(0xffff00007fffffff),
+ UINT64_C(0xffff0000ffffffff),
+ UINT64_C(0xffff0001ffffffff),
+ UINT64_C(0xffff0003ffffffff),
+ UINT64_C(0xffff0007ffffffff),
+ UINT64_C(0xffff000fffffffff),
+ UINT64_C(0xffff001fffffffff),
+ UINT64_C(0xffff003fffffffff),
+ UINT64_C(0xffff007fffffffff),
+ UINT64_C(0xffff00ffffffffff),
+ UINT64_C(0xffff01ffffffffff),
+ UINT64_C(0xffff03ffffffffff),
+ UINT64_C(0xffff07ffffffffff),
+ UINT64_C(0xffff0fffffffffff),
+ UINT64_C(0xffff1fffffffffff),
+ UINT64_C(0xffff3fffffffffff),
+ UINT64_C(0xffff7fffffffffff)
+ },
+ {
+ UINT64_C(0xfffe000000000000),
+ UINT64_C(0xfffe000000000001),
+ UINT64_C(0xfffe000000000003),
+ UINT64_C(0xfffe000000000007),
+ UINT64_C(0xfffe00000000000f),
+ UINT64_C(0xfffe00000000001f),
+ UINT64_C(0xfffe00000000003f),
+ UINT64_C(0xfffe00000000007f),
+ UINT64_C(0xfffe0000000000ff),
+ UINT64_C(0xfffe0000000001ff),
+ UINT64_C(0xfffe0000000003ff),
+ UINT64_C(0xfffe0000000007ff),
+ UINT64_C(0xfffe000000000fff),
+ UINT64_C(0xfffe000000001fff),
+ UINT64_C(0xfffe000000003fff),
+ UINT64_C(0xfffe000000007fff),
+ UINT64_C(0xfffe00000000ffff),
+ UINT64_C(0xfffe00000001ffff),
+ UINT64_C(0xfffe00000003ffff),
+ UINT64_C(0xfffe00000007ffff),
+ UINT64_C(0xfffe0000000fffff),
+ UINT64_C(0xfffe0000001fffff),
+ UINT64_C(0xfffe0000003fffff),
+ UINT64_C(0xfffe0000007fffff),
+ UINT64_C(0xfffe000000ffffff),
+ UINT64_C(0xfffe000001ffffff),
+ UINT64_C(0xfffe000003ffffff),
+ UINT64_C(0xfffe000007ffffff),
+ UINT64_C(0xfffe00000fffffff),
+ UINT64_C(0xfffe00001fffffff),
+ UINT64_C(0xfffe00003fffffff),
+ UINT64_C(0xfffe00007fffffff),
+ UINT64_C(0xfffe0000ffffffff),
+ UINT64_C(0xfffe0001ffffffff),
+ UINT64_C(0xfffe0003ffffffff),
+ UINT64_C(0xfffe0007ffffffff),
+ UINT64_C(0xfffe000fffffffff),
+ UINT64_C(0xfffe001fffffffff),
+ UINT64_C(0xfffe003fffffffff),
+ UINT64_C(0xfffe007fffffffff),
+ UINT64_C(0xfffe00ffffffffff),
+ UINT64_C(0xfffe01ffffffffff),
+ UINT64_C(0xfffe03ffffffffff),
+ UINT64_C(0xfffe07ffffffffff),
+ UINT64_C(0xfffe0fffffffffff),
+ UINT64_C(0xfffe1fffffffffff),
+ UINT64_C(0xfffe3fffffffffff),
+ UINT64_C(0xfffe7fffffffffff),
+ UINT64_C(0xfffeffffffffffff)
+ },
+ {
+ UINT64_C(0xfffc000000000000),
+ UINT64_C(0xfffc000000000001),
+ UINT64_C(0xfffc000000000003),
+ UINT64_C(0xfffc000000000007),
+ UINT64_C(0xfffc00000000000f),
+ UINT64_C(0xfffc00000000001f),
+ UINT64_C(0xfffc00000000003f),
+ UINT64_C(0xfffc00000000007f),
+ UINT64_C(0xfffc0000000000ff),
+ UINT64_C(0xfffc0000000001ff),
+ UINT64_C(0xfffc0000000003ff),
+ UINT64_C(0xfffc0000000007ff),
+ UINT64_C(0xfffc000000000fff),
+ UINT64_C(0xfffc000000001fff),
+ UINT64_C(0xfffc000000003fff),
+ UINT64_C(0xfffc000000007fff),
+ UINT64_C(0xfffc00000000ffff),
+ UINT64_C(0xfffc00000001ffff),
+ UINT64_C(0xfffc00000003ffff),
+ UINT64_C(0xfffc00000007ffff),
+ UINT64_C(0xfffc0000000fffff),
+ UINT64_C(0xfffc0000001fffff),
+ UINT64_C(0xfffc0000003fffff),
+ UINT64_C(0xfffc0000007fffff),
+ UINT64_C(0xfffc000000ffffff),
+ UINT64_C(0xfffc000001ffffff),
+ UINT64_C(0xfffc000003ffffff),
+ UINT64_C(0xfffc000007ffffff),
+ UINT64_C(0xfffc00000fffffff),
+ UINT64_C(0xfffc00001fffffff),
+ UINT64_C(0xfffc00003fffffff),
+ UINT64_C(0xfffc00007fffffff),
+ UINT64_C(0xfffc0000ffffffff),
+ UINT64_C(0xfffc0001ffffffff),
+ UINT64_C(0xfffc0003ffffffff),
+ UINT64_C(0xfffc0007ffffffff),
+ UINT64_C(0xfffc000fffffffff),
+ UINT64_C(0xfffc001fffffffff),
+ UINT64_C(0xfffc003fffffffff),
+ UINT64_C(0xfffc007fffffffff),
+ UINT64_C(0xfffc00ffffffffff),
+ UINT64_C(0xfffc01ffffffffff),
+ UINT64_C(0xfffc03ffffffffff),
+ UINT64_C(0xfffc07ffffffffff),
+ UINT64_C(0xfffc0fffffffffff),
+ UINT64_C(0xfffc1fffffffffff),
+ UINT64_C(0xfffc3fffffffffff),
+ UINT64_C(0xfffc7fffffffffff),
+ UINT64_C(0xfffcffffffffffff),
+ UINT64_C(0xfffdffffffffffff)
+ },
+ {
+ UINT64_C(0xfff8000000000000),
+ UINT64_C(0xfff8000000000001),
+ UINT64_C(0xfff8000000000003),
+ UINT64_C(0xfff8000000000007),
+ UINT64_C(0xfff800000000000f),
+ UINT64_C(0xfff800000000001f),
+ UINT64_C(0xfff800000000003f),
+ UINT64_C(0xfff800000000007f),
+ UINT64_C(0xfff80000000000ff),
+ UINT64_C(0xfff80000000001ff),
+ UINT64_C(0xfff80000000003ff),
+ UINT64_C(0xfff80000000007ff),
+ UINT64_C(0xfff8000000000fff),
+ UINT64_C(0xfff8000000001fff),
+ UINT64_C(0xfff8000000003fff),
+ UINT64_C(0xfff8000000007fff),
+ UINT64_C(0xfff800000000ffff),
+ UINT64_C(0xfff800000001ffff),
+ UINT64_C(0xfff800000003ffff),
+ UINT64_C(0xfff800000007ffff),
+ UINT64_C(0xfff80000000fffff),
+ UINT64_C(0xfff80000001fffff),
+ UINT64_C(0xfff80000003fffff),
+ UINT64_C(0xfff80000007fffff),
+ UINT64_C(0xfff8000000ffffff),
+ UINT64_C(0xfff8000001ffffff),
+ UINT64_C(0xfff8000003ffffff),
+ UINT64_C(0xfff8000007ffffff),
+ UINT64_C(0xfff800000fffffff),
+ UINT64_C(0xfff800001fffffff),
+ UINT64_C(0xfff800003fffffff),
+ UINT64_C(0xfff800007fffffff),
+ UINT64_C(0xfff80000ffffffff),
+ UINT64_C(0xfff80001ffffffff),
+ UINT64_C(0xfff80003ffffffff),
+ UINT64_C(0xfff80007ffffffff),
+ UINT64_C(0xfff8000fffffffff),
+ UINT64_C(0xfff8001fffffffff),
+ UINT64_C(0xfff8003fffffffff),
+ UINT64_C(0xfff8007fffffffff),
+ UINT64_C(0xfff800ffffffffff),
+ UINT64_C(0xfff801ffffffffff),
+ UINT64_C(0xfff803ffffffffff),
+ UINT64_C(0xfff807ffffffffff),
+ UINT64_C(0xfff80fffffffffff),
+ UINT64_C(0xfff81fffffffffff),
+ UINT64_C(0xfff83fffffffffff),
+ UINT64_C(0xfff87fffffffffff),
+ UINT64_C(0xfff8ffffffffffff),
+ UINT64_C(0xfff9ffffffffffff),
+ UINT64_C(0xfffbffffffffffff)
+ },
+ {
+ UINT64_C(0xfff0000000000000),
+ UINT64_C(0xfff0000000000001),
+ UINT64_C(0xfff0000000000003),
+ UINT64_C(0xfff0000000000007),
+ UINT64_C(0xfff000000000000f),
+ UINT64_C(0xfff000000000001f),
+ UINT64_C(0xfff000000000003f),
+ UINT64_C(0xfff000000000007f),
+ UINT64_C(0xfff00000000000ff),
+ UINT64_C(0xfff00000000001ff),
+ UINT64_C(0xfff00000000003ff),
+ UINT64_C(0xfff00000000007ff),
+ UINT64_C(0xfff0000000000fff),
+ UINT64_C(0xfff0000000001fff),
+ UINT64_C(0xfff0000000003fff),
+ UINT64_C(0xfff0000000007fff),
+ UINT64_C(0xfff000000000ffff),
+ UINT64_C(0xfff000000001ffff),
+ UINT64_C(0xfff000000003ffff),
+ UINT64_C(0xfff000000007ffff),
+ UINT64_C(0xfff00000000fffff),
+ UINT64_C(0xfff00000001fffff),
+ UINT64_C(0xfff00000003fffff),
+ UINT64_C(0xfff00000007fffff),
+ UINT64_C(0xfff0000000ffffff),
+ UINT64_C(0xfff0000001ffffff),
+ UINT64_C(0xfff0000003ffffff),
+ UINT64_C(0xfff0000007ffffff),
+ UINT64_C(0xfff000000fffffff),
+ UINT64_C(0xfff000001fffffff),
+ UINT64_C(0xfff000003fffffff),
+ UINT64_C(0xfff000007fffffff),
+ UINT64_C(0xfff00000ffffffff),
+ UINT64_C(0xfff00001ffffffff),
+ UINT64_C(0xfff00003ffffffff),
+ UINT64_C(0xfff00007ffffffff),
+ UINT64_C(0xfff0000fffffffff),
+ UINT64_C(0xfff0001fffffffff),
+ UINT64_C(0xfff0003fffffffff),
+ UINT64_C(0xfff0007fffffffff),
+ UINT64_C(0xfff000ffffffffff),
+ UINT64_C(0xfff001ffffffffff),
+ UINT64_C(0xfff003ffffffffff),
+ UINT64_C(0xfff007ffffffffff),
+ UINT64_C(0xfff00fffffffffff),
+ UINT64_C(0xfff01fffffffffff),
+ UINT64_C(0xfff03fffffffffff),
+ UINT64_C(0xfff07fffffffffff),
+ UINT64_C(0xfff0ffffffffffff),
+ UINT64_C(0xfff1ffffffffffff),
+ UINT64_C(0xfff3ffffffffffff),
+ UINT64_C(0xfff7ffffffffffff)
+ },
+ {
+ UINT64_C(0xffe0000000000000),
+ UINT64_C(0xffe0000000000001),
+ UINT64_C(0xffe0000000000003),
+ UINT64_C(0xffe0000000000007),
+ UINT64_C(0xffe000000000000f),
+ UINT64_C(0xffe000000000001f),
+ UINT64_C(0xffe000000000003f),
+ UINT64_C(0xffe000000000007f),
+ UINT64_C(0xffe00000000000ff),
+ UINT64_C(0xffe00000000001ff),
+ UINT64_C(0xffe00000000003ff),
+ UINT64_C(0xffe00000000007ff),
+ UINT64_C(0xffe0000000000fff),
+ UINT64_C(0xffe0000000001fff),
+ UINT64_C(0xffe0000000003fff),
+ UINT64_C(0xffe0000000007fff),
+ UINT64_C(0xffe000000000ffff),
+ UINT64_C(0xffe000000001ffff),
+ UINT64_C(0xffe000000003ffff),
+ UINT64_C(0xffe000000007ffff),
+ UINT64_C(0xffe00000000fffff),
+ UINT64_C(0xffe00000001fffff),
+ UINT64_C(0xffe00000003fffff),
+ UINT64_C(0xffe00000007fffff),
+ UINT64_C(0xffe0000000ffffff),
+ UINT64_C(0xffe0000001ffffff),
+ UINT64_C(0xffe0000003ffffff),
+ UINT64_C(0xffe0000007ffffff),
+ UINT64_C(0xffe000000fffffff),
+ UINT64_C(0xffe000001fffffff),
+ UINT64_C(0xffe000003fffffff),
+ UINT64_C(0xffe000007fffffff),
+ UINT64_C(0xffe00000ffffffff),
+ UINT64_C(0xffe00001ffffffff),
+ UINT64_C(0xffe00003ffffffff),
+ UINT64_C(0xffe00007ffffffff),
+ UINT64_C(0xffe0000fffffffff),
+ UINT64_C(0xffe0001fffffffff),
+ UINT64_C(0xffe0003fffffffff),
+ UINT64_C(0xffe0007fffffffff),
+ UINT64_C(0xffe000ffffffffff),
+ UINT64_C(0xffe001ffffffffff),
+ UINT64_C(0xffe003ffffffffff),
+ UINT64_C(0xffe007ffffffffff),
+ UINT64_C(0xffe00fffffffffff),
+ UINT64_C(0xffe01fffffffffff),
+ UINT64_C(0xffe03fffffffffff),
+ UINT64_C(0xffe07fffffffffff),
+ UINT64_C(0xffe0ffffffffffff),
+ UINT64_C(0xffe1ffffffffffff),
+ UINT64_C(0xffe3ffffffffffff),
+ UINT64_C(0xffe7ffffffffffff),
+ UINT64_C(0xffefffffffffffff)
+ },
+ {
+ UINT64_C(0xffc0000000000000),
+ UINT64_C(0xffc0000000000001),
+ UINT64_C(0xffc0000000000003),
+ UINT64_C(0xffc0000000000007),
+ UINT64_C(0xffc000000000000f),
+ UINT64_C(0xffc000000000001f),
+ UINT64_C(0xffc000000000003f),
+ UINT64_C(0xffc000000000007f),
+ UINT64_C(0xffc00000000000ff),
+ UINT64_C(0xffc00000000001ff),
+ UINT64_C(0xffc00000000003ff),
+ UINT64_C(0xffc00000000007ff),
+ UINT64_C(0xffc0000000000fff),
+ UINT64_C(0xffc0000000001fff),
+ UINT64_C(0xffc0000000003fff),
+ UINT64_C(0xffc0000000007fff),
+ UINT64_C(0xffc000000000ffff),
+ UINT64_C(0xffc000000001ffff),
+ UINT64_C(0xffc000000003ffff),
+ UINT64_C(0xffc000000007ffff),
+ UINT64_C(0xffc00000000fffff),
+ UINT64_C(0xffc00000001fffff),
+ UINT64_C(0xffc00000003fffff),
+ UINT64_C(0xffc00000007fffff),
+ UINT64_C(0xffc0000000ffffff),
+ UINT64_C(0xffc0000001ffffff),
+ UINT64_C(0xffc0000003ffffff),
+ UINT64_C(0xffc0000007ffffff),
+ UINT64_C(0xffc000000fffffff),
+ UINT64_C(0xffc000001fffffff),
+ UINT64_C(0xffc000003fffffff),
+ UINT64_C(0xffc000007fffffff),
+ UINT64_C(0xffc00000ffffffff),
+ UINT64_C(0xffc00001ffffffff),
+ UINT64_C(0xffc00003ffffffff),
+ UINT64_C(0xffc00007ffffffff),
+ UINT64_C(0xffc0000fffffffff),
+ UINT64_C(0xffc0001fffffffff),
+ UINT64_C(0xffc0003fffffffff),
+ UINT64_C(0xffc0007fffffffff),
+ UINT64_C(0xffc000ffffffffff),
+ UINT64_C(0xffc001ffffffffff),
+ UINT64_C(0xffc003ffffffffff),
+ UINT64_C(0xffc007ffffffffff),
+ UINT64_C(0xffc00fffffffffff),
+ UINT64_C(0xffc01fffffffffff),
+ UINT64_C(0xffc03fffffffffff),
+ UINT64_C(0xffc07fffffffffff),
+ UINT64_C(0xffc0ffffffffffff),
+ UINT64_C(0xffc1ffffffffffff),
+ UINT64_C(0xffc3ffffffffffff),
+ UINT64_C(0xffc7ffffffffffff),
+ UINT64_C(0xffcfffffffffffff),
+ UINT64_C(0xffdfffffffffffff)
+ },
+ {
+ UINT64_C(0xff80000000000000),
+ UINT64_C(0xff80000000000001),
+ UINT64_C(0xff80000000000003),
+ UINT64_C(0xff80000000000007),
+ UINT64_C(0xff8000000000000f),
+ UINT64_C(0xff8000000000001f),
+ UINT64_C(0xff8000000000003f),
+ UINT64_C(0xff8000000000007f),
+ UINT64_C(0xff800000000000ff),
+ UINT64_C(0xff800000000001ff),
+ UINT64_C(0xff800000000003ff),
+ UINT64_C(0xff800000000007ff),
+ UINT64_C(0xff80000000000fff),
+ UINT64_C(0xff80000000001fff),
+ UINT64_C(0xff80000000003fff),
+ UINT64_C(0xff80000000007fff),
+ UINT64_C(0xff8000000000ffff),
+ UINT64_C(0xff8000000001ffff),
+ UINT64_C(0xff8000000003ffff),
+ UINT64_C(0xff8000000007ffff),
+ UINT64_C(0xff800000000fffff),
+ UINT64_C(0xff800000001fffff),
+ UINT64_C(0xff800000003fffff),
+ UINT64_C(0xff800000007fffff),
+ UINT64_C(0xff80000000ffffff),
+ UINT64_C(0xff80000001ffffff),
+ UINT64_C(0xff80000003ffffff),
+ UINT64_C(0xff80000007ffffff),
+ UINT64_C(0xff8000000fffffff),
+ UINT64_C(0xff8000001fffffff),
+ UINT64_C(0xff8000003fffffff),
+ UINT64_C(0xff8000007fffffff),
+ UINT64_C(0xff800000ffffffff),
+ UINT64_C(0xff800001ffffffff),
+ UINT64_C(0xff800003ffffffff),
+ UINT64_C(0xff800007ffffffff),
+ UINT64_C(0xff80000fffffffff),
+ UINT64_C(0xff80001fffffffff),
+ UINT64_C(0xff80003fffffffff),
+ UINT64_C(0xff80007fffffffff),
+ UINT64_C(0xff8000ffffffffff),
+ UINT64_C(0xff8001ffffffffff),
+ UINT64_C(0xff8003ffffffffff),
+ UINT64_C(0xff8007ffffffffff),
+ UINT64_C(0xff800fffffffffff),
+ UINT64_C(0xff801fffffffffff),
+ UINT64_C(0xff803fffffffffff),
+ UINT64_C(0xff807fffffffffff),
+ UINT64_C(0xff80ffffffffffff),
+ UINT64_C(0xff81ffffffffffff),
+ UINT64_C(0xff83ffffffffffff),
+ UINT64_C(0xff87ffffffffffff),
+ UINT64_C(0xff8fffffffffffff),
+ UINT64_C(0xff9fffffffffffff),
+ UINT64_C(0xffbfffffffffffff)
+ },
+ {
+ UINT64_C(0xff00000000000000),
+ UINT64_C(0xff00000000000001),
+ UINT64_C(0xff00000000000003),
+ UINT64_C(0xff00000000000007),
+ UINT64_C(0xff0000000000000f),
+ UINT64_C(0xff0000000000001f),
+ UINT64_C(0xff0000000000003f),
+ UINT64_C(0xff0000000000007f),
+ UINT64_C(0xff000000000000ff),
+ UINT64_C(0xff000000000001ff),
+ UINT64_C(0xff000000000003ff),
+ UINT64_C(0xff000000000007ff),
+ UINT64_C(0xff00000000000fff),
+ UINT64_C(0xff00000000001fff),
+ UINT64_C(0xff00000000003fff),
+ UINT64_C(0xff00000000007fff),
+ UINT64_C(0xff0000000000ffff),
+ UINT64_C(0xff0000000001ffff),
+ UINT64_C(0xff0000000003ffff),
+ UINT64_C(0xff0000000007ffff),
+ UINT64_C(0xff000000000fffff),
+ UINT64_C(0xff000000001fffff),
+ UINT64_C(0xff000000003fffff),
+ UINT64_C(0xff000000007fffff),
+ UINT64_C(0xff00000000ffffff),
+ UINT64_C(0xff00000001ffffff),
+ UINT64_C(0xff00000003ffffff),
+ UINT64_C(0xff00000007ffffff),
+ UINT64_C(0xff0000000fffffff),
+ UINT64_C(0xff0000001fffffff),
+ UINT64_C(0xff0000003fffffff),
+ UINT64_C(0xff0000007fffffff),
+ UINT64_C(0xff000000ffffffff),
+ UINT64_C(0xff000001ffffffff),
+ UINT64_C(0xff000003ffffffff),
+ UINT64_C(0xff000007ffffffff),
+ UINT64_C(0xff00000fffffffff),
+ UINT64_C(0xff00001fffffffff),
+ UINT64_C(0xff00003fffffffff),
+ UINT64_C(0xff00007fffffffff),
+ UINT64_C(0xff0000ffffffffff),
+ UINT64_C(0xff0001ffffffffff),
+ UINT64_C(0xff0003ffffffffff),
+ UINT64_C(0xff0007ffffffffff),
+ UINT64_C(0xff000fffffffffff),
+ UINT64_C(0xff001fffffffffff),
+ UINT64_C(0xff003fffffffffff),
+ UINT64_C(0xff007fffffffffff),
+ UINT64_C(0xff00ffffffffffff),
+ UINT64_C(0xff01ffffffffffff),
+ UINT64_C(0xff03ffffffffffff),
+ UINT64_C(0xff07ffffffffffff),
+ UINT64_C(0xff0fffffffffffff),
+ UINT64_C(0xff1fffffffffffff),
+ UINT64_C(0xff3fffffffffffff),
+ UINT64_C(0xff7fffffffffffff)
+ },
+ {
+ UINT64_C(0xfe00000000000000),
+ UINT64_C(0xfe00000000000001),
+ UINT64_C(0xfe00000000000003),
+ UINT64_C(0xfe00000000000007),
+ UINT64_C(0xfe0000000000000f),
+ UINT64_C(0xfe0000000000001f),
+ UINT64_C(0xfe0000000000003f),
+ UINT64_C(0xfe0000000000007f),
+ UINT64_C(0xfe000000000000ff),
+ UINT64_C(0xfe000000000001ff),
+ UINT64_C(0xfe000000000003ff),
+ UINT64_C(0xfe000000000007ff),
+ UINT64_C(0xfe00000000000fff),
+ UINT64_C(0xfe00000000001fff),
+ UINT64_C(0xfe00000000003fff),
+ UINT64_C(0xfe00000000007fff),
+ UINT64_C(0xfe0000000000ffff),
+ UINT64_C(0xfe0000000001ffff),
+ UINT64_C(0xfe0000000003ffff),
+ UINT64_C(0xfe0000000007ffff),
+ UINT64_C(0xfe000000000fffff),
+ UINT64_C(0xfe000000001fffff),
+ UINT64_C(0xfe000000003fffff),
+ UINT64_C(0xfe000000007fffff),
+ UINT64_C(0xfe00000000ffffff),
+ UINT64_C(0xfe00000001ffffff),
+ UINT64_C(0xfe00000003ffffff),
+ UINT64_C(0xfe00000007ffffff),
+ UINT64_C(0xfe0000000fffffff),
+ UINT64_C(0xfe0000001fffffff),
+ UINT64_C(0xfe0000003fffffff),
+ UINT64_C(0xfe0000007fffffff),
+ UINT64_C(0xfe000000ffffffff),
+ UINT64_C(0xfe000001ffffffff),
+ UINT64_C(0xfe000003ffffffff),
+ UINT64_C(0xfe000007ffffffff),
+ UINT64_C(0xfe00000fffffffff),
+ UINT64_C(0xfe00001fffffffff),
+ UINT64_C(0xfe00003fffffffff),
+ UINT64_C(0xfe00007fffffffff),
+ UINT64_C(0xfe0000ffffffffff),
+ UINT64_C(0xfe0001ffffffffff),
+ UINT64_C(0xfe0003ffffffffff),
+ UINT64_C(0xfe0007ffffffffff),
+ UINT64_C(0xfe000fffffffffff),
+ UINT64_C(0xfe001fffffffffff),
+ UINT64_C(0xfe003fffffffffff),
+ UINT64_C(0xfe007fffffffffff),
+ UINT64_C(0xfe00ffffffffffff),
+ UINT64_C(0xfe01ffffffffffff),
+ UINT64_C(0xfe03ffffffffffff),
+ UINT64_C(0xfe07ffffffffffff),
+ UINT64_C(0xfe0fffffffffffff),
+ UINT64_C(0xfe1fffffffffffff),
+ UINT64_C(0xfe3fffffffffffff),
+ UINT64_C(0xfe7fffffffffffff),
+ UINT64_C(0xfeffffffffffffff)
+ },
+ {
+ UINT64_C(0xfc00000000000000),
+ UINT64_C(0xfc00000000000001),
+ UINT64_C(0xfc00000000000003),
+ UINT64_C(0xfc00000000000007),
+ UINT64_C(0xfc0000000000000f),
+ UINT64_C(0xfc0000000000001f),
+ UINT64_C(0xfc0000000000003f),
+ UINT64_C(0xfc0000000000007f),
+ UINT64_C(0xfc000000000000ff),
+ UINT64_C(0xfc000000000001ff),
+ UINT64_C(0xfc000000000003ff),
+ UINT64_C(0xfc000000000007ff),
+ UINT64_C(0xfc00000000000fff),
+ UINT64_C(0xfc00000000001fff),
+ UINT64_C(0xfc00000000003fff),
+ UINT64_C(0xfc00000000007fff),
+ UINT64_C(0xfc0000000000ffff),
+ UINT64_C(0xfc0000000001ffff),
+ UINT64_C(0xfc0000000003ffff),
+ UINT64_C(0xfc0000000007ffff),
+ UINT64_C(0xfc000000000fffff),
+ UINT64_C(0xfc000000001fffff),
+ UINT64_C(0xfc000000003fffff),
+ UINT64_C(0xfc000000007fffff),
+ UINT64_C(0xfc00000000ffffff),
+ UINT64_C(0xfc00000001ffffff),
+ UINT64_C(0xfc00000003ffffff),
+ UINT64_C(0xfc00000007ffffff),
+ UINT64_C(0xfc0000000fffffff),
+ UINT64_C(0xfc0000001fffffff),
+ UINT64_C(0xfc0000003fffffff),
+ UINT64_C(0xfc0000007fffffff),
+ UINT64_C(0xfc000000ffffffff),
+ UINT64_C(0xfc000001ffffffff),
+ UINT64_C(0xfc000003ffffffff),
+ UINT64_C(0xfc000007ffffffff),
+ UINT64_C(0xfc00000fffffffff),
+ UINT64_C(0xfc00001fffffffff),
+ UINT64_C(0xfc00003fffffffff),
+ UINT64_C(0xfc00007fffffffff),
+ UINT64_C(0xfc0000ffffffffff),
+ UINT64_C(0xfc0001ffffffffff),
+ UINT64_C(0xfc0003ffffffffff),
+ UINT64_C(0xfc0007ffffffffff),
+ UINT64_C(0xfc000fffffffffff),
+ UINT64_C(0xfc001fffffffffff),
+ UINT64_C(0xfc003fffffffffff),
+ UINT64_C(0xfc007fffffffffff),
+ UINT64_C(0xfc00ffffffffffff),
+ UINT64_C(0xfc01ffffffffffff),
+ UINT64_C(0xfc03ffffffffffff),
+ UINT64_C(0xfc07ffffffffffff),
+ UINT64_C(0xfc0fffffffffffff),
+ UINT64_C(0xfc1fffffffffffff),
+ UINT64_C(0xfc3fffffffffffff),
+ UINT64_C(0xfc7fffffffffffff),
+ UINT64_C(0xfcffffffffffffff),
+ UINT64_C(0xfdffffffffffffff)
+ },
+ {
+ UINT64_C(0xf800000000000000),
+ UINT64_C(0xf800000000000001),
+ UINT64_C(0xf800000000000003),
+ UINT64_C(0xf800000000000007),
+ UINT64_C(0xf80000000000000f),
+ UINT64_C(0xf80000000000001f),
+ UINT64_C(0xf80000000000003f),
+ UINT64_C(0xf80000000000007f),
+ UINT64_C(0xf8000000000000ff),
+ UINT64_C(0xf8000000000001ff),
+ UINT64_C(0xf8000000000003ff),
+ UINT64_C(0xf8000000000007ff),
+ UINT64_C(0xf800000000000fff),
+ UINT64_C(0xf800000000001fff),
+ UINT64_C(0xf800000000003fff),
+ UINT64_C(0xf800000000007fff),
+ UINT64_C(0xf80000000000ffff),
+ UINT64_C(0xf80000000001ffff),
+ UINT64_C(0xf80000000003ffff),
+ UINT64_C(0xf80000000007ffff),
+ UINT64_C(0xf8000000000fffff),
+ UINT64_C(0xf8000000001fffff),
+ UINT64_C(0xf8000000003fffff),
+ UINT64_C(0xf8000000007fffff),
+ UINT64_C(0xf800000000ffffff),
+ UINT64_C(0xf800000001ffffff),
+ UINT64_C(0xf800000003ffffff),
+ UINT64_C(0xf800000007ffffff),
+ UINT64_C(0xf80000000fffffff),
+ UINT64_C(0xf80000001fffffff),
+ UINT64_C(0xf80000003fffffff),
+ UINT64_C(0xf80000007fffffff),
+ UINT64_C(0xf8000000ffffffff),
+ UINT64_C(0xf8000001ffffffff),
+ UINT64_C(0xf8000003ffffffff),
+ UINT64_C(0xf8000007ffffffff),
+ UINT64_C(0xf800000fffffffff),
+ UINT64_C(0xf800001fffffffff),
+ UINT64_C(0xf800003fffffffff),
+ UINT64_C(0xf800007fffffffff),
+ UINT64_C(0xf80000ffffffffff),
+ UINT64_C(0xf80001ffffffffff),
+ UINT64_C(0xf80003ffffffffff),
+ UINT64_C(0xf80007ffffffffff),
+ UINT64_C(0xf8000fffffffffff),
+ UINT64_C(0xf8001fffffffffff),
+ UINT64_C(0xf8003fffffffffff),
+ UINT64_C(0xf8007fffffffffff),
+ UINT64_C(0xf800ffffffffffff),
+ UINT64_C(0xf801ffffffffffff),
+ UINT64_C(0xf803ffffffffffff),
+ UINT64_C(0xf807ffffffffffff),
+ UINT64_C(0xf80fffffffffffff),
+ UINT64_C(0xf81fffffffffffff),
+ UINT64_C(0xf83fffffffffffff),
+ UINT64_C(0xf87fffffffffffff),
+ UINT64_C(0xf8ffffffffffffff),
+ UINT64_C(0xf9ffffffffffffff),
+ UINT64_C(0xfbffffffffffffff)
+ },
+ {
+ UINT64_C(0xf000000000000000),
+ UINT64_C(0xf000000000000001),
+ UINT64_C(0xf000000000000003),
+ UINT64_C(0xf000000000000007),
+ UINT64_C(0xf00000000000000f),
+ UINT64_C(0xf00000000000001f),
+ UINT64_C(0xf00000000000003f),
+ UINT64_C(0xf00000000000007f),
+ UINT64_C(0xf0000000000000ff),
+ UINT64_C(0xf0000000000001ff),
+ UINT64_C(0xf0000000000003ff),
+ UINT64_C(0xf0000000000007ff),
+ UINT64_C(0xf000000000000fff),
+ UINT64_C(0xf000000000001fff),
+ UINT64_C(0xf000000000003fff),
+ UINT64_C(0xf000000000007fff),
+ UINT64_C(0xf00000000000ffff),
+ UINT64_C(0xf00000000001ffff),
+ UINT64_C(0xf00000000003ffff),
+ UINT64_C(0xf00000000007ffff),
+ UINT64_C(0xf0000000000fffff),
+ UINT64_C(0xf0000000001fffff),
+ UINT64_C(0xf0000000003fffff),
+ UINT64_C(0xf0000000007fffff),
+ UINT64_C(0xf000000000ffffff),
+ UINT64_C(0xf000000001ffffff),
+ UINT64_C(0xf000000003ffffff),
+ UINT64_C(0xf000000007ffffff),
+ UINT64_C(0xf00000000fffffff),
+ UINT64_C(0xf00000001fffffff),
+ UINT64_C(0xf00000003fffffff),
+ UINT64_C(0xf00000007fffffff),
+ UINT64_C(0xf0000000ffffffff),
+ UINT64_C(0xf0000001ffffffff),
+ UINT64_C(0xf0000003ffffffff),
+ UINT64_C(0xf0000007ffffffff),
+ UINT64_C(0xf000000fffffffff),
+ UINT64_C(0xf000001fffffffff),
+ UINT64_C(0xf000003fffffffff),
+ UINT64_C(0xf000007fffffffff),
+ UINT64_C(0xf00000ffffffffff),
+ UINT64_C(0xf00001ffffffffff),
+ UINT64_C(0xf00003ffffffffff),
+ UINT64_C(0xf00007ffffffffff),
+ UINT64_C(0xf0000fffffffffff),
+ UINT64_C(0xf0001fffffffffff),
+ UINT64_C(0xf0003fffffffffff),
+ UINT64_C(0xf0007fffffffffff),
+ UINT64_C(0xf000ffffffffffff),
+ UINT64_C(0xf001ffffffffffff),
+ UINT64_C(0xf003ffffffffffff),
+ UINT64_C(0xf007ffffffffffff),
+ UINT64_C(0xf00fffffffffffff),
+ UINT64_C(0xf01fffffffffffff),
+ UINT64_C(0xf03fffffffffffff),
+ UINT64_C(0xf07fffffffffffff),
+ UINT64_C(0xf0ffffffffffffff),
+ UINT64_C(0xf1ffffffffffffff),
+ UINT64_C(0xf3ffffffffffffff),
+ UINT64_C(0xf7ffffffffffffff)
+ },
+ {
+ UINT64_C(0xe000000000000000),
+ UINT64_C(0xe000000000000001),
+ UINT64_C(0xe000000000000003),
+ UINT64_C(0xe000000000000007),
+ UINT64_C(0xe00000000000000f),
+ UINT64_C(0xe00000000000001f),
+ UINT64_C(0xe00000000000003f),
+ UINT64_C(0xe00000000000007f),
+ UINT64_C(0xe0000000000000ff),
+ UINT64_C(0xe0000000000001ff),
+ UINT64_C(0xe0000000000003ff),
+ UINT64_C(0xe0000000000007ff),
+ UINT64_C(0xe000000000000fff),
+ UINT64_C(0xe000000000001fff),
+ UINT64_C(0xe000000000003fff),
+ UINT64_C(0xe000000000007fff),
+ UINT64_C(0xe00000000000ffff),
+ UINT64_C(0xe00000000001ffff),
+ UINT64_C(0xe00000000003ffff),
+ UINT64_C(0xe00000000007ffff),
+ UINT64_C(0xe0000000000fffff),
+ UINT64_C(0xe0000000001fffff),
+ UINT64_C(0xe0000000003fffff),
+ UINT64_C(0xe0000000007fffff),
+ UINT64_C(0xe000000000ffffff),
+ UINT64_C(0xe000000001ffffff),
+ UINT64_C(0xe000000003ffffff),
+ UINT64_C(0xe000000007ffffff),
+ UINT64_C(0xe00000000fffffff),
+ UINT64_C(0xe00000001fffffff),
+ UINT64_C(0xe00000003fffffff),
+ UINT64_C(0xe00000007fffffff),
+ UINT64_C(0xe0000000ffffffff),
+ UINT64_C(0xe0000001ffffffff),
+ UINT64_C(0xe0000003ffffffff),
+ UINT64_C(0xe0000007ffffffff),
+ UINT64_C(0xe000000fffffffff),
+ UINT64_C(0xe000001fffffffff),
+ UINT64_C(0xe000003fffffffff),
+ UINT64_C(0xe000007fffffffff),
+ UINT64_C(0xe00000ffffffffff),
+ UINT64_C(0xe00001ffffffffff),
+ UINT64_C(0xe00003ffffffffff),
+ UINT64_C(0xe00007ffffffffff),
+ UINT64_C(0xe0000fffffffffff),
+ UINT64_C(0xe0001fffffffffff),
+ UINT64_C(0xe0003fffffffffff),
+ UINT64_C(0xe0007fffffffffff),
+ UINT64_C(0xe000ffffffffffff),
+ UINT64_C(0xe001ffffffffffff),
+ UINT64_C(0xe003ffffffffffff),
+ UINT64_C(0xe007ffffffffffff),
+ UINT64_C(0xe00fffffffffffff),
+ UINT64_C(0xe01fffffffffffff),
+ UINT64_C(0xe03fffffffffffff),
+ UINT64_C(0xe07fffffffffffff),
+ UINT64_C(0xe0ffffffffffffff),
+ UINT64_C(0xe1ffffffffffffff),
+ UINT64_C(0xe3ffffffffffffff),
+ UINT64_C(0xe7ffffffffffffff),
+ UINT64_C(0xefffffffffffffff)
+ },
+ {
+ UINT64_C(0xc000000000000000),
+ UINT64_C(0xc000000000000001),
+ UINT64_C(0xc000000000000003),
+ UINT64_C(0xc000000000000007),
+ UINT64_C(0xc00000000000000f),
+ UINT64_C(0xc00000000000001f),
+ UINT64_C(0xc00000000000003f),
+ UINT64_C(0xc00000000000007f),
+ UINT64_C(0xc0000000000000ff),
+ UINT64_C(0xc0000000000001ff),
+ UINT64_C(0xc0000000000003ff),
+ UINT64_C(0xc0000000000007ff),
+ UINT64_C(0xc000000000000fff),
+ UINT64_C(0xc000000000001fff),
+ UINT64_C(0xc000000000003fff),
+ UINT64_C(0xc000000000007fff),
+ UINT64_C(0xc00000000000ffff),
+ UINT64_C(0xc00000000001ffff),
+ UINT64_C(0xc00000000003ffff),
+ UINT64_C(0xc00000000007ffff),
+ UINT64_C(0xc0000000000fffff),
+ UINT64_C(0xc0000000001fffff),
+ UINT64_C(0xc0000000003fffff),
+ UINT64_C(0xc0000000007fffff),
+ UINT64_C(0xc000000000ffffff),
+ UINT64_C(0xc000000001ffffff),
+ UINT64_C(0xc000000003ffffff),
+ UINT64_C(0xc000000007ffffff),
+ UINT64_C(0xc00000000fffffff),
+ UINT64_C(0xc00000001fffffff),
+ UINT64_C(0xc00000003fffffff),
+ UINT64_C(0xc00000007fffffff),
+ UINT64_C(0xc0000000ffffffff),
+ UINT64_C(0xc0000001ffffffff),
+ UINT64_C(0xc0000003ffffffff),
+ UINT64_C(0xc0000007ffffffff),
+ UINT64_C(0xc000000fffffffff),
+ UINT64_C(0xc000001fffffffff),
+ UINT64_C(0xc000003fffffffff),
+ UINT64_C(0xc000007fffffffff),
+ UINT64_C(0xc00000ffffffffff),
+ UINT64_C(0xc00001ffffffffff),
+ UINT64_C(0xc00003ffffffffff),
+ UINT64_C(0xc00007ffffffffff),
+ UINT64_C(0xc0000fffffffffff),
+ UINT64_C(0xc0001fffffffffff),
+ UINT64_C(0xc0003fffffffffff),
+ UINT64_C(0xc0007fffffffffff),
+ UINT64_C(0xc000ffffffffffff),
+ UINT64_C(0xc001ffffffffffff),
+ UINT64_C(0xc003ffffffffffff),
+ UINT64_C(0xc007ffffffffffff),
+ UINT64_C(0xc00fffffffffffff),
+ UINT64_C(0xc01fffffffffffff),
+ UINT64_C(0xc03fffffffffffff),
+ UINT64_C(0xc07fffffffffffff),
+ UINT64_C(0xc0ffffffffffffff),
+ UINT64_C(0xc1ffffffffffffff),
+ UINT64_C(0xc3ffffffffffffff),
+ UINT64_C(0xc7ffffffffffffff),
+ UINT64_C(0xcfffffffffffffff),
+ UINT64_C(0xdfffffffffffffff)
+ },
+ {
+ UINT64_C(0x8000000000000000),
+ UINT64_C(0x8000000000000001),
+ UINT64_C(0x8000000000000003),
+ UINT64_C(0x8000000000000007),
+ UINT64_C(0x800000000000000f),
+ UINT64_C(0x800000000000001f),
+ UINT64_C(0x800000000000003f),
+ UINT64_C(0x800000000000007f),
+ UINT64_C(0x80000000000000ff),
+ UINT64_C(0x80000000000001ff),
+ UINT64_C(0x80000000000003ff),
+ UINT64_C(0x80000000000007ff),
+ UINT64_C(0x8000000000000fff),
+ UINT64_C(0x8000000000001fff),
+ UINT64_C(0x8000000000003fff),
+ UINT64_C(0x8000000000007fff),
+ UINT64_C(0x800000000000ffff),
+ UINT64_C(0x800000000001ffff),
+ UINT64_C(0x800000000003ffff),
+ UINT64_C(0x800000000007ffff),
+ UINT64_C(0x80000000000fffff),
+ UINT64_C(0x80000000001fffff),
+ UINT64_C(0x80000000003fffff),
+ UINT64_C(0x80000000007fffff),
+ UINT64_C(0x8000000000ffffff),
+ UINT64_C(0x8000000001ffffff),
+ UINT64_C(0x8000000003ffffff),
+ UINT64_C(0x8000000007ffffff),
+ UINT64_C(0x800000000fffffff),
+ UINT64_C(0x800000001fffffff),
+ UINT64_C(0x800000003fffffff),
+ UINT64_C(0x800000007fffffff),
+ UINT64_C(0x80000000ffffffff),
+ UINT64_C(0x80000001ffffffff),
+ UINT64_C(0x80000003ffffffff),
+ UINT64_C(0x80000007ffffffff),
+ UINT64_C(0x8000000fffffffff),
+ UINT64_C(0x8000001fffffffff),
+ UINT64_C(0x8000003fffffffff),
+ UINT64_C(0x8000007fffffffff),
+ UINT64_C(0x800000ffffffffff),
+ UINT64_C(0x800001ffffffffff),
+ UINT64_C(0x800003ffffffffff),
+ UINT64_C(0x800007ffffffffff),
+ UINT64_C(0x80000fffffffffff),
+ UINT64_C(0x80001fffffffffff),
+ UINT64_C(0x80003fffffffffff),
+ UINT64_C(0x80007fffffffffff),
+ UINT64_C(0x8000ffffffffffff),
+ UINT64_C(0x8001ffffffffffff),
+ UINT64_C(0x8003ffffffffffff),
+ UINT64_C(0x8007ffffffffffff),
+ UINT64_C(0x800fffffffffffff),
+ UINT64_C(0x801fffffffffffff),
+ UINT64_C(0x803fffffffffffff),
+ UINT64_C(0x807fffffffffffff),
+ UINT64_C(0x80ffffffffffffff),
+ UINT64_C(0x81ffffffffffffff),
+ UINT64_C(0x83ffffffffffffff),
+ UINT64_C(0x87ffffffffffffff),
+ UINT64_C(0x8fffffffffffffff),
+ UINT64_C(0x9fffffffffffffff),
+ UINT64_C(0xbfffffffffffffff)
+ },
+ {
+ UINT64_C(0x0),
+ UINT64_C(0x1),
+ UINT64_C(0x3),
+ UINT64_C(0x7),
+ UINT64_C(0xf),
+ UINT64_C(0x1f),
+ UINT64_C(0x3f),
+ UINT64_C(0x7f),
+ UINT64_C(0xff),
+ UINT64_C(0x1ff),
+ UINT64_C(0x3ff),
+ UINT64_C(0x7ff),
+ UINT64_C(0xfff),
+ UINT64_C(0x1fff),
+ UINT64_C(0x3fff),
+ UINT64_C(0x7fff),
+ UINT64_C(0xffff),
+ UINT64_C(0x1ffff),
+ UINT64_C(0x3ffff),
+ UINT64_C(0x7ffff),
+ UINT64_C(0xfffff),
+ UINT64_C(0x1fffff),
+ UINT64_C(0x3fffff),
+ UINT64_C(0x7fffff),
+ UINT64_C(0xffffff),
+ UINT64_C(0x1ffffff),
+ UINT64_C(0x3ffffff),
+ UINT64_C(0x7ffffff),
+ UINT64_C(0xfffffff),
+ UINT64_C(0x1fffffff),
+ UINT64_C(0x3fffffff),
+ UINT64_C(0x7fffffff),
+ UINT64_C(0xffffffff),
+ UINT64_C(0x1ffffffff),
+ UINT64_C(0x3ffffffff),
+ UINT64_C(0x7ffffffff),
+ UINT64_C(0xfffffffff),
+ UINT64_C(0x1fffffffff),
+ UINT64_C(0x3fffffffff),
+ UINT64_C(0x7fffffffff),
+ UINT64_C(0xffffffffff),
+ UINT64_C(0x1ffffffffff),
+ UINT64_C(0x3ffffffffff),
+ UINT64_C(0x7ffffffffff),
+ UINT64_C(0xfffffffffff),
+ UINT64_C(0x1fffffffffff),
+ UINT64_C(0x3fffffffffff),
+ UINT64_C(0x7fffffffffff),
+ UINT64_C(0xffffffffffff),
+ UINT64_C(0x1ffffffffffff),
+ UINT64_C(0x3ffffffffffff),
+ UINT64_C(0x7ffffffffffff),
+ UINT64_C(0xfffffffffffff),
+ UINT64_C(0x1fffffffffffff),
+ UINT64_C(0x3fffffffffffff),
+ UINT64_C(0x7fffffffffffff),
+ UINT64_C(0xffffffffffffff),
+ UINT64_C(0x1ffffffffffffff),
+ UINT64_C(0x3ffffffffffffff),
+ UINT64_C(0x7ffffffffffffff),
+ UINT64_C(0xfffffffffffffff),
+ UINT64_C(0x1fffffffffffffff),
+ UINT64_C(0x3fffffffffffffff),
+ UINT64_C(0x7fffffffffffffff)
+ }
+};
+
+} // namespace sc_dt
diff --git a/src/systemc/dt/int/sc_length_param.cc b/src/systemc/dt/int/sc_length_param.cc
new file mode 100644
index 000000000..920da13b5
--- /dev/null
+++ b/src/systemc/dt/int/sc_length_param.cc
@@ -0,0 +1,91 @@
+/*****************************************************************************
+
+ 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 <sstream>
+
+#include "systemc/ext/dt/int/sc_length_param.hh"
+
+namespace sc_dt
+{
+
+// explicit template instantiations
+template class sc_global<sc_length_param>;
+template class sc_context<sc_length_param>;
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_length_param
+//
+// Length parameter type.
+// ----------------------------------------------------------------------------
+
+const std::string
+sc_length_param::to_string() const
+{
+ std::stringstream ss;
+ print(ss);
+ return ss.str();
+}
+
+void
+sc_length_param::print(::std::ostream &os) const
+{
+ os << "(" << m_len << ")";
+}
+
+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
diff --git a/src/systemc/dt/int/sc_nbcommon.inc b/src/systemc/dt/int/sc_nbcommon.inc
new file mode 100644
index 000000000..90507ff91
--- /dev/null
+++ b/src/systemc/dt/int/sc_nbcommon.inc
@@ -0,0 +1,2617 @@
+/*****************************************************************************
+
+ 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 {
+ invalid_init("int nb", nb);
+ sc_core::sc_abort(); // can't recover from here
+ }
+ 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 {
+ invalid_init("sc_bv_base", nb);
+ sc_core::sc_abort(); // can't recover from here
+ }
+ 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 {
+ invalid_init("sc_lv_base", nb);
+ sc_core::sc_abort(); // can't recover from here
+ }
+ 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 {
+ invalid_init("sc_int_subref", nb);
+ sc_core::sc_abort(); // can't recover from here
+ }
+ 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 {
+ invalid_init("sc_uint_subref", nb);
+ sc_core::sc_abort(); // can't recover from here
+ }
+ 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 {
+ invalid_init("sc_signed_subref", nb);
+ sc_core::sc_abort(); // can't recover from here
+ }
+ 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 {
+ invalid_init("sc_unsigned_subref", nb);
+ sc_core::sc_abort(); // can't recover from here
+ }
+ 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.
+ ::std::ios::fmtflags old_flags =
+ os.setf(::std::ios::dec, ::std::ios::basefield);
+
+ 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) {
+ std::stringstream msg;
+ msg << CLASS_TYPE_STR "::check_if_outside(int bit_num) : "
+ "bit_num = " << bit_num << " is out of bounds";
+ SC_REPORT_WARNING(sc_core::SC_ID_OUT_OF_BOUNDS_,
+ msg.str().c_str());
+ }
+#endif
+ return true;
+ }
+ return false;
+}
diff --git a/src/systemc/dt/int/sc_nbexterns.cc b/src/systemc/dt/int/sc_nbexterns.cc
new file mode 100644
index 000000000..479e68e85
--- /dev/null
+++ b/src/systemc/dt/int/sc_nbexterns.cc
@@ -0,0 +1,739 @@
+/*****************************************************************************
+
+ 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 "systemc/ext/dt/int/sc_nbexterns.hh"
+#include "systemc/ext/utils/functions.hh"
+
+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
diff --git a/src/systemc/dt/int/sc_nbfriends.inc b/src/systemc/dt/int/sc_nbfriends.inc
new file mode 100644
index 000000000..9161692f0
--- /dev/null
+++ b/src/systemc/dt/int/sc_nbfriends.inc
@@ -0,0 +1,582 @@
+/*****************************************************************************
+
+ 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);
+ }
+ } else {
+ // case 4
+ 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);
+}
diff --git a/src/systemc/dt/int/sc_nbutils.cc b/src/systemc/dt/int/sc_nbutils.cc
new file mode 100644
index 000000000..df7cc554d
--- /dev/null
+++ b/src/systemc/dt/int/sc_nbutils.cc
@@ -0,0 +1,1749 @@
+/*****************************************************************************
+
+ 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 <cctype>
+#include <cstdio>
+#include <cstring>
+#include <sstream>
+
+#include "systemc/ext/dt/int/sc_nbutils.hh"
+#include "systemc/ext/utils/functions.hh"
+
+namespace sc_dt
+{
+
+// only used within vec_from_str (non-standard, deprecated)
+static 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("not implemented",
+ "is_valid_base( sc_numrep base ) : "
+ "bases SC_CSD, or ending in _US and _SM are "
+ "not supported");
+ break;
+ default:
+ std::stringstream msg;
+ msg << "is_valid_base( sc_numrep base ) : base = " << base <<
+ " is not valid";
+ SC_REPORT_ERROR("value is not valid", msg.str().c_str() );
+ }
+}
+
+// ----------------------------------------------------------------------------
+// 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.
+ sc_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
+ sc_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;
+ }
+ }
+
+ // 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".
+ sc_assert(nskip <= 3);
+
+ v += nskip;
+
+ // Handles empty strings or strings without any digits after the
+ // base or base and sign specifier.
+ if (*v == '\0') {
+ static const char msg[] =
+ "get_base_and_sign( const char* v, small_type&, small_type& ) : "
+ "v = \"\" is not valid";
+ SC_REPORT_ERROR("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("conversion failed",
+ "character string is zero");
+ return;
+ }
+ if (*src_p == 0) {
+ SC_REPORT_ERROR("conversion failed",
+ "character string is empty");
+ return;
+ }
+
+
+ // 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;
+ 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:
+ {
+ std::stringstream msg;
+ msg << "character string '" << src_p <<
+ "' is not valid";
+ SC_REPORT_ERROR("conversion failed",
+ msg.str().c_str());
+ return;
+ }
+ 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:
+ {
+ std::stringstream msg;
+ msg << "character string '" << src_p <<
+ "' is not valid";
+ SC_REPORT_ERROR("conversion failed",
+ msg.str().c_str());
+ return;
+ }
+ 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("conversion failed",
+ "character string is zero");
+ return;
+ }
+ if (*src_p == 0) {
+ SC_REPORT_ERROR("conversion failed",
+ "character string is empty");
+ return;
+ }
+
+ // 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;
+ 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:
+ {
+ std::stringstream msg;
+ msg << "character string '" << src_p <<
+ "' is not valid";
+ SC_REPORT_ERROR("conversion failed",
+ msg.str().c_str());
+ return;
+ }
+ 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:
+ {
+ std::stringstream msg;
+ msg << "character string '" << src_p << "' is not valid";
+ SC_REPORT_ERROR("conversion failed",
+ msg.str().c_str() );
+ return;
+ }
+ 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
+ sc_assert((unb > 0) && (und > 0) && (u != NULL));
+ sc_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 {
+ std::stringstream msg;
+ msg << "vec_from_str( int, int, sc_digit*, const char*, " <<
+ "sc_numrep base ) : base = " << base <<
+ " does not match the default base";
+ SC_REPORT_ERROR("conversion failed",
+ msg.str().c_str());
+ return 0;
+ }
+ }
+
+ 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) {
+ std::stringstream msg;
+ msg << "vec_from_str( int, int, sc_digit*, const char*, " <<
+ "sc_numrep base ) : '" << *v << "' is not a valid " <<
+ "digit in base " << b;
+ SC_REPORT_ERROR("conversion failed",
+ msg.str().c_str());
+ return 0;
+ }
+
+ // digit = digit * b + val;
+ vec_mul_small_on(und, u, b);
+
+ if (val)
+ vec_add_small_on(und, u, val);
+ } else {
+ std::stringstream msg;
+ msg << "vec_from_str( int, int, sc_digit*, const char*, " <<
+ "sc_numrep base ) : '" << *v << "' is not a valid " <<
+ "digit in base " << b;
+ SC_REPORT_ERROR("conversion failed",
+ msg.str().c_str());
+ return 0;
+ }
+ }
+
+ 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
+ sc_assert((ulen > 0) && (u != NULL));
+ sc_assert((vlen > 0) && (v != NULL));
+ sc_assert(w != NULL);
+ sc_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
+ sc_assert((ulen > 0) && (ubegin != NULL));
+ sc_assert((vlen > 0) && (v != NULL));
+ sc_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
+ sc_assert((ulen > 0) && (ubegin != NULL));
+ sc_assert((vlen > 0) && (v != NULL));
+ sc_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
+ sc_assert((ulen > 0) && (u != NULL));
+ sc_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
+ sc_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
+ sc_assert((ulen > 0) && (u != NULL));
+ sc_assert((vlen > 0) && (v != NULL));
+ sc_assert(w != NULL);
+ sc_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
+ sc_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
+ sc_assert((ulen > 0) && (ubegin != NULL));
+ sc_assert((vlen > 0) && (v != NULL));
+ sc_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
+ sc_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
+ sc_assert((ulen > 0) && (ubegin != NULL));
+ sc_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
+ sc_assert(ulen > 0);
+ sc_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
+ sc_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
+ sc_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
+ sc_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
+ sc_assert((ulen > 0) && (u != NULL));
+ sc_assert((vlen > 0) && (vbegin != NULL));
+ sc_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.
+ sc_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.
+ sc_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
+ sc_assert((ulen > 0) && (u != NULL));
+ sc_assert(w != NULL);
+ sc_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.
+ sc_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
+ sc_assert((ulen > 0) && (u != NULL));
+ sc_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.
+ sc_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
+ sc_assert((ulen > 0) && (u != NULL));
+ sc_assert((vlen > 0) && (v != NULL));
+ sc_assert(w != NULL);
+ sc_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
+ sc_assert(xlen > 1);
+ sc_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:
+ // 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
+ sc_assert((ulen > 0) && (u != NULL));
+ sc_assert(q != NULL);
+ sc_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.
+ sc_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
+ sc_assert((ulen > 0) && (u != NULL));
+ sc_assert((vlen > 0) && (v != NULL));
+ sc_assert(w != NULL);
+ sc_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
+ sc_assert(xlen > 1);
+ sc_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
+ sc_assert((ulen > 0) && (u != NULL));
+ sc_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.
+ sc_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
+ sc_assert((ulen > 0) && (u != NULL));
+ sc_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.
+ sc_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
+ sc_assert((ulen > 0) && (u != NULL));
+ sc_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
+ sc_assert((ulen > 0) && (u != NULL));
+ sc_assert((vlen > 0) && (v != NULL));
+ sc_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
+ sc_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
+ sc_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
+ sc_assert((unb > 0) && (und > 0) && (ud != NULL));
+ sc_assert((0 <= r) && (r <= l) && (l < unb));
+#endif
+
+ if (l < r) {
+ std::stringstream msg;
+ msg << "vec_reverse( int, int, sc_digit*, int l, int r ) : " <<
+ "l = " << l << " < r = " << r << " is not valid",
+ SC_REPORT_ERROR("conversion failed", msg.str().c_str());
+ return;
+ }
+
+ // 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
+}
+
+#ifdef SC_MAX_NBITS
+void test_bound_failed(int nb)
+{
+ std::stringstream msg;
+ msg << "test_bound( int nb ) : "
+ "nb = " << nb << " > SC_MAX_NBITS = " << SC_MAX_NBITS <<
+ " is not valid";
+ SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, msg.str().c_str());
+}
+#endif // SC_MAX_NBITS
+
+} // namespace sc_dt
diff --git a/src/systemc/dt/int/sc_signed.cc b/src/systemc/dt/int/sc_signed.cc
new file mode 100644
index 000000000..63a2d0330
--- /dev/null
+++ b/src/systemc/dt/int/sc_signed.cc
@@ -0,0 +1,3982 @@
+/*****************************************************************************
+
+ 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 <cctype>
+#include <cmath>
+#include <sstream>
+
+#include "systemc/ext/dt/bit/sc_bv_base.hh"
+#include "systemc/ext/dt/bit/sc_lv_base.hh"
+#include "systemc/ext/dt/fx/sc_fix.hh"
+#include "systemc/ext/dt/fx/scfx_other_defs.hh"
+#include "systemc/ext/dt/int/sc_int_base.hh"
+#include "systemc/ext/dt/int/sc_signed.hh"
+#include "systemc/ext/dt/int/sc_uint_base.hh"
+#include "systemc/ext/dt/int/sc_unsigned.hh"
+#include "systemc/ext/dt/misc/sc_concatref.hh"
+
+// explicit template instantiations
+namespace sc_core
+{
+
+template class sc_vpool<sc_dt::sc_signed_bitref>;
+template class sc_vpool<sc_dt::sc_signed_subref>;
+
+} // namespace sc_core
+
+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);
+
+void
+sc_signed::invalid_init(const char *type_name, int nb) const
+{
+ std::stringstream msg;
+ msg << "sc_signed("<< type_name << ") : nb = " << nb << " is not valid";
+ SC_REPORT_ERROR("initialization failed", msg.str().c_str());
+}
+
+// ----------------------------------------------------------------------------
+// SECTION: Public members - Invalid selections.
+// ----------------------------------------------------------------------------
+
+void
+sc_signed::invalid_index(int i) const
+{
+ std::stringstream msg;
+ msg << "sc_bigint bit selection: index = " << i << " violates "
+ "0 <= index <= " << (nbits - 1);
+ SC_REPORT_ERROR("out of bounds", msg.str().c_str());
+ sc_core::sc_abort(); // can't recover from here
+}
+
+void
+sc_signed::invalid_range(int l, int r) const
+{
+ std::stringstream msg;
+ msg << "sc_bigint part selection: left = " <<
+ l << ", right = " << r << "\n"
+ " violates either (" << (nbits-1) << " >= left >= 0) or "
+ "(" << (nbits-1) << " >= right >= 0)";
+ SC_REPORT_ERROR("out of bounds", msg.str().c_str());
+ sc_core::sc_abort(); // can't recover from here
+}
+
+
+// ----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+// 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 = ~(~0U << 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 = ~(~0U << 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 = ~(~1U << 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 = ~(~0U << 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 = ~(~1U << 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 = ~(~0U << nbits);
+ right_word = ((digit[0] ^ DIGIT_MASK) + 1) & mask;
+ mask = ~(~0U << 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 = (~(~1U << 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 = ~(~0U << 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 = ~(~1U << 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 = ~(~0U << 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) {
+ for (src_i = 0; dst_i < end_i; dst_i++, src_i++) {
+ dst_p[dst_i] = 0;
+ }
+ dst_p[dst_i] = 0;
+
+ // DATA IS IN MORE THAN ONE WORD, AND NOT WORD ALIGNED:
+ } else {
+ mask = ~(~0U << 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 & ~(~0U << (nbits % BITS_PER_DIGIT))) ==
+ static_cast<sc_digit>(~(~0U << (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("conversion failed",
+ "character string is zero");
+ } else if (*a == 0) {
+ SC_REPORT_ERROR("conversion failed",
+ "character string is empty");
+ } else try {
+ int len = length();
+ sc_fix aa(a, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
+ return this->operator = (aa);
+ } catch(const sc_core::sc_report &) {
+ std::stringstream msg;
+ msg << "character string '" << a << "' is not valid";
+ SC_REPORT_ERROR("conversion failed", msg.str().c_str());
+ }
+ 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 (std::floor(v) && (i < ndigits)) {
+ digit[i++] = ((sc_digit)std::floor(remainder(v, DIGIT_RADIX))) &
+ DIGIT_MASK;
+ 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, static_cast<int64>(v));
+}
+
+sc_signed
+operator + (const sc_int_base &u, const sc_unsigned &v)
+{
+ return operator + (static_cast<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, static_cast<int64>(v));
+}
+
+sc_signed
+operator * (const sc_int_base &u, const sc_unsigned &v)
+{
+ return operator * (static_cast<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, static_cast<int64>(v));
+}
+
+sc_signed
+operator / (const sc_int_base &u, const sc_unsigned &v)
+{
+ return operator / (static_cast<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, static_cast<int64>(v));
+}
+
+sc_signed
+operator % (const sc_int_base &u, const sc_unsigned &v)
+{
+ return operator % (static_cast<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, static_cast<int64>(v));
+}
+
+sc_signed
+operator & (const sc_int_base &u, const sc_unsigned &v)
+{
+ return operator & (static_cast<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, static_cast<int64>(v));
+}
+
+sc_signed
+operator | (const sc_int_base &u, const sc_unsigned &v)
+{
+ return operator | (static_cast<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, static_cast<int64>(v));
+}
+
+sc_signed
+operator ^ (const sc_int_base &u, const sc_unsigned &v)
+{
+ return operator ^ (static_cast<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
diff --git a/src/systemc/dt/int/sc_signed_bitref.inc b/src/systemc/dt/int/sc_signed_bitref.inc
new file mode 100644
index 000000000..c20301c68
--- /dev/null
+++ b/src/systemc/dt/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;
+}
diff --git a/src/systemc/dt/int/sc_signed_subref.inc b/src/systemc/dt/int/sc_signed_subref.inc
new file mode 100644
index 000000000..476c81500
--- /dev/null
+++ b/src/systemc/dt/int/sc_signed_subref.inc
@@ -0,0 +1,402 @@
+/*****************************************************************************
+
+ 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 (std::floor(v) && (i < nd)) {
+#ifndef _WIN32
+ d[i++] = (sc_digit) std::floor(remainder(v, DIGIT_RADIX));
+#else
+ d[i++] = (sc_digit) std::floor(std::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();
+}
diff --git a/src/systemc/dt/int/sc_uint_base.cc b/src/systemc/dt/int/sc_uint_base.cc
new file mode 100644
index 000000000..58e4605c3
--- /dev/null
+++ b/src/systemc/dt/int/sc_uint_base.cc
@@ -0,0 +1,708 @@
+/*****************************************************************************
+
+ 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 <sstream>
+
+#include "systemc/ext/dt/bit/sc_bv_base.hh"
+#include "systemc/ext/dt/bit/sc_lv_base.hh"
+#include "systemc/ext/dt/fx/sc_ufix.hh"
+#include "systemc/ext/dt/fx/scfx_other_defs.hh"
+#include "systemc/ext/dt/int/sc_signed.hh"
+#include "systemc/ext/dt/int/sc_uint_base.hh"
+#include "systemc/ext/dt/int/sc_unsigned.hh"
+#include "systemc/ext/dt/misc/sc_concatref.hh"
+
+// explicit template instantiations
+namespace sc_core
+{
+
+template class sc_vpool<sc_dt::sc_uint_bitref>;
+template class sc_vpool<sc_dt::sc_uint_subref>;
+
+} // namespace sc_core
+
+namespace sc_dt
+{
+
+// to avoid code bloat in sc_uint_concat<T1,T2>
+
+void
+sc_uint_concref_invalid_length(int length)
+{
+ std::stringstream msg;
+ msg << "sc_uint_concref<T1,T2> initialization: length = " << length <<
+ "violates 1 <= length <= " << SC_INTWIDTH;
+ SC_REPORT_ERROR("out of bounds", msg.str().c_str());
+ sc_core::sc_abort(); // can't recover from here
+}
+
+
+
+// ----------------------------------------------------------------------------
+// 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 = ~(~UINT_ZERO << 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 = ~(~UINT_ZERO << 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
+{
+ std::stringstream msg;
+ msg << "sc_uint[_base] initialization: length = " << m_len <<
+ " violates 1 <= length <= " << SC_INTWIDTH;
+ SC_REPORT_ERROR("out of bounds", msg.str().c_str());
+ sc_core::sc_abort(); // can't recover from here}
+}
+
+void
+sc_uint_base::invalid_index(int i) const
+{
+ std::stringstream msg;
+ msg << "sc_uint[_base] bit selection: index = " << i <<
+ " violates 0 <= index <= " << (m_len - 1);
+ SC_REPORT_ERROR("out of bounds", msg.str().c_str());
+ sc_core::sc_abort(); // can't recover from here
+}
+
+void
+sc_uint_base::invalid_range(int l, int r) const
+{
+ std::stringstream msg;
+ msg << "sc_uint[_base] part selection: " <<
+ "left = " << l << ", right = " << r << " violates " <<
+ (m_len - 1) << " >= left >= right >= 0";
+ SC_REPORT_ERROR("out of bounds", msg.str().c_str());
+ sc_core::sc_abort(); // can't recover from here
+}
+
+
+void
+sc_uint_base::check_value() const
+{
+ uint_type limit = (~UINT_ZERO >> m_ulen);
+ if (m_val > limit) {
+ std::stringstream msg;
+ msg << "sc_uint[_base]: value does not fit into a length of " << m_len;
+ SC_REPORT_WARNING("out of bounds", msg.str().c_str());
+ }
+}
+
+
+// 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();
+ *this = a.to_uint64();
+}
+
+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();
+ *this = a.to_uint64();
+}
+
+// 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("conversion failed",
+ "character string is zero");
+ } else if (*a == 0) {
+ SC_REPORT_ERROR("conversion failed",
+ "character string is empty");
+ } else try {
+ int len = m_len;
+ sc_ufix aa(a, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
+ return this->operator = (aa);
+ } catch(const sc_core::sc_report &) {
+ std::stringstream msg;
+ msg << "character string '" << a << "' is not valid";
+ SC_REPORT_ERROR("conversion failed", msg.str().c_str());
+ }
+ 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_ZERO << 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_ZERO << m_len);
+ val &= mask;
+ }
+
+ // PROCESS THE FIRST WORD:
+ mask = ~(~UINT_ZERO << 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
diff --git a/src/systemc/dt/int/sc_unsigned.cc b/src/systemc/dt/int/sc_unsigned.cc
new file mode 100644
index 000000000..d2535b6b1
--- /dev/null
+++ b/src/systemc/dt/int/sc_unsigned.cc
@@ -0,0 +1,2259 @@
+/*****************************************************************************
+
+ 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 <cctype>
+#include <cmath>
+#include <sstream>
+
+#include "systemc/ext/dt/bit/sc_bv_base.hh"
+#include "systemc/ext/dt/bit/sc_lv_base.hh"
+#include "systemc/ext/dt/fx/sc_ufix.hh"
+#include "systemc/ext/dt/fx/scfx_other_defs.hh"
+#include "systemc/ext/dt/int/sc_int_base.hh"
+#include "systemc/ext/dt/int/sc_signed.hh"
+#include "systemc/ext/dt/int/sc_uint_base.hh"
+#include "systemc/ext/dt/int/sc_unsigned.hh"
+#include "systemc/ext/dt/misc/sc_concatref.hh"
+
+// explicit template instantiations
+namespace sc_core
+{
+
+template class sc_vpool<sc_dt::sc_unsigned_bitref>;
+template class sc_vpool<sc_dt::sc_unsigned_subref>;
+template class sc_vpool<sc_dt::sc_unsigned>;
+
+} // namespace sc_core
+
+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);
+
+
+void
+sc_unsigned::invalid_init(const char *type_name, int nb) const
+{
+ std::stringstream msg;
+ msg << "sc_unsigned("<< type_name << ") : nb = " << nb << " is not valid";
+ SC_REPORT_ERROR("initialization failed", msg.str().c_str());
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Public members - Invalid selections.
+// ----------------------------------------------------------------------------
+
+void
+sc_unsigned::invalid_index(int i) const
+{
+ std::stringstream msg;
+ msg << "sc_biguint bit selection: index = " << i << " violates "
+ "0 <= index <= " << (nbits-2);
+ SC_REPORT_ERROR("out of bounds", msg.str().c_str());
+ sc_core::sc_abort(); // can't recover from here
+}
+
+void
+sc_unsigned::invalid_range(int l, int r) const
+{
+ std::stringstream msg;
+ msg << "sc_biguint part selection: left = " <<
+ l << ", right = " << r << "\n"
+ " violates either (" << (nbits - 2) << " >= left >= 0) or "
+ "(" << (nbits-2) << " >= right >= 0)";
+ SC_REPORT_ERROR("out of bounds", msg.str().c_str());
+ sc_core::sc_abort(); // can't recover from here
+}
+
+// ----------------------------------------------------------------------------
+// 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 = ~(~0U << 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 = ~(~0U << 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 = ~(~1U << 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 = ~(~0U << 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 = ~(~1U << 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 = ~(~0U << nbits);
+ right_word = ((digit[0] ^ DIGIT_MASK) + 1) & mask;
+ mask = ~(~0U << 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 = (~(~1U << 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 = ~(~0U << 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 = ~(~1U << 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 = ~(~0U << 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;
+ }
+ dst_p[dst_i] = 0;
+
+ // DATA IS IN MORE THAN ONE WORD, AND NOT WORD ALIGNED:
+ } else {
+ mask = ~(~0U << 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] & ~(~0U << ((nbits - 1) % BITS_PER_DIGIT))) ==
+ static_cast<sc_digit>(~(~0U << ((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("conversion failed",
+ "character string is zero");
+ } else if (*a == 0) {
+ SC_REPORT_ERROR("conversion failed",
+ "character string is empty");
+ } else try {
+ int len = length();
+ sc_ufix aa(a, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
+ return this->operator = (aa);
+ } catch(const sc_core::sc_report &) {
+ std::stringstream msg;
+ msg << "character string '" << a << "' is not valid";
+ SC_REPORT_ERROR("conversion failed", msg.str().c_str());
+ }
+ 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 (std::floor(v) && (i < ndigits)) {
+ digit[i++] = ((sc_digit)std::floor(remainder(v, DIGIT_RADIX))) &
+ DIGIT_MASK;
+ 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
diff --git a/src/systemc/dt/int/sc_unsigned_bitref.inc b/src/systemc/dt/int/sc_unsigned_bitref.inc
new file mode 100644
index 000000000..09eccd03c
--- /dev/null
+++ b/src/systemc/dt/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;
+}
diff --git a/src/systemc/dt/int/sc_unsigned_subref.inc b/src/systemc/dt/int/sc_unsigned_subref.inc
new file mode 100644
index 000000000..f76f65ca8
--- /dev/null
+++ b/src/systemc/dt/int/sc_unsigned_subref.inc
@@ -0,0 +1,394 @@
+/*****************************************************************************
+
+ 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 (std::floor(v) && (i < nd)) {
+ d[i++] = (sc_digit) std::floor(remainder(v, DIGIT_RADIX));
+ 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();
+}