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