gem5 v24.0.0.0
Loading...
Searching...
No Matches
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
60namespace sc_dt
61{
62
63// classes defined in this module
64union ieee_double;
65class scfx_ieee_double;
66union ieee_float;
67class 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
98const unsigned int SCFX_IEEE_DOUBLE_BIAS = 1023U;
99
100const int SCFX_IEEE_DOUBLE_E_MAX = 1023;
101const int SCFX_IEEE_DOUBLE_E_MIN = -1022;
102
103const unsigned int SCFX_IEEE_DOUBLE_M_SIZE = 52;
104const unsigned int SCFX_IEEE_DOUBLE_M0_SIZE = 20;
105const unsigned int SCFX_IEEE_DOUBLE_M1_SIZE = 32;
106const 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
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
161inline 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
172inline scfx_ieee_double &
174{
175 m_id.d = d;
176 return *this;
177}
178
179inline scfx_ieee_double &
181{
182 m_id.d = a.m_id.d;
183 return *this;
184}
185
186inline scfx_ieee_double::operator double() const
187{
188 return m_id.d;
189}
190
191inline unsigned int
193{
194 return m_id.s.negative;
195}
196
197inline void
199{
200 m_id.s.negative = a & SCFX_MASK_(1);
201}
202
203inline int
205{
206 return m_id.s.exponent - SCFX_IEEE_DOUBLE_BIAS;
207}
208
209inline void
215
216inline unsigned int
218{
219 return m_id.s.mantissa0;
220}
221
222inline void
224{
226}
227
228inline unsigned int
230{
231 return m_id.s.mantissa1;
232}
233
234inline void
236{
237 m_id.s.mantissa1 = a; // & SCFX_MASK_(SCFX_IEEE_DOUBLE_M1_SIZE);
238}
239
240inline bool
242{
243 return (exponent() == SCFX_IEEE_DOUBLE_E_MIN - 1 &&
244 mantissa0() == 0U && mantissa1() == 0U);
245}
246
247inline bool
249{
250 return (exponent() == SCFX_IEEE_DOUBLE_E_MIN - 1 &&
251 (mantissa0() != 0U || mantissa1() != 0U));
252}
253
254inline bool
260
261inline bool
263{
264 return (exponent() == SCFX_IEEE_DOUBLE_E_MAX + 1 &&
265 mantissa0() == 0U && mantissa1() == 0U);
266}
267
268inline bool
270{
271 return (exponent() == SCFX_IEEE_DOUBLE_E_MAX + 1 &&
272 (mantissa0() != 0U || mantissa1() != 0U));
273}
274
275inline void
282
283inline 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
293inline 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
323inline 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
351inline const scfx_ieee_double
353{
355 id.set_nan();
356 return id;
357}
358
359inline 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
392const unsigned int SCFX_IEEE_FLOAT_BIAS = 127U;
393
394const int SCFX_IEEE_FLOAT_E_MAX = 127;
395const int SCFX_IEEE_FLOAT_E_MIN = -126;
396
397const unsigned int SCFX_IEEE_FLOAT_M_SIZE = 23;
398const 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:
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
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
458inline scfx_ieee_float &
460{
461 m_if.f = f;
462 return *this;
463}
464
465inline scfx_ieee_float &
467{
468 m_if.f = a.m_if.f;
469 return *this;
470}
471
472inline scfx_ieee_float::operator float() const
473{
474 return m_if.f;
475}
476
477inline unsigned int
479{
480 return m_if.s.negative;
481}
482
483inline void
485{
486 m_if.s.negative = a & SCFX_MASK_(1);
487}
488
489inline int
491{
492 return m_if.s.exponent - SCFX_IEEE_FLOAT_BIAS;
493}
494
495inline void
501
502inline unsigned int
504{
505 return m_if.s.mantissa;
506}
507
508inline void
510{
512}
513
514
515inline bool
517{
518 return (exponent() == SCFX_IEEE_FLOAT_E_MIN - 1 && mantissa() == 0U);
519}
520
521inline bool
523{
524 return (exponent() == SCFX_IEEE_FLOAT_E_MIN - 1 && mantissa() != 0U);
525}
526
527inline bool
533
534inline bool
536{
537 return (exponent() == SCFX_IEEE_FLOAT_E_MAX + 1 && mantissa() == 0U);
538}
539
540inline bool
542{
543 return (exponent() == SCFX_IEEE_FLOAT_E_MAX + 1 && mantissa() != 0U);
544}
545
546inline void
552
553inline 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
567inline double
568scfx_pow2(int exp)
569{
571 if (exp < SCFX_IEEE_DOUBLE_E_MIN) {
572 r = 0.0;
573 // handle subnormal case
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
597inline 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
unsigned int mantissa() const
Definition scfx_ieee.hh:503
scfx_ieee_float & operator=(float)
Definition scfx_ieee.hh:459
unsigned int negative() const
Definition scfx_ieee.hh:478
bool is_normal() const
Definition scfx_ieee.hh:528
bool is_subnormal() const
Definition scfx_ieee.hh:522
int f(int a, int b)
SwitchingFiber a
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::@376 s
struct sc_dt::ieee_float::@377 s

Generated on Tue Jun 18 2024 16:24:06 for gem5 by doxygen 1.11.0