gem5  v22.1.0.0
sc_nbutils.hh
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_nbutils.h -- External and friend functions for both sc_signed and
23  sc_unsigned classes.
24 
25  Original Author: Ali Dasdan, Synopsys, Inc.
26 
27  *****************************************************************************/
28 
29 /*****************************************************************************
30 
31  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
32  changes you are making here.
33 
34  Name, Affiliation, Date:
35  Description of Modification:
36 
37  *****************************************************************************/
38 
39 // $Log: sc_nbutils.h,v $
40 // Revision 1.6 2011/09/08 16:12:15 acg
41 // Philipp A. Hartmann: fix issue with Sun machines wrt real math libraries.
42 //
43 // Revision 1.5 2011/08/26 23:00:01 acg
44 // Torsten Maehne: remove use of ieeefp.h.
45 //
46 // Revision 1.4 2011/08/15 16:43:24 acg
47 // Torsten Maehne: changes to remove unused argument warnings.
48 //
49 // Revision 1.3 2011/02/18 20:19:15 acg
50 // Andy Goodrich: updating Copyright notice.
51 //
52 // Revision 1.2 2010/09/06 16:35:48 acg
53 // Andy Goodrich: changed i386 to __i386__ in ifdef's.
54 //
55 // Revision 1.1.1.1 2006/12/15 20:20:05 acg
56 // SystemC 2.3
57 //
58 // Revision 1.3 2006/01/13 18:49:32 acg
59 // Added $Log command so that CVS check in comments are reproduced in the
60 // source.
61 //
62 
63 #ifndef __SYSTEMC_EXT_DT_INT_SC_NBUTILS_HH__
64 #define __SYSTEMC_EXT_DT_INT_SC_NBUTILS_HH__
65 
66 #include <cmath>
67 #include <ios>
68 #include <limits>
69 #include <ostream>
70 
71 #include "../../utils/sc_report_handler.hh"
72 #include "../bit/messages.hh"
73 #include "messages.hh"
74 #include "sc_nbdefs.hh"
75 
76 namespace sc_dt
77 {
78 
79 //-----------------------------------------------------------------------------
80 //"sc_io_base"
81 //
82 // This inline function returns the type of an i/o stream's base as a SystemC
83 // base designator.
84 // stream_object = reference to the i/o stream whose base is to be returned.
85 //
86 //"sc_io_show_base"
87 //
88 // This inline function returns true if the base should be shown when a SystemC
89 // value is displayed via the supplied stream operator.
90 // stream_object = reference to the i/o stream to return showbase value for.
91 //-----------------------------------------------------------------------------
92 inline sc_numrep
93 sc_io_base(::std::ostream &os, sc_numrep def_base)
94 {
95  std::ios::fmtflags flags = os.flags() & std::ios::basefield;
96  if (flags & ::std::ios::dec) return SC_DEC;
97  if (flags & ::std::ios::hex) return SC_HEX;
98  if (flags & ::std::ios::oct) return SC_OCT;
99  return def_base;
100 }
101 
102 inline bool
103 sc_io_show_base(::std::ostream &os)
104 {
105  return (os.flags() & ::std::ios::showbase) != 0;
106 }
107 
108 const std::string to_string(sc_numrep);
109 
110 inline ::std::ostream &
111 operator << (::std::ostream &os, sc_numrep numrep)
112 {
113  os << to_string(numrep);
114  return os;
115 }
116 
117 // ----------------------------------------------------------------------------
118 
119 // One transition of the FSM to find base and sign of a number.
120 extern small_type fsm_move(
121  char c, small_type &b, small_type &s, small_type &state);
122 
123 // Parse a character string into its equivalent binary bits.
124 extern void parse_binary_bits(
125  const char *src_p, int dst_n, sc_digit *data_p, sc_digit *ctrl_p=0);
126 
127 // Parse a character string into its equivalent hexadecimal bits.
128 extern void parse_hex_bits(
129  const char *src_p, int dst_n, sc_digit *data_p, sc_digit *ctrl_p=0);
130 
131 // Find the base and sign of a number in v.
132 extern const char *get_base_and_sign(
133  const char *v, small_type &base, small_type &sign);
134 
135 // Create a number out of v in base.
136 extern small_type
137 vec_from_str(int unb, int und, sc_digit *u,
138  const char *v, sc_numrep base=SC_NOBASE);
139 
140 
141 // ----------------------------------------------------------------------------
142 // Naming convention for the vec_ functions below:
143 // vec_OP(u, v, w) : computes w = u OP v.
144 // vec_OP_on(u, v) : computes u = u OP v if u has more digits than v.
145 // vec_OP_on2(u, v) : computes u = u OP v if u has fewer digits than v.
146 // _large : parameters are vectors.
147 // _small : one of the parameters is a single digit.
148 // Xlen : the number of digits in X.
149 // ----------------------------------------------------------------------------
150 
151 // ----------------------------------------------------------------------------
152 // Functions for vector addition: w = u + v or u += v.
153 // ----------------------------------------------------------------------------
154 
155 extern void vec_add(int ulen, const sc_digit *u,
156  int vlen, const sc_digit *v, sc_digit *w);
157 extern void vec_add_on(int ulen, sc_digit *u, int vlen, const sc_digit *v);
158 extern void vec_add_on2(int ulen, sc_digit *u, int vlen, const sc_digit *v);
159 extern void vec_add_small(int ulen, const sc_digit *u,
160  sc_digit v, sc_digit *w);
161 extern void vec_add_small_on(int ulen, sc_digit *u, sc_digit v);
162 
163 // ----------------------------------------------------------------------------
164 // Functions for vector subtraction: w = u - v, u -= v, or u = v - u.
165 // ----------------------------------------------------------------------------
166 
167 extern void vec_sub(int ulen, const sc_digit *u,
168  int vlen, const sc_digit *v, sc_digit *w);
169 extern void vec_sub_on(int ulen, sc_digit *u, int vlen, const sc_digit *v);
170 extern void vec_sub_on2(int ulen, sc_digit *u, int vlen, const sc_digit *v);
171 extern void vec_sub_small(int ulen, const sc_digit *u,
172  sc_digit v, sc_digit *w);
173 extern void vec_sub_small_on(int ulen, sc_digit *u, sc_digit v);
174 
175 
176 // ----------------------------------------------------------------------------
177 // Functions for vector multiplication: w = u * v or u *= v.
178 // ----------------------------------------------------------------------------
179 
180 extern void vec_mul(int ulen, const sc_digit *u,
181  int vlen, const sc_digit *v, sc_digit *w);
182 extern void vec_mul_small(int ulen, const sc_digit *u,
183  sc_digit v, sc_digit *w);
184 extern void vec_mul_small_on(int ulen, sc_digit *u, sc_digit v);
185 
186 
187 // ----------------------------------------------------------------------------
188 // Functions for vector division: w = u / v.
189 // ----------------------------------------------------------------------------
190 
191 extern void vec_div_large(int ulen, const sc_digit *u,
192  int vlen, const sc_digit *v, sc_digit *w);
193 extern void vec_div_small(int ulen, const sc_digit *u,
194  sc_digit v, sc_digit *w);
195 
196 
197 // ----------------------------------------------------------------------------
198 // Functions for vector remainder: w = u % v or u %= v.
199 // ----------------------------------------------------------------------------
200 
201 extern void vec_rem_large(int ulen, const sc_digit *u,
202  int vlen, const sc_digit *v, sc_digit *w);
203 extern sc_digit vec_rem_small(int ulen, const sc_digit *u, sc_digit v);
204 extern sc_digit vec_rem_on_small(int ulen, sc_digit *u, sc_digit v);
205 
206 
207 // ----------------------------------------------------------------------------
208 // Functions to convert between vectors of char and sc_digit.
209 // ----------------------------------------------------------------------------
210 
211 extern int vec_to_char(int ulen, const sc_digit *u, int vlen, uchar *v);
212 extern void vec_from_char(int ulen, const uchar *u, int vlen, sc_digit *v);
213 
214 
215 // ----------------------------------------------------------------------------
216 // Functions to shift left or right, or to create a mirror image of vectors.
217 // ----------------------------------------------------------------------------
218 
219 extern void vec_shift_left(int ulen, sc_digit *u, int nsl);
220 extern void vec_shift_right(int vlen, sc_digit *u, int nsr, sc_digit fill=0);
221 extern void vec_reverse(int unb, int und, sc_digit *ud, int l, int r=0);
222 
223 
224 // ----------------------------------------------------------------------------
225 // Various utility functions.
226 // ----------------------------------------------------------------------------
227 
228 // Return the low half part of d.
229 inline sc_digit low_half(sc_digit d) { return (d & HALF_DIGIT_MASK); }
230 
231 // Return the high half part of d. The high part of the digit may have
232 // more bits than BITS_PER_HALF_DIGIT due to, e.g., overflow in the
233 // multiplication. Hence, in other functions that use high_half(),
234 // make sure that the result contains BITS_PER_HALF_DIGIT if
235 // necessary. This is done by high_half_masked().
237 inline sc_digit
239 {
240  return (high_half(d) & HALF_DIGIT_MASK);
241 }
242 
243 // Concatenate the high part h and low part l. Assumes that h and l
244 // are less than or equal to HALF_DIGIT_MASK;
245 inline sc_digit
247 {
248  return ((h << BITS_PER_HALF_DIGIT) | l);
249 }
250 
251 // Create a number with n 1's.
252 inline sc_digit
254 {
255  return (((sc_digit) 1 << n) - 1);
256 }
257 
258 // Create a number with one 1 and n 0's.
259 inline sc_digit one_and_zeros(int n) { return ((sc_digit) 1 << n); }
260 
261 
262 // ----------------------------------------------------------------------------
263 
264 // Find the digit that bit i is in.
265 inline int digit_ord(int i) { return (i / BITS_PER_DIGIT); }
266 
267 // Find the bit in digit_ord(i) that bit i corressponds to.
268 inline int bit_ord(int i) { return (i % BITS_PER_DIGIT); }
269 
270 
271 // ----------------------------------------------------------------------------
272 // Functions to compare, zero, complement vector(s).
273 // ----------------------------------------------------------------------------
274 
275 // Compare u and v and return r
276 // r = 0 if u == v
277 // r < 0 if u < v
278 // r > 0 if u > v
279 // - Assume that all the leading zero digits are already skipped.
280 // - ulen and/or vlen can be zero.
281 // - Every digit is less than or equal to DIGIT_MASK;
282 inline int
283 vec_cmp(int ulen, const sc_digit *u,
284  int vlen, const sc_digit *v)
285 {
286 
287 #ifdef DEBUG_SYSTEMC
288  // sc_assert((ulen <= 0) || (u != NULL));
289  // sc_assert((vlen <= 0) || (v != NULL));
290 
291  // ulen and vlen can be equal to 0 because vec_cmp can be called
292  // after vec_skip_leading_zeros.
293  sc_assert((ulen >= 0) && (u != NULL));
294  sc_assert((vlen >= 0) && (v != NULL));
295  // If ulen > 0, then the leading digit of u must be non-zero.
296  sc_assert((ulen <= 0) || (u[ulen - 1] != 0));
297  sc_assert((vlen <= 0) || (v[vlen - 1] != 0));
298 #endif
299 
300  if (ulen != vlen)
301  return (ulen - vlen);
302 
303  // ulen == vlen >= 1
304  while ((--ulen >= 0) && (u[ulen] == v[ulen]))
305  {}
306 
307  if (ulen < 0)
308  return 0;
309 
310 #ifdef DEBUG_SYSTEMC
311  // Test to see if the result is wrong due to the presence of
312  // overflow bits.
313  sc_assert((u[ulen] & DIGIT_MASK) != (v[ulen] & DIGIT_MASK));
314 #endif
315 
316  return (int)(u[ulen] - v[ulen]);
317 }
318 
319 // Find the index of the first non-zero digit.
320 // - ulen (before) = the number of digits in u.
321 // - the returned value = the index of the first non-zero digit.
322 // A negative value of -1 indicates that every digit in u is zero.
323 inline int
325 {
326 
327 #ifdef DEBUG_SYSTEMC
328  // sc_assert((ulen <= 0) || (u != NULL));
329  sc_assert((ulen > 0) && (u != NULL));
330 #endif
331 
332  while ((--ulen >= 0) && (! u[ulen]))
333  {}
334 
335  return ulen;
336 }
337 
338 // Skip all the leading zero digits.
339 // - ulen (before) = the number of digits in u.
340 // - the returned value = the number of non-zero digits in u.
341 // - the returned value is non-negative.
342 inline int
344 {
345 #ifdef DEBUG_SYSTEMC
346  // sc_assert((ulen <= 0) || (u != NULL));
347  sc_assert((ulen > 0) && (u != NULL));
348 #endif
349 
350  return (1 + vec_find_first_nonzero(ulen, u));
351 }
352 
353 // Compare u and v and return r
354 // r = 0 if u == v
355 // r < 0 if u < v
356 // r > 0 if u > v
357 inline int
358 vec_skip_and_cmp(int ulen, const sc_digit *u, int vlen, const sc_digit *v)
359 {
360 #ifdef DEBUG_SYSTEMC
361  sc_assert((ulen > 0) && (u != NULL));
362  sc_assert((vlen > 0) && (v != NULL));
363 #endif
364 
365  ulen = vec_skip_leading_zeros(ulen, u);
366  vlen = vec_skip_leading_zeros(vlen, v);
367  // ulen and/or vlen can be equal to zero here.
368  return vec_cmp(ulen, u, vlen, v);
369 }
370 
371 // Set u[i] = 0 where i = from ... (ulen - 1).
372 inline void
373 vec_zero(int from, int ulen, sc_digit *u)
374 {
375 #ifdef DEBUG_SYSTEMC
376  sc_assert((ulen > 0) && (u != NULL));
377 #endif
378  for (int i = from; i < ulen; i++)
379  u[i] = 0;
380 }
381 
382 // Set u[i] = 0 where i = 0 .. (ulen - 1).
383 inline void vec_zero(int ulen, sc_digit *u) { vec_zero(0, ulen, u); }
384 
385 // Copy n digits from v to u.
386 inline void
387 vec_copy(int n, sc_digit *u, const sc_digit *v)
388 {
389 #ifdef DEBUG_SYSTEMC
390  sc_assert((n > 0) && (u != NULL) && (v != NULL));
391 #endif
392  for (int i = 0; i < n; ++i)
393  u[i] = v[i];
394 }
395 
396 // Copy v to u, where ulen >= vlen, and zero the rest of the digits in u.
397 inline void
398 vec_copy_and_zero(int ulen, sc_digit *u, int vlen, const sc_digit *v)
399 {
400 
401 #ifdef DEBUG_SYSTEMC
402  sc_assert((ulen > 0) && (u != NULL));
403  sc_assert((vlen > 0) && (v != NULL));
404  sc_assert(ulen >= vlen);
405 #endif
406  vec_copy(vlen, u, v);
407  vec_zero(vlen, ulen, u);
408 
409 }
410 
411 // 2's-complement the digits in u.
412 inline void
414 {
415 
416 #ifdef DEBUG_SYSTEMC
417  sc_assert((ulen > 0) && (u != NULL));
418 #endif
419 
420  sc_digit carry = 1;
421 
422  for (int i = 0; i < ulen; ++i) {
423  carry += (~u[i] & DIGIT_MASK);
424  u[i] = carry & DIGIT_MASK;
425  carry >>= BITS_PER_DIGIT;
426  }
427 }
428 
429 
430 // ----------------------------------------------------------------------------
431 // Functions to handle built-in types or signs.
432 // ----------------------------------------------------------------------------
433 
434 // u = v
435 // - v is an unsigned long or uint64, and positive integer.
436 template<class Type>
437 inline void
438 from_uint(int ulen, sc_digit *u, Type v)
439 {
440 #ifdef DEBUG_SYSTEMC
441  // sc_assert((ulen <= 0) || (u != NULL));
442  sc_assert((ulen > 0) && (u != NULL));
443  sc_assert(v >= 0);
444 #endif
445 
446  int i = 0;
447 
448  while (v && (i < ulen)) {
449  u[i++] = static_cast<sc_digit>(v & DIGIT_MASK);
450  v >>= BITS_PER_DIGIT;
451  }
452  vec_zero(i, ulen, u);
453 }
454 
455 #ifndef __GNUC__
456 # define SC_LIKELY_(x) !!(x)
457 #else
458 # define SC_LIKELY_(x) __builtin_expect(!!(x), 1)
459 #endif
460 
461 // Get u's sign and return its absolute value.
462 // u can be long, unsigned long, int64, or uint64.
463 template<class Type>
464 inline small_type
466 {
467  if (u > 0)
468  return SC_POS;
469 
470  if (u == 0)
471  return SC_ZERO;
472 
473  // no positive number representable for minimum value,
474  // leave as is to avoid Undefined Behaviour
475  if (SC_LIKELY_(u > (std::numeric_limits<Type>::min)()))
476  u = -u;
477 
478  return SC_NEG;
479 }
480 
481 #undef SC_LIKELY_
482 
483 
484 // Return us * vs:
485 // - Return SC_ZERO if either sign is SC_ZERO.
486 // - Return SC_POS if us == vs
487 // - Return SC_NEG if us != vs.
488 inline small_type
490 {
491  if ((us == SC_ZERO) || (vs == SC_ZERO))
492  return SC_ZERO;
493 
494  if (us == vs)
495  return SC_POS;
496 
497  return SC_NEG;
498 }
499 
500 
501 // ----------------------------------------------------------------------------
502 // Functions to test for errors and print out error messages.
503 // ----------------------------------------------------------------------------
504 
505 #ifdef SC_MAX_NBITS
506 
507 void test_bound_failed(int nb);
508 
509 inline void
510 test_bound(int nb)
511 {
512  if (nb > SC_MAX_NBITS) {
513  test_bound_failed(nb);
514  sc_core::sc_abort(); // can't recover from here
515  }
516 }
517 
518 #endif
519 
520 template<class Type>
521 inline void
523 {
524  if (s == 0) {
526  "div_by_zero<Type>(Type) : division by zero");
527  sc_core::sc_abort(); // can't recover from here
528  }
529 }
530 
531 
532 // ----------------------------------------------------------------------------
533 // Functions to check if a given vector is zero or make one.
534 // ----------------------------------------------------------------------------
535 
536 // If u[i] is zero for every i = 0,..., ulen - 1, return SC_ZERO,
537 // else return s.
538 inline small_type
540 {
541 
542 #ifdef DEBUG_SYSTEMC
543  // sc_assert(ulen >= 0);
544  sc_assert((ulen > 0) && (u != NULL));
545 #endif
546 
547  if (vec_find_first_nonzero(ulen, u) < 0)
548  return SC_ZERO;
549 
550  return s;
551 }
552 
553 // If u[i] is zero for every i = 0,..., ulen - 1, return true,
554 // else return false.
555 inline bool
556 check_for_zero(int ulen, const sc_digit *u)
557 {
558 
559 #ifdef DEBUG_SYSTEMC
560  // sc_assert(ulen >= 0);
561  sc_assert((ulen > 0) && (u != NULL));
562 #endif
563 
564  if (vec_find_first_nonzero(ulen, u) < 0)
565  return true;
566 
567  return false;
568 }
569 
570 inline small_type
572 {
573  vec_zero(nd, d);
574  return SC_ZERO;
575 }
576 
577 
578 // ----------------------------------------------------------------------------
579 // Functions for both signed and unsigned numbers to convert sign-magnitude
580 // (SM) and 2's complement (2C) representations.
581 // added = 1 => for signed.
582 // added = 0 => for unsigned.
583 // IF_SC_SIGNED can be used as 'added'.
584 // ----------------------------------------------------------------------------
585 
586 // Trim the extra leading bits of a signed or unsigned number.
587 inline void
588 trim(small_type added, int nb, int nd, sc_digit *d)
589 {
590 #ifdef DEBUG_SYSTEMC
591  sc_assert((nb > 0) && (nd > 0) && (d != NULL));
592 #endif
593  d[nd - 1] &= one_and_ones(bit_ord(nb - 1) + added);
594 }
595 
596 // Convert an (un)signed number from sign-magnitude representation to
597 // 2's complement representation and trim the extra bits.
598 inline void
600  small_type s, int nb, int nd, sc_digit *d)
601 {
602  if (s == SC_NEG) {
603  vec_complement(nd, d);
604  trim(added, nb, nd, d);
605  }
606 }
607 
608 // Convert an (un)signed number from sign-magnitude representation to
609 // 2's complement representation but do not trim the extra bits.
610 inline void
612 {
613  if (s == SC_NEG)
614  vec_complement(nd, d);
615 }
616 
617 
618 // ----------------------------------------------------------------------------
619 // Functions to convert between sign-magnitude (SM) and 2's complement
620 // (2C) representations of signed numbers.
621 // ----------------------------------------------------------------------------
622 
623 // Trim the extra leading bits off a signed number.
624 inline void
625 trim_signed(int nb, int nd, sc_digit *d)
626 {
627 #ifdef DEBUG_SYSTEMC
628  sc_assert((nb > 0) && (nd > 0) && (d != NULL));
629 #endif
630  d[nd - 1] &= one_and_ones(bit_ord(nb - 1) + 1);
631 }
632 
633 // Convert a signed number from 2's complement representation to
634 // sign-magnitude representation, and return its sign. nd is d's
635 // actual size, without zeros eliminated.
636 inline small_type
638 {
639 #ifdef DEBUG_SYSTEMC
640  sc_assert((nb > 0) && (nd > 0) && (d != NULL));
641 #endif
642 
643  small_type s;
644 
645  int xnb = bit_ord(nb - 1) + 1;
646 
647  // Test the sign bit.
648  if (d[nd - 1] & one_and_zeros(xnb - 1)) {
649  s = SC_NEG;
650  vec_complement(nd, d);
651  } else {
652  s = SC_POS;
653  }
654 
655  // Trim the last digit.
656  d[nd - 1] &= one_and_ones(xnb);
657 
658  // Check if the new number is zero.
659  if (s == SC_POS)
660  return check_for_zero(s, nd, d);
661 
662  return s;
663 }
664 
665 // Convert a signed number from sign-magnitude representation to 2's
666 // complement representation, get its sign, convert back to
667 // sign-magnitude representation, and return its sign. nd is d's
668 // actual size, without zeros eliminated.
669 inline small_type
671 {
672  convert_SM_to_2C(s, nd, d);
673  return convert_signed_2C_to_SM(nb, nd, d);
674 }
675 
676 // Convert a signed number from sign-magnitude representation to 2's
677 // complement representation and trim the extra bits.
678 inline void
680 {
681  convert_SM_to_2C_trimmed(1, s, nb, nd, d);
682 }
683 
684 // Convert a signed number from sign-magnitude representation to 2's
685 // complement representation but do not trim the extra bits.
686 inline void
688 {
689  convert_SM_to_2C(s, nd, d);
690 }
691 
692 
693 // ----------------------------------------------------------------------------
694 // Functions to convert between sign-magnitude (SM) and 2's complement
695 // (2C) representations of unsigned numbers.
696 // ----------------------------------------------------------------------------
697 
698 // Trim the extra leading bits off an unsigned number.
699 inline void
700 trim_unsigned(int nb, int nd, sc_digit *d)
701 {
702 #ifdef DEBUG_SYSTEMC
703  sc_assert((nb > 0) && (nd > 0) && (d != NULL));
704 #endif
705 
706  d[nd - 1] &= one_and_ones(bit_ord(nb - 1));
707 }
708 
709 // Convert an unsigned number from 2's complement representation to
710 // sign-magnitude representation, and return its sign. nd is d's
711 // actual size, without zeros eliminated.
712 inline small_type
714 {
715  trim_unsigned(nb, nd, d);
716  return check_for_zero(SC_POS, nd, d);
717 }
718 
719 // Convert an unsigned number from sign-magnitude representation to
720 // 2's complement representation, get its sign, convert back to
721 // sign-magnitude representation, and return its sign. nd is d's
722 // actual size, without zeros eliminated.
723 inline small_type
725 {
726  convert_SM_to_2C(s, nd, d);
727  return convert_unsigned_2C_to_SM(nb, nd, d);
728 }
729 
730 // Convert an unsigned number from sign-magnitude representation to
731 // 2's complement representation and trim the extra bits.
732 inline void
734 {
735  convert_SM_to_2C_trimmed(0, s, nb, nd, d);
736 }
737 
738 // Convert an unsigned number from sign-magnitude representation to
739 // 2's complement representation but do not trim the extra bits.
740 inline void
742 {
743  convert_SM_to_2C(s, nd, d);
744 }
745 
746 
747 // ----------------------------------------------------------------------------
748 // Functions to copy one (un)signed number to another.
749 // ----------------------------------------------------------------------------
750 
751 // Copy v to u.
752 inline void
754  int unb, int und, sc_digit *ud,
755  int vnb, int vnd, const sc_digit *vd)
756 {
757  if (und <= vnd) {
758  vec_copy(und, ud, vd);
759 
760  if (unb <= vnb)
761  us = convert_signed_SM_to_2C_to_SM(us, unb, und, ud);
762  } else { // und > vnd
763  vec_copy_and_zero(und, ud, vnd, vd);
764  }
765 }
766 
767 // Copy v to u.
768 inline void
770  int unb, int und, sc_digit *ud,
771  int /* vnb */, int vnd, const sc_digit *vd)
772 {
773  if (und <= vnd)
774  vec_copy(und, ud, vd);
775  else // und > vnd
776  vec_copy_and_zero(und, ud, vnd, vd);
777 
779 }
780 
781 
782 // ----------------------------------------------------------------------------
783 // Faster set(i, v), without bound checking.
784 // ----------------------------------------------------------------------------
785 
786 // A version of set(i, v) without bound checking.
787 inline void
788 safe_set(int i, bool v, sc_digit *d)
789 {
790 
791 #ifdef DEBUG_SYSTEMC
792  sc_assert((i >= 0) && (d != NULL));
793 #endif
794 
795  int bit_num = bit_ord(i);
796  int digit_num = digit_ord(i);
797 
798  if (v)
799  d[digit_num] |= one_and_zeros(bit_num);
800  else
801  d[digit_num] &= ~(one_and_zeros(bit_num));
802 }
803 
804 
805 // ----------------------------------------------------------------------------
806 // Function to check if a double number is bad (NaN or infinite).
807 // ----------------------------------------------------------------------------
808 
809 inline bool
810 is_nan(double v)
811 {
812  return std::numeric_limits<double>::has_quiet_NaN && (v != v);
813 }
814 
815 inline bool
816 is_inf(double v)
817 {
818  return v == std::numeric_limits<double>::infinity() ||
819  v == -std::numeric_limits<double>::infinity();
820 }
821 
822 inline void
824 {
825  // Windows throws exception.
826  if (is_nan(v) || is_inf(v))
828  "is_bad_double(double v) : "
829  "v is not finite - NaN or Inf");
830 }
831 
832 } // namespace sc_dt
833 
834 #endif // __SYSTEMC_EXT_DT_INT_SC_NBUTILS_HH__
atomic_var_t state
Definition: helpers.cc:188
uint8_t flags
Definition: helpers.cc:66
static const RegId & und(unsigned index)
Definition: int.hh:529
Bitfield< 31 > n
Definition: misc_types.hh:462
Bitfield< 7 > b
Definition: misc_types.hh:388
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 22 > u
Definition: misc_types.hh:359
Bitfield< 19 > vs
Definition: misc_types.hh:576
Bitfield< 9 > d
Definition: misc_types.hh:64
Bitfield< 5 > r
Definition: pagetable.hh:60
Bitfield< 1 > s
Definition: pagetable.hh:64
Bitfield< 55 > l
Definition: pagetable.hh:54
Bitfield< 0 > v
Definition: pagetable.hh:65
Bitfield< 2 > c
Definition: pagetable.hh:63
Bitfield< 6 > w
Definition: pagetable.hh:59
Bitfield< 51, 12 > base
Definition: pagetable.hh:141
Bitfield< 17 > os
Definition: misc.hh:810
double us
microsecond
Definition: core.cc:55
void sc_abort()
Definition: sc_report.cc:178
const char SC_ID_VALUE_NOT_VALID_[]
Definition: messages.cc:39
const char SC_ID_OPERATION_FAILED_[]
Definition: messages.cc:36
Definition: sc_bit.cc:68
sc_digit vec_rem_small(int ulen, const sc_digit *u, sc_digit v)
Definition: sc_nbutils.cc:1457
void vec_sub_on2(int ulen, sc_digit *ubegin, int vlen, const sc_digit *v)
Definition: sc_nbutils.cc:880
bool is_inf(double v)
Definition: sc_nbutils.hh:816
bool is_nan(double v)
Definition: sc_nbutils.hh:810
small_type convert_signed_2C_to_SM(int nb, int nd, sc_digit *d)
Definition: sc_nbutils.hh:637
int vec_find_first_nonzero(int ulen, const sc_digit *u)
Definition: sc_nbutils.hh:324
sc_digit high_half(sc_digit d)
Definition: sc_nbutils.hh:236
void copy_digits_unsigned(small_type &us, int unb, int und, sc_digit *ud, int, int vnd, const sc_digit *vd)
Definition: sc_nbutils.hh:769
void vec_copy_and_zero(int ulen, sc_digit *u, int vlen, const sc_digit *v)
Definition: sc_nbutils.hh:398
void vec_add_on(int ulen, sc_digit *ubegin, int vlen, const sc_digit *v)
Definition: sc_nbutils.cc:663
void vec_add_on2(int ulen, sc_digit *ubegin, int, const sc_digit *v)
Definition: sc_nbutils.cc:705
void convert_SM_to_2C_trimmed(small_type added, small_type s, int nb, int nd, sc_digit *d)
Definition: sc_nbutils.hh:599
int small_type
Definition: sc_nbdefs.hh:108
sc_digit one_and_ones(int n)
Definition: sc_nbutils.hh:253
sc_digit vec_rem_on_small(int ulen, sc_digit *u, sc_digit v)
Definition: sc_nbutils.cc:1487
void vec_div_small(int ulen, const sc_digit *u, sc_digit v, sc_digit *q)
Definition: sc_nbutils.cc:1273
void convert_unsigned_SM_to_2C_trimmed(small_type s, int nb, int nd, sc_digit *d)
Definition: sc_nbutils.hh:733
sc_digit high_half_masked(sc_digit d)
Definition: sc_nbutils.hh:238
sc_numrep sc_io_base(::std::ostream &os, sc_numrep def_base)
Definition: sc_nbutils.hh:93
void vec_sub_on(int ulen, sc_digit *ubegin, int vlen, const sc_digit *v)
Definition: sc_nbutils.cc:843
int vec_cmp(int ulen, const sc_digit *u, int vlen, const sc_digit *v)
Definition: sc_nbutils.hh:283
void vec_shift_right(int ulen, sc_digit *u, int nsr, sc_digit fill)
Definition: sc_nbutils.cc:1640
int vec_skip_and_cmp(int ulen, const sc_digit *u, int vlen, const sc_digit *v)
Definition: sc_nbutils.hh:358
sc_numrep
Definition: sc_nbdefs.hh:82
@ SC_HEX
Definition: sc_nbdefs.hh:87
@ SC_NOBASE
Definition: sc_nbdefs.hh:83
@ SC_OCT
Definition: sc_nbdefs.hh:85
@ SC_DEC
Definition: sc_nbdefs.hh:86
void vec_reverse(int unb, int und, sc_digit *ud, int l, int r)
Definition: sc_nbutils.cc:1697
const char * get_base_and_sign(const char *v, small_type &b, small_type &s)
Definition: sc_nbutils.cc:197
void convert_signed_SM_to_2C(small_type s, int nd, sc_digit *d)
Definition: sc_nbutils.hh:687
void vec_add(int ulen, const sc_digit *u, int vlen, const sc_digit *v, sc_digit *w)
Definition: sc_nbutils.cc:622
small_type convert_unsigned_2C_to_SM(int nb, int nd, sc_digit *d)
Definition: sc_nbutils.hh:713
void vec_sub_small_on(int ulen, sc_digit *u, sc_digit v)
Definition: sc_nbutils.cc:944
small_type get_sign(Type &u)
Definition: sc_nbutils.hh:465
void from_uint(int ulen, sc_digit *u, Type v)
Definition: sc_nbutils.hh:438
small_type convert_unsigned_SM_to_2C_to_SM(small_type s, int nb, int nd, sc_digit *d)
Definition: sc_nbutils.hh:724
small_type convert_signed_SM_to_2C_to_SM(small_type s, int nb, int nd, sc_digit *d)
Definition: sc_nbutils.hh:670
small_type make_zero(int nd, sc_digit *d)
Definition: sc_nbutils.hh:571
void vec_add_small(int ulen, const sc_digit *u, sc_digit v, sc_digit *w)
Definition: sc_nbutils.cc:742
void vec_div_large(int ulen, const sc_digit *u, int vlen, const sc_digit *v, sc_digit *w)
Definition: sc_nbutils.cc:1135
void vec_shift_left(int ulen, sc_digit *u, int nsl)
Definition: sc_nbutils.cc:1587
void vec_copy(int n, sc_digit *u, const sc_digit *v)
Definition: sc_nbutils.hh:387
void vec_mul_small_on(int ulen, sc_digit *u, sc_digit v)
Definition: sc_nbutils.cc:1101
void vec_sub_small(int ulen, const sc_digit *u, sc_digit v, sc_digit *w)
Definition: sc_nbutils.cc:911
int digit_ord(int i)
Definition: sc_nbutils.hh:265
sc_concref_r< sc_bitref_r< T1 >, sc_bitref_r< T2 > > concat(sc_bitref_r< T1 >, sc_bitref_r< T2 >)
void safe_set(int i, bool v, sc_digit *d)
Definition: sc_nbutils.hh:788
sc_digit low_half(sc_digit d)
Definition: sc_nbutils.hh:229
void is_bad_double(double v)
Definition: sc_nbutils.hh:823
small_type check_for_zero(small_type s, int ulen, const sc_digit *u)
Definition: sc_nbutils.hh:539
int vec_to_char(int ulen, const sc_digit *u, int vlen, uchar *v)
Definition: sc_nbutils.cc:1517
void vec_sub(int ulen, const sc_digit *u, int vlen, const sc_digit *v, sc_digit *w)
Definition: sc_nbutils.cc:802
void vec_add_small_on(int ulen, sc_digit *u, sc_digit v)
Definition: sc_nbutils.cc:774
int bit_ord(int i)
Definition: sc_nbutils.hh:268
void vec_mul(int ulen, const sc_digit *u, int vlen, const sc_digit *vbegin, sc_digit *wbegin)
Definition: sc_nbutils.cc:963
void vec_complement(int ulen, sc_digit *u)
Definition: sc_nbutils.hh:413
void convert_SM_to_2C(small_type s, int nd, sc_digit *d)
Definition: sc_nbutils.hh:611
void convert_signed_SM_to_2C_trimmed(small_type s, int nb, int nd, sc_digit *d)
Definition: sc_nbutils.hh:679
small_type vec_from_str(int unb, int und, sc_digit *u, const char *v, sc_numrep base)
Definition: sc_nbutils.cc:545
sc_signed operator<<(const sc_signed &u, const sc_int_base &v)
Definition: sc_signed.cc:853
void div_by_zero(Type s)
Definition: sc_nbutils.hh:522
unsigned int sc_digit
Definition: sc_nbdefs.hh:163
small_type fsm_move(char c, small_type &b, small_type &s, small_type &state)
Definition: sc_nbutils.cc:142
small_type mul_signs(small_type us, small_type vs)
Definition: sc_nbutils.hh:489
void vec_zero(int from, int ulen, sc_digit *u)
Definition: sc_nbutils.hh:373
void vec_mul_small(int ulen, const sc_digit *u, sc_digit v, sc_digit *w)
Definition: sc_nbutils.cc:1071
const std::string to_string(sc_enc enc)
Definition: sc_fxdefs.cc:60
bool sc_io_show_base(::std::ostream &os)
Definition: sc_nbutils.hh:103
unsigned char uchar
Definition: sc_nbdefs.hh:104
void vec_from_char(int ulen, const uchar *u, int vlen, sc_digit *v)
Definition: sc_nbutils.cc:1552
void trim_signed(int nb, int nd, sc_digit *d)
Definition: sc_nbutils.hh:625
void trim(small_type added, int nb, int nd, sc_digit *d)
Definition: sc_nbutils.hh:588
void convert_unsigned_SM_to_2C(small_type s, int nd, sc_digit *d)
Definition: sc_nbutils.hh:741
sc_digit one_and_zeros(int n)
Definition: sc_nbutils.hh:259
void parse_hex_bits(const char *src_p, int dst_n, sc_digit *data_p, sc_digit *ctrl_p)
Definition: sc_nbutils.cc:385
void trim_unsigned(int nb, int nd, sc_digit *d)
Definition: sc_nbutils.hh:700
void vec_rem_large(int ulen, const sc_digit *u, int vlen, const sc_digit *v, sc_digit *w)
Definition: sc_nbutils.cc:1332
int vec_skip_leading_zeros(int ulen, const sc_digit *u)
Definition: sc_nbutils.hh:343
void parse_binary_bits(const char *src_p, int dst_n, sc_digit *data_p, sc_digit *ctrl_p)
Definition: sc_nbutils.cc:256
void copy_digits_signed(small_type &us, int unb, int und, sc_digit *ud, int vnb, int vnd, const sc_digit *vd)
Definition: sc_nbutils.hh:753
#define DIGIT_MASK
Definition: sc_nbdefs.hh:129
#define HALF_DIGIT_MASK
Definition: sc_nbdefs.hh:137
#define SC_NEG
Definition: sc_nbdefs.hh:99
#define SC_ZERO
Definition: sc_nbdefs.hh:100
#define BITS_PER_DIGIT
Definition: sc_nbdefs.hh:127
#define BITS_PER_HALF_DIGIT
Definition: sc_nbdefs.hh:135
#define SC_POS
Definition: sc_nbdefs.hh:101
#define SC_LIKELY_(x)
Definition: sc_nbutils.hh:456
#define sc_assert(expr)
#define SC_REPORT_ERROR(msg_type, msg)

Generated on Wed Dec 21 2022 10:22:42 for gem5 by doxygen 1.9.1