sc_unsigned.cc revision 13160
112854Sgabeblack@google.com/*****************************************************************************
212854Sgabeblack@google.com
312854Sgabeblack@google.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
412854Sgabeblack@google.com  more contributor license agreements.  See the NOTICE file distributed
512854Sgabeblack@google.com  with this work for additional information regarding copyright ownership.
612854Sgabeblack@google.com  Accellera licenses this file to you under the Apache License, Version 2.0
712854Sgabeblack@google.com  (the "License"); you may not use this file except in compliance with the
812854Sgabeblack@google.com  License.  You may obtain a copy of the License at
912854Sgabeblack@google.com
1012854Sgabeblack@google.com    http://www.apache.org/licenses/LICENSE-2.0
1112854Sgabeblack@google.com
1212854Sgabeblack@google.com  Unless required by applicable law or agreed to in writing, software
1312854Sgabeblack@google.com  distributed under the License is distributed on an "AS IS" BASIS,
1412854Sgabeblack@google.com  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1512854Sgabeblack@google.com  implied.  See the License for the specific language governing
1612854Sgabeblack@google.com  permissions and limitations under the License.
1712854Sgabeblack@google.com
1812854Sgabeblack@google.com *****************************************************************************/
1912854Sgabeblack@google.com
2012854Sgabeblack@google.com/*****************************************************************************
2112854Sgabeblack@google.com
2212854Sgabeblack@google.com  sc_unsigned.cpp -- Arbitrary precision signed arithmetic.
2312854Sgabeblack@google.com
2412854Sgabeblack@google.com    This file includes the definitions of sc_unsigned_bitref,
2512854Sgabeblack@google.com    sc_unsigned_subref, and sc_unsigned classes. The first two classes
2612854Sgabeblack@google.com    are proxy classes to reference one bit and a range of bits of a
2712854Sgabeblack@google.com    sc_unsigned number, respectively. This file also includes
2812854Sgabeblack@google.com    sc_nbcommon.cpp and sc_nbfriends.cpp, which contain the
2912854Sgabeblack@google.com    definitions shared by sc_unsigned.
3012854Sgabeblack@google.com
3112854Sgabeblack@google.com  Original Author: Ali Dasdan, Synopsys, Inc.
3212854Sgabeblack@google.com
3312854Sgabeblack@google.com *****************************************************************************/
3412854Sgabeblack@google.com
3512854Sgabeblack@google.com/*****************************************************************************
3612854Sgabeblack@google.com
3712854Sgabeblack@google.com  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
3812854Sgabeblack@google.com  changes you are making here.
3912854Sgabeblack@google.com
4012854Sgabeblack@google.com      Name, Affiliation, Date:
4112854Sgabeblack@google.com  Description of Modification:
4212854Sgabeblack@google.com
4312854Sgabeblack@google.com *****************************************************************************/
4412854Sgabeblack@google.com
4512854Sgabeblack@google.com
4612854Sgabeblack@google.com// $Log: sc_unsigned.cpp,v $
4712854Sgabeblack@google.com// Revision 1.7  2011/02/18 20:19:15  acg
4812854Sgabeblack@google.com//  Andy Goodrich: updating Copyright notice.
4912854Sgabeblack@google.com//
5012854Sgabeblack@google.com// Revision 1.6  2008/12/10 20:38:45  acg
5112854Sgabeblack@google.com//  Andy Goodrich: fixed conversion of double values to the digits vector.
5212854Sgabeblack@google.com//  The bits above the radix were not being masked off.
5312854Sgabeblack@google.com//
5412854Sgabeblack@google.com// Revision 1.5  2008/06/19 17:47:57  acg
5512854Sgabeblack@google.com//  Andy Goodrich: fixes for bugs. See 2.2.1 RELEASENOTES.
5612854Sgabeblack@google.com//
5712854Sgabeblack@google.com// Revision 1.4  2008/06/19 16:57:57  acg
5812854Sgabeblack@google.com//  Andy Goodrich: added case for negative unsigned values to the support in
5912854Sgabeblack@google.com//  concate_get_data().
6012854Sgabeblack@google.com//
6112854Sgabeblack@google.com// Revision 1.3  2007/11/04 21:27:00  acg
6212854Sgabeblack@google.com//  Andy Goodrich: changes to make sure the proper value is returned from
6312854Sgabeblack@google.com//  concat_get_data().
6412854Sgabeblack@google.com//
6512854Sgabeblack@google.com// Revision 1.2  2007/02/22 21:35:05  acg
6612854Sgabeblack@google.com//  Andy Goodrich: cleaned up comments in concat_get_ctrl and concat_get_data.
6712854Sgabeblack@google.com//
6812854Sgabeblack@google.com// Revision 1.1.1.1  2006/12/15 20:20:05  acg
6912854Sgabeblack@google.com// SystemC 2.3
7012854Sgabeblack@google.com//
7112854Sgabeblack@google.com// Revision 1.4  2006/08/29 23:36:54  acg
7212854Sgabeblack@google.com//  Andy Goodrich: fixed and_reduce and optimized or_reduce.
7312854Sgabeblack@google.com//
7412854Sgabeblack@google.com// Revision 1.3  2006/01/13 18:49:32  acg
7512854Sgabeblack@google.com// Added $Log command so that CVS check in comments are reproduced in the
7612854Sgabeblack@google.com// source.
7712854Sgabeblack@google.com//
7812854Sgabeblack@google.com
7912854Sgabeblack@google.com#include <cctype>
8012854Sgabeblack@google.com#include <cmath>
8112854Sgabeblack@google.com#include <sstream>
8212854Sgabeblack@google.com
8312854Sgabeblack@google.com#include "systemc/ext/dt/bit/sc_bv_base.hh"
8412854Sgabeblack@google.com#include "systemc/ext/dt/bit/sc_lv_base.hh"
8512854Sgabeblack@google.com#include "systemc/ext/dt/fx/sc_ufix.hh"
8612854Sgabeblack@google.com#include "systemc/ext/dt/fx/scfx_other_defs.hh"
8712854Sgabeblack@google.com#include "systemc/ext/dt/int/sc_int_base.hh"
8812854Sgabeblack@google.com#include "systemc/ext/dt/int/sc_signed.hh"
8912854Sgabeblack@google.com#include "systemc/ext/dt/int/sc_uint_base.hh"
9012854Sgabeblack@google.com#include "systemc/ext/dt/int/sc_unsigned.hh"
9112854Sgabeblack@google.com#include "systemc/ext/dt/misc/sc_concatref.hh"
9212854Sgabeblack@google.com
9312854Sgabeblack@google.com// explicit template instantiations
9412854Sgabeblack@google.comnamespace sc_core
9512854Sgabeblack@google.com{
9612854Sgabeblack@google.com
9712854Sgabeblack@google.comtemplate class sc_vpool<sc_dt::sc_unsigned_bitref>;
9812854Sgabeblack@google.comtemplate class sc_vpool<sc_dt::sc_unsigned_subref>;
9912854Sgabeblack@google.comtemplate class sc_vpool<sc_dt::sc_unsigned>;
10012854Sgabeblack@google.com
10112854Sgabeblack@google.com} // namespace sc_core
10212854Sgabeblack@google.com
10312854Sgabeblack@google.comnamespace sc_dt
10412854Sgabeblack@google.com{
10512854Sgabeblack@google.com
10612854Sgabeblack@google.com// Pool of temporary instances:
10712854Sgabeblack@google.com//   The sc_unsigned pool is used by the concatenation support.
10812854Sgabeblack@google.com//   The bit and part reference pools allow references to be returned.
10912854Sgabeblack@google.com
11012854Sgabeblack@google.comsc_core::sc_vpool<sc_unsigned> sc_unsigned::m_pool(8);
11112854Sgabeblack@google.comsc_core::sc_vpool<sc_unsigned_bitref> sc_unsigned_bitref::m_pool(9);
11212854Sgabeblack@google.comsc_core::sc_vpool<sc_unsigned_subref> sc_unsigned_subref::m_pool(9);
11312854Sgabeblack@google.com
11412854Sgabeblack@google.com
11512854Sgabeblack@google.comvoid
11612854Sgabeblack@google.comsc_unsigned::invalid_init(const char *type_name, int nb) const
11712854Sgabeblack@google.com{
11812854Sgabeblack@google.com    std::stringstream msg;
11912854Sgabeblack@google.com    msg << "sc_unsigned("<< type_name << ") : nb = " << nb << " is not valid";
12012854Sgabeblack@google.com    SC_REPORT_ERROR("initialization failed", msg.str().c_str());
12112854Sgabeblack@google.com}
12212854Sgabeblack@google.com
12312854Sgabeblack@google.com
12412854Sgabeblack@google.com// ----------------------------------------------------------------------------
12512854Sgabeblack@google.com// SECTION: Public members - Invalid selections.
12612854Sgabeblack@google.com// ----------------------------------------------------------------------------
12712854Sgabeblack@google.com
12812854Sgabeblack@google.comvoid
12912854Sgabeblack@google.comsc_unsigned::invalid_index(int i) const
13012854Sgabeblack@google.com{
13112854Sgabeblack@google.com    std::stringstream msg;
13212854Sgabeblack@google.com    msg << "sc_biguint bit selection: index = " << i << " violates "
13312854Sgabeblack@google.com           "0 <= index <= " << (nbits-2);
13413138Sgabeblack@google.com    SC_REPORT_ERROR("(E5) out of bounds", msg.str().c_str());
13512854Sgabeblack@google.com    sc_core::sc_abort(); // can't recover from here
13612854Sgabeblack@google.com}
13712854Sgabeblack@google.com
13812854Sgabeblack@google.comvoid
13912854Sgabeblack@google.comsc_unsigned::invalid_range(int l, int r) const
14012854Sgabeblack@google.com{
14112854Sgabeblack@google.com    std::stringstream msg;
14212854Sgabeblack@google.com    msg << "sc_biguint part selection: left = " <<
14313160Sgabeblack@google.com           l << ", right = " << r << " \n"
14412854Sgabeblack@google.com           "  violates either (" << (nbits - 2) << " >= left >= 0) or "
14512854Sgabeblack@google.com           "(" << (nbits-2) << " >= right >= 0)";
14613138Sgabeblack@google.com    SC_REPORT_ERROR("(E5) out of bounds", msg.str().c_str());
14712854Sgabeblack@google.com    sc_core::sc_abort(); // can't recover from here
14812854Sgabeblack@google.com}
14912854Sgabeblack@google.com
15012854Sgabeblack@google.com// ----------------------------------------------------------------------------
15112854Sgabeblack@google.com//  SECTION: Public members - Concatenation support.
15212854Sgabeblack@google.com// ----------------------------------------------------------------------------
15312854Sgabeblack@google.com
15412854Sgabeblack@google.com// Most public members are included from sc_nbcommon.inc. However, some
15512854Sgabeblack@google.com// concatenation support appears here to optimize between the signed and
15612854Sgabeblack@google.com// unsigned cases.
15712854Sgabeblack@google.com
15812854Sgabeblack@google.com
15912854Sgabeblack@google.com
16012854Sgabeblack@google.com// Insert this object's value at the specified place in a vector of big style
16112854Sgabeblack@google.com// values.
16212854Sgabeblack@google.com
16312854Sgabeblack@google.combool
16412854Sgabeblack@google.comsc_unsigned::concat_get_ctrl(sc_digit *dst_p, int low_i) const
16512854Sgabeblack@google.com{
16612854Sgabeblack@google.com    int dst_i; // Index to next word to set in dst_p.
16712854Sgabeblack@google.com    int end_i; // Index of high order word to set.
16812854Sgabeblack@google.com    int left_shift; // Amount to shift value left.
16912854Sgabeblack@google.com    sc_digit mask; // Mask for partial word sets.
17012854Sgabeblack@google.com
17112854Sgabeblack@google.com
17212854Sgabeblack@google.com    // CALCULATE METRICS FOR DATA MOVEMENT:
17312854Sgabeblack@google.com    dst_i = low_i / BITS_PER_DIGIT;
17412854Sgabeblack@google.com    end_i = (low_i + nbits - 2) / BITS_PER_DIGIT;
17512854Sgabeblack@google.com    left_shift = low_i % BITS_PER_DIGIT;
17612854Sgabeblack@google.com
17712854Sgabeblack@google.com    // MOVE FIRST WORD (IT MAY BE PARTIAL) AND THEN ANY OTHERS:
17812854Sgabeblack@google.com    //
17912854Sgabeblack@google.com    // We may "clobber" upper bits, but they will be written at some point
18012854Sgabeblack@google.com    // anyway.
18112854Sgabeblack@google.com
18212854Sgabeblack@google.com    mask = ~(~0U << left_shift);
18312854Sgabeblack@google.com    dst_p[dst_i] = (dst_p[dst_i] & ~mask);
18412854Sgabeblack@google.com    dst_i++;
18512854Sgabeblack@google.com
18612854Sgabeblack@google.com    for (; dst_i <= end_i; dst_i++)
18712854Sgabeblack@google.com        dst_p[dst_i] = 0;
18812854Sgabeblack@google.com
18912854Sgabeblack@google.com    return false;
19012854Sgabeblack@google.com}
19112854Sgabeblack@google.com
19212854Sgabeblack@google.combool
19312854Sgabeblack@google.comsc_unsigned::concat_get_data(sc_digit *dst_p, int low_i) const
19412854Sgabeblack@google.com{
19512854Sgabeblack@google.com    sc_digit carry; // Carry for negating value.
19612854Sgabeblack@google.com    int dst_i; // Index to next word to set in dst_p.
19712854Sgabeblack@google.com    int end_i; // Index of high order word to set.
19812854Sgabeblack@google.com    int high_i; // Index w/in word of high order bit.
19912854Sgabeblack@google.com    int left_shift; // Amount to shift value left.
20012854Sgabeblack@google.com    sc_digit left_word; // High word component for set.
20112854Sgabeblack@google.com    sc_digit mask; // Mask for partial word sets.
20212854Sgabeblack@google.com    bool result; // True if inserting non-zero data.
20312854Sgabeblack@google.com    int right_shift; // Amount to shift value right.
20412854Sgabeblack@google.com    sc_digit right_word; // Low word component for set.
20512854Sgabeblack@google.com    int real_bits; // nbits - 1.
20612854Sgabeblack@google.com    int src_i; // Index to next word to get from digit.
20712854Sgabeblack@google.com
20812854Sgabeblack@google.com    // CALCULATE METRICS FOR DATA MOVEMENT:
20912854Sgabeblack@google.com    real_bits = nbits - 1; // Remove that extra sign bit.
21012854Sgabeblack@google.com    dst_i = low_i / BITS_PER_DIGIT;
21112854Sgabeblack@google.com    high_i = low_i + real_bits - 1;
21212854Sgabeblack@google.com    end_i = high_i / BITS_PER_DIGIT;
21312854Sgabeblack@google.com    left_shift = low_i % BITS_PER_DIGIT;
21412854Sgabeblack@google.com
21512854Sgabeblack@google.com    switch (sgn) {
21612854Sgabeblack@google.com      // POSITIVE SOURCE VALUE:
21712854Sgabeblack@google.com      case SC_POS:
21812854Sgabeblack@google.com        result = true;
21912854Sgabeblack@google.com
22012854Sgabeblack@google.com        // ALL DATA TO BE MOVED IS IN A SINGLE WORD:
22112854Sgabeblack@google.com        if (dst_i == end_i) {
22212854Sgabeblack@google.com            mask = ~(~0U << left_shift);
22312854Sgabeblack@google.com            dst_p[dst_i] = ((dst_p[dst_i] & mask) |
22412854Sgabeblack@google.com                (digit[0] << left_shift)) & DIGIT_MASK;
22512854Sgabeblack@google.com
22612854Sgabeblack@google.com        // DATA IS IN MORE THAN ONE WORD, BUT IS WORD ALIGNED:
22712854Sgabeblack@google.com        } else if (left_shift == 0) {
22812854Sgabeblack@google.com            for (src_i = 0; dst_i < end_i; dst_i++, src_i++) {
22912854Sgabeblack@google.com                dst_p[dst_i] = digit[src_i];
23012854Sgabeblack@google.com            }
23112854Sgabeblack@google.com            high_i = high_i % BITS_PER_DIGIT;
23212854Sgabeblack@google.com            mask = ~(~1U << high_i) & DIGIT_MASK;
23312854Sgabeblack@google.com            dst_p[dst_i] = digit[src_i] & mask;
23412854Sgabeblack@google.com
23512854Sgabeblack@google.com        // DATA IS IN MORE THAN ONE WORD, AND NOT WORD ALIGNED:
23612854Sgabeblack@google.com        } else {
23712854Sgabeblack@google.com            high_i = high_i % BITS_PER_DIGIT;
23812854Sgabeblack@google.com            right_shift = BITS_PER_DIGIT - left_shift;
23912854Sgabeblack@google.com            mask = ~(~0U << left_shift);
24012854Sgabeblack@google.com            right_word = digit[0];
24112854Sgabeblack@google.com            dst_p[dst_i] = (dst_p[dst_i] & mask) |
24212854Sgabeblack@google.com                ((right_word << left_shift) & DIGIT_MASK);
24312854Sgabeblack@google.com            for (src_i = 1, dst_i++; dst_i < end_i; dst_i++, src_i++) {
24412854Sgabeblack@google.com                left_word = digit[src_i];
24512854Sgabeblack@google.com                dst_p[dst_i] = ((left_word << left_shift) & DIGIT_MASK) |
24612854Sgabeblack@google.com                    (right_word >> right_shift);
24712854Sgabeblack@google.com                right_word = left_word;
24812854Sgabeblack@google.com            }
24912854Sgabeblack@google.com            left_word = (src_i < ndigits) ? digit[src_i] : 0;
25012854Sgabeblack@google.com            mask = ~(~1U << high_i) & DIGIT_MASK;
25112854Sgabeblack@google.com            dst_p[dst_i] = ((left_word << left_shift) |
25212854Sgabeblack@google.com                (right_word >> right_shift)) & mask;
25312854Sgabeblack@google.com        }
25412854Sgabeblack@google.com        break;
25512854Sgabeblack@google.com
25612854Sgabeblack@google.com      // SOURCE VALUE IS NEGATIVE:
25712854Sgabeblack@google.com      case SC_NEG:
25812854Sgabeblack@google.com        // ALL DATA TO BE MOVED IS IN A SINGLE WORD:
25912854Sgabeblack@google.com        result = true;
26012854Sgabeblack@google.com        if (dst_i == end_i) {
26112854Sgabeblack@google.com            mask = ~(~0U << nbits);
26212854Sgabeblack@google.com            right_word = ((digit[0] ^ DIGIT_MASK) + 1) & mask;
26312854Sgabeblack@google.com            mask = ~(~0U << left_shift);
26412854Sgabeblack@google.com            dst_p[dst_i] = ((dst_p[dst_i] & mask) |
26512854Sgabeblack@google.com                (right_word << left_shift)) & DIGIT_MASK;
26612854Sgabeblack@google.com
26712854Sgabeblack@google.com        // DATA IS IN MORE THAN ONE WORD, BUT IS WORD ALIGNED:
26812854Sgabeblack@google.com
26912854Sgabeblack@google.com        } else if (left_shift == 0) {
27012854Sgabeblack@google.com            carry = 1;
27112854Sgabeblack@google.com            for (src_i = 0; dst_i < end_i; dst_i++, src_i++) {
27212854Sgabeblack@google.com                right_word = (digit[src_i] ^ DIGIT_MASK) + carry;
27312854Sgabeblack@google.com                dst_p[dst_i] = right_word &  DIGIT_MASK;
27412854Sgabeblack@google.com                carry = right_word >> BITS_PER_DIGIT;
27512854Sgabeblack@google.com            }
27612854Sgabeblack@google.com            high_i = high_i % BITS_PER_DIGIT;
27712854Sgabeblack@google.com            mask = (~(~1U << high_i)) & DIGIT_MASK;
27812854Sgabeblack@google.com            right_word = (src_i < ndigits) ?
27912854Sgabeblack@google.com                (digit[src_i] ^ DIGIT_MASK) + carry : DIGIT_MASK + carry;
28012854Sgabeblack@google.com            dst_p[dst_i] = right_word & mask;
28112854Sgabeblack@google.com
28212854Sgabeblack@google.com        // DATA IS IN MORE THAN ONE WORD, AND NOT WORD ALIGNED:
28312854Sgabeblack@google.com        } else {
28412854Sgabeblack@google.com            high_i = high_i % BITS_PER_DIGIT;
28512854Sgabeblack@google.com            right_shift = BITS_PER_DIGIT - left_shift;
28612854Sgabeblack@google.com            mask = ~(~0U << left_shift);
28712854Sgabeblack@google.com            carry = 1;
28812854Sgabeblack@google.com            right_word = (digit[0] ^ DIGIT_MASK) + carry;
28912854Sgabeblack@google.com            dst_p[dst_i] = (dst_p[dst_i] & mask) |
29012854Sgabeblack@google.com                ((right_word << left_shift) & DIGIT_MASK);
29112854Sgabeblack@google.com            carry = right_word >> BITS_PER_DIGIT;
29212854Sgabeblack@google.com            right_word &= DIGIT_MASK;
29312854Sgabeblack@google.com            for (src_i = 1, dst_i++; dst_i < end_i; dst_i++, src_i++) {
29412854Sgabeblack@google.com                left_word = (digit[src_i] ^ DIGIT_MASK) + carry;
29512854Sgabeblack@google.com                dst_p[dst_i] = ((left_word << left_shift)&DIGIT_MASK) |
29612854Sgabeblack@google.com                    (right_word >> right_shift);
29712854Sgabeblack@google.com                carry = left_word >> BITS_PER_DIGIT;
29812854Sgabeblack@google.com                right_word = left_word & DIGIT_MASK;
29912854Sgabeblack@google.com            }
30012854Sgabeblack@google.com            left_word = (src_i < ndigits) ?
30112854Sgabeblack@google.com                (digit[src_i] ^ DIGIT_MASK) + carry : carry;
30212854Sgabeblack@google.com            mask = ~(~1U << high_i) & DIGIT_MASK;
30312854Sgabeblack@google.com            dst_p[dst_i] = ((left_word << left_shift) |
30412854Sgabeblack@google.com                (right_word >> right_shift)) & mask;
30512854Sgabeblack@google.com        }
30612854Sgabeblack@google.com        break;
30712854Sgabeblack@google.com      // VALUE IS ZERO:
30812854Sgabeblack@google.com      default:
30912854Sgabeblack@google.com        result = false;
31012854Sgabeblack@google.com        // ALL DATA TO BE MOVED IS IN A SINGLE WORD:
31112854Sgabeblack@google.com        if (dst_i == end_i) {
31212854Sgabeblack@google.com            mask = ~(~0U << real_bits) << left_shift;
31312854Sgabeblack@google.com            dst_p[dst_i] = dst_p[dst_i] & ~mask;
31412854Sgabeblack@google.com
31512854Sgabeblack@google.com        // DATA IS IN MORE THAN ONE WORD, BUT IS WORD ALIGNED:
31612854Sgabeblack@google.com
31712854Sgabeblack@google.com        } else if (left_shift == 0) {
31812854Sgabeblack@google.com            for (src_i = 0; dst_i < end_i; dst_i++, src_i++) {
31912854Sgabeblack@google.com                dst_p[dst_i] = 0;
32012854Sgabeblack@google.com            }
32112854Sgabeblack@google.com            dst_p[dst_i] = 0;
32212854Sgabeblack@google.com
32312854Sgabeblack@google.com        // DATA IS IN MORE THAN ONE WORD, AND NOT WORD ALIGNED:
32412854Sgabeblack@google.com        } else {
32512854Sgabeblack@google.com            mask = ~(~0U << left_shift);
32612854Sgabeblack@google.com            dst_p[dst_i] = (dst_p[dst_i] & mask);
32712854Sgabeblack@google.com            for (dst_i++; dst_i <= end_i; dst_i++) {
32812854Sgabeblack@google.com                dst_p[dst_i] = 0;
32912854Sgabeblack@google.com            }
33012854Sgabeblack@google.com        }
33112854Sgabeblack@google.com        break;
33212854Sgabeblack@google.com    }
33312854Sgabeblack@google.com    return result;
33412854Sgabeblack@google.com}
33512854Sgabeblack@google.com
33612854Sgabeblack@google.com// Return this object instance's bits as a uint64 without sign extension.
33712854Sgabeblack@google.comuint64
33812854Sgabeblack@google.comsc_unsigned::concat_get_uint64() const
33912854Sgabeblack@google.com{
34012854Sgabeblack@google.com    uint64 result;
34112854Sgabeblack@google.com
34212854Sgabeblack@google.com    switch (sgn) {
34312854Sgabeblack@google.com      case SC_POS:
34412854Sgabeblack@google.com        result = 0;
34512854Sgabeblack@google.com        if (ndigits > 2)
34612854Sgabeblack@google.com            result = digit[2];
34712854Sgabeblack@google.com        if (ndigits > 1)
34812854Sgabeblack@google.com            result = (result << BITS_PER_DIGIT) | digit[1];
34912854Sgabeblack@google.com        result = (result << BITS_PER_DIGIT) | digit[0];
35012854Sgabeblack@google.com        break;
35112854Sgabeblack@google.com      default:
35212854Sgabeblack@google.com        result = 0;
35312854Sgabeblack@google.com        break;
35412854Sgabeblack@google.com    }
35512854Sgabeblack@google.com    return result;
35612854Sgabeblack@google.com}
35712854Sgabeblack@google.com
35812854Sgabeblack@google.com// #### OPTIMIZE
35912854Sgabeblack@google.comvoid
36012854Sgabeblack@google.comsc_unsigned::concat_set(int64 src, int low_i)
36112854Sgabeblack@google.com{
36212854Sgabeblack@google.com    *this = (low_i < 64) ? src >> low_i : src >> 63;
36312854Sgabeblack@google.com}
36412854Sgabeblack@google.com
36512854Sgabeblack@google.comvoid
36612854Sgabeblack@google.comsc_unsigned::concat_set(const sc_signed &src, int low_i)
36712854Sgabeblack@google.com{
36812854Sgabeblack@google.com    if (low_i < src.length())
36912854Sgabeblack@google.com        *this = src >> low_i;
37012854Sgabeblack@google.com    else
37112854Sgabeblack@google.com        *this = (src < 0) ? (int_type)-1 : 0;
37212854Sgabeblack@google.com}
37312854Sgabeblack@google.com
37412854Sgabeblack@google.comvoid
37512854Sgabeblack@google.comsc_unsigned::concat_set(const sc_unsigned &src, int low_i)
37612854Sgabeblack@google.com{
37712854Sgabeblack@google.com    if (low_i < src.length())
37812854Sgabeblack@google.com        *this = src >> low_i;
37912854Sgabeblack@google.com    else
38012854Sgabeblack@google.com        *this = 0;
38112854Sgabeblack@google.com}
38212854Sgabeblack@google.com
38312854Sgabeblack@google.comvoid
38412854Sgabeblack@google.comsc_unsigned::concat_set(uint64 src, int low_i)
38512854Sgabeblack@google.com{
38612854Sgabeblack@google.com    *this = (low_i < 64) ? src >> low_i : 0;
38712854Sgabeblack@google.com}
38812854Sgabeblack@google.com
38912854Sgabeblack@google.com
39012854Sgabeblack@google.com// ----------------------------------------------------------------------------
39112854Sgabeblack@google.com//  SECTION: Public members - Reduction methods.
39212854Sgabeblack@google.com// ----------------------------------------------------------------------------
39312854Sgabeblack@google.com
39412854Sgabeblack@google.combool
39512854Sgabeblack@google.comsc_unsigned::and_reduce() const
39612854Sgabeblack@google.com{
39712854Sgabeblack@google.com    int i; // Digit examining.
39812854Sgabeblack@google.com
39912854Sgabeblack@google.com    if (sgn == SC_ZERO)
40012854Sgabeblack@google.com        return false;
40112854Sgabeblack@google.com    for (i = 0; i < ndigits - 1; i++)
40212854Sgabeblack@google.com        if ((digit[i] & DIGIT_MASK) != DIGIT_MASK)
40312854Sgabeblack@google.com            return false;
40412854Sgabeblack@google.com    if ((digit[i] & ~(~0U << ((nbits - 1) % BITS_PER_DIGIT))) ==
40512854Sgabeblack@google.com         static_cast<sc_digit>(~(~0U << ((nbits - 1) % BITS_PER_DIGIT)))) {
40612854Sgabeblack@google.com        return true;
40712854Sgabeblack@google.com    }
40812854Sgabeblack@google.com    return false;
40912854Sgabeblack@google.com}
41012854Sgabeblack@google.com
41112854Sgabeblack@google.combool
41212854Sgabeblack@google.comsc_unsigned::or_reduce() const
41312854Sgabeblack@google.com{
41412854Sgabeblack@google.com        return (sgn == SC_ZERO) ? false : true;
41512854Sgabeblack@google.com}
41612854Sgabeblack@google.com
41712854Sgabeblack@google.combool
41812854Sgabeblack@google.comsc_unsigned::xor_reduce() const
41912854Sgabeblack@google.com{
42012854Sgabeblack@google.com    int i; // Digit examining.
42112854Sgabeblack@google.com    int odd; // Flag for odd number of digits.
42212854Sgabeblack@google.com
42312854Sgabeblack@google.com    odd = 0;
42412854Sgabeblack@google.com    for (i = 0; i < nbits - 1; i++)
42512854Sgabeblack@google.com        if (test(i))
42612854Sgabeblack@google.com            odd = ~odd;
42712854Sgabeblack@google.com    return odd ? true : false;
42812854Sgabeblack@google.com}
42912854Sgabeblack@google.com
43012854Sgabeblack@google.com
43112854Sgabeblack@google.com// ----------------------------------------------------------------------------
43212854Sgabeblack@google.com//  SECTION: Public members - Assignment operators.
43312854Sgabeblack@google.com// ----------------------------------------------------------------------------
43412854Sgabeblack@google.com
43512854Sgabeblack@google.com// assignment operators
43612854Sgabeblack@google.comconst sc_unsigned &
43712854Sgabeblack@google.comsc_unsigned::operator = (const char *a)
43812854Sgabeblack@google.com{
43912854Sgabeblack@google.com    if (a == 0) {
44012854Sgabeblack@google.com        SC_REPORT_ERROR("conversion failed",
44112854Sgabeblack@google.com                        "character string is zero");
44212854Sgabeblack@google.com    } else if (*a == 0) {
44312854Sgabeblack@google.com        SC_REPORT_ERROR("conversion failed",
44412854Sgabeblack@google.com                        "character string is empty");
44512854Sgabeblack@google.com    } else try {
44612854Sgabeblack@google.com        int len = length();
44712854Sgabeblack@google.com        sc_ufix aa(a, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
44812854Sgabeblack@google.com        return this->operator = (aa);
44912854Sgabeblack@google.com    } catch(const sc_core::sc_report &) {
45012854Sgabeblack@google.com        std::stringstream msg;
45112854Sgabeblack@google.com        msg << "character string '" << a << "' is not valid";
45212854Sgabeblack@google.com        SC_REPORT_ERROR("conversion failed", msg.str().c_str());
45312854Sgabeblack@google.com    }
45412854Sgabeblack@google.com    return *this;
45512854Sgabeblack@google.com}
45612854Sgabeblack@google.com
45712854Sgabeblack@google.comconst sc_unsigned &
45812854Sgabeblack@google.comsc_unsigned::operator = (int64 v)
45912854Sgabeblack@google.com{
46012854Sgabeblack@google.com    sgn = get_sign(v);
46112854Sgabeblack@google.com    if (sgn == SC_ZERO) {
46212854Sgabeblack@google.com        vec_zero(ndigits, digit);
46312854Sgabeblack@google.com    } else {
46412854Sgabeblack@google.com        from_uint(ndigits, digit, (uint64) v);
46512854Sgabeblack@google.com        convert_SM_to_2C_to_SM();
46612854Sgabeblack@google.com    }
46712854Sgabeblack@google.com    return *this;
46812854Sgabeblack@google.com}
46912854Sgabeblack@google.com
47012854Sgabeblack@google.comconst sc_unsigned &
47112854Sgabeblack@google.comsc_unsigned::operator = (uint64 v)
47212854Sgabeblack@google.com{
47312854Sgabeblack@google.com    if (v == 0) {
47412854Sgabeblack@google.com        sgn = SC_ZERO;
47512854Sgabeblack@google.com        vec_zero(ndigits, digit);
47612854Sgabeblack@google.com    } else {
47712854Sgabeblack@google.com        sgn = SC_POS;
47812854Sgabeblack@google.com        from_uint(ndigits, digit, v);
47912854Sgabeblack@google.com        convert_SM_to_2C_to_SM();
48012854Sgabeblack@google.com    }
48112854Sgabeblack@google.com    return *this;
48212854Sgabeblack@google.com}
48312854Sgabeblack@google.com
48412854Sgabeblack@google.comconst sc_unsigned &
48512854Sgabeblack@google.comsc_unsigned::operator = (long v)
48612854Sgabeblack@google.com{
48712854Sgabeblack@google.com    sgn = get_sign(v);
48812854Sgabeblack@google.com    if (sgn == SC_ZERO) {
48912854Sgabeblack@google.com        vec_zero(ndigits, digit);
49012854Sgabeblack@google.com    } else {
49112854Sgabeblack@google.com        from_uint(ndigits, digit, (unsigned long)v);
49212854Sgabeblack@google.com        convert_SM_to_2C_to_SM();
49312854Sgabeblack@google.com    }
49412854Sgabeblack@google.com    return *this;
49512854Sgabeblack@google.com}
49612854Sgabeblack@google.com
49712854Sgabeblack@google.comconst sc_unsigned &
49812854Sgabeblack@google.comsc_unsigned::operator = (unsigned long v)
49912854Sgabeblack@google.com{
50012854Sgabeblack@google.com    if (v == 0) {
50112854Sgabeblack@google.com        sgn = SC_ZERO;
50212854Sgabeblack@google.com        vec_zero(ndigits, digit);
50312854Sgabeblack@google.com    } else {
50412854Sgabeblack@google.com        sgn = SC_POS;
50512854Sgabeblack@google.com        from_uint(ndigits, digit, v);
50612854Sgabeblack@google.com        convert_SM_to_2C_to_SM();
50712854Sgabeblack@google.com    }
50812854Sgabeblack@google.com    return *this;
50912854Sgabeblack@google.com}
51012854Sgabeblack@google.com
51112854Sgabeblack@google.comconst sc_unsigned &
51212854Sgabeblack@google.comsc_unsigned::operator = (double v)
51312854Sgabeblack@google.com{
51412854Sgabeblack@google.com    is_bad_double(v);
51512854Sgabeblack@google.com    sgn = SC_POS;
51612854Sgabeblack@google.com    int i = 0;
51712854Sgabeblack@google.com    while (std::floor(v) && (i < ndigits)) {
51812854Sgabeblack@google.com        digit[i++] = ((sc_digit)std::floor(remainder(v, DIGIT_RADIX))) &
51912854Sgabeblack@google.com            DIGIT_MASK;
52012854Sgabeblack@google.com        v /= DIGIT_RADIX;
52112854Sgabeblack@google.com    }
52212854Sgabeblack@google.com    vec_zero(i, ndigits, digit);
52312854Sgabeblack@google.com    convert_SM_to_2C_to_SM();
52412854Sgabeblack@google.com    return *this;
52512854Sgabeblack@google.com}
52612854Sgabeblack@google.com
52712854Sgabeblack@google.com
52812854Sgabeblack@google.com// ----------------------------------------------------------------------------
52912854Sgabeblack@google.com
53012854Sgabeblack@google.comconst sc_unsigned &
53112854Sgabeblack@google.comsc_unsigned::operator = (const sc_bv_base &v)
53212854Sgabeblack@google.com{
53312854Sgabeblack@google.com    int minlen = sc_min(nbits, v.length());
53412854Sgabeblack@google.com    int i = 0;
53512854Sgabeblack@google.com    for (; i < minlen; ++i) {
53612854Sgabeblack@google.com        safe_set(i, v.get_bit(i), digit);
53712854Sgabeblack@google.com    }
53812854Sgabeblack@google.com    for (; i < nbits; ++i) {
53912854Sgabeblack@google.com        safe_set(i, 0, digit); // zero-extend
54012854Sgabeblack@google.com    }
54112854Sgabeblack@google.com    convert_2C_to_SM();
54212854Sgabeblack@google.com    return *this;
54312854Sgabeblack@google.com}
54412854Sgabeblack@google.com
54512854Sgabeblack@google.comconst sc_unsigned &
54612854Sgabeblack@google.comsc_unsigned::operator = (const sc_lv_base &v)
54712854Sgabeblack@google.com{
54812854Sgabeblack@google.com    int minlen = sc_min(nbits, v.length());
54912854Sgabeblack@google.com    int i = 0;
55012854Sgabeblack@google.com    for (; i < minlen; ++i) {
55112854Sgabeblack@google.com        safe_set(i, sc_logic(v.get_bit(i)).to_bool(), digit);
55212854Sgabeblack@google.com    }
55312854Sgabeblack@google.com    for (; i < nbits; ++i) {
55412854Sgabeblack@google.com        safe_set(i, 0, digit);  // zero-extend
55512854Sgabeblack@google.com    }
55612854Sgabeblack@google.com    convert_2C_to_SM();
55712854Sgabeblack@google.com    return *this;
55812854Sgabeblack@google.com}
55912854Sgabeblack@google.com
56012854Sgabeblack@google.com
56112854Sgabeblack@google.com// explicit conversion to character string
56212854Sgabeblack@google.comconst std::string
56312854Sgabeblack@google.comsc_unsigned::to_string(sc_numrep numrep) const
56412854Sgabeblack@google.com{
56512854Sgabeblack@google.com    int len = length();
56612854Sgabeblack@google.com    sc_ufix aa(*this, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
56712854Sgabeblack@google.com    return aa.to_string(numrep);
56812854Sgabeblack@google.com}
56912854Sgabeblack@google.com
57012854Sgabeblack@google.comconst std::string
57112854Sgabeblack@google.comsc_unsigned::to_string(sc_numrep numrep, bool w_prefix) const
57212854Sgabeblack@google.com{
57312854Sgabeblack@google.com    int len = length();
57412854Sgabeblack@google.com    sc_ufix aa(*this, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
57512854Sgabeblack@google.com    return aa.to_string(numrep, w_prefix);
57612854Sgabeblack@google.com}
57712854Sgabeblack@google.com
57812854Sgabeblack@google.com
57912854Sgabeblack@google.com// ----------------------------------------------------------------------------
58012854Sgabeblack@google.com//  SECTION: Interfacing with sc_int_base
58112854Sgabeblack@google.com// ----------------------------------------------------------------------------
58212854Sgabeblack@google.com
58312854Sgabeblack@google.comconst sc_unsigned &
58412854Sgabeblack@google.comsc_unsigned::operator = (const sc_int_base &v)
58512854Sgabeblack@google.com{
58612854Sgabeblack@google.com    return operator = ((int64)v);
58712854Sgabeblack@google.com}
58812854Sgabeblack@google.com
58912854Sgabeblack@google.comconst sc_unsigned &
59012854Sgabeblack@google.comsc_unsigned::operator += (const sc_int_base &v)
59112854Sgabeblack@google.com{
59212854Sgabeblack@google.com    return operator += ((int64)v);
59312854Sgabeblack@google.com}
59412854Sgabeblack@google.com
59512854Sgabeblack@google.comconst sc_unsigned &
59612854Sgabeblack@google.comsc_unsigned::operator -= (const sc_int_base &v)
59712854Sgabeblack@google.com{
59812854Sgabeblack@google.com    return operator -= ((int64)v);
59912854Sgabeblack@google.com}
60012854Sgabeblack@google.com
60112854Sgabeblack@google.comconst sc_unsigned &
60212854Sgabeblack@google.comsc_unsigned::operator *= (const sc_int_base &v)
60312854Sgabeblack@google.com{
60412854Sgabeblack@google.com    return operator *= ((int64)v);
60512854Sgabeblack@google.com}
60612854Sgabeblack@google.com
60712854Sgabeblack@google.comconst sc_unsigned &
60812854Sgabeblack@google.comsc_unsigned::operator /= (const sc_int_base &v)
60912854Sgabeblack@google.com{
61012854Sgabeblack@google.com    return operator /= ((int64)v);
61112854Sgabeblack@google.com}
61212854Sgabeblack@google.com
61312854Sgabeblack@google.comconst sc_unsigned &
61412854Sgabeblack@google.comsc_unsigned::operator %= (const sc_int_base &v)
61512854Sgabeblack@google.com{
61612854Sgabeblack@google.com    return operator %= ((int64)v);
61712854Sgabeblack@google.com}
61812854Sgabeblack@google.com
61912854Sgabeblack@google.comconst sc_unsigned &
62012854Sgabeblack@google.comsc_unsigned::operator &= (const sc_int_base &v)
62112854Sgabeblack@google.com{
62212854Sgabeblack@google.com    return operator &= ((int64)v);
62312854Sgabeblack@google.com}
62412854Sgabeblack@google.com
62512854Sgabeblack@google.comconst sc_unsigned &
62612854Sgabeblack@google.comsc_unsigned::operator |= (const sc_int_base &v)
62712854Sgabeblack@google.com{
62812854Sgabeblack@google.com    return operator |= ((int64)v);
62912854Sgabeblack@google.com}
63012854Sgabeblack@google.com
63112854Sgabeblack@google.comconst sc_unsigned &
63212854Sgabeblack@google.comsc_unsigned::operator ^= (const sc_int_base &v)
63312854Sgabeblack@google.com{
63412854Sgabeblack@google.com    return operator ^= ((int64)v);
63512854Sgabeblack@google.com}
63612854Sgabeblack@google.com
63712854Sgabeblack@google.comsc_unsigned
63812854Sgabeblack@google.comoperator << (const sc_unsigned &u, const sc_int_base &v)
63912854Sgabeblack@google.com{
64012854Sgabeblack@google.com    return operator << (u, (int64)v);
64112854Sgabeblack@google.com}
64212854Sgabeblack@google.comconst sc_unsigned &
64312854Sgabeblack@google.comsc_unsigned::operator <<= (const sc_int_base &v)
64412854Sgabeblack@google.com{
64512854Sgabeblack@google.com    return operator <<= ((int64)v);
64612854Sgabeblack@google.com}
64712854Sgabeblack@google.com
64812854Sgabeblack@google.comsc_unsigned
64912854Sgabeblack@google.comoperator >> (const sc_unsigned&    u, const sc_int_base&  v)
65012854Sgabeblack@google.com{
65112854Sgabeblack@google.com    return operator >> (u, (int64)v);
65212854Sgabeblack@google.com}
65312854Sgabeblack@google.comconst sc_unsigned &
65412854Sgabeblack@google.comsc_unsigned::operator >>= (const sc_int_base&  v)
65512854Sgabeblack@google.com{
65612854Sgabeblack@google.com    return operator >>= ((int64)v);
65712854Sgabeblack@google.com}
65812854Sgabeblack@google.com
65912854Sgabeblack@google.combool
66012854Sgabeblack@google.comoperator == (const sc_unsigned &u, const sc_int_base &v)
66112854Sgabeblack@google.com{
66212854Sgabeblack@google.com    return operator == (u, (int64)v);
66312854Sgabeblack@google.com}
66412854Sgabeblack@google.combool
66512854Sgabeblack@google.comoperator == (const sc_int_base &u, const sc_unsigned &v)
66612854Sgabeblack@google.com{
66712854Sgabeblack@google.com    return operator == ((int64)u, v);
66812854Sgabeblack@google.com}
66912854Sgabeblack@google.com
67012854Sgabeblack@google.combool
67112854Sgabeblack@google.comoperator != (const sc_unsigned &u, const sc_int_base &v)
67212854Sgabeblack@google.com{
67312854Sgabeblack@google.com    return operator != (u, (int64)v);
67412854Sgabeblack@google.com}
67512854Sgabeblack@google.combool
67612854Sgabeblack@google.comoperator != (const sc_int_base &u, const sc_unsigned &v)
67712854Sgabeblack@google.com{
67812854Sgabeblack@google.com    return operator != ((int64)u, v);
67912854Sgabeblack@google.com}
68012854Sgabeblack@google.com
68112854Sgabeblack@google.combool
68212854Sgabeblack@google.comoperator < (const sc_unsigned &u, const sc_int_base &v)
68312854Sgabeblack@google.com{
68412854Sgabeblack@google.com    return operator < (u, (int64)v);
68512854Sgabeblack@google.com}
68612854Sgabeblack@google.combool
68712854Sgabeblack@google.comoperator < (const sc_int_base &u, const sc_unsigned &v)
68812854Sgabeblack@google.com{
68912854Sgabeblack@google.com    return operator < ((int64)u, v);
69012854Sgabeblack@google.com}
69112854Sgabeblack@google.com
69212854Sgabeblack@google.combool
69312854Sgabeblack@google.comoperator <= (const sc_unsigned &u, const sc_int_base &v)
69412854Sgabeblack@google.com{
69512854Sgabeblack@google.com    return operator <= (u, (int64)v);
69612854Sgabeblack@google.com}
69712854Sgabeblack@google.combool
69812854Sgabeblack@google.comoperator <= (const sc_int_base &u, const sc_unsigned &v)
69912854Sgabeblack@google.com{
70012854Sgabeblack@google.com    return operator <= ((int64)u, v);
70112854Sgabeblack@google.com}
70212854Sgabeblack@google.com
70312854Sgabeblack@google.combool
70412854Sgabeblack@google.comoperator > (const sc_unsigned &u, const sc_int_base &v)
70512854Sgabeblack@google.com{
70612854Sgabeblack@google.com    return operator > (u, (int64)v);
70712854Sgabeblack@google.com}
70812854Sgabeblack@google.combool
70912854Sgabeblack@google.comoperator > (const sc_int_base &u, const sc_unsigned &v)
71012854Sgabeblack@google.com{
71112854Sgabeblack@google.com    return operator > ((int64)u, v);
71212854Sgabeblack@google.com}
71312854Sgabeblack@google.com
71412854Sgabeblack@google.combool
71512854Sgabeblack@google.comoperator >= (const sc_unsigned &u, const sc_int_base &v)
71612854Sgabeblack@google.com{
71712854Sgabeblack@google.com    return operator >= (u, (int64)v);
71812854Sgabeblack@google.com}
71912854Sgabeblack@google.combool
72012854Sgabeblack@google.comoperator >= (const sc_int_base &u, const sc_unsigned &v)
72112854Sgabeblack@google.com{
72212854Sgabeblack@google.com    return operator >= ((int64)u, v);
72312854Sgabeblack@google.com}
72412854Sgabeblack@google.com
72512854Sgabeblack@google.com
72612854Sgabeblack@google.com// ----------------------------------------------------------------------------
72712854Sgabeblack@google.com//  SECTION: Interfacing with sc_uint_base
72812854Sgabeblack@google.com// ----------------------------------------------------------------------------
72912854Sgabeblack@google.com
73012854Sgabeblack@google.comconst sc_unsigned &
73112854Sgabeblack@google.comsc_unsigned::operator = (const sc_uint_base &v)
73212854Sgabeblack@google.com{
73312854Sgabeblack@google.com    return operator = ((uint64)v);
73412854Sgabeblack@google.com}
73512854Sgabeblack@google.com
73612854Sgabeblack@google.comsc_unsigned
73712854Sgabeblack@google.comoperator + (const sc_unsigned &u, const sc_uint_base &v)
73812854Sgabeblack@google.com{
73912854Sgabeblack@google.com    return operator + (u, (uint64)v);
74012854Sgabeblack@google.com}
74112854Sgabeblack@google.comsc_unsigned
74212854Sgabeblack@google.comoperator + (const sc_uint_base &u, const sc_unsigned &v)
74312854Sgabeblack@google.com{
74412854Sgabeblack@google.com    return operator + ((uint64)u, v);
74512854Sgabeblack@google.com}
74612854Sgabeblack@google.comconst sc_unsigned &
74712854Sgabeblack@google.comsc_unsigned::operator += (const sc_uint_base &v)
74812854Sgabeblack@google.com{
74912854Sgabeblack@google.com    return operator += ((uint64)v);
75012854Sgabeblack@google.com}
75112854Sgabeblack@google.com
75212854Sgabeblack@google.comconst sc_unsigned &
75312854Sgabeblack@google.comsc_unsigned::operator -= (const sc_uint_base &v)
75412854Sgabeblack@google.com{
75512854Sgabeblack@google.com    return operator -= ((uint64)v);
75612854Sgabeblack@google.com}
75712854Sgabeblack@google.com
75812854Sgabeblack@google.comsc_unsigned
75912854Sgabeblack@google.comoperator * (const sc_unsigned &u, const sc_uint_base &v)
76012854Sgabeblack@google.com{
76112854Sgabeblack@google.com    return operator * (u, (uint64)v);
76212854Sgabeblack@google.com}
76312854Sgabeblack@google.comsc_unsigned
76412854Sgabeblack@google.comoperator * (const sc_uint_base &u, const sc_unsigned &v)
76512854Sgabeblack@google.com{
76612854Sgabeblack@google.com    return operator * ((uint64)u, v);
76712854Sgabeblack@google.com}
76812854Sgabeblack@google.comconst sc_unsigned &
76912854Sgabeblack@google.comsc_unsigned::operator *= (const sc_uint_base &v)
77012854Sgabeblack@google.com{
77112854Sgabeblack@google.com    return operator *= ((uint64)v);
77212854Sgabeblack@google.com}
77312854Sgabeblack@google.com
77412854Sgabeblack@google.comsc_unsigned
77512854Sgabeblack@google.comoperator / (const sc_unsigned &u, const sc_uint_base &v)
77612854Sgabeblack@google.com{
77712854Sgabeblack@google.com    return operator / (u, (uint64)v);
77812854Sgabeblack@google.com}
77912854Sgabeblack@google.comsc_unsigned
78012854Sgabeblack@google.comoperator / (const sc_uint_base &u, const sc_unsigned &v)
78112854Sgabeblack@google.com{
78212854Sgabeblack@google.com    return operator / ((uint64)u, v);
78312854Sgabeblack@google.com}
78412854Sgabeblack@google.comconst sc_unsigned &
78512854Sgabeblack@google.comsc_unsigned::operator /= (const sc_uint_base &v)
78612854Sgabeblack@google.com{
78712854Sgabeblack@google.com    return operator /= ((uint64)v);
78812854Sgabeblack@google.com}
78912854Sgabeblack@google.com
79012854Sgabeblack@google.comsc_unsigned
79112854Sgabeblack@google.comoperator % (const sc_unsigned &u, const sc_uint_base &v)
79212854Sgabeblack@google.com{
79312854Sgabeblack@google.com    return operator % (u, (uint64)v);
79412854Sgabeblack@google.com}
79512854Sgabeblack@google.comsc_unsigned
79612854Sgabeblack@google.comoperator % (const sc_uint_base &u, const sc_unsigned &v)
79712854Sgabeblack@google.com{
79812854Sgabeblack@google.com    return operator % ((uint64)u, v);
79912854Sgabeblack@google.com}
80012854Sgabeblack@google.comconst sc_unsigned &
80112854Sgabeblack@google.comsc_unsigned::operator %= (const sc_uint_base &v)
80212854Sgabeblack@google.com{
80312854Sgabeblack@google.com    return operator %= ((uint64)v);
80412854Sgabeblack@google.com}
80512854Sgabeblack@google.com
80612854Sgabeblack@google.comsc_unsigned
80712854Sgabeblack@google.comoperator & (const sc_unsigned &u, const sc_uint_base &v)
80812854Sgabeblack@google.com{
80912854Sgabeblack@google.com    return operator & (u, (uint64)v);
81012854Sgabeblack@google.com}
81112854Sgabeblack@google.comsc_unsigned
81212854Sgabeblack@google.comoperator & (const sc_uint_base &u, const sc_unsigned &v)
81312854Sgabeblack@google.com{
81412854Sgabeblack@google.com    return operator & ((uint64)u, v);
81512854Sgabeblack@google.com}
81612854Sgabeblack@google.comconst sc_unsigned &
81712854Sgabeblack@google.comsc_unsigned::operator &= (const sc_uint_base &v)
81812854Sgabeblack@google.com{
81912854Sgabeblack@google.com    return operator &= ((uint64)v);
82012854Sgabeblack@google.com}
82112854Sgabeblack@google.com
82212854Sgabeblack@google.comsc_unsigned
82312854Sgabeblack@google.comoperator | (const sc_unsigned &u, const sc_uint_base &v)
82412854Sgabeblack@google.com{
82512854Sgabeblack@google.com    return operator | (u, (uint64)v);
82612854Sgabeblack@google.com}
82712854Sgabeblack@google.comsc_unsigned
82812854Sgabeblack@google.comoperator | (const sc_uint_base &u, const sc_unsigned &v)
82912854Sgabeblack@google.com{
83012854Sgabeblack@google.com    return operator | ((uint64)u, v);
83112854Sgabeblack@google.com}
83212854Sgabeblack@google.comconst sc_unsigned &
83312854Sgabeblack@google.comsc_unsigned::operator |= (const sc_uint_base &v)
83412854Sgabeblack@google.com{
83512854Sgabeblack@google.com    return operator |= ((uint64)v);
83612854Sgabeblack@google.com}
83712854Sgabeblack@google.com
83812854Sgabeblack@google.comsc_unsigned
83912854Sgabeblack@google.comoperator ^ (const sc_unsigned &u, const sc_uint_base &v)
84012854Sgabeblack@google.com{
84112854Sgabeblack@google.com    return operator ^ (u, (uint64)v);
84212854Sgabeblack@google.com}
84312854Sgabeblack@google.comsc_unsigned
84412854Sgabeblack@google.comoperator ^ (const sc_uint_base &u, const sc_unsigned &v)
84512854Sgabeblack@google.com{
84612854Sgabeblack@google.com    return operator ^ ((uint64)u, v);
84712854Sgabeblack@google.com}
84812854Sgabeblack@google.comconst sc_unsigned &
84912854Sgabeblack@google.comsc_unsigned::operator ^= (const sc_uint_base &v)
85012854Sgabeblack@google.com{
85112854Sgabeblack@google.com    return operator ^= ((uint64)v);
85212854Sgabeblack@google.com}
85312854Sgabeblack@google.com
85412854Sgabeblack@google.comsc_unsigned
85512854Sgabeblack@google.comoperator << (const sc_unsigned &u, const sc_uint_base &v)
85612854Sgabeblack@google.com{
85712854Sgabeblack@google.com    return operator << (u, (uint64)v);
85812854Sgabeblack@google.com}
85912854Sgabeblack@google.comconst sc_unsigned &
86012854Sgabeblack@google.comsc_unsigned::operator <<= (const sc_uint_base &v)
86112854Sgabeblack@google.com{
86212854Sgabeblack@google.com    return operator <<= ((uint64)v);
86312854Sgabeblack@google.com}
86412854Sgabeblack@google.com
86512854Sgabeblack@google.comsc_unsigned
86612854Sgabeblack@google.comoperator >> (const sc_unsigned &u, const sc_uint_base &v)
86712854Sgabeblack@google.com{
86812854Sgabeblack@google.com    return operator >> (u, (uint64)v);
86912854Sgabeblack@google.com}
87012854Sgabeblack@google.comconst sc_unsigned &
87112854Sgabeblack@google.comsc_unsigned::operator >>= (const sc_uint_base &v)
87212854Sgabeblack@google.com{
87312854Sgabeblack@google.com    return operator >>= ((uint64)v);
87412854Sgabeblack@google.com}
87512854Sgabeblack@google.com
87612854Sgabeblack@google.combool
87712854Sgabeblack@google.comoperator == (const sc_unsigned &u, const sc_uint_base &v)
87812854Sgabeblack@google.com{
87912854Sgabeblack@google.com    return operator == (u, (uint64)v);
88012854Sgabeblack@google.com}
88112854Sgabeblack@google.combool
88212854Sgabeblack@google.comoperator == (const sc_uint_base &u, const sc_unsigned &v)
88312854Sgabeblack@google.com{
88412854Sgabeblack@google.com    return operator == ((uint64)u, v);
88512854Sgabeblack@google.com}
88612854Sgabeblack@google.com
88712854Sgabeblack@google.combool
88812854Sgabeblack@google.comoperator != (const sc_unsigned &u, const sc_uint_base &v)
88912854Sgabeblack@google.com{
89012854Sgabeblack@google.com    return operator != (u, (uint64)v);
89112854Sgabeblack@google.com}
89212854Sgabeblack@google.combool
89312854Sgabeblack@google.comoperator != (const sc_uint_base &u, const sc_unsigned &v)
89412854Sgabeblack@google.com{
89512854Sgabeblack@google.com    return operator != ((uint64)u, v);
89612854Sgabeblack@google.com}
89712854Sgabeblack@google.com
89812854Sgabeblack@google.combool
89912854Sgabeblack@google.comoperator < (const sc_unsigned &u, const sc_uint_base &v)
90012854Sgabeblack@google.com{
90112854Sgabeblack@google.com    return operator < (u, (uint64)v);
90212854Sgabeblack@google.com}
90312854Sgabeblack@google.combool
90412854Sgabeblack@google.comoperator < (const sc_uint_base &u, const sc_unsigned &v)
90512854Sgabeblack@google.com{
90612854Sgabeblack@google.com    return operator < ((uint64)u, v);
90712854Sgabeblack@google.com}
90812854Sgabeblack@google.com
90912854Sgabeblack@google.combool
91012854Sgabeblack@google.comoperator <= (const sc_unsigned &u, const sc_uint_base &v)
91112854Sgabeblack@google.com{
91212854Sgabeblack@google.com    return operator <= (u, (uint64)v);
91312854Sgabeblack@google.com}
91412854Sgabeblack@google.combool
91512854Sgabeblack@google.comoperator <= (const sc_uint_base &u, const sc_unsigned &v)
91612854Sgabeblack@google.com{
91712854Sgabeblack@google.com    return operator <= ((uint64)u, v);
91812854Sgabeblack@google.com}
91912854Sgabeblack@google.com
92012854Sgabeblack@google.combool
92112854Sgabeblack@google.comoperator > (const sc_unsigned &u, const sc_uint_base &v)
92212854Sgabeblack@google.com{
92312854Sgabeblack@google.com    return operator > (u, (uint64)v);
92412854Sgabeblack@google.com}
92512854Sgabeblack@google.combool
92612854Sgabeblack@google.comoperator > (const sc_uint_base &u, const sc_unsigned &v)
92712854Sgabeblack@google.com{
92812854Sgabeblack@google.com    return operator > ((uint64)u, v);
92912854Sgabeblack@google.com}
93012854Sgabeblack@google.com
93112854Sgabeblack@google.combool
93212854Sgabeblack@google.comoperator >= (const sc_unsigned &u, const sc_uint_base &v)
93312854Sgabeblack@google.com{
93412854Sgabeblack@google.com    return operator >= (u, (uint64)v);
93512854Sgabeblack@google.com}
93612854Sgabeblack@google.combool
93712854Sgabeblack@google.comoperator >= (const sc_uint_base &u, const sc_unsigned &v)
93812854Sgabeblack@google.com{
93912854Sgabeblack@google.com    return operator >= ((uint64)u, v);
94012854Sgabeblack@google.com}
94112854Sgabeblack@google.com
94212854Sgabeblack@google.com
94312854Sgabeblack@google.com// ----------------------------------------------------------------------------
94412854Sgabeblack@google.com//  SECTION: Input and output operators
94512854Sgabeblack@google.com// ----------------------------------------------------------------------------
94612854Sgabeblack@google.com
94712854Sgabeblack@google.com// The operators in this section are included from sc_nbcommon.cpp.
94812854Sgabeblack@google.com
94912854Sgabeblack@google.com
95012854Sgabeblack@google.com// ----------------------------------------------------------------------------
95112854Sgabeblack@google.com//  SECTION: Operator macros.
95212854Sgabeblack@google.com// ----------------------------------------------------------------------------
95312854Sgabeblack@google.com
95412854Sgabeblack@google.com#define CONVERT_LONG(u) \
95512854Sgabeblack@google.comsmall_type u ## s = get_sign(u); \
95612854Sgabeblack@google.comsc_digit u ## d[DIGITS_PER_ULONG]; \
95712854Sgabeblack@google.comfrom_uint(DIGITS_PER_ULONG, u ## d, (unsigned long) u);
95812854Sgabeblack@google.com
95912854Sgabeblack@google.com#define CONVERT_LONG_2(u) \
96012854Sgabeblack@google.comsc_digit u ## d[DIGITS_PER_ULONG]; \
96112854Sgabeblack@google.comfrom_uint(DIGITS_PER_ULONG, u ## d, (unsigned long) u);
96212854Sgabeblack@google.com
96312854Sgabeblack@google.com#define CONVERT_INT(u) \
96412854Sgabeblack@google.comsmall_type u ## s = get_sign(u); \
96512854Sgabeblack@google.comsc_digit u ## d[DIGITS_PER_UINT]; \
96612854Sgabeblack@google.comfrom_uint(DIGITS_PER_UINT, u ## d, (unsigned int) u);
96712854Sgabeblack@google.com
96812854Sgabeblack@google.com#define CONVERT_INT_2(u) \
96912854Sgabeblack@google.comsc_digit u ## d[DIGITS_PER_UINT]; \
97012854Sgabeblack@google.comfrom_uint(DIGITS_PER_UINT, u ## d, (unsigned int) u);
97112854Sgabeblack@google.com
97212854Sgabeblack@google.com#define CONVERT_INT64(u) \
97312854Sgabeblack@google.comsmall_type u ## s = get_sign(u); \
97412854Sgabeblack@google.comsc_digit u ## d[DIGITS_PER_UINT64]; \
97512854Sgabeblack@google.comfrom_uint(DIGITS_PER_UINT64, u ## d, (uint64) u);
97612854Sgabeblack@google.com
97712854Sgabeblack@google.com#define CONVERT_INT64_2(u) \
97812854Sgabeblack@google.comsc_digit u ## d[DIGITS_PER_UINT64]; \
97912854Sgabeblack@google.comfrom_uint(DIGITS_PER_UINT64, u ## d, (uint64) u);
98012854Sgabeblack@google.com
98112854Sgabeblack@google.com
98212854Sgabeblack@google.com// ----------------------------------------------------------------------------
98312854Sgabeblack@google.com//  SECTION: PLUS operators: +, +=, ++
98412854Sgabeblack@google.com// ----------------------------------------------------------------------------
98512854Sgabeblack@google.com
98612854Sgabeblack@google.com// Cases to consider when computing u + v:
98712854Sgabeblack@google.com// 1. 0 + v = v
98812854Sgabeblack@google.com// 2. u + 0 = u
98912854Sgabeblack@google.com// 3. if sgn(u) == sgn(v)
99012854Sgabeblack@google.com//    3.1 u + v = +(u + v) = sgn(u) * (u + v)
99112854Sgabeblack@google.com//    3.2 (-u) + (-v) = -(u + v) = sgn(u) * (u + v)
99212854Sgabeblack@google.com// 4. if sgn(u) != sgn(v)
99312854Sgabeblack@google.com//    4.1 u + (-v) = u - v = sgn(u) * (u - v)
99412854Sgabeblack@google.com//    4.2 (-u) + v = -(u - v) ==> sgn(u) * (u - v)
99512854Sgabeblack@google.com//
99612854Sgabeblack@google.com// Specialization of above cases for computing ++u or u++:
99712854Sgabeblack@google.com// 1. 0 + 1 = 1
99812854Sgabeblack@google.com// 3. u + 1 = u + 1 = sgn(u) * (u + 1)
99912854Sgabeblack@google.com// 4. (-u) + 1 = -(u - 1) = sgn(u) * (u - 1)
100012854Sgabeblack@google.com
100112854Sgabeblack@google.comsc_unsigned
100212854Sgabeblack@google.comoperator + (const sc_unsigned &u, const sc_unsigned &v)
100312854Sgabeblack@google.com{
100412854Sgabeblack@google.com    if (u.sgn == SC_ZERO) // case 1
100512854Sgabeblack@google.com        return sc_unsigned(v);
100612854Sgabeblack@google.com
100712854Sgabeblack@google.com    if (v.sgn == SC_ZERO) // case 2
100812854Sgabeblack@google.com        return sc_unsigned(u);
100912854Sgabeblack@google.com
101012854Sgabeblack@google.com    // cases 3 and 4
101112854Sgabeblack@google.com    return add_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
101212854Sgabeblack@google.com                               v.sgn, v.nbits, v.ndigits, v.digit);
101312854Sgabeblack@google.com}
101412854Sgabeblack@google.com
101512854Sgabeblack@google.com
101612854Sgabeblack@google.comsc_unsigned
101712854Sgabeblack@google.comoperator + (const sc_unsigned &u, uint64 v)
101812854Sgabeblack@google.com{
101912854Sgabeblack@google.com    if (v == 0) // case 2
102012854Sgabeblack@google.com        return sc_unsigned(u);
102112854Sgabeblack@google.com
102212854Sgabeblack@google.com    CONVERT_INT64(v);
102312854Sgabeblack@google.com
102412854Sgabeblack@google.com    if (u.sgn == SC_ZERO)    // case 1
102512854Sgabeblack@google.com        return sc_unsigned(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
102612854Sgabeblack@google.com
102712854Sgabeblack@google.com    // cases 3 and 4
102812854Sgabeblack@google.com    return add_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
102912854Sgabeblack@google.com                               vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
103012854Sgabeblack@google.com}
103112854Sgabeblack@google.com
103212854Sgabeblack@google.com
103312854Sgabeblack@google.comsc_unsigned
103412854Sgabeblack@google.comoperator + (uint64 u, const sc_unsigned &v)
103512854Sgabeblack@google.com{
103612854Sgabeblack@google.com    if (u == 0) // case 1
103712854Sgabeblack@google.com        return sc_unsigned(v);
103812854Sgabeblack@google.com
103912854Sgabeblack@google.com    CONVERT_INT64(u);
104012854Sgabeblack@google.com
104112854Sgabeblack@google.com    if (v.sgn == SC_ZERO) // case 2
104212854Sgabeblack@google.com        return sc_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
104312854Sgabeblack@google.com
104412854Sgabeblack@google.com    // cases 3 and 4
104512854Sgabeblack@google.com    return add_unsigned_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
104612854Sgabeblack@google.com                               v.sgn, v.nbits, v.ndigits, v.digit);
104712854Sgabeblack@google.com}
104812854Sgabeblack@google.com
104912854Sgabeblack@google.com
105012854Sgabeblack@google.comsc_unsigned
105112854Sgabeblack@google.comoperator + (const sc_unsigned &u, unsigned long v)
105212854Sgabeblack@google.com{
105312854Sgabeblack@google.com    if (v == 0) // case 2
105412854Sgabeblack@google.com        return sc_unsigned(u);
105512854Sgabeblack@google.com
105612854Sgabeblack@google.com    CONVERT_LONG(v);
105712854Sgabeblack@google.com
105812854Sgabeblack@google.com    if (u.sgn == SC_ZERO) // case 1
105912854Sgabeblack@google.com        return sc_unsigned(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
106012854Sgabeblack@google.com
106112854Sgabeblack@google.com    // cases 3 and 4
106212854Sgabeblack@google.com    return add_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
106312854Sgabeblack@google.com                               vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
106412854Sgabeblack@google.com}
106512854Sgabeblack@google.com
106612854Sgabeblack@google.com
106712854Sgabeblack@google.comsc_unsigned
106812854Sgabeblack@google.comoperator + (unsigned long u, const sc_unsigned &v)
106912854Sgabeblack@google.com{
107012854Sgabeblack@google.com    if (u == 0) // case 1
107112854Sgabeblack@google.com        return sc_unsigned(v);
107212854Sgabeblack@google.com
107312854Sgabeblack@google.com    CONVERT_LONG(u);
107412854Sgabeblack@google.com
107512854Sgabeblack@google.com    if (v.sgn == SC_ZERO) // case 2
107612854Sgabeblack@google.com        return sc_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
107712854Sgabeblack@google.com
107812854Sgabeblack@google.com    // cases 3 and 4
107912854Sgabeblack@google.com    return add_unsigned_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
108012854Sgabeblack@google.com                               v.sgn, v.nbits, v.ndigits, v.digit);
108112854Sgabeblack@google.com}
108212854Sgabeblack@google.com
108312854Sgabeblack@google.com// The rest of the operators in this section are included from
108412854Sgabeblack@google.com// sc_nbcommon.cpp.
108512854Sgabeblack@google.com
108612854Sgabeblack@google.com
108712854Sgabeblack@google.com// ----------------------------------------------------------------------------
108812854Sgabeblack@google.com//  SECTION: MINUS operators: -, -=, --
108912854Sgabeblack@google.com// ----------------------------------------------------------------------------
109012854Sgabeblack@google.com
109112854Sgabeblack@google.com// Cases to consider when computing u + v:
109212854Sgabeblack@google.com// 1. u - 0 = u
109312854Sgabeblack@google.com// 2. 0 - v = -v
109412854Sgabeblack@google.com// 3. if sgn(u) != sgn(v)
109512854Sgabeblack@google.com//    3.1 u - (-v) = u + v = sgn(u) * (u + v)
109612854Sgabeblack@google.com//    3.2 (-u) - v = -(u + v) ==> sgn(u) * (u + v)
109712854Sgabeblack@google.com// 4. if sgn(u) == sgn(v)
109812854Sgabeblack@google.com//    4.1 u - v = +(u - v) = sgn(u) * (u - v)
109912854Sgabeblack@google.com//    4.2 (-u) - (-v) = -(u - v) = sgn(u) * (u - v)
110012854Sgabeblack@google.com//
110112854Sgabeblack@google.com// Specialization of above cases for computing --u or u--:
110212854Sgabeblack@google.com// 1. 0 - 1 = -1
110312854Sgabeblack@google.com// 3. (-u) - 1 = -(u + 1) = sgn(u) * (u + 1)
110412854Sgabeblack@google.com// 4. u - 1 = u - 1 = sgn(u) * (u - 1)
110512854Sgabeblack@google.com
110612854Sgabeblack@google.com// The operators in this section are included from sc_nbcommon.cpp.
110712854Sgabeblack@google.com
110812854Sgabeblack@google.com
110912854Sgabeblack@google.com// ----------------------------------------------------------------------------
111012854Sgabeblack@google.com//  SECTION: MULTIPLICATION operators: *, *=
111112854Sgabeblack@google.com// ----------------------------------------------------------------------------
111212854Sgabeblack@google.com
111312854Sgabeblack@google.com// Cases to consider when computing u * v:
111412854Sgabeblack@google.com// 1. u * 0 = 0 * v = 0
111512854Sgabeblack@google.com// 2. 1 * v = v and -1 * v = -v
111612854Sgabeblack@google.com// 3. u * 1 = u and u * -1 = -u
111712854Sgabeblack@google.com// 4. u * v = u * v
111812854Sgabeblack@google.com
111912854Sgabeblack@google.comsc_unsigned
112012854Sgabeblack@google.comoperator * (const sc_unsigned &u, const sc_unsigned &v)
112112854Sgabeblack@google.com{
112212854Sgabeblack@google.com    small_type s = mul_signs(u.sgn, v.sgn);
112312854Sgabeblack@google.com
112412854Sgabeblack@google.com    if (s == SC_ZERO) // case 1
112512854Sgabeblack@google.com        return sc_unsigned();
112612854Sgabeblack@google.com
112712854Sgabeblack@google.com    // cases 2-4
112812854Sgabeblack@google.com    return mul_unsigned_friend(s, u.nbits, u.ndigits, u.digit,
112912854Sgabeblack@google.com                               v.nbits, v.ndigits, v.digit);
113012854Sgabeblack@google.com}
113112854Sgabeblack@google.com
113212854Sgabeblack@google.com
113312854Sgabeblack@google.comsc_unsigned
113412854Sgabeblack@google.comoperator * (const sc_unsigned &u, uint64 v)
113512854Sgabeblack@google.com{
113612854Sgabeblack@google.com    small_type s = mul_signs(u.sgn, get_sign(v));
113712854Sgabeblack@google.com
113812854Sgabeblack@google.com    if (s == SC_ZERO) // case 1
113912854Sgabeblack@google.com        return sc_unsigned();
114012854Sgabeblack@google.com
114112854Sgabeblack@google.com    CONVERT_INT64_2(v);
114212854Sgabeblack@google.com
114312854Sgabeblack@google.com    // cases 2-4
114412854Sgabeblack@google.com    return mul_unsigned_friend(s, u.nbits, u.ndigits, u.digit,
114512854Sgabeblack@google.com                               BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
114612854Sgabeblack@google.com}
114712854Sgabeblack@google.com
114812854Sgabeblack@google.com
114912854Sgabeblack@google.comsc_unsigned
115012854Sgabeblack@google.comoperator * (uint64 u, const sc_unsigned &v)
115112854Sgabeblack@google.com{
115212854Sgabeblack@google.com    small_type s = mul_signs(v.sgn, get_sign(u));
115312854Sgabeblack@google.com
115412854Sgabeblack@google.com    if (s == SC_ZERO) // case 1
115512854Sgabeblack@google.com        return sc_unsigned();
115612854Sgabeblack@google.com
115712854Sgabeblack@google.com    CONVERT_INT64_2(u);
115812854Sgabeblack@google.com
115912854Sgabeblack@google.com    // cases 2-4
116012854Sgabeblack@google.com    return mul_unsigned_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
116112854Sgabeblack@google.com                               v.nbits, v.ndigits, v.digit);
116212854Sgabeblack@google.com}
116312854Sgabeblack@google.com
116412854Sgabeblack@google.com
116512854Sgabeblack@google.comsc_unsigned
116612854Sgabeblack@google.comoperator * (const sc_unsigned &u, unsigned long v)
116712854Sgabeblack@google.com{
116812854Sgabeblack@google.com    small_type s = mul_signs(u.sgn, get_sign(v));
116912854Sgabeblack@google.com
117012854Sgabeblack@google.com    if (s == SC_ZERO) // case 1
117112854Sgabeblack@google.com        return sc_unsigned();
117212854Sgabeblack@google.com
117312854Sgabeblack@google.com    CONVERT_LONG_2(v);
117412854Sgabeblack@google.com
117512854Sgabeblack@google.com    // else cases 2-4
117612854Sgabeblack@google.com    return mul_unsigned_friend(s, u.nbits, u.ndigits, u.digit,
117712854Sgabeblack@google.com                               BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
117812854Sgabeblack@google.com}
117912854Sgabeblack@google.com
118012854Sgabeblack@google.comsc_unsigned
118112854Sgabeblack@google.comoperator * (unsigned long u, const sc_unsigned &v)
118212854Sgabeblack@google.com{
118312854Sgabeblack@google.com    small_type s = mul_signs(v.sgn, get_sign(u));
118412854Sgabeblack@google.com
118512854Sgabeblack@google.com    if (s == SC_ZERO) // case 1
118612854Sgabeblack@google.com        return sc_unsigned();
118712854Sgabeblack@google.com
118812854Sgabeblack@google.com    CONVERT_LONG_2(u);
118912854Sgabeblack@google.com
119012854Sgabeblack@google.com    // cases 2-4
119112854Sgabeblack@google.com    return mul_unsigned_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
119212854Sgabeblack@google.com                               v.nbits, v.ndigits, v.digit);
119312854Sgabeblack@google.com}
119412854Sgabeblack@google.com
119512854Sgabeblack@google.com// The rest of the operators in this section are included from
119612854Sgabeblack@google.com// sc_nbcommon.cpp.
119712854Sgabeblack@google.com
119812854Sgabeblack@google.com
119912854Sgabeblack@google.com// ----------------------------------------------------------------------------
120012854Sgabeblack@google.com//  SECTION: DIVISION operators: /, /=
120112854Sgabeblack@google.com// ----------------------------------------------------------------------------
120212854Sgabeblack@google.com
120312854Sgabeblack@google.com// Cases to consider when finding the quotient q = floor(u/v):
120412854Sgabeblack@google.com// Note that u = q * v + r for r < q.
120512854Sgabeblack@google.com// 1. 0 / 0 or u / 0 => error
120612854Sgabeblack@google.com// 2. 0 / v => 0 = 0 * v + 0
120712854Sgabeblack@google.com// 3. u / v & &u = v => u = 1 * u + 0  - u or v can be 1 or -1
120812854Sgabeblack@google.com// 4. u / v & &u < v => u = 0 * v + u  - u can be 1 or -1
120912854Sgabeblack@google.com// 5. u / v & &u > v => u = q * v + r  - v can be 1 or -1
121012854Sgabeblack@google.com
121112854Sgabeblack@google.comsc_unsigned
121212854Sgabeblack@google.comoperator / (const sc_unsigned &u, const sc_unsigned &v)
121312854Sgabeblack@google.com{
121412854Sgabeblack@google.com    small_type s = mul_signs(u.sgn, v.sgn);
121512854Sgabeblack@google.com
121612854Sgabeblack@google.com    if (s == SC_ZERO) {
121712854Sgabeblack@google.com        div_by_zero(v.sgn); // case 1
121812854Sgabeblack@google.com        return sc_unsigned(); // case 2
121912854Sgabeblack@google.com    }
122012854Sgabeblack@google.com
122112854Sgabeblack@google.com    // other cases
122212854Sgabeblack@google.com    return div_unsigned_friend(s, u.nbits, u.ndigits, u.digit,
122312854Sgabeblack@google.com                               v.nbits, v.ndigits, v.digit);
122412854Sgabeblack@google.com}
122512854Sgabeblack@google.com
122612854Sgabeblack@google.com
122712854Sgabeblack@google.comsc_unsigned
122812854Sgabeblack@google.comoperator / (const sc_unsigned &u, uint64 v)
122912854Sgabeblack@google.com{
123012854Sgabeblack@google.com    small_type s = mul_signs(u.sgn, get_sign(v));
123112854Sgabeblack@google.com
123212854Sgabeblack@google.com    if (s == SC_ZERO) {
123312854Sgabeblack@google.com        div_by_zero(v); // case 1
123412854Sgabeblack@google.com        return sc_unsigned(); // case 2
123512854Sgabeblack@google.com    }
123612854Sgabeblack@google.com
123712854Sgabeblack@google.com    CONVERT_INT64_2(v);
123812854Sgabeblack@google.com
123912854Sgabeblack@google.com    // other cases
124012854Sgabeblack@google.com    return div_unsigned_friend(s, u.nbits, u.ndigits, u.digit,
124112854Sgabeblack@google.com                               BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
124212854Sgabeblack@google.com}
124312854Sgabeblack@google.com
124412854Sgabeblack@google.com
124512854Sgabeblack@google.comsc_unsigned
124612854Sgabeblack@google.comoperator / (uint64 u, const sc_unsigned &v)
124712854Sgabeblack@google.com{
124812854Sgabeblack@google.com    small_type s = mul_signs(v.sgn, get_sign(u));
124912854Sgabeblack@google.com
125012854Sgabeblack@google.com    if (s == SC_ZERO) {
125112854Sgabeblack@google.com        div_by_zero(v.sgn); // case 1
125212854Sgabeblack@google.com        return sc_unsigned(); // case 2
125312854Sgabeblack@google.com
125412854Sgabeblack@google.com    }
125512854Sgabeblack@google.com
125612854Sgabeblack@google.com    CONVERT_INT64_2(u);
125712854Sgabeblack@google.com
125812854Sgabeblack@google.com    // other cases
125912854Sgabeblack@google.com    return div_unsigned_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
126012854Sgabeblack@google.com                               v.nbits, v.ndigits, v.digit);
126112854Sgabeblack@google.com}
126212854Sgabeblack@google.com
126312854Sgabeblack@google.com
126412854Sgabeblack@google.comsc_unsigned
126512854Sgabeblack@google.comoperator / (const sc_unsigned &u, unsigned long v)
126612854Sgabeblack@google.com{
126712854Sgabeblack@google.com    small_type s = mul_signs(u.sgn, get_sign(v));
126812854Sgabeblack@google.com
126912854Sgabeblack@google.com    if (s == SC_ZERO) {
127012854Sgabeblack@google.com        div_by_zero(v); // case 1
127112854Sgabeblack@google.com        return sc_unsigned(); // case 2
127212854Sgabeblack@google.com    }
127312854Sgabeblack@google.com
127412854Sgabeblack@google.com    CONVERT_LONG_2(v);
127512854Sgabeblack@google.com
127612854Sgabeblack@google.com    // other cases
127712854Sgabeblack@google.com    return div_unsigned_friend(s, u.nbits, u.ndigits, u.digit,
127812854Sgabeblack@google.com                               BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
127912854Sgabeblack@google.com}
128012854Sgabeblack@google.com
128112854Sgabeblack@google.com
128212854Sgabeblack@google.comsc_unsigned
128312854Sgabeblack@google.comoperator / (unsigned long u, const sc_unsigned &v)
128412854Sgabeblack@google.com{
128512854Sgabeblack@google.com    small_type s = mul_signs(v.sgn, get_sign(u));
128612854Sgabeblack@google.com
128712854Sgabeblack@google.com    if (s == SC_ZERO) {
128812854Sgabeblack@google.com        div_by_zero(v.sgn); // case 1
128912854Sgabeblack@google.com        return sc_unsigned(); // case 2
129012854Sgabeblack@google.com
129112854Sgabeblack@google.com    }
129212854Sgabeblack@google.com
129312854Sgabeblack@google.com    CONVERT_LONG_2(u);
129412854Sgabeblack@google.com
129512854Sgabeblack@google.com    // other cases
129612854Sgabeblack@google.com    return div_unsigned_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
129712854Sgabeblack@google.com                               v.nbits, v.ndigits, v.digit);
129812854Sgabeblack@google.com}
129912854Sgabeblack@google.com
130012854Sgabeblack@google.com// The rest of the operators in this section are included from
130112854Sgabeblack@google.com// sc_nbcommon.cpp.
130212854Sgabeblack@google.com
130312854Sgabeblack@google.com
130412854Sgabeblack@google.com// ----------------------------------------------------------------------------
130512854Sgabeblack@google.com//  SECTION: MOD operators: %, %=.
130612854Sgabeblack@google.com// ----------------------------------------------------------------------------
130712854Sgabeblack@google.com
130812854Sgabeblack@google.com// Cases to consider when finding the remainder r = u % v:
130912854Sgabeblack@google.com// Note that u = q * v + r for r < q.
131012854Sgabeblack@google.com// 1. 0 % 0 or u % 0 => error
131112854Sgabeblack@google.com// 2. 0 % v => 0 = 0 * v + 0
131212854Sgabeblack@google.com// 3. u % v & &u = v => u = 1 * u + 0  - u or v can be 1 or -1
131312854Sgabeblack@google.com// 4. u % v & &u < v => u = 0 * v + u  - u can be 1 or -1
131412854Sgabeblack@google.com// 5. u % v & &u > v => u = q * v + r  - v can be 1 or -1
131512854Sgabeblack@google.com
131612854Sgabeblack@google.comsc_unsigned
131712854Sgabeblack@google.comoperator % (const sc_unsigned &u, const sc_unsigned &v)
131812854Sgabeblack@google.com{
131912854Sgabeblack@google.com    if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) {
132012854Sgabeblack@google.com        div_by_zero(v.sgn); // case 1
132112854Sgabeblack@google.com        return sc_unsigned(); // case 2
132212854Sgabeblack@google.com    }
132312854Sgabeblack@google.com
132412854Sgabeblack@google.com    // other cases
132512854Sgabeblack@google.com    return mod_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
132612854Sgabeblack@google.com                               v.nbits, v.ndigits, v.digit);
132712854Sgabeblack@google.com}
132812854Sgabeblack@google.com
132912854Sgabeblack@google.com
133012854Sgabeblack@google.comsc_unsigned
133112854Sgabeblack@google.comoperator % (const sc_unsigned &u, uint64 v)
133212854Sgabeblack@google.com{
133312854Sgabeblack@google.com    if ((u.sgn == SC_ZERO) || (v == 0)) {
133412854Sgabeblack@google.com        div_by_zero(v); // case 1
133512854Sgabeblack@google.com        return sc_unsigned(); // case 2
133612854Sgabeblack@google.com    }
133712854Sgabeblack@google.com
133812854Sgabeblack@google.com    CONVERT_INT64_2(v);
133912854Sgabeblack@google.com
134012854Sgabeblack@google.com    // other cases
134112854Sgabeblack@google.com    return mod_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
134212854Sgabeblack@google.com                               BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
134312854Sgabeblack@google.com
134412854Sgabeblack@google.com}
134512854Sgabeblack@google.com
134612854Sgabeblack@google.com
134712854Sgabeblack@google.comsc_unsigned
134812854Sgabeblack@google.comoperator % (uint64 u, const sc_unsigned &v)
134912854Sgabeblack@google.com{
135012854Sgabeblack@google.com    if ((u == 0) || (v.sgn == SC_ZERO)) {
135112854Sgabeblack@google.com        div_by_zero(v.sgn); // case 1
135212854Sgabeblack@google.com        return sc_unsigned(); // case 2
135312854Sgabeblack@google.com    }
135412854Sgabeblack@google.com
135512854Sgabeblack@google.com    CONVERT_INT64(u);
135612854Sgabeblack@google.com
135712854Sgabeblack@google.com    // other cases
135812854Sgabeblack@google.com    return mod_unsigned_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
135912854Sgabeblack@google.com                               v.nbits, v.ndigits, v.digit);
136012854Sgabeblack@google.com}
136112854Sgabeblack@google.com
136212854Sgabeblack@google.com
136312854Sgabeblack@google.comsc_unsigned
136412854Sgabeblack@google.comoperator % (const sc_unsigned &u, unsigned long v)
136512854Sgabeblack@google.com{
136612854Sgabeblack@google.com    if ((u.sgn == SC_ZERO) || (v == 0)) {
136712854Sgabeblack@google.com        div_by_zero(v); // case 1
136812854Sgabeblack@google.com        return sc_unsigned(); // case 2
136912854Sgabeblack@google.com    }
137012854Sgabeblack@google.com
137112854Sgabeblack@google.com    CONVERT_LONG_2(v);
137212854Sgabeblack@google.com
137312854Sgabeblack@google.com    // other cases
137412854Sgabeblack@google.com    return mod_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
137512854Sgabeblack@google.com                               BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
137612854Sgabeblack@google.com}
137712854Sgabeblack@google.com
137812854Sgabeblack@google.com
137912854Sgabeblack@google.comsc_unsigned
138012854Sgabeblack@google.comoperator % (unsigned long u, const sc_unsigned &v)
138112854Sgabeblack@google.com{
138212854Sgabeblack@google.com    if ((u == 0) || (v.sgn == SC_ZERO)) {
138312854Sgabeblack@google.com        div_by_zero(v.sgn); // case 1
138412854Sgabeblack@google.com        return sc_unsigned(); // case 2
138512854Sgabeblack@google.com    }
138612854Sgabeblack@google.com
138712854Sgabeblack@google.com    CONVERT_LONG(u);
138812854Sgabeblack@google.com
138912854Sgabeblack@google.com    // other cases
139012854Sgabeblack@google.com    return mod_unsigned_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
139112854Sgabeblack@google.com                               v.nbits, v.ndigits, v.digit);
139212854Sgabeblack@google.com}
139312854Sgabeblack@google.com
139412854Sgabeblack@google.com// The rest of the operators in this section are included from
139512854Sgabeblack@google.com// sc_nbcommon.cpp.
139612854Sgabeblack@google.com
139712854Sgabeblack@google.com
139812854Sgabeblack@google.com// ----------------------------------------------------------------------------
139912854Sgabeblack@google.com//  SECTION: Bitwise AND operators: &, &=
140012854Sgabeblack@google.com// ----------------------------------------------------------------------------
140112854Sgabeblack@google.com
140212854Sgabeblack@google.com// Cases to consider when computing u  &v:
140312854Sgabeblack@google.com// 1. u & 0 = 0  &v = 0
140412854Sgabeblack@google.com// 2. u  &v => sgn = +
140512854Sgabeblack@google.com// 3. (-u) & (-v) => sgn = -
140612854Sgabeblack@google.com// 4. u & (-v) => sgn = +
140712854Sgabeblack@google.com// 5. (-u)  &v => sgn = +
140812854Sgabeblack@google.com
140912854Sgabeblack@google.comsc_unsigned
141012854Sgabeblack@google.comoperator & (const sc_unsigned &u, const sc_unsigned &v)
141112854Sgabeblack@google.com{
141212854Sgabeblack@google.com    if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) // case 1
141312854Sgabeblack@google.com        return sc_unsigned();
141412854Sgabeblack@google.com
141512854Sgabeblack@google.com    // other cases
141612854Sgabeblack@google.com    return and_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
141712854Sgabeblack@google.com                               v.sgn, v.nbits, v.ndigits, v.digit);
141812854Sgabeblack@google.com}
141912854Sgabeblack@google.com
142012854Sgabeblack@google.com
142112854Sgabeblack@google.comsc_unsigned
142212854Sgabeblack@google.comoperator & (const sc_unsigned &u, uint64 v)
142312854Sgabeblack@google.com{
142412854Sgabeblack@google.com    if ((u.sgn == SC_ZERO) || (v == 0)) // case 1
142512854Sgabeblack@google.com        return sc_unsigned();
142612854Sgabeblack@google.com
142712854Sgabeblack@google.com    CONVERT_INT64(v);
142812854Sgabeblack@google.com
142912854Sgabeblack@google.com    // other cases
143012854Sgabeblack@google.com    return and_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
143112854Sgabeblack@google.com                               vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
143212854Sgabeblack@google.com}
143312854Sgabeblack@google.com
143412854Sgabeblack@google.com
143512854Sgabeblack@google.comsc_unsigned
143612854Sgabeblack@google.comoperator & (uint64 u, const sc_unsigned &v)
143712854Sgabeblack@google.com{
143812854Sgabeblack@google.com    if ((u == 0) || (v.sgn == SC_ZERO)) // case 1
143912854Sgabeblack@google.com        return sc_unsigned();
144012854Sgabeblack@google.com
144112854Sgabeblack@google.com    CONVERT_INT64(u);
144212854Sgabeblack@google.com
144312854Sgabeblack@google.com    // other cases
144412854Sgabeblack@google.com    return and_unsigned_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
144512854Sgabeblack@google.com                               v.sgn, v.nbits, v.ndigits, v.digit);
144612854Sgabeblack@google.com}
144712854Sgabeblack@google.com
144812854Sgabeblack@google.com
144912854Sgabeblack@google.comsc_unsigned
145012854Sgabeblack@google.comoperator & (const sc_unsigned &u, unsigned long v)
145112854Sgabeblack@google.com{
145212854Sgabeblack@google.com    if ((u.sgn == SC_ZERO) || (v == 0)) // case 1
145312854Sgabeblack@google.com        return sc_unsigned();
145412854Sgabeblack@google.com
145512854Sgabeblack@google.com    CONVERT_LONG(v);
145612854Sgabeblack@google.com
145712854Sgabeblack@google.com    // other cases
145812854Sgabeblack@google.com    return and_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
145912854Sgabeblack@google.com                               vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
146012854Sgabeblack@google.com}
146112854Sgabeblack@google.com
146212854Sgabeblack@google.com
146312854Sgabeblack@google.comsc_unsigned
146412854Sgabeblack@google.comoperator & (unsigned long u, const sc_unsigned &v)
146512854Sgabeblack@google.com{
146612854Sgabeblack@google.com    if ((u == 0) || (v.sgn == SC_ZERO)) // case 1
146712854Sgabeblack@google.com        return sc_unsigned();
146812854Sgabeblack@google.com
146912854Sgabeblack@google.com    CONVERT_LONG(u);
147012854Sgabeblack@google.com
147112854Sgabeblack@google.com    // other cases
147212854Sgabeblack@google.com    return and_unsigned_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
147312854Sgabeblack@google.com                               v.sgn, v.nbits, v.ndigits, v.digit);
147412854Sgabeblack@google.com}
147512854Sgabeblack@google.com
147612854Sgabeblack@google.com// The rest of the operators in this section are included from
147712854Sgabeblack@google.com// sc_nbcommon.cpp.
147812854Sgabeblack@google.com
147912854Sgabeblack@google.com
148012854Sgabeblack@google.com// ----------------------------------------------------------------------------
148112854Sgabeblack@google.com//  SECTION: Bitwise OR operators: |, |=
148212854Sgabeblack@google.com// ----------------------------------------------------------------------------
148312854Sgabeblack@google.com
148412854Sgabeblack@google.com// Cases to consider when computing u | v:
148512854Sgabeblack@google.com// 1. u | 0 = u
148612854Sgabeblack@google.com// 2. 0 | v = v
148712854Sgabeblack@google.com// 3. u | v => sgn = +
148812854Sgabeblack@google.com// 4. (-u) | (-v) => sgn = -
148912854Sgabeblack@google.com// 5. u | (-v) => sgn = -
149012854Sgabeblack@google.com// 6. (-u) | v => sgn = -
149112854Sgabeblack@google.com
149212854Sgabeblack@google.comsc_unsigned
149312854Sgabeblack@google.comoperator | (const sc_unsigned &u, const sc_unsigned &v)
149412854Sgabeblack@google.com{
149512854Sgabeblack@google.com    if (v.sgn == SC_ZERO) // case 1
149612854Sgabeblack@google.com        return sc_unsigned(u);
149712854Sgabeblack@google.com
149812854Sgabeblack@google.com    if (u.sgn == SC_ZERO) // case 2
149912854Sgabeblack@google.com        return sc_unsigned(v);
150012854Sgabeblack@google.com
150112854Sgabeblack@google.com    // other cases
150212854Sgabeblack@google.com    return or_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
150312854Sgabeblack@google.com                              v.sgn, v.nbits, v.ndigits, v.digit);
150412854Sgabeblack@google.com}
150512854Sgabeblack@google.com
150612854Sgabeblack@google.com
150712854Sgabeblack@google.comsc_unsigned
150812854Sgabeblack@google.comoperator | (const sc_unsigned &u, uint64 v)
150912854Sgabeblack@google.com{
151012854Sgabeblack@google.com    if (v == 0) // case 1
151112854Sgabeblack@google.com        return sc_unsigned(u);
151212854Sgabeblack@google.com
151312854Sgabeblack@google.com    CONVERT_INT64(v);
151412854Sgabeblack@google.com
151512854Sgabeblack@google.com    if (u.sgn == SC_ZERO) // case 2
151612854Sgabeblack@google.com        return sc_unsigned(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
151712854Sgabeblack@google.com
151812854Sgabeblack@google.com    // other cases
151912854Sgabeblack@google.com    return or_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
152012854Sgabeblack@google.com                              vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
152112854Sgabeblack@google.com}
152212854Sgabeblack@google.com
152312854Sgabeblack@google.com
152412854Sgabeblack@google.comsc_unsigned
152512854Sgabeblack@google.comoperator | (uint64 u, const sc_unsigned &v)
152612854Sgabeblack@google.com{
152712854Sgabeblack@google.com    if (u == 0)
152812854Sgabeblack@google.com        return sc_unsigned(v);
152912854Sgabeblack@google.com
153012854Sgabeblack@google.com    CONVERT_INT64(u);
153112854Sgabeblack@google.com
153212854Sgabeblack@google.com    if (v.sgn == SC_ZERO)
153312854Sgabeblack@google.com        return sc_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
153412854Sgabeblack@google.com
153512854Sgabeblack@google.com    // other cases
153612854Sgabeblack@google.com    return or_unsigned_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
153712854Sgabeblack@google.com                              v.sgn, v.nbits, v.ndigits, v.digit);
153812854Sgabeblack@google.com}
153912854Sgabeblack@google.com
154012854Sgabeblack@google.com
154112854Sgabeblack@google.comsc_unsigned
154212854Sgabeblack@google.comoperator | (const sc_unsigned &u, unsigned long v)
154312854Sgabeblack@google.com{
154412854Sgabeblack@google.com    if (v == 0) // case 1
154512854Sgabeblack@google.com        return sc_unsigned(u);
154612854Sgabeblack@google.com
154712854Sgabeblack@google.com    CONVERT_LONG(v);
154812854Sgabeblack@google.com
154912854Sgabeblack@google.com    if (u.sgn == SC_ZERO) // case 2
155012854Sgabeblack@google.com        return sc_unsigned(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
155112854Sgabeblack@google.com
155212854Sgabeblack@google.com    // other cases
155312854Sgabeblack@google.com    return or_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
155412854Sgabeblack@google.com                              vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
155512854Sgabeblack@google.com}
155612854Sgabeblack@google.com
155712854Sgabeblack@google.com
155812854Sgabeblack@google.comsc_unsigned
155912854Sgabeblack@google.comoperator | (unsigned long u, const sc_unsigned &v)
156012854Sgabeblack@google.com{
156112854Sgabeblack@google.com    if (u == 0)
156212854Sgabeblack@google.com        return sc_unsigned(v);
156312854Sgabeblack@google.com
156412854Sgabeblack@google.com    CONVERT_LONG(u);
156512854Sgabeblack@google.com
156612854Sgabeblack@google.com    if (v.sgn == SC_ZERO)
156712854Sgabeblack@google.com        return sc_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
156812854Sgabeblack@google.com
156912854Sgabeblack@google.com    // other cases
157012854Sgabeblack@google.com    return or_unsigned_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
157112854Sgabeblack@google.com                              v.sgn, v.nbits, v.ndigits, v.digit);
157212854Sgabeblack@google.com}
157312854Sgabeblack@google.com
157412854Sgabeblack@google.com// The rest of the operators in this section are included from
157512854Sgabeblack@google.com// sc_nbcommon.cpp.
157612854Sgabeblack@google.com
157712854Sgabeblack@google.com
157812854Sgabeblack@google.com// ----------------------------------------------------------------------------
157912854Sgabeblack@google.com//  SECTION: Bitwise XOR operators: ^, ^=
158012854Sgabeblack@google.com// ----------------------------------------------------------------------------
158112854Sgabeblack@google.com
158212854Sgabeblack@google.com// Cases to consider when computing u ^ v:
158312854Sgabeblack@google.com// Note that  u ^ v = (~u  &v) | (u & ~v).
158412854Sgabeblack@google.com// 1. u ^ 0 = u
158512854Sgabeblack@google.com// 2. 0 ^ v = v
158612854Sgabeblack@google.com// 3. u ^ v => sgn = +
158712854Sgabeblack@google.com// 4. (-u) ^ (-v) => sgn = -
158812854Sgabeblack@google.com// 5. u ^ (-v) => sgn = -
158912854Sgabeblack@google.com// 6. (-u) ^ v => sgn = +
159012854Sgabeblack@google.com
159112854Sgabeblack@google.comsc_unsigned
159212854Sgabeblack@google.comoperator ^ (const sc_unsigned &u, const sc_unsigned &v)
159312854Sgabeblack@google.com{
159412854Sgabeblack@google.com    if (v.sgn == SC_ZERO) // case 1
159512854Sgabeblack@google.com        return sc_unsigned(u);
159612854Sgabeblack@google.com
159712854Sgabeblack@google.com    if (u.sgn == SC_ZERO) // case 2
159812854Sgabeblack@google.com        return sc_unsigned(v);
159912854Sgabeblack@google.com
160012854Sgabeblack@google.com    // other cases
160112854Sgabeblack@google.com    return xor_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
160212854Sgabeblack@google.com                               v.sgn, v.nbits, v.ndigits, v.digit);
160312854Sgabeblack@google.com}
160412854Sgabeblack@google.com
160512854Sgabeblack@google.com
160612854Sgabeblack@google.comsc_unsigned
160712854Sgabeblack@google.comoperator ^ (const sc_unsigned &u, uint64 v)
160812854Sgabeblack@google.com{
160912854Sgabeblack@google.com    if (v == 0) // case 1
161012854Sgabeblack@google.com        return sc_unsigned(u);
161112854Sgabeblack@google.com
161212854Sgabeblack@google.com    CONVERT_INT64(v);
161312854Sgabeblack@google.com
161412854Sgabeblack@google.com    if (u.sgn == SC_ZERO) // case 2
161512854Sgabeblack@google.com        return sc_unsigned(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
161612854Sgabeblack@google.com
161712854Sgabeblack@google.com    // other cases
161812854Sgabeblack@google.com    return xor_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
161912854Sgabeblack@google.com                               vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
162012854Sgabeblack@google.com}
162112854Sgabeblack@google.com
162212854Sgabeblack@google.comsc_unsigned
162312854Sgabeblack@google.comoperator ^ (uint64 u, const sc_unsigned &v)
162412854Sgabeblack@google.com{
162512854Sgabeblack@google.com    if (u == 0)
162612854Sgabeblack@google.com        return sc_unsigned(v);
162712854Sgabeblack@google.com
162812854Sgabeblack@google.com    CONVERT_INT64(u);
162912854Sgabeblack@google.com
163012854Sgabeblack@google.com    if (v.sgn == SC_ZERO)
163112854Sgabeblack@google.com        return sc_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
163212854Sgabeblack@google.com
163312854Sgabeblack@google.com    // other cases
163412854Sgabeblack@google.com    return xor_unsigned_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
163512854Sgabeblack@google.com                               v.sgn, v.nbits, v.ndigits, v.digit);
163612854Sgabeblack@google.com}
163712854Sgabeblack@google.com
163812854Sgabeblack@google.com
163912854Sgabeblack@google.comsc_unsigned
164012854Sgabeblack@google.comoperator ^ (const sc_unsigned &u, unsigned long v)
164112854Sgabeblack@google.com{
164212854Sgabeblack@google.com    if (v == 0) // case 1
164312854Sgabeblack@google.com        return sc_unsigned(u);
164412854Sgabeblack@google.com
164512854Sgabeblack@google.com    CONVERT_LONG(v);
164612854Sgabeblack@google.com
164712854Sgabeblack@google.com    if (u.sgn == SC_ZERO) // case 2
164812854Sgabeblack@google.com        return sc_unsigned(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
164912854Sgabeblack@google.com
165012854Sgabeblack@google.com    // other cases
165112854Sgabeblack@google.com    return xor_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
165212854Sgabeblack@google.com                               vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
165312854Sgabeblack@google.com}
165412854Sgabeblack@google.com
165512854Sgabeblack@google.comsc_unsigned
165612854Sgabeblack@google.comoperator ^ (unsigned long u, const sc_unsigned &v)
165712854Sgabeblack@google.com{
165812854Sgabeblack@google.com    if (u == 0)
165912854Sgabeblack@google.com        return sc_unsigned(v);
166012854Sgabeblack@google.com
166112854Sgabeblack@google.com    CONVERT_LONG(u);
166212854Sgabeblack@google.com
166312854Sgabeblack@google.com    if (v.sgn == SC_ZERO)
166412854Sgabeblack@google.com        return sc_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
166512854Sgabeblack@google.com
166612854Sgabeblack@google.com    // other cases
166712854Sgabeblack@google.com    return xor_unsigned_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
166812854Sgabeblack@google.com                               v.sgn, v.nbits, v.ndigits, v.digit);
166912854Sgabeblack@google.com}
167012854Sgabeblack@google.com
167112854Sgabeblack@google.com// The rest of the operators in this section are included from
167212854Sgabeblack@google.com// sc_nbcommon.cpp.
167312854Sgabeblack@google.com
167412854Sgabeblack@google.com
167512854Sgabeblack@google.com// ----------------------------------------------------------------------------
167612854Sgabeblack@google.com//  SECTION: Bitwise NOT operator: ~
167712854Sgabeblack@google.com// ----------------------------------------------------------------------------
167812854Sgabeblack@google.com
167912854Sgabeblack@google.com// Operators in this section are included from sc_nbcommon.cpp.
168012854Sgabeblack@google.com
168112854Sgabeblack@google.com
168212854Sgabeblack@google.com// ----------------------------------------------------------------------------
168312854Sgabeblack@google.com//  SECTION: LEFT SHIFT operators: <<, <<=
168412854Sgabeblack@google.com// ----------------------------------------------------------------------------
168512854Sgabeblack@google.com
168612854Sgabeblack@google.comsc_unsigned
168712854Sgabeblack@google.comoperator << (const sc_unsigned &u, const sc_signed &v)
168812854Sgabeblack@google.com{
168912854Sgabeblack@google.com    if ((v.sgn == SC_ZERO) || (v.sgn == SC_NEG))
169012854Sgabeblack@google.com        return sc_unsigned(u);
169112854Sgabeblack@google.com
169212854Sgabeblack@google.com    return operator << (u, v.to_ulong());
169312854Sgabeblack@google.com}
169412854Sgabeblack@google.com
169512854Sgabeblack@google.com// The rest of the operators in this section are included from
169612854Sgabeblack@google.com// sc_nbcommon.cpp.
169712854Sgabeblack@google.com
169812854Sgabeblack@google.com
169912854Sgabeblack@google.com// ----------------------------------------------------------------------------
170012854Sgabeblack@google.com//    SECTION: RIGHT SHIFT operators: >>, >>=
170112854Sgabeblack@google.com// ----------------------------------------------------------------------------
170212854Sgabeblack@google.com
170312854Sgabeblack@google.comsc_unsigned
170412854Sgabeblack@google.comoperator >> (const sc_unsigned &u, const sc_signed &v)
170512854Sgabeblack@google.com{
170612854Sgabeblack@google.com
170712854Sgabeblack@google.com    if ((v.sgn == SC_ZERO) || (v.sgn == SC_NEG))
170812854Sgabeblack@google.com        return sc_unsigned(u);
170912854Sgabeblack@google.com
171012854Sgabeblack@google.com    return operator >> (u, v.to_long());
171112854Sgabeblack@google.com
171212854Sgabeblack@google.com}
171312854Sgabeblack@google.com
171412854Sgabeblack@google.com// The rest of the operators in this section are included from
171512854Sgabeblack@google.com// sc_nbcommon.cpp.
171612854Sgabeblack@google.com
171712854Sgabeblack@google.com
171812854Sgabeblack@google.com// ----------------------------------------------------------------------------
171912854Sgabeblack@google.com//    SECTION: Unary arithmetic operators.
172012854Sgabeblack@google.com// ----------------------------------------------------------------------------
172112854Sgabeblack@google.com
172212854Sgabeblack@google.comsc_unsigned
172312854Sgabeblack@google.comoperator + (const sc_unsigned &u)
172412854Sgabeblack@google.com{
172512854Sgabeblack@google.com    return sc_unsigned(u);
172612854Sgabeblack@google.com}
172712854Sgabeblack@google.com
172812854Sgabeblack@google.com
172912854Sgabeblack@google.com// ----------------------------------------------------------------------------
173012854Sgabeblack@google.com//    SECTION: EQUAL operator: ==
173112854Sgabeblack@google.com// ----------------------------------------------------------------------------
173212854Sgabeblack@google.com
173312854Sgabeblack@google.combool
173412854Sgabeblack@google.comoperator == (const sc_unsigned &u, const sc_unsigned &v)
173512854Sgabeblack@google.com{
173612854Sgabeblack@google.com    if (&u == &v)
173712854Sgabeblack@google.com        return true;
173812854Sgabeblack@google.com    if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
173912854Sgabeblack@google.com                         v.sgn, v.nbits, v.ndigits, v.digit) != 0) {
174012854Sgabeblack@google.com        return false;
174112854Sgabeblack@google.com    }
174212854Sgabeblack@google.com    return true;
174312854Sgabeblack@google.com}
174412854Sgabeblack@google.com
174512854Sgabeblack@google.com
174612854Sgabeblack@google.combool
174712854Sgabeblack@google.comoperator == (const sc_unsigned &u, const sc_signed &v)
174812854Sgabeblack@google.com{
174912854Sgabeblack@google.com    if (v.sgn == SC_NEG)
175012854Sgabeblack@google.com        return false;
175112854Sgabeblack@google.com    if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
175212854Sgabeblack@google.com                         v.sgn, v.nbits, v.ndigits, v.digit, 0, 1) != 0) {
175312854Sgabeblack@google.com        return false;
175412854Sgabeblack@google.com    }
175512854Sgabeblack@google.com    return true;
175612854Sgabeblack@google.com}
175712854Sgabeblack@google.com
175812854Sgabeblack@google.com
175912854Sgabeblack@google.combool
176012854Sgabeblack@google.comoperator == (const sc_signed &u, const sc_unsigned &v)
176112854Sgabeblack@google.com{
176212854Sgabeblack@google.com    if (u.sgn == SC_NEG)
176312854Sgabeblack@google.com        return false;
176412854Sgabeblack@google.com    if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
176512854Sgabeblack@google.com                         v.sgn, v.nbits, v.ndigits, v.digit, 1, 0) != 0) {
176612854Sgabeblack@google.com        return false;
176712854Sgabeblack@google.com    }
176812854Sgabeblack@google.com    return true;
176912854Sgabeblack@google.com}
177012854Sgabeblack@google.com
177112854Sgabeblack@google.com
177212854Sgabeblack@google.combool
177312854Sgabeblack@google.comoperator == (const sc_unsigned &u, int64 v)
177412854Sgabeblack@google.com{
177512854Sgabeblack@google.com    if (v < 0)
177612854Sgabeblack@google.com        return false;
177712854Sgabeblack@google.com    CONVERT_INT64(v);
177812854Sgabeblack@google.com    if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
177912854Sgabeblack@google.com                         vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd) != 0) {
178012854Sgabeblack@google.com        return false;
178112854Sgabeblack@google.com    }
178212854Sgabeblack@google.com    return true;
178312854Sgabeblack@google.com}
178412854Sgabeblack@google.com
178512854Sgabeblack@google.com
178612854Sgabeblack@google.combool
178712854Sgabeblack@google.comoperator == (int64 u, const sc_unsigned &v)
178812854Sgabeblack@google.com{
178912854Sgabeblack@google.com    if (u < 0)
179012854Sgabeblack@google.com        return false;
179112854Sgabeblack@google.com    CONVERT_INT64(u);
179212854Sgabeblack@google.com    if (compare_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
179312854Sgabeblack@google.com                         v.sgn, v.nbits, v.ndigits, v.digit) != 0) {
179412854Sgabeblack@google.com        return false;
179512854Sgabeblack@google.com    }
179612854Sgabeblack@google.com    return true;
179712854Sgabeblack@google.com}
179812854Sgabeblack@google.com
179912854Sgabeblack@google.com
180012854Sgabeblack@google.combool
180112854Sgabeblack@google.comoperator == (const sc_unsigned &u, uint64 v)
180212854Sgabeblack@google.com{
180312854Sgabeblack@google.com    CONVERT_INT64(v);
180412854Sgabeblack@google.com    if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
180512854Sgabeblack@google.com                         vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd) != 0)
180612854Sgabeblack@google.com        return false;
180712854Sgabeblack@google.com    return true;
180812854Sgabeblack@google.com}
180912854Sgabeblack@google.com
181012854Sgabeblack@google.com
181112854Sgabeblack@google.combool
181212854Sgabeblack@google.comoperator == (uint64 u, const sc_unsigned &v)
181312854Sgabeblack@google.com{
181412854Sgabeblack@google.com    CONVERT_INT64(u);
181512854Sgabeblack@google.com    if (compare_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
181612854Sgabeblack@google.com                         v.sgn, v.nbits, v.ndigits, v.digit) != 0)
181712854Sgabeblack@google.com        return false;
181812854Sgabeblack@google.com    return true;
181912854Sgabeblack@google.com}
182012854Sgabeblack@google.com
182112854Sgabeblack@google.com
182212854Sgabeblack@google.combool
182312854Sgabeblack@google.comoperator == (const sc_unsigned &u, long v)
182412854Sgabeblack@google.com{
182512854Sgabeblack@google.com    if (v < 0)
182612854Sgabeblack@google.com        return false;
182712854Sgabeblack@google.com    CONVERT_LONG(v);
182812854Sgabeblack@google.com    if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
182912854Sgabeblack@google.com                         vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd) != 0)
183012854Sgabeblack@google.com        return false;
183112854Sgabeblack@google.com    return true;
183212854Sgabeblack@google.com}
183312854Sgabeblack@google.com
183412854Sgabeblack@google.com
183512854Sgabeblack@google.combool
183612854Sgabeblack@google.comoperator == (long u, const sc_unsigned &v)
183712854Sgabeblack@google.com{
183812854Sgabeblack@google.com    if (u < 0)
183912854Sgabeblack@google.com        return false;
184012854Sgabeblack@google.com    CONVERT_LONG(u);
184112854Sgabeblack@google.com    if (compare_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
184212854Sgabeblack@google.com                         v.sgn, v.nbits, v.ndigits, v.digit) != 0)
184312854Sgabeblack@google.com        return false;
184412854Sgabeblack@google.com    return true;
184512854Sgabeblack@google.com}
184612854Sgabeblack@google.com
184712854Sgabeblack@google.com
184812854Sgabeblack@google.combool
184912854Sgabeblack@google.comoperator == (const sc_unsigned &u, unsigned long v)
185012854Sgabeblack@google.com{
185112854Sgabeblack@google.com    CONVERT_LONG(v);
185212854Sgabeblack@google.com    if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
185312854Sgabeblack@google.com                         vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd) != 0)
185412854Sgabeblack@google.com        return false;
185512854Sgabeblack@google.com    return true;
185612854Sgabeblack@google.com}
185712854Sgabeblack@google.com
185812854Sgabeblack@google.com
185912854Sgabeblack@google.combool
186012854Sgabeblack@google.comoperator == (unsigned long u, const sc_unsigned &v)
186112854Sgabeblack@google.com{
186212854Sgabeblack@google.com    CONVERT_LONG(u);
186312854Sgabeblack@google.com    if (compare_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
186412854Sgabeblack@google.com                         v.sgn, v.nbits, v.ndigits, v.digit) != 0)
186512854Sgabeblack@google.com        return false;
186612854Sgabeblack@google.com    return true;
186712854Sgabeblack@google.com}
186812854Sgabeblack@google.com
186912854Sgabeblack@google.com
187012854Sgabeblack@google.com// ----------------------------------------------------------------------------
187112854Sgabeblack@google.com//  SECTION: NOT_EQUAL operator: !=
187212854Sgabeblack@google.com// ----------------------------------------------------------------------------
187312854Sgabeblack@google.com
187412854Sgabeblack@google.combool
187512854Sgabeblack@google.comoperator != (const sc_unsigned &u, const sc_signed &v)
187612854Sgabeblack@google.com{
187712854Sgabeblack@google.com    return (!operator == (u, v));
187812854Sgabeblack@google.com}
187912854Sgabeblack@google.com
188012854Sgabeblack@google.com
188112854Sgabeblack@google.combool
188212854Sgabeblack@google.comoperator != (const sc_signed &u, const sc_unsigned &v)
188312854Sgabeblack@google.com{
188412854Sgabeblack@google.com    return (!operator == (u, v));
188512854Sgabeblack@google.com}
188612854Sgabeblack@google.com
188712854Sgabeblack@google.com// The rest of the operators in this section are included from sc_nbcommon.cpp.
188812854Sgabeblack@google.com
188912854Sgabeblack@google.com
189012854Sgabeblack@google.com// ----------------------------------------------------------------------------
189112854Sgabeblack@google.com//  SECTION: LESS THAN operator: <
189212854Sgabeblack@google.com// ----------------------------------------------------------------------------
189312854Sgabeblack@google.com
189412854Sgabeblack@google.combool
189512854Sgabeblack@google.comoperator < (const sc_unsigned &u, const sc_unsigned &v)
189612854Sgabeblack@google.com{
189712854Sgabeblack@google.com    if (&u == &v)
189812854Sgabeblack@google.com        return false;
189912854Sgabeblack@google.com    if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
190012854Sgabeblack@google.com                         v.sgn, v.nbits, v.ndigits, v.digit) < 0) {
190112854Sgabeblack@google.com        return true;
190212854Sgabeblack@google.com    }
190312854Sgabeblack@google.com    return false;
190412854Sgabeblack@google.com}
190512854Sgabeblack@google.com
190612854Sgabeblack@google.com
190712854Sgabeblack@google.combool
190812854Sgabeblack@google.comoperator < (const sc_unsigned &u, const sc_signed &v)
190912854Sgabeblack@google.com{
191012854Sgabeblack@google.com    if (v.sgn == SC_NEG)
191112854Sgabeblack@google.com        return false;
191212854Sgabeblack@google.com    if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
191312854Sgabeblack@google.com                         v.sgn, v.nbits, v.ndigits, v.digit, 0, 1) < 0) {
191412854Sgabeblack@google.com        return true;
191512854Sgabeblack@google.com    }
191612854Sgabeblack@google.com    return false;
191712854Sgabeblack@google.com}
191812854Sgabeblack@google.com
191912854Sgabeblack@google.com
192012854Sgabeblack@google.combool
192112854Sgabeblack@google.comoperator < (const sc_signed &u, const sc_unsigned &v)
192212854Sgabeblack@google.com{
192312854Sgabeblack@google.com    if (u.sgn == SC_NEG)
192412854Sgabeblack@google.com        return true;
192512854Sgabeblack@google.com    if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
192612854Sgabeblack@google.com                       v.sgn, v.nbits, v.ndigits, v.digit, 1, 0) < 0) {
192712854Sgabeblack@google.com        return true;
192812854Sgabeblack@google.com    }
192912854Sgabeblack@google.com    return false;
193012854Sgabeblack@google.com}
193112854Sgabeblack@google.com
193212854Sgabeblack@google.com
193312854Sgabeblack@google.combool
193412854Sgabeblack@google.comoperator < (const sc_unsigned &u, int64 v)
193512854Sgabeblack@google.com{
193612854Sgabeblack@google.com    if (v < 0)
193712854Sgabeblack@google.com        return false;
193812854Sgabeblack@google.com    CONVERT_INT64(v);
193912854Sgabeblack@google.com    if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
194012854Sgabeblack@google.com                         vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd) < 0) {
194112854Sgabeblack@google.com        return true;
194212854Sgabeblack@google.com    }
194312854Sgabeblack@google.com    return false;
194412854Sgabeblack@google.com}
194512854Sgabeblack@google.com
194612854Sgabeblack@google.com
194712854Sgabeblack@google.combool
194812854Sgabeblack@google.comoperator < (int64 u, const sc_unsigned &v)
194912854Sgabeblack@google.com{
195012854Sgabeblack@google.com    if (u < 0)
195112854Sgabeblack@google.com        return true;
195212854Sgabeblack@google.com    CONVERT_INT64(u);
195312854Sgabeblack@google.com    if (compare_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
195412854Sgabeblack@google.com                         v.sgn, v.nbits, v.ndigits, v.digit) < 0) {
195512854Sgabeblack@google.com        return true;
195612854Sgabeblack@google.com    }
195712854Sgabeblack@google.com    return false;
195812854Sgabeblack@google.com}
195912854Sgabeblack@google.com
196012854Sgabeblack@google.com
196112854Sgabeblack@google.combool
196212854Sgabeblack@google.comoperator < (const sc_unsigned &u, uint64 v)
196312854Sgabeblack@google.com{
196412854Sgabeblack@google.com    CONVERT_INT64(v);
196512854Sgabeblack@google.com    if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
196612854Sgabeblack@google.com                         vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd) < 0) {
196712854Sgabeblack@google.com        return true;
196812854Sgabeblack@google.com    }
196912854Sgabeblack@google.com    return false;
197012854Sgabeblack@google.com}
197112854Sgabeblack@google.com
197212854Sgabeblack@google.com
197312854Sgabeblack@google.combool
197412854Sgabeblack@google.comoperator < (uint64 u, const sc_unsigned &v)
197512854Sgabeblack@google.com{
197612854Sgabeblack@google.com    CONVERT_INT64(u);
197712854Sgabeblack@google.com    if (compare_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
197812854Sgabeblack@google.com                         v.sgn, v.nbits, v.ndigits, v.digit) < 0){
197912854Sgabeblack@google.com        return true;
198012854Sgabeblack@google.com    }
198112854Sgabeblack@google.com    return false;
198212854Sgabeblack@google.com}
198312854Sgabeblack@google.com
198412854Sgabeblack@google.com
198512854Sgabeblack@google.combool
198612854Sgabeblack@google.comoperator < (const sc_unsigned &u, long v)
198712854Sgabeblack@google.com{
198812854Sgabeblack@google.com    if (v < 0)
198912854Sgabeblack@google.com        return false;
199012854Sgabeblack@google.com    CONVERT_LONG(v);
199112854Sgabeblack@google.com    if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
199212854Sgabeblack@google.com                         vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd) < 0) {
199312854Sgabeblack@google.com        return true;
199412854Sgabeblack@google.com    }
199512854Sgabeblack@google.com    return false;
199612854Sgabeblack@google.com}
199712854Sgabeblack@google.com
199812854Sgabeblack@google.com
199912854Sgabeblack@google.combool
200012854Sgabeblack@google.comoperator < (long u, const sc_unsigned &v)
200112854Sgabeblack@google.com{
200212854Sgabeblack@google.com    if (u < 0)
200312854Sgabeblack@google.com        return true;
200412854Sgabeblack@google.com    CONVERT_LONG(u);
200512854Sgabeblack@google.com    if (compare_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
200612854Sgabeblack@google.com                         v.sgn, v.nbits, v.ndigits, v.digit) < 0) {
200712854Sgabeblack@google.com        return true;
200812854Sgabeblack@google.com    }
200912854Sgabeblack@google.com    return false;
201012854Sgabeblack@google.com}
201112854Sgabeblack@google.com
201212854Sgabeblack@google.com
201312854Sgabeblack@google.combool
201412854Sgabeblack@google.comoperator < (const sc_unsigned &u, unsigned long v)
201512854Sgabeblack@google.com{
201612854Sgabeblack@google.com    CONVERT_LONG(v);
201712854Sgabeblack@google.com    if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
201812854Sgabeblack@google.com                         vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd) < 0) {
201912854Sgabeblack@google.com        return true;
202012854Sgabeblack@google.com    }
202112854Sgabeblack@google.com    return false;
202212854Sgabeblack@google.com}
202312854Sgabeblack@google.com
202412854Sgabeblack@google.com
202512854Sgabeblack@google.combool
202612854Sgabeblack@google.comoperator < (unsigned long u, const sc_unsigned &v)
202712854Sgabeblack@google.com{
202812854Sgabeblack@google.com    CONVERT_LONG(u);
202912854Sgabeblack@google.com    if (compare_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
203012854Sgabeblack@google.com                         v.sgn, v.nbits, v.ndigits, v.digit) < 0) {
203112854Sgabeblack@google.com        return true;
203212854Sgabeblack@google.com    }
203312854Sgabeblack@google.com    return false;
203412854Sgabeblack@google.com}
203512854Sgabeblack@google.com
203612854Sgabeblack@google.com
203712854Sgabeblack@google.com// ----------------------------------------------------------------------------
203812854Sgabeblack@google.com//  SECTION: LESS THAN or EQUAL operator: <=
203912854Sgabeblack@google.com// ----------------------------------------------------------------------------
204012854Sgabeblack@google.com
204112854Sgabeblack@google.combool
204212854Sgabeblack@google.comoperator <= (const sc_unsigned &u, const sc_signed &v)
204312854Sgabeblack@google.com{
204412854Sgabeblack@google.com    return (operator < (u, v) || operator == (u, v));
204512854Sgabeblack@google.com}
204612854Sgabeblack@google.com
204712854Sgabeblack@google.com
204812854Sgabeblack@google.combool
204912854Sgabeblack@google.comoperator <= (const sc_signed &u, const sc_unsigned &v)
205012854Sgabeblack@google.com{
205112854Sgabeblack@google.com    return (operator < (u, v) || operator == (u, v));
205212854Sgabeblack@google.com}
205312854Sgabeblack@google.com
205412854Sgabeblack@google.com// The rest of the operators in this section are included from sc_nbcommon.cpp.
205512854Sgabeblack@google.com
205612854Sgabeblack@google.com
205712854Sgabeblack@google.com// ----------------------------------------------------------------------------
205812854Sgabeblack@google.com//  SECTION: GREATER THAN operator: >
205912854Sgabeblack@google.com// ----------------------------------------------------------------------------
206012854Sgabeblack@google.com
206112854Sgabeblack@google.combool
206212854Sgabeblack@google.comoperator > (const sc_unsigned &u, const sc_signed &v)
206312854Sgabeblack@google.com{
206412854Sgabeblack@google.com  return (!(operator <= (u, v)));
206512854Sgabeblack@google.com}
206612854Sgabeblack@google.com
206712854Sgabeblack@google.com
206812854Sgabeblack@google.combool
206912854Sgabeblack@google.comoperator > (const sc_signed &u, const sc_unsigned &v)
207012854Sgabeblack@google.com{
207112854Sgabeblack@google.com  return (!(operator <= (u, v)));
207212854Sgabeblack@google.com}
207312854Sgabeblack@google.com
207412854Sgabeblack@google.com// The rest of the operators in this section are included from sc_nbcommon.cpp.
207512854Sgabeblack@google.com
207612854Sgabeblack@google.com
207712854Sgabeblack@google.com// ----------------------------------------------------------------------------
207812854Sgabeblack@google.com//  SECTION: GREATER THAN or EQUAL operator: >=
207912854Sgabeblack@google.com// ----------------------------------------------------------------------------
208012854Sgabeblack@google.com
208112854Sgabeblack@google.combool
208212854Sgabeblack@google.comoperator >= (const sc_unsigned &u, const sc_signed &v)
208312854Sgabeblack@google.com{
208412854Sgabeblack@google.com  return (!(operator < (u, v)));
208512854Sgabeblack@google.com}
208612854Sgabeblack@google.com
208712854Sgabeblack@google.com
208812854Sgabeblack@google.combool
208912854Sgabeblack@google.comoperator >= (const sc_signed &u, const sc_unsigned &v)
209012854Sgabeblack@google.com{
209112854Sgabeblack@google.com  return (!(operator < (u, v)));
209212854Sgabeblack@google.com}
209312854Sgabeblack@google.com
209412854Sgabeblack@google.com// The rest of the operators in this section are included from sc_nbcommon.cpp.
209512854Sgabeblack@google.com
209612854Sgabeblack@google.com
209712854Sgabeblack@google.com// ----------------------------------------------------------------------------
209812854Sgabeblack@google.com//  SECTION: Friends
209912854Sgabeblack@google.com// ----------------------------------------------------------------------------
210012854Sgabeblack@google.com
210112854Sgabeblack@google.com// Compare u and v as unsigned and return r
210212854Sgabeblack@google.com//  r = 0 if u == v
210312854Sgabeblack@google.com//  r < 0 if u < v
210412854Sgabeblack@google.com//  r > 0 if u > v
210512854Sgabeblack@google.com
210612854Sgabeblack@google.comint
210712854Sgabeblack@google.comcompare_unsigned(small_type us, int unb, int und, const sc_digit *ud,
210812854Sgabeblack@google.com                 small_type vs, int vnb, int vnd, const sc_digit *vd,
210912854Sgabeblack@google.com                 small_type if_u_signed, small_type if_v_signed)
211012854Sgabeblack@google.com{
211112854Sgabeblack@google.com    if (us == vs) {
211212854Sgabeblack@google.com        if (us == SC_ZERO) {
211312854Sgabeblack@google.com            return 0;
211412854Sgabeblack@google.com        } else {
211512854Sgabeblack@google.com            int cmp_res = vec_skip_and_cmp(und, ud, vnd, vd);
211612854Sgabeblack@google.com            if (us == SC_POS)
211712854Sgabeblack@google.com                return cmp_res;
211812854Sgabeblack@google.com            else
211912854Sgabeblack@google.com                return -cmp_res;
212012854Sgabeblack@google.com        }
212112854Sgabeblack@google.com    } else {
212212854Sgabeblack@google.com        if (us == SC_ZERO)
212312854Sgabeblack@google.com            return -vs;
212412854Sgabeblack@google.com        if (vs == SC_ZERO)
212512854Sgabeblack@google.com            return us;
212612854Sgabeblack@google.com
212712854Sgabeblack@google.com        int cmp_res;
212812854Sgabeblack@google.com        int nd = (us == SC_NEG ? und : vnd);
212912854Sgabeblack@google.com
213012854Sgabeblack@google.com#ifdef SC_MAX_NBITS
213112854Sgabeblack@google.com        sc_digit d[MAX_NDIGITS];
213212854Sgabeblack@google.com#else
213312854Sgabeblack@google.com        sc_digit *d = new sc_digit[nd];
213412854Sgabeblack@google.com#endif
213512854Sgabeblack@google.com
213612854Sgabeblack@google.com        if (us == SC_NEG) {
213712854Sgabeblack@google.com            vec_copy(nd, d, ud);
213812854Sgabeblack@google.com            vec_complement(nd, d);
213912854Sgabeblack@google.com            trim(if_u_signed, unb, nd, d);
214012854Sgabeblack@google.com            cmp_res = vec_skip_and_cmp(nd, d, vnd, vd);
214112854Sgabeblack@google.com        } else {
214212854Sgabeblack@google.com            vec_copy(nd, d, vd);
214312854Sgabeblack@google.com            vec_complement(nd, d);
214412854Sgabeblack@google.com            trim(if_v_signed, vnb, nd, d);
214512854Sgabeblack@google.com            cmp_res = vec_skip_and_cmp(und, ud, nd, d);
214612854Sgabeblack@google.com        }
214712854Sgabeblack@google.com
214812854Sgabeblack@google.com#ifndef SC_MAX_NBITS
214912854Sgabeblack@google.com        delete [] d;
215012854Sgabeblack@google.com#endif
215112854Sgabeblack@google.com
215212854Sgabeblack@google.com        return cmp_res;
215312854Sgabeblack@google.com    }
215412854Sgabeblack@google.com}
215512854Sgabeblack@google.com
215612854Sgabeblack@google.com
215712854Sgabeblack@google.com// ----------------------------------------------------------------------------
215812854Sgabeblack@google.com//  SECTION: Public members - Other utils.
215912854Sgabeblack@google.com// ----------------------------------------------------------------------------
216012854Sgabeblack@google.com
216112854Sgabeblack@google.combool
216212854Sgabeblack@google.comsc_unsigned::iszero() const
216312854Sgabeblack@google.com{
216412854Sgabeblack@google.com    if (sgn == SC_ZERO) {
216512854Sgabeblack@google.com        return true;
216612854Sgabeblack@google.com    } else if (sgn == SC_NEG) {
216712854Sgabeblack@google.com        // A negative unsigned number can be zero, e.g., -16 in 4 bits, so
216812854Sgabeblack@google.com        // check that.
216912854Sgabeblack@google.com
217012854Sgabeblack@google.com#ifdef SC_MAX_NBITS
217112854Sgabeblack@google.com        sc_digit d[MAX_NDIGITS];
217212854Sgabeblack@google.com#else
217312854Sgabeblack@google.com        sc_digit *d = new sc_digit[ndigits];
217412854Sgabeblack@google.com#endif
217512854Sgabeblack@google.com
217612854Sgabeblack@google.com        vec_copy(ndigits, d, digit);
217712854Sgabeblack@google.com        vec_complement(ndigits, d);
217812854Sgabeblack@google.com        trim_unsigned(nbits, ndigits, d);
217912854Sgabeblack@google.com
218012854Sgabeblack@google.com        bool res = check_for_zero(ndigits, d);
218112854Sgabeblack@google.com
218212854Sgabeblack@google.com#ifndef SC_MAX_NBITS
218312854Sgabeblack@google.com        delete [] d;
218412854Sgabeblack@google.com#endif
218512854Sgabeblack@google.com
218612854Sgabeblack@google.com        return res;
218712854Sgabeblack@google.com    } else {
218812854Sgabeblack@google.com        return false;
218912854Sgabeblack@google.com    }
219012854Sgabeblack@google.com}
219112854Sgabeblack@google.com
219212854Sgabeblack@google.com// The rest of the utils in this section are included from sc_nbcommon.cpp.
219312854Sgabeblack@google.com
219412854Sgabeblack@google.com
219512854Sgabeblack@google.com// ----------------------------------------------------------------------------
219612854Sgabeblack@google.com//  SECTION: Private members.
219712854Sgabeblack@google.com// ----------------------------------------------------------------------------
219812854Sgabeblack@google.com
219912854Sgabeblack@google.com// The private members in this section are included from
220012854Sgabeblack@google.com// sc_nbcommon.cpp.
220112854Sgabeblack@google.com
220212854Sgabeblack@google.com#define CLASS_TYPE sc_unsigned
220312854Sgabeblack@google.com#define CLASS_TYPE_STR "sc_unsigned"
220412854Sgabeblack@google.com
220512854Sgabeblack@google.com#define ADD_HELPER add_unsigned_friend
220612854Sgabeblack@google.com#define SUB_HELPER sub_unsigned_friend
220712854Sgabeblack@google.com#define MUL_HELPER mul_unsigned_friend
220812854Sgabeblack@google.com#define DIV_HELPER div_unsigned_friend
220912854Sgabeblack@google.com#define MOD_HELPER mod_unsigned_friend
221012854Sgabeblack@google.com#define AND_HELPER and_unsigned_friend
221112854Sgabeblack@google.com#define OR_HELPER or_unsigned_friend
221212854Sgabeblack@google.com#define XOR_HELPER xor_unsigned_friend
221312854Sgabeblack@google.com
221412854Sgabeblack@google.com#include "sc_nbfriends.inc"
221512854Sgabeblack@google.com
221612854Sgabeblack@google.com#undef SC_SIGNED
221712854Sgabeblack@google.com#define SC_UNSIGNED
221812854Sgabeblack@google.com#define IF_SC_SIGNED 0 // 0 = sc_unsigned
221912854Sgabeblack@google.com#define CLASS_TYPE_SUBREF sc_unsigned_subref_r
222012854Sgabeblack@google.com#define OTHER_CLASS_TYPE sc_signed
222112854Sgabeblack@google.com#define OTHER_CLASS_TYPE_SUBREF sc_signed_subref_r
222212854Sgabeblack@google.com
222312854Sgabeblack@google.com#define MUL_ON_HELPER mul_on_help_unsigned
222412854Sgabeblack@google.com#define DIV_ON_HELPER div_on_help_unsigned
222512854Sgabeblack@google.com#define MOD_ON_HELPER mod_on_help_unsigned
222612854Sgabeblack@google.com
222712854Sgabeblack@google.com#include "sc_nbcommon.inc"
222812854Sgabeblack@google.com
222912854Sgabeblack@google.com#undef MOD_ON_HELPER
223012854Sgabeblack@google.com#undef DIV_ON_HELPER
223112854Sgabeblack@google.com#undef MUL_ON_HELPER
223212854Sgabeblack@google.com
223312854Sgabeblack@google.com#undef OTHER_CLASS_TYPE_SUBREF
223412854Sgabeblack@google.com#undef OTHER_CLASS_TYPE
223512854Sgabeblack@google.com#undef CLASS_TYPE_SUBREF
223612854Sgabeblack@google.com#undef IF_SC_SIGNED
223712854Sgabeblack@google.com#undef SC_UNSIGNED
223812854Sgabeblack@google.com
223912854Sgabeblack@google.com#undef XOR_HELPER
224012854Sgabeblack@google.com#undef OR_HELPER
224112854Sgabeblack@google.com#undef AND_HELPER
224212854Sgabeblack@google.com#undef MOD_HELPER
224312854Sgabeblack@google.com#undef DIV_HELPER
224412854Sgabeblack@google.com#undef MUL_HELPER
224512854Sgabeblack@google.com#undef SUB_HELPER
224612854Sgabeblack@google.com#undef ADD_HELPER
224712854Sgabeblack@google.com
224812854Sgabeblack@google.com#undef CLASS_TYPE
224912854Sgabeblack@google.com#undef CLASS_TYPE_STR
225012854Sgabeblack@google.com
225112854Sgabeblack@google.com#include "sc_unsigned_bitref.inc"
225212854Sgabeblack@google.com#include "sc_unsigned_subref.inc"
225312854Sgabeblack@google.com
225412854Sgabeblack@google.com#undef CONVERT_LONG
225512854Sgabeblack@google.com#undef CONVERT_LONG_2
225612854Sgabeblack@google.com#undef CONVERT_INT64
225712854Sgabeblack@google.com#undef CONVERT_INT64_2
225812854Sgabeblack@google.com
225912854Sgabeblack@google.com} // namespace sc_dt
2260