sc_signed.cc revision 13322
12SN/A/*****************************************************************************
213107Sgiacomo.travaglini@arm.com
310905Sandreas.sandberg@arm.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
410905Sandreas.sandberg@arm.com  more contributor license agreements.  See the NOTICE file distributed
510905Sandreas.sandberg@arm.com  with this work for additional information regarding copyright ownership.
610905Sandreas.sandberg@arm.com  Accellera licenses this file to you under the Apache License, Version 2.0
710905Sandreas.sandberg@arm.com  (the "License"); you may not use this file except in compliance with the
810905Sandreas.sandberg@arm.com  License.  You may obtain a copy of the License at
910905Sandreas.sandberg@arm.com
1010905Sandreas.sandberg@arm.com    http://www.apache.org/licenses/LICENSE-2.0
1110905Sandreas.sandberg@arm.com
1210905Sandreas.sandberg@arm.com  Unless required by applicable law or agreed to in writing, software
1310905Sandreas.sandberg@arm.com  distributed under the License is distributed on an "AS IS" BASIS,
141762SN/A  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
152SN/A  implied.  See the License for the specific language governing
162SN/A  permissions and limitations under the License.
172SN/A
182SN/A *****************************************************************************/
192SN/A
202SN/A/*****************************************************************************
212SN/A
222SN/A  sc_signed.cpp -- Arbitrary precision signed arithmetic.
232SN/A
242SN/A                   This file includes the definitions of sc_signed_bitref,
252SN/A                   sc_signed_subref, and sc_signed classes. The first two
262SN/A                   classes are proxy classes to reference one bit and a range
272SN/A                   of bits of a sc_signed number, respectively. This file also
282SN/A                   includes sc_nbcommon.cpp and sc_nbfriends.cpp, which
292SN/A                   contain the definitions shared by sc_unsigned.
302SN/A
312SN/A  Original Author: Ali Dasdan, Synopsys, Inc.
322SN/A
332SN/A *****************************************************************************/
342SN/A
352SN/A/*****************************************************************************
362SN/A
372SN/A  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
382SN/A  changes you are making here.
392665Ssaidi@eecs.umich.edu
402760Sbinkertn@umich.edu      Name, Affiliation, Date:
412760Sbinkertn@umich.edu  Description of Modification:
422665Ssaidi@eecs.umich.edu
4310905Sandreas.sandberg@arm.com *****************************************************************************/
442SN/A
452SN/A
462SN/A// $Log: sc_signed.cpp,v $
472SN/A// Revision 1.6  2011/02/18 20:19:15  acg
482SN/A//  Andy Goodrich: updating Copyright notice.
492SN/A//
502SN/A// Revision 1.5  2008/12/10 20:38:45  acg
512SN/A//  Andy Goodrich: fixed conversion of double values to the digits vector.
522SN/A//  The bits above the radix were not being masked off.
532SN/A//
5413107Sgiacomo.travaglini@arm.com// Revision 1.4  2008/06/19 17:47:56  acg
558229Snate@binkert.org//  Andy Goodrich: fixes for bugs. See 2.2.1 RELEASENOTES.
562SN/A//
578229Snate@binkert.org// Revision 1.3  2008/04/29 21:20:41  acg
5810905Sandreas.sandberg@arm.com//  Andy Goodrich: added mask to first word transferred when processing
5911076SCurtis.Dunham@arm.com//  a negative sc_signed value in sc_signed::concat_get_data().
604841Ssaidi@eecs.umich.edu//
612SN/A// Revision 1.2  2007/11/04 21:27:00  acg
6210459SAndreas.Sandberg@ARM.com//  Andy Goodrich: changes to make sure the proper value is returned from
6313414Sgiacomo.travaglini@arm.com//  concat_get_data().
6413414Sgiacomo.travaglini@arm.com//
652SN/A// Revision 1.1.1.1  2006/12/15 20:20:05  acg
662738Sstever@eecs.umich.edu// SystemC 2.3
674000Ssaidi@eecs.umich.edu//
6811067Sandreas.sandberg@arm.com// Revision 1.5  2006/10/23 19:32:47  acg
692SN/A//  Andy Goodrich: further fix for incorrect value being returned from
7010905Sandreas.sandberg@arm.com//  concat_get_data. This one is in the non-aligned value code.
7110905Sandreas.sandberg@arm.com//
7213414Sgiacomo.travaglini@arm.com// Revision 1.3  2006/01/13 18:49:32  acg
7313414Sgiacomo.travaglini@arm.com// Added $Log command so that CVS check in comments are reproduced in the
7413414Sgiacomo.travaglini@arm.com// source.
7510905Sandreas.sandberg@arm.com//
7613414Sgiacomo.travaglini@arm.com
77217SN/A#include <cctype>
7813414Sgiacomo.travaglini@arm.com#include <cmath>
7910459SAndreas.Sandberg@ARM.com#include <sstream>
8013414Sgiacomo.travaglini@arm.com
8113414Sgiacomo.travaglini@arm.com#include "systemc/ext/dt/bit/sc_bv_base.hh"
8213414Sgiacomo.travaglini@arm.com#include "systemc/ext/dt/bit/sc_lv_base.hh"
83217SN/A#include "systemc/ext/dt/fx/sc_fix.hh"
8413414Sgiacomo.travaglini@arm.com#include "systemc/ext/dt/fx/scfx_other_defs.hh"
8510459SAndreas.Sandberg@ARM.com#include "systemc/ext/dt/int/sc_int_base.hh"
8613414Sgiacomo.travaglini@arm.com#include "systemc/ext/dt/int/sc_signed.hh"
8713414Sgiacomo.travaglini@arm.com#include "systemc/ext/dt/int/sc_uint_base.hh"
886820SLisa.Hsu@amd.com#include "systemc/ext/dt/int/sc_unsigned.hh"
8913414Sgiacomo.travaglini@arm.com#include "systemc/ext/dt/misc/sc_concatref.hh"
9013414Sgiacomo.travaglini@arm.com
9110459SAndreas.Sandberg@ARM.com// explicit template instantiations
92217SN/Anamespace sc_core
9313414Sgiacomo.travaglini@arm.com{
9413414Sgiacomo.travaglini@arm.com
954841Ssaidi@eecs.umich.edutemplate class sc_vpool<sc_dt::sc_signed_bitref>;
9613414Sgiacomo.travaglini@arm.comtemplate class sc_vpool<sc_dt::sc_signed_subref>;
9713414Sgiacomo.travaglini@arm.com
9813414Sgiacomo.travaglini@arm.com} // namespace sc_core
9913414Sgiacomo.travaglini@arm.com
10013414Sgiacomo.travaglini@arm.comnamespace sc_dt
10113414Sgiacomo.travaglini@arm.com{
1027948SAli.Saidi@ARM.com
10313414Sgiacomo.travaglini@arm.com// Pool of temporary instances:
10413414Sgiacomo.travaglini@arm.com
10513414Sgiacomo.travaglini@arm.comsc_core::sc_vpool<sc_signed_bitref> sc_signed_bitref::m_pool(9);
10611076SCurtis.Dunham@arm.comsc_core::sc_vpool<sc_signed_subref> sc_signed_subref::m_pool(9);
10713414Sgiacomo.travaglini@arm.com
10813414Sgiacomo.travaglini@arm.comvoid
10913414Sgiacomo.travaglini@arm.comsc_signed::invalid_init(const char *type_name, int nb) const
11013414Sgiacomo.travaglini@arm.com{
11113414Sgiacomo.travaglini@arm.com    std::stringstream msg;
112217SN/A    msg << "sc_signed("<< type_name << ") : nb = " << nb << " is not valid";
11313414Sgiacomo.travaglini@arm.com    SC_REPORT_ERROR("initialization failed", msg.str().c_str());
11413414Sgiacomo.travaglini@arm.com}
11513414Sgiacomo.travaglini@arm.com
11613414Sgiacomo.travaglini@arm.com// ----------------------------------------------------------------------------
11713414Sgiacomo.travaglini@arm.com// SECTION: Public members - Invalid selections.
1184841Ssaidi@eecs.umich.edu// ----------------------------------------------------------------------------
11913414Sgiacomo.travaglini@arm.com
12013414Sgiacomo.travaglini@arm.comvoid
12113414Sgiacomo.travaglini@arm.comsc_signed::invalid_index(int i) const
122217SN/A{
1239342SAndreas.Sandberg@arm.com    std::stringstream msg;
1242SN/A    msg << "sc_bigint bit selection: index = " << i << " violates "
1259342SAndreas.Sandberg@arm.com           "0 <= index <= " << (nbits - 1);
12610905Sandreas.sandberg@arm.com    SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, msg.str().c_str());
12710905Sandreas.sandberg@arm.com    sc_core::sc_abort(); // can't recover from here
12810905Sandreas.sandberg@arm.com}
12910905Sandreas.sandberg@arm.com
13010905Sandreas.sandberg@arm.comvoid
13110905Sandreas.sandberg@arm.comsc_signed::invalid_range(int l, int r) const
13210905Sandreas.sandberg@arm.com{
13310905Sandreas.sandberg@arm.com    std::stringstream msg;
13410905Sandreas.sandberg@arm.com    msg << "sc_bigint part selection: left = " <<
13510905Sandreas.sandberg@arm.com           l << ", right = " << r << " \n"
13610905Sandreas.sandberg@arm.com           "  violates either (" << (nbits-1) << " >= left >= 0) or "
13710905Sandreas.sandberg@arm.com           "(" << (nbits-1) << " >= right >= 0)";
13810905Sandreas.sandberg@arm.com    SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, msg.str().c_str());
13910905Sandreas.sandberg@arm.com    sc_core::sc_abort(); // can't recover from here
14010905Sandreas.sandberg@arm.com}
14110905Sandreas.sandberg@arm.com
14210905Sandreas.sandberg@arm.com
14310905Sandreas.sandberg@arm.com// ----------------------------------------------------------------------------
14410905Sandreas.sandberg@arm.com
14510905Sandreas.sandberg@arm.com// ----------------------------------------------------------------------------
14610905Sandreas.sandberg@arm.com//  SECTION: Public members.
1479342SAndreas.Sandberg@arm.com// ----------------------------------------------------------------------------
1489342SAndreas.Sandberg@arm.com
1499342SAndreas.Sandberg@arm.com// Most public members are included from sc_nbcommon.inc. However, some
1509342SAndreas.Sandberg@arm.com// concatenation support appears here to optimize between the signed and
1519342SAndreas.Sandberg@arm.com// unsigned cases.
1522SN/A
153395SN/A// Insert this object's value at the specified place in a vector of biguint
1542SN/A// style values.
1552SN/A
15610905Sandreas.sandberg@arm.combool
15710905Sandreas.sandberg@arm.comsc_signed::concat_get_ctrl(sc_digit *dst_p, int low_i) const
15810905Sandreas.sandberg@arm.com{
15910905Sandreas.sandberg@arm.com    int dst_i; // Index to next word to set in dst_p.
16010905Sandreas.sandberg@arm.com    int end_i; // Index of high order word to set.
16110905Sandreas.sandberg@arm.com    int left_shift; // Amount to shift value left.
16210905Sandreas.sandberg@arm.com    sc_digit mask; // Mask for partial word sets.
16310905Sandreas.sandberg@arm.com
16410905Sandreas.sandberg@arm.com    // CALCULATE METRICS FOR DATA MOVEMENT:
16510905Sandreas.sandberg@arm.com    dst_i = low_i / BITS_PER_DIGIT;
16610905Sandreas.sandberg@arm.com    end_i = (low_i + nbits - 1) / BITS_PER_DIGIT;
16710905Sandreas.sandberg@arm.com    left_shift = low_i % BITS_PER_DIGIT;
16810905Sandreas.sandberg@arm.com
16910905Sandreas.sandberg@arm.com    // ALL DATA TO BE MOVED IS IN A SINGLE WORD:
17010905Sandreas.sandberg@arm.com    mask = ~(~0U << left_shift);
17110905Sandreas.sandberg@arm.com    dst_p[dst_i] = (dst_p[dst_i] & ~mask);
17210905Sandreas.sandberg@arm.com    dst_i++;
17310905Sandreas.sandberg@arm.com
17410905Sandreas.sandberg@arm.com    for (; dst_i <= end_i; dst_i++)
17510905Sandreas.sandberg@arm.com        dst_p[dst_i] = 0;
17610905Sandreas.sandberg@arm.com
17710905Sandreas.sandberg@arm.com    return false;
17810905Sandreas.sandberg@arm.com}
17910905Sandreas.sandberg@arm.com
18010905Sandreas.sandberg@arm.combool
18110905Sandreas.sandberg@arm.comsc_signed::concat_get_data(sc_digit *dst_p, int low_i) const
18210905Sandreas.sandberg@arm.com{
18310905Sandreas.sandberg@arm.com    sc_digit carry; // Carry bit for complements.
18410905Sandreas.sandberg@arm.com    int dst_i; // Index to next word to set in dst_p.
18510905Sandreas.sandberg@arm.com    int end_i; // Index of high order word to set.
18610905Sandreas.sandberg@arm.com    int high_i; // Index w/in word of high order bit.
18710905Sandreas.sandberg@arm.com    int left_shift; // Amount to shift value left.
18810905Sandreas.sandberg@arm.com    sc_digit left_word; // High word component for set.
18910905Sandreas.sandberg@arm.com    sc_digit mask; // Mask for partial word sets.
19010905Sandreas.sandberg@arm.com    bool result; // True if inserted non-zero data.
19110905Sandreas.sandberg@arm.com    int right_shift; // Amount to shift value right.
19210905Sandreas.sandberg@arm.com    sc_digit right_word; // Low word component for set.
19310905Sandreas.sandberg@arm.com    int src_i; // Index to next word to get from digit.
19410905Sandreas.sandberg@arm.com
19510905Sandreas.sandberg@arm.com    // CALCULATE METRICS FOR DATA MOVEMENT:
19610905Sandreas.sandberg@arm.com    dst_i = low_i / BITS_PER_DIGIT;
19710905Sandreas.sandberg@arm.com    high_i = low_i + nbits - 1;
19810905Sandreas.sandberg@arm.com    end_i = high_i / BITS_PER_DIGIT;
19910905Sandreas.sandberg@arm.com    left_shift = low_i % BITS_PER_DIGIT;
20010905Sandreas.sandberg@arm.com
2012SN/A    switch (sgn) {
2022SN/A      // POSITIVE SOURCE VALUE:
2035739Snate@binkert.org      case SC_POS:
2045739Snate@binkert.org        result = true;
2052SN/A
20610905Sandreas.sandberg@arm.com        // ALL DATA TO BE MOVED IS IN A SINGLE WORD:
20710905Sandreas.sandberg@arm.com        if (dst_i == end_i) {
20810905Sandreas.sandberg@arm.com            mask = ~(~0U << left_shift);
20910905Sandreas.sandberg@arm.com            dst_p[dst_i] = ((dst_p[dst_i] & mask) |
21010905Sandreas.sandberg@arm.com                (digit[0] << left_shift)) & DIGIT_MASK;
21110905Sandreas.sandberg@arm.com
21210905Sandreas.sandberg@arm.com        // DATA IS IN MORE THAN ONE WORD, BUT IS WORD ALIGNED:
21310905Sandreas.sandberg@arm.com        } else if (left_shift == 0) {
2142SN/A            for (src_i = 0; dst_i < end_i; dst_i++, src_i++) {
21510905Sandreas.sandberg@arm.com                dst_p[dst_i] = digit[src_i];
21610905Sandreas.sandberg@arm.com            }
21710905Sandreas.sandberg@arm.com            high_i = high_i % BITS_PER_DIGIT;
21810905Sandreas.sandberg@arm.com            mask = ~(~1U << high_i) & DIGIT_MASK;
21910905Sandreas.sandberg@arm.com            dst_p[dst_i] = digit[src_i] & mask;
22010905Sandreas.sandberg@arm.com
22110905Sandreas.sandberg@arm.com        // DATA IS IN MORE THAN ONE WORD, AND NOT WORD ALIGNED:
22210905Sandreas.sandberg@arm.com        } else {
223237SN/A            high_i = high_i % BITS_PER_DIGIT;
22410905Sandreas.sandberg@arm.com            right_shift = BITS_PER_DIGIT - left_shift;
22510905Sandreas.sandberg@arm.com            mask = ~(~0U << left_shift);
22610905Sandreas.sandberg@arm.com            right_word = digit[0];
22710905Sandreas.sandberg@arm.com            dst_p[dst_i] = (dst_p[dst_i] & mask) |
22810905Sandreas.sandberg@arm.com                ((right_word << left_shift) & DIGIT_MASK);
22910905Sandreas.sandberg@arm.com            for (src_i = 1, dst_i++; dst_i < end_i; dst_i++, src_i++) {
23010905Sandreas.sandberg@arm.com                left_word = digit[src_i];
23110905Sandreas.sandberg@arm.com                dst_p[dst_i] = ((left_word << left_shift)&DIGIT_MASK) |
23210905Sandreas.sandberg@arm.com                    (right_word >> right_shift);
23310905Sandreas.sandberg@arm.com                right_word = left_word;
23410905Sandreas.sandberg@arm.com            }
23510905Sandreas.sandberg@arm.com            left_word = (src_i < ndigits) ? digit[src_i] : 0;
23610905Sandreas.sandberg@arm.com            mask = ~(~1U << high_i) & DIGIT_MASK;
23710905Sandreas.sandberg@arm.com            dst_p[dst_i] = ((left_word << left_shift) |
23810905Sandreas.sandberg@arm.com                (right_word >> right_shift)) & mask;
23910905Sandreas.sandberg@arm.com        }
24010905Sandreas.sandberg@arm.com        break;
24110905Sandreas.sandberg@arm.com
24210905Sandreas.sandberg@arm.com      // SOURCE VALUE IS NEGATIVE:
24310905Sandreas.sandberg@arm.com      case SC_NEG:
24410905Sandreas.sandberg@arm.com        // ALL DATA TO BE MOVED IS IN A SINGLE WORD:
24510905Sandreas.sandberg@arm.com        result = true;
24610905Sandreas.sandberg@arm.com        if (dst_i == end_i) {
24710905Sandreas.sandberg@arm.com            mask = ~(~0U << nbits);
24810905Sandreas.sandberg@arm.com            right_word = ((digit[0] ^ DIGIT_MASK) + 1) & mask;
24910905Sandreas.sandberg@arm.com            mask = ~(~0U << left_shift);
25010905Sandreas.sandberg@arm.com            dst_p[dst_i] = ((dst_p[dst_i] & mask) |
25110905Sandreas.sandberg@arm.com                (right_word << left_shift)) & DIGIT_MASK;
25210905Sandreas.sandberg@arm.com
25310905Sandreas.sandberg@arm.com        // DATA IS IN MORE THAN ONE WORD, BUT IS WORD ALIGNED:
25410905Sandreas.sandberg@arm.com        } else if (left_shift == 0) {
25510905Sandreas.sandberg@arm.com            carry = 1;
25610905Sandreas.sandberg@arm.com            for (src_i = 0; dst_i < end_i; dst_i++, src_i++) {
25710905Sandreas.sandberg@arm.com                right_word = (digit[src_i] ^ DIGIT_MASK) + carry;
25810905Sandreas.sandberg@arm.com                dst_p[dst_i] = right_word &  DIGIT_MASK;
25910905Sandreas.sandberg@arm.com                carry = right_word >> BITS_PER_DIGIT;
2602287SN/A            }
2612287SN/A            high_i = high_i % BITS_PER_DIGIT;
2622287SN/A            mask = (~(~1U << high_i)) & DIGIT_MASK;
2632868Sktlim@umich.edu            right_word = (src_i < ndigits) ?
26410905Sandreas.sandberg@arm.com                (digit[src_i] ^ DIGIT_MASK) + carry : DIGIT_MASK + carry;
26510905Sandreas.sandberg@arm.com            dst_p[dst_i] = right_word & mask;
26610905Sandreas.sandberg@arm.com
26710905Sandreas.sandberg@arm.com        // DATA IS IN MORE THAN ONE WORD, AND NOT WORD ALIGNED:
2682SN/A        } else {
2692SN/A            high_i = high_i % BITS_PER_DIGIT;
27013414Sgiacomo.travaglini@arm.com            right_shift = BITS_PER_DIGIT - left_shift;
27113414Sgiacomo.travaglini@arm.com            mask = ~(~0U << left_shift);
27213414Sgiacomo.travaglini@arm.com            carry = 1;
27313414Sgiacomo.travaglini@arm.com            right_word = (digit[0] ^ DIGIT_MASK) + carry;
27413414Sgiacomo.travaglini@arm.com            dst_p[dst_i] = (dst_p[dst_i] & mask) |
27513414Sgiacomo.travaglini@arm.com                ((right_word << left_shift) & DIGIT_MASK);
27613414Sgiacomo.travaglini@arm.com            carry = right_word >> BITS_PER_DIGIT;
27713414Sgiacomo.travaglini@arm.com            right_word &= DIGIT_MASK;
27813414Sgiacomo.travaglini@arm.com            for (src_i = 1, dst_i++; dst_i < end_i; dst_i++, src_i++) {
27913414Sgiacomo.travaglini@arm.com                left_word = (digit[src_i] ^ DIGIT_MASK) + carry;
2809554Sandreas.hansson@arm.com                dst_p[dst_i] = ((left_word << left_shift)&DIGIT_MASK) |
28113414Sgiacomo.travaglini@arm.com                    (right_word >> right_shift);
28213414Sgiacomo.travaglini@arm.com                carry = left_word >> BITS_PER_DIGIT;
28313414Sgiacomo.travaglini@arm.com                right_word = left_word & DIGIT_MASK;
28413414Sgiacomo.travaglini@arm.com            }
28513414Sgiacomo.travaglini@arm.com            left_word = (src_i < ndigits) ?
28613414Sgiacomo.travaglini@arm.com                (digit[src_i] ^ DIGIT_MASK) + carry : carry;
28710453SAndrew.Bardsley@arm.com            mask = ~(~1U << high_i) & DIGIT_MASK;
28813415Sgiacomo.travaglini@arm.com            dst_p[dst_i] = ((left_word << left_shift) |
28913415Sgiacomo.travaglini@arm.com                (right_word >> right_shift)) & mask;
29013415Sgiacomo.travaglini@arm.com        }
29113415Sgiacomo.travaglini@arm.com        break;
29213567Sodanrc@yahoo.com.br
29313567Sodanrc@yahoo.com.br      // VALUE IS ZERO:
29413415Sgiacomo.travaglini@arm.com      default:
29513415Sgiacomo.travaglini@arm.com        result = false;
29613415Sgiacomo.travaglini@arm.com        // ALL DATA TO BE MOVED IS IN A SINGLE WORD:
29713415Sgiacomo.travaglini@arm.com        if (dst_i == end_i) {
29813415Sgiacomo.travaglini@arm.com            mask = ~(~0U << nbits) << left_shift;
29913415Sgiacomo.travaglini@arm.com            dst_p[dst_i] = dst_p[dst_i] & ~mask;
30013415Sgiacomo.travaglini@arm.com
30113415Sgiacomo.travaglini@arm.com        // DATA IS IN MORE THAN ONE WORD, BUT IS WORD ALIGNED:
30213415Sgiacomo.travaglini@arm.com        } else if (left_shift == 0) {
30313415Sgiacomo.travaglini@arm.com            for (src_i = 0; dst_i < end_i; dst_i++, src_i++) {
30413415Sgiacomo.travaglini@arm.com                dst_p[dst_i] = 0;
30513415Sgiacomo.travaglini@arm.com            }
30613415Sgiacomo.travaglini@arm.com            dst_p[dst_i] = 0;
30713415Sgiacomo.travaglini@arm.com
30813415Sgiacomo.travaglini@arm.com        // DATA IS IN MORE THAN ONE WORD, AND NOT WORD ALIGNED:
30913415Sgiacomo.travaglini@arm.com        } else {
31013415Sgiacomo.travaglini@arm.com            mask = ~(~0U << left_shift);
31113415Sgiacomo.travaglini@arm.com            dst_p[dst_i] = (dst_p[dst_i] & mask);
31213414Sgiacomo.travaglini@arm.com            for (dst_i++; dst_i <= end_i; dst_i++) {
31313414Sgiacomo.travaglini@arm.com                dst_p[dst_i] = 0;
31413414Sgiacomo.travaglini@arm.com            }
31513414Sgiacomo.travaglini@arm.com        }
316237SN/A        break;
31713414Sgiacomo.travaglini@arm.com    }
31813414Sgiacomo.travaglini@arm.com    return result;
319237SN/A}
32013414Sgiacomo.travaglini@arm.com
32113414Sgiacomo.travaglini@arm.com// Return this object instance's bits as a uint64 without sign extension.
32213414Sgiacomo.travaglini@arm.com
32313414Sgiacomo.travaglini@arm.comuint64
32413414Sgiacomo.travaglini@arm.comsc_signed::concat_get_uint64() const
32513414Sgiacomo.travaglini@arm.com{
326237SN/A    uint64        result;
32713414Sgiacomo.travaglini@arm.com    switch (sgn) {
32813414Sgiacomo.travaglini@arm.com      case SC_POS:
32913414Sgiacomo.travaglini@arm.com        result = 0;
33013414Sgiacomo.travaglini@arm.com        if (ndigits > 2)
33113414Sgiacomo.travaglini@arm.com            result = digit[2];
33213414Sgiacomo.travaglini@arm.com        if (ndigits > 1)
33310453SAndrew.Bardsley@arm.com            result = (result << BITS_PER_DIGIT) | digit[1];
33413414Sgiacomo.travaglini@arm.com        result = (result << BITS_PER_DIGIT) | digit[0];
33513414Sgiacomo.travaglini@arm.com        break;
33613414Sgiacomo.travaglini@arm.com      case SC_NEG:
33713414Sgiacomo.travaglini@arm.com        result = 0;
33813414Sgiacomo.travaglini@arm.com        if (ndigits > 2)
33913414Sgiacomo.travaglini@arm.com            result = digit[2];
340237SN/A        if (ndigits > 1)
34113414Sgiacomo.travaglini@arm.com            result = (result << BITS_PER_DIGIT) | digit[1];
34213414Sgiacomo.travaglini@arm.com        result = (result << BITS_PER_DIGIT) | digit[0];
34313414Sgiacomo.travaglini@arm.com        result = -result;
34413414Sgiacomo.travaglini@arm.com        if (nbits < 64) {
34513414Sgiacomo.travaglini@arm.com            uint64 mask = ~0;
34613414Sgiacomo.travaglini@arm.com            result = result & ~(mask << nbits);
347937SN/A        }
34813414Sgiacomo.travaglini@arm.com        break;
34913414Sgiacomo.travaglini@arm.com      default:
35013414Sgiacomo.travaglini@arm.com        result = 0;
35113414Sgiacomo.travaglini@arm.com        break;
35213414Sgiacomo.travaglini@arm.com    }
35313414Sgiacomo.travaglini@arm.com    return result;
354237SN/A}
35513414Sgiacomo.travaglini@arm.com
35613414Sgiacomo.travaglini@arm.com// #### OPTIMIZE
35713414Sgiacomo.travaglini@arm.comvoid
35813414Sgiacomo.travaglini@arm.comsc_signed::concat_set(int64 src, int low_i)
35913414Sgiacomo.travaglini@arm.com{
36013414Sgiacomo.travaglini@arm.com    *this = (low_i < 64) ? src >> low_i : src >> 63;
36113414Sgiacomo.travaglini@arm.com}
362304SN/A
36313414Sgiacomo.travaglini@arm.comvoid
36413414Sgiacomo.travaglini@arm.comsc_signed::concat_set(const sc_signed &src, int low_i)
36513414Sgiacomo.travaglini@arm.com{
36613414Sgiacomo.travaglini@arm.com    if (low_i < src.length())
36713414Sgiacomo.travaglini@arm.com        *this = src >> low_i;
36813414Sgiacomo.travaglini@arm.com    else
36913414Sgiacomo.travaglini@arm.com        *this = (src<0) ? (int_type)-1 : 0;
37013414Sgiacomo.travaglini@arm.com}
37111655Sandreas.sandberg@arm.com
37213414Sgiacomo.travaglini@arm.comvoid
37313414Sgiacomo.travaglini@arm.comsc_signed::concat_set(const sc_unsigned &src, int low_i)
37413414Sgiacomo.travaglini@arm.com{
37513414Sgiacomo.travaglini@arm.com    if (low_i < src.length())
37613414Sgiacomo.travaglini@arm.com        *this = src >> low_i;
37713414Sgiacomo.travaglini@arm.com    else
37813414Sgiacomo.travaglini@arm.com        *this = 0;
37913414Sgiacomo.travaglini@arm.com}
380449SN/A
38113414Sgiacomo.travaglini@arm.comvoid
38213414Sgiacomo.travaglini@arm.comsc_signed::concat_set(uint64 src, int low_i)
38313414Sgiacomo.travaglini@arm.com{
38413414Sgiacomo.travaglini@arm.com    *this = (low_i < 64) ? src >> low_i : 0;
38513414Sgiacomo.travaglini@arm.com}
38613414Sgiacomo.travaglini@arm.com
38713414Sgiacomo.travaglini@arm.com// ----------------------------------------------------------------------------
38813414Sgiacomo.travaglini@arm.com//  SECTION: Public members - Reduction methods.
38913414Sgiacomo.travaglini@arm.com// ----------------------------------------------------------------------------
39013414Sgiacomo.travaglini@arm.com
3917491Ssteve.reinhardt@amd.combool
39213414Sgiacomo.travaglini@arm.comsc_signed::and_reduce() const
39313414Sgiacomo.travaglini@arm.com{
39413414Sgiacomo.travaglini@arm.com    sc_digit current; // Current digit examining.
39513414Sgiacomo.travaglini@arm.com    int i; // Index of digit examining.
39613414Sgiacomo.travaglini@arm.com
39713414Sgiacomo.travaglini@arm.com    if (sgn == SC_NEG) {
39813414Sgiacomo.travaglini@arm.com        current = (1 << BITS_PER_DIGIT);
39913414Sgiacomo.travaglini@arm.com        for (i = 0; i < ndigits-1; i++) {
40013414Sgiacomo.travaglini@arm.com            current = (current >> BITS_PER_DIGIT) + (digit[i]^DIGIT_MASK);
40113414Sgiacomo.travaglini@arm.com            if ((current & DIGIT_MASK) != DIGIT_MASK) return false;
40213414Sgiacomo.travaglini@arm.com        }
40313414Sgiacomo.travaglini@arm.com        current = (current >> BITS_PER_DIGIT) + (digit[i]^DIGIT_MASK);
40413414Sgiacomo.travaglini@arm.com        if ((current & ~(~0U << (nbits % BITS_PER_DIGIT))) ==
40513414Sgiacomo.travaglini@arm.com             static_cast<sc_digit>(~(~0U << (nbits % BITS_PER_DIGIT)))) {
40613414Sgiacomo.travaglini@arm.com            return true;
407449SN/A        }
40813414Sgiacomo.travaglini@arm.com    }
40913414Sgiacomo.travaglini@arm.com    return false;
41013414Sgiacomo.travaglini@arm.com}
41113414Sgiacomo.travaglini@arm.com
41213414Sgiacomo.travaglini@arm.combool
41313414Sgiacomo.travaglini@arm.comsc_signed::or_reduce() const
41413414Sgiacomo.travaglini@arm.com{
41513414Sgiacomo.travaglini@arm.com    return sgn == SC_ZERO ? false : true;
41613414Sgiacomo.travaglini@arm.com}
41713414Sgiacomo.travaglini@arm.com
41813414Sgiacomo.travaglini@arm.combool
41913414Sgiacomo.travaglini@arm.comsc_signed::xor_reduce() const
42013414Sgiacomo.travaglini@arm.com{
42113414Sgiacomo.travaglini@arm.com    int i; // Digit examining.
42213414Sgiacomo.travaglini@arm.com    int odd; // Flag for odd number of digits.
42313414Sgiacomo.travaglini@arm.com
42413414Sgiacomo.travaglini@arm.com    odd = 0;
42513414Sgiacomo.travaglini@arm.com    for (i = 0; i < nbits; i++)
42613414Sgiacomo.travaglini@arm.com        if (test(i))
42713414Sgiacomo.travaglini@arm.com            odd = ~odd;
42813414Sgiacomo.travaglini@arm.com    return odd ? true : false;
42913414Sgiacomo.travaglini@arm.com}
43013414Sgiacomo.travaglini@arm.com
43113414Sgiacomo.travaglini@arm.com
43213414Sgiacomo.travaglini@arm.com
43313414Sgiacomo.travaglini@arm.com// ----------------------------------------------------------------------------
43413414Sgiacomo.travaglini@arm.com//  SECTION: Public members - Assignment operators.
43513414Sgiacomo.travaglini@arm.com// ----------------------------------------------------------------------------
43613414Sgiacomo.travaglini@arm.com
43713414Sgiacomo.travaglini@arm.com// assignment operators
43813414Sgiacomo.travaglini@arm.com
43913414Sgiacomo.travaglini@arm.comconst sc_signed &
44013414Sgiacomo.travaglini@arm.comsc_signed::operator = (const char *a)
44113414Sgiacomo.travaglini@arm.com{
44213414Sgiacomo.travaglini@arm.com    if (a == 0) {
44313414Sgiacomo.travaglini@arm.com        SC_REPORT_ERROR("conversion failed",
44413414Sgiacomo.travaglini@arm.com                        "character string is zero");
44513414Sgiacomo.travaglini@arm.com    } else if (*a == 0) {
44613414Sgiacomo.travaglini@arm.com        SC_REPORT_ERROR("conversion failed",
44713414Sgiacomo.travaglini@arm.com                        "character string is empty");
44813414Sgiacomo.travaglini@arm.com    } else try {
44913414Sgiacomo.travaglini@arm.com        int len = length();
45013414Sgiacomo.travaglini@arm.com        sc_fix aa(a, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
45113414Sgiacomo.travaglini@arm.com        return this->operator = (aa);
45213414Sgiacomo.travaglini@arm.com    } catch(const sc_core::sc_report &) {
45313414Sgiacomo.travaglini@arm.com        std::stringstream msg;
45413414Sgiacomo.travaglini@arm.com        msg << "character string '" << a << "' is not valid";
45513414Sgiacomo.travaglini@arm.com        SC_REPORT_ERROR("conversion failed", msg.str().c_str());
45613414Sgiacomo.travaglini@arm.com    }
45713414Sgiacomo.travaglini@arm.com    return *this;
45813414Sgiacomo.travaglini@arm.com}
45913414Sgiacomo.travaglini@arm.com
46013414Sgiacomo.travaglini@arm.comconst sc_signed &
46113414Sgiacomo.travaglini@arm.comsc_signed::operator=(int64 v)
46213414Sgiacomo.travaglini@arm.com{
46313414Sgiacomo.travaglini@arm.com    sgn = get_sign(v);
46413414Sgiacomo.travaglini@arm.com    // v >= 0 now.
46513414Sgiacomo.travaglini@arm.com    if (sgn == SC_ZERO) {
46613414Sgiacomo.travaglini@arm.com        vec_zero(ndigits, digit);
46713414Sgiacomo.travaglini@arm.com    } else {
46813414Sgiacomo.travaglini@arm.com        from_uint(ndigits, digit, (uint64)v);
46913414Sgiacomo.travaglini@arm.com        if (nbits <= (int)BITS_PER_INT64)
47013414Sgiacomo.travaglini@arm.com            convert_SM_to_2C_to_SM();
47113414Sgiacomo.travaglini@arm.com    }
47213414Sgiacomo.travaglini@arm.com    return *this;
47313414Sgiacomo.travaglini@arm.com}
47413414Sgiacomo.travaglini@arm.com
47513414Sgiacomo.travaglini@arm.comconst sc_signed &
47613414Sgiacomo.travaglini@arm.comsc_signed::operator=(uint64 v)
47713414Sgiacomo.travaglini@arm.com{
47813414Sgiacomo.travaglini@arm.com    sgn = get_sign(v);
47913414Sgiacomo.travaglini@arm.com    if (sgn == SC_ZERO) {
48013414Sgiacomo.travaglini@arm.com        vec_zero(ndigits, digit);
48113414Sgiacomo.travaglini@arm.com    } else {
48213414Sgiacomo.travaglini@arm.com        from_uint(ndigits, digit, v);
48313414Sgiacomo.travaglini@arm.com        if (nbits <= (int)BITS_PER_INT64)
48413414Sgiacomo.travaglini@arm.com            convert_SM_to_2C_to_SM();
48513414Sgiacomo.travaglini@arm.com    }
48613414Sgiacomo.travaglini@arm.com    return *this;
48713414Sgiacomo.travaglini@arm.com}
48813414Sgiacomo.travaglini@arm.com
48913414Sgiacomo.travaglini@arm.comconst sc_signed &
49013414Sgiacomo.travaglini@arm.comsc_signed::operator=(long v)
49113414Sgiacomo.travaglini@arm.com{
49213414Sgiacomo.travaglini@arm.com    sgn = get_sign(v);
49313414Sgiacomo.travaglini@arm.com    // v >= 0 now.
49413414Sgiacomo.travaglini@arm.com    if (sgn == SC_ZERO) {
49513414Sgiacomo.travaglini@arm.com        vec_zero(ndigits, digit);
49613414Sgiacomo.travaglini@arm.com    } else {
49713414Sgiacomo.travaglini@arm.com        from_uint(ndigits, digit, (unsigned long)v);
49813414Sgiacomo.travaglini@arm.com        if (nbits <= (int)BITS_PER_LONG)
49913414Sgiacomo.travaglini@arm.com            convert_SM_to_2C_to_SM();
50013414Sgiacomo.travaglini@arm.com    }
50113414Sgiacomo.travaglini@arm.com    return *this;
50213414Sgiacomo.travaglini@arm.com}
50313414Sgiacomo.travaglini@arm.com
50413414Sgiacomo.travaglini@arm.comconst sc_signed &
50513414Sgiacomo.travaglini@arm.comsc_signed::operator=(unsigned long v)
50613414Sgiacomo.travaglini@arm.com{
50713414Sgiacomo.travaglini@arm.com    sgn = get_sign(v);
50813414Sgiacomo.travaglini@arm.com    if (sgn == SC_ZERO) {
50913414Sgiacomo.travaglini@arm.com        vec_zero(ndigits, digit);
51013414Sgiacomo.travaglini@arm.com    } else {
51113414Sgiacomo.travaglini@arm.com        from_uint(ndigits, digit, v);
51213414Sgiacomo.travaglini@arm.com        if (nbits <= (int)BITS_PER_LONG)
51313414Sgiacomo.travaglini@arm.com            convert_SM_to_2C_to_SM();
51413414Sgiacomo.travaglini@arm.com    }
51513414Sgiacomo.travaglini@arm.com    return *this;
51613414Sgiacomo.travaglini@arm.com}
51713414Sgiacomo.travaglini@arm.com
51813414Sgiacomo.travaglini@arm.comconst sc_signed &
51913414Sgiacomo.travaglini@arm.comsc_signed::operator=(double v)
52013414Sgiacomo.travaglini@arm.com{
52113414Sgiacomo.travaglini@arm.com    is_bad_double(v);
52213414Sgiacomo.travaglini@arm.com    if (v < 0) {
52313414Sgiacomo.travaglini@arm.com        v = -v;
52413414Sgiacomo.travaglini@arm.com        sgn = SC_NEG;
52513414Sgiacomo.travaglini@arm.com    } else {
52613414Sgiacomo.travaglini@arm.com      sgn = SC_POS;
52713414Sgiacomo.travaglini@arm.com    }
52813414Sgiacomo.travaglini@arm.com
52913414Sgiacomo.travaglini@arm.com    int i = 0;
53013414Sgiacomo.travaglini@arm.com    while (std::floor(v) && (i < ndigits)) {
53113414Sgiacomo.travaglini@arm.com        digit[i++] = ((sc_digit)std::floor(remainder(v, DIGIT_RADIX))) &
53213414Sgiacomo.travaglini@arm.com                                           DIGIT_MASK;
53313414Sgiacomo.travaglini@arm.com        v /= DIGIT_RADIX;
53413414Sgiacomo.travaglini@arm.com    }
53513414Sgiacomo.travaglini@arm.com    vec_zero(i, ndigits, digit);
53613414Sgiacomo.travaglini@arm.com    convert_SM_to_2C_to_SM();
53713414Sgiacomo.travaglini@arm.com    return *this;
53813414Sgiacomo.travaglini@arm.com}
53913414Sgiacomo.travaglini@arm.com
54013414Sgiacomo.travaglini@arm.com
54113414Sgiacomo.travaglini@arm.com// ----------------------------------------------------------------------------
54213414Sgiacomo.travaglini@arm.com
54313414Sgiacomo.travaglini@arm.comconst sc_signed &
54413414Sgiacomo.travaglini@arm.comsc_signed::operator = (const sc_bv_base &v)
54513414Sgiacomo.travaglini@arm.com{
54613414Sgiacomo.travaglini@arm.com    int minlen = sc_min(nbits, v.length());
54713414Sgiacomo.travaglini@arm.com    int i = 0;
54813414Sgiacomo.travaglini@arm.com    for (; i < minlen; ++i) {
54913414Sgiacomo.travaglini@arm.com        safe_set(i, v.get_bit(i), digit);
55013414Sgiacomo.travaglini@arm.com    }
55113414Sgiacomo.travaglini@arm.com    for (; i < nbits; ++i) {
55213414Sgiacomo.travaglini@arm.com        safe_set(i, 0, digit); // zero-extend
55313414Sgiacomo.travaglini@arm.com    }
55413414Sgiacomo.travaglini@arm.com    convert_2C_to_SM();
55513414Sgiacomo.travaglini@arm.com    return *this;
55613414Sgiacomo.travaglini@arm.com}
55713414Sgiacomo.travaglini@arm.com
55813414Sgiacomo.travaglini@arm.comconst sc_signed &
55913414Sgiacomo.travaglini@arm.comsc_signed::operator = (const sc_lv_base &v)
56013414Sgiacomo.travaglini@arm.com{
56113414Sgiacomo.travaglini@arm.com    int minlen = sc_min(nbits, v.length());
56213414Sgiacomo.travaglini@arm.com    int i = 0;
56313414Sgiacomo.travaglini@arm.com    for (; i < minlen; ++i) {
56413414Sgiacomo.travaglini@arm.com        safe_set(i, sc_logic(v.get_bit(i)).to_bool(), digit);
56513414Sgiacomo.travaglini@arm.com    }
56613414Sgiacomo.travaglini@arm.com    for (; i < nbits; ++i) {
56713414Sgiacomo.travaglini@arm.com        safe_set(i, 0, digit);  // zero-extend
56813414Sgiacomo.travaglini@arm.com    }
56913414Sgiacomo.travaglini@arm.com    convert_2C_to_SM();
57013414Sgiacomo.travaglini@arm.com    return *this;
57113414Sgiacomo.travaglini@arm.com}
57213414Sgiacomo.travaglini@arm.com
57313414Sgiacomo.travaglini@arm.com
57413414Sgiacomo.travaglini@arm.com// explicit conversion to character string
57513414Sgiacomo.travaglini@arm.comconst std::string
57613414Sgiacomo.travaglini@arm.comsc_signed::to_string(sc_numrep numrep) const
57713414Sgiacomo.travaglini@arm.com{
57813414Sgiacomo.travaglini@arm.com    int len = length();
57913414Sgiacomo.travaglini@arm.com    sc_fix aa(*this, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
58013414Sgiacomo.travaglini@arm.com    return aa.to_string(numrep);
58113414Sgiacomo.travaglini@arm.com}
58213414Sgiacomo.travaglini@arm.com
58313414Sgiacomo.travaglini@arm.comconst std::string
58413414Sgiacomo.travaglini@arm.comsc_signed::to_string(sc_numrep numrep, bool w_prefix) const
58513414Sgiacomo.travaglini@arm.com{
58613414Sgiacomo.travaglini@arm.com    int len = length();
58713414Sgiacomo.travaglini@arm.com    sc_fix aa(*this, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
58813414Sgiacomo.travaglini@arm.com    return aa.to_string(numrep, w_prefix);
58913414Sgiacomo.travaglini@arm.com}
59013414Sgiacomo.travaglini@arm.com
59113414Sgiacomo.travaglini@arm.com
59213414Sgiacomo.travaglini@arm.com// ----------------------------------------------------------------------------
59313414Sgiacomo.travaglini@arm.com//  SECTION: Interfacing with sc_int_base
59413414Sgiacomo.travaglini@arm.com// ----------------------------------------------------------------------------
59513414Sgiacomo.travaglini@arm.com
59613414Sgiacomo.travaglini@arm.comconst sc_signed &
59713414Sgiacomo.travaglini@arm.comsc_signed::operator = (const sc_int_base &v)
59813414Sgiacomo.travaglini@arm.com{
59913414Sgiacomo.travaglini@arm.com    return operator = ((int64)v);
60013414Sgiacomo.travaglini@arm.com}
60113414Sgiacomo.travaglini@arm.com
60213414Sgiacomo.travaglini@arm.com
60313414Sgiacomo.travaglini@arm.comsc_signed
60413414Sgiacomo.travaglini@arm.comoperator + (const sc_unsigned &u, const sc_int_base &v)
60513414Sgiacomo.travaglini@arm.com{
60613414Sgiacomo.travaglini@arm.com    return operator + (u, static_cast<int64>(v));
60713414Sgiacomo.travaglini@arm.com}
60813414Sgiacomo.travaglini@arm.com
60913414Sgiacomo.travaglini@arm.comsc_signed
61013414Sgiacomo.travaglini@arm.comoperator + (const sc_int_base &u, const sc_unsigned &v)
61113414Sgiacomo.travaglini@arm.com{
61213414Sgiacomo.travaglini@arm.com    return operator + (static_cast<int64>(u), v);
61313414Sgiacomo.travaglini@arm.com}
61413414Sgiacomo.travaglini@arm.com
61513414Sgiacomo.travaglini@arm.comsc_signed
61613414Sgiacomo.travaglini@arm.comoperator + (const sc_signed &u, const sc_int_base &v)
61713414Sgiacomo.travaglini@arm.com{
61813414Sgiacomo.travaglini@arm.com    return operator + (u, (int64)v);
61913414Sgiacomo.travaglini@arm.com}
62013414Sgiacomo.travaglini@arm.com
62113414Sgiacomo.travaglini@arm.comsc_signed
62213414Sgiacomo.travaglini@arm.comoperator + (const sc_int_base &u, const sc_signed &v)
62313414Sgiacomo.travaglini@arm.com{
62413414Sgiacomo.travaglini@arm.com    return operator + ((int64)u, v);
62513414Sgiacomo.travaglini@arm.com}
62613414Sgiacomo.travaglini@arm.com
62713414Sgiacomo.travaglini@arm.comconst sc_signed &
62813414Sgiacomo.travaglini@arm.comsc_signed::operator += (const sc_int_base &v)
62913414Sgiacomo.travaglini@arm.com{
63013414Sgiacomo.travaglini@arm.com    return operator += ((int64)v);
63113414Sgiacomo.travaglini@arm.com}
63213414Sgiacomo.travaglini@arm.com
63313414Sgiacomo.travaglini@arm.com
63413414Sgiacomo.travaglini@arm.comsc_signed
63513414Sgiacomo.travaglini@arm.comoperator - (const sc_unsigned &u, const sc_int_base &v)
63613414Sgiacomo.travaglini@arm.com{
63713414Sgiacomo.travaglini@arm.com    return operator - (u, (int64)v);
63813414Sgiacomo.travaglini@arm.com}
63913414Sgiacomo.travaglini@arm.com
64013414Sgiacomo.travaglini@arm.comsc_signed
64113414Sgiacomo.travaglini@arm.comoperator - (const sc_int_base &u, const sc_unsigned &v)
64213414Sgiacomo.travaglini@arm.com{
64313414Sgiacomo.travaglini@arm.com    return operator - ((int64)u, v);
64413414Sgiacomo.travaglini@arm.com}
64513414Sgiacomo.travaglini@arm.com
64613414Sgiacomo.travaglini@arm.comsc_signed
64713414Sgiacomo.travaglini@arm.comoperator - (const sc_signed &u, const sc_int_base &v)
64813414Sgiacomo.travaglini@arm.com{
64913414Sgiacomo.travaglini@arm.com    return operator - (u, (int64)v);
65013414Sgiacomo.travaglini@arm.com}
65113414Sgiacomo.travaglini@arm.com
65213414Sgiacomo.travaglini@arm.comsc_signed
65313414Sgiacomo.travaglini@arm.comoperator - (const sc_int_base &u, const sc_signed &v)
65413414Sgiacomo.travaglini@arm.com{
65513414Sgiacomo.travaglini@arm.com    return operator - ((int64)u, v);
65613414Sgiacomo.travaglini@arm.com}
65713414Sgiacomo.travaglini@arm.com
65813414Sgiacomo.travaglini@arm.comconst sc_signed &
65913414Sgiacomo.travaglini@arm.comsc_signed::operator -= (const sc_int_base &v)
66013414Sgiacomo.travaglini@arm.com{
66113414Sgiacomo.travaglini@arm.com    return operator -= ((int64)v);
66213414Sgiacomo.travaglini@arm.com}
66313414Sgiacomo.travaglini@arm.com
66413414Sgiacomo.travaglini@arm.com
66513414Sgiacomo.travaglini@arm.comsc_signed
66613414Sgiacomo.travaglini@arm.comoperator * (const sc_unsigned &u, const sc_int_base &v)
66713414Sgiacomo.travaglini@arm.com{
66813414Sgiacomo.travaglini@arm.com    return operator * (u, static_cast<int64>(v));
66913414Sgiacomo.travaglini@arm.com}
67013414Sgiacomo.travaglini@arm.com
67113414Sgiacomo.travaglini@arm.comsc_signed
67213414Sgiacomo.travaglini@arm.comoperator * (const sc_int_base &u, const sc_unsigned &v)
67313414Sgiacomo.travaglini@arm.com{
67413414Sgiacomo.travaglini@arm.com    return operator * (static_cast<int64>(u), v);
67513414Sgiacomo.travaglini@arm.com}
67613414Sgiacomo.travaglini@arm.com
67713414Sgiacomo.travaglini@arm.comsc_signed
67813414Sgiacomo.travaglini@arm.comoperator * (const sc_signed &u, const sc_int_base &v)
67913414Sgiacomo.travaglini@arm.com{
68013414Sgiacomo.travaglini@arm.com    return operator * (u, (int64)v);
6812SN/A}
6822SN/A
683sc_signed
684operator * (const sc_int_base &u, const sc_signed &v)
685{
686    return operator * ((int64)u, v);
687}
688
689const sc_signed &
690sc_signed::operator *= (const sc_int_base &v)
691{
692    return operator *= ((int64)v);
693}
694
695
696sc_signed
697operator / (const sc_unsigned &u, const sc_int_base &v)
698{
699    return operator / (u, static_cast<int64>(v));
700}
701
702sc_signed
703operator / (const sc_int_base &u, const sc_unsigned &v)
704{
705    return operator / (static_cast<int64>(u), v);
706}
707
708sc_signed
709operator / (const sc_signed &u, const sc_int_base &v)
710{
711    return operator / (u, (int64)v);
712}
713
714sc_signed
715operator / (const sc_int_base &u, const sc_signed &v)
716{
717    return operator / ((int64)u, v);
718}
719
720const sc_signed &
721sc_signed::operator /= (const sc_int_base &v)
722{
723    return operator /= ((int64)v);
724}
725
726
727sc_signed
728operator % (const sc_unsigned &u, const sc_int_base &v)
729{
730    return operator % (u, static_cast<int64>(v));
731}
732
733sc_signed
734operator % (const sc_int_base &u, const sc_unsigned &v)
735{
736    return operator % (static_cast<int64>(u), v);
737}
738
739sc_signed
740operator % (const sc_signed &u, const sc_int_base &v)
741{
742    return operator % (u, (int64)v);
743}
744
745sc_signed
746operator % (const sc_int_base &u, const sc_signed &v)
747{
748    return operator % ((int64)u, v);
749}
750
751const sc_signed &
752sc_signed::operator %= (const sc_int_base &v)
753{
754    return operator %= ((int64)v);
755}
756
757
758sc_signed
759operator & (const sc_unsigned &u, const sc_int_base &v)
760{
761    return operator & (u, static_cast<int64>(v));
762}
763
764sc_signed
765operator & (const sc_int_base &u, const sc_unsigned &v)
766{
767    return operator & (static_cast<int64>(u), v);
768}
769
770sc_signed
771operator & (const sc_signed &u, const sc_int_base &v)
772{
773    return operator & (u, (int64)v);
774}
775
776sc_signed
777operator & (const sc_int_base &u, const sc_signed &v)
778{
779    return operator & ((int64)u, v);
780}
781
782const sc_signed &
783sc_signed::operator &= (const sc_int_base &v)
784{
785    return operator &= ((int64)v);
786}
787
788
789sc_signed
790operator | (const sc_unsigned &u, const sc_int_base &v)
791{
792    return operator | (u, static_cast<int64>(v));
793}
794
795sc_signed
796operator | (const sc_int_base &u, const sc_unsigned &v)
797{
798    return operator | (static_cast<int64>(u), v);
799}
800
801sc_signed
802operator | (const sc_signed& u, const sc_int_base &v)
803{
804    return operator|(u, (int64)v);
805}
806
807sc_signed
808operator | (const sc_int_base &u, const sc_signed &v)
809{
810    return operator | ((int64)u, v);
811}
812
813const sc_signed &
814sc_signed::operator |= (const sc_int_base &v)
815{
816    return operator |= ((int64)v);
817}
818
819
820sc_signed
821operator ^ (const sc_unsigned &u, const sc_int_base &v)
822{
823    return operator ^ (u, static_cast<int64>(v));
824}
825
826sc_signed
827operator ^ (const sc_int_base &u, const sc_unsigned &v)
828{
829    return operator ^ (static_cast<int64>(u), v);
830}
831
832sc_signed
833operator ^ (const sc_signed &u, const sc_int_base &v)
834{
835    return operator ^ (u, (int64)v);
836}
837
838sc_signed
839operator ^ (const sc_int_base &u, const sc_signed &v)
840{
841    return operator ^ ((int64)u, v);
842}
843
844const sc_signed &
845sc_signed::operator ^= (const sc_int_base &v)
846{
847    return operator ^= ((int64)v);
848}
849
850
851sc_signed
852operator << (const sc_signed &u, const sc_int_base &v)
853{
854    return operator << (u, (int64)v);
855}
856
857const sc_signed &
858sc_signed::operator <<= (const sc_int_base &v)
859{
860    return operator <<= ((int64)v);
861}
862
863
864sc_signed
865operator >> (const sc_signed &u, const sc_int_base &v)
866{
867    return operator >> (u, (int64)v);
868}
869
870const sc_signed &
871sc_signed::operator >>= (const sc_int_base &v)
872{
873    return operator >>= ((int64)v);
874}
875
876
877bool
878operator == (const sc_signed &u, const sc_int_base &v)
879{
880    return operator == (u, (int64)v);
881}
882
883bool
884operator == (const sc_int_base &u, const sc_signed &v)
885{
886    return operator == ((int64)u, v);
887}
888
889
890bool
891operator != (const sc_signed &u, const sc_int_base &v)
892{
893    return operator != (u, (int64)v);
894}
895
896bool
897operator != (const sc_int_base &u, const sc_signed &v)
898{
899    return operator != ((int64)u, v);
900}
901
902
903bool
904operator < (const sc_signed &u, const sc_int_base &v)
905{
906    return operator < (u, (int64)v);
907}
908
909bool
910operator  <  (const sc_int_base &u, const sc_signed &v)
911{
912    return operator < ((int64)u, v);
913}
914
915
916bool
917operator  <=  (const sc_signed &u, const sc_int_base &v)
918{
919    return operator <= (u, (int64)v);
920}
921
922bool
923operator  <=  (const sc_int_base &u, const sc_signed &v)
924{
925    return operator <= ((int64)u, v);
926}
927
928
929bool
930operator  >  (const sc_signed &u, const sc_int_base &v)
931{
932    return operator > (u, (int64)v);
933}
934
935bool
936operator  >  (const sc_int_base &u, const sc_signed &v)
937{
938    return operator > ((int64)u, v);
939}
940
941
942bool
943operator  >=  (const sc_signed &u, const sc_int_base &v)
944{
945    return operator >= (u, (int64)v);
946}
947
948bool
949operator  >=  (const sc_int_base &u, const sc_signed &v)
950{
951    return operator >= ((int64)u, v);
952}
953
954
955// ----------------------------------------------------------------------------
956//  SECTION: Interfacing with sc_uint_base
957// ----------------------------------------------------------------------------
958
959const sc_signed &
960sc_signed::operator = (const sc_uint_base &v)
961{
962    return operator = ((uint64)v);
963}
964
965
966sc_signed
967operator + (const sc_signed &u, const sc_uint_base &v)
968{
969    return operator + (u, (uint64)v);
970}
971
972sc_signed
973operator + (const sc_uint_base &u, const sc_signed &v)
974{
975    return operator + ((uint64)u, v);
976}
977
978const sc_signed &
979sc_signed::operator += (const sc_uint_base &v)
980{
981    return operator += ((uint64)v);
982}
983
984
985sc_signed
986operator - (const sc_unsigned &u, const sc_uint_base &v)
987{
988    return operator - (u, (uint64)v);
989}
990
991sc_signed
992operator - (const sc_uint_base &u, const sc_unsigned &v)
993{
994    return operator - ((uint64)u, v);
995}
996
997sc_signed
998operator - (const sc_signed &u, const sc_uint_base &v)
999{
1000    return operator - (u, (uint64)v);
1001}
1002
1003sc_signed
1004operator - (const sc_uint_base &u, const sc_signed &v)
1005{
1006    return operator - ((uint64)u, v);
1007}
1008
1009const sc_signed &
1010sc_signed::operator -= (const sc_uint_base &v)
1011{
1012    return operator -= ((uint64)v);
1013}
1014
1015
1016sc_signed
1017operator * (const sc_signed &u, const sc_uint_base &v)
1018{
1019    return operator * (u, (uint64)v);
1020}
1021
1022sc_signed
1023operator * (const sc_uint_base &u, const sc_signed &v)
1024{
1025    return operator * ((uint64)u, v);
1026}
1027
1028const sc_signed &
1029sc_signed::operator *= (const sc_uint_base &v)
1030{
1031    return operator *= ((uint64)v);
1032}
1033
1034
1035sc_signed
1036operator / (const sc_signed &u, const sc_uint_base &v)
1037{
1038    return operator / (u, (uint64)v);
1039}
1040
1041sc_signed
1042operator / (const sc_uint_base &u, const sc_signed &v)
1043{
1044    return operator / ((uint64)u, v);
1045}
1046
1047const sc_signed &
1048sc_signed::operator /= (const sc_uint_base &v)
1049{
1050    return operator /= ((uint64)v);
1051}
1052
1053
1054sc_signed
1055operator % (const sc_signed &u, const sc_uint_base &v)
1056{
1057    return operator % (u, (uint64)v);
1058}
1059
1060sc_signed
1061operator % (const sc_uint_base &u, const sc_signed &v)
1062{
1063    return operator % ((uint64)u, v);
1064}
1065
1066const sc_signed&
1067sc_signed::operator %= (const sc_uint_base &v)
1068{
1069    return operator %= ((uint64)v);
1070}
1071
1072
1073sc_signed
1074operator & (const sc_signed &u, const sc_uint_base &v)
1075{
1076    return operator & (u, (uint64)v);
1077}
1078
1079sc_signed
1080operator & (const sc_uint_base &u, const sc_signed &v)
1081{
1082    return operator & ((uint64)u, v);
1083}
1084
1085const sc_signed &
1086sc_signed::operator &= (const sc_uint_base &v)
1087{
1088    return operator &= ((uint64)v);
1089}
1090
1091
1092sc_signed
1093operator | (const sc_signed &u, const sc_uint_base &v)
1094{
1095    return operator | (u, (uint64)v);
1096}
1097
1098sc_signed
1099operator | (const sc_uint_base &u, const sc_signed &v)
1100{
1101    return operator | ((uint64)u, v);
1102}
1103
1104const sc_signed &
1105sc_signed::operator |= (const sc_uint_base &v)
1106{
1107    return operator |= ((uint64)v);
1108}
1109
1110
1111sc_signed
1112operator ^ (const sc_signed &u, const sc_uint_base &v)
1113{
1114    return operator ^ (u, (uint64)v);
1115}
1116
1117sc_signed
1118operator ^ (const sc_uint_base &u, const sc_signed &v)
1119{
1120    return operator ^ ((uint64)u, v);
1121}
1122
1123const sc_signed &
1124sc_signed::operator ^= (const sc_uint_base &v)
1125{
1126    return operator ^= ((uint64)v);
1127}
1128
1129
1130sc_signed
1131operator << (const sc_signed &u, const sc_uint_base &v)
1132{
1133    return operator << (u, (uint64)v);
1134}
1135
1136const sc_signed &
1137sc_signed::operator <<= (const sc_uint_base &v)
1138{
1139    return operator <<= ((uint64)v);
1140}
1141
1142
1143sc_signed
1144operator >> (const sc_signed& u, const sc_uint_base& v)
1145{
1146    return operator >> (u, (uint64)v);
1147}
1148
1149const sc_signed &
1150sc_signed::operator >>= (const sc_uint_base& v)
1151{
1152    return operator >>= ((uint64)v);
1153}
1154
1155
1156bool
1157operator == (const sc_signed &u, const sc_uint_base &v)
1158{
1159    return operator == (u, (uint64)v);
1160}
1161
1162bool
1163operator == (const sc_uint_base &u, const sc_signed &v)
1164{
1165    return operator == ((uint64)u, v);
1166}
1167
1168
1169bool
1170operator != (const sc_signed &u, const sc_uint_base &v)
1171{
1172    return operator != (u, (uint64)v);
1173}
1174
1175bool
1176operator != (const sc_uint_base &u, const sc_signed &v)
1177{
1178    return operator != ((uint64)u, v);
1179}
1180
1181
1182bool
1183operator < (const sc_signed &u, const sc_uint_base &v)
1184{
1185    return operator < (u, (uint64)v);
1186}
1187
1188bool
1189operator < (const sc_uint_base &u, const sc_signed &v)
1190{
1191    return operator < ((uint64)u, v);
1192}
1193
1194
1195bool
1196operator <= (const sc_signed &u, const sc_uint_base &v)
1197{
1198    return operator <= (u, (uint64)v);
1199}
1200
1201bool
1202operator <= (const sc_uint_base &u, const sc_signed &v)
1203{
1204    return operator <= ((uint64)u, v);
1205}
1206
1207
1208bool
1209operator > (const sc_signed &u, const sc_uint_base &v)
1210{
1211    return operator > (u, (uint64)v);
1212}
1213
1214bool
1215operator > (const sc_uint_base &u, const sc_signed &v)
1216{
1217    return operator > ((uint64)u, v);
1218}
1219
1220
1221bool
1222operator >= (const sc_signed &u, const sc_uint_base &v)
1223{
1224    return operator >= (u, (uint64)v);
1225}
1226
1227bool
1228operator >= (const sc_uint_base &u, const sc_signed &v)
1229{
1230    return operator >= ((uint64)u, v);
1231}
1232
1233
1234// ----------------------------------------------------------------------------
1235//  SECTION: Input and output operators
1236// ----------------------------------------------------------------------------
1237
1238// Operators in this section are included from sc_nbcommon.cpp.
1239
1240
1241// ----------------------------------------------------------------------------
1242//  SECTION: Operator macros.
1243// ----------------------------------------------------------------------------
1244
1245#define CONVERT_LONG(u) \
1246small_type u ## s = get_sign(u); \
1247sc_digit u ## d[DIGITS_PER_ULONG]; \
1248from_uint(DIGITS_PER_ULONG, u ## d, (unsigned long) u);
1249
1250#define CONVERT_LONG_2(u) \
1251sc_digit u ## d[DIGITS_PER_ULONG]; \
1252from_uint(DIGITS_PER_ULONG, u ## d, (unsigned long) u);
1253
1254#define CONVERT_INT(u) \
1255small_type u ## s = get_sign(u); \
1256sc_digit u ## d[DIGITS_PER_UINT]; \
1257from_uint(DIGITS_PER_UINT, u ## d, (unsigned int) u);
1258
1259#define CONVERT_INT_2(u) \
1260sc_digit u ## d[DIGITS_PER_UINT]; \
1261from_uint(DIGITS_PER_UINT, u ## d, (unsigned int) u);
1262
1263#define CONVERT_INT64(u) \
1264small_type u ## s = get_sign(u); \
1265sc_digit u ## d[DIGITS_PER_UINT64]; \
1266from_uint(DIGITS_PER_UINT64, u ## d, (uint64) u);
1267
1268#define CONVERT_INT64_2(u) \
1269sc_digit u ## d[DIGITS_PER_UINT64]; \
1270from_uint(DIGITS_PER_UINT64, u ## d, (uint64) u);
1271
1272
1273// ----------------------------------------------------------------------------
1274//  SECTION: PLUS operators: +, +=, ++
1275// ----------------------------------------------------------------------------
1276
1277// Cases to consider when computing u + v:
1278// 1. 0 + v = v
1279// 2. u + 0 = u
1280// 3. if sgn(u) == sgn(v)
1281//    3.1 u + v = +(u + v) = sgn(u) * (u + v)
1282//    3.2 (-u) + (-v) = -(u + v) = sgn(u) * (u + v)
1283// 4. if sgn(u) != sgn(v)
1284//    4.1 u + (-v) = u - v = sgn(u) * (u - v)
1285//    4.2 (-u) + v = -(u - v) ==> sgn(u) * (u - v)
1286//
1287// Specialization of above cases for computing ++u or u++:
1288// 1. 0 + 1 = 1
1289// 3. u + 1 = u + 1 = sgn(u) * (u + 1)
1290// 4. (-u) + 1 = -(u - 1) = sgn(u) * (u - 1)
1291
1292sc_signed
1293operator + (const sc_unsigned &u, const sc_signed &v)
1294{
1295    if (u.sgn == SC_ZERO) // case 1
1296        return sc_signed(v);
1297
1298    if (v.sgn == SC_ZERO) // case 2
1299        return sc_signed(u);
1300
1301    // cases 3 and 4
1302    return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1303                             v.sgn, v.nbits, v.ndigits, v.digit);
1304}
1305
1306
1307sc_signed
1308operator + (const sc_signed &u, const sc_unsigned &v)
1309{
1310    if (u.sgn == SC_ZERO) // case 1
1311        return sc_signed(v);
1312
1313    if (v.sgn == SC_ZERO) // case 2
1314        return sc_signed(u);
1315
1316    // cases 3 and 4
1317    return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1318                             v.sgn, v.nbits, v.ndigits, v.digit);
1319}
1320
1321
1322sc_signed
1323operator + (const sc_signed &u, const sc_signed &v)
1324{
1325    if (u.sgn == SC_ZERO) // case 1
1326        return sc_signed(v);
1327
1328    if (v.sgn == SC_ZERO) // case 2
1329        return sc_signed(u);
1330
1331    // cases 3 and 4
1332    return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1333                             v.sgn, v.nbits, v.ndigits, v.digit);
1334}
1335
1336
1337sc_signed
1338operator + (const sc_signed &u, int64 v)
1339{
1340    if (v == 0) // case 2
1341        return sc_signed(u);
1342
1343    CONVERT_INT64(v);
1344
1345    if (u.sgn == SC_ZERO) // case 1
1346        return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
1347
1348    // cases 3 and 4
1349    return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1350                             vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
1351}
1352
1353
1354sc_signed
1355operator + (int64 u, const sc_signed &v)
1356{
1357    if (u == 0) // case 1
1358        return sc_signed(v);
1359
1360    CONVERT_INT64(u);
1361
1362    if (v.sgn == SC_ZERO) // case 2
1363        return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
1364
1365    // cases 3 and 4
1366    return add_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
1367                             v.sgn, v.nbits, v.ndigits, v.digit);
1368}
1369
1370
1371sc_signed
1372operator + (const sc_unsigned &u, int64 v)
1373{
1374    if (v == 0) // case 2
1375        return sc_signed(u);
1376
1377    CONVERT_INT64(v);
1378
1379    if (u.sgn == SC_ZERO) // case 1
1380        return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
1381
1382    // cases 3 and 4
1383    return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1384                             vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
1385}
1386
1387
1388sc_signed
1389operator + (int64 u, const sc_unsigned &v)
1390{
1391    if (u == 0) // case 1
1392        return sc_signed(v);
1393
1394    CONVERT_INT64(u);
1395
1396    if (v.sgn == SC_ZERO) // case 2
1397        return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
1398
1399    // cases 3 and 4
1400    return add_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
1401                             v.sgn, v.nbits, v.ndigits, v.digit);
1402}
1403
1404
1405sc_signed
1406operator + (const sc_signed &u, uint64 v)
1407{
1408    if (v == 0) // case 2
1409        return sc_signed(u);
1410
1411    CONVERT_INT64(v);
1412
1413    if (u.sgn == SC_ZERO) // case 1
1414        return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
1415
1416    // cases 3 and 4
1417    return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1418                             vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
1419}
1420
1421
1422sc_signed
1423operator + (uint64 u, const sc_signed &v)
1424{
1425    if (u == 0) // case 1
1426        return sc_signed(v);
1427
1428    CONVERT_INT64(u);
1429
1430    if (v.sgn == SC_ZERO) // case 2
1431        return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
1432
1433    // cases 3 and 4
1434    return add_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
1435                             v.sgn, v.nbits, v.ndigits, v.digit);
1436}
1437
1438
1439sc_signed
1440operator + (const sc_signed &u, long v)
1441{
1442    if (v == 0) // case 2
1443        return sc_signed(u);
1444
1445    CONVERT_LONG(v);
1446
1447    if (u.sgn == SC_ZERO) // case 1
1448        return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
1449
1450    // cases 3 and 4
1451    return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1452                             vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
1453}
1454
1455
1456sc_signed
1457operator + (long u, const sc_signed &v)
1458{
1459    if (u == 0) // case 1
1460        return sc_signed(v);
1461
1462    CONVERT_LONG(u);
1463
1464    if (v.sgn == SC_ZERO) // case 2
1465        return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
1466
1467    // cases 3 and 4
1468    return add_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
1469                             v.sgn, v.nbits, v.ndigits, v.digit);
1470}
1471
1472
1473sc_signed
1474operator + (const sc_unsigned &u, long v)
1475{
1476    if (v == 0) // case 2
1477        return sc_signed(u);
1478
1479    CONVERT_LONG(v);
1480
1481    if (u.sgn == SC_ZERO) // case 1
1482        return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
1483
1484    // cases 3 and 4
1485    return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1486                             vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
1487}
1488
1489
1490sc_signed
1491operator + (long u, const sc_unsigned &v)
1492{
1493    if (u == 0) // case 1
1494        return sc_signed(v);
1495
1496    CONVERT_LONG(u);
1497
1498    if (v.sgn == SC_ZERO) // case 2
1499        return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
1500
1501    // cases 3 and 4
1502    return add_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
1503                             v.sgn, v.nbits, v.ndigits, v.digit);
1504}
1505
1506
1507sc_signed
1508operator + (const sc_signed &u, unsigned long v)
1509{
1510    if (v == 0) // case 2
1511        return sc_signed(u);
1512
1513    CONVERT_LONG(v);
1514
1515    if (u.sgn == SC_ZERO) // case 1
1516        return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
1517
1518    // cases 3 and 4
1519    return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1520                             vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
1521}
1522
1523
1524sc_signed
1525operator + (unsigned long u, const sc_signed &v)
1526{
1527    if (u == 0) // case 1
1528        return sc_signed(v);
1529
1530    CONVERT_LONG(u);
1531
1532    if (v.sgn == SC_ZERO)  // case 2
1533        return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
1534
1535    // cases 3 and 4
1536    return add_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
1537                             v.sgn, v.nbits, v.ndigits, v.digit);
1538}
1539
1540// The rest of the operators in this section are included from
1541// sc_nbcommon.cpp.
1542
1543// ----------------------------------------------------------------------------
1544//  SECTION: MINUS operators: -, -=, --
1545// ----------------------------------------------------------------------------
1546
1547// Cases to consider when computing u + v:
1548// 1. u - 0 = u
1549// 2. 0 - v = -v
1550// 3. if sgn(u) != sgn(v)
1551//    3.1 u - (-v) = u + v = sgn(u) * (u + v)
1552//    3.2 (-u) - v = -(u + v) ==> sgn(u) * (u + v)
1553// 4. if sgn(u) == sgn(v)
1554//    4.1 u - v = +(u - v) = sgn(u) * (u - v)
1555//    4.2 (-u) - (-v) = -(u - v) = sgn(u) * (u - v)
1556//
1557// Specialization of above cases for computing --u or u--:
1558// 1. 0 - 1 = -1
1559// 3. (-u) - 1 = -(u + 1) = sgn(u) * (u + 1)
1560// 4. u - 1 = u - 1 = sgn(u) * (u - 1)
1561
1562sc_signed
1563operator - (const sc_unsigned &u, const sc_unsigned &v)
1564{
1565    if (v.sgn == SC_ZERO)  // case 1
1566        return sc_signed(u);
1567
1568    if (u.sgn == SC_ZERO) // case 2
1569        return sc_signed(v, -v.sgn);
1570
1571    // cases 3 and 4
1572    return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1573                             -v.sgn, v.nbits, v.ndigits, v.digit);
1574}
1575
1576
1577sc_signed
1578operator - (const sc_unsigned &u, const sc_signed &v)
1579{
1580    if (v.sgn == SC_ZERO) // case 1
1581        return sc_signed(u);
1582
1583    if (u.sgn == SC_ZERO) // case 2
1584        return sc_signed(v, -v.sgn);
1585
1586    // cases 3 and 4
1587    return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1588                             -v.sgn, v.nbits, v.ndigits, v.digit);
1589}
1590
1591
1592sc_signed
1593operator - (const sc_signed &u, const sc_unsigned &v)
1594{
1595    if (v.sgn == SC_ZERO) // case 1
1596        return sc_signed(u);
1597
1598    if (u.sgn == SC_ZERO) // case 2
1599        return sc_signed(v, -v.sgn);
1600
1601    // cases 3 and 4
1602    return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1603                             -v.sgn, v.nbits, v.ndigits, v.digit);
1604}
1605
1606
1607sc_signed
1608operator - (const sc_signed &u, const sc_signed &v)
1609{
1610    if (v.sgn == SC_ZERO)  // case 1
1611        return sc_signed(u);
1612
1613    if (u.sgn == SC_ZERO) // case 2
1614        return sc_signed(v, -v.sgn);
1615
1616    // cases 3 and 4
1617    return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1618                             -v.sgn, v.nbits, v.ndigits, v.digit);
1619}
1620
1621
1622sc_signed
1623operator - (const sc_signed &u, int64 v)
1624{
1625    if (v == 0) // case 1
1626        return sc_signed(u);
1627
1628    CONVERT_INT64(v);
1629
1630    if (u.sgn == SC_ZERO) // case 2
1631        return sc_signed(-vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
1632
1633    // cases 3 and 4
1634    return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1635                             -vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
1636}
1637
1638
1639sc_signed
1640operator - (int64 u, const sc_signed &v)
1641{
1642    if (u == 0) // case 1
1643        return sc_signed(v, -v.sgn);
1644
1645    CONVERT_INT64(u);
1646
1647    if (v.sgn == SC_ZERO) // case 2
1648        return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
1649
1650    // cases 3 and 4
1651    return add_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
1652                             -v.sgn, v.nbits, v.ndigits, v.digit);
1653}
1654
1655
1656sc_signed
1657operator - (const sc_unsigned &u, int64 v)
1658{
1659    if (v == 0) // case 1
1660        return sc_signed(u);
1661
1662    CONVERT_INT64(v);
1663
1664    if (u.sgn == SC_ZERO) // case 2
1665        return sc_signed(-vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
1666
1667    // cases 3 and 4
1668    return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1669                             -vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
1670}
1671
1672
1673sc_signed
1674operator - (int64 u, const sc_unsigned &v)
1675{
1676    if (u == 0) // case 1
1677        return sc_signed(v, -v.sgn);
1678
1679    CONVERT_INT64(u);
1680
1681    if (v.sgn == SC_ZERO) // case 2
1682        return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
1683
1684    // cases 3 and 4
1685    return add_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
1686                             -v.sgn, v.nbits, v.ndigits, v.digit);
1687}
1688
1689
1690sc_signed
1691operator - (const sc_signed &u, uint64 v)
1692{
1693    if (v == 0) // case 1
1694        return sc_signed(u);
1695
1696    CONVERT_INT64(v);
1697
1698    if (u.sgn == SC_ZERO) // case 2
1699        return sc_signed(-vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
1700
1701    // cases 3 and 4
1702
1703    return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1704                             -vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
1705}
1706
1707
1708sc_signed
1709operator - (uint64 u, const sc_signed &v)
1710{
1711    if (u == 0) // case 1
1712        return sc_signed(v, -v.sgn);
1713
1714    CONVERT_INT64(u);
1715
1716    if (v.sgn == SC_ZERO) // case 2
1717        return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
1718
1719    // cases 3 and 4
1720    return add_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
1721                             -v.sgn, v.nbits, v.ndigits, v.digit);
1722}
1723
1724
1725sc_signed
1726operator - (const sc_unsigned &u, uint64 v)
1727{
1728    if (v == 0) // case 1
1729        return sc_signed(u);
1730
1731    CONVERT_INT64(v);
1732
1733    if (u.sgn == SC_ZERO) // case 2
1734        return sc_signed(-vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
1735
1736    // cases 3 and 4
1737    return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1738                             -vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
1739}
1740
1741
1742sc_signed
1743operator - (uint64 u, const sc_unsigned &v)
1744{
1745    if (u == 0) // case 1
1746        return sc_signed(v, -v.sgn);
1747
1748    CONVERT_INT64(u);
1749
1750    if (v.sgn == SC_ZERO) // case 2
1751        return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
1752
1753    // cases 3 and 4
1754    return add_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
1755                             -v.sgn, v.nbits, v.ndigits, v.digit);
1756}
1757
1758
1759sc_signed
1760operator - (const sc_signed &u, long v)
1761{
1762    if (v == 0) // case 1
1763        return sc_signed(u);
1764
1765    CONVERT_LONG(v);
1766
1767    if (u.sgn == SC_ZERO) // case 2
1768        return sc_signed(-vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
1769
1770    // cases 3 and 4
1771    return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1772                             -vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
1773}
1774
1775
1776sc_signed
1777operator - (long u, const sc_signed &v)
1778{
1779    if (u == 0) // case 1
1780        return sc_signed(v, -v.sgn);
1781
1782    CONVERT_LONG(u);
1783
1784    if (v.sgn == SC_ZERO) // case 2
1785        return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
1786
1787    // cases 3 and 4
1788    return add_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
1789                             -v.sgn, v.nbits, v.ndigits, v.digit);
1790}
1791
1792
1793sc_signed
1794operator - (const sc_unsigned &u, long v)
1795{
1796    if (v == 0) // case 1
1797        return sc_signed(u);
1798
1799    CONVERT_LONG(v);
1800
1801    if (u.sgn == SC_ZERO) // case 2
1802        return sc_signed(-vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
1803
1804    // cases 3 and 4
1805    return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1806                             -vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
1807}
1808
1809
1810sc_signed
1811operator - (long u, const sc_unsigned &v)
1812{
1813    if (u == 0) // case 1
1814        return sc_signed(v, -v.sgn);
1815
1816    CONVERT_LONG(u);
1817
1818    if (v.sgn == SC_ZERO) // case 2
1819        return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
1820
1821    // cases 3 and 4
1822    return add_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
1823                             -v.sgn, v.nbits, v.ndigits, v.digit);
1824}
1825
1826
1827sc_signed
1828operator - (const sc_signed &u, unsigned long v)
1829{
1830    if (v == 0) // case 1
1831        return sc_signed(u);
1832
1833    CONVERT_LONG(v);
1834
1835    if (u.sgn == SC_ZERO) // case 2
1836        return sc_signed(-vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
1837
1838    // cases 3 and 4
1839    return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1840                             -vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
1841}
1842
1843
1844sc_signed
1845operator - (unsigned long u, const sc_signed &v)
1846{
1847    if (u == 0) // case 1
1848        return sc_signed(v, -v.sgn);
1849
1850    CONVERT_LONG(u);
1851
1852    if (v.sgn == SC_ZERO) // case 2
1853        return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
1854
1855    // cases 3 and 4
1856    return add_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
1857                             -v.sgn, v.nbits, v.ndigits, v.digit);
1858}
1859
1860
1861sc_signed
1862operator - (const sc_unsigned &u, unsigned long v)
1863{
1864    if (v == 0) // case 1
1865        return sc_signed(u);
1866
1867    CONVERT_LONG(v);
1868
1869    if (u.sgn == SC_ZERO) // case 2
1870        return sc_signed(-vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
1871
1872    // cases 3 and 4
1873    return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1874                             -vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
1875}
1876
1877
1878sc_signed
1879operator - (unsigned long u, const sc_unsigned &v)
1880{
1881    if (u == 0) // case 1
1882        return sc_signed(v, -v.sgn);
1883
1884    CONVERT_LONG(u);
1885
1886    if (v.sgn == SC_ZERO) // case 2
1887        return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
1888
1889    // cases 3 and 4
1890    return add_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
1891                             -v.sgn, v.nbits, v.ndigits, v.digit);
1892}
1893
1894// The rest of the operators in this section are included from
1895// sc_nbcommon.cpp.
1896
1897
1898// ----------------------------------------------------------------------------
1899//  SECTION: MULTIPLICATION operators: *, *=
1900// ----------------------------------------------------------------------------
1901
1902// Cases to consider when computing u * v:
1903// 1. u * 0 = 0 * v = 0
1904// 2. 1 * v = v and -1 * v = -v
1905// 3. u * 1 = u and u * -1 = -u
1906// 4. u * v = u * v
1907
1908sc_signed
1909operator * (const sc_unsigned &u, const sc_signed &v)
1910{
1911    small_type s = mul_signs(u.sgn, v.sgn);
1912
1913    if (s == SC_ZERO) // case 1
1914        return sc_signed();
1915
1916    // cases 2-4
1917    return mul_signed_friend(s, u.nbits, u.ndigits, u.digit,
1918                             v.nbits, v.ndigits, v.digit);
1919}
1920
1921
1922sc_signed
1923operator * (const sc_signed &u, const sc_unsigned &v)
1924{
1925    small_type s = mul_signs(u.sgn, v.sgn);
1926
1927    if (s == SC_ZERO) // case 1
1928        return sc_signed();
1929
1930    // cases 2-4
1931    return mul_signed_friend(s, u.nbits, u.ndigits, u.digit,
1932                             v.nbits, v.ndigits, v.digit);
1933}
1934
1935
1936sc_signed
1937operator * (const sc_signed &u, const sc_signed &v)
1938{
1939    small_type s = mul_signs(u.sgn, v.sgn);
1940
1941    if (s == SC_ZERO) // case 1
1942        return sc_signed();
1943
1944    // cases 2-4
1945    return mul_signed_friend(s, u.nbits, u.ndigits, u.digit,
1946                             v.nbits, v.ndigits, v.digit);
1947}
1948
1949
1950sc_signed
1951operator * (const sc_signed &u, int64 v)
1952{
1953    small_type s = mul_signs(u.sgn, get_sign(v));
1954
1955    if (s == SC_ZERO) // case 1
1956        return sc_signed();
1957
1958    CONVERT_INT64_2(v);
1959
1960    // cases 2-4
1961    return mul_signed_friend(s, u.nbits, u.ndigits, u.digit,
1962                             BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
1963}
1964
1965
1966sc_signed
1967operator * (int64 u, const sc_signed &v)
1968{
1969    small_type s = mul_signs(v.sgn, get_sign(u));
1970
1971    if (s == SC_ZERO) // case 1
1972        return sc_signed();
1973
1974    CONVERT_INT64_2(u);
1975
1976    // cases 2-4
1977    return mul_signed_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
1978                             v.nbits, v.ndigits, v.digit);
1979}
1980
1981
1982sc_signed
1983operator * (const sc_unsigned &u, int64 v)
1984{
1985    small_type s = mul_signs(u.sgn, get_sign(v));
1986
1987    if (s == SC_ZERO) // case 1
1988        return sc_signed();
1989
1990    CONVERT_INT64_2(v);
1991
1992    // cases 2-4
1993    return mul_signed_friend(s, u.nbits, u.ndigits, u.digit,
1994                             BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
1995}
1996
1997
1998sc_signed
1999operator * (int64 u, const sc_unsigned &v)
2000{
2001    small_type s = mul_signs(v.sgn, get_sign(u));
2002
2003    if (s == SC_ZERO) // case 1
2004        return sc_signed();
2005
2006    CONVERT_INT64_2(u);
2007
2008    // cases 2-4
2009    return mul_signed_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
2010                             v.nbits, v.ndigits, v.digit);
2011}
2012
2013
2014sc_signed
2015operator * (const sc_signed &u, uint64 v)
2016{
2017    small_type s = mul_signs(u.sgn, get_sign(v));
2018
2019    if (s == SC_ZERO) // case 1
2020        return sc_signed();
2021
2022    CONVERT_INT64_2(v);
2023
2024    // cases 2-4
2025    return mul_signed_friend(s, u.nbits, u.ndigits, u.digit,
2026                             BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
2027}
2028
2029
2030sc_signed
2031operator * (uint64 u, const sc_signed &v)
2032{
2033    small_type s = mul_signs(v.sgn, get_sign(u));
2034
2035    if (s == SC_ZERO) // case 1
2036        return sc_signed();
2037
2038    CONVERT_INT64_2(u);
2039
2040    // cases 2-4
2041    return mul_signed_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
2042                             v.nbits, v.ndigits, v.digit);
2043}
2044
2045
2046sc_signed
2047operator * (const sc_signed &u, long v)
2048{
2049    small_type s = mul_signs(u.sgn, get_sign(v));
2050
2051    if (s == SC_ZERO) // case 1
2052        return sc_signed();
2053
2054    CONVERT_LONG_2(v);
2055
2056    // cases 2-4
2057    return mul_signed_friend(s, u.nbits, u.ndigits, u.digit,
2058                             BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
2059}
2060
2061
2062sc_signed
2063operator * (long u, const sc_signed &v)
2064{
2065    small_type s = mul_signs(v.sgn, get_sign(u));
2066
2067    if (s == SC_ZERO) // case 1
2068        return sc_signed();
2069
2070    CONVERT_LONG_2(u);
2071
2072    // cases 2-4
2073    return mul_signed_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
2074                             v.nbits, v.ndigits, v.digit);
2075}
2076
2077
2078sc_signed
2079operator * (const sc_unsigned &u, long v)
2080{
2081    small_type s = mul_signs(u.sgn, get_sign(v));
2082
2083    if (s == SC_ZERO) // case 1
2084        return sc_signed();
2085
2086    CONVERT_LONG_2(v);
2087
2088    // cases 2-4
2089    return mul_signed_friend(s, u.nbits, u.ndigits, u.digit,
2090                             BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
2091}
2092
2093
2094sc_signed
2095operator * (long u, const sc_unsigned &v)
2096{
2097    small_type s = mul_signs(v.sgn, get_sign(u));
2098
2099    if (s == SC_ZERO) // case 1
2100        return sc_signed();
2101
2102    CONVERT_LONG_2(u);
2103
2104    // cases 2-4
2105    return mul_signed_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
2106                             v.nbits, v.ndigits, v.digit);
2107}
2108
2109
2110sc_signed
2111operator * (const sc_signed &u, unsigned long v)
2112{
2113    small_type s = mul_signs(u.sgn, get_sign(v));
2114
2115    if (s == SC_ZERO) // case 1
2116        return sc_signed();
2117
2118    CONVERT_LONG_2(v);
2119
2120    // else cases 2-4
2121    return mul_signed_friend(s, u.nbits, u.ndigits, u.digit,
2122                             BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
2123}
2124
2125sc_signed
2126operator * (unsigned long u, const sc_signed &v)
2127{
2128    small_type s = mul_signs(v.sgn, get_sign(u));
2129
2130    if (s == SC_ZERO) // case 1
2131        return sc_signed();
2132
2133    CONVERT_LONG_2(u);
2134
2135    // cases 2-4
2136    return mul_signed_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
2137                             v.nbits, v.ndigits, v.digit);
2138}
2139
2140// The rest of the operators in this section are included from
2141// sc_nbcommon.cpp.
2142
2143
2144// ----------------------------------------------------------------------------
2145//  SECTION: DIVISION operators: /, /=
2146// ----------------------------------------------------------------------------
2147
2148// Cases to consider when finding the quotient q = floor(u/v):
2149// Note that u = q * v + r for r < q.
2150// 1. 0 / 0 or u / 0 => error
2151// 2. 0 / v => 0 = 0 * v + 0
2152// 3. u / v & &u = v => u = 1 * u + 0  - u or v can be 1 or -1
2153// 4. u / v & &u < v => u = 0 * v + u  - u can be 1 or -1
2154// 5. u / v & &u > v => u = q * v + r  - v can be 1 or -1
2155
2156sc_signed
2157operator / (const sc_unsigned &u, const sc_signed &v)
2158{
2159    small_type s = mul_signs(u.sgn, v.sgn);
2160
2161    if (s == SC_ZERO) {
2162        div_by_zero(v.sgn); // case 1
2163        return sc_signed(); // case 2
2164    }
2165
2166    // other cases
2167    return div_signed_friend(s, u.nbits, u.ndigits, u.digit,
2168                             v.nbits, v.ndigits, v.digit);
2169}
2170
2171
2172sc_signed
2173operator / (const sc_signed &u, const sc_unsigned &v)
2174{
2175    small_type s = mul_signs(u.sgn, v.sgn);
2176
2177    if (s == SC_ZERO) {
2178        div_by_zero(v.sgn); // case 1
2179        return sc_signed(); // case 2
2180    }
2181
2182    // other cases
2183    return div_signed_friend(s, u.nbits, u.ndigits, u.digit,
2184                             v.nbits, v.ndigits, v.digit);
2185}
2186
2187
2188sc_signed
2189operator / (const sc_signed &u, const sc_signed &v)
2190{
2191    small_type s = mul_signs(u.sgn, v.sgn);
2192
2193    if (s == SC_ZERO) {
2194        div_by_zero(v.sgn); // case 1
2195        return sc_signed(); // case 2
2196    }
2197
2198    // other cases
2199    return div_signed_friend(s, u.nbits, u.ndigits, u.digit,
2200                             v.nbits, v.ndigits, v.digit);
2201}
2202
2203
2204sc_signed
2205operator / (const sc_signed &u, int64 v)
2206{
2207    small_type s = mul_signs(u.sgn, get_sign(v));
2208
2209    if (s == SC_ZERO) {
2210        div_by_zero(v); // case 1
2211        return sc_signed(); // case 2
2212    }
2213
2214    CONVERT_INT64_2(v);
2215
2216    // other cases
2217    return div_signed_friend(s, u.nbits, u.ndigits, u.digit,
2218                             BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
2219}
2220
2221
2222sc_signed
2223operator / (int64 u, const sc_signed &v)
2224{
2225    small_type s = mul_signs(v.sgn, get_sign(u));
2226
2227    if (s == SC_ZERO) {
2228        div_by_zero(v.sgn); // case 1
2229        return sc_signed(); // case 2
2230    }
2231
2232    CONVERT_INT64_2(u);
2233
2234    // other cases
2235    return div_signed_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
2236                             v.nbits, v.ndigits, v.digit);
2237}
2238
2239
2240sc_signed
2241operator / (const sc_unsigned &u, int64 v)
2242{
2243    small_type s = mul_signs(u.sgn, get_sign(v));
2244
2245    if (s == SC_ZERO) {
2246        div_by_zero(v); // case 1
2247        return sc_signed(); // case 2
2248    }
2249
2250    CONVERT_INT64_2(v);
2251
2252    // other cases
2253    return div_signed_friend(s, u.nbits, u.ndigits, u.digit,
2254                             BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
2255}
2256
2257
2258sc_signed
2259operator / (int64 u, const sc_unsigned &v)
2260{
2261    small_type s = mul_signs(v.sgn, get_sign(u));
2262
2263    if (s == SC_ZERO) {
2264        div_by_zero(v.sgn); // case 1
2265        return sc_signed(); // case 2
2266    }
2267
2268    CONVERT_INT64_2(u);
2269
2270    // other cases
2271    return div_signed_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
2272                             v.nbits, v.ndigits, v.digit);
2273}
2274
2275
2276sc_signed
2277operator / (const sc_signed &u, uint64 v)
2278{
2279    small_type s = mul_signs(u.sgn, get_sign(v));
2280
2281    if (s == SC_ZERO) {
2282        div_by_zero(v); // case 1
2283        return sc_signed(); // case 2
2284    }
2285
2286    CONVERT_INT64_2(v);
2287
2288    // other cases
2289    return div_signed_friend(s, u.nbits, u.ndigits, u.digit,
2290                             BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
2291}
2292
2293
2294sc_signed
2295operator / (uint64 u, const sc_signed &v)
2296{
2297    small_type s = mul_signs(v.sgn, get_sign(u));
2298
2299    if (s == SC_ZERO) {
2300        div_by_zero(v.sgn); // case 1
2301        return sc_signed(); // case 2
2302
2303    }
2304
2305    CONVERT_INT64_2(u);
2306
2307    // other cases
2308    return div_signed_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
2309                             v.nbits, v.ndigits, v.digit);
2310}
2311
2312
2313sc_signed
2314operator / (const sc_signed &u, long v)
2315{
2316    small_type s = mul_signs(u.sgn, get_sign(v));
2317
2318    if (s == SC_ZERO) {
2319        div_by_zero(v); // case 1
2320        return sc_signed(); // case 2
2321    }
2322
2323    CONVERT_LONG_2(v);
2324
2325    // other cases
2326    return div_signed_friend(s, u.nbits, u.ndigits, u.digit,
2327                             BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
2328}
2329
2330
2331sc_signed
2332operator / (long u, const sc_signed &v)
2333{
2334    small_type s = mul_signs(v.sgn, get_sign(u));
2335
2336    if (s == SC_ZERO) {
2337        div_by_zero(v.sgn); // case 1
2338        return sc_signed(); // case 2
2339    }
2340
2341    CONVERT_LONG_2(u);
2342
2343    // other cases
2344    return div_signed_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
2345                             v.nbits, v.ndigits, v.digit);
2346}
2347
2348
2349sc_signed
2350operator / (const sc_unsigned &u, long v)
2351{
2352    small_type s = mul_signs(u.sgn, get_sign(v));
2353
2354    if (s == SC_ZERO) {
2355        div_by_zero(v); // case 1
2356        return sc_signed(); // case 2
2357    }
2358
2359    CONVERT_LONG_2(v);
2360
2361    // other cases
2362    return div_signed_friend(s, u.nbits, u.ndigits, u.digit,
2363                             BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
2364}
2365
2366
2367sc_signed
2368operator / (long u, const sc_unsigned &v)
2369{
2370    small_type s = mul_signs(v.sgn, get_sign(u));
2371
2372    if (s == SC_ZERO) {
2373        div_by_zero(v.sgn); // case 1
2374        return sc_signed(); // case 2
2375    }
2376
2377    CONVERT_LONG_2(u);
2378
2379    // other cases
2380    return div_signed_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
2381                             v.nbits, v.ndigits, v.digit);
2382}
2383
2384
2385sc_signed
2386operator / (const sc_signed &u, unsigned long v)
2387{
2388    small_type s = mul_signs(u.sgn, get_sign(v));
2389
2390    if (s == SC_ZERO) {
2391        div_by_zero(v); // case 1
2392        return sc_signed(); // case 2
2393    }
2394
2395    CONVERT_LONG_2(v);
2396
2397    // other cases
2398    return div_signed_friend(s, u.nbits, u.ndigits, u.digit,
2399                             BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
2400}
2401
2402
2403sc_signed
2404operator / (unsigned long u, const sc_signed &v)
2405{
2406    small_type s = mul_signs(v.sgn, get_sign(u));
2407
2408    if (s == SC_ZERO) {
2409        div_by_zero(v.sgn); // case 1
2410        return sc_signed(); // case 2
2411
2412    }
2413
2414    CONVERT_LONG_2(u);
2415
2416    // other cases
2417    return div_signed_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
2418                             v.nbits, v.ndigits, v.digit);
2419}
2420
2421// The rest of the operators in this section are included from
2422// sc_nbcommon.cpp.
2423
2424
2425// ----------------------------------------------------------------------------
2426//  SECTION: MOD operators: %, %=.
2427// ----------------------------------------------------------------------------
2428
2429// Cases to consider when finding the remainder r = u % v:
2430// Note that u = q * v + r for r < q.
2431// 1. 0 % 0 or u % 0 => error
2432// 2. 0 % v => 0 = 0 * v + 0
2433// 3. u % v & &u = v => u = 1 * u + 0  - u or v can be 1 or -1
2434// 4. u % v & &u < v => u = 0 * v + u  - u can be 1 or -1
2435// 5. u % v & &u > v => u = q * v + r  - v can be 1 or -1
2436
2437sc_signed
2438operator % (const sc_unsigned &u, const sc_signed &v)
2439{
2440    if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) {
2441        div_by_zero(v.sgn); // case 1
2442        return sc_signed(); // case 2
2443    }
2444
2445    // other cases
2446    return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
2447                             v.nbits, v.ndigits, v.digit);
2448}
2449
2450
2451sc_signed
2452operator % (const sc_signed &u, const sc_unsigned &v)
2453{
2454    if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) {
2455        div_by_zero(v.sgn); // case 1
2456        return sc_signed(); // case 2
2457    }
2458
2459    // other cases
2460    return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
2461                             v.nbits, v.ndigits, v.digit);
2462}
2463
2464
2465sc_signed
2466operator % (const sc_signed &u, const sc_signed &v)
2467{
2468    if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) {
2469        div_by_zero(v.sgn); // case 1
2470        return sc_signed(); // case 2
2471    }
2472
2473    // other cases
2474    return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
2475                             v.nbits, v.ndigits, v.digit);
2476}
2477
2478
2479sc_signed
2480operator % (const sc_signed &u, int64 v)
2481{
2482    small_type vs = get_sign(v);
2483
2484    if ((u.sgn == SC_ZERO) || (vs == SC_ZERO)) {
2485        div_by_zero(v); // case 1
2486        return sc_signed(); // case 2
2487    }
2488
2489    CONVERT_INT64_2(v);
2490
2491    // other cases
2492    return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
2493                             BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
2494}
2495
2496
2497sc_signed
2498operator % (int64 u, const sc_signed &v)
2499{
2500    small_type us = get_sign(u);
2501
2502    if ((us == SC_ZERO) || (v.sgn == SC_ZERO)) {
2503        div_by_zero(v.sgn); // case 1
2504        return sc_signed(); // case 2
2505    }
2506
2507    CONVERT_INT64_2(u);
2508
2509    // other cases
2510    return mod_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
2511                             v.nbits, v.ndigits, v.digit);
2512}
2513
2514
2515sc_signed
2516operator % (const sc_unsigned &u, int64 v)
2517{
2518    small_type vs = get_sign(v);
2519
2520    if ((u.sgn == SC_ZERO) || (vs == SC_ZERO)) {
2521        div_by_zero(v); // case 1
2522        return sc_signed(); // case 2
2523    }
2524
2525    CONVERT_INT64_2(v);
2526
2527    // other cases
2528    return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
2529                             BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
2530}
2531
2532
2533sc_signed
2534operator % (int64 u, const sc_unsigned &v)
2535{
2536    small_type us = get_sign(u);
2537
2538    if ((us == SC_ZERO) || (v.sgn == SC_ZERO)) {
2539        div_by_zero(v.sgn); // case 1
2540        return sc_signed(); // case 2
2541    }
2542
2543    CONVERT_INT64_2(u);
2544
2545    // other cases
2546    return mod_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
2547                             v.nbits, v.ndigits, v.digit);
2548}
2549
2550
2551sc_signed
2552operator % (const sc_signed &u, uint64 v)
2553{
2554    if ((u.sgn == SC_ZERO) || (v == 0)) {
2555        div_by_zero(v); // case 1
2556        return sc_signed(); // case 2
2557    }
2558
2559    CONVERT_INT64_2(v);
2560
2561    // other cases
2562    return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
2563                             BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
2564}
2565
2566
2567sc_signed
2568operator % (uint64 u, const sc_signed &v)
2569{
2570    if ((u == 0) || (v.sgn == SC_ZERO)) {
2571        div_by_zero(v.sgn); // case 1
2572        return sc_signed(); // case 2
2573    }
2574
2575    CONVERT_INT64(u);
2576
2577    // other cases
2578    return mod_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
2579                             v.nbits, v.ndigits, v.digit);
2580}
2581
2582
2583sc_signed
2584operator % (const sc_signed &u, long v)
2585{
2586    small_type vs = get_sign(v);
2587
2588    if ((u.sgn == SC_ZERO) || (vs == SC_ZERO)) {
2589        div_by_zero(v); // case 1
2590        return sc_signed(); // case 2
2591    }
2592
2593    CONVERT_LONG_2(v);
2594
2595    // other cases
2596    return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
2597                             BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
2598}
2599
2600
2601sc_signed
2602operator % (long u, const sc_signed &v)
2603{
2604    small_type us = get_sign(u);
2605
2606    if ((us == SC_ZERO) || (v.sgn == SC_ZERO)) {
2607        div_by_zero(v.sgn); // case 1
2608        return sc_signed(); // case 2
2609    }
2610
2611    CONVERT_LONG_2(u);
2612
2613    // other cases
2614    return mod_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
2615                             v.nbits, v.ndigits, v.digit);
2616}
2617
2618
2619sc_signed
2620operator % (const sc_unsigned &u, long v)
2621{
2622
2623  small_type vs = get_sign(v);
2624
2625  if ((u.sgn == SC_ZERO) || (vs == SC_ZERO)) {
2626    div_by_zero(v); // case 1
2627    return sc_signed(); // case 2
2628  }
2629
2630  CONVERT_LONG_2(v);
2631
2632  // other cases
2633  return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
2634                           BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
2635}
2636
2637
2638sc_signed
2639operator % (long u, const sc_unsigned &v)
2640{
2641    small_type us = get_sign(u);
2642
2643    if ((us == SC_ZERO) || (v.sgn == SC_ZERO)) {
2644        div_by_zero(v.sgn); // case 1
2645        return sc_signed(); // case 2
2646    }
2647
2648    CONVERT_LONG_2(u);
2649
2650    // other cases
2651    return mod_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
2652                             v.nbits, v.ndigits, v.digit);
2653}
2654
2655
2656sc_signed
2657operator % (const sc_signed &u, unsigned long v)
2658{
2659    if ((u.sgn == SC_ZERO) || (v == 0)) {
2660        div_by_zero(v); // case 1
2661        return sc_signed(); // case 2
2662    }
2663
2664    CONVERT_LONG_2(v);
2665
2666    // other cases
2667    return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
2668                             BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
2669}
2670
2671
2672sc_signed
2673operator % (unsigned long u, const sc_signed &v)
2674{
2675    if ((u == 0) || (v.sgn == SC_ZERO)) {
2676        div_by_zero(v.sgn); // case 1
2677        return sc_signed(); // case 2
2678    }
2679
2680    CONVERT_LONG(u);
2681
2682    // other cases
2683    return mod_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
2684                             v.nbits, v.ndigits, v.digit);
2685}
2686
2687// The rest of the operators in this section are included from
2688// sc_nbcommon.cpp.
2689
2690
2691// ----------------------------------------------------------------------------
2692//  SECTION: Bitwise AND operators: &, &=
2693// ----------------------------------------------------------------------------
2694
2695// Cases to consider when computing u  &v:
2696// 1. u & 0 = 0  &v = 0
2697// 2. u  &v => sgn = +
2698// 3. (-u) & (-v) => sgn = -
2699// 4. u & (-v) => sgn = +
2700// 5. (-u)  &v => sgn = +
2701
2702sc_signed
2703operator & (const sc_unsigned &u, const sc_signed &v)
2704{
2705    if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) // case 1
2706        return sc_signed();
2707
2708    // other cases
2709    return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
2710                             v.sgn, v.nbits, v.ndigits, v.digit);
2711}
2712
2713
2714sc_signed
2715operator & (const sc_signed &u, const sc_unsigned &v)
2716{
2717    if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) // case 1
2718        return sc_signed();
2719
2720    // other cases
2721    return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
2722                             v.sgn, v.nbits, v.ndigits, v.digit);
2723}
2724
2725
2726sc_signed
2727operator & (const sc_signed &u, const sc_signed &v)
2728{
2729    if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) // case 1
2730        return sc_signed();
2731
2732    // other cases
2733    return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
2734                             v.sgn, v.nbits, v.ndigits, v.digit);
2735}
2736
2737
2738sc_signed
2739operator & (const sc_signed &u, int64 v)
2740{
2741    if ((u.sgn == SC_ZERO) || (v == 0)) // case 1
2742        return sc_signed();
2743
2744    CONVERT_INT64(v);
2745
2746    // other cases
2747    return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
2748                             vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
2749}
2750
2751
2752sc_signed
2753operator & (int64 u, const sc_signed &v)
2754{
2755    if ((u == 0) || (v.sgn == SC_ZERO)) // case 1
2756        return sc_signed();
2757
2758    CONVERT_INT64(u);
2759
2760    // other cases
2761    return and_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
2762                             v.sgn, v.nbits, v.ndigits, v.digit);
2763}
2764
2765
2766sc_signed
2767operator & (const sc_unsigned &u, int64 v)
2768{
2769    if ((u.sgn == SC_ZERO) || (v == 0)) // case 1
2770        return sc_signed();
2771
2772    CONVERT_INT64(v);
2773
2774    // other cases
2775    return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
2776                             vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
2777}
2778
2779
2780sc_signed
2781operator & (int64 u, const sc_unsigned &v)
2782{
2783    if ((u == 0) || (v.sgn == SC_ZERO)) // case 1
2784        return sc_signed();
2785
2786    CONVERT_INT64(u);
2787
2788    // other cases
2789    return and_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
2790                             v.sgn, v.nbits, v.ndigits, v.digit);
2791}
2792
2793
2794sc_signed
2795operator & (const sc_signed &u, uint64 v)
2796{
2797    if ((u.sgn == SC_ZERO) || (v == 0)) // case 1
2798        return sc_signed();
2799
2800    CONVERT_INT64(v);
2801
2802    // other cases
2803    return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
2804                             vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
2805}
2806
2807
2808sc_signed
2809operator & (uint64 u, const sc_signed &v)
2810{
2811    if ((u == 0) || (v.sgn == SC_ZERO)) // case 1
2812        return sc_signed();
2813
2814    CONVERT_INT64(u);
2815
2816    // other cases
2817    return and_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
2818                             v.sgn, v.nbits, v.ndigits, v.digit);
2819}
2820
2821
2822sc_signed
2823operator & (const sc_signed &u, long v)
2824{
2825    if ((u.sgn == SC_ZERO) || (v == 0)) // case 1
2826        return sc_signed();
2827
2828    CONVERT_LONG(v);
2829
2830    // other cases
2831    return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
2832                             vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
2833}
2834
2835
2836sc_signed
2837operator & (long u, const sc_signed &v)
2838{
2839    if ((u == 0) || (v.sgn == SC_ZERO)) // case 1
2840        return sc_signed();
2841
2842    CONVERT_LONG(u);
2843
2844    // other cases
2845    return and_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
2846                             v.sgn, v.nbits, v.ndigits, v.digit);
2847}
2848
2849
2850sc_signed
2851operator & (const sc_unsigned &u, long v)
2852{
2853    if ((u.sgn == SC_ZERO) || (v == 0)) // case 1
2854        return sc_signed();
2855
2856    CONVERT_LONG(v);
2857
2858    // other cases
2859    return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
2860                             vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
2861}
2862
2863
2864sc_signed
2865operator & (long u, const sc_unsigned &v)
2866{
2867    if ((u == 0) || (v.sgn == SC_ZERO)) // case 1
2868        return sc_signed();
2869
2870    CONVERT_LONG(u);
2871
2872    // other cases
2873    return and_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
2874                             v.sgn, v.nbits, v.ndigits, v.digit);
2875}
2876
2877
2878sc_signed
2879operator & (const sc_signed &u, unsigned long v)
2880{
2881    if ((u.sgn == SC_ZERO) || (v == 0)) // case 1
2882        return sc_signed();
2883
2884    CONVERT_LONG(v);
2885
2886    // other cases
2887    return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
2888                             vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
2889}
2890
2891
2892sc_signed
2893operator & (unsigned long u, const sc_signed &v)
2894{
2895    if ((u == 0) || (v.sgn == SC_ZERO)) // case 1
2896        return sc_signed();
2897
2898    CONVERT_LONG(u);
2899
2900    // other cases
2901    return and_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
2902                             v.sgn, v.nbits, v.ndigits, v.digit);
2903}
2904
2905// The rest of the operators in this section are included from
2906// sc_nbcommon.cpp.
2907
2908
2909// ----------------------------------------------------------------------------
2910//  SECTION: Bitwise OR operators: |, |=
2911// ----------------------------------------------------------------------------
2912
2913// Cases to consider when computing u | v:
2914// 1. u | 0 = u
2915// 2. 0 | v = v
2916// 3. u | v => sgn = +
2917// 4. (-u) | (-v) => sgn = -
2918// 5. u | (-v) => sgn = -
2919// 6. (-u) | v => sgn = -
2920
2921sc_signed
2922operator | (const sc_unsigned &u, const sc_signed &v)
2923{
2924    if (v.sgn == SC_ZERO) // case 1
2925        return sc_signed(u);
2926
2927    if (u.sgn == SC_ZERO) // case 2
2928        return sc_signed(v);
2929
2930    // other cases
2931    return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
2932                            v.sgn, v.nbits, v.ndigits, v.digit);
2933}
2934
2935
2936sc_signed
2937operator | (const sc_signed &u, const sc_unsigned &v)
2938{
2939    if (v.sgn == SC_ZERO) // case 1
2940        return sc_signed(u);
2941
2942    if (u.sgn == SC_ZERO) // case 2
2943        return sc_signed(v);
2944
2945    // other cases
2946    return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
2947                            v.sgn, v.nbits, v.ndigits, v.digit);
2948}
2949
2950
2951sc_signed
2952operator | (const sc_signed &u, const sc_signed &v)
2953{
2954    if (v.sgn == SC_ZERO) // case 1
2955        return sc_signed(u);
2956
2957    if (u.sgn == SC_ZERO) // case 2
2958        return sc_signed(v);
2959
2960    // other cases
2961    return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
2962                            v.sgn, v.nbits, v.ndigits, v.digit);
2963}
2964
2965
2966sc_signed
2967operator | (const sc_signed &u, int64 v)
2968{
2969    if (v == 0) // case 1
2970        return sc_signed(u);
2971
2972    CONVERT_INT64(v);
2973
2974    if (u.sgn == SC_ZERO) // case 2
2975        return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
2976
2977    // other cases
2978    return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
2979                            vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
2980}
2981
2982
2983sc_signed
2984operator | (int64 u, const sc_signed &v)
2985{
2986    if (u == 0)
2987        return sc_signed(v);
2988
2989    CONVERT_INT64(u);
2990
2991    if (v.sgn == SC_ZERO)
2992        return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
2993
2994    // other cases
2995    return or_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
2996                            v.sgn, v.nbits, v.ndigits, v.digit);
2997}
2998
2999
3000sc_signed
3001operator | (const sc_unsigned &u, int64 v)
3002{
3003    if (v == 0) // case 1
3004        return sc_signed(u);
3005
3006    CONVERT_INT64(v);
3007
3008    if (u.sgn == SC_ZERO) // case 2
3009        return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
3010
3011    // other cases
3012    return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
3013                            vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
3014}
3015
3016
3017sc_signed
3018operator | (int64 u, const sc_unsigned &v)
3019{
3020    if (u == 0)
3021        return sc_signed(v);
3022
3023    CONVERT_INT64(u);
3024
3025    if (v.sgn == SC_ZERO)
3026        return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
3027
3028    // other cases
3029    return or_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
3030                            v.sgn, v.nbits, v.ndigits, v.digit);
3031}
3032
3033
3034sc_signed
3035operator | (const sc_signed &u, uint64 v)
3036{
3037    if (v == 0) // case 1
3038        return sc_signed(u);
3039
3040    CONVERT_INT64(v);
3041
3042    if (u.sgn == SC_ZERO) // case 2
3043        return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
3044
3045    // other cases
3046    return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
3047                            vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
3048}
3049
3050
3051sc_signed
3052operator | (uint64 u, const sc_signed &v)
3053{
3054    if (u == 0)
3055        return sc_signed(v);
3056
3057    CONVERT_INT64(u);
3058
3059    if (v.sgn == SC_ZERO)
3060        return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
3061
3062    // other cases
3063    return or_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
3064                            v.sgn, v.nbits, v.ndigits, v.digit);
3065}
3066
3067
3068sc_signed
3069operator | (const sc_signed &u, long v)
3070{
3071    if (v == 0) // case 1
3072        return sc_signed(u);
3073
3074    CONVERT_LONG(v);
3075
3076    if (u.sgn == SC_ZERO) // case 2
3077        return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
3078
3079    // other cases
3080    return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
3081                            vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
3082}
3083
3084
3085sc_signed
3086operator | (long u, const sc_signed &v)
3087{
3088    if (u == 0)
3089        return sc_signed(v);
3090
3091    CONVERT_LONG(u);
3092
3093    if (v.sgn == SC_ZERO)
3094        return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
3095
3096    // other cases
3097    return or_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
3098                            v.sgn, v.nbits, v.ndigits, v.digit);
3099}
3100
3101
3102sc_signed
3103operator | (const sc_unsigned &u, long v)
3104{
3105    if (v == 0) // case 1
3106        return sc_signed(u);
3107
3108    CONVERT_LONG(v);
3109
3110    if (u.sgn == SC_ZERO) // case 2
3111        return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
3112
3113    // other cases
3114    return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
3115                            vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
3116}
3117
3118
3119sc_signed
3120operator | (long u, const sc_unsigned &v)
3121{
3122    if (u == 0)
3123        return sc_signed(v);
3124
3125    CONVERT_LONG(u);
3126
3127    if (v.sgn == SC_ZERO)
3128        return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
3129
3130    // other cases
3131    return or_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
3132                            v.sgn, v.nbits, v.ndigits, v.digit);
3133}
3134
3135
3136sc_signed
3137operator | (const sc_signed &u, unsigned long v)
3138{
3139    if (v == 0) // case 1
3140        return sc_signed(u);
3141
3142    CONVERT_LONG(v);
3143
3144    if (u.sgn == SC_ZERO) // case 2
3145        return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
3146
3147    // other cases
3148    return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
3149                            vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
3150}
3151
3152
3153sc_signed
3154operator | (unsigned long u, const sc_signed &v)
3155{
3156    if (u == 0)
3157        return sc_signed(v);
3158
3159    CONVERT_LONG(u);
3160
3161    if (v.sgn == SC_ZERO)
3162        return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
3163
3164    // other cases
3165    return or_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
3166                            v.sgn, v.nbits, v.ndigits, v.digit);
3167}
3168
3169// The rest of the operators in this section are included from
3170// sc_nbcommon.cpp.
3171
3172
3173// ----------------------------------------------------------------------------
3174//  SECTION: Bitwise XOR operators: ^, ^=
3175// ----------------------------------------------------------------------------
3176
3177// Cases to consider when computing u ^ v:
3178// Note that  u ^ v = (~u  &v) | (u & ~v).
3179// 1. u ^ 0 = u
3180// 2. 0 ^ v = v
3181// 3. u ^ v => sgn = +
3182// 4. (-u) ^ (-v) => sgn = -
3183// 5. u ^ (-v) => sgn = -
3184// 6. (-u) ^ v => sgn = +
3185
3186sc_signed
3187operator ^ (const sc_unsigned &u, const sc_signed &v)
3188{
3189
3190  if (v.sgn == SC_ZERO) // case 1
3191    return sc_signed(u);
3192
3193  if (u.sgn == SC_ZERO) // case 2
3194    return sc_signed(v);
3195
3196  // other cases
3197  return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
3198                           v.sgn, v.nbits, v.ndigits, v.digit);
3199
3200}
3201
3202
3203sc_signed
3204operator ^ (const sc_signed &u, const sc_unsigned &v)
3205{
3206    if (v.sgn == SC_ZERO) // case 1
3207        return sc_signed(u);
3208
3209    if (u.sgn == SC_ZERO) // case 2
3210        return sc_signed(v);
3211
3212    // other cases
3213    return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
3214                             v.sgn, v.nbits, v.ndigits, v.digit);
3215}
3216
3217
3218sc_signed
3219operator ^ (const sc_signed &u, const sc_signed &v)
3220{
3221    if (v.sgn == SC_ZERO) // case 1
3222        return sc_signed(u);
3223
3224    if (u.sgn == SC_ZERO) // case 2
3225        return sc_signed(v);
3226
3227    // other cases
3228    return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
3229                             v.sgn, v.nbits, v.ndigits, v.digit);
3230}
3231
3232
3233sc_signed
3234operator ^ (const sc_signed &u, int64 v)
3235{
3236    if (v == 0) // case 1
3237        return sc_signed(u);
3238
3239    CONVERT_INT64(v);
3240
3241    if (u.sgn == SC_ZERO) // case 2
3242        return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
3243
3244    // other cases
3245    return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
3246                             vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
3247}
3248
3249
3250sc_signed
3251operator ^ (int64 u, const sc_signed &v)
3252{
3253    if (u == 0)
3254        return sc_signed(v);
3255
3256    CONVERT_INT64(u);
3257
3258    if (v.sgn == SC_ZERO)
3259        return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
3260
3261    // other cases
3262    return xor_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
3263                             v.sgn, v.nbits, v.ndigits, v.digit);
3264}
3265
3266
3267sc_signed
3268operator ^ (const sc_unsigned &u, int64 v)
3269{
3270    if (v == 0) // case 1
3271        return sc_signed(u);
3272
3273    CONVERT_INT64(v);
3274
3275    if (u.sgn == SC_ZERO) // case 2
3276        return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
3277
3278    // other cases
3279    return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
3280                             vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
3281}
3282
3283
3284sc_signed
3285operator ^ (int64 u, const sc_unsigned &v)
3286{
3287    if (u == 0)
3288        return sc_signed(v);
3289
3290    CONVERT_INT64(u);
3291
3292    if (v.sgn == SC_ZERO)
3293        return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
3294
3295    // other cases
3296    return xor_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
3297                             v.sgn, v.nbits, v.ndigits, v.digit);
3298}
3299
3300
3301sc_signed
3302operator ^ (const sc_signed &u, uint64 v)
3303{
3304    if (v == 0) // case 1
3305        return sc_signed(u);
3306
3307    CONVERT_INT64(v);
3308
3309    if (u.sgn == SC_ZERO) // case 2
3310        return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
3311
3312    // other cases
3313    return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
3314                             vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
3315}
3316
3317sc_signed
3318operator ^ (uint64 u, const sc_signed &v)
3319{
3320    if (u == 0)
3321        return sc_signed(v);
3322
3323    CONVERT_INT64(u);
3324
3325    if (v.sgn == SC_ZERO)
3326        return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
3327
3328    // other cases
3329    return xor_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
3330                             v.sgn, v.nbits, v.ndigits, v.digit);
3331}
3332
3333
3334sc_signed
3335operator ^ (const sc_signed &u, long v)
3336{
3337    if (v == 0) // case 1
3338        return sc_signed(u);
3339
3340    CONVERT_LONG(v);
3341
3342    if (u.sgn == SC_ZERO) // case 2
3343        return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
3344
3345    // other cases
3346    return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
3347                             vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
3348}
3349
3350
3351sc_signed
3352operator ^ (long u, const sc_signed &v)
3353{
3354    if (u == 0)
3355        return sc_signed(v);
3356
3357    CONVERT_LONG(u);
3358
3359    if (v.sgn == SC_ZERO)
3360        return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
3361
3362    // other cases
3363    return xor_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
3364                             v.sgn, v.nbits, v.ndigits, v.digit);
3365}
3366
3367
3368sc_signed
3369operator ^ (const sc_unsigned &u, long v)
3370{
3371    if (v == 0) // case 1
3372        return sc_signed(u);
3373
3374    CONVERT_LONG(v);
3375
3376    if (u.sgn == SC_ZERO) // case 2
3377        return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
3378
3379    // other cases
3380    return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
3381                             vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
3382}
3383
3384
3385sc_signed
3386operator ^ (long u, const sc_unsigned &v)
3387{
3388    if (u == 0)
3389        return sc_signed(v);
3390
3391    CONVERT_LONG(u);
3392
3393    if (v.sgn == SC_ZERO)
3394        return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
3395
3396    // other cases
3397    return xor_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
3398                             v.sgn, v.nbits, v.ndigits, v.digit);
3399}
3400
3401
3402sc_signed
3403operator ^ (const sc_signed &u, unsigned long v)
3404{
3405    if (v == 0) // case 1
3406        return sc_signed(u);
3407
3408    CONVERT_LONG(v);
3409
3410    if (u.sgn == SC_ZERO) // case 2
3411        return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
3412
3413    // other cases
3414    return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
3415                             vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
3416}
3417
3418sc_signed
3419operator ^ (unsigned long u, const sc_signed &v)
3420{
3421    if (u == 0)
3422        return sc_signed(v);
3423
3424    CONVERT_LONG(u);
3425
3426    if (v.sgn == SC_ZERO)
3427        return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
3428
3429    // other cases
3430    return xor_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
3431                             v.sgn, v.nbits, v.ndigits, v.digit);
3432}
3433
3434// The rest of the operators in this section are included from
3435// sc_nbcommon.cpp.
3436
3437
3438// ----------------------------------------------------------------------------
3439//  SECTION: Bitwise NOT operator: ~
3440// ----------------------------------------------------------------------------
3441
3442// Operators in this section are included from sc_nbcommon.cpp.
3443
3444
3445// ----------------------------------------------------------------------------
3446//  SECTION: LEFT SHIFT operators: <<, <<=
3447// ----------------------------------------------------------------------------
3448
3449sc_signed
3450operator << (const sc_signed &u, const sc_unsigned &v)
3451{
3452    if (v.sgn == SC_ZERO)
3453        return sc_signed(u);
3454
3455    return operator << (u, v.to_ulong());
3456}
3457
3458// The rest of the operators in this section are included from
3459// sc_nbcommon.cpp.
3460
3461
3462// ----------------------------------------------------------------------------
3463//  SECTION: RIGHT SHIFT operators: >>, >>=
3464// ----------------------------------------------------------------------------
3465
3466sc_signed
3467operator >> (const sc_signed &u, const sc_unsigned &v)
3468{
3469    if (v.sgn == SC_ZERO)
3470        return sc_signed(u);
3471
3472    return operator >> (u, v.to_ulong());
3473}
3474
3475// The rest of the operators in this section are included from
3476// sc_nbcommon.cpp.
3477
3478
3479// ----------------------------------------------------------------------------
3480//  SECTION: Unary arithmetic operators.
3481// ----------------------------------------------------------------------------
3482
3483sc_signed
3484operator + (const sc_signed &u)
3485{
3486    return sc_signed(u);
3487}
3488
3489sc_signed
3490operator - (const sc_signed &u)
3491{
3492    return sc_signed(u, -u.sgn);
3493}
3494
3495sc_signed
3496operator - (const sc_unsigned &u)
3497{
3498    return sc_signed(u, -u.sgn);
3499}
3500
3501
3502// ----------------------------------------------------------------------------
3503//    SECTION: EQUAL operator: ==
3504// ----------------------------------------------------------------------------
3505
3506bool
3507operator == (const sc_signed &u, const sc_signed &v)
3508{
3509    if (u.sgn != v.sgn)
3510        return false;
3511
3512    if (&u == &v)
3513        return true;
3514
3515    if (vec_skip_and_cmp(u.ndigits, u.digit, v.ndigits, v.digit) != 0)
3516        return false;
3517
3518    return true;
3519}
3520
3521
3522bool
3523operator == (const sc_signed &u, int64 v)
3524{
3525    CONVERT_INT64(v);
3526
3527    if (u.sgn != vs)
3528        return false;
3529
3530    if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_INT64, vd) != 0)
3531        return false;
3532
3533    return true;
3534}
3535
3536
3537bool
3538operator == (int64 u, const sc_signed &v)
3539{
3540    CONVERT_INT64(u);
3541
3542    if (us != v.sgn)
3543        return false;
3544
3545    if (vec_skip_and_cmp(DIGITS_PER_INT64, ud, v.ndigits, v.digit) != 0)
3546        return false;
3547
3548    return true;
3549}
3550
3551
3552bool
3553operator == (const sc_signed &u, uint64 v)
3554{
3555    CONVERT_INT64(v);
3556
3557    if (u.sgn != vs)
3558        return false;
3559
3560    if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_INT64, vd) != 0)
3561        return false;
3562
3563    return true;
3564}
3565
3566
3567bool
3568operator == (uint64 u, const sc_signed &v)
3569{
3570    CONVERT_INT64(u);
3571
3572    if (us != v.sgn)
3573        return false;
3574
3575    if (vec_skip_and_cmp(DIGITS_PER_INT64, ud, v.ndigits, v.digit) != 0)
3576        return false;
3577
3578    return true;
3579}
3580
3581
3582bool
3583operator == (const sc_signed &u, long v)
3584{
3585    CONVERT_LONG(v);
3586
3587    if (u.sgn != vs)
3588        return false;
3589
3590    if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_LONG, vd) != 0)
3591        return false;
3592
3593    return true;
3594}
3595
3596
3597bool
3598operator == (long u, const sc_signed &v)
3599{
3600    CONVERT_LONG(u);
3601
3602    if (us != v.sgn)
3603        return false;
3604
3605    if (vec_skip_and_cmp(DIGITS_PER_LONG, ud, v.ndigits, v.digit) != 0)
3606        return false;
3607
3608    return true;
3609}
3610
3611
3612bool
3613operator == (const sc_signed &u, unsigned long v)
3614{
3615    CONVERT_LONG(v);
3616
3617    if (u.sgn != vs)
3618        return false;
3619
3620    if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_LONG, vd) != 0)
3621        return false;
3622
3623    return true;
3624}
3625
3626
3627bool
3628operator == (unsigned long u, const sc_signed &v)
3629{
3630    CONVERT_LONG(u);
3631
3632    if (us != v.sgn)
3633        return false;
3634
3635    if (vec_skip_and_cmp(DIGITS_PER_LONG, ud, v.ndigits, v.digit) != 0)
3636        return false;
3637
3638    return true;
3639}
3640
3641
3642// ----------------------------------------------------------------------------
3643//    SECTION: NOT_EQUAL operator: !=
3644// ----------------------------------------------------------------------------
3645
3646// Operators in this section are included from sc_nbcommon.cpp.
3647
3648
3649// ----------------------------------------------------------------------------
3650//    SECTION: LESS THAN operator: <
3651// ----------------------------------------------------------------------------
3652
3653bool
3654operator < (const sc_signed &u, const sc_signed &v)
3655{
3656    if (u.sgn < v.sgn)
3657        return true;
3658
3659    if (u.sgn > v.sgn)
3660        return false;
3661
3662    // u.sgn == v.sgn
3663
3664    if (&u == &v)
3665        return false;
3666
3667    if (u.sgn == SC_POS) {
3668        if (vec_skip_and_cmp(u.ndigits, u.digit, v.ndigits, v.digit) < 0)
3669            return true;
3670    } else if (u.sgn == SC_NEG) {
3671        if (vec_skip_and_cmp(u.ndigits, u.digit, v.ndigits, v.digit) > 0)
3672            return true;
3673    }
3674
3675    return false;
3676}
3677
3678
3679bool
3680operator < (const sc_signed &u, int64 v)
3681{
3682    CONVERT_INT64(v);
3683
3684    if (u.sgn < vs)
3685        return true;
3686
3687    if (u.sgn > vs)
3688        return false;
3689
3690    // u.sgn == vs
3691
3692    if (vs == SC_POS) {
3693        if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_INT64, vd) < 0)
3694            return true;
3695    } else if (vs == SC_NEG) {
3696        if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_INT64, vd) > 0)
3697            return true;
3698    }
3699
3700    return false;
3701}
3702
3703
3704bool
3705operator < (int64 u, const sc_signed &v)
3706{
3707    CONVERT_INT64(u);
3708
3709    if (us < v.sgn)
3710        return true;
3711
3712    if (us > v.sgn)
3713        return false;
3714
3715    // us == v.sgn
3716
3717    if (us == SC_POS) {
3718        if (vec_skip_and_cmp(DIGITS_PER_INT64, ud, v.ndigits, v.digit) < 0)
3719            return true;
3720    } else if (us == SC_NEG) {
3721        if (vec_skip_and_cmp(DIGITS_PER_INT64, ud, v.ndigits, v.digit) > 0)
3722            return true;
3723    }
3724
3725    return false;
3726}
3727
3728
3729bool
3730operator < (const sc_signed &u, uint64 v)
3731{
3732    CONVERT_INT64(v);
3733
3734    if (u.sgn < vs)
3735        return true;
3736
3737    if (u.sgn > vs)
3738        return false;
3739
3740    // u.sgn == vs
3741
3742    if (vs == SC_POS) {
3743        if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_INT64, vd) < 0)
3744            return true;
3745    }
3746
3747    return false;
3748}
3749
3750
3751bool
3752operator < (uint64 u, const sc_signed &v)
3753{
3754    CONVERT_INT64(u);
3755
3756    if (us < v.sgn)
3757        return true;
3758
3759    if (us > v.sgn)
3760        return false;
3761
3762    // us == v.sgn
3763
3764    if (us == SC_POS) {
3765        if (vec_skip_and_cmp(DIGITS_PER_INT64, ud, v.ndigits, v.digit) < 0)
3766            return true;
3767    }
3768
3769    return false;
3770}
3771
3772
3773bool
3774operator < (const sc_signed &u, long v)
3775{
3776    CONVERT_LONG(v);
3777
3778    if (u.sgn < vs)
3779        return true;
3780
3781    if (u.sgn > vs)
3782        return false;
3783
3784    // u.sgn == vs
3785
3786    if (vs == SC_POS) {
3787        if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_LONG, vd) < 0)
3788            return true;
3789
3790    } else if (vs == SC_NEG) {
3791        if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_LONG, vd) > 0)
3792            return true;
3793    }
3794
3795    return false;
3796}
3797
3798
3799bool
3800operator < (long u, const sc_signed &v)
3801{
3802    CONVERT_LONG(u);
3803
3804    if (us < v.sgn)
3805        return true;
3806
3807    if (us > v.sgn)
3808        return false;
3809
3810    // us == v.sgn
3811
3812    if (us == SC_POS) {
3813        if (vec_skip_and_cmp(DIGITS_PER_LONG, ud, v.ndigits, v.digit) < 0)
3814            return true;
3815    } else if (us == SC_NEG) {
3816        if (vec_skip_and_cmp(DIGITS_PER_LONG, ud, v.ndigits, v.digit) > 0)
3817            return true;
3818    }
3819
3820    return false;
3821}
3822
3823
3824bool
3825operator < (const sc_signed &u, unsigned long v)
3826{
3827    CONVERT_LONG(v);
3828
3829    if (u.sgn < vs)
3830        return true;
3831
3832    if (u.sgn > vs)
3833        return false;
3834
3835    // u.sgn == vs
3836
3837    if (vs == SC_POS) {
3838        if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_LONG, vd) < 0)
3839            return true;
3840    }
3841
3842    return false;
3843}
3844
3845
3846bool
3847operator < (unsigned long u, const sc_signed &v)
3848{
3849    CONVERT_LONG(u);
3850
3851    if (us < v.sgn)
3852        return true;
3853
3854    if (us > v.sgn)
3855        return false;
3856
3857    // us == v.sgn
3858
3859    if (us == SC_POS) {
3860        if (vec_skip_and_cmp(DIGITS_PER_LONG, ud, v.ndigits, v.digit) < 0)
3861            return true;
3862    }
3863
3864    return false;
3865}
3866
3867
3868// ---------------------------------------------------------------------------
3869//    SECTION: LESS THAN or EQUAL operator: <=
3870// ---------------------------------------------------------------------------
3871
3872// Operators in this section are included from sc_nbcommon.cpp.
3873
3874
3875// ---------------------------------------------------------------------------
3876//    SECTION: GREATER THAN operator: >
3877// ---------------------------------------------------------------------------
3878
3879// Operators in this section are included from sc_nbcommon.cpp.
3880
3881
3882// ---------------------------------------------------------------------------
3883//    SECTION: GREATER THAN or EQUAL operator: >=
3884// ---------------------------------------------------------------------------
3885
3886// Operators in this section are included from sc_nbcommon.cpp.
3887
3888
3889// ---------------------------------------------------------------------------
3890//    SECTION: Public members - Other utils.
3891// ---------------------------------------------------------------------------
3892
3893bool
3894sc_signed::iszero() const
3895{
3896    if (sgn == SC_ZERO)
3897        return true;
3898    else if (sgn != SC_NOSIGN)
3899        return false;
3900    else
3901        return check_for_zero(ndigits, digit);
3902}
3903
3904
3905bool
3906sc_signed::sign() const
3907{
3908    if (sgn == SC_NEG)
3909        return 1;
3910    else if (sgn != SC_NOSIGN)
3911        return 0;
3912    else
3913        return ((digit[ndigits - 1] & one_and_zeros(bit_ord(nbits - 1))) != 0);
3914}
3915
3916// The rest of the utils in this section are included from sc_nbcommon.cpp.
3917
3918
3919// ----------------------------------------------------------------------------
3920//    SECTION: Private members.
3921// ----------------------------------------------------------------------------
3922
3923// The private members in this section are included from sc_nbcommon.cpp.
3924
3925#define CLASS_TYPE sc_signed
3926#define CLASS_TYPE_STR "sc_signed"
3927
3928#define ADD_HELPER add_signed_friend
3929#define SUB_HELPER sub_signed_friend
3930#define MUL_HELPER mul_signed_friend
3931#define DIV_HELPER div_signed_friend
3932#define MOD_HELPER mod_signed_friend
3933#define AND_HELPER and_signed_friend
3934#define OR_HELPER or_signed_friend
3935#define XOR_HELPER xor_signed_friend
3936
3937#include "sc_nbfriends.inc"
3938
3939#undef SC_UNSIGNED
3940#define SC_SIGNED
3941#define IF_SC_SIGNED 1 // 1 = sc_signed
3942#define CLASS_TYPE_SUBREF sc_signed_subref_r
3943#define OTHER_CLASS_TYPE sc_unsigned
3944#define OTHER_CLASS_TYPE_SUBREF sc_unsigned_subref_r
3945
3946#define MUL_ON_HELPER mul_on_help_signed
3947#define DIV_ON_HELPER div_on_help_signed
3948#define MOD_ON_HELPER mod_on_help_signed
3949
3950#include "sc_nbcommon.inc"
3951
3952#undef MOD_ON_HELPER
3953#undef DIV_ON_HELPER
3954#undef MUL_ON_HELPER
3955
3956#undef OTHER_CLASS_TYPE_SUBREF
3957#undef OTHER_CLASS_TYPE
3958#undef CLASS_TYPE_SUBREF
3959#undef IF_SC_SIGNED
3960#undef SC_SIGNED
3961
3962#undef XOR_HELPER
3963#undef OR_HELPER
3964#undef AND_HELPER
3965#undef MOD_HELPER
3966#undef DIV_HELPER
3967#undef MUL_HELPER
3968#undef SUB_HELPER
3969#undef ADD_HELPER
3970
3971#undef CLASS_TYPE
3972#undef CLASS_TYPE_STR
3973
3974#include "sc_signed_bitref.inc"
3975#include "sc_signed_subref.inc"
3976
3977#undef CONVERT_LONG
3978#undef CONVERT_LONG_2
3979#undef CONVERT_INT64
3980#undef CONVERT_INT64_2
3981
3982} // namespace sc_dt
3983