scfx_ieee.hh revision 12853
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