gem5  v21.1.0.2
scfx_rep.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  scfx_rep.cpp -
23 
24  Original Author: Robert Graulich, Synopsys, Inc.
25  Martin Janssen, 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 
40 // $Log: scfx_rep.cpp,v $
41 // Revision 1.4 2011/08/24 22:05:43 acg
42 // Torsten Maehne: initialization changes to remove warnings.
43 //
44 // Revision 1.3 2011/08/15 16:43:24 acg
45 // Torsten Maehne: changes to remove unused argument warnings.
46 //
47 // Revision 1.2 2009/02/28 00:26:20 acg
48 // Andy Goodrich: bug fixes.
49 //
50 // Revision 1.2 2008/11/06 17:22:47 acg
51 // Andy Goodrich: bug fixes for 2.2.1.
52 //
53 // Revision 1.1.1.1 2006/12/15 20:31:36 acg
54 // SystemC 2.2
55 //
56 // Revision 1.3 2006/01/13 18:53:58 acg
57 // Andy Goodrich: added $Log command so that CVS comments are reproduced in
58 // the source.
59 //
60 
61 #include <cctype>
62 #include <cmath>
63 #include <cstdio>
64 #include <cstdlib>
65 
66 #include "base/compiler.hh"
76 
77 namespace sc_dt
78 {
79 
80 // ----------------------------------------------------------------------------
81 // some utilities
82 // ----------------------------------------------------------------------------
83 
84 static scfx_pow10 pow10_fx;
85 
87 
88 static inline int
89 n_word(int x)
90 {
91  return (x + bits_in_word - 1) / bits_in_word;
92 }
93 
94 
95 // ----------------------------------------------------------------------------
96 // CONSTRUCTORS
97 // ----------------------------------------------------------------------------
98 
100  m_mant(min_mant), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
101  m_r_flag(false)
102 {
103  set_zero();
104 }
105 
106 scfx_rep::scfx_rep(int a) : m_mant(min_mant), m_wp(), m_sign(), m_state(),
107  m_msw(), m_lsw(), m_r_flag(false)
108 {
109  if (a != 0) {
110  m_mant.clear();
111  m_wp = m_msw = m_lsw = 2;
112  m_state = normal;
113  if (a > 0) {
114  m_mant[2] = a;
115  m_sign = 1;
116  } else {
117  m_mant[2] = -a;
118  m_sign = -1;
119  }
120  } else {
121  set_zero();
122  }
123 }
124 
125 scfx_rep::scfx_rep(unsigned int a) : m_mant(min_mant), m_wp(), m_sign(),
126  m_state(), m_msw(), m_lsw(), m_r_flag(false)
127 {
128  if (a != 0) {
129  m_mant.clear();
130  m_wp = m_msw = m_lsw = 2;
131  m_state = normal;
132  m_mant[2] = a;
133  m_sign = 1;
134  } else {
135  set_zero();
136  }
137 }
138 
139 scfx_rep::scfx_rep(long a) :
140  m_mant(min_mant), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
141  m_r_flag(false)
142 {
143  if (a != 0) {
144  m_mant.clear();
145  m_state = normal;
146  if (a > 0) {
147  m_sign = 1;
148  } else {
149  a = -a;
150  m_sign = -1;
151  }
152 # if SC_LONG_64
153  m_wp = 1;
154  m_mant[1] = static_cast<word>(a);
155  m_mant[2] = static_cast<word>(a >> bits_in_word);
156  find_sw();
157 # else
158  m_wp = 2;
159  m_msw = 2;
160  m_lsw = 2;
161  m_mant[2] = a;
162 # endif
163  } else {
164  set_zero();
165  }
166 }
167 
168 scfx_rep::scfx_rep(unsigned long a) :
169  m_mant(min_mant), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
170  m_r_flag(false)
171 {
172  if (a != 0) {
173  m_mant.clear();
174  m_wp = m_msw = m_lsw = 2;
175  m_state = normal;
176 # if SC_LONG_64
177  m_wp = 1;
178  m_mant[1] = static_cast<word>(a);
179  m_mant[2] = static_cast<word>(a >> bits_in_word);
180  find_sw();
181 # else
182  m_wp = 2;
183  m_msw = 2;
184  m_lsw = 2;
185  m_mant[2] = a;
186 # endif
187  m_sign = 1;
188  }
189  else
190  set_zero();
191 }
192 
193 scfx_rep::scfx_rep(double a) :
194  m_mant(min_mant), m_wp(0), m_sign(), m_state(normal), m_msw(0),
195  m_lsw(0), m_r_flag(false)
196 {
197  m_mant.clear();
198 
200 
201  m_sign = id.negative() ? -1 : 1;
202 
203  if (id.is_nan()) {
205  } else if (id.is_inf()) {
206  m_state = infinity;
207  } else if (id.is_subnormal()) {
208  m_mant[0] = id.mantissa1();
209  m_mant[1] = id.mantissa0();
210  normalize(id.exponent() + 1 - SCFX_IEEE_DOUBLE_M_SIZE);
211  } else if (id.is_normal()) {
212  m_mant[0] = id.mantissa1();
213  m_mant[1] = id.mantissa0() | (1 << mantissa0_size);
214  normalize(id.exponent() - SCFX_IEEE_DOUBLE_M_SIZE);
215  }
216 }
217 
219  m_mant(min_mant), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
220  m_r_flag(false)
221 {
222  if (a != 0) {
223  m_mant.clear();
224  m_wp = 1;
226  if (a > 0) {
227  m_mant[1] = static_cast<word>(a);
228  m_mant[2] = static_cast<word>(a >> bits_in_word);
229  m_sign = 1;
230  } else {
231  m_mant[1] = static_cast<word>(-a);
232  m_mant[2] = static_cast<word>((-a) >> bits_in_word);
233  m_sign = -1;
234  }
235  find_sw();
236  } else {
237  set_zero();
238  }
239 }
240 
242  m_mant(min_mant), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
243  m_r_flag(false)
244 {
245  if (a != 0) {
246  m_mant.clear();
247  m_wp = 1;
248  m_state = normal;
249  m_mant[1] = static_cast<word>(a);
250  m_mant[2] = static_cast<word>(a >> bits_in_word);
251  m_sign = 1;
252  find_sw();
253  } else {
254  set_zero();
255  }
256 }
257 
258 scfx_rep::scfx_rep(const sc_signed &a) :
259  m_mant(min_mant), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
260  m_r_flag(false)
261 {
262  if (a.iszero()) {
263  set_zero();
264  } else {
265  int words = n_word(a.length());
266  if (words > size())
267  resize_to(words);
268  m_mant.clear();
269  m_wp = 0;
270  m_state = normal;
271  if (a.sign()) {
272  sc_signed a2 = -a;
273  for (int i = 0; i < a2.length(); ++i) {
274  if (a2[i]) {
276  m_mant[x.wi()] |= 1 << x.bi();
277  }
278  }
279  m_sign = -1;
280  } else {
281  for (int i = 0; i < a.length(); ++i) {
282  if (a[i]) {
283  scfx_index x = calc_indices(i);
284  m_mant[x.wi()] |= 1 << x.bi();
285  }
286  }
287  m_sign = 1;
288  }
289  find_sw();
290  }
291 }
292 
293 scfx_rep::scfx_rep(const sc_unsigned &a) :
294  m_mant(min_mant), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
295  m_r_flag(false)
296 {
297  if (a.iszero()) {
298  set_zero();
299  } else {
300  int words = n_word(a.length());
301  if (words > size())
302  resize_to(words);
303  m_mant.clear();
304  m_wp = 0;
305  m_state = normal;
306  for (int i = 0; i < a.length(); ++i) {
307  if (a[i]) {
308  scfx_index x = calc_indices(i);
309  m_mant[x.wi()] |= 1 << x.bi();
310  }
311  }
312  m_sign = 1;
313  find_sw();
314  }
315 }
316 
317 // copy constructor
318 scfx_rep::scfx_rep(const scfx_rep &a) :
319  m_mant(a.m_mant), m_wp(a.m_wp), m_sign(a.m_sign), m_state(a.m_state),
320  m_msw(a.m_msw), m_lsw(a.m_lsw), m_r_flag(false)
321 {}
322 
323 
324 // ----------------------------------------------------------------------------
325 // OPERATORS : new, delete
326 //
327 // Memory management for class scfx_rep.
328 // ----------------------------------------------------------------------------
329 
330 union scfx_rep_node
331 {
332  char data[sizeof(scfx_rep)];
334 };
335 
336 static scfx_rep_node *list = 0;
337 
338 void *
339 scfx_rep::operator new(std::size_t size)
340 {
341  const int ALLOC_SIZE = 1024;
342 
343  if (size != sizeof(scfx_rep))
344  return ::operator new(size);
345 
346  if (!list) {
347  list = new scfx_rep_node[ALLOC_SIZE];
348  for (int i = 0; i < ALLOC_SIZE - 1; i++)
349  list[i].next = list + i + 1;
350  list[ALLOC_SIZE - 1].next = 0;
351  }
352 
353  scfx_rep *ptr = reinterpret_cast<scfx_rep *>(list->data);
354  list = list->next;
355 
356  return ptr;
357 }
358 
359 void
360 scfx_rep::operator delete(void *ptr, std::size_t size)
361 {
362  if (size != sizeof(scfx_rep)) {
363  ::operator delete(ptr);
364  return;
365  }
366 
367  scfx_rep_node *node = static_cast<scfx_rep_node *>(ptr);
368  node->next = list;
369  list = node;
370 }
371 
372 
373 // ----------------------------------------------------------------------------
374 // METHOD : from_string
375 //
376 // Convert from character string to sc_fxrep.
377 // ----------------------------------------------------------------------------
378 
379 #define SCFX_FAIL_IF_(cnd) \
380 { \
381  if ((cnd)) { \
382  m_state = not_a_number; \
383  m_mant.clear(); /* to avoid Purify UMRs during assignment */ \
384  return; \
385  } \
386 }
387 
388 void
389 scfx_rep::from_string(const char *s, int cte_wl)
390 {
391  SCFX_FAIL_IF_(s == 0 || *s == 0);
392 
393  scfx_string s2;
394  s2 += s;
395  s2 += '\0';
396 
397  bool sign_char;
398  m_sign = scfx_parse_sign(s, sign_char);
399 
400  sc_numrep numrep = scfx_parse_prefix(s);
401 
402  int base = 0;
403 
404  switch (numrep) {
405  case SC_DEC:
406  {
407  base = 10;
408  if (scfx_is_nan(s)) { // special case: NaN
410  m_mant.clear(); /* to avoid Purify UMRs during assignment */
411  return;
412  }
413  if (scfx_is_inf(s)) { // special case: Infinity
414  m_state = infinity;
415  m_mant.clear(); /* to avoid Purify UMRs during assignment */
416  return;
417  }
418  break;
419  }
420  case SC_BIN:
421  case SC_BIN_US:
422  {
423  SCFX_FAIL_IF_(sign_char);
424  base = 2;
425  break;
426  }
427 
428  case SC_BIN_SM:
429  {
430  base = 2;
431  break;
432  }
433  case SC_OCT:
434  case SC_OCT_US:
435  {
436  SCFX_FAIL_IF_(sign_char);
437  base = 8;
438  break;
439  }
440  case SC_OCT_SM:
441  {
442  base = 8;
443  break;
444  }
445  case SC_HEX:
446  case SC_HEX_US:
447  {
448  SCFX_FAIL_IF_(sign_char);
449  base = 16;
450  break;
451  }
452  case SC_HEX_SM:
453  {
454  base = 16;
455  break;
456  }
457  case SC_CSD:
458  {
459  SCFX_FAIL_IF_(sign_char);
460  base = 2;
461  scfx_csd2tc(s2);
462  s = (const char *)s2 + 4;
463  numrep = SC_BIN;
464  break;
465  }
466  default:
467  ;
468  }
469 
470  //
471  // find end of mantissa and count the digits and points
472  //
473 
474  const char *end = s;
475  bool based_point = false;
476  int int_digits = 0;
477  int frac_digits = 0;
478 
479  while (*end) {
480  if (scfx_exp_start(end))
481  break;
482 
483  if (*end == '.') {
484  SCFX_FAIL_IF_(based_point);
485  based_point = true;
486  } else {
487  SCFX_FAIL_IF_(!scfx_is_digit(*end, numrep));
488  if (based_point)
489  frac_digits++;
490  else
491  int_digits++;
492  }
493 
494  ++end;
495  }
496 
497  SCFX_FAIL_IF_(int_digits == 0 && frac_digits == 0);
498 
499  // [ exponent ]
500  int exponent = 0;
501 
502  if (*end) {
503  for (const char *e = end + 2; *e; ++e)
505  exponent = std::atoi(end + 1);
506  }
507 
508  //
509  // check if the mantissa is negative
510  //
511  bool mant_is_neg = false;
512  switch (numrep) {
513  case SC_BIN:
514  case SC_OCT:
515  case SC_HEX:
516  {
517  const char *p = s;
518  if (*p == '.')
519  ++p;
520 
521  mant_is_neg = (scfx_to_digit(* p, numrep) >= (base >> 1));
522  break;
523  }
524  default:
525  ;
526  }
527 
528  //
529  // convert the mantissa
530  //
531 
532  switch (base) {
533  case 2:
534  {
535  int bit_offset = exponent % bits_in_word;
536  int word_offset = exponent / bits_in_word;
537 
538  int_digits += bit_offset;
539  frac_digits -= bit_offset;
540 
541  int words = n_word(int_digits) + n_word(frac_digits);
542  if (words > size())
543  resize_to(words);
544  m_mant.clear();
545 
546  int j = n_word(frac_digits) * bits_in_word + int_digits - 1;
547 
548  for (; s < end; s++) {
549  switch (*s) {
550  case '1':
551  set_bin(j);
553  case '0':
554  j--;
556  case '.':
557  break;
558  default:
559  SCFX_FAIL_IF_(true); // should not happen
560  }
561  }
562 
563  m_wp = n_word(frac_digits) - word_offset;
564  break;
565  }
566  case 8:
567  {
568  exponent *= 3;
569  int_digits *= 3;
570  frac_digits *= 3;
571 
572  int bit_offset = exponent % bits_in_word;
573  int word_offset = exponent / bits_in_word;
574 
575  int_digits += bit_offset;
576  frac_digits -= bit_offset;
577 
578  int words = n_word(int_digits) + n_word(frac_digits);
579  if (words > size())
580  resize_to(words);
581  m_mant.clear();
582 
583  int j = n_word(frac_digits) * bits_in_word + int_digits - 3;
584 
585  for (; s < end; s++) {
586  switch (*s) {
587  case '7': case '6': case '5': case '4':
588  case '3': case '2': case '1':
589  set_oct(j, *s - '0');
591  case '0':
592  j -= 3;
594  case '.':
595  break;
596  default:
597  SCFX_FAIL_IF_(true); // should not happen
598  }
599  }
600 
601  m_wp = n_word(frac_digits) - word_offset;
602  break;
603  }
604  case 10:
605  {
606  word carry, temp;
607  int length = int_digits + frac_digits;
608  resize_to(sc_max(min_mant, n_word(4 * length)));
609 
610  m_mant.clear();
611  m_msw = m_lsw = 0;
612 
613  for (; s < end; s++) {
614  switch (*s) {
615  case '9': case '8': case '7': case '6': case '5':
616  case '4': case '3': case '2': case '1': case '0':
617  multiply_by_ten();
618  carry = *s - '0';
619  for (int i = 0; carry && i < m_mant.size(); i++) {
620  temp = m_mant[i];
621  temp += carry;
622  carry = temp < m_mant[i];
623  m_mant[i] = temp;
624  }
625  case '.':
626  break;
627  default:
628  SCFX_FAIL_IF_(true); // should not happen
629  }
630  }
631 
632  m_wp = 0;
633  find_sw();
634 
635  int denominator = frac_digits - exponent;
636 
637  if (denominator) {
638  scfx_rep frac_num = pow10_fx(denominator);
639  scfx_rep *temp_num =
640  div_scfx_rep(const_cast<const scfx_rep &>(*this),
641  frac_num, cte_wl);
642  *this = *temp_num;
643  delete temp_num;
644  }
645 
646  break;
647  }
648  case 16:
649  {
650  exponent *= 4;
651  int_digits *= 4;
652  frac_digits *= 4;
653 
654  int bit_offset = exponent % bits_in_word;
655  int word_offset = exponent / bits_in_word;
656 
657  int_digits += bit_offset;
658  frac_digits -= bit_offset;
659 
660  int words = n_word(int_digits) + n_word(frac_digits);
661  if (words > size())
662  resize_to(words);
663  m_mant.clear();
664 
665  int j = n_word(frac_digits) * bits_in_word + int_digits - 4;
666 
667  for (; s < end; s ++) {
668  switch (*s) {
669  case 'f': case 'e': case 'd': case 'c': case 'b': case 'a':
670  set_hex(j, *s - 'a' + 10);
671  j -= 4;
672  break;
673  case 'F': case 'E': case 'D': case 'C': case 'B': case 'A':
674  set_hex(j, *s - 'A' + 10);
675  j -= 4;
676  break;
677  case '9': case '8': case '7': case '6': case '5':
678  case '4': case '3': case '2': case '1':
679  set_hex(j, *s - '0');
681  case '0':
682  j -= 4;
684  case '.':
685  break;
686  default:
687  SCFX_FAIL_IF_(true); // should not happen
688  }
689  }
690 
691  m_wp = n_word(frac_digits) - word_offset;
692  break;
693  }
694  }
695 
696  m_state = normal;
697  find_sw();
698 
699  //
700  // two's complement of mantissa if it is negative
701  //
702  if (mant_is_neg) {
703  m_mant[m_msw] |= ~0U << scfx_find_msb(m_mant[m_msw]);
704  for (int i = m_msw + 1; i < m_mant.size(); ++i)
705  m_mant[i] = static_cast<word>(-1);
707  inc(m_mant);
708  m_sign *= -1;
709  find_sw();
710  }
711 }
712 
713 #undef SCFX_FAIL_IF_
714 
715 // ----------------------------------------------------------------------------
716 // METHOD : to_double
717 //
718 // Convert from scfx_rep to double.
719 // ----------------------------------------------------------------------------
720 
721 double
722 scfx_rep::to_double() const
723 {
724  scfx_ieee_double id;
725 
726  // handle special cases
727  if (is_nan()) {
728  id.set_nan();
729  return id;
730  }
731 
732  if (is_inf()) {
733  id.set_inf();
734  id.negative(m_sign < 0);
735  return id;
736  }
737 
738  if (is_zero()) {
739  id = 0.;
740  id.negative(m_sign < 0);
741  return id;
742  }
743 
744  int msb = scfx_find_msb(m_mant[m_msw]);
745 
746  int exp = (m_msw - m_wp) * bits_in_word + msb;
747 
748  if (exp > SCFX_IEEE_DOUBLE_E_MAX) {
749  id.set_inf();
750  id.negative(m_sign < 0);
751  return id;
752  }
753 
755  static_cast<int>(SCFX_IEEE_DOUBLE_M_SIZE))
756  {
757  id = 0.;
758  return id;
759  }
760 
761  int shift = mantissa0_size - msb;
762 
763  unsigned int m0;
764  unsigned int m1 = 0;
765  unsigned int guard = 0;
766 
767  if (shift == 0) {
768  m0 = m_mant[m_msw] & ~(1 << mantissa0_size);
769  if (m_msw > m_lsw) {
770  m1 = m_mant[m_msw - 1];
771  if (m_msw - 1 > m_lsw)
772  guard = m_mant[m_msw - 2] >> (bits_in_word - 1);
773  }
774  } else if (shift < 0) {
775  m0 = (m_mant[m_msw] >> -shift) & ~(1 << mantissa0_size);
776  m1 = m_mant[m_msw] << (bits_in_word + shift);
777  if (m_msw > m_lsw) {
778  m1 |= m_mant[m_msw - 1] >> -shift;
779  guard = (m_mant[m_msw - 1] >> (-shift - 1)) & 1;
780  }
781  } else {
782  m0 = (m_mant[m_msw] << shift) & ~(1 << mantissa0_size);
783  if (m_msw > m_lsw) {
784  m0 |= m_mant[m_msw - 1] >> (bits_in_word - shift);
785  m1 = m_mant[m_msw - 1] << shift;
786  if (m_msw - 1 > m_lsw) {
787  m1 |= m_mant[m_msw - 2] >> (bits_in_word - shift);
788  guard = (m_mant[m_msw - 2] >> (bits_in_word - shift - 1)) & 1;
789  }
790  }
791  }
792 
793  if (exp < SCFX_IEEE_DOUBLE_E_MIN) {
794  m0 |= (1 << mantissa0_size);
795 
796  int subnormal_shift = SCFX_IEEE_DOUBLE_E_MIN - exp;
797 
798  if (subnormal_shift < bits_in_word) {
799  m1 = m1 >> subnormal_shift |
800  m0 << (bits_in_word - subnormal_shift);
801  m0 = m0 >> subnormal_shift;
802  } else {
803  m1 = m0 >> (subnormal_shift - bits_in_word);
804  m0 = 0;
805  }
806 
807  guard = 0;
808 
809  exp = SCFX_IEEE_DOUBLE_E_MIN - 1;
810  }
811 
812  id.mantissa0(m0);
813  id.mantissa1(m1);
814  id.exponent(exp);
815  id.negative(m_sign < 0);
816 
817  double result = id;
818 
819  if (guard != 0)
820  result += m_sign * scfx_pow2(exp - SCFX_IEEE_DOUBLE_M_SIZE);
821 
822  return result;
823 }
824 
825 
826 // ----------------------------------------------------------------------------
827 // METHOD : to_uint64
828 //
829 // Convert from scfx_rep to uint64.
830 // Truncates towards 0 _then_ wraps; infinities and NaN go to zero.
831 // ----------------------------------------------------------------------------
832 
833 uint64
834 scfx_rep::to_uint64() const
835 {
836  if (!is_normal() || is_zero()) {
837  return 0;
838  }
839 
840  uint64 result = 0;
841  int shift = 0;
842  int idx = m_wp;
843 
844  // Ignore bits off the top; they modulo out.
845  // Ignore bits off the bottom; we're truncating.
846  while (shift < 64 && m_msw >= idx && idx >= m_lsw) {
847  result += static_cast<uint64>(m_mant[idx]) << shift;
848  shift += bits_in_word;
849  idx += 1;
850  }
851 
852  return m_sign > 0 ? result : -result;
853 }
854 
855 
856 // ----------------------------------------------------------------------------
857 // METHOD : to_string
858 //
859 // Convert from scfx_rep to character string.
860 // ----------------------------------------------------------------------------
861 
862 void
863 print_dec(scfx_string &s, const scfx_rep &num, int w_prefix, sc_fmt fmt)
864 {
865  if (num.is_neg())
866  s += '-';
867 
868  if (w_prefix == 1) {
870  }
871 
872  if (num.is_zero()) {
873  s += '0';
874  return;
875  }
876 
877  // split 'num' into its integer and fractional part
878  scfx_rep int_part = num;
879  scfx_rep frac_part = num;
880 
881  int i;
882 
883  for (i = int_part.m_lsw; i <= int_part.m_msw && i < int_part.m_wp; i++)
884  int_part.m_mant[i] = 0;
885  int_part.find_sw();
886  if (int_part.m_wp < int_part.m_lsw)
887  int_part.resize_to(int_part.size() - int_part.m_wp, -1);
888 
889  for (i = frac_part.m_msw;
890  i >= frac_part.m_lsw && i >= frac_part.m_wp; i--)
891  frac_part.m_mant[i] = 0;
892  frac_part.find_sw();
893  if (frac_part.m_msw == frac_part.size() - 1)
894  frac_part.resize_to(frac_part.size() + 1, 1);
895 
896  // print integer part
897  int int_digits = 0;
898  int int_zeros = 0;
899 
900  if (!int_part.is_zero()) {
901  double int_wl = (int_part.m_msw - int_part.m_wp) * bits_in_word +
902  scfx_find_msb(int_part.m_mant[int_part.m_msw]) + 1;
903  int_digits = (int)std::ceil(int_wl * std::log10(2.));
904 
905  int len = s.length();
906  s.append(int_digits);
907 
908  bool zero_digits = (frac_part.is_zero() && fmt != SC_F);
909 
910  for (i = int_digits + len - 1; i >= len; i--) {
911  unsigned int remainder = int_part.divide_by_ten();
912  s[i] = static_cast<char>('0' + remainder);
913 
914  if (zero_digits) {
915  if (remainder == 0)
916  int_zeros++;
917  else
918  zero_digits = false;
919  }
920  }
921 
922  // discard trailing zeros from int_part
923  s.discard(int_zeros);
924 
925  if (s[len] == '0') {
926  // int_digits was overestimated by one
927  s.remove(len);
928  --int_digits;
929  }
930  }
931 
932  // print fractional part
933  int frac_digits = 0;
934  int frac_zeros = 0;
935 
936  if (!frac_part.is_zero()) {
937  s += '.';
938 
939  bool zero_digits = (int_digits == 0 && fmt != SC_F);
940 
941  double frac_wl = (frac_part.m_wp - frac_part.m_msw) * bits_in_word -
942  scfx_find_msb(frac_part.m_mant[frac_part.m_msw]) - 1;
943  frac_zeros = (int)std::floor(frac_wl * std::log10(2.));
944 
945  scfx_rep temp;
946  sc_dt::multiply(temp, frac_part, pow10_fx(frac_zeros));
947  frac_part = temp;
948  if (frac_part.m_msw == frac_part.size() - 1)
949  frac_part.resize_to(frac_part.size() + 1, 1);
950 
951  frac_digits = frac_zeros;
952  if (!zero_digits) {
953  for (i = 0; i < frac_zeros; i++)
954  s += '0';
955  frac_zeros = 0;
956  }
957 
958  while (!frac_part.is_zero()) {
959  frac_part.multiply_by_ten();
960  int n = frac_part.m_mant[frac_part.m_msw + 1];
961 
962  if (zero_digits) {
963  if (n == 0)
964  frac_zeros++;
965  else
966  zero_digits = false;
967  }
968 
969  if (! zero_digits)
970  s += static_cast<char>('0' + n);
971 
972  frac_part.m_mant[frac_part.m_msw + 1] = 0;
973  frac_digits++;
974  }
975  }
976 
977  // print exponent
978  if (fmt != SC_F) {
979  if (frac_digits == 0)
980  scfx_print_exp(s, int_zeros);
981  else if (int_digits == 0)
982  scfx_print_exp(s, -frac_zeros);
983  }
984 }
985 
986 void
987 print_other(scfx_string &s, const scfx_rep &a, sc_numrep numrep, int w_prefix,
988  sc_fmt fmt, const scfx_params *params)
989 {
990  scfx_rep b = a;
991 
992  sc_numrep numrep2 = numrep;
993 
994  bool numrep_is_sm = (numrep == SC_BIN_SM ||
995  numrep == SC_OCT_SM ||
996  numrep == SC_HEX_SM);
997 
998  if (numrep_is_sm) {
999  if (b.is_neg()) {
1000  s += '-';
1001  b = *neg_scfx_rep(a);
1002  }
1003  switch (numrep) {
1004  case SC_BIN_SM:
1005  numrep2 = SC_BIN_US;
1006  break;
1007  case SC_OCT_SM:
1008  numrep2 = SC_OCT_US;
1009  break;
1010  case SC_HEX_SM:
1011  numrep2 = SC_HEX_US;
1012  break;
1013  default:
1014  ;
1015  }
1016  }
1017 
1018  if (w_prefix != 0) {
1020  }
1021 
1022  numrep = numrep2;
1023 
1024  int msb, lsb;
1025 
1026  if (params != 0) {
1027  msb = params->iwl() - 1;
1028  lsb = params->iwl() - params->wl();
1029 
1030  if (params->enc() == SC_TC_ &&
1031  (numrep == SC_BIN_US ||
1032  numrep == SC_OCT_US ||
1033  numrep == SC_HEX_US) &&
1034  !numrep_is_sm &&
1035  params->wl() > 1) {
1036  --msb;
1037  } else if (params->enc() == SC_US_ &&
1038  (numrep == SC_BIN ||
1039  numrep == SC_OCT ||
1040  numrep == SC_HEX ||
1041  numrep == SC_CSD)) {
1042  ++msb;
1043  }
1044  } else {
1045  if (b.is_zero()) {
1046  msb = 0;
1047  lsb = 0;
1048  } else {
1049  msb = (b.m_msw - b.m_wp) * bits_in_word
1050  + scfx_find_msb(b.m_mant[ b.m_msw ]) + 1;
1051  while (b.get_bit(msb) == b.get_bit(msb - 1))
1052  --msb;
1053 
1054  if (numrep == SC_BIN_US ||
1055  numrep == SC_OCT_US ||
1056  numrep == SC_HEX_US) {
1057  --msb;
1058  }
1059 
1060  lsb = (b.m_lsw - b.m_wp) * bits_in_word +
1061  scfx_find_lsb(b.m_mant[b.m_lsw]);
1062 
1063  }
1064  }
1065 
1066  int step;
1067 
1068  switch (numrep) {
1069  case SC_BIN:
1070  case SC_BIN_US:
1071  case SC_CSD:
1072  step = 1;
1073  break;
1074  case SC_OCT:
1075  case SC_OCT_US:
1076  step = 3;
1077  break;
1078  case SC_HEX:
1079  case SC_HEX_US:
1080  step = 4;
1081  break;
1082  default:
1084  "unexpected sc_numrep");
1086  }
1087 
1088  msb = (int)std::ceil(double(msb + 1) / step) * step - 1;
1089 
1090  lsb = (int)std::floor(double(lsb) / step) * step;
1091 
1092  if (msb < 0) {
1093  s += '.';
1094  if (fmt == SC_F) {
1095  int sign = (b.is_neg()) ? (1 << step) - 1 : 0;
1096  for (int i = (msb + 1) / step; i < 0; i++) {
1097  if (sign < 10)
1098  s += static_cast<char>(sign + '0');
1099  else
1100  s += static_cast<char>(sign + 'a' - 10);
1101  }
1102  }
1103  }
1104 
1105  int i = msb;
1106  while (i >= lsb) {
1107  int value = 0;
1108  for (int j = step - 1; j >= 0; --j) {
1109  value += static_cast<int>(b.get_bit(i)) << j;
1110  --i;
1111  }
1112  if (value < 10)
1113  s += static_cast<char>(value + '0');
1114  else
1115  s += static_cast<char>(value + 'a' - 10);
1116  if (i == -1)
1117  s += '.';
1118  }
1119 
1120  if (lsb > 0 && fmt == SC_F) {
1121  for (int i = lsb / step; i > 0; i--)
1122  s += '0';
1123  }
1124 
1125  if (s[s.length() - 1] == '.')
1126  s.discard(1);
1127 
1128  if (fmt != SC_F) {
1129  if (msb < 0)
1130  scfx_print_exp(s, (msb + 1) / step);
1131  else if (lsb > 0)
1132  scfx_print_exp(s, lsb / step);
1133  }
1134 
1135  if (numrep == SC_CSD)
1136  scfx_tc2csd(s, w_prefix);
1137 }
1138 
1139 const char *
1140 scfx_rep::to_string(sc_numrep numrep, int w_prefix,
1141  sc_fmt fmt, const scfx_params *params) const
1142 {
1143  static scfx_string s;
1144 
1145  s.clear();
1146 
1147  if (is_nan()) {
1148  scfx_print_nan(s);
1149  } else if (is_inf()) {
1150  scfx_print_inf(s, is_neg());
1151  } else if (is_neg() && !is_zero() &&
1152  (numrep == SC_BIN_US ||
1153  numrep == SC_OCT_US ||
1154  numrep == SC_HEX_US)) {
1155  s += "negative";
1156  } else if (numrep == SC_DEC || numrep == SC_NOBASE) {
1157  sc_dt::print_dec(s, *this, w_prefix, fmt);
1158  } else {
1159  sc_dt::print_other(s, *this, numrep, w_prefix, fmt, params);
1160  }
1161 
1162  return s;
1163 }
1164 
1165 
1166 // ----------------------------------------------------------------------------
1167 // ADD
1168 //
1169 // add two mantissas of the same size
1170 // result has the same size
1171 // returns carry of operation
1172 // ----------------------------------------------------------------------------
1173 
1174 static inline int
1175 add_mants(int size, scfx_mant &result, const scfx_mant &a, const scfx_mant &b)
1176 {
1177  unsigned int carry = 0;
1178 
1179  int index = 0;
1180 
1181  do {
1182  word x = a[index];
1183  word y = b[index];
1184 
1185  y += carry;
1186  carry = y < carry;
1187  y += x;
1188  carry += y < x;
1189  result[index] = y;
1190  } while (++index < size);
1191 
1192  return (carry ? 1 : 0);
1193 }
1194 
1195 static inline int
1196 sub_mants(int size, scfx_mant &result, const scfx_mant &a, const scfx_mant &b)
1197 {
1198  unsigned carry = 0;
1199 
1200  int index = 0;
1201 
1202  do {
1203  word x = a[index];
1204  word y = b[index];
1205 
1206  y += carry;
1207  carry = y < carry;
1208  y = x - y;
1209  carry += y > x;
1210  result[index] = y;
1211  } while (++index < size);
1212 
1213  return (carry ? 1 : 0);
1214 }
1215 
1216 scfx_rep *
1217 add_scfx_rep(const scfx_rep &lhs, const scfx_rep &rhs, int max_wl)
1218 {
1219  scfx_rep &result = *new scfx_rep;
1220 
1221  //
1222  // check for special cases
1223  //
1224  if (lhs.is_nan() || rhs.is_nan() ||
1225  (lhs.is_inf() && rhs.is_inf() && lhs.m_sign != rhs.m_sign)) {
1226  result.set_nan();
1227  return &result;
1228  }
1229 
1230  if (lhs.is_inf()) {
1231  result.set_inf(lhs.m_sign);
1232  return &result;
1233  }
1234 
1235  if (rhs.is_inf()) {
1236  result.set_inf(rhs.m_sign);
1237  return &result;
1238  }
1239 
1240  //
1241  // align operands if needed
1242  //
1243  scfx_mant_ref lhs_mant;
1244  scfx_mant_ref rhs_mant;
1245 
1246  int len_mant = lhs.size();
1247  int new_wp = lhs.m_wp;
1248 
1249  align(lhs, rhs, new_wp, len_mant, lhs_mant, rhs_mant);
1250 
1251  //
1252  // size the result mantissa
1253  //
1254  result.resize_to(len_mant);
1255  result.m_wp = new_wp;
1256 
1257  //
1258  // do it
1259  //
1260  if (lhs.m_sign == rhs.m_sign) {
1261  add_mants(len_mant, result.m_mant, lhs_mant, rhs_mant);
1262  result.m_sign = lhs.m_sign;
1263  } else {
1264  int cmp = compare_abs(lhs, rhs);
1265 
1266  if (cmp == 1) {
1267  sub_mants(len_mant, result.m_mant, lhs_mant, rhs_mant);
1268  result.m_sign = lhs.m_sign;
1269  } else if (cmp == -1) {
1270  sub_mants(len_mant, result.m_mant, rhs_mant, lhs_mant);
1271  result.m_sign = rhs.m_sign;
1272  } else {
1273  result.m_mant.clear();
1274  result.m_sign = 1;
1275  }
1276  }
1277 
1278  result.find_sw();
1279  result.round(max_wl);
1280 
1281  return &result;
1282 }
1283 
1284 
1285 // ----------------------------------------------------------------------------
1286 // SUB
1287 //
1288 // sub two word's of the same size
1289 // result has the same size
1290 // returns carry of operation
1291 // ----------------------------------------------------------------------------
1292 
1293 static inline int
1294 sub_with_index(scfx_mant &a, int a_msw, int /*a_lsw*/,
1295  const scfx_mant &b, int b_msw, int b_lsw)
1296 {
1297  unsigned carry = 0;
1298 
1299  int size = b_msw - b_lsw;
1300  int a_index = a_msw - size;
1301  int b_index = b_msw - size;
1302 
1303  do {
1304  word x = a[a_index];
1305  word y = b[b_index];
1306 
1307  y += carry;
1308  carry = y < carry;
1309  y = x - y;
1310  carry += y > x;
1311  a[a_index] = y;
1312 
1313  a_index++;
1314  b_index++;
1315  } while (size--);
1316 
1317  if (carry) {
1318  // special case: a[a_msw + 1] == 1
1319  a[a_msw + 1] = 0;
1320  }
1321 
1322  return (carry ? 1 : 0);
1323 }
1324 
1325 scfx_rep *
1326 sub_scfx_rep(const scfx_rep &lhs, const scfx_rep &rhs, int max_wl)
1327 {
1328  scfx_rep &result = *new scfx_rep;
1329 
1330  //
1331  // check for special cases
1332  //
1333  if (lhs.is_nan() || rhs.is_nan() ||
1334  (lhs.is_inf() && rhs.is_inf() && lhs.m_sign == rhs.m_sign)) {
1335  result.set_nan();
1336  return &result;
1337  }
1338 
1339  if (lhs.is_inf()) {
1340  result.set_inf(lhs.m_sign);
1341  return &result;
1342  }
1343 
1344  if (rhs.is_inf()) {
1345  result.set_inf(-1 * rhs.m_sign);
1346  return &result;
1347  }
1348 
1349  //
1350  // align operands if needed
1351  //
1352  scfx_mant_ref lhs_mant;
1353  scfx_mant_ref rhs_mant;
1354 
1355  int len_mant = lhs.size();
1356  int new_wp = lhs.m_wp;
1357 
1358  align(lhs, rhs, new_wp, len_mant, lhs_mant, rhs_mant);
1359 
1360  //
1361  // size the result mantissa
1362  //
1363  result.resize_to(len_mant);
1364  result.m_wp = new_wp;
1365 
1366  //
1367  // do it
1368  //
1369  if (lhs.m_sign != rhs.m_sign) {
1370  add_mants(len_mant, result.m_mant, lhs_mant, rhs_mant);
1371  result.m_sign = lhs.m_sign;
1372  } else {
1373  int cmp = compare_abs(lhs, rhs);
1374 
1375  if (cmp == 1) {
1376  sub_mants(len_mant, result.m_mant, lhs_mant, rhs_mant);
1377  result.m_sign = lhs.m_sign;
1378  } else if (cmp == -1) {
1379  sub_mants(len_mant, result.m_mant, rhs_mant, lhs_mant);
1380  result.m_sign = -rhs.m_sign;
1381  } else {
1382  result.m_mant.clear();
1383  result.m_sign = 1;
1384  }
1385  }
1386 
1387  result.find_sw();
1388  result.round(max_wl);
1389 
1390  return &result;
1391 }
1392 
1393 
1394 // ----------------------------------------------------------------------------
1395 // MUL
1396 // ----------------------------------------------------------------------------
1397 
1398 union word_short
1399 {
1400  word l;
1401  struct
1402  {
1403 #if defined(SC_BOOST_BIG_ENDIAN)
1404  half_word u;
1405  half_word l;
1406 #elif defined(SC_BOOST_LITTLE_ENDIAN)
1407  half_word l;
1408  half_word u;
1409 #endif
1410  } s;
1411 };
1412 
1413 #if defined(SC_BOOST_BIG_ENDIAN)
1414 static const int half_word_incr = -1;
1415 #elif defined(SC_BOOST_LITTLE_ENDIAN)
1416 static const int half_word_incr = 1;
1417 #endif
1418 
1419 void
1420 multiply(scfx_rep &result, const scfx_rep &lhs, const scfx_rep &rhs,
1421  int max_wl)
1422 {
1423  //
1424  // check for special cases
1425  //
1426  if (lhs.is_nan() || rhs.is_nan() ||
1427  (lhs.is_inf() && rhs.is_zero()) ||
1428  (lhs.is_zero() && rhs.is_inf())) {
1429  result.set_nan();
1430  return;
1431  }
1433  if (lhs.is_inf() || rhs.is_inf()) {
1434  result.set_inf(lhs.m_sign * rhs.m_sign);
1435  return;
1436  }
1437 
1438  if (lhs.is_zero() || rhs.is_zero()) {
1439  result.set_zero(lhs.m_sign * rhs.m_sign);
1440  return;
1441  }
1442 
1443  //
1444  // do it
1445  //
1446  int len_lhs = lhs.m_msw - lhs.m_lsw + 1;
1447  int len_rhs = rhs.m_msw - rhs.m_lsw + 1;
1448 
1449  int new_size = sc_max(min_mant, len_lhs + len_rhs);
1450  int new_wp = (lhs.m_wp - lhs.m_lsw) + (rhs.m_wp - rhs.m_lsw);
1451  int new_sign = lhs.m_sign * rhs.m_sign;
1453  result.resize_to(new_size);
1454  result.m_mant.clear();
1455  result.m_wp = new_wp;
1456  result.m_sign = new_sign;
1457  result.m_state = scfx_rep::normal;
1458 
1459  half_word *s1 = lhs.m_mant.half_addr(lhs.m_lsw);
1460  half_word *s2 = rhs.m_mant.half_addr(rhs.m_lsw);
1461 
1462  half_word *t = result.m_mant.half_addr();
1463 
1464  len_lhs <<= 1;
1465  len_rhs <<= 1;
1466 
1467  int i1, i2;
1468 
1469  for (i1 = 0; i1 * half_word_incr < len_lhs; i1 += half_word_incr) {
1470  word_short ls;
1471  ls.l = 0;
1472 
1473  half_word v1 = s1[i1];
1474 
1475  for (i2 = 0; i2 * half_word_incr < len_rhs; i2 += half_word_incr) {
1476  ls.l += v1 * s2[i2];
1477  ls.s.l = ls.s.u + ((t[i2] += ls.s.l) < ls.s.l);
1478  ls.s.u = 0;
1479  }
1480 
1481  t[i2] = ls.s.l;
1482  t += half_word_incr;
1483  }
1484 
1485  result.find_sw();
1486  result.round(max_wl);
1487 }
1488 
1489 
1490 // ----------------------------------------------------------------------------
1491 // DIV
1492 // ----------------------------------------------------------------------------
1493 
1494 scfx_rep *
1495 div_scfx_rep(const scfx_rep &lhs, const scfx_rep &rhs, int div_wl)
1496 {
1497  scfx_rep &result = *new scfx_rep;
1498 
1499  //
1500  // check for special cases
1501  //
1502  if (lhs.is_nan() || rhs.is_nan() || (lhs.is_inf() && rhs.is_inf()) ||
1503  (lhs.is_zero() && rhs.is_zero())) {
1504  result.set_nan();
1505  return &result;
1506  }
1507 
1508  if (lhs.is_inf() || rhs.is_zero()) {
1509  result.set_inf(lhs.m_sign * rhs.m_sign);
1510  return &result;
1511  }
1512 
1513  if (lhs.is_zero() || rhs.is_inf()) {
1514  result.set_zero(lhs.m_sign * rhs.m_sign);
1515  return &result;
1516  }
1517 
1518  //
1519  // do it
1520  //
1521 
1522  // compute one bit more for rounding
1523  div_wl++;
1524 
1525  result.resize_to(sc_max(n_word(div_wl) + 1, min_mant));
1526  result.m_mant.clear();
1527  result.m_sign = lhs.m_sign * rhs.m_sign;
1528 
1529  int msb_lhs = scfx_find_msb(lhs.m_mant[lhs.m_msw]) +
1530  (lhs.m_msw - lhs.m_wp) * bits_in_word;
1531  int msb_rhs = scfx_find_msb(rhs.m_mant[rhs.m_msw]) +
1532  (rhs.m_msw - rhs.m_wp) * bits_in_word;
1533 
1534  int msb_res = msb_lhs - msb_rhs;
1535  int to_shift = -msb_res % bits_in_word;
1536  int result_index;
1537 
1538  int c = (msb_res % bits_in_word >= 0) ? 1 : 0;
1539 
1540  result_index = (result.size() - c) * bits_in_word + msb_res % bits_in_word;
1541  result.m_wp = (result.size() - c) - msb_res / bits_in_word;
1542 
1543  scfx_rep remainder = lhs;
1544 
1545  // align msb from remainder to msb from rhs
1546  remainder.lshift(to_shift);
1547 
1548  // make sure msw(remainder) < size - 1
1549  if (remainder.m_msw == remainder.size() - 1)
1550  remainder.resize_to(remainder.size() + 1, 1);
1551 
1552  // make sure msw(remainder) >= msw(rhs)!
1553  int msw_diff = rhs.m_msw - remainder.m_msw;
1554  if (msw_diff > 0)
1555  remainder.resize_to(remainder.size() + msw_diff, -1);
1556 
1557  int counter;
1558 
1559  for (counter = div_wl; counter && !remainder.is_zero(); counter--) {
1560  if (compare_msw_ff(rhs, remainder) <= 0) {
1561  result.set_bin(result_index);
1562  sub_with_index(remainder.m_mant, remainder.m_msw, remainder.m_lsw,
1563  rhs.m_mant, rhs.m_msw, rhs.m_lsw);
1564  }
1565  result_index--;
1566  remainder.shift_left(1);
1567  remainder.m_lsw = remainder.find_lsw();
1568  }
1569 
1570  // perform convergent rounding, if needed
1571  if (counter == 0) {
1572  int index = result_index + 1 - result.m_wp * bits_in_word;
1573 
1574  scfx_index x = result.calc_indices(index);
1575  scfx_index x1 = result.calc_indices(index + 1);
1576 
1577  if (result.o_bit_at(x) && result.o_bit_at(x1))
1578  result.q_incr(x);
1579 
1580  result.m_r_flag = true;
1581  }
1582 
1583  result.find_sw();
1584 
1585  return &result;
1586 }
1587 
1588 // ----------------------------------------------------------------------------
1589 // destructive shift mantissa to the left
1590 // ----------------------------------------------------------------------------
1591 
1592 void
1593 scfx_rep::lshift(int n)
1594 {
1595  if (n == 0)
1596  return;
1597 
1598  if (n < 0) {
1599  rshift(-n);
1600  return;
1601  }
1602 
1603  if (is_normal()) {
1604  int shift_bits = n % bits_in_word;
1605  int shift_words = n / bits_in_word;
1606 
1607  // resize if needed
1608  if (m_msw == size() - 1 &&
1609  scfx_find_msb(m_mant[m_msw]) >= bits_in_word - shift_bits)
1610  resize_to(size() + 1, 1);
1611 
1612  // do it
1613  m_wp -= shift_words;
1614  shift_left(shift_bits);
1615  find_sw();
1616  }
1617 }
1618 
1619 // ----------------------------------------------------------------------------
1620 // destructive shift mantissa to the right
1621 // ----------------------------------------------------------------------------
1622 
1623 void
1624 scfx_rep::rshift(int n)
1626  if (n == 0)
1627  return;
1628 
1629  if (n < 0) {
1630  lshift(-n);
1631  return;
1632  }
1633 
1634  if (is_normal()) {
1635  int shift_bits = n % bits_in_word;
1636  int shift_words = n / bits_in_word;
1637 
1638  // resize if needed
1639  if (m_lsw == 0 && scfx_find_lsb(m_mant[m_lsw]) < shift_bits)
1640  resize_to(size() + 1, -1);
1641 
1642  // do it
1643  m_wp += shift_words;
1644  shift_right(shift_bits);
1645  find_sw();
1646  }
1647 }
1648 
1649 
1650 // ----------------------------------------------------------------------------
1651 // FRIEND FUNCTION : compare_abs
1652 //
1653 // Compares the absolute values of two scfx_reps, excluding the special cases.
1654 // ----------------------------------------------------------------------------
1655 
1656 int
1657 compare_abs(const scfx_rep &a, const scfx_rep &b)
1658 {
1659  // check for zero
1660  word a_word = a.m_mant[a.m_msw];
1661  word b_word = b.m_mant[b.m_msw];
1662 
1663  if (a_word == 0 || b_word == 0) {
1664  if (a_word != 0)
1665  return 1;
1666  if (b_word != 0)
1667  return -1;
1668  return 0;
1669  }
1670 
1671  // compare msw index
1672  int a_msw = a.m_msw - a.m_wp;
1673  int b_msw = b.m_msw - b.m_wp;
1674 
1675  if (a_msw > b_msw)
1676  return 1;
1677 
1678  if (a_msw < b_msw)
1679  return -1;
1680 
1681  // compare content
1682  int a_i = a.m_msw;
1683  int b_i = b.m_msw;
1684 
1685  while (a_i >= a.m_lsw && b_i >= b.m_lsw) {
1686  a_word = a.m_mant[a_i];
1687  b_word = b.m_mant[b_i];
1688  if (a_word > b_word)
1689  return 1;
1690  if (a_word < b_word)
1691  return -1;
1692  --a_i;
1693  --b_i;
1694  }
1695 
1696  bool a_zero = true;
1697  while (a_i >= a.m_lsw) {
1698  a_zero = a_zero && (a.m_mant[a_i] == 0);
1699  --a_i;
1700  }
1701 
1702  bool b_zero = true;
1703  while (b_i >= b.m_lsw) {
1704  b_zero = b_zero && (b.m_mant[b_i] == 0);
1705  --b_i;
1706  }
1707 
1708  // assertion: a_zero || b_zero
1709 
1710  if (!a_zero && b_zero)
1711  return 1;
1712 
1713  if (a_zero && !b_zero)
1714  return -1;
1715 
1716  return 0;
1717 }
1718 
1719 // ----------------------------------------------------------------------------
1720 // FRIEND FUNCTION : cmp_scfx_rep
1721 //
1722 // Compares the values of two scfx_reps, including the special cases.
1723 // ----------------------------------------------------------------------------
1724 
1725 int
1726 cmp_scfx_rep(const scfx_rep &a, const scfx_rep &b)
1727 {
1728  // handle special cases
1729 
1730  if (a.is_nan() || b.is_nan()) {
1731  return 2;
1732  }
1733 
1734  if (a.is_inf() || b.is_inf()) {
1735  if (a.is_inf()) {
1736  if (!a.is_neg()) {
1737  if (b.is_inf() && !b.is_neg()) {
1738  return 0;
1739  } else {
1740  return 1;
1741  }
1742  } else {
1743  if (b.is_inf() && b.is_neg()) {
1744  return 0;
1745  } else {
1746  return -1;
1747  }
1748  }
1749  }
1750  if (b.is_inf()) {
1751  if (!b.is_neg()) {
1752  return -1;
1753  } else {
1754  return 1;
1755  }
1756  }
1757  }
1759  if (a.is_zero() && b.is_zero()) {
1760  return 0;
1761  }
1762 
1763  // compare sign
1764  if (a.m_sign != b.m_sign) {
1765  return a.m_sign;
1766  }
1767 
1768  return (a.m_sign * compare_abs(a, b));
1769 }
1770 
1771 
1772 // ----------------------------------------------------------------------------
1773 // PRIVATE METHOD : quantization
1774 //
1775 // Performs destructive quantization.
1776 // ----------------------------------------------------------------------------
1777 
1778 void
1779 scfx_rep::quantization(const scfx_params &params, bool &q_flag)
1780 {
1781  scfx_index x = calc_indices(params.iwl() - params.wl());
1782 
1783  if (x.wi() < 0)
1784  return;
1785 
1786  if (x.wi() >= size())
1787  resize_to(x.wi() + 1, 1);
1788 
1789  bool qb = q_bit(x);
1790  bool qz = q_zero(x);
1791 
1792  q_flag = (qb || ! qz);
1793 
1794  if (q_flag) {
1795  switch (params.q_mode()) {
1796  case SC_TRN: // truncation
1797  {
1798  if (is_neg())
1799  q_incr(x);
1800  break;
1801  }
1802  case SC_RND: // rounding to plus infinity
1803  {
1804  if (!is_neg()) {
1805  if (qb)
1806  q_incr(x);
1807  } else {
1808  if (qb && !qz)
1809  q_incr(x);
1810  }
1811  break;
1812  }
1813  case SC_TRN_ZERO: // truncation to zero
1814  {
1815  break;
1816  }
1817  case SC_RND_INF: // rounding to infinity
1818  {
1819  if (qb)
1820  q_incr(x);
1821  break;
1822  }
1823  case SC_RND_CONV: // convergent rounding
1824  {
1825  if ((qb && !qz) || (qb && qz && q_odd(x)))
1826  q_incr(x);
1827  break;
1828  }
1829  case SC_RND_ZERO: // rounding to zero
1830  {
1831  if (qb && !qz)
1832  q_incr(x);
1833  break;
1834  }
1835  case SC_RND_MIN_INF: // rounding to minus infinity
1836  {
1837  if (!is_neg()) {
1838  if (qb && !qz)
1839  q_incr(x);
1840  } else {
1841  if (qb)
1842  q_incr(x);
1843  }
1844  break;
1845  }
1846  default:
1847  ;
1848  }
1849  q_clear(x);
1850 
1851  find_sw();
1852  }
1853 }
1854 
1855 
1856 // ----------------------------------------------------------------------------
1857 // PRIVATE METHOD : overflow
1858 //
1859 // Performs destructive overflow handling.
1860 // ----------------------------------------------------------------------------
1861 
1862 void
1863 scfx_rep::overflow(const scfx_params &params, bool &o_flag)
1864 {
1865  scfx_index x = calc_indices(params.iwl() - 1);
1866 
1867  if (x.wi() >= size())
1868  resize_to(x.wi() + 1, 1);
1869 
1870  if (x.wi() < 0) {
1871  resize_to(size() - x.wi(), -1);
1872  x.wi(0);
1873  }
1874 
1875  bool zero_left = o_zero_left(x);
1876  bool bit_at = o_bit_at(x);
1877  bool zero_right = o_zero_right(x);
1878 
1879  bool under = false;
1880  bool over = false;
1881 
1882  sc_enc enc = params.enc();
1883 
1884  if (enc == SC_TC_) {
1885  if (is_neg()) {
1886  if (params.o_mode() == SC_SAT_SYM)
1887  under = (!zero_left || bit_at);
1888  else
1889  under = (!zero_left || (zero_left && bit_at && ! zero_right));
1890  } else {
1891  over = (! zero_left || bit_at);
1892  }
1893  } else {
1894  if (is_neg())
1895  under = (!is_zero());
1896  else
1897  over = (!zero_left);
1898  }
1899 
1900  o_flag = (under || over);
1901 
1902  if (o_flag) {
1903  scfx_index x2 = calc_indices(params.iwl() - params.wl());
1904 
1905  if (x2.wi() < 0) {
1906  resize_to(size() - x2.wi(), -1);
1907  x.wi(x.wi() - x2.wi());
1908  x2.wi(0);
1909  }
1910 
1911  switch (params.o_mode()) {
1912  case SC_WRAP: // wrap-around
1913  {
1914  int n_bits = params.n_bits();
1915 
1916  if (n_bits == 0) {
1917  // wrap-around all 'wl' bits
1918  toggle_tc();
1919  o_extend(x, enc);
1920  toggle_tc();
1921  } else if (n_bits < params.wl()) {
1922  scfx_index x3 = calc_indices(params.iwl() - 1 - n_bits);
1923 
1924  // wrap-around least significant 'wl - n_bits' bits;
1925  // saturate most significant 'n_bits' bits
1926  toggle_tc();
1927  o_set(x, x3, enc, under);
1928  o_extend(x, enc);
1929  toggle_tc();
1930  } else {
1931  // saturate all 'wl' bits
1932  if (under)
1933  o_set_low(x, enc);
1934  else
1935  o_set_high(x, x2, enc);
1936  }
1937  break;
1938  }
1939  case SC_SAT: // saturation
1940  {
1941  if (under)
1942  o_set_low(x, enc);
1943  else
1944  o_set_high(x, x2, enc);
1945  break;
1946  }
1947  case SC_SAT_SYM: // symmetrical saturation
1948  {
1949  if (under) {
1950  if (enc == SC_TC_)
1951  o_set_high(x, x2, SC_TC_, -1);
1952  else
1953  o_set_low(x, SC_US_);
1954  } else {
1955  o_set_high(x, x2, enc);
1956  }
1957  break;
1958  }
1959  case SC_SAT_ZERO: // saturation to zero
1960  {
1961  set_zero();
1962  break;
1963  }
1964  case SC_WRAP_SM: // sign magnitude wrap-around
1965  {
1966  SC_ERROR_IF_(enc == SC_US_,
1968 
1969  int n_bits = params.n_bits();
1970 
1971  if (n_bits == 0) {
1972  scfx_index x4 = calc_indices(params.iwl());
1973 
1974  if (x4.wi() >= size())
1975  resize_to(x4.wi() + 1, 1);
1976 
1977  toggle_tc();
1978  if (o_bit_at(x4) != o_bit_at(x))
1979  o_invert(x2);
1980  o_extend(x, SC_TC_);
1981  toggle_tc();
1982  } else if (n_bits == 1) {
1983  toggle_tc();
1984  if (is_neg() != o_bit_at(x))
1985  o_invert(x2);
1986  o_extend(x, SC_TC_);
1987  toggle_tc();
1988  } else if (n_bits < params.wl()) {
1989  scfx_index x3 = calc_indices(params.iwl() - 1 - n_bits);
1990  scfx_index x4 = calc_indices(params.iwl() - n_bits);
1991 
1992  // wrap-around least significant 'wl - n_bits' bits;
1993  // saturate most significant 'n_bits' bits
1994  toggle_tc();
1995  if (is_neg() == o_bit_at(x4))
1996  o_invert(x2);
1997  o_set(x, x3, SC_TC_, under);
1998  o_extend(x, SC_TC_);
1999  toggle_tc();
2000  } else {
2001  if (under)
2002  o_set_low(x, SC_TC_);
2003  else
2004  o_set_high(x, x2, SC_TC_);
2005  }
2006  break;
2007  }
2008  default:
2009  ;
2010  }
2011 
2012  find_sw();
2013  }
2014 }
2015 
2016 
2017 // ----------------------------------------------------------------------------
2018 // PUBLIC METHOD : cast
2019 //
2020 // Performs a destructive cast operation on a scfx_rep.
2021 // ----------------------------------------------------------------------------
2022 
2023 void
2024 scfx_rep::cast(const scfx_params &params, bool &q_flag, bool &o_flag)
2025 {
2026  q_flag = false;
2027  o_flag = false;
2028 
2029  // check for special cases
2030  if (is_zero()) {
2031  if (is_neg())
2032  m_sign = 1;
2033  return;
2034  }
2035 
2036  // perform casting
2037  quantization(params, q_flag);
2038  overflow(params, o_flag);
2039 
2040  // check for special case: -0
2041  if (is_zero() && is_neg())
2042  m_sign = 1;
2043 }
2044 
2045 
2046 // ----------------------------------------------------------------------------
2047 // make sure, the two mantissas are aligned
2048 // ----------------------------------------------------------------------------
2049 
2050 void
2051 align(const scfx_rep &lhs, const scfx_rep &rhs, int &new_wp,
2052  int &len_mant, scfx_mant_ref &lhs_mant, scfx_mant_ref &rhs_mant)
2053 {
2054  bool need_lhs = true;
2055  bool need_rhs = true;
2057  if (lhs.m_wp != rhs.m_wp || lhs.size() != rhs.size()) {
2058  int lower_bound_lhs = lhs.m_lsw - lhs.m_wp;
2059  int upper_bound_lhs = lhs.m_msw - lhs.m_wp;
2060  int lower_bound_rhs = rhs.m_lsw - rhs.m_wp;
2061  int upper_bound_rhs = rhs.m_msw - rhs.m_wp;
2062 
2063  int lower_bound = sc_min(lower_bound_lhs, lower_bound_rhs);
2064  int upper_bound = sc_max(upper_bound_lhs, upper_bound_rhs);
2065 
2066  new_wp = -lower_bound;
2067  len_mant = sc_max(min_mant, upper_bound - lower_bound + 1);
2068 
2069  if (new_wp != lhs.m_wp || len_mant != lhs.size()) {
2070  lhs_mant = lhs.resize(len_mant, new_wp);
2071  need_lhs = false;
2072  }
2073 
2074  if (new_wp != rhs.m_wp || len_mant != rhs.size()) {
2075  rhs_mant = rhs.resize(len_mant, new_wp);
2076  need_rhs = false;
2077  }
2078  }
2079 
2080  if (need_lhs) {
2081  lhs_mant = lhs.m_mant;
2082  }
2084  if (need_rhs) {
2085  rhs_mant = rhs.m_mant;
2086  }
2087 }
2088 
2089 
2090 // ----------------------------------------------------------------------------
2091 // compare two mantissas
2092 // ----------------------------------------------------------------------------
2093 
2094 int
2095 compare_msw_ff(const scfx_rep &lhs, const scfx_rep &rhs)
2096 {
2097  // special case: rhs.m_mant[rhs.m_msw + 1] == 1
2098  if (rhs.m_msw < rhs.size() - 1 && rhs.m_mant[rhs.m_msw + 1 ] != 0) {
2099  return -1;
2100  }
2101 
2102  int lhs_size = lhs.m_msw - lhs.m_lsw + 1;
2103  int rhs_size = rhs.m_msw - rhs.m_lsw + 1;
2104 
2105  int size = sc_min(lhs_size, rhs_size);
2106 
2107  int lhs_index = lhs.m_msw;
2108  int rhs_index = rhs.m_msw;
2109 
2110  int i;
2111 
2112  for (i = 0;
2113  i < size && lhs.m_mant[lhs_index] == rhs.m_mant[rhs_index];
2114  i++) {
2115  lhs_index--;
2116  rhs_index--;
2117  }
2118 
2119  if (i == size) {
2120  if (lhs_size == rhs_size) {
2121  return 0;
2122  }
2123 
2124  if (lhs_size < rhs_size) {
2125  return -1;
2126  } else {
2127  return 1;
2128  }
2129  }
2130 
2131  if (lhs.m_mant[lhs_index] < rhs.m_mant[rhs_index]) {
2132  return -1;
2133  } else {
2134  return 1;
2135  }
2136 }
2137 
2138 
2139 // ----------------------------------------------------------------------------
2140 // divide the mantissa by ten
2141 // ----------------------------------------------------------------------------
2142 
2143 unsigned int
2145 {
2146 #if defined(SC_BOOST_BIG_ENDIAN)
2147  half_word *hw = (half_word *)&m_mant[m_msw];
2148 #elif defined(SC_BOOST_LITTLE_ENDIAN)
2149  half_word *hw = ((half_word *)&m_mant[m_msw]) + 1;
2150 #endif
2151 
2152  unsigned int remainder = 0;
2153 
2154  word_short ls;
2155  ls.l = 0;
2156 
2157 #if defined(SC_BOOST_BIG_ENDIAN)
2158  for (int i = 0, end = (m_msw - m_wp + 1) * 2; i < end; i++) {
2159 #elif defined(SC_BOOST_LITTLE_ENDIAN)
2160  for (int i = 0, end = -(m_msw - m_wp + 1) * 2; i > end; i--) {
2161 #endif
2162  ls.s.u = static_cast<half_word>(remainder);
2163  ls.s.l = hw[i];
2164  remainder = ls.l % 10;
2165  ls.l /= 10;
2166  hw[i] = ls.s.l;
2167  }
2168 
2169  return remainder;
2170 }
2171 
2172 
2173 // ----------------------------------------------------------------------------
2174 // multiply the mantissa by ten
2175 // ----------------------------------------------------------------------------
2177 void
2179 {
2180  int size = m_mant.size() + 1;
2181 
2182  scfx_mant mant8(size);
2183  scfx_mant mant2(size);
2184 
2185  size--;
2186 
2187  mant8[size] = (m_mant[size - 1] >> (bits_in_word - 3));
2188  mant2[size] = (m_mant[size - 1] >> (bits_in_word - 1));
2189 
2190  while (--size) {
2191  mant8[size] = (m_mant[size] << 3) |
2192  (m_mant[size - 1] >> (bits_in_word - 3));
2193  mant2[size] = (m_mant[size] << 1) |
2194  (m_mant[size - 1] >> (bits_in_word - 1));
2195  }
2196 
2197  mant8[0] = (m_mant[0] << 3);
2198  mant2[0] = (m_mant[0] << 1);
2199 
2200  add_mants(m_mant.size(), m_mant, mant8, mant2);
2202 
2203 
2204 // ----------------------------------------------------------------------------
2205 // normalize
2206 // ----------------------------------------------------------------------------
2207 
2208 void
2209 scfx_rep::normalize(int exponent)
2210 {
2211  int shift = exponent % bits_in_word;
2212  if (shift < 0) {
2213  shift += bits_in_word;
2214  }
2215 
2216  if (shift) {
2217  shift_left(shift);
2218  }
2219 
2220  find_sw();
2221 
2222  m_wp = (shift - exponent) / bits_in_word;
2223 }
2224 
2225 
2226 // ----------------------------------------------------------------------------
2227 // return a new mantissa that is aligned and resized
2228 // ----------------------------------------------------------------------------
2229 
2230 scfx_mant *
2231 scfx_rep::resize(int new_size, int new_wp) const
2232 {
2233  scfx_mant *result = new scfx_mant(new_size);
2234 
2235  result->clear();
2236 
2237  int shift = new_wp - m_wp;
2238 
2239  for (int j = m_lsw; j <= m_msw; j++) {
2240  (*result)[j + shift] = m_mant[j];
2241  }
2242 
2243  return result;
2244 }
2245 
2246 
2247 // ----------------------------------------------------------------------------
2248 // set a single bit
2249 // ----------------------------------------------------------------------------
2250 
2251 void
2253 {
2254  m_mant[i >> 5] |= 1 << (i & 31);
2255 }
2256 
2257 
2258 // ----------------------------------------------------------------------------
2259 // set three bits
2260 // ----------------------------------------------------------------------------
2261 
2262 void
2264 {
2265  if (n & 1) {
2266  m_mant[i >> 5] |= 1 << (i & 31);
2267  }
2268  i++;
2269  if (n & 2) {
2270  m_mant[i >> 5] |= 1 << (i & 31);
2271  }
2272  i++;
2273  if (n & 4) {
2274  m_mant[i >> 5] |= 1 << (i & 31);
2275  }
2276 }
2277 
2278 
2279 // ----------------------------------------------------------------------------
2280 // set four bits
2281 // ----------------------------------------------------------------------------
2282 
2283 void
2285 {
2286  if (n & 1) {
2287  m_mant[i >> 5] |= 1 << (i & 31);
2288  }
2289  i++;
2290  if (n & 2) {
2291  m_mant[i >> 5] |= 1 << (i & 31);
2292  }
2293  i++;
2294  if (n & 4) {
2295  m_mant[i >> 5] |= 1 << (i & 31);
2296  }
2297  i++;
2298  if (n & 8) {
2299  m_mant[i >> 5] |= 1 << (i & 31);
2300  }
2301 }
2302 
2303 
2304 // ----------------------------------------------------------------------------
2305 // PRIVATE METHOD : shift_left
2306 //
2307 // Shifts a scfx_rep to the left by a MAXIMUM of bits_in_word - 1 bits.
2308 // ----------------------------------------------------------------------------
2309 
2310 void
2312 {
2313  if (n != 0) {
2314  int shift_left = n;
2315  int shift_right = bits_in_word - n;
2316 
2317  SC_ASSERT_(!(m_mant[size() - 1] >> shift_right),
2318  "shift_left overflow");
2319 
2320  for (int i = size() - 1; i > 0; i--) {
2321  m_mant[i] = (m_mant[i] << shift_left) |
2322  (m_mant[i - 1] >> shift_right);
2323  }
2324  m_mant[0] <<= shift_left;
2325  }
2326 }
2327 
2328 
2329 // ----------------------------------------------------------------------------
2330 // PRIVATE METHOD : shift_right
2331 //
2332 // Shifts a scfx_rep to the right by a MAXIMUM of bits_in_word - 1 bits.
2333 // ----------------------------------------------------------------------------
2334 
2335 void
2337 {
2338  if (n != 0) {
2339  int shift_left = bits_in_word - n;
2340  int shift_right = n;
2341 
2342  SC_ASSERT_(!(m_mant[0] << shift_left), "shift_right overflow");
2343 
2344  for (int i = 0; i < size() - 1; i++) {
2345  m_mant[i] = (m_mant[i] >> shift_right) |
2346  (m_mant[i + 1] << shift_left);
2347  }
2348  m_mant[size() - 1] >>= shift_right;
2349  }
2350 }
2351 
2352 
2353 // ----------------------------------------------------------------------------
2354 // METHOD : get_bit
2355 //
2356 // Tests a bit, in two's complement.
2357 // ----------------------------------------------------------------------------
2358 
2359 bool
2361 {
2362  if (!is_normal())
2363  return false;
2364 
2366 
2367  if (x.wi() >= size())
2368  return is_neg();
2369 
2370  if (x.wi() < 0)
2371  return false;
2372 
2373  const_cast<scfx_rep*>(this)->toggle_tc();
2374 
2375  bool result = (m_mant[x.wi()] & (1 << x.bi())) != 0;
2376 
2377  const_cast<scfx_rep *>(this)->toggle_tc();
2378 
2379  return result;
2380 }
2381 
2382 
2383 // ----------------------------------------------------------------------------
2384 // METHOD : set
2385 //
2386 // Sets a bit, in two's complement, between iwl-1 and -fwl.
2387 // ----------------------------------------------------------------------------
2388 
2389 bool
2390 scfx_rep::set(int i, const scfx_params &params)
2391 {
2392  if (!is_normal())
2393  return false;
2394 
2396 
2397  if (x.wi() >= size()) {
2398  if (is_neg())
2399  return true;
2400  else
2401  resize_to(x.wi() + 1, 1);
2402  } else if (x.wi() < 0) {
2403  resize_to(size() - x.wi(), -1);
2404  x.wi(0);
2405  }
2406 
2407  toggle_tc();
2408 
2409  m_mant[x.wi()] |= 1 << x.bi();
2410 
2411  if (i == params.iwl() - 1)
2412  o_extend(x, params.enc()); // sign extension
2413 
2414  toggle_tc();
2415 
2416  find_sw();
2417 
2418  return true;
2419 }
2420 
2421 
2422 // ----------------------------------------------------------------------------
2423 // METHOD : clear
2424 //
2425 // Clears a bit, in two's complement, between iwl-1 and -fwl.
2426 // ----------------------------------------------------------------------------
2427 
2428 bool
2429 scfx_rep::clear(int i, const scfx_params &params)
2430 {
2431  if (!is_normal())
2432  return false;
2433 
2435 
2436  if (x.wi() >= size()) {
2437  if (!is_neg())
2438  return true;
2439  else
2440  resize_to(x.wi() + 1, 1);
2441  } else if (x.wi() < 0) {
2442  return true;
2443  }
2444 
2445  toggle_tc();
2446 
2447  m_mant[x.wi()] &= ~(1 << x.bi());
2448 
2449  if (i == params.iwl() - 1)
2450  o_extend(x, params.enc()); // sign extension
2451 
2452  toggle_tc();
2453 
2454  find_sw();
2455 
2456  return true;
2457 }
2458 
2459 
2460 // ----------------------------------------------------------------------------
2461 // METHOD : get_slice
2462 // ----------------------------------------------------------------------------
2463 
2464 bool
2465 scfx_rep::get_slice(int i, int j, const scfx_params &, sc_bv_base &bv) const
2466 {
2467  if (is_nan() || is_inf())
2468  return false;
2469 
2470  // get the bits
2471 
2472  int l = j;
2473  for (int k = 0; k < bv.length(); ++k) {
2474  bv[k] = get_bit(l);
2475 
2476  if (i >= j)
2477  ++l;
2478  else
2479  --l;
2480  }
2481 
2482  return true;
2483 }
2484 
2485 bool
2486 scfx_rep::set_slice(int i, int j, const scfx_params &params,
2487  const sc_bv_base &bv)
2488 {
2489  if (is_nan() || is_inf())
2490  return false;
2491 
2492  // set the bits
2493  int l = j;
2494  for (int k = 0; k < bv.length(); ++k) {
2495  if (bv[k].to_bool())
2496  set(l, params);
2497  else
2498  clear(l, params);
2499 
2500  if (i >= j)
2501  ++l;
2502  else
2503  --l;
2504  }
2505 
2506  return true;
2507 }
2508 
2509 
2510 // ----------------------------------------------------------------------------
2511 // METHOD : print
2512 // ----------------------------------------------------------------------------
2513 
2514 void
2515 scfx_rep::print(::std::ostream &os) const
2516 {
2517  os << to_string(SC_DEC, -1, SC_E);
2518 }
2519 
2520 
2521 // ----------------------------------------------------------------------------
2522 // METHOD : dump
2523 // ----------------------------------------------------------------------------
2524 
2525 void
2526 scfx_rep::dump(::std::ostream &os) const
2527 {
2528  os << "scfx_rep" << ::std::endl;
2529  os << "(" << ::std::endl;
2530 
2531  os << "mant =" << ::std::endl;
2532  for (int i = size() - 1; i >= 0; i--) {
2533  char buf[BUFSIZ];
2534  std::sprintf(buf, " %d: %10u (%8x)", i,
2535  (int)m_mant[i], (int)m_mant[i]);
2536  os << buf << ::std::endl;
2537  }
2538 
2539  os << "wp = " << m_wp << ::std::endl;
2540  os << "sign = " << m_sign << ::std::endl;
2541 
2542  os << "state = ";
2543  switch (m_state) {
2544  case normal:
2545  os << "normal";
2546  break;
2547  case infinity:
2548  os << "infinity";
2549  break;
2550  case not_a_number:
2551  os << "not_a_number";
2552  break;
2553  default:
2554  os << "unknown";
2555  }
2556  os << ::std::endl;
2557 
2558  os << "msw = " << m_msw << ::std::endl;
2559  os << "lsw = " << m_lsw << ::std::endl;
2560 
2561  os << ")" << ::std::endl;
2562 }
2563 
2564 
2565 // ----------------------------------------------------------------------------
2566 // METHOD : get_type
2567 // ----------------------------------------------------------------------------
2568 
2569 void
2570 scfx_rep::get_type(int &wl, int &iwl, sc_enc &enc) const
2571 {
2572  if (is_nan() || is_inf()) {
2573  wl = 0;
2574  iwl = 0;
2575  enc = SC_TC_;
2576  return;
2577  }
2578 
2579  if (is_zero()) {
2580  wl = 1;
2581  iwl = 1;
2582  enc = SC_US_;
2583  return;
2584  }
2585 
2586  int msb = (m_msw - m_wp) * bits_in_word +
2587  scfx_find_msb(m_mant[ m_msw ]) + 1;
2588  while (get_bit(msb) == get_bit(msb - 1)) {
2589  --msb;
2590  }
2591 
2592  int lsb = (m_lsw - m_wp) * bits_in_word +
2594 
2595  if (is_neg()) {
2596  wl = msb - lsb + 1;
2597  iwl = msb + 1;
2598  enc = SC_TC_;
2599  } else {
2600  wl = msb - lsb;
2601  iwl = msb;
2602  enc = SC_US_;
2603  }
2604 }
2605 
2606 
2607 // ----------------------------------------------------------------------------
2608 // PRIVATE METHOD : round
2609 //
2610 // Performs convergent rounding (rounding to even) as in floating-point.
2611 // ----------------------------------------------------------------------------
2612 
2613 void
2615 {
2616  // check for special cases
2617 
2618  if (is_nan() || is_inf() || is_zero())
2619  return;
2620 
2621  // estimate effective wordlength and compare
2622  int wl_effective;
2623  wl_effective = (m_msw - m_lsw + 1) * bits_in_word;
2624  if (wl_effective <= wl)
2625  return;
2626 
2627  // calculate effective wordlength and compare
2628  int msb = scfx_find_msb(m_mant[m_msw]);
2629  int lsb = scfx_find_lsb(m_mant[m_lsw]);
2630  wl_effective = (m_msw * bits_in_word + msb) -
2631  (m_lsw * bits_in_word + lsb) + 1;
2632  if (wl_effective <= wl)
2633  return;
2634 
2635  // perform rounding
2636  int wi = m_msw - (wl - 1) / bits_in_word;
2637  int bi = msb - (wl - 1) % bits_in_word;
2638  if (bi < 0) {
2639  --wi;
2640  bi += bits_in_word;
2641  }
2642 
2643  scfx_index x(wi, bi);
2644 
2645  if ((q_bit(x) && ! q_zero(x)) || (q_bit(x) && q_zero(x) && q_odd(x))) {
2646  q_incr(x);
2647  }
2648  q_clear(x);
2649 
2650  find_sw();
2651 
2652  m_r_flag = true;
2653 }
2654 
2655 } // namespace sc_dt
sc_dt::scfx_mant::clear
void clear()
Definition: scfx_mant.hh:227
sc_dt::SC_OCT_US
@ SC_OCT_US
Definition: sc_nbdefs.hh:158
sc_dt::scfx_parse_prefix
sc_numrep scfx_parse_prefix(const char *&s)
Definition: scfx_utils.hh:161
sc_dt::add_scfx_rep
scfx_rep * add_scfx_rep(const scfx_rep &lhs, const scfx_rep &rhs, int max_wl)
Definition: scfx_rep.cc:1249
sc_dt::scfx_rep::m_lsw
int m_lsw
Definition: scfx_rep.hh:313
sc_dt::SC_BIN
@ SC_BIN
Definition: sc_nbdefs.hh:152
sc_dt::scfx_rep::normalize
void normalize(int)
Definition: scfx_rep.cc:2209
gem5::ArmISA::len
Bitfield< 18, 16 > len
Definition: misc_types.hh:444
sc_dt::scfx_is_digit
bool scfx_is_digit(char c, sc_numrep numrep)
Definition: scfx_utils.hh:294
messages.hh
sc_dt::SCFX_IEEE_DOUBLE_E_MAX
const int SCFX_IEEE_DOUBLE_E_MAX
Definition: scfx_ieee.hh:131
sc_dt::word
unsigned int word
Definition: scfx_mant.hh:96
sc_dt::scfx_rep::find_sw
void find_sw()
Definition: scfx_rep.hh:739
sc_dt::SC_F
@ SC_F
Definition: sc_fxdefs.hh:166
sc_dt::SCFX_IEEE_DOUBLE_E_MIN
const int SCFX_IEEE_DOUBLE_E_MIN
Definition: scfx_ieee.hh:132
sc_dt::scfx_rep
Definition: scfx_rep.hh:169
sc_dt::compare_abs
int compare_abs(const scfx_rep &a, const scfx_rep &b)
Definition: scfx_rep.cc:1689
sc_dt::scfx_rep::calc_indices
const scfx_index calc_indices(int) const
Definition: scfx_rep.hh:458
sc_dt::sc_bv_base::length
int length() const
Definition: sc_bv_base.hh:248
sc_dt::SC_HEX_SM
@ SC_HEX_SM
Definition: sc_nbdefs.hh:161
sc_dt::scfx_mant::size
int size() const
Definition: scfx_mant.hh:145
gem5::MipsISA::index
Bitfield< 30, 0 > index
Definition: pra_constants.hh:47
sc_dt
Definition: sc_bit.cc:67
sc_dt::scfx_rep::o_bit_at
bool o_bit_at(const scfx_index &) const
Definition: scfx_rep.hh:495
sc_dt::scfx_rep::set_zero
void set_zero(int=1)
Definition: scfx_rep.hh:321
sc_dt::cmp_scfx_rep
int cmp_scfx_rep(const scfx_rep &a, const scfx_rep &b)
Definition: scfx_rep.cc:1758
sc_dt::scfx_params
Definition: scfx_params.hh:98
sc_dt::scfx_rep::quantization
void quantization(const scfx_params &, bool &)
Definition: scfx_rep.cc:1811
sc_dt::div_scfx_rep
scfx_rep * div_scfx_rep(const scfx_rep &lhs, const scfx_rep &rhs, int div_wl)
Definition: scfx_rep.cc:1527
SCFX_FAIL_IF_
#define SCFX_FAIL_IF_(cnd)
Definition: scfx_rep.cc:411
sc_dt::scfx_rep::scfx_rep
scfx_rep()
Definition: scfx_rep.cc:131
sc_dt::scfx_rep::clear
bool clear(int, const scfx_params &)
Definition: scfx_rep.cc:2429
sc_dt::scfx_to_digit
int scfx_to_digit(char c, sc_numrep numrep)
Definition: scfx_utils.hh:383
sc_dt::scfx_rep::is_neg
bool is_neg() const
Definition: scfx_rep.hh:404
sc_dt::scfx_rep::infinity
@ infinity
Definition: scfx_rep.hh:174
sc_dt::SC_OCT
@ SC_OCT
Definition: sc_nbdefs.hh:153
sc_dt::scfx_rep::o_zero_left
bool o_zero_left(const scfx_index &) const
Definition: scfx_rep.hh:506
sc_dt::scfx_rep::m_state
state m_state
Definition: scfx_rep.hh:311
sc_dt::scfx_tc2csd
void scfx_tc2csd(scfx_string &s, int w_prefix)
Definition: scfx_utils.cc:85
sc_dt::pow10_fx
static scfx_pow10 pow10_fx
Definition: scfx_rep.cc:116
GEM5_FALLTHROUGH
#define GEM5_FALLTHROUGH
Definition: compiler.hh:61
sc_dt::sc_bv_base
Definition: sc_bv_base.hh:105
gem5::ArmISA::e
Bitfield< 9 > e
Definition: misc_types.hh:64
sc_dt::SCFX_IEEE_DOUBLE_M_SIZE
const unsigned int SCFX_IEEE_DOUBLE_M_SIZE
Definition: scfx_ieee.hh:134
gem5::ArmISA::a
Bitfield< 8 > a
Definition: misc_types.hh:65
sc_dt::scfx_index
Definition: scfx_rep.hh:147
SC_REPORT_FATAL
#define SC_REPORT_FATAL(msg_type, msg)
Definition: sc_report_handler.hh:131
sc_dt::list
static scfx_rep_node * list
Definition: scfx_rep.cc:368
sc_dt::scfx_rep::set_inf
void set_inf(int)
Definition: scfx_rep.hh:337
sc_dt::SC_SAT_ZERO
@ SC_SAT_ZERO
Definition: sc_fxdefs.hh:120
sc_dt::n_word
static int n_word(int x)
Definition: scfx_rep.cc:121
sc_dt::scfx_print_inf
void scfx_print_inf(scfx_string &s, bool negative)
Definition: scfx_utils.hh:441
sc_dt::scfx_pow2
double scfx_pow2(int exp)
Definition: scfx_ieee.hh:599
sc_bv_base.hh
sc_dt::scfx_rep::shift_right
void shift_right(int)
Definition: scfx_rep.cc:2336
sc_dt::scfx_rep::to_double
double to_double() const
Definition: scfx_rep.cc:754
sc_dt::scfx_rep::rshift
void rshift(int)
Definition: scfx_rep.cc:1656
sc_dt::scfx_rep::round
void round(int)
Definition: scfx_rep.cc:2614
sc_dt::scfx_rep::m_msw
int m_msw
Definition: scfx_rep.hh:312
gem5::X86ISA::base
Bitfield< 51, 12 > base
Definition: pagetable.hh:141
sc_dt::scfx_rep::overflow
void overflow(const scfx_params &, bool &)
Definition: scfx_rep.cc:1895
sc_dt::scfx_rep::shift_left
void shift_left(int)
Definition: scfx_rep.cc:2311
sc_dt::remainder
return remainder
Definition: scfx_rep.cc:2201
sc_dt::SC_RND_INF
@ SC_RND_INF
Definition: sc_fxdefs.hh:96
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:66
sc_dt::scfx_rep::from_string
void from_string(const char *, int)
Definition: scfx_rep.cc:421
sc_dt::sc_enc
sc_enc
Definition: sc_fxdefs.hh:70
gem5::PowerISA::bi
Bitfield< 20, 16 > bi
Definition: types.hh:80
sc_dt::scfx_string
Definition: scfx_string.hh:108
sc_dt::scfx_rep::normal
@ normal
Definition: scfx_rep.hh:173
sc_dt::scfx_rep::o_invert
void o_invert(const scfx_index &)
Definition: scfx_rep.hh:622
sc_dt::scfx_params::enc
sc_enc enc() const
Definition: scfx_params.hh:150
sc_dt::scfx_exp_start
bool scfx_exp_start(const char *s)
Definition: scfx_utils.hh:283
sc_dt::align
void align(const scfx_rep &lhs, const scfx_rep &rhs, int &new_wp, int &len_mant, scfx_mant_ref &lhs_mant, scfx_mant_ref &rhs_mant)
Definition: scfx_rep.cc:2083
sc_dt::inc
void inc(scfx_mant &mant)
Definition: scfx_mant.hh:341
sc_dt::scfx_rep::set_nan
void set_nan()
Definition: scfx_rep.hh:330
sc_dt::scfx_rep::get_bit
bool get_bit(int) const
Definition: scfx_rep.cc:2360
sc_dt::SC_RND_CONV
@ SC_RND_CONV
Definition: sc_fxdefs.hh:97
gem5::ArmISA::shift
Bitfield< 6, 5 > shift
Definition: types.hh:117
sc_dt::scfx_rep::cast
void cast(const scfx_params &, bool &, bool &)
Definition: scfx_rep.cc:2056
sc_dt::scfx_find_lsb
int scfx_find_lsb(unsigned long x)
Definition: scfx_utils.hh:117
sc_dt::scfx_rep::multiply_by_ten
void multiply_by_ten()
Definition: scfx_rep.cc:2178
sc_dt::complement
void complement(scfx_mant &target, const scfx_mant &source, int size)
Definition: scfx_mant.hh:329
sc_dt::scfx_rep::m_mant
scfx_mant m_mant
Definition: scfx_rep.hh:308
sc_dt::scfx_rep::divide_by_ten
unsigned int divide_by_ten()
Definition: scfx_rep.cc:2176
sc_dt::scfx_rep::set_hex
void set_hex(int, int)
Definition: scfx_rep.cc:2284
sc_dt::SC_BIN_US
@ SC_BIN_US
Definition: sc_nbdefs.hh:156
sc_dt::SC_E
@ SC_E
Definition: sc_fxdefs.hh:167
gem5::ArmISA::j
Bitfield< 24 > j
Definition: misc_types.hh:57
sc_dt::scfx_rep::resize
scfx_mant * resize(int, int) const
Definition: scfx_rep.cc:2231
gem5::ArmISA::b
Bitfield< 7 > b
Definition: misc_types.hh:381
sc_dt::sc_fmt
sc_fmt
Definition: sc_fxdefs.hh:164
sc_dt::uint64
uint64_t uint64
Definition: sc_nbdefs.hh:206
sc_dt::SC_NOBASE
@ SC_NOBASE
Definition: sc_nbdefs.hh:151
sc_dt::scfx_rep::dump
void dump(::std::ostream &) const
Definition: scfx_rep.cc:2526
sc_dt::SC_SAT
@ SC_SAT
Definition: sc_fxdefs.hh:119
sc_dt::neg_scfx_rep
scfx_rep * neg_scfx_rep(const scfx_rep &)
Definition: scfx_rep.hh:371
sc_dt::scfx_print_nan
void scfx_print_nan(scfx_string &s)
Definition: scfx_utils.hh:439
gem5::MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:326
sc_dt::min_mant
const int min_mant
Definition: scfx_rep.hh:137
sc_dt::sub_mants
static int sub_mants(int size, scfx_mant &result, const scfx_mant &a, const scfx_mant &b)
Definition: scfx_rep.cc:1228
sc_dt::scfx_rep::set_bin
void set_bin(int)
Definition: scfx_rep.cc:2252
sc_dt::scfx_rep::q_clear
void q_clear(const scfx_index &)
Definition: scfx_rep.hh:649
sc_dt::scfx_rep::not_a_number
@ not_a_number
Definition: scfx_rep.hh:175
sc_dt::bits_in_word
const int bits_in_word
Definition: scfx_rep.hh:140
gem5::ArmISA::s
Bitfield< 4 > s
Definition: misc_types.hh:561
sc_dt::scfx_parse_sign
int scfx_parse_sign(const char *&s, bool &sign_char)
Definition: scfx_utils.hh:142
gem5::to_bool
bool to_bool(const std::string &value, bool &retval)
Turn a string representation of a boolean into a boolean value.
Definition: str.hh:204
sc_dt::SC_RND_ZERO
@ SC_RND_ZERO
Definition: sc_fxdefs.hh:94
sc_dt::mantissa0_size
static const int mantissa0_size
Definition: scfx_rep.cc:118
sc_dt::scfx_rep::to_uint64
uint64 to_uint64() const
Definition: scfx_rep.cc:866
sc_dt::SC_TRN
@ SC_TRN
Definition: sc_fxdefs.hh:98
sc_dt::scfx_rep::set
bool set(int, const scfx_params &)
Definition: scfx_rep.cc:2390
sc_dt::word_short::s
struct sc_dt::word_short::@112 s
sc_dt::scfx_rep::set_slice
bool set_slice(int, int, const scfx_params &, const sc_bv_base &)
Definition: scfx_rep.cc:2486
sc_dt::scfx_mant
Definition: scfx_mant.hh:107
sc_dt::scfx_rep::o_extend
void o_extend(const scfx_index &, sc_enc)
Definition: scfx_rep.hh:472
sc_dt::SC_WRAP
@ SC_WRAP
Definition: sc_fxdefs.hh:122
gem5::MipsISA::l
Bitfield< 5 > l
Definition: pra_constants.hh:323
compiler.hh
sc_dt::SC_OCT_SM
@ SC_OCT_SM
Definition: sc_nbdefs.hh:159
sc_dt::scfx_rep::is_nan
bool is_nan() const
Definition: scfx_rep.hh:420
sc_dt::half_word
unsigned short half_word
Definition: scfx_mant.hh:99
sc_dt::SC_SAT_SYM
@ SC_SAT_SYM
Definition: sc_fxdefs.hh:121
sc_dt::add_mants
static int add_mants(int size, scfx_mant &result, const scfx_mant &a, const scfx_mant &b)
Definition: scfx_rep.cc:1207
sc_dt::int64
int64_t int64
Definition: sc_nbdefs.hh:205
gem5::ArmISA::t
Bitfield< 5 > t
Definition: misc_types.hh:70
gem5::ArmISA::c
Bitfield< 29 > c
Definition: misc_types.hh:53
sc_core::SC_ID_ASSERTION_FAILED_
const char SC_ID_ASSERTION_FAILED_[]
Definition: messages.cc:39
sc_dt::sub_with_index
static int sub_with_index(scfx_mant &a, int a_msw, int, const scfx_mant &b, int b_msw, int b_lsw)
Definition: scfx_rep.cc:1326
sc_dt::scfx_rep::is_zero
bool is_zero() const
Definition: scfx_rep.hh:407
sc_dt::compare_msw_ff
int compare_msw_ff(const scfx_rep &lhs, const scfx_rep &rhs)
Definition: scfx_rep.cc:2127
sc_dt::scfx_is_inf
bool scfx_is_inf(const char *s)
Definition: scfx_utils.hh:277
sc_dt::scfx_rep::print
void print(::std::ostream &) const
Definition: scfx_rep.cc:2515
endian.hh
messages.hh
sc_dt::scfx_rep::div_scfx_rep
friend scfx_rep * div_scfx_rep(const scfx_rep &, const scfx_rep &, int)
Definition: scfx_rep.cc:1527
sc_dt::sc_min
const T sc_min(const T &a, const T &b)
Definition: functions.hh:59
sc_dt::scfx_rep_node::next
scfx_rep_node * next
Definition: scfx_rep.cc:365
sc_dt::scfx_rep::lshift
void lshift(int)
Definition: scfx_rep.cc:1625
sc_dt::print_dec
static void print_dec(scfx_string &s, scfx_ieee_double id, int w_prefix, sc_fmt fmt)
Definition: sc_fxval.cc:214
sc_dt::SC_RND_MIN_INF
@ SC_RND_MIN_INF
Definition: sc_fxdefs.hh:95
sc_dt::scfx_rep::q_zero
bool q_zero(const scfx_index &) const
Definition: scfx_rep.hh:694
sc_dt::word_short::l
word l
Definition: scfx_rep.cc:1432
sc_dt::scfx_find_msb
int scfx_find_msb(unsigned long x)
Definition: scfx_utils.hh:98
sc_dt::SC_BIN_SM
@ SC_BIN_SM
Definition: sc_nbdefs.hh:157
sc_dt::SC_CSD
@ SC_CSD
Definition: sc_nbdefs.hh:162
sc_dt::scfx_rep::q_incr
void q_incr(const scfx_index &)
Definition: scfx_rep.hh:662
sc_dt::scfx_rep::m_sign
int m_sign
Definition: scfx_rep.hh:310
sc_dt::sc_numrep
sc_numrep
Definition: sc_nbdefs.hh:115
sc_dt::scfx_rep::q_bit
bool q_bit(const scfx_index &) const
Definition: scfx_rep.hh:633
gem5::ArmISA::u
Bitfield< 22 > u
Definition: misc_types.hh:352
sc_dt::scfx_print_exp
void scfx_print_exp(scfx_string &s, int exp)
Definition: scfx_utils.hh:492
scfx_utils.hh
sc_dt::scfx_rep::to_string
const char * to_string(sc_numrep, int, sc_fmt, const scfx_params *=0) const
Definition: scfx_rep.cc:1172
gem5::RiscvISA::x
Bitfield< 3 > x
Definition: pagetable.hh:73
sc_dt::sc_max
const T sc_max(const T &a, const T &b)
Definition: functions.hh:56
sc_dt::SC_HEX
@ SC_HEX
Definition: sc_nbdefs.hh:155
gem5::ArmISA::n
Bitfield< 31 > n
Definition: misc_types.hh:455
gem5::X86ISA::os
Bitfield< 17 > os
Definition: misc.hh:809
sc_dt::SC_TC_
@ SC_TC_
Definition: sc_fxdefs.hh:72
sc_dt::print_other
static void print_other(scfx_string &s, const scfx_ieee_double &id, sc_numrep numrep, int w_prefix, sc_fmt fmt, const scfx_params *params)
Definition: sc_fxval.cc:321
gem5::X86ISA::over
Bitfield< 62 > over
Definition: misc.hh:774
sc_dt::scfx_print_prefix
void scfx_print_prefix(scfx_string &s, sc_numrep numrep)
Definition: scfx_utils.hh:450
sc_dt::scfx_rep::resize_to
void resize_to(int, int=0)
Definition: scfx_rep.hh:446
sc_dt::scfx_rep_node::data
char data[sizeof(scfx_rep)]
Definition: scfx_rep.cc:364
sc_dt::scfx_rep::set_oct
void set_oct(int, int)
Definition: scfx_rep.cc:2263
sc_dt::scfx_rep_node
Definition: scfx_rep.cc:362
sc_dt::scfx_rep::is_inf
bool is_inf() const
Definition: scfx_rep.hh:422
sc_dt::scfx_rep::o_zero_right
bool o_zero_right(const scfx_index &) const
Definition: scfx_rep.hh:523
sc_dt::scfx_is_nan
bool scfx_is_nan(const char *s)
Definition: scfx_utils.hh:271
sc_core::sc_abort
void sc_abort()
Definition: sc_report.cc:178
gem5::ArmISA::id
Bitfield< 33 > id
Definition: misc_types.hh:250
sc_dt::scfx_rep::toggle_tc
void toggle_tc()
Definition: scfx_rep.hh:746
sc_dt::bits_in_int
const int bits_in_int
Definition: scfx_rep.hh:139
gem5::MipsISA::k
Bitfield< 23 > k
Definition: dt_constants.hh:81
sc_dt::scfx_rep::q_odd
bool q_odd(const scfx_index &) const
Definition: scfx_rep.hh:683
scfx_rep.hh
sc_dt::sub_scfx_rep
scfx_rep * sub_scfx_rep(const scfx_rep &lhs, const scfx_rep &rhs, int max_wl)
Definition: scfx_rep.cc:1358
sc_dt::scfx_params::iwl
int iwl() const
Definition: scfx_params.hh:169
sc_dt::multiply
void multiply(scfx_rep &result, const scfx_rep &lhs, const scfx_rep &rhs, int max_wl)
Definition: scfx_rep.cc:1452
sc_core::SC_ID_WRAP_SM_NOT_DEFINED_
const char SC_ID_WRAP_SM_NOT_DEFINED_[]
Definition: messages.cc:45
sc_dt::scfx_rep::is_normal
bool is_normal() const
Definition: scfx_rep.hh:424
sc_dt::scfx_ieee_double
Definition: scfx_ieee.hh:146
sc_dt::scfx_index::wi
int wi() const
Definition: scfx_rep.hh:152
sc_dt::scfx_rep::size
int size() const
Definition: scfx_rep.hh:402
sc_lv_base.hh
sc_dt::SC_WRAP_SM
@ SC_WRAP_SM
Definition: sc_fxdefs.hh:123
scfx_pow10.hh
SC_ERROR_IF_
#define SC_ERROR_IF_(cnd, id)
Definition: sc_fxdefs.hh:251
sc_dt::SC_DEC
@ SC_DEC
Definition: sc_nbdefs.hh:154
sc_dt::scfx_csd2tc
void scfx_csd2tc(scfx_string &csd)
Definition: scfx_utils.cc:140
sc_dt::scfx_mant_ref
Definition: scfx_mant.hh:356
sc_dt::scfx_rep::m_wp
int m_wp
Definition: scfx_rep.hh:309
sc_dt::scfx_rep::o_set_low
void o_set_low(const scfx_index &, sc_enc)
Definition: scfx_rep.hh:538
sc_dt::SC_RND
@ SC_RND
Definition: sc_fxdefs.hh:93
sc_dt::scfx_rep::get_type
void get_type(int &, int &, sc_enc &) const
Definition: scfx_rep.cc:2570
SC_ASSERT_
#define SC_ASSERT_(cnd, msg)
Definition: sc_fxdefs.hh:248
sc_dt::scfx_rep::m_r_flag
bool m_r_flag
Definition: scfx_rep.hh:314
sc_dt::scfx_rep::o_set
void o_set(const scfx_index &, const scfx_index &, sc_enc, bool)
Definition: scfx_rep.hh:589
sc_dt::scfx_rep::o_set_high
void o_set_high(const scfx_index &, const scfx_index &, sc_enc, int=1)
Definition: scfx_rep.hh:556
sc_dt::SC_HEX_US
@ SC_HEX_US
Definition: sc_nbdefs.hh:160
scfx_ieee.hh
sc_dt::scfx_rep::get_slice
bool get_slice(int, int, const scfx_params &, sc_bv_base &) const
Definition: scfx_rep.cc:2465
sc_dt::SC_US_
@ SC_US_
Definition: sc_fxdefs.hh:73
sc_dt::word_short
Definition: scfx_rep.cc:1430
sc_dt::SC_TRN_ZERO
@ SC_TRN_ZERO
Definition: sc_fxdefs.hh:99

Generated on Tue Sep 21 2021 12:25:50 for gem5 by doxygen 1.8.17