SystemC 3.0.0
Accellera SystemC proof-of-concept library
scfx_ieee.h
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 SCFX_IEEE_H
55#define SCFX_IEEE_H
56
57
59
60
61namespace sc_dt
62{
63
64// classes defined in this module
65union ieee_double;
66class scfx_ieee_double;
67union ieee_float;
68class scfx_ieee_float;
69
70#define SCFX_MASK_(Size) \
71 ((1u << (Size))-1u)
72
73// ----------------------------------------------------------------------------
74// UNION : ieee_double
75//
76// IEEE 754 double-precision format.
77// ----------------------------------------------------------------------------
78
80{
81
82 double d;
83
84 struct
85 {
86#if defined( SC_BIG_ENDIAN )
87 unsigned negative:1;
88 unsigned exponent:11;
89 unsigned mantissa0:20;
90 unsigned mantissa1:32;
91#elif defined( SC_LITTLE_ENDIAN )
92 unsigned mantissa1:32;
93 unsigned mantissa0:20;
94 unsigned exponent:11;
95 unsigned negative:1;
96#endif
97 } s;
98
99};
100
101
102const unsigned int SCFX_IEEE_DOUBLE_BIAS = 1023U;
103
104const int SCFX_IEEE_DOUBLE_E_MAX = 1023;
105const int SCFX_IEEE_DOUBLE_E_MIN = -1022;
106
107const unsigned int SCFX_IEEE_DOUBLE_M_SIZE = 52;
108const unsigned int SCFX_IEEE_DOUBLE_M0_SIZE = 20;
109const unsigned int SCFX_IEEE_DOUBLE_M1_SIZE = 32;
110const unsigned int SCFX_IEEE_DOUBLE_E_SIZE = 11;
111
112
113
114// ----------------------------------------------------------------------------
115// CLASS : scfx_ieee_double
116//
117// Convenient interface to union ieee_double.
118// ----------------------------------------------------------------------------
119
121{
122
123 ieee_double m_id;
124
125public:
126
128 scfx_ieee_double( double );
130
131 scfx_ieee_double& operator = ( double );
132 scfx_ieee_double& operator = ( const scfx_ieee_double& );
133
134 operator double() const;
135
136 unsigned int negative() const;
137 void negative( unsigned int );
138 int exponent() const;
139 void exponent( int );
140 unsigned int mantissa0() const;
141 void mantissa0( unsigned int );
142 unsigned int mantissa1() const;
143 void mantissa1( unsigned int );
144
145 bool is_zero() const;
146 bool is_subnormal() const;
147 bool is_normal() const;
148 bool is_inf() const;
149 bool is_nan() const;
150
151 void set_inf();
152 void set_nan();
153
154 int msb() const; // most significant non-zero bit
155 int lsb() const; // least significant non-zero bit
156
157 static scfx_ieee_double nan();
158 static scfx_ieee_double inf( int );
159
160};
161
162
163// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
164
165inline
167{
168 m_id.d = 0.0;
169}
170
171inline
173{
174 m_id.d = d;
175}
176
177inline
179{
180 // m_id.d = a.m_id.d;
181}
182
183
184inline
187{
188 m_id.d = d;
189 return *this;
190}
191
192inline
195{
196 m_id.d = a.m_id.d;
197 return *this;
198}
199
200
201inline
202scfx_ieee_double::operator double() const
203{
204 return m_id.d;
205}
206
207
208inline
209unsigned int
211{
212 return m_id.s.negative;
213}
214
215inline
216void
218{
219 m_id.s.negative = a & SCFX_MASK_(1);
220}
221
222inline
223int
225{
226 return static_cast<int>(m_id.s.exponent) - SCFX_IEEE_DOUBLE_BIAS;
227}
228
229inline
230void
232{
233 m_id.s.exponent = static_cast<unsigned int>((SCFX_IEEE_DOUBLE_BIAS + a)
235}
236
237inline
238unsigned int
240{
241 return m_id.s.mantissa0;
242}
243
244inline
245void
247{
249}
250
251inline
252unsigned int
254{
255 return m_id.s.mantissa1;
256}
257
258inline
259void
261{
262 m_id.s.mantissa1 = a; // & SCFX_MASK_(SCFX_IEEE_DOUBLE_M1_SIZE);
263}
264
265
266inline
267bool
269{
270 return ( exponent() == SCFX_IEEE_DOUBLE_E_MIN - 1 &&
271 mantissa0() == 0U && mantissa1() == 0U );
272}
273
274inline
275bool
277{
278 return ( exponent() == SCFX_IEEE_DOUBLE_E_MIN - 1 &&
279 ( mantissa0() != 0U || mantissa1() != 0U ) );
280}
281
282inline
283bool
285{
286 return ( exponent() >= SCFX_IEEE_DOUBLE_E_MIN &&
288}
289
290inline
291bool
293{
294 return ( exponent() == SCFX_IEEE_DOUBLE_E_MAX + 1 &&
295 mantissa0() == 0U && mantissa1() == 0U );
296}
297
298inline
299bool
301{
302 return ( exponent() == SCFX_IEEE_DOUBLE_E_MAX + 1 &&
303 ( mantissa0() != 0U || mantissa1() != 0U ) );
304}
305
306
307inline
308void
310{
312 mantissa0( 0U );
313 mantissa1( 0U );
314}
315
316inline
317void
319{
321 mantissa0( (unsigned int) -1 );
322 mantissa1( (unsigned int) -1 );
323}
324
325
326#define MSB_STATEMENT(x,n) if( x >> n ) { x >>= n; i += n; }
327
328inline
329int
331{
332 unsigned int m0 = mantissa0();
333 unsigned int m1 = mantissa1();
334 if( m0 != 0 )
335 {
336 int i = 0;
337 MSB_STATEMENT(m0,16);
338 MSB_STATEMENT(m0,8);
339 MSB_STATEMENT(m0,4);
340 MSB_STATEMENT(m0,2);
341 MSB_STATEMENT(m0,1);
342 return ( i - 20 );
343 }
344 else if( m1 != 0 )
345 {
346 int i = 0;
347 MSB_STATEMENT(m1,16);
348 MSB_STATEMENT(m1,8);
349 MSB_STATEMENT(m1,4);
350 MSB_STATEMENT(m1,2);
351 MSB_STATEMENT(m1,1);
352 return ( i - 52 );
353 }
354 else
355 {
356 return 0;
357 }
358}
359
360#undef MSB_STATEMENT
361
362#define LSB_STATEMENT(x,n) if( x << n ) { x <<= n; i -= n; }
363
364inline
365int
367{
368 unsigned int m0 = mantissa0();
369 unsigned int m1 = mantissa1();
370 if( m1 != 0 )
371 {
372 int i = 31;
373 LSB_STATEMENT(m1,16);
374 LSB_STATEMENT(m1,8);
375 LSB_STATEMENT(m1,4);
376 LSB_STATEMENT(m1,2);
377 LSB_STATEMENT(m1,1);
378 return ( i - 52 );
379 }
380 else if( m0 != 0 )
381 {
382 int i = 31;
383 LSB_STATEMENT(m0,16);
384 LSB_STATEMENT(m0,8);
385 LSB_STATEMENT(m0,4);
386 LSB_STATEMENT(m0,2);
387 LSB_STATEMENT(m0,1);
388 return ( i - 20 );
389 }
390 else
391 {
392 return 0;
393 }
394}
395
396#undef LSB_STATEMENT
397
398
399inline
402{
404 id.set_nan();
405 return id;
406}
407
408inline
411{
412 scfx_ieee_double id( sign );
413 id.set_inf();
414 return id;
415}
416
417
418// ----------------------------------------------------------------------------
419// UNION : ieee_float
420//
421// IEEE 754 single-precision format.
422// ----------------------------------------------------------------------------
423
425{
426
427 float f;
428
429 struct
430 {
431#if defined( SC_BIG_ENDIAN )
432 unsigned negative:1;
433 unsigned exponent:8;
434 unsigned mantissa:23;
435#elif defined( SC_LITTLE_ENDIAN )
436 unsigned mantissa:23;
437 unsigned exponent:8;
438 unsigned negative:1;
439#endif
440 } s;
441
442};
443
444
445const unsigned int SCFX_IEEE_FLOAT_BIAS = 127U;
446
447const int SCFX_IEEE_FLOAT_E_MAX = 127;
448const int SCFX_IEEE_FLOAT_E_MIN = -126;
449
450const unsigned int SCFX_IEEE_FLOAT_M_SIZE = 23;
451const unsigned int SCFX_IEEE_FLOAT_E_SIZE = 8;
452
453
454// ----------------------------------------------------------------------------
455// CLASS : scfx_ieee_float
456//
457// Convenient wrapper to union ieee_float.
458// ----------------------------------------------------------------------------
459
461{
462
463 ieee_float m_if;
464
465public:
466
468 scfx_ieee_float( float );
470
471 scfx_ieee_float& operator = ( float );
472 scfx_ieee_float& operator = ( const scfx_ieee_float& );
473
474 operator float() const;
475
476 unsigned int negative() const;
477 void negative( unsigned int );
478 int exponent() const;
479 void exponent( int );
480 unsigned int mantissa() const;
481 void mantissa( unsigned int );
482
483 bool is_zero() const;
484 bool is_subnormal() const;
485 bool is_normal() const;
486 bool is_inf() const;
487 bool is_nan() const;
488
489 void set_inf();
490 void set_nan();
491
492};
493
494
495// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
496
497inline
499{
500 m_if.f = 0.0;
501}
502
503inline
505{
506 m_if.f = f;
507}
508
509inline
511{
512 // m_if.f = a.m_if.f;
513}
514
515
516inline
519{
520 m_if.f = f;
521 return *this;
522}
523
524inline
527{
528 m_if.f = a.m_if.f;
529 return *this;
530}
531
532
533inline
534scfx_ieee_float::operator float() const
535{
536 return m_if.f;
537}
538
539
540inline
541unsigned int
543{
544 return m_if.s.negative;
545}
546
547inline
548void
550{
551 m_if.s.negative = a & SCFX_MASK_(1);
552}
553
554inline
555int
557{
558 return m_if.s.exponent - SCFX_IEEE_FLOAT_BIAS;
559}
560
561inline
562void
564{
565 m_if.s.exponent = (SCFX_IEEE_FLOAT_BIAS + a)
567}
568
569inline
570unsigned int
572{
573 return m_if.s.mantissa;
574}
575
576inline
577void
579{
581}
582
583
584inline
585bool
587{
588 return ( exponent() == SCFX_IEEE_FLOAT_E_MIN - 1 && mantissa() == 0U );
589}
590
591inline
592bool
594{
595 return ( exponent() == SCFX_IEEE_FLOAT_E_MIN - 1 && mantissa() != 0U );
596}
597
598inline
599bool
601{
602 return ( exponent() >= SCFX_IEEE_FLOAT_E_MIN &&
604}
605
606inline
607bool
609{
610 return ( exponent() == SCFX_IEEE_FLOAT_E_MAX + 1 && mantissa() == 0U );
611}
612
613inline
614bool
616{
617 return ( exponent() == SCFX_IEEE_FLOAT_E_MAX + 1 && mantissa() != 0U );
618}
619
620
621inline
622void
624{
626 mantissa( 0U );
627}
628
629inline
630void
632{
634 mantissa( (unsigned int) -1 );
635}
636
637
638// ----------------------------------------------------------------------------
639// FUNCTION : scfx_pow2
640//
641// Computes 2.0**exp in double-precision.
642// ----------------------------------------------------------------------------
643
644inline
645double scfx_pow2( int exp )
646{
648 if( exp < SCFX_IEEE_DOUBLE_E_MIN )
649 {
650 r = 0.0;
651 // handle subnormal case
653 if( ( exp += 20 ) >= 0 )
654 {
655 r.mantissa0( 1U << exp );
656 }
657 else if( ( exp += 32 ) >= 0 )
658 {
659 r.mantissa1( 1U << exp );
660 }
661 }
662 else if( exp > SCFX_IEEE_DOUBLE_E_MAX )
663 {
664 r.set_inf();
665 }
666 else
667 {
668 r = 1.0;
669 r.exponent( exp );
670 }
671 return r;
672}
673
674
675// ----------------------------------------------------------------------------
676// FUNCTION : uint64_to_double
677//
678// Platform independent conversion from double uint64 to double.
679// Needed because VC++6 doesn't support this conversion.
680// ----------------------------------------------------------------------------
681
682inline
683double
685{
686#if defined( _MSC_VER ) || defined( __clang__ )
687 // conversion from uint64 to double not implemented; use int64
688 double tmp = static_cast<double>( static_cast<int64>( a ) );
689 return ( tmp >= 0 ) ? tmp : tmp + sc_dt::scfx_pow2( 64 );
690#else
691 return static_cast<double>( a );
692#endif
693}
694
695} // namespace sc_dt
696
697#undef SCFX_MASK_
698
699#endif
700
701// Taf!
#define SCFX_MASK_(Size)
Definition: scfx_ieee.h:70
#define LSB_STATEMENT(x, n)
Definition: scfx_ieee.h:362
#define MSB_STATEMENT(x, n)
Definition: scfx_ieee.h:326
#define SC_API
Definition: sc_cmnhdr.h:148
bool is_inf(double v)
Definition: sc_nbutils.h:229
bool is_nan(double v)
Definition: sc_nbutils.h:222
const int SCFX_IEEE_FLOAT_E_MIN
Definition: scfx_ieee.h:448
const unsigned int SCFX_IEEE_DOUBLE_M1_SIZE
Definition: scfx_ieee.h:109
const int SCFX_IEEE_DOUBLE_E_MIN
Definition: scfx_ieee.h:105
double uint64_to_double(uint64 a)
Definition: scfx_ieee.h:684
const unsigned int SCFX_IEEE_DOUBLE_E_SIZE
Definition: scfx_ieee.h:110
unsigned long long uint64
Definition: sc_nbdefs.h:216
const int SCFX_IEEE_DOUBLE_E_MAX
Definition: scfx_ieee.h:104
const unsigned int SCFX_IEEE_DOUBLE_M0_SIZE
Definition: scfx_ieee.h:108
const int SCFX_IEEE_FLOAT_E_MAX
Definition: scfx_ieee.h:447
const unsigned int SCFX_IEEE_FLOAT_E_SIZE
Definition: scfx_ieee.h:451
const unsigned int SCFX_IEEE_DOUBLE_M_SIZE
Definition: scfx_ieee.h:107
const unsigned int SCFX_IEEE_DOUBLE_BIAS
Definition: scfx_ieee.h:102
const unsigned int SCFX_IEEE_FLOAT_BIAS
Definition: scfx_ieee.h:445
double scfx_pow2(int exp)
Definition: scfx_ieee.h:645
long long int64
Definition: sc_nbdefs.h:215
const unsigned int SCFX_IEEE_FLOAT_M_SIZE
Definition: scfx_ieee.h:450
unsigned mantissa0
Definition: scfx_ieee.h:93
struct sc_dt::ieee_double::@0 s
unsigned negative
Definition: scfx_ieee.h:95
unsigned exponent
Definition: scfx_ieee.h:94
unsigned mantissa1
Definition: scfx_ieee.h:92
bool is_inf() const
Definition: scfx_ieee.h:292
unsigned int mantissa1() const
Definition: scfx_ieee.h:253
static scfx_ieee_double nan()
Definition: scfx_ieee.h:401
static scfx_ieee_double inf(int)
Definition: scfx_ieee.h:410
unsigned int mantissa0() const
Definition: scfx_ieee.h:239
scfx_ieee_double & operator=(double)
Definition: scfx_ieee.h:186
bool is_nan() const
Definition: scfx_ieee.h:300
bool is_subnormal() const
Definition: scfx_ieee.h:276
unsigned int negative() const
Definition: scfx_ieee.h:210
bool is_normal() const
Definition: scfx_ieee.h:284
int exponent() const
Definition: scfx_ieee.h:224
bool is_zero() const
Definition: scfx_ieee.h:268
unsigned exponent
Definition: scfx_ieee.h:437
unsigned mantissa
Definition: scfx_ieee.h:436
struct sc_dt::ieee_float::@1 s
unsigned negative
Definition: scfx_ieee.h:438
bool is_nan() const
Definition: scfx_ieee.h:615
unsigned int mantissa() const
Definition: scfx_ieee.h:571
bool is_zero() const
Definition: scfx_ieee.h:586
scfx_ieee_float & operator=(float)
Definition: scfx_ieee.h:518
unsigned int negative() const
Definition: scfx_ieee.h:542
int exponent() const
Definition: scfx_ieee.h:556
bool is_inf() const
Definition: scfx_ieee.h:608
bool is_normal() const
Definition: scfx_ieee.h:600
bool is_subnormal() const
Definition: scfx_ieee.h:593