scfx_mant.h

Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003   The following code is derived, directly or indirectly, from the SystemC
00004   source code Copyright (c) 1996-2006 by all Contributors.
00005   All Rights reserved.
00006 
00007   The contents of this file are subject to the restrictions and limitations
00008   set forth in the SystemC Open Source License Version 2.4 (the "License");
00009   You may not use this file except in compliance with such restrictions and
00010   limitations. You may obtain instructions on how to receive a copy of the
00011   License at http://www.systemc.org/. Software distributed by Contributors
00012   under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
00013   ANY KIND, either express or implied. See the License for the specific
00014   language governing rights and limitations under the License.
00015 
00016  *****************************************************************************/
00017 
00018 /*****************************************************************************
00019 
00020   scfx_mant.h - 
00021 
00022   Original Author: Robert Graulich, Synopsys, Inc.
00023                    Martin Janssen,  Synopsys, Inc.
00024 
00025  *****************************************************************************/
00026 
00027 /*****************************************************************************
00028 
00029   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
00030   changes you are making here.
00031 
00032       Name, Affiliation, Date:
00033   Description of Modification:
00034 
00035  *****************************************************************************/
00036 
00037 // $Log: scfx_mant.h,v $
00038 // Revision 1.1.1.1  2006/12/15 20:31:36  acg
00039 // SystemC 2.2
00040 //
00041 // Revision 1.3  2006/01/13 18:53:58  acg
00042 // Andy Goodrich: added $Log command so that CVS comments are reproduced in
00043 // the source.
00044 //
00045 
00046 #ifndef SCFX_MANT_H
00047 #define SCFX_MANT_H
00048 
00049 
00050 #include "sysc/datatypes/fx/scfx_ieee.h"
00051 #include "sysc/datatypes/fx/scfx_utils.h"
00052 #include "sysc/kernel/sc_macros.h"
00053 
00054 
00055 namespace sc_dt
00056 {
00057 
00058 // classes defined in this module
00059 class scfx_mant;
00060 class scfx_mant_ref;
00061 
00062 
00063 typedef unsigned int  word;       // Using int because of 64-bit machines.
00064 typedef unsigned short half_word;
00065 
00066 
00067 // ----------------------------------------------------------------------------
00068 //  CLASS : scfx_mant
00069 //
00070 //  Mantissa class.
00071 // ----------------------------------------------------------------------------
00072 
00073 class scfx_mant
00074 {
00075 
00076     word* m_array;
00077     int   m_size;
00078 
00079 public:
00080 
00081     explicit scfx_mant( std::size_t );
00082              scfx_mant( const scfx_mant& );
00083 
00084     scfx_mant& operator = ( const scfx_mant& );
00085 
00086     ~scfx_mant();
00087 
00088     void clear();
00089 
00090     void resize_to( int, int = 0 );
00091 
00092     int size() const;
00093 
00094     word  operator [] ( int ) const;
00095     word& operator [] ( int );
00096 
00097     half_word  half_at( int ) const;
00098     half_word& half_at( int );
00099 
00100     half_word* half_addr( int = 0 ) const;
00101 
00102 private:
00103 
00104     static word* alloc( std::size_t );
00105     static void free( word*, std::size_t );
00106 
00107     static word* alloc_word( std::size_t size );
00108     static void free_word( word* array, std::size_t size );
00109 
00110 };
00111 
00112 
00113 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00114 
00115 inline
00116 int
00117 scfx_mant::size() const
00118 {
00119     return m_size;
00120 }
00121 
00122 
00123 inline
00124 word*
00125 scfx_mant::alloc( std::size_t size )
00126 {
00127 #if defined( SC_BIG_ENDIAN )
00128     return alloc_word( size ) + ( size - 1 );
00129 #elif defined( SC_LITTLE_ENDIAN )
00130     return alloc_word( size );
00131 #endif
00132 }
00133 
00134 inline
00135 void
00136 scfx_mant::free( word* mant, std::size_t size )
00137 {
00138 #if defined( SC_BIG_ENDIAN )
00139     free_word( mant - ( size - 1 ), size );
00140 #elif defined( SC_LITTLE_ENDIAN )
00141     free_word( mant, size );
00142 #endif
00143 }
00144 
00145 inline
00146 word
00147 scfx_mant::operator[]( int i ) const
00148 {
00149     SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" );
00150 #if defined( SC_BIG_ENDIAN )
00151     return m_array[-i];
00152 #elif defined( SC_LITTLE_ENDIAN )
00153     return m_array[i];
00154 #endif
00155 }
00156 
00157 inline
00158 word&
00159 scfx_mant::operator[]( int i )
00160 {
00161     SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" );
00162 #if defined( SC_BIG_ENDIAN )
00163     return m_array[-i];
00164 #elif defined( SC_LITTLE_ENDIAN )
00165     return m_array[i];
00166 #endif
00167 }
00168 
00169 inline
00170 scfx_mant::scfx_mant( std::size_t size )
00171 {
00172     m_array = alloc( m_size = size );
00173 }
00174 
00175 inline
00176 scfx_mant::scfx_mant( const scfx_mant& rhs )
00177 {
00178     m_array = alloc( m_size = rhs.m_size );
00179     for( int i = 0; i < m_size; i ++ )
00180     {
00181         (*this)[i] = rhs[i];
00182     }
00183 }
00184 
00185 inline
00186 scfx_mant&
00187 scfx_mant::operator = ( const scfx_mant& rhs )
00188 {
00189     if( &rhs != this )
00190     {
00191         if( m_size != rhs.m_size )
00192     {
00193         free( m_array, m_size );
00194         m_array = alloc( m_size = rhs.m_size );
00195     }
00196 
00197     for( int i = 0; i < m_size; i ++ )
00198     {
00199         (*this)[i] = rhs[i];
00200     }
00201     }
00202     return *this;
00203 }
00204 
00205 inline
00206 scfx_mant::~scfx_mant()
00207 {
00208     if( m_array != 0 )
00209     {
00210         free( m_array, m_size );
00211     }
00212 }
00213 
00214 inline
00215 void
00216 scfx_mant::clear()
00217 {
00218     for( int i = 0; i < m_size; i ++ )
00219     {
00220         (*this)[i] = 0;
00221     }
00222 }
00223 
00224 inline
00225 void
00226 scfx_mant::resize_to( int size, int restore )
00227 {
00228     if( size == m_size )
00229     {
00230         return;
00231     }
00232 
00233     if( ! m_array )
00234     {
00235         m_array = alloc( m_size = size );
00236     }
00237     else
00238     {
00239         word* p = alloc( size );
00240 
00241     if( restore )
00242     {
00243         int end = sc_min( size, m_size );
00244         if( restore == 1 )      // msb resized -> align at 0
00245         {
00246             for( int i = 0; i < size; i ++ )
00247         {
00248             if( i < end )
00249             {
00250 #if defined( SC_BIG_ENDIAN )
00251                 p[-i] = m_array[-i];
00252 #elif defined( SC_LITTLE_ENDIAN )
00253             p[i] = m_array[i];
00254 #endif
00255             }
00256             else
00257             {
00258 #if defined( SC_BIG_ENDIAN )
00259                 p[-i] = 0;
00260 #elif defined( SC_LITTLE_ENDIAN )
00261             p[i] = 0;
00262 #endif
00263             }
00264         }
00265         }
00266         else            // lsb resized -> align at size-1
00267         {
00268             for( int i = 0; i < size; i ++ )
00269         {
00270             if( i < end )
00271             {
00272 #if defined( SC_BIG_ENDIAN )
00273                 p[-size+1+i] = m_array[-m_size+1+i];
00274 #elif defined( SC_LITTLE_ENDIAN )
00275             p[size-1-i] = m_array[m_size-1-i];
00276 #endif
00277             }
00278             else
00279             {
00280 #if defined( SC_BIG_ENDIAN )
00281                 p[-size+1+i] = 0;
00282 #elif defined( SC_LITTLE_ENDIAN )
00283             p[size-1-i] = 0;
00284 #endif
00285             }
00286         }
00287         }
00288     }
00289 
00290     free( m_array, m_size );
00291     m_array = p;
00292     m_size = size;
00293     }
00294 }
00295 
00296 inline
00297 half_word
00298 scfx_mant::half_at( int i ) const
00299 {
00300     SC_ASSERT_( ( i >> 1 ) >= 0 && ( i >> 1 ) < m_size,
00301         "mantissa index out of range" );
00302 #if defined( SC_BIG_ENDIAN )
00303     return reinterpret_cast<half_word*>( m_array )[-i];
00304 #elif defined( SC_LITTLE_ENDIAN )
00305     return reinterpret_cast<half_word*>( m_array )[i];
00306 #endif
00307 }
00308 
00309 inline
00310 half_word&
00311 scfx_mant::half_at( int i )
00312 {
00313     SC_ASSERT_( ( i >> 1 ) >= 0 && ( i >> 1 ) < m_size,
00314         "mantissa index out of range" );
00315 #if defined( SC_BIG_ENDIAN )
00316     return reinterpret_cast<half_word*>( m_array )[-i];
00317 #elif defined( SC_LITTLE_ENDIAN )
00318     return reinterpret_cast<half_word*>( m_array )[i];
00319 #endif
00320 }
00321 
00322 inline
00323 half_word*
00324 scfx_mant::half_addr( int i ) const
00325 {
00326     SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" );
00327 #if defined( SC_BIG_ENDIAN )
00328     return reinterpret_cast<half_word*>( m_array - i ) + 1;
00329 #elif defined( SC_LITTLE_ENDIAN )
00330     return reinterpret_cast<half_word*>( m_array + i );
00331 #endif
00332 }
00333 
00334 
00335 // ----------------------------------------------------------------------------
00336 //  one's complement of a mantissa
00337 // ----------------------------------------------------------------------------
00338 
00339 inline
00340 void
00341 complement( scfx_mant& target, const scfx_mant& source, int size )
00342 {
00343     for( int i = 0; i < size; i ++ )
00344     {
00345         target[i] = ~source[i];
00346     }
00347 }
00348 
00349 
00350 // ----------------------------------------------------------------------------
00351 //  increment mantissa
00352 // ----------------------------------------------------------------------------
00353 
00354 inline
00355 void
00356 inc( scfx_mant& mant )
00357 {
00358     for( int i = 0; i < mant.size(); i ++ )
00359     {
00360         if( ++ mant[i] )
00361     {
00362         break;
00363     }
00364     }
00365 }
00366 
00367 
00368 // ----------------------------------------------------------------------------
00369 //  CLASS : scfx_mant_ref
00370 //
00371 //  Mantissa reference class.
00372 // ----------------------------------------------------------------------------
00373 
00374 class scfx_mant_ref
00375 {
00376 
00377     scfx_mant* m_mant;
00378     bool       m_not_const;
00379 
00380 public:
00381 
00382     scfx_mant_ref();
00383     scfx_mant_ref( const scfx_mant& );
00384     scfx_mant_ref( scfx_mant* );
00385 
00386     scfx_mant_ref& operator = ( const scfx_mant& );
00387     scfx_mant_ref& operator = ( scfx_mant* );
00388 
00389     ~scfx_mant_ref();
00390 
00391     operator scfx_mant&();
00392 
00393     word operator [] ( int );
00394 
00395 private:
00396 
00397     void remove_it();
00398 
00399     scfx_mant_ref( const scfx_mant_ref& );
00400     scfx_mant_ref& operator = ( const scfx_mant_ref& );
00401 
00402     void* operator new( std::size_t sz ) { return ::operator new( sz ); }
00403 
00404 };
00405 
00406 
00407 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00408 
00409 inline
00410 void
00411 scfx_mant_ref::remove_it()
00412 {
00413     if( m_not_const )
00414     {
00415         delete m_mant;
00416     }
00417 }
00418 
00419 inline
00420 scfx_mant_ref::scfx_mant_ref()
00421 : m_mant( 0 ), m_not_const( false )
00422 {}
00423 
00424 inline
00425 scfx_mant_ref::scfx_mant_ref( const scfx_mant& mant )
00426 : m_mant( const_cast<scfx_mant*>( &mant ) ), m_not_const( false )
00427 {}
00428 
00429 inline
00430 scfx_mant_ref::scfx_mant_ref( scfx_mant* mant )
00431 : m_mant( mant ), m_not_const( true )
00432 {}
00433 
00434 inline
00435 scfx_mant_ref&
00436 scfx_mant_ref::operator = ( const scfx_mant& mant )
00437 {
00438     remove_it();
00439 
00440     m_mant = const_cast<scfx_mant*>( &mant );
00441     m_not_const = false;
00442 
00443     return *this;
00444 }
00445 
00446 inline
00447 scfx_mant_ref&
00448 scfx_mant_ref::operator = ( scfx_mant* mant )
00449 {
00450     remove_it();
00451 
00452     m_mant = mant;
00453     m_not_const = true;
00454 
00455     return *this;
00456 }
00457 
00458 inline
00459 scfx_mant_ref::~scfx_mant_ref()
00460 {
00461     remove_it();
00462 }
00463 
00464 inline
00465 scfx_mant_ref::operator scfx_mant&()
00466 {
00467     // SC_ASSERT_( m_not_const, "not allowed to modify mant" );
00468     return *m_mant;
00469 }
00470 
00471 inline
00472 word
00473 scfx_mant_ref::operator [] ( int i )
00474 {
00475     return (*m_mant)[i];
00476 }
00477 
00478 } // namespace sc_dt
00479 
00480 
00481 #endif
00482 
00483 // Taf!

Generated on Wed Jan 21 15:32:08 2009 for SystemC by  doxygen 1.5.5