gem5  v20.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 
77 union ieee_double
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 
115 class scfx_ieee_double
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 
156 inline scfx_ieee_double::scfx_ieee_double() : m_id()
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 
166 inline scfx_ieee_double::scfx_ieee_double(const scfx_ieee_double &a) :
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 &
180 scfx_ieee_double::operator = (const scfx_ieee_double &a)
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
198 scfx_ieee_double::negative(unsigned int a)
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 {
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
294 scfx_ieee_double::msb() const
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
324 scfx_ieee_double::lsb() const
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
360 scfx_ieee_double::inf(int sign)
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 
374 union ieee_float
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 
441 inline scfx_ieee_float::scfx_ieee_float() : m_if()
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 
451 inline scfx_ieee_float::scfx_ieee_float(const scfx_ieee_float &a) :
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 &
466 scfx_ieee_float::operator = (const scfx_ieee_float &a)
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
484 scfx_ieee_float::negative(unsigned int a)
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__
sc_dt::ieee_float::s
struct sc_dt::ieee_float::@118 s
sc_dt::SCFX_IEEE_DOUBLE_E_MAX
const int SCFX_IEEE_DOUBLE_E_MAX
Definition: scfx_ieee.hh:131
sc_dt::scfx_ieee_double::scfx_ieee_double
scfx_ieee_double()
Definition: scfx_ieee.hh:187
sc_dt::SCFX_IEEE_FLOAT_BIAS
const unsigned int SCFX_IEEE_FLOAT_BIAS
Definition: scfx_ieee.hh:423
sc_dt::scfx_ieee_double::m_id
ieee_double m_id
Definition: scfx_ieee.hh:148
sc_dt::SCFX_IEEE_DOUBLE_E_MIN
const int SCFX_IEEE_DOUBLE_E_MIN
Definition: scfx_ieee.hh:132
sc_dt::SCFX_IEEE_DOUBLE_E_SIZE
const unsigned int SCFX_IEEE_DOUBLE_E_SIZE
Definition: scfx_ieee.hh:137
sc_dt
Definition: sc_bit.cc:67
sc_dt::uint64_to_double
double uint64_to_double(uint64 a)
Definition: scfx_ieee.hh:629
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
sc_dt::scfx_ieee_double::set_nan
void set_nan()
Definition: scfx_ieee.hh:315
sc_dt::ieee_double::s
struct sc_dt::ieee_double::@117 s
sc_dt::scfx_ieee_double::msb
int msb() const
Definition: scfx_ieee.hh:325
sc_dt::scfx_ieee_float::m_if
ieee_float m_if
Definition: scfx_ieee.hh:440
sc_dt::SCFX_IEEE_DOUBLE_M_SIZE
const unsigned int SCFX_IEEE_DOUBLE_M_SIZE
Definition: scfx_ieee.hh:134
sc_dt::scfx_ieee_float::set_inf
void set_inf()
Definition: scfx_ieee.hh:578
sc_dt::SCFX_IEEE_FLOAT_E_MIN
const int SCFX_IEEE_FLOAT_E_MIN
Definition: scfx_ieee.hh:426
sc_dt::scfx_pow2
double scfx_pow2(int exp)
Definition: scfx_ieee.hh:599
sc_fxdefs.hh
sc_dt::scfx_ieee_float::is_normal
bool is_normal() const
Definition: scfx_ieee.hh:559
sc_dt::ieee_double
Definition: scfx_ieee.hh:108
sc_dt::scfx_ieee_double::inf
static const scfx_ieee_double inf(int)
Definition: scfx_ieee.hh:391
sc_dt::SCFX_IEEE_DOUBLE_BIAS
const unsigned int SCFX_IEEE_DOUBLE_BIAS
Definition: scfx_ieee.hh:129
LSB_STATEMENT
#define LSB_STATEMENT(x, n)
Definition: scfx_ieee.hh:352
sc_dt::scfx_ieee_float::is_zero
bool is_zero() const
Definition: scfx_ieee.hh:547
sc_dt::scfx_ieee_float::is_subnormal
bool is_subnormal() const
Definition: scfx_ieee.hh:553
SCFX_MASK_
#define SCFX_MASK_(Size)
Definition: scfx_ieee.hh:100
sc_dt::ieee_float
Definition: scfx_ieee.hh:405
sc_dt::scfx_ieee_float::mantissa
unsigned int mantissa() const
Definition: scfx_ieee.hh:534
ArmISA::a
Bitfield< 8 > a
Definition: miscregs_types.hh:62
sc_dt::scfx_ieee_double::is_normal
bool is_normal() const
Definition: scfx_ieee.hh:286
sc_dt::uint64
uint64_t uint64
Definition: sc_nbdefs.hh:206
sc_dt::SCFX_IEEE_FLOAT_E_SIZE
const unsigned int SCFX_IEEE_FLOAT_E_SIZE
Definition: scfx_ieee.hh:429
ArmISA::d
Bitfield< 9 > d
Definition: miscregs_types.hh:60
sc_dt::scfx_ieee_double::set_inf
void set_inf()
Definition: scfx_ieee.hh:307
sc_dt::SCFX_IEEE_DOUBLE_M1_SIZE
const unsigned int SCFX_IEEE_DOUBLE_M1_SIZE
Definition: scfx_ieee.hh:136
sc_dt::scfx_ieee_double::operator=
scfx_ieee_double & operator=(double)
Definition: scfx_ieee.hh:204
MipsISA::r
r
Definition: pra_constants.hh:95
sc_dt::scfx_ieee_double::mantissa0
unsigned int mantissa0() const
Definition: scfx_ieee.hh:248
sc_dt::SCFX_IEEE_FLOAT_M_SIZE
const unsigned int SCFX_IEEE_FLOAT_M_SIZE
Definition: scfx_ieee.hh:428
sc_dt::scfx_ieee_double::is_zero
bool is_zero() const
Definition: scfx_ieee.hh:272
sc_dt::int64
int64_t int64
Definition: sc_nbdefs.hh:205
sc_dt::scfx_ieee_float
Definition: scfx_ieee.hh:438
sc_dt::scfx_ieee_double::mantissa1
unsigned int mantissa1() const
Definition: scfx_ieee.hh:260
sc_dt::scfx_ieee_double::is_nan
bool is_nan() const
Definition: scfx_ieee.hh:300
sc_dt::scfx_ieee_float::exponent
int exponent() const
Definition: scfx_ieee.hh:521
sc_dt::ieee_float::f
float f
Definition: scfx_ieee.hh:407
sc_dt::scfx_ieee_float::is_inf
bool is_inf() const
Definition: scfx_ieee.hh:566
sc_dt::scfx_ieee_double::is_subnormal
bool is_subnormal() const
Definition: scfx_ieee.hh:279
sc_dt::ieee_double::d
double d
Definition: scfx_ieee.hh:110
sc_dt::scfx_ieee_float::scfx_ieee_float
scfx_ieee_float()
Definition: scfx_ieee.hh:472
sc_dt::scfx_ieee_float::negative
unsigned int negative() const
Definition: scfx_ieee.hh:509
sc_dt::scfx_ieee_double::lsb
int lsb() const
Definition: scfx_ieee.hh:355
sc_dt::scfx_ieee_float::set_nan
void set_nan()
Definition: scfx_ieee.hh:585
sc_dt::scfx_ieee_double::is_inf
bool is_inf() const
Definition: scfx_ieee.hh:293
sc_dt::scfx_ieee_double::negative
unsigned int negative() const
Definition: scfx_ieee.hh:223
sc_dt::scfx_ieee_float::is_nan
bool is_nan() const
Definition: scfx_ieee.hh:572
sc_dt::SCFX_IEEE_DOUBLE_M0_SIZE
const unsigned int SCFX_IEEE_DOUBLE_M0_SIZE
Definition: scfx_ieee.hh:135
sc_dt::scfx_ieee_double::nan
static const scfx_ieee_double nan()
Definition: scfx_ieee.hh:383
sc_dt::scfx_ieee_float::operator=
scfx_ieee_float & operator=(float)
Definition: scfx_ieee.hh:490
sc_dt::scfx_ieee_double
Definition: scfx_ieee.hh:146
sc_dt::SCFX_IEEE_FLOAT_E_MAX
const int SCFX_IEEE_FLOAT_E_MAX
Definition: scfx_ieee.hh:425
sc_dt::scfx_ieee_double::exponent
int exponent() const
Definition: scfx_ieee.hh:235
ArmISA::id
Bitfield< 33 > id
Definition: miscregs_types.hh:247
MSB_STATEMENT
#define MSB_STATEMENT(x, n)
Definition: scfx_ieee.hh:322
ArmISA::f
Bitfield< 6 > f
Definition: miscregs_types.hh:64

Generated on Wed Sep 30 2020 14:02:15 for gem5 by doxygen 1.8.17