gem5  v22.1.0.0
scfx_ieee.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  scfx_ieee.h -
23 
24  Original Author: Martin Janssen, Synopsys, Inc.
25 
26  *****************************************************************************/
27 
28 /*****************************************************************************
29 
30  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
31  changes you are making here.
32 
33  Name, Affiliation, Date:
34  Description of Modification:
35 
36  *****************************************************************************/
37 
38 // $Log: scfx_ieee.h,v $
39 // Revision 1.3 2011/08/24 22:05:43 acg
40 // Torsten Maehne: initialization changes to remove warnings.
41 //
42 // Revision 1.2 2011/08/07 18:55:24 acg
43 // Philipp A. Hartmann: added guard for __clang__ to get the clang platform
44 // working.
45 //
46 // Revision 1.1.1.1 2006/12/15 20:20:04 acg
47 // SystemC 2.3
48 //
49 // Revision 1.3 2006/01/13 18:53:58 acg
50 // Andy Goodrich: added $Log command so that CVS comments are reproduced in
51 // the source.
52 //
53 
54 #ifndef __SYSTEMC_EXT_DT_FX_SCFX_IEEE_HH__
55 #define __SYSTEMC_EXT_DT_FX_SCFX_IEEE_HH__
56 
57 #include "../../utils/endian.hh"
58 #include "sc_fxdefs.hh"
59 
60 namespace sc_dt
61 {
62 
63 // classes defined in this module
64 union ieee_double;
65 class scfx_ieee_double;
66 union ieee_float;
67 class scfx_ieee_float;
68 
69 #define SCFX_MASK_(Size) ((1u << (Size))-1u)
70 
71 // ----------------------------------------------------------------------------
72 // UNION : ieee_double
73 //
74 // IEEE 754 double-precision format.
75 // ----------------------------------------------------------------------------
76 
78 {
79  double d;
80 
81  struct
82  {
83 #if defined(SC_BOOST_BIG_ENDIAN)
84  unsigned negative:1;
85  unsigned exponent:11;
86  unsigned mantissa0:20;
87  unsigned mantissa1:32;
88 #elif defined(SC_BOOST_LITTLE_ENDIAN)
89  unsigned mantissa1:32;
90  unsigned mantissa0:20;
91  unsigned exponent:11;
92  unsigned negative:1;
93 #endif
94  } s;
95 };
96 
97 
98 const unsigned int SCFX_IEEE_DOUBLE_BIAS = 1023U;
99 
100 const int SCFX_IEEE_DOUBLE_E_MAX = 1023;
101 const int SCFX_IEEE_DOUBLE_E_MIN = -1022;
102 
103 const unsigned int SCFX_IEEE_DOUBLE_M_SIZE = 52;
104 const unsigned int SCFX_IEEE_DOUBLE_M0_SIZE = 20;
105 const unsigned int SCFX_IEEE_DOUBLE_M1_SIZE = 32;
106 const unsigned int SCFX_IEEE_DOUBLE_E_SIZE = 11;
107 
108 
109 // ----------------------------------------------------------------------------
110 // CLASS : scfx_ieee_double
111 //
112 // Convenient interface to union ieee_double.
113 // ----------------------------------------------------------------------------
114 
116 {
118  public:
120  scfx_ieee_double(double);
122 
123  scfx_ieee_double &operator = (double);
125 
126  operator double() const;
127 
128  unsigned int negative() const;
129  void negative(unsigned int);
130  int exponent() const;
131  void exponent(int);
132  unsigned int mantissa0() const;
133  void mantissa0(unsigned int);
134  unsigned int mantissa1() const;
135  void mantissa1(unsigned int);
136 
137  bool is_zero() const;
138  bool is_subnormal() const;
139  bool is_normal() const;
140  bool is_inf() const;
141  bool is_nan() const;
142 
143  void set_inf();
144  void set_nan();
145 
146  int msb() const; // most significant non-zero bit
147  int lsb() const; // least significant non-zero bit
148 
149  static const scfx_ieee_double nan();
150  static const scfx_ieee_double inf(int);
151 };
152 
153 
154 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
155 
157 {
158  m_id.d = 0.0;
159 }
160 
161 inline scfx_ieee_double::scfx_ieee_double(double d) : m_id()
162 {
163  m_id.d = d;
164 }
165 
167  m_id(a.m_id)
168 {
169  // m_id.d = a.m_id.d;
170 }
171 
172 inline scfx_ieee_double &
174 {
175  m_id.d = d;
176  return *this;
177 }
178 
179 inline scfx_ieee_double &
181 {
182  m_id.d = a.m_id.d;
183  return *this;
184 }
185 
186 inline scfx_ieee_double::operator double() const
187 {
188  return m_id.d;
189 }
190 
191 inline unsigned int
193 {
194  return m_id.s.negative;
195 }
196 
197 inline void
199 {
200  m_id.s.negative = a & SCFX_MASK_(1);
201 }
202 
203 inline int
205 {
206  return m_id.s.exponent - SCFX_IEEE_DOUBLE_BIAS;
207 }
208 
209 inline void
211 {
212  m_id.s.exponent = (SCFX_IEEE_DOUBLE_BIAS + a)
214 }
215 
216 inline unsigned int
218 {
219  return m_id.s.mantissa0;
220 }
221 
222 inline void
224 {
225  m_id.s.mantissa0 = a & SCFX_MASK_(SCFX_IEEE_DOUBLE_M0_SIZE);
226 }
227 
228 inline unsigned int
230 {
231  return m_id.s.mantissa1;
232 }
233 
234 inline void
236 {
237  m_id.s.mantissa1 = a; // & SCFX_MASK_(SCFX_IEEE_DOUBLE_M1_SIZE);
238 }
239 
240 inline bool
242 {
243  return (exponent() == SCFX_IEEE_DOUBLE_E_MIN - 1 &&
244  mantissa0() == 0U && mantissa1() == 0U);
245 }
246 
247 inline bool
249 {
250  return (exponent() == SCFX_IEEE_DOUBLE_E_MIN - 1 &&
251  (mantissa0() != 0U || mantissa1() != 0U));
252 }
253 
254 inline bool
256 {
257  return (exponent() >= SCFX_IEEE_DOUBLE_E_MIN &&
259 }
260 
261 inline bool
263 {
264  return (exponent() == SCFX_IEEE_DOUBLE_E_MAX + 1 &&
265  mantissa0() == 0U && mantissa1() == 0U);
266 }
267 
268 inline bool
270 {
271  return (exponent() == SCFX_IEEE_DOUBLE_E_MAX + 1 &&
272  (mantissa0() != 0U || mantissa1() != 0U));
273 }
274 
275 inline void
277 {
279  mantissa0(0U);
280  mantissa1(0U);
281 }
282 
283 inline void
285 {
287  mantissa0((unsigned int)-1);
288  mantissa1((unsigned int)-1);
289 }
290 
291 #define MSB_STATEMENT(x,n) if ( x >> n ) { x >>= n; i += n; }
292 
293 inline int
295 {
296  unsigned int m0 = mantissa0();
297  unsigned int m1 = mantissa1();
298  if (m0 != 0) {
299  int i = 0;
300  MSB_STATEMENT(m0, 16);
301  MSB_STATEMENT(m0, 8);
302  MSB_STATEMENT(m0, 4);
303  MSB_STATEMENT(m0, 2);
304  MSB_STATEMENT(m0, 1);
305  return (i - 20);
306  } else if (m1 != 0) {
307  int i = 0;
308  MSB_STATEMENT(m1, 16);
309  MSB_STATEMENT(m1, 8);
310  MSB_STATEMENT(m1, 4);
311  MSB_STATEMENT(m1, 2);
312  MSB_STATEMENT(m1, 1);
313  return (i - 52);
314  } else {
315  return 0;
316  }
317 }
318 
319 #undef MSB_STATEMENT
320 
321 #define LSB_STATEMENT(x,n) if ( x << n ) { x <<= n; i -= n; }
322 
323 inline int
325 {
326  unsigned int m0 = mantissa0();
327  unsigned int m1 = mantissa1();
328  if (m1 != 0) {
329  int i = 31;
330  LSB_STATEMENT(m1, 16);
331  LSB_STATEMENT(m1, 8);
332  LSB_STATEMENT(m1, 4);
333  LSB_STATEMENT(m1, 2);
334  LSB_STATEMENT(m1, 1);
335  return (i - 52);
336  } else if (m0 != 0) {
337  int i = 31;
338  LSB_STATEMENT(m0, 16);
339  LSB_STATEMENT(m0, 8);
340  LSB_STATEMENT(m0, 4);
341  LSB_STATEMENT(m0, 2);
342  LSB_STATEMENT(m0, 1);
343  return (i - 20);
344  } else {
345  return 0;
346  }
347 }
348 
349 #undef LSB_STATEMENT
350 
351 inline const scfx_ieee_double
353 {
355  id.set_nan();
356  return id;
357 }
358 
359 inline const scfx_ieee_double
361 {
362  scfx_ieee_double id(sign);
363  id.set_inf();
364  return id;
365 }
366 
367 
368 // ----------------------------------------------------------------------------
369 // UNION : ieee_float
370 //
371 // IEEE 754 single-precision format.
372 // ----------------------------------------------------------------------------
373 
375 {
376  float f;
377  struct
378  {
379 #if defined(SC_BOOST_BIG_ENDIAN)
380  unsigned negative:1;
381  unsigned exponent:8;
382  unsigned mantissa:23;
383 #elif defined(SC_BOOST_LITTLE_ENDIAN)
384  unsigned mantissa:23;
385  unsigned exponent:8;
386  unsigned negative:1;
387 #endif
388  } s;
389 };
390 
391 
392 const unsigned int SCFX_IEEE_FLOAT_BIAS = 127U;
393 
394 const int SCFX_IEEE_FLOAT_E_MAX = 127;
395 const int SCFX_IEEE_FLOAT_E_MIN = -126;
396 
397 const unsigned int SCFX_IEEE_FLOAT_M_SIZE = 23;
398 const unsigned int SCFX_IEEE_FLOAT_E_SIZE = 8;
399 
400 
401 // ----------------------------------------------------------------------------
402 // CLASS : scfx_ieee_float
403 //
404 // Convenient wrapper to union ieee_float.
405 // ----------------------------------------------------------------------------
406 
408 {
410 
411  public:
412  scfx_ieee_float();
413  scfx_ieee_float(float);
415 
418 
419  operator float() const;
420 
421  unsigned int negative() const;
422  void negative(unsigned int);
423  int exponent() const;
424  void exponent(int);
425  unsigned int mantissa() const;
426  void mantissa(unsigned int);
427 
428  bool is_zero() const;
429  bool is_subnormal() const;
430  bool is_normal() const;
431  bool is_inf() const;
432  bool is_nan() const;
433 
434  void set_inf();
435  void set_nan();
436 };
437 
438 
439 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
440 
442 {
443  m_if.f = 0.0;
444 }
445 
446 inline scfx_ieee_float::scfx_ieee_float(float f) : m_if()
447 {
448  m_if.f = f;
449 }
450 
452  m_if(a.m_if)
453 {
454  // m_if.f = a.m_if.f;
455 }
456 
457 
458 inline scfx_ieee_float &
460 {
461  m_if.f = f;
462  return *this;
463 }
464 
465 inline scfx_ieee_float &
467 {
468  m_if.f = a.m_if.f;
469  return *this;
470 }
471 
472 inline scfx_ieee_float::operator float() const
473 {
474  return m_if.f;
475 }
476 
477 inline unsigned int
479 {
480  return m_if.s.negative;
481 }
482 
483 inline void
485 {
486  m_if.s.negative = a & SCFX_MASK_(1);
487 }
488 
489 inline int
491 {
492  return m_if.s.exponent - SCFX_IEEE_FLOAT_BIAS;
493 }
494 
495 inline void
497 {
498  m_if.s.exponent = (SCFX_IEEE_FLOAT_BIAS + a) &
500 }
501 
502 inline unsigned int
504 {
505  return m_if.s.mantissa;
506 }
507 
508 inline void
510 {
511  m_if.s.mantissa = a & SCFX_MASK_(SCFX_IEEE_FLOAT_M_SIZE);
512 }
513 
514 
515 inline bool
517 {
518  return (exponent() == SCFX_IEEE_FLOAT_E_MIN - 1 && mantissa() == 0U);
519 }
520 
521 inline bool
523 {
524  return (exponent() == SCFX_IEEE_FLOAT_E_MIN - 1 && mantissa() != 0U);
525 }
526 
527 inline bool
529 {
530  return (exponent() >= SCFX_IEEE_FLOAT_E_MIN &&
532 }
533 
534 inline bool
536 {
537  return (exponent() == SCFX_IEEE_FLOAT_E_MAX + 1 && mantissa() == 0U);
538 }
539 
540 inline bool
542 {
543  return (exponent() == SCFX_IEEE_FLOAT_E_MAX + 1 && mantissa() != 0U);
544 }
545 
546 inline void
548 {
550  mantissa(0U);
551 }
552 
553 inline void
555 {
557  mantissa((unsigned int)-1);
558 }
559 
560 
561 // ----------------------------------------------------------------------------
562 // FUNCTION : scfx_pow2
563 //
564 // Computes 2.0**exp in double-precision.
565 // ----------------------------------------------------------------------------
566 
567 inline double
568 scfx_pow2(int exp)
569 {
571  if (exp < SCFX_IEEE_DOUBLE_E_MIN) {
572  r = 0.0;
573  // handle subnormal case
574  exp -= SCFX_IEEE_DOUBLE_E_MIN;
575  if ((exp += 20) >= 0) {
576  r.mantissa0(1U << exp);
577  } else if ((exp += 32) >= 0) {
578  r.mantissa1(1U << exp);
579  }
580  } else if (exp > SCFX_IEEE_DOUBLE_E_MAX) {
581  r.set_inf();
582  } else {
583  r = 1.0;
584  r.exponent(exp);
585  }
586  return r;
587 }
588 
589 
590 // ----------------------------------------------------------------------------
591 // FUNCTION : uint64_to_double
592 //
593 // Platform independent conversion from double uint64 to double.
594 // Needed because VC++6 doesn't support this conversion.
595 // ----------------------------------------------------------------------------
596 
597 inline double
599 {
600 #if defined(__clang__)
601  // conversion from uint64 to double not implemented; use int64
602  double tmp = static_cast<double>(static_cast<int64>(a));
603  return (tmp >= 0) ? tmp : tmp + sc_dt::scfx_pow2(64);
604 #else
605  return static_cast<double>(a);
606 #endif
607 }
608 
609 } // namespace sc_dt
610 
611 #undef SCFX_MASK_
612 
613 #endif // __SYSTEMC_EXT_DT_FX_SCFX_IEEE_HH__
static const scfx_ieee_double nan()
Definition: scfx_ieee.hh:352
unsigned int mantissa1() const
Definition: scfx_ieee.hh:229
static const scfx_ieee_double inf(int)
Definition: scfx_ieee.hh:360
unsigned int mantissa0() const
Definition: scfx_ieee.hh:217
scfx_ieee_double & operator=(double)
Definition: scfx_ieee.hh:173
bool is_subnormal() const
Definition: scfx_ieee.hh:248
unsigned int negative() const
Definition: scfx_ieee.hh:192
bool is_normal() const
Definition: scfx_ieee.hh:255
bool is_zero() const
Definition: scfx_ieee.hh:241
bool is_nan() const
Definition: scfx_ieee.hh:541
unsigned int mantissa() const
Definition: scfx_ieee.hh:503
bool is_zero() const
Definition: scfx_ieee.hh:516
scfx_ieee_float & operator=(float)
Definition: scfx_ieee.hh:459
unsigned int negative() const
Definition: scfx_ieee.hh:478
int exponent() const
Definition: scfx_ieee.hh:490
bool is_inf() const
Definition: scfx_ieee.hh:535
bool is_normal() const
Definition: scfx_ieee.hh:528
bool is_subnormal() const
Definition: scfx_ieee.hh:522
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 33 > id
Definition: misc_types.hh:257
Bitfield< 8 > a
Definition: misc_types.hh:66
Bitfield< 9 > d
Definition: misc_types.hh:64
Bitfield< 5 > r
Definition: pagetable.hh:60
Bitfield< 56 > f
Definition: pagetable.hh:53
Definition: sc_bit.cc:68
uint64_t uint64
Definition: sc_nbdefs.hh:172
const int SCFX_IEEE_FLOAT_E_MIN
Definition: scfx_ieee.hh:395
const unsigned int SCFX_IEEE_DOUBLE_M1_SIZE
Definition: scfx_ieee.hh:105
const int SCFX_IEEE_DOUBLE_E_MIN
Definition: scfx_ieee.hh:101
double uint64_to_double(uint64 a)
Definition: scfx_ieee.hh:598
const unsigned int SCFX_IEEE_DOUBLE_E_SIZE
Definition: scfx_ieee.hh:106
const int SCFX_IEEE_DOUBLE_E_MAX
Definition: scfx_ieee.hh:100
int64_t int64
Definition: sc_nbdefs.hh:171
const unsigned int SCFX_IEEE_DOUBLE_M0_SIZE
Definition: scfx_ieee.hh:104
const int SCFX_IEEE_FLOAT_E_MAX
Definition: scfx_ieee.hh:394
const unsigned int SCFX_IEEE_FLOAT_E_SIZE
Definition: scfx_ieee.hh:398
const unsigned int SCFX_IEEE_DOUBLE_M_SIZE
Definition: scfx_ieee.hh:103
const unsigned int SCFX_IEEE_DOUBLE_BIAS
Definition: scfx_ieee.hh:98
const unsigned int SCFX_IEEE_FLOAT_BIAS
Definition: scfx_ieee.hh:392
double scfx_pow2(int exp)
Definition: scfx_ieee.hh:568
const unsigned int SCFX_IEEE_FLOAT_M_SIZE
Definition: scfx_ieee.hh:397
#define SCFX_MASK_(Size)
Definition: scfx_ieee.hh:69
#define LSB_STATEMENT(x, n)
Definition: scfx_ieee.hh:321
#define MSB_STATEMENT(x, n)
Definition: scfx_ieee.hh:291
struct sc_dt::ieee_double::@342 s
struct sc_dt::ieee_float::@343 s

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