Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

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-2004 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.3 (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 #ifndef SCFX_MANT_H
00038 #define SCFX_MANT_H
00039 
00040 
00041 #include "systemc/datatypes/fx/scfx_ieee.h"
00042 #include "systemc/datatypes/fx/scfx_utils.h"
00043 #include "systemc/kernel/sc_macros.h"
00044 
00045 
00046 namespace sc_dt
00047 {
00048 
00049 // classes defined in this module
00050 class scfx_mant;
00051 class scfx_mant_ref;
00052 
00053 
00054 typedef unsigned long  word;
00055 typedef unsigned short half_word;
00056 
00057 
00058 // ----------------------------------------------------------------------------
00059 //  CLASS : scfx_mant
00060 //
00061 //  Mantissa class.
00062 // ----------------------------------------------------------------------------
00063 
00064 class scfx_mant
00065 {
00066 
00067     word* m_array;
00068     int   m_size;
00069 
00070 public:
00071 
00072     explicit scfx_mant( size_t );
00073              scfx_mant( const scfx_mant& );
00074 
00075     scfx_mant& operator = ( const scfx_mant& );
00076 
00077     ~scfx_mant();
00078 
00079     void clear();
00080 
00081     void resize_to( int, int = 0 );
00082 
00083     int size() const;
00084 
00085     word  operator [] ( int ) const;
00086     word& operator [] ( int );
00087 
00088     half_word  half_at( int ) const;
00089     half_word& half_at( int );
00090 
00091     half_word* half_addr( int = 0 ) const;
00092 
00093 private:
00094 
00095     static word* alloc( size_t );
00096     static void free( word*, size_t );
00097 
00098     static word* alloc_word( size_t size );
00099     static void free_word( word* array, size_t size );
00100 
00101 };
00102 
00103 
00104 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00105 
00106 inline
00107 int
00108 scfx_mant::size() const
00109 {
00110     return m_size;
00111 }
00112 
00113 
00114 inline
00115 word*
00116 scfx_mant::alloc( size_t size )
00117 {
00118 #if defined( SCFX_BIG_ENDIAN )
00119     return alloc_word( size ) + ( size - 1 );
00120 #elif defined( SCFX_LITTLE_ENDIAN )
00121     return alloc_word( size );
00122 #endif
00123 }
00124 
00125 inline
00126 void
00127 scfx_mant::free( word* mant, size_t size )
00128 {
00129 #if defined( SCFX_BIG_ENDIAN )
00130     free_word( mant - ( size - 1 ), size );
00131 #elif defined( SCFX_LITTLE_ENDIAN )
00132     free_word( mant, size );
00133 #endif
00134 }
00135 
00136 inline
00137 word
00138 scfx_mant::operator[]( int i ) const
00139 {
00140     SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" );
00141 #if defined( SCFX_BIG_ENDIAN )
00142     return m_array[-i];
00143 #elif defined( SCFX_LITTLE_ENDIAN )
00144     return m_array[i];
00145 #endif
00146 }
00147 
00148 inline
00149 word&
00150 scfx_mant::operator[]( int i )
00151 {
00152     SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" );
00153 #if defined( SCFX_BIG_ENDIAN )
00154     return m_array[-i];
00155 #elif defined( SCFX_LITTLE_ENDIAN )
00156     return m_array[i];
00157 #endif
00158 }
00159 
00160 inline
00161 scfx_mant::scfx_mant( size_t size )
00162 {
00163     m_array = alloc( m_size = size );
00164 }
00165 
00166 inline
00167 scfx_mant::scfx_mant( const scfx_mant& rhs )
00168 {
00169     m_array = alloc( m_size = rhs.m_size );
00170     for( int i = 0; i < m_size; i ++ )
00171     {
00172         (*this)[i] = rhs[i];
00173     }
00174 }
00175 
00176 inline
00177 scfx_mant&
00178 scfx_mant::operator = ( const scfx_mant& rhs )
00179 {
00180     if( &rhs != this )
00181     {
00182         if( m_size != rhs.m_size )
00183   {
00184       free( m_array, m_size );
00185       m_array = alloc( m_size = rhs.m_size );
00186   }
00187 
00188   for( int i = 0; i < m_size; i ++ )
00189   {
00190       (*this)[i] = rhs[i];
00191   }
00192     }
00193     return *this;
00194 }
00195 
00196 inline
00197 scfx_mant::~scfx_mant()
00198 {
00199     if( m_array != 0 )
00200     {
00201         free( m_array, m_size );
00202     }
00203 }
00204 
00205 inline
00206 void
00207 scfx_mant::clear()
00208 {
00209     for( int i = 0; i < m_size; i ++ )
00210     {
00211         (*this)[i] = 0;
00212     }
00213 }
00214 
00215 inline
00216 void
00217 scfx_mant::resize_to( int size, int restore )
00218 {
00219     if( size == m_size )
00220     {
00221         return;
00222     }
00223 
00224     if( ! m_array )
00225     {
00226         m_array = alloc( m_size = size );
00227     }
00228     else
00229     {
00230         word* p = alloc( size );
00231 
00232   if( restore )
00233   {
00234       int end = sc_min( size, m_size );
00235       if( restore == 1 )    // msb resized -> align at 0
00236       {
00237           for( int i = 0; i < size; i ++ )
00238     {
00239         if( i < end )
00240         {
00241 #if defined( SCFX_BIG_ENDIAN )
00242             p[-i] = m_array[-i];
00243 #elif defined( SCFX_LITTLE_ENDIAN )
00244       p[i] = m_array[i];
00245 #endif
00246         }
00247         else
00248         {
00249 #if defined( SCFX_BIG_ENDIAN )
00250             p[-i] = 0;
00251 #elif defined( SCFX_LITTLE_ENDIAN )
00252       p[i] = 0;
00253 #endif
00254         }
00255     }
00256       }
00257       else      // lsb resized -> align at size-1
00258       {
00259           for( int i = 0; i < size; i ++ )
00260     {
00261         if( i < end )
00262         {
00263 #if defined( SCFX_BIG_ENDIAN )
00264             p[-size+1+i] = m_array[-m_size+1+i];
00265 #elif defined( SCFX_LITTLE_ENDIAN )
00266       p[size-1-i] = m_array[m_size-1-i];
00267 #endif
00268         }
00269         else
00270         {
00271 #if defined( SCFX_BIG_ENDIAN )
00272             p[-size+1+i] = 0;
00273 #elif defined( SCFX_LITTLE_ENDIAN )
00274       p[size-1-i] = 0;
00275 #endif
00276         }
00277     }
00278       }
00279   }
00280 
00281   free( m_array, m_size );
00282   m_array = p;
00283   m_size = size;
00284     }
00285 }
00286 
00287 inline
00288 half_word
00289 scfx_mant::half_at( int i ) const
00290 {
00291     SC_ASSERT_( ( i >> 1 ) >= 0 && ( i >> 1 ) < m_size,
00292     "mantissa index out of range" );
00293 #if defined( SCFX_BIG_ENDIAN )
00294     return reinterpret_cast<half_word*>( m_array )[-i];
00295 #elif defined( SCFX_LITTLE_ENDIAN )
00296     return reinterpret_cast<half_word*>( m_array )[i];
00297 #endif
00298 }
00299 
00300 inline
00301 half_word&
00302 scfx_mant::half_at( int i )
00303 {
00304     SC_ASSERT_( ( i >> 1 ) >= 0 && ( i >> 1 ) < m_size,
00305     "mantissa index out of range" );
00306 #if defined( SCFX_BIG_ENDIAN )
00307     return reinterpret_cast<half_word*>( m_array )[-i];
00308 #elif defined( SCFX_LITTLE_ENDIAN )
00309     return reinterpret_cast<half_word*>( m_array )[i];
00310 #endif
00311 }
00312 
00313 inline
00314 half_word*
00315 scfx_mant::half_addr( int i ) const
00316 {
00317     SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" );
00318 #if defined( SCFX_BIG_ENDIAN )
00319     return reinterpret_cast<half_word*>( m_array - i ) + 1;
00320 #elif defined( SCFX_LITTLE_ENDIAN )
00321     return reinterpret_cast<half_word*>( m_array + i );
00322 #endif
00323 }
00324 
00325 
00326 // ----------------------------------------------------------------------------
00327 //  one's complement of a mantissa
00328 // ----------------------------------------------------------------------------
00329 
00330 inline
00331 void
00332 complement( scfx_mant& target, const scfx_mant& source, int size )
00333 {
00334     for( int i = 0; i < size; i ++ )
00335     {
00336         target[i] = ~source[i];
00337     }
00338 }
00339 
00340 
00341 // ----------------------------------------------------------------------------
00342 //  increment mantissa
00343 // ----------------------------------------------------------------------------
00344 
00345 inline
00346 void
00347 inc( scfx_mant& mant )
00348 {
00349     for( int i = 0; i < mant.size(); i ++ )
00350     {
00351         if( ++ mant[i] )
00352   {
00353       break;
00354   }
00355     }
00356 }
00357 
00358 
00359 // ----------------------------------------------------------------------------
00360 //  CLASS : scfx_mant_ref
00361 //
00362 //  Mantissa reference class.
00363 // ----------------------------------------------------------------------------
00364 
00365 class scfx_mant_ref
00366 {
00367 
00368     scfx_mant* m_mant;
00369     bool       m_not_const;
00370 
00371 public:
00372 
00373     scfx_mant_ref();
00374     scfx_mant_ref( const scfx_mant& );
00375     scfx_mant_ref( scfx_mant* );
00376 
00377     scfx_mant_ref& operator = ( const scfx_mant& );
00378     scfx_mant_ref& operator = ( scfx_mant* );
00379 
00380     ~scfx_mant_ref();
00381 
00382     operator scfx_mant&();
00383 
00384     word operator [] ( int );
00385 
00386 private:
00387 
00388     void remove_it();
00389 
00390     scfx_mant_ref( const scfx_mant_ref& );
00391     scfx_mant_ref& operator = ( const scfx_mant_ref& );
00392 
00393     void* operator new( size_t sz ) { return ::operator new( sz ); }
00394 
00395 };
00396 
00397 
00398 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00399 
00400 inline
00401 void
00402 scfx_mant_ref::remove_it()
00403 {
00404     if( m_not_const )
00405     {
00406         delete m_mant;
00407     }
00408 }
00409 
00410 inline
00411 scfx_mant_ref::scfx_mant_ref()
00412 : m_mant( 0 ), m_not_const( false )
00413 {}
00414 
00415 inline
00416 scfx_mant_ref::scfx_mant_ref( const scfx_mant& mant )
00417 : m_mant( const_cast<scfx_mant*>( &mant ) ), m_not_const( false )
00418 {}
00419 
00420 inline
00421 scfx_mant_ref::scfx_mant_ref( scfx_mant* mant )
00422 : m_mant( mant ), m_not_const( true )
00423 {}
00424 
00425 inline
00426 scfx_mant_ref&
00427 scfx_mant_ref::operator = ( const scfx_mant& mant )
00428 {
00429     remove_it();
00430 
00431     m_mant = const_cast<scfx_mant*>( &mant );
00432     m_not_const = false;
00433 
00434     return *this;
00435 }
00436 
00437 inline
00438 scfx_mant_ref&
00439 scfx_mant_ref::operator = ( scfx_mant* mant )
00440 {
00441     remove_it();
00442 
00443     m_mant = mant;
00444     m_not_const = true;
00445 
00446     return *this;
00447 }
00448 
00449 inline
00450 scfx_mant_ref::~scfx_mant_ref()
00451 {
00452     remove_it();
00453 }
00454 
00455 inline
00456 scfx_mant_ref::operator scfx_mant&()
00457 {
00458     // SC_ASSERT_( m_not_const, "not allowed to modify mant" );
00459     return *m_mant;
00460 }
00461 
00462 inline
00463 word
00464 scfx_mant_ref::operator [] ( int i )
00465 {
00466     return (*m_mant)[i];
00467 }
00468 
00469 } // namespace sc_dt
00470 
00471 
00472 #endif
00473 
00474 // Taf!

Generated on Fri Jan 14 08:29:09 2005 for SystemC2.1beta11(excludingMSLib)(IncludingSCV)\nProvidedby:www.openverificationfoundation.org by doxygen1.2.18