gem5 v24.0.0.0
Loading...
Searching...
No Matches
sc_unsigned.cc
Go to the documentation of this file.
1/*****************************************************************************
2
3 Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4 more contributor license agreements. See the NOTICE file distributed
5 with this work for additional information regarding copyright ownership.
6 Accellera licenses this file to you under the Apache License, Version 2.0
7 (the "License"); you may not use this file except in compliance with the
8 License. You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15 implied. See the License for the specific language governing
16 permissions and limitations under the License.
17
18 *****************************************************************************/
19
20/*****************************************************************************
21
22 sc_unsigned.cpp -- Arbitrary precision signed arithmetic.
23
24 This file includes the definitions of sc_unsigned_bitref,
25 sc_unsigned_subref, and sc_unsigned classes. The first two classes
26 are proxy classes to reference one bit and a range of bits of a
27 sc_unsigned number, respectively. This file also includes
28 sc_nbcommon.cpp and sc_nbfriends.cpp, which contain the
29 definitions shared by sc_unsigned.
30
31 Original Author: Ali Dasdan, Synopsys, Inc.
32
33 *****************************************************************************/
34
35/*****************************************************************************
36
37 MODIFICATION LOG - modifiers, enter your name, affiliation, date and
38 changes you are making here.
39
40 Name, Affiliation, Date:
41 Description of Modification:
42
43 *****************************************************************************/
44
45
46// $Log: sc_unsigned.cpp,v $
47// Revision 1.7 2011/02/18 20:19:15 acg
48// Andy Goodrich: updating Copyright notice.
49//
50// Revision 1.6 2008/12/10 20:38:45 acg
51// Andy Goodrich: fixed conversion of double values to the digits vector.
52// The bits above the radix were not being masked off.
53//
54// Revision 1.5 2008/06/19 17:47:57 acg
55// Andy Goodrich: fixes for bugs. See 2.2.1 RELEASENOTES.
56//
57// Revision 1.4 2008/06/19 16:57:57 acg
58// Andy Goodrich: added case for negative unsigned values to the support in
59// concate_get_data().
60//
61// Revision 1.3 2007/11/04 21:27:00 acg
62// Andy Goodrich: changes to make sure the proper value is returned from
63// concat_get_data().
64//
65// Revision 1.2 2007/02/22 21:35:05 acg
66// Andy Goodrich: cleaned up comments in concat_get_ctrl and concat_get_data.
67//
68// Revision 1.1.1.1 2006/12/15 20:20:05 acg
69// SystemC 2.3
70//
71// Revision 1.4 2006/08/29 23:36:54 acg
72// Andy Goodrich: fixed and_reduce and optimized or_reduce.
73//
74// Revision 1.3 2006/01/13 18:49:32 acg
75// Added $Log command so that CVS check in comments are reproduced in the
76// source.
77//
78
79#include <cctype>
80#include <cmath>
81#include <sstream>
82
94
95// explicit template instantiations
96namespace sc_core
97{
98
99template class sc_vpool<sc_dt::sc_unsigned_bitref>;
100template class sc_vpool<sc_dt::sc_unsigned_subref>;
101template class sc_vpool<sc_dt::sc_unsigned>;
102
103} // namespace sc_core
104
105namespace sc_dt
106{
107
108// Pool of temporary instances:
109// The sc_unsigned pool is used by the concatenation support.
110// The bit and part reference pools allow references to be returned.
111
112sc_core::sc_vpool<sc_unsigned> sc_unsigned::m_pool(8);
113sc_core::sc_vpool<sc_unsigned_bitref> sc_unsigned_bitref::m_pool(9);
114sc_core::sc_vpool<sc_unsigned_subref> sc_unsigned_subref::m_pool(9);
115
116
117void
118sc_unsigned::invalid_init(const char *type_name, int nb) const
119{
120 std::stringstream msg;
121 msg << "sc_unsigned("<< type_name << ") : nb = " << nb << " is not valid";
123}
124
125
126// ----------------------------------------------------------------------------
127// SECTION: Public members - Invalid selections.
128// ----------------------------------------------------------------------------
129
130void
131sc_unsigned::invalid_index(int i) const
132{
133 std::stringstream msg;
134 msg << "sc_biguint bit selection: index = " << i << " violates "
135 "0 <= index <= " << (nbits-2);
137 sc_core::sc_abort(); // can't recover from here
138}
139
140void
141sc_unsigned::invalid_range(int l, int r) const
142{
143 std::stringstream msg;
144 msg << "sc_biguint part selection: left = " <<
145 l << ", right = " << r << " \n"
146 " violates either (" << (nbits - 2) << " >= left >= 0) or "
147 "(" << (nbits-2) << " >= right >= 0)";
149 sc_core::sc_abort(); // can't recover from here
150}
151
152// ----------------------------------------------------------------------------
153// SECTION: Public members - Concatenation support.
154// ----------------------------------------------------------------------------
155
156// Most public members are included from sc_nbcommon.inc. However, some
157// concatenation support appears here to optimize between the signed and
158// unsigned cases.
159
160
161
162// Insert this object's value at the specified place in a vector of big style
163// values.
164
165bool
166sc_unsigned::concat_get_ctrl(sc_digit *dst_p, int low_i) const
167{
168 int dst_i; // Index to next word to set in dst_p.
169 int end_i; // Index of high order word to set.
170 int left_shift; // Amount to shift value left.
171 sc_digit mask; // Mask for partial word sets.
172
173
174 // CALCULATE METRICS FOR DATA MOVEMENT:
175 dst_i = low_i / BITS_PER_DIGIT;
176 end_i = (low_i + nbits - 2) / BITS_PER_DIGIT;
177 left_shift = low_i % BITS_PER_DIGIT;
178
179 // MOVE FIRST WORD (IT MAY BE PARTIAL) AND THEN ANY OTHERS:
180 //
181 // We may "clobber" upper bits, but they will be written at some point
182 // anyway.
183
184 mask = ~(~0U << left_shift);
185 dst_p[dst_i] = (dst_p[dst_i] & ~mask);
186 dst_i++;
187
188 for (; dst_i <= end_i; dst_i++)
189 dst_p[dst_i] = 0;
190
191 return false;
192}
193
194bool
195sc_unsigned::concat_get_data(sc_digit *dst_p, int low_i) const
196{
197 sc_digit carry; // Carry for negating value.
198 int dst_i; // Index to next word to set in dst_p.
199 int end_i; // Index of high order word to set.
200 int high_i; // Index w/in word of high order bit.
201 int left_shift; // Amount to shift value left.
202 sc_digit left_word; // High word component for set.
203 sc_digit mask; // Mask for partial word sets.
204 bool result; // True if inserting non-zero data.
205 int right_shift; // Amount to shift value right.
206 sc_digit right_word; // Low word component for set.
207 int real_bits; // nbits - 1.
208 int src_i; // Index to next word to get from digit.
209
210 // CALCULATE METRICS FOR DATA MOVEMENT:
211 real_bits = nbits - 1; // Remove that extra sign bit.
212 dst_i = low_i / BITS_PER_DIGIT;
213 high_i = low_i + real_bits - 1;
214 end_i = high_i / BITS_PER_DIGIT;
215 left_shift = low_i % BITS_PER_DIGIT;
216
217 switch (sgn) {
218 // POSITIVE SOURCE VALUE:
219 case SC_POS:
220 result = true;
221
222 // ALL DATA TO BE MOVED IS IN A SINGLE WORD:
223 if (dst_i == end_i) {
224 mask = ~(~0U << left_shift);
225 dst_p[dst_i] = ((dst_p[dst_i] & mask) |
226 (digit[0] << left_shift)) & DIGIT_MASK;
227
228 // DATA IS IN MORE THAN ONE WORD, BUT IS WORD ALIGNED:
229 } else if (left_shift == 0) {
230 for (src_i = 0; dst_i < end_i; dst_i++, src_i++) {
231 dst_p[dst_i] = digit[src_i];
232 }
233 high_i = high_i % BITS_PER_DIGIT;
234 mask = ~(~1U << high_i) & DIGIT_MASK;
235 dst_p[dst_i] = digit[src_i] & mask;
236
237 // DATA IS IN MORE THAN ONE WORD, AND NOT WORD ALIGNED:
238 } else {
239 high_i = high_i % BITS_PER_DIGIT;
240 right_shift = BITS_PER_DIGIT - left_shift;
241 mask = ~(~0U << left_shift);
242 right_word = digit[0];
243 dst_p[dst_i] = (dst_p[dst_i] & mask) |
244 ((right_word << left_shift) & DIGIT_MASK);
245 for (src_i = 1, dst_i++; dst_i < end_i; dst_i++, src_i++) {
246 left_word = digit[src_i];
247 dst_p[dst_i] = ((left_word << left_shift) & DIGIT_MASK) |
248 (right_word >> right_shift);
249 right_word = left_word;
250 }
251 left_word = (src_i < ndigits) ? digit[src_i] : 0;
252 mask = ~(~1U << high_i) & DIGIT_MASK;
253 dst_p[dst_i] = ((left_word << left_shift) |
254 (right_word >> right_shift)) & mask;
255 }
256 break;
257
258 // SOURCE VALUE IS NEGATIVE:
259 case SC_NEG:
260 // ALL DATA TO BE MOVED IS IN A SINGLE WORD:
261 result = true;
262 if (dst_i == end_i) {
263 mask = ~(~0U << nbits);
264 right_word = ((digit[0] ^ DIGIT_MASK) + 1) & mask;
265 mask = ~(~0U << left_shift);
266 dst_p[dst_i] = ((dst_p[dst_i] & mask) |
267 (right_word << left_shift)) & DIGIT_MASK;
268
269 // DATA IS IN MORE THAN ONE WORD, BUT IS WORD ALIGNED:
270
271 } else if (left_shift == 0) {
272 carry = 1;
273 for (src_i = 0; dst_i < end_i; dst_i++, src_i++) {
274 right_word = (digit[src_i] ^ DIGIT_MASK) + carry;
275 dst_p[dst_i] = right_word & DIGIT_MASK;
276 carry = right_word >> BITS_PER_DIGIT;
277 }
278 high_i = high_i % BITS_PER_DIGIT;
279 mask = (~(~1U << high_i)) & DIGIT_MASK;
280 right_word = (src_i < ndigits) ?
281 (digit[src_i] ^ DIGIT_MASK) + carry : DIGIT_MASK + carry;
282 dst_p[dst_i] = right_word & mask;
283
284 // DATA IS IN MORE THAN ONE WORD, AND NOT WORD ALIGNED:
285 } else {
286 high_i = high_i % BITS_PER_DIGIT;
287 right_shift = BITS_PER_DIGIT - left_shift;
288 mask = ~(~0U << left_shift);
289 carry = 1;
290 right_word = (digit[0] ^ DIGIT_MASK) + carry;
291 dst_p[dst_i] = (dst_p[dst_i] & mask) |
292 ((right_word << left_shift) & DIGIT_MASK);
293 carry = right_word >> BITS_PER_DIGIT;
294 right_word &= DIGIT_MASK;
295 for (src_i = 1, dst_i++; dst_i < end_i; dst_i++, src_i++) {
296 left_word = (digit[src_i] ^ DIGIT_MASK) + carry;
297 dst_p[dst_i] = ((left_word << left_shift)&DIGIT_MASK) |
298 (right_word >> right_shift);
299 carry = left_word >> BITS_PER_DIGIT;
300 right_word = left_word & DIGIT_MASK;
301 }
302 left_word = (src_i < ndigits) ?
303 (digit[src_i] ^ DIGIT_MASK) + carry : carry;
304 mask = ~(~1U << high_i) & DIGIT_MASK;
305 dst_p[dst_i] = ((left_word << left_shift) |
306 (right_word >> right_shift)) & mask;
307 }
308 break;
309 // VALUE IS ZERO:
310 default:
311 result = false;
312 // ALL DATA TO BE MOVED IS IN A SINGLE WORD:
313 if (dst_i == end_i) {
314 mask = ~(~0U << real_bits) << left_shift;
315 dst_p[dst_i] = dst_p[dst_i] & ~mask;
316
317 // DATA IS IN MORE THAN ONE WORD, BUT IS WORD ALIGNED:
318
319 } else if (left_shift == 0) {
320 for (src_i = 0; dst_i < end_i; dst_i++, src_i++) {
321 dst_p[dst_i] = 0;
322 }
323 dst_p[dst_i] = 0;
324
325 // DATA IS IN MORE THAN ONE WORD, AND NOT WORD ALIGNED:
326 } else {
327 mask = ~(~0U << left_shift);
328 dst_p[dst_i] = (dst_p[dst_i] & mask);
329 for (dst_i++; dst_i <= end_i; dst_i++) {
330 dst_p[dst_i] = 0;
331 }
332 }
333 break;
334 }
335 return result;
336}
337
338// Return this object instance's bits as a uint64 without sign extension.
339uint64
340sc_unsigned::concat_get_uint64() const
341{
342 uint64 result;
343
344 switch (sgn) {
345 case SC_POS:
346 result = 0;
347 if (ndigits > 2)
348 result = digit[2];
349 if (ndigits > 1)
350 result = (result << BITS_PER_DIGIT) | digit[1];
351 result = (result << BITS_PER_DIGIT) | digit[0];
352 break;
353 default:
354 result = 0;
355 break;
356 }
357 return result;
358}
359
360// #### OPTIMIZE
361void
362sc_unsigned::concat_set(int64 src, int low_i)
363{
364 *this = (low_i < 64) ? src >> low_i : src >> 63;
365}
366
367void
368sc_unsigned::concat_set(const sc_signed &src, int low_i)
369{
370 if (low_i < src.length())
371 *this = src >> low_i;
372 else
373 *this = (src < 0) ? (int_type)-1 : 0;
374}
375
376void
377sc_unsigned::concat_set(const sc_unsigned &src, int low_i)
378{
379 if (low_i < src.length())
380 *this = src >> low_i;
381 else
382 *this = 0;
383}
384
385void
386sc_unsigned::concat_set(uint64 src, int low_i)
387{
388 *this = (low_i < 64) ? src >> low_i : 0;
389}
390
391
392// ----------------------------------------------------------------------------
393// SECTION: Public members - Reduction methods.
394// ----------------------------------------------------------------------------
395
396bool
397sc_unsigned::and_reduce() const
398{
399 int i; // Digit examining.
400
401 if (sgn == SC_ZERO)
402 return false;
403 for (i = 0; i < ndigits - 1; i++)
404 if ((digit[i] & DIGIT_MASK) != DIGIT_MASK)
405 return false;
406 if ((digit[i] & ~(~0U << ((nbits - 1) % BITS_PER_DIGIT))) ==
407 static_cast<sc_digit>(~(~0U << ((nbits - 1) % BITS_PER_DIGIT)))) {
408 return true;
409 }
410 return false;
411}
412
413bool
414sc_unsigned::or_reduce() const
415{
416 return (sgn == SC_ZERO) ? false : true;
417}
418
419bool
420sc_unsigned::xor_reduce() const
421{
422 int i; // Digit examining.
423 int odd; // Flag for odd number of digits.
424
425 odd = 0;
426 for (i = 0; i < nbits - 1; i++)
427 if (test(i))
428 odd = ~odd;
429 return odd ? true : false;
430}
431
432
433// ----------------------------------------------------------------------------
434// SECTION: Public members - Assignment operators.
435// ----------------------------------------------------------------------------
436
437// assignment operators
438const sc_unsigned &
439sc_unsigned::operator = (const char *a)
440{
441 if (a == 0) {
443 "character string is zero");
444 } else if (*a == 0) {
446 "character string is empty");
447 } else try {
448 int len = length();
449 sc_ufix aa(a, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
450 return this->operator = (aa);
451 } catch(const sc_core::sc_report &) {
452 std::stringstream msg;
453 msg << "character string '" << a << "' is not valid";
455 }
456 return *this;
457}
458
459const sc_unsigned &
460sc_unsigned::operator = (int64 v)
461{
462 sgn = get_sign(v);
463 if (sgn == SC_ZERO) {
464 vec_zero(ndigits, digit);
465 } else {
466 from_uint(ndigits, digit, (uint64) v);
467 convert_SM_to_2C_to_SM();
468 }
469 return *this;
470}
471
472const sc_unsigned &
473sc_unsigned::operator = (uint64 v)
474{
475 if (v == 0) {
476 sgn = SC_ZERO;
477 vec_zero(ndigits, digit);
478 } else {
479 sgn = SC_POS;
480 from_uint(ndigits, digit, v);
481 convert_SM_to_2C_to_SM();
482 }
483 return *this;
484}
485
486const sc_unsigned &
487sc_unsigned::operator = (long v)
488{
489 sgn = get_sign(v);
490 if (sgn == SC_ZERO) {
491 vec_zero(ndigits, digit);
492 } else {
493 from_uint(ndigits, digit, (unsigned long)v);
494 convert_SM_to_2C_to_SM();
495 }
496 return *this;
497}
498
499const sc_unsigned &
500sc_unsigned::operator = (unsigned long v)
501{
502 if (v == 0) {
503 sgn = SC_ZERO;
504 vec_zero(ndigits, digit);
505 } else {
506 sgn = SC_POS;
507 from_uint(ndigits, digit, v);
508 convert_SM_to_2C_to_SM();
509 }
510 return *this;
511}
512
513const sc_unsigned &
514sc_unsigned::operator = (double v)
515{
516 is_bad_double(v);
517 sgn = SC_POS;
518 int i = 0;
519 while (std::floor(v) && (i < ndigits)) {
520 digit[i++] = ((sc_digit)std::floor(remainder(v, DIGIT_RADIX))) &
522 v /= DIGIT_RADIX;
523 }
524 vec_zero(i, ndigits, digit);
525 convert_SM_to_2C_to_SM();
526 return *this;
527}
528
529
530// ----------------------------------------------------------------------------
531
532const sc_unsigned &
533sc_unsigned::operator = (const sc_bv_base &v)
534{
535 int minlen = sc_min(nbits, v.length());
536 int i = 0;
537 for (; i < minlen; ++i) {
538 safe_set(i, v.get_bit(i), digit);
539 }
540 for (; i < nbits; ++i) {
541 safe_set(i, 0, digit); // zero-extend
542 }
543 convert_2C_to_SM();
544 return *this;
545}
546
547const sc_unsigned &
548sc_unsigned::operator = (const sc_lv_base &v)
549{
550 int minlen = sc_min(nbits, v.length());
551 int i = 0;
552 for (; i < minlen; ++i) {
553 safe_set(i, sc_logic(v.get_bit(i)).to_bool(), digit);
554 }
555 for (; i < nbits; ++i) {
556 safe_set(i, 0, digit); // zero-extend
557 }
558 convert_2C_to_SM();
559 return *this;
560}
561
562
563// explicit conversion to character string
564const std::string
565sc_unsigned::to_string(sc_numrep numrep) const
566{
567 int len = length();
568 sc_ufix aa(*this, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
569 return aa.to_string(numrep);
570}
571
572const std::string
573sc_unsigned::to_string(sc_numrep numrep, bool w_prefix) const
574{
575 int len = length();
576 sc_ufix aa(*this, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
577 return aa.to_string(numrep, w_prefix);
578}
579
580
581// ----------------------------------------------------------------------------
582// SECTION: Interfacing with sc_int_base
583// ----------------------------------------------------------------------------
584
585const sc_unsigned &
586sc_unsigned::operator = (const sc_int_base &v)
587{
588 return operator = ((int64)v);
589}
590
591const sc_unsigned &
592sc_unsigned::operator += (const sc_int_base &v)
593{
594 return operator += ((int64)v);
595}
596
597const sc_unsigned &
598sc_unsigned::operator -= (const sc_int_base &v)
599{
600 return operator -= ((int64)v);
601}
602
603const sc_unsigned &
604sc_unsigned::operator *= (const sc_int_base &v)
605{
606 return operator *= ((int64)v);
607}
608
609const sc_unsigned &
610sc_unsigned::operator /= (const sc_int_base &v)
611{
612 return operator /= ((int64)v);
613}
614
615const sc_unsigned &
616sc_unsigned::operator %= (const sc_int_base &v)
617{
618 return operator %= ((int64)v);
619}
620
621const sc_unsigned &
622sc_unsigned::operator &= (const sc_int_base &v)
623{
624 return operator &= ((int64)v);
625}
626
627const sc_unsigned &
628sc_unsigned::operator |= (const sc_int_base &v)
629{
630 return operator |= ((int64)v);
631}
632
633const sc_unsigned &
634sc_unsigned::operator ^= (const sc_int_base &v)
635{
636 return operator ^= ((int64)v);
637}
638
640operator << (const sc_unsigned &u, const sc_int_base &v)
641{
642 return operator << (u, (int64)v);
643}
645sc_unsigned::operator <<= (const sc_int_base &v)
646{
647 return operator <<= ((int64)v);
648}
649
651operator >> (const sc_unsigned& u, const sc_int_base& v)
652{
653 return operator >> (u, (int64)v);
654}
655const sc_unsigned &
656sc_unsigned::operator >>= (const sc_int_base& v)
657{
658 return operator >>= ((int64)v);
659}
660
661bool
663{
664 return operator == (u, (int64)v);
665}
666bool
668{
669 return operator == ((int64)u, v);
670}
671
672bool
673operator != (const sc_unsigned &u, const sc_int_base &v)
674{
675 return operator != (u, (int64)v);
676}
677bool
678operator != (const sc_int_base &u, const sc_unsigned &v)
679{
680 return operator != ((int64)u, v);
681}
682
683bool
684operator < (const sc_unsigned &u, const sc_int_base &v)
685{
686 return operator < (u, (int64)v);
687}
688bool
689operator < (const sc_int_base &u, const sc_unsigned &v)
690{
691 return operator < ((int64)u, v);
692}
693
694bool
695operator <= (const sc_unsigned &u, const sc_int_base &v)
696{
697 return operator <= (u, (int64)v);
698}
699bool
700operator <= (const sc_int_base &u, const sc_unsigned &v)
701{
702 return operator <= ((int64)u, v);
703}
704
705bool
706operator > (const sc_unsigned &u, const sc_int_base &v)
707{
708 return operator > (u, (int64)v);
709}
710bool
711operator > (const sc_int_base &u, const sc_unsigned &v)
712{
713 return operator > ((int64)u, v);
714}
715
716bool
717operator >= (const sc_unsigned &u, const sc_int_base &v)
718{
719 return operator >= (u, (int64)v);
720}
721bool
722operator >= (const sc_int_base &u, const sc_unsigned &v)
723{
724 return operator >= ((int64)u, v);
725}
726
727
728// ----------------------------------------------------------------------------
729// SECTION: Interfacing with sc_uint_base
730// ----------------------------------------------------------------------------
731
732const sc_unsigned &
733sc_unsigned::operator = (const sc_uint_base &v)
734{
735 return operator = ((uint64)v);
736}
737
739operator + (const sc_unsigned &u, const sc_uint_base &v)
740{
741 return operator + (u, (uint64)v);
742}
744operator + (const sc_uint_base &u, const sc_unsigned &v)
745{
746 return operator + ((uint64)u, v);
747}
748const sc_unsigned &
749sc_unsigned::operator += (const sc_uint_base &v)
750{
751 return operator += ((uint64)v);
752}
753
754const sc_unsigned &
755sc_unsigned::operator -= (const sc_uint_base &v)
756{
757 return operator -= ((uint64)v);
758}
759
761operator * (const sc_unsigned &u, const sc_uint_base &v)
762{
763 return operator * (u, (uint64)v);
764}
766operator * (const sc_uint_base &u, const sc_unsigned &v)
767{
768 return operator * ((uint64)u, v);
769}
770const sc_unsigned &
771sc_unsigned::operator *= (const sc_uint_base &v)
772{
773 return operator *= ((uint64)v);
774}
775
777operator / (const sc_unsigned &u, const sc_uint_base &v)
778{
779 return operator / (u, (uint64)v);
780}
782operator / (const sc_uint_base &u, const sc_unsigned &v)
783{
784 return operator / ((uint64)u, v);
785}
786const sc_unsigned &
787sc_unsigned::operator /= (const sc_uint_base &v)
788{
789 return operator /= ((uint64)v);
790}
791
793operator % (const sc_unsigned &u, const sc_uint_base &v)
794{
795 return operator % (u, (uint64)v);
796}
798operator % (const sc_uint_base &u, const sc_unsigned &v)
799{
800 return operator % ((uint64)u, v);
801}
802const sc_unsigned &
803sc_unsigned::operator %= (const sc_uint_base &v)
804{
805 return operator %= ((uint64)v);
806}
807
809operator & (const sc_unsigned &u, const sc_uint_base &v)
810{
811 return operator & (u, (uint64)v);
812}
814operator & (const sc_uint_base &u, const sc_unsigned &v)
815{
816 return operator & ((uint64)u, v);
817}
818const sc_unsigned &
819sc_unsigned::operator &= (const sc_uint_base &v)
820{
821 return operator &= ((uint64)v);
822}
823
825operator | (const sc_unsigned &u, const sc_uint_base &v)
826{
827 return operator | (u, (uint64)v);
828}
830operator | (const sc_uint_base &u, const sc_unsigned &v)
831{
832 return operator | ((uint64)u, v);
833}
834const sc_unsigned &
835sc_unsigned::operator |= (const sc_uint_base &v)
836{
837 return operator |= ((uint64)v);
838}
839
841operator ^ (const sc_unsigned &u, const sc_uint_base &v)
842{
843 return operator ^ (u, (uint64)v);
844}
846operator ^ (const sc_uint_base &u, const sc_unsigned &v)
847{
848 return operator ^ ((uint64)u, v);
849}
850const sc_unsigned &
851sc_unsigned::operator ^= (const sc_uint_base &v)
852{
853 return operator ^= ((uint64)v);
854}
855
857operator << (const sc_unsigned &u, const sc_uint_base &v)
858{
859 return operator << (u, (uint64)v);
860}
862sc_unsigned::operator <<= (const sc_uint_base &v)
863{
864 return operator <<= ((uint64)v);
865}
866
868operator >> (const sc_unsigned &u, const sc_uint_base &v)
869{
870 return operator >> (u, (uint64)v);
871}
872const sc_unsigned &
873sc_unsigned::operator >>= (const sc_uint_base &v)
874{
875 return operator >>= ((uint64)v);
876}
877
878bool
880{
881 return operator == (u, (uint64)v);
882}
883bool
885{
886 return operator == ((uint64)u, v);
887}
888
889bool
890operator != (const sc_unsigned &u, const sc_uint_base &v)
891{
892 return operator != (u, (uint64)v);
893}
894bool
895operator != (const sc_uint_base &u, const sc_unsigned &v)
896{
897 return operator != ((uint64)u, v);
898}
899
900bool
901operator < (const sc_unsigned &u, const sc_uint_base &v)
902{
903 return operator < (u, (uint64)v);
904}
905bool
906operator < (const sc_uint_base &u, const sc_unsigned &v)
907{
908 return operator < ((uint64)u, v);
909}
910
911bool
912operator <= (const sc_unsigned &u, const sc_uint_base &v)
913{
914 return operator <= (u, (uint64)v);
915}
916bool
917operator <= (const sc_uint_base &u, const sc_unsigned &v)
918{
919 return operator <= ((uint64)u, v);
920}
921
922bool
923operator > (const sc_unsigned &u, const sc_uint_base &v)
924{
925 return operator > (u, (uint64)v);
926}
927bool
928operator > (const sc_uint_base &u, const sc_unsigned &v)
929{
930 return operator > ((uint64)u, v);
931}
932
933bool
934operator >= (const sc_unsigned &u, const sc_uint_base &v)
935{
936 return operator >= (u, (uint64)v);
937}
938bool
939operator >= (const sc_uint_base &u, const sc_unsigned &v)
940{
941 return operator >= ((uint64)u, v);
942}
943
944
945// ----------------------------------------------------------------------------
946// SECTION: Input and output operators
947// ----------------------------------------------------------------------------
948
949// The operators in this section are included from sc_nbcommon.cpp.
950
951
952// ----------------------------------------------------------------------------
953// SECTION: Operator macros.
954// ----------------------------------------------------------------------------
955
956#define CONVERT_LONG(u) \
957small_type u ## s = get_sign(u); \
958sc_digit u ## d[DIGITS_PER_ULONG]; \
959from_uint(DIGITS_PER_ULONG, u ## d, (unsigned long) u);
960
961#define CONVERT_LONG_2(u) \
962sc_digit u ## d[DIGITS_PER_ULONG]; \
963from_uint(DIGITS_PER_ULONG, u ## d, (unsigned long) u);
964
965#define CONVERT_INT(u) \
966small_type u ## s = get_sign(u); \
967sc_digit u ## d[DIGITS_PER_UINT]; \
968from_uint(DIGITS_PER_UINT, u ## d, (unsigned int) u);
969
970#define CONVERT_INT_2(u) \
971sc_digit u ## d[DIGITS_PER_UINT]; \
972from_uint(DIGITS_PER_UINT, u ## d, (unsigned int) u);
973
974#define CONVERT_INT64(u) \
975small_type u ## s = get_sign(u); \
976sc_digit u ## d[DIGITS_PER_UINT64]; \
977from_uint(DIGITS_PER_UINT64, u ## d, (uint64) u);
978
979#define CONVERT_INT64_2(u) \
980sc_digit u ## d[DIGITS_PER_UINT64]; \
981from_uint(DIGITS_PER_UINT64, u ## d, (uint64) u);
982
983
984// ----------------------------------------------------------------------------
985// SECTION: PLUS operators: +, +=, ++
986// ----------------------------------------------------------------------------
987
988// Cases to consider when computing u + v:
989// 1. 0 + v = v
990// 2. u + 0 = u
991// 3. if sgn(u) == sgn(v)
992// 3.1 u + v = +(u + v) = sgn(u) * (u + v)
993// 3.2 (-u) + (-v) = -(u + v) = sgn(u) * (u + v)
994// 4. if sgn(u) != sgn(v)
995// 4.1 u + (-v) = u - v = sgn(u) * (u - v)
996// 4.2 (-u) + v = -(u - v) ==> sgn(u) * (u - v)
997//
998// Specialization of above cases for computing ++u or u++:
999// 1. 0 + 1 = 1
1000// 3. u + 1 = u + 1 = sgn(u) * (u + 1)
1001// 4. (-u) + 1 = -(u - 1) = sgn(u) * (u - 1)
1002
1003sc_unsigned
1004operator + (const sc_unsigned &u, const sc_unsigned &v)
1005{
1006 if (u.sgn == SC_ZERO) // case 1
1007 return sc_unsigned(v);
1008
1009 if (v.sgn == SC_ZERO) // case 2
1010 return sc_unsigned(u);
1011
1012 // cases 3 and 4
1013 return add_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1014 v.sgn, v.nbits, v.ndigits, v.digit);
1015}
1016
1017
1019operator + (const sc_unsigned &u, uint64 v)
1020{
1021 if (v == 0) // case 2
1022 return sc_unsigned(u);
1023
1024 CONVERT_INT64(v);
1025
1026 if (u.sgn == SC_ZERO) // case 1
1027 return sc_unsigned(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
1028
1029 // cases 3 and 4
1030 return add_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1032}
1033
1034
1036operator + (uint64 u, const sc_unsigned &v)
1037{
1038 if (u == 0) // case 1
1039 return sc_unsigned(v);
1040
1041 CONVERT_INT64(u);
1042
1043 if (v.sgn == SC_ZERO) // case 2
1044 return sc_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
1045
1046 // cases 3 and 4
1048 v.sgn, v.nbits, v.ndigits, v.digit);
1049}
1050
1051
1053operator + (const sc_unsigned &u, unsigned long v)
1054{
1055 if (v == 0) // case 2
1056 return sc_unsigned(u);
1057
1058 CONVERT_LONG(v);
1059
1060 if (u.sgn == SC_ZERO) // case 1
1061 return sc_unsigned(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
1062
1063 // cases 3 and 4
1064 return add_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1066}
1067
1068
1070operator + (unsigned long u, const sc_unsigned &v)
1071{
1072 if (u == 0) // case 1
1073 return sc_unsigned(v);
1074
1075 CONVERT_LONG(u);
1076
1077 if (v.sgn == SC_ZERO) // case 2
1078 return sc_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
1079
1080 // cases 3 and 4
1082 v.sgn, v.nbits, v.ndigits, v.digit);
1083}
1084
1085// The rest of the operators in this section are included from
1086// sc_nbcommon.cpp.
1087
1088
1089// ----------------------------------------------------------------------------
1090// SECTION: MINUS operators: -, -=, --
1091// ----------------------------------------------------------------------------
1092
1093// Cases to consider when computing u + v:
1094// 1. u - 0 = u
1095// 2. 0 - v = -v
1096// 3. if sgn(u) != sgn(v)
1097// 3.1 u - (-v) = u + v = sgn(u) * (u + v)
1098// 3.2 (-u) - v = -(u + v) ==> sgn(u) * (u + v)
1099// 4. if sgn(u) == sgn(v)
1100// 4.1 u - v = +(u - v) = sgn(u) * (u - v)
1101// 4.2 (-u) - (-v) = -(u - v) = sgn(u) * (u - v)
1102//
1103// Specialization of above cases for computing --u or u--:
1104// 1. 0 - 1 = -1
1105// 3. (-u) - 1 = -(u + 1) = sgn(u) * (u + 1)
1106// 4. u - 1 = u - 1 = sgn(u) * (u - 1)
1107
1108// The operators in this section are included from sc_nbcommon.cpp.
1109
1110
1111// ----------------------------------------------------------------------------
1112// SECTION: MULTIPLICATION operators: *, *=
1113// ----------------------------------------------------------------------------
1114
1115// Cases to consider when computing u * v:
1116// 1. u * 0 = 0 * v = 0
1117// 2. 1 * v = v and -1 * v = -v
1118// 3. u * 1 = u and u * -1 = -u
1119// 4. u * v = u * v
1120
1122operator * (const sc_unsigned &u, const sc_unsigned &v)
1123{
1124 small_type s = mul_signs(u.sgn, v.sgn);
1125
1126 if (s == SC_ZERO) // case 1
1127 return sc_unsigned();
1128
1129 // cases 2-4
1130 return mul_unsigned_friend(s, u.nbits, u.ndigits, u.digit,
1131 v.nbits, v.ndigits, v.digit);
1132}
1133
1134
1136operator * (const sc_unsigned &u, uint64 v)
1137{
1138 small_type s = mul_signs(u.sgn, get_sign(v));
1139
1140 if (s == SC_ZERO) // case 1
1141 return sc_unsigned();
1142
1143 CONVERT_INT64_2(v);
1144
1145 // cases 2-4
1146 return mul_unsigned_friend(s, u.nbits, u.ndigits, u.digit,
1148}
1149
1150
1152operator * (uint64 u, const sc_unsigned &v)
1153{
1154 small_type s = mul_signs(v.sgn, get_sign(u));
1155
1156 if (s == SC_ZERO) // case 1
1157 return sc_unsigned();
1158
1159 CONVERT_INT64_2(u);
1160
1161 // cases 2-4
1163 v.nbits, v.ndigits, v.digit);
1164}
1165
1166
1168operator * (const sc_unsigned &u, unsigned long v)
1169{
1170 small_type s = mul_signs(u.sgn, get_sign(v));
1171
1172 if (s == SC_ZERO) // case 1
1173 return sc_unsigned();
1174
1175 CONVERT_LONG_2(v);
1176
1177 // else cases 2-4
1178 return mul_unsigned_friend(s, u.nbits, u.ndigits, u.digit,
1180}
1181
1183operator * (unsigned long u, const sc_unsigned &v)
1184{
1185 small_type s = mul_signs(v.sgn, get_sign(u));
1186
1187 if (s == SC_ZERO) // case 1
1188 return sc_unsigned();
1189
1190 CONVERT_LONG_2(u);
1191
1192 // cases 2-4
1194 v.nbits, v.ndigits, v.digit);
1195}
1196
1197// The rest of the operators in this section are included from
1198// sc_nbcommon.cpp.
1199
1200
1201// ----------------------------------------------------------------------------
1202// SECTION: DIVISION operators: /, /=
1203// ----------------------------------------------------------------------------
1204
1205// Cases to consider when finding the quotient q = floor(u/v):
1206// Note that u = q * v + r for r < q.
1207// 1. 0 / 0 or u / 0 => error
1208// 2. 0 / v => 0 = 0 * v + 0
1209// 3. u / v & &u = v => u = 1 * u + 0 - u or v can be 1 or -1
1210// 4. u / v & &u < v => u = 0 * v + u - u can be 1 or -1
1211// 5. u / v & &u > v => u = q * v + r - v can be 1 or -1
1212
1214operator / (const sc_unsigned &u, const sc_unsigned &v)
1215{
1216 small_type s = mul_signs(u.sgn, v.sgn);
1217
1218 if (s == SC_ZERO) {
1219 div_by_zero(v.sgn); // case 1
1220 return sc_unsigned(); // case 2
1221 }
1222
1223 // other cases
1224 return div_unsigned_friend(s, u.nbits, u.ndigits, u.digit,
1225 v.nbits, v.ndigits, v.digit);
1226}
1227
1228
1230operator / (const sc_unsigned &u, uint64 v)
1231{
1232 small_type s = mul_signs(u.sgn, get_sign(v));
1233
1234 if (s == SC_ZERO) {
1235 div_by_zero(v); // case 1
1236 return sc_unsigned(); // case 2
1237 }
1238
1239 CONVERT_INT64_2(v);
1240
1241 // other cases
1242 return div_unsigned_friend(s, u.nbits, u.ndigits, u.digit,
1244}
1245
1246
1248operator / (uint64 u, const sc_unsigned &v)
1249{
1250 small_type s = mul_signs(v.sgn, get_sign(u));
1251
1252 if (s == SC_ZERO) {
1253 div_by_zero(v.sgn); // case 1
1254 return sc_unsigned(); // case 2
1255
1256 }
1257
1258 CONVERT_INT64_2(u);
1259
1260 // other cases
1262 v.nbits, v.ndigits, v.digit);
1263}
1264
1265
1267operator / (const sc_unsigned &u, unsigned long v)
1268{
1269 small_type s = mul_signs(u.sgn, get_sign(v));
1270
1271 if (s == SC_ZERO) {
1272 div_by_zero(v); // case 1
1273 return sc_unsigned(); // case 2
1274 }
1275
1276 CONVERT_LONG_2(v);
1277
1278 // other cases
1279 return div_unsigned_friend(s, u.nbits, u.ndigits, u.digit,
1281}
1282
1283
1285operator / (unsigned long u, const sc_unsigned &v)
1286{
1287 small_type s = mul_signs(v.sgn, get_sign(u));
1288
1289 if (s == SC_ZERO) {
1290 div_by_zero(v.sgn); // case 1
1291 return sc_unsigned(); // case 2
1292
1293 }
1294
1295 CONVERT_LONG_2(u);
1296
1297 // other cases
1299 v.nbits, v.ndigits, v.digit);
1300}
1301
1302// The rest of the operators in this section are included from
1303// sc_nbcommon.cpp.
1304
1305
1306// ----------------------------------------------------------------------------
1307// SECTION: MOD operators: %, %=.
1308// ----------------------------------------------------------------------------
1309
1310// Cases to consider when finding the remainder r = u % v:
1311// Note that u = q * v + r for r < q.
1312// 1. 0 % 0 or u % 0 => error
1313// 2. 0 % v => 0 = 0 * v + 0
1314// 3. u % v & &u = v => u = 1 * u + 0 - u or v can be 1 or -1
1315// 4. u % v & &u < v => u = 0 * v + u - u can be 1 or -1
1316// 5. u % v & &u > v => u = q * v + r - v can be 1 or -1
1317
1319operator % (const sc_unsigned &u, const sc_unsigned &v)
1320{
1321 if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) {
1322 div_by_zero(v.sgn); // case 1
1323 return sc_unsigned(); // case 2
1324 }
1325
1326 // other cases
1327 return mod_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1328 v.nbits, v.ndigits, v.digit);
1329}
1330
1331
1333operator % (const sc_unsigned &u, uint64 v)
1334{
1335 if ((u.sgn == SC_ZERO) || (v == 0)) {
1336 div_by_zero(v); // case 1
1337 return sc_unsigned(); // case 2
1338 }
1339
1340 CONVERT_INT64_2(v);
1341
1342 // other cases
1343 return mod_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1345
1346}
1347
1348
1350operator % (uint64 u, const sc_unsigned &v)
1351{
1352 if ((u == 0) || (v.sgn == SC_ZERO)) {
1353 div_by_zero(v.sgn); // case 1
1354 return sc_unsigned(); // case 2
1355 }
1356
1357 CONVERT_INT64(u);
1358
1359 // other cases
1361 v.nbits, v.ndigits, v.digit);
1362}
1363
1364
1366operator % (const sc_unsigned &u, unsigned long v)
1367{
1368 if ((u.sgn == SC_ZERO) || (v == 0)) {
1369 div_by_zero(v); // case 1
1370 return sc_unsigned(); // case 2
1371 }
1372
1373 CONVERT_LONG_2(v);
1374
1375 // other cases
1376 return mod_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1378}
1379
1380
1382operator % (unsigned long u, const sc_unsigned &v)
1383{
1384 if ((u == 0) || (v.sgn == SC_ZERO)) {
1385 div_by_zero(v.sgn); // case 1
1386 return sc_unsigned(); // case 2
1387 }
1388
1389 CONVERT_LONG(u);
1390
1391 // other cases
1393 v.nbits, v.ndigits, v.digit);
1394}
1395
1396// The rest of the operators in this section are included from
1397// sc_nbcommon.cpp.
1398
1399
1400// ----------------------------------------------------------------------------
1401// SECTION: Bitwise AND operators: &, &=
1402// ----------------------------------------------------------------------------
1403
1404// Cases to consider when computing u &v:
1405// 1. u & 0 = 0 &v = 0
1406// 2. u &v => sgn = +
1407// 3. (-u) & (-v) => sgn = -
1408// 4. u & (-v) => sgn = +
1409// 5. (-u) &v => sgn = +
1410
1412operator & (const sc_unsigned &u, const sc_unsigned &v)
1413{
1414 if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) // case 1
1415 return sc_unsigned();
1416
1417 // other cases
1418 return and_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1419 v.sgn, v.nbits, v.ndigits, v.digit);
1420}
1421
1422
1424operator & (const sc_unsigned &u, uint64 v)
1425{
1426 if ((u.sgn == SC_ZERO) || (v == 0)) // case 1
1427 return sc_unsigned();
1428
1429 CONVERT_INT64(v);
1430
1431 // other cases
1432 return and_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1434}
1435
1436
1438operator & (uint64 u, const sc_unsigned &v)
1439{
1440 if ((u == 0) || (v.sgn == SC_ZERO)) // case 1
1441 return sc_unsigned();
1442
1443 CONVERT_INT64(u);
1444
1445 // other cases
1447 v.sgn, v.nbits, v.ndigits, v.digit);
1448}
1449
1450
1452operator & (const sc_unsigned &u, unsigned long v)
1453{
1454 if ((u.sgn == SC_ZERO) || (v == 0)) // case 1
1455 return sc_unsigned();
1456
1457 CONVERT_LONG(v);
1458
1459 // other cases
1460 return and_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1462}
1463
1464
1466operator & (unsigned long u, const sc_unsigned &v)
1467{
1468 if ((u == 0) || (v.sgn == SC_ZERO)) // case 1
1469 return sc_unsigned();
1470
1471 CONVERT_LONG(u);
1472
1473 // other cases
1475 v.sgn, v.nbits, v.ndigits, v.digit);
1476}
1477
1478// The rest of the operators in this section are included from
1479// sc_nbcommon.cpp.
1480
1481
1482// ----------------------------------------------------------------------------
1483// SECTION: Bitwise OR operators: |, |=
1484// ----------------------------------------------------------------------------
1485
1486// Cases to consider when computing u | v:
1487// 1. u | 0 = u
1488// 2. 0 | v = v
1489// 3. u | v => sgn = +
1490// 4. (-u) | (-v) => sgn = -
1491// 5. u | (-v) => sgn = -
1492// 6. (-u) | v => sgn = -
1493
1495operator | (const sc_unsigned &u, const sc_unsigned &v)
1496{
1497 if (v.sgn == SC_ZERO) // case 1
1498 return sc_unsigned(u);
1499
1500 if (u.sgn == SC_ZERO) // case 2
1501 return sc_unsigned(v);
1502
1503 // other cases
1504 return or_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1505 v.sgn, v.nbits, v.ndigits, v.digit);
1506}
1507
1508
1510operator | (const sc_unsigned &u, uint64 v)
1511{
1512 if (v == 0) // case 1
1513 return sc_unsigned(u);
1514
1515 CONVERT_INT64(v);
1516
1517 if (u.sgn == SC_ZERO) // case 2
1518 return sc_unsigned(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
1519
1520 // other cases
1521 return or_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1523}
1524
1525
1527operator | (uint64 u, const sc_unsigned &v)
1528{
1529 if (u == 0)
1530 return sc_unsigned(v);
1531
1532 CONVERT_INT64(u);
1533
1534 if (v.sgn == SC_ZERO)
1535 return sc_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
1536
1537 // other cases
1539 v.sgn, v.nbits, v.ndigits, v.digit);
1540}
1541
1542
1544operator | (const sc_unsigned &u, unsigned long v)
1545{
1546 if (v == 0) // case 1
1547 return sc_unsigned(u);
1548
1549 CONVERT_LONG(v);
1550
1551 if (u.sgn == SC_ZERO) // case 2
1552 return sc_unsigned(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
1553
1554 // other cases
1555 return or_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1557}
1558
1559
1561operator | (unsigned long u, const sc_unsigned &v)
1562{
1563 if (u == 0)
1564 return sc_unsigned(v);
1565
1566 CONVERT_LONG(u);
1567
1568 if (v.sgn == SC_ZERO)
1569 return sc_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
1570
1571 // other cases
1573 v.sgn, v.nbits, v.ndigits, v.digit);
1574}
1575
1576// The rest of the operators in this section are included from
1577// sc_nbcommon.cpp.
1578
1579
1580// ----------------------------------------------------------------------------
1581// SECTION: Bitwise XOR operators: ^, ^=
1582// ----------------------------------------------------------------------------
1583
1584// Cases to consider when computing u ^ v:
1585// Note that u ^ v = (~u &v) | (u & ~v).
1586// 1. u ^ 0 = u
1587// 2. 0 ^ v = v
1588// 3. u ^ v => sgn = +
1589// 4. (-u) ^ (-v) => sgn = -
1590// 5. u ^ (-v) => sgn = -
1591// 6. (-u) ^ v => sgn = +
1592
1594operator ^ (const sc_unsigned &u, const sc_unsigned &v)
1595{
1596 if (v.sgn == SC_ZERO) // case 1
1597 return sc_unsigned(u);
1598
1599 if (u.sgn == SC_ZERO) // case 2
1600 return sc_unsigned(v);
1601
1602 // other cases
1603 return xor_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1604 v.sgn, v.nbits, v.ndigits, v.digit);
1605}
1606
1607
1609operator ^ (const sc_unsigned &u, uint64 v)
1610{
1611 if (v == 0) // case 1
1612 return sc_unsigned(u);
1613
1614 CONVERT_INT64(v);
1615
1616 if (u.sgn == SC_ZERO) // case 2
1617 return sc_unsigned(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
1618
1619 // other cases
1620 return xor_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1622}
1623
1625operator ^ (uint64 u, const sc_unsigned &v)
1626{
1627 if (u == 0)
1628 return sc_unsigned(v);
1629
1630 CONVERT_INT64(u);
1631
1632 if (v.sgn == SC_ZERO)
1633 return sc_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
1634
1635 // other cases
1637 v.sgn, v.nbits, v.ndigits, v.digit);
1638}
1639
1640
1642operator ^ (const sc_unsigned &u, unsigned long v)
1643{
1644 if (v == 0) // case 1
1645 return sc_unsigned(u);
1646
1647 CONVERT_LONG(v);
1648
1649 if (u.sgn == SC_ZERO) // case 2
1650 return sc_unsigned(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
1651
1652 // other cases
1653 return xor_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
1655}
1656
1658operator ^ (unsigned long u, const sc_unsigned &v)
1659{
1660 if (u == 0)
1661 return sc_unsigned(v);
1662
1663 CONVERT_LONG(u);
1664
1665 if (v.sgn == SC_ZERO)
1666 return sc_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
1667
1668 // other cases
1670 v.sgn, v.nbits, v.ndigits, v.digit);
1671}
1672
1673// The rest of the operators in this section are included from
1674// sc_nbcommon.cpp.
1675
1676
1677// ----------------------------------------------------------------------------
1678// SECTION: Bitwise NOT operator: ~
1679// ----------------------------------------------------------------------------
1680
1681// Operators in this section are included from sc_nbcommon.cpp.
1682
1683
1684// ----------------------------------------------------------------------------
1685// SECTION: LEFT SHIFT operators: <<, <<=
1686// ----------------------------------------------------------------------------
1687
1689operator << (const sc_unsigned &u, const sc_signed &v)
1690{
1691 if ((v.sgn == SC_ZERO) || (v.sgn == SC_NEG))
1692 return sc_unsigned(u);
1693
1694 return operator << (u, v.to_ulong());
1695}
1696
1697// The rest of the operators in this section are included from
1698// sc_nbcommon.cpp.
1699
1700
1701// ----------------------------------------------------------------------------
1702// SECTION: RIGHT SHIFT operators: >>, >>=
1703// ----------------------------------------------------------------------------
1704
1706operator >> (const sc_unsigned &u, const sc_signed &v)
1707{
1708
1709 if ((v.sgn == SC_ZERO) || (v.sgn == SC_NEG))
1710 return sc_unsigned(u);
1711
1712 return operator >> (u, v.to_long());
1713
1714}
1715
1716// The rest of the operators in this section are included from
1717// sc_nbcommon.cpp.
1718
1719
1720// ----------------------------------------------------------------------------
1721// SECTION: Unary arithmetic operators.
1722// ----------------------------------------------------------------------------
1723
1725operator + (const sc_unsigned &u)
1726{
1727 return sc_unsigned(u);
1728}
1729
1730
1731// ----------------------------------------------------------------------------
1732// SECTION: EQUAL operator: ==
1733// ----------------------------------------------------------------------------
1734
1735bool
1737{
1738 if (&u == &v)
1739 return true;
1740 if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
1741 v.sgn, v.nbits, v.ndigits, v.digit) != 0) {
1742 return false;
1743 }
1744 return true;
1745}
1746
1747
1748bool
1750{
1751 if (v.sgn == SC_NEG)
1752 return false;
1753 if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
1754 v.sgn, v.nbits, v.ndigits, v.digit, 0, 1) != 0) {
1755 return false;
1756 }
1757 return true;
1758}
1759
1760
1761bool
1763{
1764 if (u.sgn == SC_NEG)
1765 return false;
1766 if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
1767 v.sgn, v.nbits, v.ndigits, v.digit, 1, 0) != 0) {
1768 return false;
1769 }
1770 return true;
1771}
1772
1773
1774bool
1776{
1777 if (v < 0)
1778 return false;
1779 CONVERT_INT64(v);
1780 if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
1781 vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd) != 0) {
1782 return false;
1783 }
1784 return true;
1785}
1786
1787
1788bool
1790{
1791 if (u < 0)
1792 return false;
1793 CONVERT_INT64(u);
1795 v.sgn, v.nbits, v.ndigits, v.digit) != 0) {
1796 return false;
1797 }
1798 return true;
1799}
1800
1801
1802bool
1804{
1805 CONVERT_INT64(v);
1806 if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
1807 vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd) != 0)
1808 return false;
1809 return true;
1810}
1811
1812
1813bool
1815{
1816 CONVERT_INT64(u);
1818 v.sgn, v.nbits, v.ndigits, v.digit) != 0)
1819 return false;
1820 return true;
1821}
1822
1823
1824bool
1825operator == (const sc_unsigned &u, long v)
1826{
1827 if (v < 0)
1828 return false;
1829 CONVERT_LONG(v);
1830 if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
1831 vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd) != 0)
1832 return false;
1833 return true;
1834}
1835
1836
1837bool
1838operator == (long u, const sc_unsigned &v)
1839{
1840 if (u < 0)
1841 return false;
1842 CONVERT_LONG(u);
1844 v.sgn, v.nbits, v.ndigits, v.digit) != 0)
1845 return false;
1846 return true;
1847}
1848
1849
1850bool
1851operator == (const sc_unsigned &u, unsigned long v)
1852{
1853 CONVERT_LONG(v);
1854 if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
1855 vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd) != 0)
1856 return false;
1857 return true;
1858}
1859
1860
1861bool
1862operator == (unsigned long u, const sc_unsigned &v)
1863{
1864 CONVERT_LONG(u);
1866 v.sgn, v.nbits, v.ndigits, v.digit) != 0)
1867 return false;
1868 return true;
1869}
1870
1871
1872// ----------------------------------------------------------------------------
1873// SECTION: NOT_EQUAL operator: !=
1874// ----------------------------------------------------------------------------
1875
1876bool
1877operator != (const sc_unsigned &u, const sc_signed &v)
1878{
1879 return (!operator == (u, v));
1880}
1881
1882
1883bool
1884operator != (const sc_signed &u, const sc_unsigned &v)
1885{
1886 return (!operator == (u, v));
1887}
1888
1889// The rest of the operators in this section are included from sc_nbcommon.cpp.
1890
1891
1892// ----------------------------------------------------------------------------
1893// SECTION: LESS THAN operator: <
1894// ----------------------------------------------------------------------------
1895
1896bool
1897operator < (const sc_unsigned &u, const sc_unsigned &v)
1898{
1899 if (&u == &v)
1900 return false;
1901 if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
1902 v.sgn, v.nbits, v.ndigits, v.digit) < 0) {
1903 return true;
1904 }
1905 return false;
1906}
1907
1908
1909bool
1910operator < (const sc_unsigned &u, const sc_signed &v)
1911{
1912 if (v.sgn == SC_NEG)
1913 return false;
1914 if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
1915 v.sgn, v.nbits, v.ndigits, v.digit, 0, 1) < 0) {
1916 return true;
1917 }
1918 return false;
1919}
1920
1921
1922bool
1923operator < (const sc_signed &u, const sc_unsigned &v)
1924{
1925 if (u.sgn == SC_NEG)
1926 return true;
1927 if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
1928 v.sgn, v.nbits, v.ndigits, v.digit, 1, 0) < 0) {
1929 return true;
1930 }
1931 return false;
1932}
1933
1934
1935bool
1936operator < (const sc_unsigned &u, int64 v)
1937{
1938 if (v < 0)
1939 return false;
1940 CONVERT_INT64(v);
1941 if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
1942 vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd) < 0) {
1943 return true;
1944 }
1945 return false;
1946}
1947
1948
1949bool
1950operator < (int64 u, const sc_unsigned &v)
1951{
1952 if (u < 0)
1953 return true;
1954 CONVERT_INT64(u);
1956 v.sgn, v.nbits, v.ndigits, v.digit) < 0) {
1957 return true;
1958 }
1959 return false;
1960}
1961
1962
1963bool
1964operator < (const sc_unsigned &u, uint64 v)
1965{
1966 CONVERT_INT64(v);
1967 if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
1968 vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd) < 0) {
1969 return true;
1970 }
1971 return false;
1972}
1973
1974
1975bool
1976operator < (uint64 u, const sc_unsigned &v)
1977{
1978 CONVERT_INT64(u);
1980 v.sgn, v.nbits, v.ndigits, v.digit) < 0){
1981 return true;
1982 }
1983 return false;
1984}
1985
1986
1987bool
1988operator < (const sc_unsigned &u, long v)
1989{
1990 if (v < 0)
1991 return false;
1992 CONVERT_LONG(v);
1993 if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
1994 vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd) < 0) {
1995 return true;
1996 }
1997 return false;
1998}
1999
2000
2001bool
2002operator < (long u, const sc_unsigned &v)
2003{
2004 if (u < 0)
2005 return true;
2006 CONVERT_LONG(u);
2008 v.sgn, v.nbits, v.ndigits, v.digit) < 0) {
2009 return true;
2010 }
2011 return false;
2012}
2013
2014
2015bool
2016operator < (const sc_unsigned &u, unsigned long v)
2017{
2018 CONVERT_LONG(v);
2019 if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
2020 vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd) < 0) {
2021 return true;
2022 }
2023 return false;
2024}
2025
2026
2027bool
2028operator < (unsigned long u, const sc_unsigned &v)
2029{
2030 CONVERT_LONG(u);
2032 v.sgn, v.nbits, v.ndigits, v.digit) < 0) {
2033 return true;
2034 }
2035 return false;
2036}
2037
2038
2039// ----------------------------------------------------------------------------
2040// SECTION: LESS THAN or EQUAL operator: <=
2041// ----------------------------------------------------------------------------
2042
2043bool
2044operator <= (const sc_unsigned &u, const sc_signed &v)
2045{
2046 return (operator < (u, v) || operator == (u, v));
2047}
2048
2049
2050bool
2051operator <= (const sc_signed &u, const sc_unsigned &v)
2052{
2053 return (operator < (u, v) || operator == (u, v));
2054}
2055
2056// The rest of the operators in this section are included from sc_nbcommon.cpp.
2057
2058
2059// ----------------------------------------------------------------------------
2060// SECTION: GREATER THAN operator: >
2061// ----------------------------------------------------------------------------
2062
2063bool
2064operator > (const sc_unsigned &u, const sc_signed &v)
2065{
2066 return (!(operator <= (u, v)));
2067}
2068
2069
2070bool
2071operator > (const sc_signed &u, const sc_unsigned &v)
2072{
2073 return (!(operator <= (u, v)));
2074}
2075
2076// The rest of the operators in this section are included from sc_nbcommon.cpp.
2077
2078
2079// ----------------------------------------------------------------------------
2080// SECTION: GREATER THAN or EQUAL operator: >=
2081// ----------------------------------------------------------------------------
2082
2083bool
2084operator >= (const sc_unsigned &u, const sc_signed &v)
2085{
2086 return (!(operator < (u, v)));
2087}
2088
2089
2090bool
2091operator >= (const sc_signed &u, const sc_unsigned &v)
2092{
2093 return (!(operator < (u, v)));
2094}
2095
2096// The rest of the operators in this section are included from sc_nbcommon.cpp.
2097
2098
2099// ----------------------------------------------------------------------------
2100// SECTION: Friends
2101// ----------------------------------------------------------------------------
2102
2103// Compare u and v as unsigned and return r
2104// r = 0 if u == v
2105// r < 0 if u < v
2106// r > 0 if u > v
2107
2108int
2109compare_unsigned(small_type us, int unb, int und, const sc_digit *ud,
2110 small_type vs, int vnb, int vnd, const sc_digit *vd,
2111 small_type if_u_signed, small_type if_v_signed)
2112{
2113 if (us == vs) {
2114 if (us == SC_ZERO) {
2115 return 0;
2116 } else {
2117 int cmp_res = vec_skip_and_cmp(und, ud, vnd, vd);
2118 if (us == SC_POS)
2119 return cmp_res;
2120 else
2121 return -cmp_res;
2122 }
2123 } else {
2124 if (us == SC_ZERO)
2125 return -vs;
2126 if (vs == SC_ZERO)
2127 return us;
2128
2129 int cmp_res;
2130 int nd = (us == SC_NEG ? und : vnd);
2131
2132#ifdef SC_MAX_NBITS
2133 sc_digit d[MAX_NDIGITS];
2134#else
2135 sc_digit *d = new sc_digit[nd];
2136#endif
2137
2138 if (us == SC_NEG) {
2139 vec_copy(nd, d, ud);
2140 vec_complement(nd, d);
2141 trim(if_u_signed, unb, nd, d);
2142 cmp_res = vec_skip_and_cmp(nd, d, vnd, vd);
2143 } else {
2144 vec_copy(nd, d, vd);
2145 vec_complement(nd, d);
2146 trim(if_v_signed, vnb, nd, d);
2147 cmp_res = vec_skip_and_cmp(und, ud, nd, d);
2148 }
2149
2150#ifndef SC_MAX_NBITS
2151 delete [] d;
2152#endif
2153
2154 return cmp_res;
2155 }
2156}
2157
2158
2159// ----------------------------------------------------------------------------
2160// SECTION: Public members - Other utils.
2161// ----------------------------------------------------------------------------
2162
2163bool
2164sc_unsigned::iszero() const
2165{
2166 if (sgn == SC_ZERO) {
2167 return true;
2168 } else if (sgn == SC_NEG) {
2169 // A negative unsigned number can be zero, e.g., -16 in 4 bits, so
2170 // check that.
2171
2172#ifdef SC_MAX_NBITS
2173 sc_digit d[MAX_NDIGITS];
2174#else
2175 sc_digit *d = new sc_digit[ndigits];
2176#endif
2177
2178 vec_copy(ndigits, d, digit);
2179 vec_complement(ndigits, d);
2180 trim_unsigned(nbits, ndigits, d);
2181
2182 bool res = check_for_zero(ndigits, d);
2183
2184#ifndef SC_MAX_NBITS
2185 delete [] d;
2186#endif
2187
2188 return res;
2189 } else {
2190 return false;
2191 }
2192}
2193
2194// The rest of the utils in this section are included from sc_nbcommon.cpp.
2195
2196
2197// ----------------------------------------------------------------------------
2198// SECTION: Private members.
2199// ----------------------------------------------------------------------------
2200
2201// The private members in this section are included from
2202// sc_nbcommon.cpp.
2203
2204#define CLASS_TYPE sc_unsigned
2205#define CLASS_TYPE_STR "sc_unsigned"
2206
2207#define ADD_HELPER add_unsigned_friend
2208#define SUB_HELPER sub_unsigned_friend
2209#define MUL_HELPER mul_unsigned_friend
2210#define DIV_HELPER div_unsigned_friend
2211#define MOD_HELPER mod_unsigned_friend
2212#define AND_HELPER and_unsigned_friend
2213#define OR_HELPER or_unsigned_friend
2214#define XOR_HELPER xor_unsigned_friend
2215
2216#include "sc_nbfriends.inc"
2217
2218#undef SC_SIGNED
2219#define SC_UNSIGNED
2220#define IF_SC_SIGNED 0 // 0 = sc_unsigned
2221#define CLASS_TYPE_SUBREF sc_unsigned_subref_r
2222#define OTHER_CLASS_TYPE sc_signed
2223#define OTHER_CLASS_TYPE_SUBREF sc_signed_subref_r
2224
2225#define MUL_ON_HELPER mul_on_help_unsigned
2226#define DIV_ON_HELPER div_on_help_unsigned
2227#define MOD_ON_HELPER mod_on_help_unsigned
2228
2229#include "sc_nbcommon.inc"
2230
2231#undef MOD_ON_HELPER
2232#undef DIV_ON_HELPER
2233#undef MUL_ON_HELPER
2234
2235#undef OTHER_CLASS_TYPE_SUBREF
2236#undef OTHER_CLASS_TYPE
2237#undef CLASS_TYPE_SUBREF
2238#undef IF_SC_SIGNED
2239#undef SC_UNSIGNED
2240
2241#undef XOR_HELPER
2242#undef OR_HELPER
2243#undef AND_HELPER
2244#undef MOD_HELPER
2245#undef DIV_HELPER
2246#undef MUL_HELPER
2247#undef SUB_HELPER
2248#undef ADD_HELPER
2249
2250#undef CLASS_TYPE
2251#undef CLASS_TYPE_STR
2252
2253#include "sc_unsigned_bitref.inc"
2254#include "sc_unsigned_subref.inc"
2255
2256#undef CONVERT_LONG
2257#undef CONVERT_LONG_2
2258#undef CONVERT_INT64
2259#undef CONVERT_INT64_2
2260
2261} // namespace sc_dt
bool operator==(const arr_struct1 &, const arr_struct1 &)
Definition arr_struct.h:47
bool to_bool() const
Definition sc_logic.hh:240
int length() const
SwitchingFiber a
uint16_t len
Definition helpers.cc:83
void sc_abort()
Definition sc_report.cc:178
const char SC_ID_CONVERSION_FAILED_[]
Definition messages.cc:37
const char SC_ID_INIT_FAILED_[]
Definition messages.cc:34
const char SC_ID_OUT_OF_BOUNDS_[]
Definition messages.cc:40
uint64_t uint64
Definition sc_nbdefs.hh:172
sc_unsigned div_unsigned_friend(small_type s, int unb, int und, const sc_digit *ud, int vnb, int vnd, const sc_digit *vd)
int small_type
Definition sc_nbdefs.hh:108
int vec_skip_and_cmp(int ulen, const sc_digit *u, int vlen, const sc_digit *v)
sc_unsigned mod_unsigned_friend(small_type us, int unb, int und, const sc_digit *ud, int vnb, int vnd, const sc_digit *vd)
return remainder
Definition scfx_rep.cc:2169
small_type get_sign(Type &u)
void from_uint(int ulen, sc_digit *u, Type v)
void vec_copy(int n, sc_digit *u, const sc_digit *v)
int64_t int64
Definition sc_nbdefs.hh:171
sc_unsigned or_unsigned_friend(small_type us, int unb, int und, const sc_digit *ud, small_type vs, int vnb, int vnd, const sc_digit *vd)
void safe_set(int i, bool v, sc_digit *d)
void is_bad_double(double v)
sc_unsigned mul_unsigned_friend(small_type s, int unb, int und, const sc_digit *ud, int vnb, int vnd, const sc_digit *vd)
int64 int_type
Definition sc_nbdefs.hh:206
small_type check_for_zero(small_type s, int ulen, const sc_digit *u)
int compare_unsigned(small_type us, int unb, int und, const sc_digit *ud, small_type vs, int vnb, int vnd, const sc_digit *vd, small_type if_u_signed, small_type if_v_signed)
void vec_complement(int ulen, sc_digit *u)
sc_unsigned and_unsigned_friend(small_type us, int unb, int und, const sc_digit *ud, small_type vs, int vnb, int vnd, const sc_digit *vd)
sc_unsigned xor_unsigned_friend(small_type us, int unb, int und, const sc_digit *ud, small_type vs, int vnb, int vnd, const sc_digit *vd)
sc_unsigned add_unsigned_friend(small_type us, int unb, int und, const sc_digit *ud, small_type vs, int vnb, int vnd, const sc_digit *vd)
void div_by_zero(Type s)
unsigned int sc_digit
Definition sc_nbdefs.hh:163
small_type mul_signs(small_type us, small_type vs)
void vec_zero(int from, int ulen, sc_digit *u)
void trim(small_type added, int nb, int nd, sc_digit *d)
void trim_unsigned(int nb, int nd, sc_digit *d)
std::ostream & operator<<(std::ostream &os, gem5::RiscvISA::PrivilegeMode pm)
Definition isa.cc:1001
#define BITS_PER_ULONG
Definition sc_nbdefs.hh:187
#define DIGIT_RADIX
Definition sc_nbdefs.hh:128
#define DIGITS_PER_ULONG
Definition sc_nbdefs.hh:196
#define DIGIT_MASK
Definition sc_nbdefs.hh:129
#define SC_NEG
Definition sc_nbdefs.hh:99
#define BITS_PER_UINT64
Definition sc_nbdefs.hh:188
#define SC_ZERO
Definition sc_nbdefs.hh:100
#define DIGITS_PER_UINT64
Definition sc_nbdefs.hh:197
#define BITS_PER_DIGIT
Definition sc_nbdefs.hh:127
#define SC_POS
Definition sc_nbdefs.hh:101
#define SC_REPORT_ERROR(msg_type, msg)
#define CONVERT_INT64(u)
#define CONVERT_LONG(u)
#define CONVERT_INT64_2(u)
#define CONVERT_LONG_2(u)
Definition test.h:38

Generated on Tue Jun 18 2024 16:24:06 for gem5 by doxygen 1.11.0