112853Sgabeblack@google.com/*****************************************************************************
212853Sgabeblack@google.com
312853Sgabeblack@google.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
412853Sgabeblack@google.com  more contributor license agreements.  See the NOTICE file distributed
512853Sgabeblack@google.com  with this work for additional information regarding copyright ownership.
612853Sgabeblack@google.com  Accellera licenses this file to you under the Apache License, Version 2.0
712853Sgabeblack@google.com  (the "License"); you may not use this file except in compliance with the
812853Sgabeblack@google.com  License.  You may obtain a copy of the License at
912853Sgabeblack@google.com
1012853Sgabeblack@google.com    http://www.apache.org/licenses/LICENSE-2.0
1112853Sgabeblack@google.com
1212853Sgabeblack@google.com  Unless required by applicable law or agreed to in writing, software
1312853Sgabeblack@google.com  distributed under the License is distributed on an "AS IS" BASIS,
1412853Sgabeblack@google.com  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1512853Sgabeblack@google.com  implied.  See the License for the specific language governing
1612853Sgabeblack@google.com  permissions and limitations under the License.
1712853Sgabeblack@google.com
1812853Sgabeblack@google.com *****************************************************************************/
1912853Sgabeblack@google.com
2012853Sgabeblack@google.com/*****************************************************************************
2112853Sgabeblack@google.com
2212853Sgabeblack@google.com  scfx_ieee.h -
2312853Sgabeblack@google.com
2412853Sgabeblack@google.com  Original Author: Martin Janssen, Synopsys, Inc.
2512853Sgabeblack@google.com
2612853Sgabeblack@google.com *****************************************************************************/
2712853Sgabeblack@google.com
2812853Sgabeblack@google.com/*****************************************************************************
2912853Sgabeblack@google.com
3012853Sgabeblack@google.com  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
3112853Sgabeblack@google.com  changes you are making here.
3212853Sgabeblack@google.com
3312853Sgabeblack@google.com      Name, Affiliation, Date:
3412853Sgabeblack@google.com  Description of Modification:
3512853Sgabeblack@google.com
3612853Sgabeblack@google.com *****************************************************************************/
3712853Sgabeblack@google.com
3812853Sgabeblack@google.com// $Log: scfx_ieee.h,v $
3912853Sgabeblack@google.com// Revision 1.3  2011/08/24 22:05:43  acg
4012853Sgabeblack@google.com//  Torsten Maehne: initialization changes to remove warnings.
4112853Sgabeblack@google.com//
4212853Sgabeblack@google.com// Revision 1.2  2011/08/07 18:55:24  acg
4312853Sgabeblack@google.com//  Philipp A. Hartmann: added guard for __clang__ to get the clang platform
4412853Sgabeblack@google.com//  working.
4512853Sgabeblack@google.com//
4612853Sgabeblack@google.com// Revision 1.1.1.1  2006/12/15 20:20:04  acg
4712853Sgabeblack@google.com// SystemC 2.3
4812853Sgabeblack@google.com//
4912853Sgabeblack@google.com// Revision 1.3  2006/01/13 18:53:58  acg
5012853Sgabeblack@google.com// Andy Goodrich: added $Log command so that CVS comments are reproduced in
5112853Sgabeblack@google.com// the source.
5212853Sgabeblack@google.com//
5312853Sgabeblack@google.com
5412853Sgabeblack@google.com#ifndef __SYSTEMC_EXT_DT_FX_SCFX_IEEE_HH__
5512853Sgabeblack@google.com#define __SYSTEMC_EXT_DT_FX_SCFX_IEEE_HH__
5612853Sgabeblack@google.com
5712853Sgabeblack@google.com#include "../../utils/endian.hh"
5812853Sgabeblack@google.com#include "sc_fxdefs.hh"
5912853Sgabeblack@google.com
6012853Sgabeblack@google.comnamespace sc_dt
6112853Sgabeblack@google.com{
6212853Sgabeblack@google.com
6312853Sgabeblack@google.com// classes defined in this module
6412853Sgabeblack@google.comunion ieee_double;
6512853Sgabeblack@google.comclass scfx_ieee_double;
6612853Sgabeblack@google.comunion ieee_float;
6712853Sgabeblack@google.comclass scfx_ieee_float;
6812853Sgabeblack@google.com
6912853Sgabeblack@google.com#define SCFX_MASK_(Size) ((1u << (Size))-1u)
7012853Sgabeblack@google.com
7112853Sgabeblack@google.com// ----------------------------------------------------------------------------
7212853Sgabeblack@google.com//  UNION : ieee_double
7312853Sgabeblack@google.com//
7412853Sgabeblack@google.com//  IEEE 754 double-precision format.
7512853Sgabeblack@google.com// ----------------------------------------------------------------------------
7612853Sgabeblack@google.com
7712853Sgabeblack@google.comunion ieee_double
7812853Sgabeblack@google.com{
7912853Sgabeblack@google.com    double d;
8012853Sgabeblack@google.com
8112853Sgabeblack@google.com    struct
8212853Sgabeblack@google.com    {
8312853Sgabeblack@google.com#if defined(SC_BOOST_BIG_ENDIAN)
8412853Sgabeblack@google.com        unsigned negative:1;
8512853Sgabeblack@google.com        unsigned exponent:11;
8612853Sgabeblack@google.com        unsigned mantissa0:20;
8712853Sgabeblack@google.com        unsigned mantissa1:32;
8812853Sgabeblack@google.com#elif defined(SC_BOOST_LITTLE_ENDIAN)
8912853Sgabeblack@google.com        unsigned mantissa1:32;
9012853Sgabeblack@google.com        unsigned mantissa0:20;
9112853Sgabeblack@google.com        unsigned exponent:11;
9212853Sgabeblack@google.com        unsigned negative:1;
9312853Sgabeblack@google.com#endif
9412853Sgabeblack@google.com    } s;
9512853Sgabeblack@google.com};
9612853Sgabeblack@google.com
9712853Sgabeblack@google.com
9812853Sgabeblack@google.comconst unsigned int SCFX_IEEE_DOUBLE_BIAS = 1023U;
9912853Sgabeblack@google.com
10012853Sgabeblack@google.comconst int SCFX_IEEE_DOUBLE_E_MAX = 1023;
10112853Sgabeblack@google.comconst int SCFX_IEEE_DOUBLE_E_MIN = -1022;
10212853Sgabeblack@google.com
10312853Sgabeblack@google.comconst unsigned int SCFX_IEEE_DOUBLE_M_SIZE = 52;
10412853Sgabeblack@google.comconst unsigned int SCFX_IEEE_DOUBLE_M0_SIZE = 20;
10512853Sgabeblack@google.comconst unsigned int SCFX_IEEE_DOUBLE_M1_SIZE = 32;
10612853Sgabeblack@google.comconst unsigned int SCFX_IEEE_DOUBLE_E_SIZE = 11;
10712853Sgabeblack@google.com
10812853Sgabeblack@google.com
10912853Sgabeblack@google.com// ----------------------------------------------------------------------------
11012853Sgabeblack@google.com//  CLASS : scfx_ieee_double
11112853Sgabeblack@google.com//
11212853Sgabeblack@google.com//  Convenient interface to union ieee_double.
11312853Sgabeblack@google.com// ----------------------------------------------------------------------------
11412853Sgabeblack@google.com
11512853Sgabeblack@google.comclass scfx_ieee_double
11612853Sgabeblack@google.com{
11712853Sgabeblack@google.com    ieee_double m_id;
11812853Sgabeblack@google.com  public:
11912853Sgabeblack@google.com    scfx_ieee_double();
12012853Sgabeblack@google.com    scfx_ieee_double(double);
12112853Sgabeblack@google.com    scfx_ieee_double(const scfx_ieee_double &);
12212853Sgabeblack@google.com
12312853Sgabeblack@google.com    scfx_ieee_double &operator = (double);
12412853Sgabeblack@google.com    scfx_ieee_double &operator = (const scfx_ieee_double &);
12512853Sgabeblack@google.com
12612853Sgabeblack@google.com    operator double() const;
12712853Sgabeblack@google.com
12812853Sgabeblack@google.com    unsigned int negative() const;
12912853Sgabeblack@google.com    void negative(unsigned int);
13012853Sgabeblack@google.com    int exponent() const;
13112853Sgabeblack@google.com    void exponent(int);
13212853Sgabeblack@google.com    unsigned int mantissa0() const;
13312853Sgabeblack@google.com    void mantissa0(unsigned int);
13412853Sgabeblack@google.com    unsigned int mantissa1() const;
13512853Sgabeblack@google.com    void mantissa1(unsigned int);
13612853Sgabeblack@google.com
13712853Sgabeblack@google.com    bool is_zero() const;
13812853Sgabeblack@google.com    bool is_subnormal() const;
13912853Sgabeblack@google.com    bool is_normal() const;
14012853Sgabeblack@google.com    bool is_inf() const;
14112853Sgabeblack@google.com    bool is_nan() const;
14212853Sgabeblack@google.com
14312853Sgabeblack@google.com    void set_inf();
14412853Sgabeblack@google.com    void set_nan();
14512853Sgabeblack@google.com
14612853Sgabeblack@google.com    int msb() const; // most significant non-zero bit
14712853Sgabeblack@google.com    int lsb() const; // least significant non-zero bit
14812853Sgabeblack@google.com
14912853Sgabeblack@google.com    static const scfx_ieee_double nan();
15012853Sgabeblack@google.com    static const scfx_ieee_double inf(int);
15112853Sgabeblack@google.com};
15212853Sgabeblack@google.com
15312853Sgabeblack@google.com
15412853Sgabeblack@google.com// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
15512853Sgabeblack@google.com
15612853Sgabeblack@google.cominline scfx_ieee_double::scfx_ieee_double() : m_id()
15712853Sgabeblack@google.com{
15812853Sgabeblack@google.com    m_id.d = 0.0;
15912853Sgabeblack@google.com}
16012853Sgabeblack@google.com
16112853Sgabeblack@google.cominline scfx_ieee_double::scfx_ieee_double(double d) : m_id()
16212853Sgabeblack@google.com{
16312853Sgabeblack@google.com    m_id.d = d;
16412853Sgabeblack@google.com}
16512853Sgabeblack@google.com
16612853Sgabeblack@google.cominline scfx_ieee_double::scfx_ieee_double(const scfx_ieee_double &a) :
16712853Sgabeblack@google.com        m_id(a.m_id)
16812853Sgabeblack@google.com{
16912853Sgabeblack@google.com    // m_id.d = a.m_id.d;
17012853Sgabeblack@google.com}
17112853Sgabeblack@google.com
17212853Sgabeblack@google.cominline scfx_ieee_double &
17312853Sgabeblack@google.comscfx_ieee_double::operator = (double d)
17412853Sgabeblack@google.com{
17512853Sgabeblack@google.com    m_id.d = d;
17612853Sgabeblack@google.com    return *this;
17712853Sgabeblack@google.com}
17812853Sgabeblack@google.com
17912853Sgabeblack@google.cominline scfx_ieee_double &
18012853Sgabeblack@google.comscfx_ieee_double::operator = (const scfx_ieee_double &a)
18112853Sgabeblack@google.com{
18212853Sgabeblack@google.com    m_id.d = a.m_id.d;
18312853Sgabeblack@google.com    return *this;
18412853Sgabeblack@google.com}
18512853Sgabeblack@google.com
18612853Sgabeblack@google.cominline scfx_ieee_double::operator double() const
18712853Sgabeblack@google.com{
18812853Sgabeblack@google.com    return m_id.d;
18912853Sgabeblack@google.com}
19012853Sgabeblack@google.com
19112853Sgabeblack@google.cominline unsigned int
19212853Sgabeblack@google.comscfx_ieee_double::negative() const
19312853Sgabeblack@google.com{
19412853Sgabeblack@google.com    return m_id.s.negative;
19512853Sgabeblack@google.com}
19612853Sgabeblack@google.com
19712853Sgabeblack@google.cominline void
19812853Sgabeblack@google.comscfx_ieee_double::negative(unsigned int a)
19912853Sgabeblack@google.com{
20012853Sgabeblack@google.com    m_id.s.negative = a & SCFX_MASK_(1);
20112853Sgabeblack@google.com}
20212853Sgabeblack@google.com
20312853Sgabeblack@google.cominline int
20412853Sgabeblack@google.comscfx_ieee_double::exponent() const
20512853Sgabeblack@google.com{
20612853Sgabeblack@google.com    return m_id.s.exponent - SCFX_IEEE_DOUBLE_BIAS;
20712853Sgabeblack@google.com}
20812853Sgabeblack@google.com
20912853Sgabeblack@google.cominline void
21012853Sgabeblack@google.comscfx_ieee_double::exponent(int a)
21112853Sgabeblack@google.com{
21212853Sgabeblack@google.com    m_id.s.exponent = (SCFX_IEEE_DOUBLE_BIAS + a)
21312853Sgabeblack@google.com                      & SCFX_MASK_(SCFX_IEEE_DOUBLE_E_SIZE);
21412853Sgabeblack@google.com}
21512853Sgabeblack@google.com
21612853Sgabeblack@google.cominline unsigned int
21712853Sgabeblack@google.comscfx_ieee_double::mantissa0() const
21812853Sgabeblack@google.com{
21912853Sgabeblack@google.com    return m_id.s.mantissa0;
22012853Sgabeblack@google.com}
22112853Sgabeblack@google.com
22212853Sgabeblack@google.cominline void
22312853Sgabeblack@google.comscfx_ieee_double::mantissa0(unsigned int a)
22412853Sgabeblack@google.com{
22512853Sgabeblack@google.com    m_id.s.mantissa0 = a & SCFX_MASK_(SCFX_IEEE_DOUBLE_M0_SIZE);
22612853Sgabeblack@google.com}
22712853Sgabeblack@google.com
22812853Sgabeblack@google.cominline unsigned int
22912853Sgabeblack@google.comscfx_ieee_double::mantissa1() const
23012853Sgabeblack@google.com{
23112853Sgabeblack@google.com    return m_id.s.mantissa1;
23212853Sgabeblack@google.com}
23312853Sgabeblack@google.com
23412853Sgabeblack@google.cominline void
23512853Sgabeblack@google.comscfx_ieee_double::mantissa1(unsigned int a)
23612853Sgabeblack@google.com{
23712853Sgabeblack@google.com    m_id.s.mantissa1 = a; // & SCFX_MASK_(SCFX_IEEE_DOUBLE_M1_SIZE);
23812853Sgabeblack@google.com}
23912853Sgabeblack@google.com
24012853Sgabeblack@google.cominline bool
24112853Sgabeblack@google.comscfx_ieee_double::is_zero() const
24212853Sgabeblack@google.com{
24312853Sgabeblack@google.com    return (exponent() == SCFX_IEEE_DOUBLE_E_MIN - 1 &&
24412853Sgabeblack@google.com            mantissa0() == 0U && mantissa1() == 0U);
24512853Sgabeblack@google.com}
24612853Sgabeblack@google.com
24712853Sgabeblack@google.cominline bool
24812853Sgabeblack@google.comscfx_ieee_double::is_subnormal() const
24912853Sgabeblack@google.com{
25012853Sgabeblack@google.com    return (exponent() == SCFX_IEEE_DOUBLE_E_MIN - 1 &&
25112853Sgabeblack@google.com            (mantissa0() != 0U || mantissa1() != 0U));
25212853Sgabeblack@google.com}
25312853Sgabeblack@google.com
25412853Sgabeblack@google.cominline bool
25512853Sgabeblack@google.comscfx_ieee_double::is_normal() const
25612853Sgabeblack@google.com{
25712853Sgabeblack@google.com    return (exponent() >= SCFX_IEEE_DOUBLE_E_MIN &&
25812853Sgabeblack@google.com            exponent() <= SCFX_IEEE_DOUBLE_E_MAX);
25912853Sgabeblack@google.com}
26012853Sgabeblack@google.com
26112853Sgabeblack@google.cominline bool
26212853Sgabeblack@google.comscfx_ieee_double::is_inf() const
26312853Sgabeblack@google.com{
26412853Sgabeblack@google.com    return (exponent() == SCFX_IEEE_DOUBLE_E_MAX + 1 &&
26512853Sgabeblack@google.com            mantissa0() == 0U && mantissa1() == 0U);
26612853Sgabeblack@google.com}
26712853Sgabeblack@google.com
26812853Sgabeblack@google.cominline bool
26912853Sgabeblack@google.comscfx_ieee_double::is_nan() const
27012853Sgabeblack@google.com{
27112853Sgabeblack@google.com    return (exponent() == SCFX_IEEE_DOUBLE_E_MAX + 1 &&
27212853Sgabeblack@google.com             (mantissa0() != 0U || mantissa1() != 0U));
27312853Sgabeblack@google.com}
27412853Sgabeblack@google.com
27512853Sgabeblack@google.cominline void
27612853Sgabeblack@google.comscfx_ieee_double::set_inf()
27712853Sgabeblack@google.com{
27812853Sgabeblack@google.com    exponent(SCFX_IEEE_DOUBLE_E_MAX + 1);
27912853Sgabeblack@google.com    mantissa0(0U);
28012853Sgabeblack@google.com    mantissa1(0U);
28112853Sgabeblack@google.com}
28212853Sgabeblack@google.com
28312853Sgabeblack@google.cominline void
28412853Sgabeblack@google.comscfx_ieee_double::set_nan()
28512853Sgabeblack@google.com{
28612853Sgabeblack@google.com    exponent(SCFX_IEEE_DOUBLE_E_MAX + 1);
28712853Sgabeblack@google.com    mantissa0((unsigned int)-1);
28812853Sgabeblack@google.com    mantissa1((unsigned int)-1);
28912853Sgabeblack@google.com}
29012853Sgabeblack@google.com
29112853Sgabeblack@google.com#define MSB_STATEMENT(x,n) if ( x >> n ) { x >>= n; i += n; }
29212853Sgabeblack@google.com
29312853Sgabeblack@google.cominline int
29412853Sgabeblack@google.comscfx_ieee_double::msb() const
29512853Sgabeblack@google.com{
29612853Sgabeblack@google.com    unsigned int m0 = mantissa0();
29712853Sgabeblack@google.com    unsigned int m1 = mantissa1();
29812853Sgabeblack@google.com    if (m0 != 0) {
29912853Sgabeblack@google.com        int i = 0;
30012853Sgabeblack@google.com        MSB_STATEMENT(m0, 16);
30112853Sgabeblack@google.com        MSB_STATEMENT(m0, 8);
30212853Sgabeblack@google.com        MSB_STATEMENT(m0, 4);
30312853Sgabeblack@google.com        MSB_STATEMENT(m0, 2);
30412853Sgabeblack@google.com        MSB_STATEMENT(m0, 1);
30512853Sgabeblack@google.com        return (i - 20);
30612853Sgabeblack@google.com    } else if (m1 != 0) {
30712853Sgabeblack@google.com        int i = 0;
30812853Sgabeblack@google.com        MSB_STATEMENT(m1, 16);
30912853Sgabeblack@google.com        MSB_STATEMENT(m1, 8);
31012853Sgabeblack@google.com        MSB_STATEMENT(m1, 4);
31112853Sgabeblack@google.com        MSB_STATEMENT(m1, 2);
31212853Sgabeblack@google.com        MSB_STATEMENT(m1, 1);
31312853Sgabeblack@google.com        return (i - 52);
31412853Sgabeblack@google.com    } else {
31512853Sgabeblack@google.com        return 0;
31612853Sgabeblack@google.com    }
31712853Sgabeblack@google.com}
31812853Sgabeblack@google.com
31912853Sgabeblack@google.com#undef MSB_STATEMENT
32012853Sgabeblack@google.com
32112853Sgabeblack@google.com#define LSB_STATEMENT(x,n) if ( x << n ) { x <<= n; i -= n; }
32212853Sgabeblack@google.com
32312853Sgabeblack@google.cominline int
32412853Sgabeblack@google.comscfx_ieee_double::lsb() const
32512853Sgabeblack@google.com{
32612853Sgabeblack@google.com    unsigned int m0 = mantissa0();
32712853Sgabeblack@google.com    unsigned int m1 = mantissa1();
32812853Sgabeblack@google.com    if (m1 != 0) {
32912853Sgabeblack@google.com        int i = 31;
33012853Sgabeblack@google.com        LSB_STATEMENT(m1, 16);
33112853Sgabeblack@google.com        LSB_STATEMENT(m1, 8);
33212853Sgabeblack@google.com        LSB_STATEMENT(m1, 4);
33312853Sgabeblack@google.com        LSB_STATEMENT(m1, 2);
33412853Sgabeblack@google.com        LSB_STATEMENT(m1, 1);
33512853Sgabeblack@google.com        return (i - 52);
33612853Sgabeblack@google.com    } else if (m0 != 0) {
33712853Sgabeblack@google.com        int i = 31;
33812853Sgabeblack@google.com        LSB_STATEMENT(m0, 16);
33912853Sgabeblack@google.com        LSB_STATEMENT(m0, 8);
34012853Sgabeblack@google.com        LSB_STATEMENT(m0, 4);
34112853Sgabeblack@google.com        LSB_STATEMENT(m0, 2);
34212853Sgabeblack@google.com        LSB_STATEMENT(m0, 1);
34312853Sgabeblack@google.com        return (i - 20);
34412853Sgabeblack@google.com    } else {
34512853Sgabeblack@google.com        return 0;
34612853Sgabeblack@google.com    }
34712853Sgabeblack@google.com}
34812853Sgabeblack@google.com
34912853Sgabeblack@google.com#undef LSB_STATEMENT
35012853Sgabeblack@google.com
35112853Sgabeblack@google.cominline const scfx_ieee_double
35212853Sgabeblack@google.comscfx_ieee_double::nan()
35312853Sgabeblack@google.com{
35412853Sgabeblack@google.com    scfx_ieee_double id;
35512853Sgabeblack@google.com    id.set_nan();
35612853Sgabeblack@google.com    return id;
35712853Sgabeblack@google.com}
35812853Sgabeblack@google.com
35912853Sgabeblack@google.cominline const scfx_ieee_double
36012853Sgabeblack@google.comscfx_ieee_double::inf(int sign)
36112853Sgabeblack@google.com{
36212853Sgabeblack@google.com    scfx_ieee_double id(sign);
36312853Sgabeblack@google.com    id.set_inf();
36412853Sgabeblack@google.com    return id;
36512853Sgabeblack@google.com}
36612853Sgabeblack@google.com
36712853Sgabeblack@google.com
36812853Sgabeblack@google.com// ----------------------------------------------------------------------------
36912853Sgabeblack@google.com//  UNION : ieee_float
37012853Sgabeblack@google.com//
37112853Sgabeblack@google.com//  IEEE 754 single-precision format.
37212853Sgabeblack@google.com// ----------------------------------------------------------------------------
37312853Sgabeblack@google.com
37412853Sgabeblack@google.comunion ieee_float
37512853Sgabeblack@google.com{
37612853Sgabeblack@google.com    float f;
37712853Sgabeblack@google.com    struct
37812853Sgabeblack@google.com    {
37912853Sgabeblack@google.com#if defined(SC_BOOST_BIG_ENDIAN)
38012853Sgabeblack@google.com        unsigned negative:1;
38112853Sgabeblack@google.com        unsigned exponent:8;
38212853Sgabeblack@google.com        unsigned mantissa:23;
38312853Sgabeblack@google.com#elif defined(SC_BOOST_LITTLE_ENDIAN)
38412853Sgabeblack@google.com        unsigned mantissa:23;
38512853Sgabeblack@google.com        unsigned exponent:8;
38612853Sgabeblack@google.com        unsigned negative:1;
38712853Sgabeblack@google.com#endif
38812853Sgabeblack@google.com    } s;
38912853Sgabeblack@google.com};
39012853Sgabeblack@google.com
39112853Sgabeblack@google.com
39212853Sgabeblack@google.comconst unsigned int SCFX_IEEE_FLOAT_BIAS = 127U;
39312853Sgabeblack@google.com
39412853Sgabeblack@google.comconst int SCFX_IEEE_FLOAT_E_MAX = 127;
39512853Sgabeblack@google.comconst int SCFX_IEEE_FLOAT_E_MIN = -126;
39612853Sgabeblack@google.com
39712853Sgabeblack@google.comconst unsigned int SCFX_IEEE_FLOAT_M_SIZE = 23;
39812853Sgabeblack@google.comconst unsigned int SCFX_IEEE_FLOAT_E_SIZE = 8;
39912853Sgabeblack@google.com
40012853Sgabeblack@google.com
40112853Sgabeblack@google.com// ----------------------------------------------------------------------------
40212853Sgabeblack@google.com//  CLASS : scfx_ieee_float
40312853Sgabeblack@google.com//
40412853Sgabeblack@google.com// Convenient wrapper to union ieee_float.
40512853Sgabeblack@google.com// ----------------------------------------------------------------------------
40612853Sgabeblack@google.com
40712853Sgabeblack@google.comclass scfx_ieee_float
40812853Sgabeblack@google.com{
40912853Sgabeblack@google.com    ieee_float m_if;
41012853Sgabeblack@google.com
41112853Sgabeblack@google.com  public:
41212853Sgabeblack@google.com    scfx_ieee_float();
41312853Sgabeblack@google.com    scfx_ieee_float(float);
41412853Sgabeblack@google.com    scfx_ieee_float(const scfx_ieee_float &);
41512853Sgabeblack@google.com
41612853Sgabeblack@google.com    scfx_ieee_float &operator = (float);
41712853Sgabeblack@google.com    scfx_ieee_float &operator = (const scfx_ieee_float &);
41812853Sgabeblack@google.com
41912853Sgabeblack@google.com    operator float() const;
42012853Sgabeblack@google.com
42112853Sgabeblack@google.com    unsigned int negative() const;
42212853Sgabeblack@google.com    void negative(unsigned int);
42312853Sgabeblack@google.com    int exponent() const;
42412853Sgabeblack@google.com    void exponent(int);
42512853Sgabeblack@google.com    unsigned int mantissa() const;
42612853Sgabeblack@google.com    void mantissa(unsigned int);
42712853Sgabeblack@google.com
42812853Sgabeblack@google.com    bool is_zero() const;
42912853Sgabeblack@google.com    bool is_subnormal() const;
43012853Sgabeblack@google.com    bool is_normal() const;
43112853Sgabeblack@google.com    bool is_inf() const;
43212853Sgabeblack@google.com    bool is_nan() const;
43312853Sgabeblack@google.com
43412853Sgabeblack@google.com    void set_inf();
43512853Sgabeblack@google.com    void set_nan();
43612853Sgabeblack@google.com};
43712853Sgabeblack@google.com
43812853Sgabeblack@google.com
43912853Sgabeblack@google.com// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
44012853Sgabeblack@google.com
44112853Sgabeblack@google.cominline scfx_ieee_float::scfx_ieee_float() : m_if()
44212853Sgabeblack@google.com{
44312853Sgabeblack@google.com    m_if.f = 0.0;
44412853Sgabeblack@google.com}
44512853Sgabeblack@google.com
44612853Sgabeblack@google.cominline scfx_ieee_float::scfx_ieee_float(float f) : m_if()
44712853Sgabeblack@google.com{
44812853Sgabeblack@google.com    m_if.f = f;
44912853Sgabeblack@google.com}
45012853Sgabeblack@google.com
45112853Sgabeblack@google.cominline scfx_ieee_float::scfx_ieee_float(const scfx_ieee_float &a) :
45212853Sgabeblack@google.com        m_if(a.m_if)
45312853Sgabeblack@google.com{
45412853Sgabeblack@google.com    // m_if.f = a.m_if.f;
45512853Sgabeblack@google.com}
45612853Sgabeblack@google.com
45712853Sgabeblack@google.com
45812853Sgabeblack@google.cominline scfx_ieee_float &
45912853Sgabeblack@google.comscfx_ieee_float::operator = (float f)
46012853Sgabeblack@google.com{
46112853Sgabeblack@google.com    m_if.f = f;
46212853Sgabeblack@google.com    return *this;
46312853Sgabeblack@google.com}
46412853Sgabeblack@google.com
46512853Sgabeblack@google.cominline scfx_ieee_float &
46612853Sgabeblack@google.comscfx_ieee_float::operator = (const scfx_ieee_float &a)
46712853Sgabeblack@google.com{
46812853Sgabeblack@google.com    m_if.f = a.m_if.f;
46912853Sgabeblack@google.com    return *this;
47012853Sgabeblack@google.com}
47112853Sgabeblack@google.com
47212853Sgabeblack@google.cominline scfx_ieee_float::operator float() const
47312853Sgabeblack@google.com{
47412853Sgabeblack@google.com    return m_if.f;
47512853Sgabeblack@google.com}
47612853Sgabeblack@google.com
47712853Sgabeblack@google.cominline unsigned int
47812853Sgabeblack@google.comscfx_ieee_float::negative() const
47912853Sgabeblack@google.com{
48012853Sgabeblack@google.com    return m_if.s.negative;
48112853Sgabeblack@google.com}
48212853Sgabeblack@google.com
48312853Sgabeblack@google.cominline void
48412853Sgabeblack@google.comscfx_ieee_float::negative(unsigned int a)
48512853Sgabeblack@google.com{
48612853Sgabeblack@google.com    m_if.s.negative = a & SCFX_MASK_(1);
48712853Sgabeblack@google.com}
48812853Sgabeblack@google.com
48912853Sgabeblack@google.cominline int
49012853Sgabeblack@google.comscfx_ieee_float::exponent() const
49112853Sgabeblack@google.com{
49212853Sgabeblack@google.com    return m_if.s.exponent - SCFX_IEEE_FLOAT_BIAS;
49312853Sgabeblack@google.com}
49412853Sgabeblack@google.com
49512853Sgabeblack@google.cominline void
49612853Sgabeblack@google.comscfx_ieee_float::exponent(int a)
49712853Sgabeblack@google.com{
49812853Sgabeblack@google.com    m_if.s.exponent = (SCFX_IEEE_FLOAT_BIAS + a) &
49912853Sgabeblack@google.com                      SCFX_MASK_(SCFX_IEEE_FLOAT_E_SIZE);
50012853Sgabeblack@google.com}
50112853Sgabeblack@google.com
50212853Sgabeblack@google.cominline unsigned int
50312853Sgabeblack@google.comscfx_ieee_float::mantissa() const
50412853Sgabeblack@google.com{
50512853Sgabeblack@google.com    return m_if.s.mantissa;
50612853Sgabeblack@google.com}
50712853Sgabeblack@google.com
50812853Sgabeblack@google.cominline void
50912853Sgabeblack@google.comscfx_ieee_float::mantissa(unsigned int a)
51012853Sgabeblack@google.com{
51112853Sgabeblack@google.com    m_if.s.mantissa = a & SCFX_MASK_(SCFX_IEEE_FLOAT_M_SIZE);
51212853Sgabeblack@google.com}
51312853Sgabeblack@google.com
51412853Sgabeblack@google.com
51512853Sgabeblack@google.cominline bool
51612853Sgabeblack@google.comscfx_ieee_float::is_zero() const
51712853Sgabeblack@google.com{
51812853Sgabeblack@google.com    return (exponent() == SCFX_IEEE_FLOAT_E_MIN - 1 && mantissa() == 0U);
51912853Sgabeblack@google.com}
52012853Sgabeblack@google.com
52112853Sgabeblack@google.cominline bool
52212853Sgabeblack@google.comscfx_ieee_float::is_subnormal() const
52312853Sgabeblack@google.com{
52412853Sgabeblack@google.com    return (exponent() == SCFX_IEEE_FLOAT_E_MIN - 1 && mantissa() != 0U);
52512853Sgabeblack@google.com}
52612853Sgabeblack@google.com
52712853Sgabeblack@google.cominline bool
52812853Sgabeblack@google.comscfx_ieee_float::is_normal() const
52912853Sgabeblack@google.com{
53012853Sgabeblack@google.com    return (exponent() >= SCFX_IEEE_FLOAT_E_MIN &&
53112853Sgabeblack@google.com            exponent() <= SCFX_IEEE_FLOAT_E_MAX);
53212853Sgabeblack@google.com}
53312853Sgabeblack@google.com
53412853Sgabeblack@google.cominline bool
53512853Sgabeblack@google.comscfx_ieee_float::is_inf() const
53612853Sgabeblack@google.com{
53712853Sgabeblack@google.com    return (exponent() == SCFX_IEEE_FLOAT_E_MAX + 1 && mantissa() == 0U);
53812853Sgabeblack@google.com}
53912853Sgabeblack@google.com
54012853Sgabeblack@google.cominline bool
54112853Sgabeblack@google.comscfx_ieee_float::is_nan() const
54212853Sgabeblack@google.com{
54312853Sgabeblack@google.com    return (exponent() == SCFX_IEEE_FLOAT_E_MAX + 1 && mantissa() != 0U);
54412853Sgabeblack@google.com}
54512853Sgabeblack@google.com
54612853Sgabeblack@google.cominline void
54712853Sgabeblack@google.comscfx_ieee_float::set_inf()
54812853Sgabeblack@google.com{
54912853Sgabeblack@google.com    exponent(SCFX_IEEE_FLOAT_E_MAX + 1);
55012853Sgabeblack@google.com    mantissa(0U);
55112853Sgabeblack@google.com}
55212853Sgabeblack@google.com
55312853Sgabeblack@google.cominline void
55412853Sgabeblack@google.comscfx_ieee_float::set_nan()
55512853Sgabeblack@google.com{
55612853Sgabeblack@google.com    exponent(SCFX_IEEE_FLOAT_E_MAX + 1);
55712853Sgabeblack@google.com    mantissa((unsigned int)-1);
55812853Sgabeblack@google.com}
55912853Sgabeblack@google.com
56012853Sgabeblack@google.com
56112853Sgabeblack@google.com// ----------------------------------------------------------------------------
56212853Sgabeblack@google.com//  FUNCTION : scfx_pow2
56312853Sgabeblack@google.com//
56412853Sgabeblack@google.com//  Computes 2.0**exp in double-precision.
56512853Sgabeblack@google.com// ----------------------------------------------------------------------------
56612853Sgabeblack@google.com
56712853Sgabeblack@google.cominline double
56812853Sgabeblack@google.comscfx_pow2(int exp)
56912853Sgabeblack@google.com{
57012853Sgabeblack@google.com    scfx_ieee_double r;
57112853Sgabeblack@google.com    if (exp < SCFX_IEEE_DOUBLE_E_MIN) {
57212853Sgabeblack@google.com        r = 0.0;
57312853Sgabeblack@google.com        // handle subnormal case
57412853Sgabeblack@google.com        exp -= SCFX_IEEE_DOUBLE_E_MIN;
57512853Sgabeblack@google.com        if ((exp += 20) >= 0) {
57612853Sgabeblack@google.com            r.mantissa0(1U << exp);
57712853Sgabeblack@google.com        } else if ((exp += 32) >= 0) {
57812853Sgabeblack@google.com            r.mantissa1(1U << exp);
57912853Sgabeblack@google.com        }
58012853Sgabeblack@google.com    } else if (exp > SCFX_IEEE_DOUBLE_E_MAX) {
58112853Sgabeblack@google.com        r.set_inf();
58212853Sgabeblack@google.com    } else {
58312853Sgabeblack@google.com        r = 1.0;
58412853Sgabeblack@google.com        r.exponent(exp);
58512853Sgabeblack@google.com    }
58612853Sgabeblack@google.com    return r;
58712853Sgabeblack@google.com}
58812853Sgabeblack@google.com
58912853Sgabeblack@google.com
59012853Sgabeblack@google.com// ----------------------------------------------------------------------------
59112853Sgabeblack@google.com//  FUNCTION : uint64_to_double
59212853Sgabeblack@google.com//
59312853Sgabeblack@google.com//  Platform independent conversion from double uint64 to double.
59412853Sgabeblack@google.com//  Needed because VC++6 doesn't support this conversion.
59512853Sgabeblack@google.com// ----------------------------------------------------------------------------
59612853Sgabeblack@google.com
59712853Sgabeblack@google.cominline double
59812853Sgabeblack@google.comuint64_to_double(uint64 a)
59912853Sgabeblack@google.com{
60012853Sgabeblack@google.com#if defined(__clang__)
60112853Sgabeblack@google.com    // conversion from uint64 to double not implemented; use int64
60212853Sgabeblack@google.com    double tmp = static_cast<double>(static_cast<int64>(a));
60312853Sgabeblack@google.com    return (tmp >= 0) ? tmp : tmp + sc_dt::scfx_pow2(64);
60412853Sgabeblack@google.com#else
60512853Sgabeblack@google.com    return static_cast<double>(a);
60612853Sgabeblack@google.com#endif
60712853Sgabeblack@google.com}
60812853Sgabeblack@google.com
60912853Sgabeblack@google.com} // namespace sc_dt
61012853Sgabeblack@google.com
61112853Sgabeblack@google.com#undef SCFX_MASK_
61212853Sgabeblack@google.com
61312853Sgabeblack@google.com#endif // __SYSTEMC_EXT_DT_FX_SCFX_IEEE_HH__
614