1 /*
2 * Copyright (c) 1998-2018 Stephen Williams (steve@icarus.com)
3 *
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20 # include "config.h"
21
22 # include "verinum.h"
23 # include <iostream>
24 # include <cassert>
25 # include <climits>
26 # include <cmath> // Needed to get pow for as_double().
27 # include <cstdio> // Needed to get snprintf for as_string().
28 # include <algorithm>
29
30 #if !defined(HAVE_LROUND)
31 /*
32 * If the system doesn't provide the lround function, then we provide
33 * it ourselves here. It is simply the nearest integer, rounded away
34 * from zero.
35 */
lround(double x)36 extern "C" long int lround(double x)
37 {
38 if (x >= 0.0)
39 return (long)floor(x+0.5);
40 else
41 return (long)ceil(x-0.5);
42 }
43 #endif
44
45 static verinum::V add_with_carry(verinum::V l, verinum::V r, verinum::V&c);
46
verinum()47 verinum::verinum()
48 : bits_(0), nbits_(0), has_len_(false), has_sign_(false), is_single_(false), string_flag_(false)
49 {
50 }
51
verinum(const V * bits,unsigned nbits,bool has_len__)52 verinum::verinum(const V*bits, unsigned nbits, bool has_len__)
53 : has_len_(has_len__), has_sign_(false), is_single_(false), string_flag_(false)
54 {
55 nbits_ = nbits;
56 bits_ = new V [nbits];
57 for (unsigned idx = 0 ; idx < nbits ; idx += 1) {
58 bits_[idx] = bits[idx];
59 }
60 }
61
process_verilog_string_quotes(const string & str)62 static string process_verilog_string_quotes(const string&str)
63 {
64 string res;
65
66 int idx = 0;
67 int str_len = str.length();
68
69 while (idx < str_len) {
70 if (str[idx] == '\\') {
71 idx += 1;
72 assert(idx < str_len);
73 switch (str[idx]) {
74 case 'n':
75 res = res + '\n';
76 idx += 1;
77 break;
78 case 't':
79 res = res + '\t';
80 idx += 1;
81 break;
82 case '0':
83 case '1':
84 case '2':
85 case '3':
86 case '4':
87 case '5':
88 case '6':
89 case '7': {
90 char byte_val = 0;
91 int odx = 0;
92 while (odx < 3 && idx+odx < str_len
93 && str[idx+odx] >= '0'
94 && str[idx+odx] <= '7') {
95 byte_val = 8*byte_val + str[idx+odx]-'0';
96 odx += 1;
97 }
98 idx += odx;
99 res = res + byte_val;
100 break;
101 }
102 default:
103 res = res + str[idx];
104 idx += 1;
105 break;
106 }
107 } else {
108 res = res + str[idx];
109 idx += 1;
110 }
111 }
112 return res;
113 }
114
verinum(const string & s)115 verinum::verinum(const string&s)
116 : has_len_(true), has_sign_(false), is_single_(false), string_flag_(true)
117 {
118 string str = process_verilog_string_quotes(s);
119 nbits_ = str.length() * 8;
120
121 // Special case: The string "" is 8 bits of 0.
122 if (nbits_ == 0) {
123 nbits_ = 8;
124 bits_ = new V [nbits_];
125 bits_[0] = V0;
126 bits_[1] = V0;
127 bits_[2] = V0;
128 bits_[3] = V0;
129 bits_[4] = V0;
130 bits_[5] = V0;
131 bits_[6] = V0;
132 bits_[7] = V0;
133 return;
134 }
135
136 bits_ = new V [nbits_];
137
138 unsigned idx, cp;
139 V*bp = bits_+nbits_;
140 for (idx = nbits_, cp = 0 ; idx > 0 ; idx -= 8, cp += 1) {
141 char ch = str[cp];
142 *(--bp) = (ch&0x80) ? V1 : V0;
143 *(--bp) = (ch&0x40) ? V1 : V0;
144 *(--bp) = (ch&0x20) ? V1 : V0;
145 *(--bp) = (ch&0x10) ? V1 : V0;
146 *(--bp) = (ch&0x08) ? V1 : V0;
147 *(--bp) = (ch&0x04) ? V1 : V0;
148 *(--bp) = (ch&0x02) ? V1 : V0;
149 *(--bp) = (ch&0x01) ? V1 : V0;
150 }
151 }
152
verinum(verinum::V val,unsigned n,bool h)153 verinum::verinum(verinum::V val, unsigned n, bool h)
154 : has_len_(h), has_sign_(false), is_single_(false), string_flag_(false)
155 {
156 nbits_ = n;
157 bits_ = new V[nbits_];
158 for (unsigned idx = 0 ; idx < nbits_ ; idx += 1)
159 bits_[idx] = val;
160 }
161
verinum(uint64_t val,unsigned n)162 verinum::verinum(uint64_t val, unsigned n)
163 : has_len_(true), has_sign_(false), is_single_(false), string_flag_(false)
164 {
165 nbits_ = n;
166 bits_ = new V[nbits_];
167 for (unsigned idx = 0 ; idx < nbits_ ; idx += 1) {
168 bits_[idx] = (val&1) ? V1 : V0;
169 val >>= (uint64_t)1;
170 }
171 }
172
173 /* The second argument is not used! It is there to make this
174 * constructor unique. */
verinum(double val,bool)175 verinum::verinum(double val, bool)
176 : has_len_(false), has_sign_(true), is_single_(false), string_flag_(false)
177 {
178 bool is_neg = false;
179 double fraction;
180 int exponent;
181 const unsigned BITS_IN_LONG = 8*sizeof(long);
182
183 /* We return `bx for a NaN or +/- infinity. */
184 if (val != val || (val && (val == 0.5*val))) {
185 nbits_ = 1;
186 bits_ = new V[nbits_];
187 bits_[0] = Vx;
188 return;
189 }
190
191 /* Convert to a positive result. */
192 if (val < 0.0) {
193 is_neg = true;
194 val = -val;
195 }
196
197 /* Round to the nearest integer now, as this may increase the
198 number of bits we need to allocate. */
199 val = round(val);
200
201 /* Get the exponent and fractional part of the number. */
202 fraction = frexp(val, &exponent);
203 nbits_ = exponent+1;
204 bits_ = new V[nbits_];
205
206 /* If the value is small enough just use lround(). */
207 if (nbits_ <= BITS_IN_LONG) {
208 long sval = lround(val);
209 if (is_neg) sval = -sval;
210 for (unsigned idx = 0; idx < nbits_; idx += 1) {
211 bits_[idx] = (sval&1) ? V1 : V0;
212 sval >>= 1;
213 }
214 /* Trim the result. */
215 signed_trim();
216 return;
217 }
218
219 unsigned nwords = (exponent-1)/BITS_IN_LONG;
220
221 fraction = ldexp(fraction, (exponent-1) % BITS_IN_LONG + 1);
222
223 if (nwords == 0) {
224 unsigned long bits = (unsigned long) fraction;
225 fraction = fraction - (double) bits;
226 for (unsigned idx = 0; idx < nbits_; idx += 1) {
227 bits_[idx] = (bits&1) ? V1 : V0;
228 bits >>= 1;
229 }
230 } else {
231 for (int wd = nwords; wd >= 0; wd -= 1) {
232 unsigned long bits = (unsigned long) fraction;
233 fraction = fraction - (double) bits;
234 unsigned max_idx = (wd+1)*BITS_IN_LONG;
235 if (max_idx > nbits_) max_idx = nbits_;
236 for (unsigned idx = wd*BITS_IN_LONG; idx < max_idx; idx += 1) {
237 bits_[idx] = (bits&1) ? V1 : V0;
238 bits >>= 1;
239 }
240 fraction = ldexp(fraction, BITS_IN_LONG);
241 }
242 }
243
244 /* Convert a negative number if needed. */
245 if (is_neg) {
246 *this = -(*this);
247 }
248
249 /* Trim the result. */
250 signed_trim();
251 }
252
253
254 /* This is used by the double constructor above. It is needed to remove
255 * extra sign bits that can occur when calculating a negative value. */
signed_trim()256 void verinum::signed_trim()
257 {
258 /* Do we have any extra digits? */
259 unsigned tlen = nbits_-1;
260 verinum::V sign = bits_[tlen];
261 while ((tlen > 0) && (bits_[tlen] == sign)) tlen -= 1;
262
263 /* tlen now points to the first digit that is not the sign.
264 * or bit 0. Set the length to include this bit and one proper
265 * sign bit if needed. */
266 if (bits_[tlen] != sign) tlen += 1;
267 tlen += 1;
268
269 /* Trim the bits if needed. */
270 if (tlen < nbits_) {
271 V* tbits = new V[tlen];
272 for (unsigned idx = 0; idx < tlen; idx += 1)
273 tbits[idx] = bits_[idx];
274 delete[] bits_;
275 bits_ = tbits;
276 nbits_ = tlen;
277 }
278 }
279
verinum(const verinum & that)280 verinum::verinum(const verinum&that)
281 {
282 string_flag_ = that.string_flag_;
283 nbits_ = that.nbits_;
284 bits_ = new V[nbits_];
285 has_len_ = that.has_len_;
286 has_sign_ = that.has_sign_;
287 is_single_ = that.is_single_;
288 for (unsigned idx = 0 ; idx < nbits_ ; idx += 1)
289 bits_[idx] = that.bits_[idx];
290 }
291
verinum(const verinum & that,unsigned nbits)292 verinum::verinum(const verinum&that, unsigned nbits)
293 {
294 string_flag_ = that.string_flag_ && (that.nbits_ == nbits);
295 nbits_ = nbits;
296 bits_ = new V[nbits_];
297 has_len_ = true;
298 has_sign_ = that.has_sign_;
299 is_single_ = false;
300
301 unsigned copy = nbits;
302 if (copy > that.nbits_)
303 copy = that.nbits_;
304 for (unsigned idx = 0 ; idx < copy ; idx += 1)
305 bits_[idx] = that.bits_[idx];
306
307 if (copy < nbits_) {
308 if (has_sign_ || that.is_single_) {
309 for (unsigned idx = copy ; idx < nbits_ ; idx += 1)
310 bits_[idx] = bits_[idx-1];
311 } else {
312 for (unsigned idx = copy ; idx < nbits_ ; idx += 1)
313 bits_[idx] = verinum::V0;
314 }
315 }
316 }
317
verinum(int64_t that)318 verinum::verinum(int64_t that)
319 : has_len_(false), has_sign_(true), is_single_(false), string_flag_(false)
320 {
321 int64_t tmp;
322
323 if (that < 0) tmp = (that+1)/2;
324 else tmp = that/2;
325 nbits_ = 1;
326 while (tmp != 0) {
327 nbits_ += 1;
328 tmp /= 2;
329 }
330
331 nbits_ += 1;
332
333 bits_ = new V[nbits_];
334 for (unsigned idx = 0 ; idx < nbits_ ; idx += 1) {
335 bits_[idx] = (that & 1)? V1 : V0;
336 that >>= 1;
337 }
338 }
339
~verinum()340 verinum::~verinum()
341 {
342 delete[]bits_;
343 }
344
operator =(const verinum & that)345 verinum& verinum::operator= (const verinum&that)
346 {
347 if (this == &that) return *this;
348 if (nbits_ != that.nbits_) {
349 delete[]bits_;
350 nbits_ = that.nbits_;
351 bits_ = new V[that.nbits_];
352 }
353 for (unsigned idx = 0 ; idx < nbits_ ; idx += 1)
354 bits_[idx] = that.bits_[idx];
355
356 has_len_ = that.has_len_;
357 has_sign_ = that.has_sign_;
358 is_single_ = that.is_single_;
359 string_flag_ = that.string_flag_;
360 return *this;
361 }
362
get(unsigned idx) const363 verinum::V verinum::get(unsigned idx) const
364 {
365 assert(idx < nbits_);
366 return bits_[idx];
367 }
368
set(unsigned idx,verinum::V val)369 verinum::V verinum::set(unsigned idx, verinum::V val)
370 {
371 assert(idx < nbits_);
372 return bits_[idx] = val;
373 }
374
set(unsigned off,const verinum & val)375 void verinum::set(unsigned off, const verinum&val)
376 {
377 assert(off + val.len() <= nbits_);
378 for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
379 bits_[off+idx] = val[idx];
380 }
381
as_unsigned() const382 unsigned verinum::as_unsigned() const
383 {
384 if (nbits_ == 0)
385 return 0;
386
387 if (!is_defined())
388 return 0;
389
390 unsigned val = 0;
391 unsigned mask = 1;
392 for (unsigned idx = 0 ; idx < nbits_ ; idx += 1, mask <<= 1)
393 if (bits_[idx] == V1) {
394 if (mask == 0) return ~mask;
395 val |= mask;
396 }
397
398 return val;
399 }
400
as_ulong() const401 unsigned long verinum::as_ulong() const
402 {
403 if (nbits_ == 0)
404 return 0;
405
406 if (!is_defined())
407 return 0;
408
409 unsigned long val = 0;
410 unsigned long mask = 1;
411 for (unsigned idx = 0 ; idx < nbits_ ; idx += 1, mask <<= 1)
412 if (bits_[idx] == V1) {
413 if (mask == 0) return ~mask;
414 val |= mask;
415 }
416
417 return val;
418 }
419
as_ulong64() const420 uint64_t verinum::as_ulong64() const
421 {
422 if (nbits_ == 0)
423 return 0;
424
425 if (!is_defined())
426 return 0;
427
428 uint64_t val = 0;
429 uint64_t mask = 1;
430 for (unsigned idx = 0 ; idx < nbits_ ; idx += 1, mask <<= 1)
431 if (bits_[idx] == V1) {
432 if (mask == 0) return ~mask;
433 val |= mask;
434 }
435
436 return val;
437 }
438
439 /*
440 * This function returns the native long integer that represents the
441 * value of this object. It accounts for sign extension if the value
442 * is signed.
443 *
444 * If the value is undefined, return 0.
445 *
446 * This function presumes that the native format is 2s complement
447 * (pretty safe these days) and masks/sets bits accordingly. If the
448 * value is too large for the native form, it truncates the high bits.
449 */
as_long() const450 signed long verinum::as_long() const
451 {
452 #define IVLLBITS (8 * sizeof(long) - 1)
453 if (nbits_ == 0)
454 return 0;
455
456 if (!is_defined())
457 return 0;
458
459 signed long val = 0;
460 unsigned diag_top = 0;
461
462 unsigned top = nbits_;
463 if (top > IVLLBITS) {
464 diag_top = top;
465 top = IVLLBITS;
466 }
467 int lost_bits=0;
468
469 if (has_sign_ && (bits_[nbits_-1] == V1)) {
470 val = -1;
471 signed long mask = ~1L;
472 for (unsigned idx = 0 ; idx < top ; idx += 1) {
473 if (bits_[idx] == V0) val &= mask;
474 mask = (mask << 1) | 1L;
475 }
476 if (diag_top) {
477 for (unsigned idx = top; idx < diag_top; idx += 1) {
478 if (bits_[idx] == V0) lost_bits=1;
479 }
480 }
481 } else {
482 signed long mask = 1;
483 for (unsigned idx = 0 ; idx < top ; idx += 1, mask <<= 1) {
484 if (bits_[idx] == V1) val |= mask;
485 }
486 if (diag_top) {
487 for (unsigned idx = top; idx < diag_top; idx += 1) {
488 if (bits_[idx] == V1) lost_bits=1;
489 }
490 }
491 }
492
493 if (lost_bits) cerr << "warning: verinum::as_long() truncated " <<
494 diag_top << " bits to " << IVLLBITS << ", returns " << val << endl;
495 return val;
496 #undef IVLLBITS
497 }
498
as_double() const499 double verinum::as_double() const
500 {
501 if (nbits_ == 0) return 0.0;
502
503 double val = 0.0;
504 /* Do we have/want a signed value? */
505 if (has_sign_ && bits_[nbits_-1] == V1) {
506 V carry = V1;
507 for (unsigned idx = 0; idx < nbits_; idx += 1) {
508 V sum = add_with_carry(~bits_[idx], V0, carry);
509 if (sum == V1)
510 val += pow(2.0, (double)idx);
511 }
512 val *= -1.0;
513 } else {
514 for (unsigned idx = 0; idx < nbits_; idx += 1) {
515 if (bits_[idx] == V1)
516 val += pow(2.0, (double)idx);
517 }
518 }
519 return val;
520 }
521
as_string() const522 string verinum::as_string() const
523 {
524 assert( nbits_%8 == 0 );
525 if (nbits_ == 0)
526 return "";
527
528 string res;
529 for (unsigned idx = nbits_ ; idx > 0 ; idx -= 8) {
530 char char_val = 0;
531 V*bp = bits_+idx;
532
533 if (*(--bp) == V1) char_val |= 0x80;
534 if (*(--bp) == V1) char_val |= 0x40;
535 if (*(--bp) == V1) char_val |= 0x20;
536 if (*(--bp) == V1) char_val |= 0x10;
537 if (*(--bp) == V1) char_val |= 0x08;
538 if (*(--bp) == V1) char_val |= 0x04;
539 if (*(--bp) == V1) char_val |= 0x02;
540 if (*(--bp) == V1) char_val |= 0x01;
541
542 if (char_val == '"' || char_val == '\\') {
543 char tmp[5];
544 snprintf(tmp, sizeof tmp, "\\%03o", char_val);
545 res = res + tmp;
546 } else if (isprint(char_val)) {
547 res = res + char_val;
548 } else {
549 char tmp[5];
550 snprintf(tmp, sizeof tmp, "\\%03o", (unsigned char)char_val);
551 res = res + tmp;
552 }
553 }
554 return res;
555 }
556
is_before(const verinum & that) const557 bool verinum::is_before(const verinum&that) const
558 {
559 if (that.nbits_ > nbits_) return true;
560 if (that.nbits_ < nbits_) return false;
561
562 for (unsigned idx = nbits_ ; idx > 0 ; idx -= 1) {
563 if (bits_[idx-1] < that.bits_[idx-1]) return true;
564 if (bits_[idx-1] > that.bits_[idx-1]) return false;
565 }
566 return false;
567 }
568
is_defined() const569 bool verinum::is_defined() const
570 {
571 for (unsigned idx = 0 ; idx < nbits_ ; idx += 1) {
572 if (bits_[idx] == Vx) return false;
573 if (bits_[idx] == Vz) return false;
574 }
575 return true;
576 }
577
is_zero() const578 bool verinum::is_zero() const
579 {
580 for (unsigned idx = 0 ; idx < nbits_ ; idx += 1)
581 if (bits_[idx] != V0) return false;
582
583 return true;
584 }
585
is_negative() const586 bool verinum::is_negative() const
587 {
588 return (bits_[nbits_-1] == V1) && has_sign();
589 }
590
significant_bits() const591 unsigned verinum::significant_bits() const
592 {
593 unsigned sbits = nbits_;
594
595 if (has_sign_) {
596 V sign_bit = bits_[sbits-1];
597 while ((sbits > 1) && (bits_[sbits-2] == sign_bit))
598 sbits -= 1;
599 } else {
600 while ((sbits > 1) && (bits_[sbits-1] == verinum::V0))
601 sbits -= 1;
602 }
603 return sbits;
604 }
605
cast_to_int2()606 void verinum::cast_to_int2()
607 {
608 for (unsigned idx = 0 ; idx < nbits_ ; idx += 1) {
609 if (bits_[idx] == Vx || bits_[idx] == Vz)
610 bits_[idx] = V0;
611 }
612 }
613
pad_to_width(const verinum & that,unsigned width)614 verinum pad_to_width(const verinum&that, unsigned width)
615 {
616 if (that.len() >= width)
617 return that;
618
619 if (that.len() == 0) {
620 verinum val (verinum::V0, width, that.has_len());
621 val.has_sign(that.has_sign());
622 return val;
623 }
624
625 verinum::V pad = that[that.len()-1];
626 if (pad==verinum::V1 && !that.has_sign() && !that.is_single())
627 pad = verinum::V0;
628 if (that.has_len() && !that.has_sign() && !that.is_single()) {
629 if (pad==verinum::Vx)
630 pad = verinum::V0;
631 if (pad==verinum::Vz)
632 pad = verinum::V0;
633 }
634
635 verinum val(pad, width, that.has_len());
636
637 for (unsigned idx = 0 ; idx < that.len() ; idx += 1)
638 val.set(idx, that[idx]);
639
640 val.has_sign(that.has_sign());
641 if (that.is_string() && (width % 8) == 0) {
642 val = verinum(val.as_string());
643 }
644 return val;
645 }
646
cast_to_width(const verinum & that,unsigned width)647 verinum cast_to_width(const verinum&that, unsigned width)
648 {
649 if (that.has_len() && (that.len() == width))
650 return that;
651
652 if (that.len() >= width)
653 return verinum(that, width);
654
655 if (that.len() == 0) {
656 verinum val (verinum::V0, width, true);
657 val.has_sign(that.has_sign());
658 return val;
659 }
660
661 verinum::V pad = that[that.len()-1];
662 if (pad==verinum::V1 && !that.has_sign() && !that.is_single())
663 pad = verinum::V0;
664 if (that.has_len() && !that.has_sign() && !that.is_single()) {
665 if (pad==verinum::Vx)
666 pad = verinum::V0;
667 if (pad==verinum::Vz)
668 pad = verinum::V0;
669 }
670
671 verinum val(pad, width, true);
672
673 for (unsigned idx = 0 ; idx < that.len() ; idx += 1)
674 val.set(idx, that[idx]);
675
676 val.has_sign(that.has_sign());
677 return val;
678 }
679
680 /*
681 * This function returns a version of the verinum that has only as
682 * many bits as are needed to accurately represent the value. It takes
683 * into account the signedness of the value.
684 *
685 * If the input value has a definite length, then that value is just
686 * returned as is.
687 */
trim_vnum(const verinum & that)688 verinum trim_vnum(const verinum&that)
689 {
690 unsigned tlen;
691
692 if (that.has_len())
693 return that;
694
695 if (that.len() < 2)
696 return that;
697
698 if (that.has_sign()) {
699 unsigned top = that.len()-1;
700 verinum::V sign = that.get(top);
701
702 while ((top > 0) && (that.get(top) == sign))
703 top -= 1;
704
705 /* top points to the first digit that is not the
706 sign. Set the length to include this and one proper
707 sign bit. */
708
709 if (that.get(top) != sign)
710 top += 1;
711
712 tlen = top+1;
713
714 } else {
715
716 /* If the result is unsigned and has an indefinite
717 length, then trim off all but one leading zero. */
718 unsigned top = that.len()-1;
719 while ((top > 0) && (that.get(top) == verinum::V0))
720 top -= 1;
721
722 /* Now top is the index of the highest non-zero bit. If
723 that turns out to the highest bit in the vector, then
724 there is no trimming possible. */
725 if (top+1 == that.len())
726 return that;
727
728 /* Make tlen wide enough to include the highest non-zero
729 bit, plus one extra 0 bit. */
730 tlen = top+2;
731
732 /* This can only happen when the verinum is all zeros,
733 so make it a single bit wide. */
734 if (that.get(top) == verinum::V0) tlen -= 1;
735 }
736
737 verinum tmp (verinum::V0, tlen, false);
738 tmp.has_sign(that.has_sign());
739 for (unsigned idx = 0 ; idx < tmp.len() ; idx += 1)
740 tmp.set(idx, that.get(idx));
741
742 return tmp;
743 }
744
operator <<(ostream & o,verinum::V v)745 ostream& operator<< (ostream&o, verinum::V v)
746 {
747 switch (v) {
748 case verinum::V0:
749 o << "0";
750 break;
751 case verinum::V1:
752 o << "1";
753 break;
754 case verinum::Vx:
755 o << "x";
756 break;
757 case verinum::Vz:
758 o << "z";
759 break;
760 }
761 return o;
762 }
763
764 /*
765 * This operator is used by various dumpers to write the Verilog
766 * number in a Verilog format.
767 */
operator <<(ostream & o,const verinum & v)768 ostream& operator<< (ostream&o, const verinum&v)
769 {
770 if (v.is_string()) {
771 o << "\"" << v.as_string() << "\"";
772 return o;
773 }
774
775 /* If the verinum number has a fixed length, dump all the bits
776 literally. This is how we express the fixed length in the
777 output. */
778 if (v.has_len()) {
779 o << v.len();
780 }
781
782 /* If the number is fully defined (no x or z) then print it
783 out as a decimal number. */
784 unsigned dec_len = 8*sizeof(int); /* avoid 32/64 bit differences. */
785 if (! v.has_sign()) dec_len -= 1; /* an unsigned number. */
786 if (v.is_defined() && v.len() <= dec_len) {
787 if (v.has_sign())
788 o << "'sd" << v.as_long();
789 else
790 o << "'d" << v.as_ulong();
791 return o;
792 }
793
794 /* Oh, well. Print the minimum to get the value properly
795 displayed. */
796 if (v.has_sign())
797 o << "'sb";
798 else
799 o << "'b";
800
801 if (v.len() == 0) {
802 o << "0";
803 return o;
804 }
805
806 verinum::V trim_left = v.get(v.len()-1);
807 unsigned idx;
808
809 if (v.has_sign()) {
810 for (idx = v.len()-1; idx > 0; idx -= 1)
811 if (trim_left != v.get(idx-1))
812 break;
813
814 o << trim_left;
815 } else {
816 idx = v.len();
817 }
818
819 while (idx > 0) {
820 o << v.get(idx-1);
821 idx -= 1;
822 }
823
824 return o;
825 }
826
operator ==(const verinum & left,const verinum & right)827 verinum::V operator == (const verinum&left, const verinum&right)
828 {
829 verinum::V left_pad = verinum::V0;
830 verinum::V right_pad = verinum::V0;
831 if (left.has_sign() && right.has_sign()) {
832 left_pad = left.get(left.len()-1);
833 right_pad = right.get(right.len()-1);
834
835 if (left_pad == verinum::V1 && right_pad == verinum::V0)
836 return verinum::V0;
837 if (left_pad == verinum::V0 && right_pad == verinum::V1)
838 return verinum::V0;
839 }
840
841 unsigned max_len = left.len();
842 if (right.len() > max_len)
843 max_len = right.len();
844
845 for (unsigned idx = 0 ; idx < max_len ; idx += 1) {
846 verinum::V left_bit = idx < left.len() ? left[idx] : left_pad;
847 verinum::V right_bit = idx < right.len()? right[idx] : right_pad;
848 if (left_bit != right_bit)
849 return verinum::V0;
850 }
851
852 return verinum::V1;
853 }
854
operator <=(const verinum & left,const verinum & right)855 verinum::V operator <= (const verinum&left, const verinum&right)
856 {
857 verinum::V left_pad = verinum::V0;
858 verinum::V right_pad = verinum::V0;
859 bool signed_calc = left.has_sign() && right.has_sign();
860 if (signed_calc) {
861 left_pad = left.get(left.len()-1);
862 right_pad = right.get(right.len()-1);
863
864 if (left_pad == verinum::V1 && right_pad == verinum::V0)
865 return verinum::V1;
866 if (left_pad == verinum::V0 && right_pad == verinum::V1)
867 return verinum::V0;
868 }
869
870 unsigned idx;
871 for (idx = left.len() ; idx > right.len() ; idx -= 1) {
872 if (left[idx-1] != right_pad) {
873 // A change of padding for a negative left argument
874 // denotes the left value is less than the right.
875 return (signed_calc &&
876 (left_pad == verinum::V1)) ? verinum::V1 :
877 verinum::V0;
878 }
879 }
880
881 for (idx = right.len() ; idx > left.len() ; idx -= 1) {
882 if (right[idx-1] != left_pad) {
883 // A change of padding for a negative right argument
884 // denotes the left value is not less than the right.
885 return (signed_calc &&
886 (right_pad == verinum::V1)) ? verinum::V0 :
887 verinum::V1;
888 }
889 }
890
891 idx = right.len();
892 if (left.len() < idx) idx = left.len();
893
894 while (idx > 0) {
895 if (left[idx-1] == verinum::Vx) return verinum::Vx;
896 if (left[idx-1] == verinum::Vz) return verinum::Vx;
897 if (right[idx-1] == verinum::Vx) return verinum::Vx;
898 if (right[idx-1] == verinum::Vz) return verinum::Vx;
899 if (left[idx-1] > right[idx-1]) return verinum::V0;
900 if (left[idx-1] < right[idx-1]) return verinum::V1;
901 idx -= 1;
902 }
903
904 return verinum::V1;
905 }
906
operator <(const verinum & left,const verinum & right)907 verinum::V operator < (const verinum&left, const verinum&right)
908 {
909 verinum::V left_pad = verinum::V0;
910 verinum::V right_pad = verinum::V0;
911 bool signed_calc = left.has_sign() && right.has_sign();
912 if (signed_calc) {
913 left_pad = left.get(left.len()-1);
914 right_pad = right.get(right.len()-1);
915
916 if (left_pad == verinum::V1 && right_pad == verinum::V0)
917 return verinum::V1;
918 if (left_pad == verinum::V0 && right_pad == verinum::V1)
919 return verinum::V0;
920 }
921
922 unsigned idx;
923 for (idx = left.len() ; idx > right.len() ; idx -= 1) {
924 if (left[idx-1] != right_pad) {
925 // A change of padding for a negative left argument
926 // denotes the left value is less than the right.
927 return (signed_calc &&
928 (left_pad == verinum::V1)) ? verinum::V1 :
929 verinum::V0;
930 }
931 }
932
933 for (idx = right.len() ; idx > left.len() ; idx -= 1) {
934 if (right[idx-1] != left_pad) {
935 // A change of padding for a negative right argument
936 // denotes the left value is not less than the right.
937 return (signed_calc &&
938 (right_pad == verinum::V1)) ? verinum::V0 :
939 verinum::V1;
940 }
941 }
942
943 while (idx > 0) {
944 if (left[idx-1] == verinum::Vx) return verinum::Vx;
945 if (left[idx-1] == verinum::Vz) return verinum::Vx;
946 if (right[idx-1] == verinum::Vx) return verinum::Vx;
947 if (right[idx-1] == verinum::Vz) return verinum::Vx;
948 if (left[idx-1] > right[idx-1]) return verinum::V0;
949 if (left[idx-1] < right[idx-1]) return verinum::V1;
950 idx -= 1;
951 }
952
953 return verinum::V0;
954 }
955
add_with_carry(verinum::V l,verinum::V r,verinum::V & c)956 static verinum::V add_with_carry(verinum::V l, verinum::V r, verinum::V&c)
957 {
958 unsigned sum = 0;
959 switch (c) {
960 case verinum::Vx:
961 case verinum::Vz:
962 c = verinum::Vx;
963 return verinum::Vx;
964 case verinum::V0:
965 break;
966 case verinum::V1:
967 sum += 1;
968 }
969
970 switch (l) {
971 case verinum::Vx:
972 case verinum::Vz:
973 c = verinum::Vx;
974 return verinum::Vx;
975 case verinum::V0:
976 break;
977 case verinum::V1:
978 sum += 1;
979 break;
980 }
981
982 switch (r) {
983 case verinum::Vx:
984 case verinum::Vz:
985 c = verinum::Vx;
986 return verinum::Vx;
987 case verinum::V0:
988 break;
989 case verinum::V1:
990 sum += 1;
991 break;
992 }
993
994 if (sum & 2)
995 c = verinum::V1;
996 else
997 c = verinum::V0;
998 if (sum & 1)
999 return verinum::V1;
1000 else
1001 return verinum::V0;
1002 }
1003
operator ~(const verinum & left)1004 verinum operator ~ (const verinum&left)
1005 {
1006 verinum val = left;
1007 for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
1008 switch (val[idx]) {
1009 case verinum::V0:
1010 val.set(idx, verinum::V1);
1011 break;
1012 case verinum::V1:
1013 val.set(idx, verinum::V0);
1014 break;
1015 default:
1016 val.set(idx, verinum::Vx);
1017 break;
1018 }
1019
1020 return val;
1021 }
1022
1023 /*
1024 * Addition and subtraction works a bit at a time, from the least
1025 * significant up to the most significant. The result is signed only
1026 * if both of the operands are signed. If either operand is unsized,
1027 * the result is expanded as needed to prevent overflow.
1028 */
1029
operator +(const verinum & left,const verinum & right)1030 verinum operator + (const verinum&left, const verinum&right)
1031 {
1032 const bool has_len_flag = left.has_len() && right.has_len();
1033 const bool signed_flag = left.has_sign() && right.has_sign();
1034
1035 unsigned min_len = min(left.len(), right.len());
1036 unsigned max_len = max(left.len(), right.len());
1037
1038 // If either the left or right values are undefined, the
1039 // entire result is undefined.
1040 if (!left.is_defined() || !right.is_defined()) {
1041 unsigned len = has_len_flag ? max_len : 1;
1042 verinum result (verinum::Vx, len, has_len_flag);
1043 result.has_sign(signed_flag);
1044 return result;
1045 }
1046
1047 verinum::V*val_bits = new verinum::V[max_len+1];
1048
1049 verinum::V carry = verinum::V0;
1050 for (unsigned idx = 0 ; idx < min_len ; idx += 1)
1051 val_bits[idx] = add_with_carry(left[idx], right[idx], carry);
1052
1053 verinum::V rpad = sign_bit(right);
1054 verinum::V lpad = sign_bit(left);
1055
1056 if (left.len() > right.len()) {
1057
1058 for (unsigned idx = min_len ; idx < max_len ; idx += 1)
1059 val_bits[idx] = add_with_carry(left[idx], rpad, carry);
1060
1061 } else {
1062
1063 for (unsigned idx = min_len ; idx < max_len ; idx += 1)
1064 val_bits[idx] = add_with_carry(lpad, right[idx], carry);
1065 }
1066
1067 unsigned len = max_len;
1068 if (!has_len_flag) {
1069 val_bits[max_len] = add_with_carry(lpad, rpad, carry);
1070 if (signed_flag) {
1071 if (val_bits[max_len] != val_bits[max_len-1]) len += 1;
1072 } else {
1073 if (val_bits[max_len] != verinum::V0) len += 1;
1074 }
1075 }
1076 verinum result (val_bits, len, has_len_flag);
1077 result.has_sign(signed_flag);
1078
1079 delete[]val_bits;
1080
1081 return result;
1082 }
1083
operator -(const verinum & left,const verinum & right)1084 verinum operator - (const verinum&left, const verinum&right)
1085 {
1086 const bool has_len_flag = left.has_len() && right.has_len();
1087 const bool signed_flag = left.has_sign() && right.has_sign();
1088
1089 unsigned min_len = min(left.len(), right.len());
1090 unsigned max_len = max(left.len(), right.len());
1091
1092 // If either the left or right values are undefined, the
1093 // entire result is undefined.
1094 if (!left.is_defined() || !right.is_defined()) {
1095 unsigned len = has_len_flag ? max_len : 1;
1096 verinum result (verinum::Vx, len, has_len_flag);
1097 result.has_sign(signed_flag);
1098 return result;
1099 }
1100
1101 verinum::V*val_bits = new verinum::V[max_len+1];
1102
1103 verinum::V carry = verinum::V1;
1104 for (unsigned idx = 0 ; idx < min_len ; idx += 1)
1105 val_bits[idx] = add_with_carry(left[idx], ~right[idx], carry);
1106
1107 verinum::V rpad = sign_bit(right);
1108 verinum::V lpad = sign_bit(left);
1109
1110 if (left.len() > right.len()) {
1111
1112 for (unsigned idx = min_len ; idx < max_len ; idx += 1)
1113 val_bits[idx] = add_with_carry(left[idx], ~rpad, carry);
1114
1115 } else {
1116
1117 for (unsigned idx = min_len ; idx < max_len ; idx += 1)
1118 val_bits[idx] = add_with_carry(lpad, ~right[idx], carry);
1119 }
1120
1121 unsigned len = max_len;
1122 if (signed_flag && !has_len_flag) {
1123 val_bits[max_len] = add_with_carry(lpad, ~rpad, carry);
1124 if (val_bits[max_len] != val_bits[max_len-1]) len += 1;
1125 }
1126 verinum result (val_bits, len, has_len_flag);
1127 result.has_sign(signed_flag);
1128
1129 delete[]val_bits;
1130
1131 return result;
1132 }
1133
operator -(const verinum & right)1134 verinum operator - (const verinum&right)
1135 {
1136 const bool has_len_flag = right.has_len();
1137 const bool signed_flag = right.has_sign();
1138
1139 unsigned len = right.len();
1140
1141 // If either the left or right values are undefined, the
1142 // entire result is undefined.
1143 if (!right.is_defined()) {
1144 verinum result (verinum::Vx, has_len_flag ? len : 1, has_len_flag);
1145 result.has_sign(signed_flag);
1146 return result;
1147 }
1148
1149 verinum::V*val_bits = new verinum::V[len+1];
1150
1151 verinum::V carry = verinum::V1;
1152 for (unsigned idx = 0 ; idx < len ; idx += 1)
1153 val_bits[idx] = add_with_carry(verinum::V0, ~right[idx], carry);
1154
1155 if (signed_flag && !has_len_flag) {
1156 val_bits[len] = add_with_carry(verinum::V0, ~sign_bit(right), carry);
1157 if (val_bits[len] != val_bits[len-1]) len += 1;
1158 }
1159 verinum result (val_bits, len, has_len_flag);
1160 result.has_sign(signed_flag);
1161
1162 delete[]val_bits;
1163
1164 return result;
1165 }
1166
1167 /*
1168 * This operator multiplies the left number by the right number. The
1169 * result is signed only if both of the operands are signed. If either
1170 * operand is unsized, the resulting number is as large as the sum of
1171 * the sizes of the operands.
1172 *
1173 * The algorithm used is successive shift and add operations,
1174 * implemented as the nested loops.
1175 */
operator *(const verinum & left,const verinum & right)1176 verinum operator * (const verinum&left, const verinum&right)
1177 {
1178 const bool has_len_flag = left.has_len() && right.has_len();
1179 const bool signed_flag = left.has_sign() && right.has_sign();
1180
1181 const unsigned l_len = left.len();
1182 const unsigned r_len = right.len();
1183
1184 unsigned len = has_len_flag ? max(l_len, r_len) : l_len + r_len;
1185
1186 // If either the left or right values are undefined, the
1187 // entire result is undefined.
1188 if (!left.is_defined() || !right.is_defined()) {
1189 verinum result (verinum::Vx, has_len_flag ? len : 1, has_len_flag);
1190 result.has_sign(signed_flag);
1191 return result;
1192 }
1193
1194 verinum result(verinum::V0, len, has_len_flag);
1195 result.has_sign(signed_flag);
1196
1197 verinum::V r_sign = sign_bit(right);
1198 for (unsigned rdx = 0 ; rdx < len ; rdx += 1) {
1199
1200 verinum::V r_bit = rdx < r_len ? right.get(rdx) : r_sign;
1201 if (r_bit == verinum::V0)
1202 continue;
1203
1204 verinum::V l_sign = sign_bit(left);
1205 verinum::V carry = verinum::V0;
1206 for (unsigned ldx = 0 ; ldx < (len - rdx) ; ldx += 1) {
1207 verinum::V l_bit = ldx < l_len ? left[ldx] : l_sign;
1208 result.set(ldx+rdx, add_with_carry(l_bit,
1209 result[rdx+ldx],
1210 carry));
1211 }
1212 }
1213
1214 return trim_vnum(result);
1215 }
1216
make_p_one(unsigned len,bool has_len,bool has_sign)1217 static verinum make_p_one(unsigned len, bool has_len, bool has_sign)
1218 {
1219 verinum tmp (verinum::V0, has_len ? len : 2, has_len);
1220 tmp.set(0, verinum::V1);
1221 tmp.has_sign(has_sign);
1222 return tmp;
1223 }
1224
make_m_one(unsigned len,bool has_len,bool has_sign)1225 static verinum make_m_one(unsigned len, bool has_len, bool has_sign)
1226 {
1227 verinum tmp (verinum::V1, has_len ? len : 1, has_len);
1228 tmp.has_sign(has_sign);
1229 return tmp;
1230 }
1231
recursive_pow(const verinum & left,verinum & right)1232 static verinum recursive_pow(const verinum&left, verinum&right)
1233 {
1234 // If the exponent is zero, return a value of 1
1235 if (right.is_zero()) {
1236 return make_p_one(left.len(), left.has_len(), left.has_sign());
1237 }
1238
1239 verinum result;
1240 if (right.get(0) == 1) {
1241 // The exponent is odd, so subtract 1 from it and recurse.
1242 // We know it's odd, so the subtraction is easy.
1243 right.set(0, verinum::V0);
1244 result = pow(left, right);
1245 result = left * result;
1246 } else {
1247 // The exponent is even, so divide it by 2 and recurse
1248 right = right >> 1;
1249 result = pow(left, right);
1250 result = result * result;
1251 }
1252 return result;
1253 }
1254
pow(const verinum & left,const verinum & right)1255 verinum pow(const verinum&left, const verinum&right)
1256 {
1257 verinum result;
1258
1259 // We need positive and negative one in a few places.
1260 verinum p_one = make_p_one(left.len(), left.has_len(), left.has_sign());
1261 verinum m_one = make_m_one(left.len(), left.has_len(), left.has_sign());
1262
1263 // If either the left or right values are undefined, the
1264 // entire result is undefined.
1265 if (!left.is_defined() || !right.is_defined()) {
1266 result = verinum(verinum::Vx, left.len(), left.has_len());
1267 result.has_sign(left.has_sign());
1268
1269 // If the right value is zero we need to set the result to 1.
1270 } else if (right.is_zero()) {
1271 result = p_one;
1272
1273 } else if (right.is_negative()) {
1274
1275 // 0 ** <negative> is 'bx.
1276 if (left.is_zero()) {
1277 result = verinum(verinum::Vx, left.len(), left.has_len());
1278 result.has_sign(left.has_sign());
1279
1280 // -1 ** <negative> is 1 or -1. Note that this must be done
1281 // before testing for +1 in case 'left' has a width of 1.
1282 } else if (left.has_sign() && left == m_one) {
1283 if (right.get(0) == verinum::V0) {
1284 result = p_one;
1285 } else {
1286 result = m_one;
1287 }
1288
1289 // 1 ** <negative> is 1.
1290 } else if (left == p_one) {
1291 result = p_one;
1292
1293 // Everything else is 0.
1294 } else {
1295 result = verinum(verinum::V0, left.len(), left.has_len());
1296 result.has_sign(left.has_sign());
1297 }
1298
1299 } else {
1300 verinum exponent = right;
1301 result = recursive_pow(left, exponent);
1302 }
1303
1304 return trim_vnum(result);
1305 }
1306
operator <<(const verinum & that,unsigned shift)1307 verinum operator << (const verinum&that, unsigned shift)
1308 {
1309 bool has_len_flag = that.has_len();
1310
1311 unsigned len = that.len();
1312 if (!has_len_flag) len += shift;
1313
1314 verinum result(verinum::V0, len, has_len_flag);
1315 result.has_sign(that.has_sign());
1316
1317 for (unsigned idx = shift ; idx < len ; idx += 1)
1318 result.set(idx, that.get(idx - shift));
1319
1320 return trim_vnum(result);
1321 }
1322
operator >>(const verinum & that,unsigned shift)1323 verinum operator >> (const verinum&that, unsigned shift)
1324 {
1325 bool has_len_flag = that.has_len();
1326
1327 unsigned len = that.len();
1328
1329 verinum::V sign_bit = that.has_sign() ? that.get(len-1) : verinum::V0;
1330
1331 if (shift >= len) {
1332 if (!has_len_flag) len = 1;
1333 verinum result(sign_bit, len, has_len_flag);
1334 result.has_sign(that.has_sign());
1335 return result;
1336 }
1337
1338 if (!has_len_flag) len -= shift;
1339 verinum result(sign_bit, len, has_len_flag);
1340 result.has_sign(that.has_sign());
1341
1342 for (unsigned idx = shift ; idx < that.len() ; idx += 1)
1343 result.set(idx-shift, that.get(idx));
1344
1345 return trim_vnum(result);
1346 }
1347
unsigned_divide(verinum num,verinum den,bool signed_result)1348 static verinum unsigned_divide(verinum num, verinum den, bool signed_result)
1349 {
1350 // We need the following calculations to be lossless. The
1351 // result will be cast to the required width by the caller.
1352 num.has_len(false);
1353 den.has_len(false);
1354
1355 unsigned nwid = num.len();
1356 while (nwid > 0 && (num.get(nwid-1) == verinum::V0))
1357 nwid -= 1;
1358
1359 unsigned dwid = den.len();
1360 while (dwid > 0 && (den.get(dwid-1) == verinum::V0))
1361 dwid -= 1;
1362
1363 if (dwid > nwid)
1364 return verinum(verinum::V0, 1);
1365
1366 den = den << (nwid-dwid);
1367
1368 unsigned idx = nwid - dwid + 1;
1369 verinum result (verinum::V0, signed_result ? idx + 1 : idx);
1370 if (signed_result) {
1371 result.set(idx, verinum::V0);
1372 result.has_sign(true);
1373 }
1374 while (idx > 0) {
1375 if (den <= num) {
1376 verinum dif = num - den;
1377 num = dif;
1378 result.set(idx-1, verinum::V1);
1379 }
1380 den = den >> 1;
1381 idx -= 1;
1382 }
1383
1384 return result;
1385 }
1386
unsigned_modulus(verinum num,verinum den)1387 static verinum unsigned_modulus(verinum num, verinum den)
1388 {
1389 // We need the following calculations to be lossless. The
1390 // result will be cast to the required width by the caller.
1391 num.has_len(false);
1392 den.has_len(false);
1393
1394 unsigned nwid = num.len();
1395 while (nwid > 0 && (num.get(nwid-1) == verinum::V0))
1396 nwid -= 1;
1397
1398 unsigned dwid = den.len();
1399 while (dwid > 0 && (den.get(dwid-1) == verinum::V0))
1400 dwid -= 1;
1401
1402 if (dwid > nwid)
1403 return num;
1404
1405 den = den << (nwid-dwid);
1406
1407 unsigned idx = nwid - dwid + 1;
1408 while (idx > 0) {
1409 if (den <= num) {
1410 verinum dif = num - den;
1411 num = dif;
1412 }
1413 den = den >> 1;
1414 idx -= 1;
1415 }
1416
1417 return num;
1418 }
1419
1420 /*
1421 * This operator divides the left number by the right number. The result
1422 * is signed only if both of the operands are signed.
1423 */
operator /(const verinum & left,const verinum & right)1424 verinum operator / (const verinum&left, const verinum&right)
1425 {
1426 const bool has_len_flag = left.has_len() && right.has_len();
1427 const bool signed_flag = left.has_sign() && right.has_sign();
1428
1429 unsigned use_len = left.len();
1430
1431 // If either the left or right values are undefined, or the
1432 // right value is zero, the entire result is undefined.
1433 if (!left.is_defined() || !right.is_defined() || right.is_zero()) {
1434 verinum result (verinum::Vx, use_len, has_len_flag);
1435 result.has_sign(signed_flag);
1436 return result;
1437 }
1438
1439 verinum result(verinum::Vz, use_len, has_len_flag);
1440
1441 /* do the operation differently, depending on whether the
1442 result is signed or not. */
1443 if (signed_flag) {
1444
1445 if (use_len <= (8*sizeof(long) - 1)) {
1446 long l = left.as_long();
1447 long r = right.as_long();
1448 bool overflow = (l == LONG_MIN) && (r == -1);
1449 long v = overflow ? LONG_MIN : l / r;
1450 for (unsigned idx = 0 ; idx < use_len ; idx += 1) {
1451 result.set(idx, (v & 1)? verinum::V1 : verinum::V0);
1452 v >>= 1;
1453 }
1454
1455 } else {
1456 verinum use_left, use_right;
1457 bool negative = false;
1458 if (left.is_negative()) {
1459 use_left = -left;
1460 negative = !negative;
1461 } else {
1462 use_left = left;
1463 }
1464 use_left.has_sign(false);
1465 if (right.is_negative()) {
1466 use_right = -right;
1467 negative = !negative;
1468 } else {
1469 use_right = right;
1470 }
1471 use_right.has_sign(false);
1472 result = unsigned_divide(use_left, use_right, true);
1473 if (negative) result = -result;
1474 }
1475
1476 } else {
1477
1478 if (use_len <= 8 * sizeof(unsigned long)) {
1479 /* Use native unsigned division to do the work. */
1480
1481 unsigned long l = left.as_ulong();
1482 unsigned long r = right.as_ulong();
1483 unsigned long v = l / r;
1484 for (unsigned idx = 0 ; idx < use_len ; idx += 1) {
1485 result.set(idx, (v & 1)? verinum::V1 : verinum::V0);
1486 v >>= 1;
1487 }
1488
1489 } else {
1490 result = unsigned_divide(left, right, false);
1491 }
1492 }
1493
1494 if (has_len_flag)
1495 result = cast_to_width(result, use_len);
1496
1497 result.has_sign(signed_flag);
1498 return trim_vnum(result);
1499 }
1500
operator %(const verinum & left,const verinum & right)1501 verinum operator % (const verinum&left, const verinum&right)
1502 {
1503 const bool has_len_flag = left.has_len() && right.has_len();
1504 const bool signed_flag = left.has_sign() && right.has_sign();
1505
1506 unsigned use_len = left.len();
1507
1508 // If either the left or right values are undefined, or the
1509 // right value is zero, the entire result is undefined.
1510 if (!left.is_defined() || !right.is_defined() || right.is_zero()) {
1511 verinum result (verinum::Vx, use_len, has_len_flag);
1512 result.has_sign(signed_flag);
1513 return result;
1514 }
1515
1516 verinum result(verinum::Vz, use_len, has_len_flag);
1517
1518 if (signed_flag) {
1519 if (use_len <= 8*sizeof(long)) {
1520 /* Use native signed modulus to do the work. */
1521 long l = left.as_long();
1522 long r = right.as_long();
1523 bool overflow = (l == LONG_MIN) && (r == -1);
1524 long v = overflow ? 0 : l % r;
1525 for (unsigned idx = 0 ; idx < use_len ; idx += 1) {
1526 result.set(idx, (v & 1)? verinum::V1 : verinum::V0);
1527 v >>= 1;
1528 }
1529 } else {
1530 verinum use_left, use_right;
1531 bool negative = false;
1532 if (left.is_negative()) {
1533 use_left = -left;
1534 negative = true;
1535 } else {
1536 use_left = left;
1537 }
1538 use_left.has_sign(false);
1539 if (right.is_negative()) {
1540 use_right = -right;
1541 } else {
1542 use_right = right;
1543 }
1544 use_right.has_sign(false);
1545 result = unsigned_modulus(use_left, use_right);
1546 if (negative) result = -result;
1547 }
1548 } else {
1549 if (use_len <= 8*sizeof(unsigned long)) {
1550 /* Use native unsigned modulus to do the work. */
1551 unsigned long l = left.as_ulong();
1552 unsigned long r = right.as_ulong();
1553 unsigned long v = l % r;
1554 for (unsigned idx = 0 ; idx < use_len ; idx += 1) {
1555 result.set(idx, (v & 1)? verinum::V1 : verinum::V0);
1556 v >>= 1;
1557 }
1558 } else {
1559 result = unsigned_modulus(left, right);
1560 }
1561 }
1562
1563 if (has_len_flag)
1564 result = cast_to_width(result, use_len);
1565
1566 result.has_sign(signed_flag);
1567 return trim_vnum(result);
1568 }
1569
concat(const verinum & left,const verinum & right)1570 verinum concat(const verinum&left, const verinum&right)
1571 {
1572 if (left.is_string() && right.is_string()) {
1573 std::string tmp = left.as_string() + right.as_string();
1574 verinum res (tmp);
1575 return res;
1576 }
1577
1578 verinum res (verinum::V0, left.len() + right.len());
1579 for (unsigned idx = 0 ; idx < right.len() ; idx += 1)
1580 res.set(idx, right.get(idx));
1581
1582 for (unsigned idx = 0 ; idx < left.len() ; idx += 1)
1583 res.set(idx+right.len(), left.get(idx));
1584
1585 return res;
1586 }
1587
operator ~(verinum::V l)1588 verinum::V operator ~ (verinum::V l)
1589 {
1590 switch (l) {
1591 case verinum::V0:
1592 return verinum::V1;
1593 case verinum::V1:
1594 return verinum::V0;
1595 default:
1596 return verinum::Vx;
1597 }
1598 }
1599
operator |(verinum::V l,verinum::V r)1600 verinum::V operator | (verinum::V l, verinum::V r)
1601 {
1602 if (l == verinum::V1)
1603 return verinum::V1;
1604 if (r == verinum::V1)
1605 return verinum::V1;
1606 if (l != verinum::V0)
1607 return verinum::Vx;
1608 if (r != verinum::V0)
1609 return verinum::Vx;
1610 return verinum::V0;
1611 }
1612
operator &(verinum::V l,verinum::V r)1613 verinum::V operator & (verinum::V l, verinum::V r)
1614 {
1615 if (l == verinum::V0)
1616 return verinum::V0;
1617 if (r == verinum::V0)
1618 return verinum::V0;
1619 if (l != verinum::V1)
1620 return verinum::Vx;
1621 if (r != verinum::V1)
1622 return verinum::Vx;
1623 return verinum::V1;
1624 }
1625
operator ^(verinum::V l,verinum::V r)1626 verinum::V operator ^ (verinum::V l, verinum::V r)
1627 {
1628 if (l == verinum::V0)
1629 return bit4_z2x(r);
1630 if (r == verinum::V0)
1631 return bit4_z2x(l);
1632 if ((l == verinum::V1) && (r == verinum::V1))
1633 return verinum::V0;
1634
1635 return verinum::Vx;
1636 }
1637