00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
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
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
00060
00061
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
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 )
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
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
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
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
00361
00362
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
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
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 }
00470
00471
00472 #endif
00473
00474