scfx_mant.h revision 12027
1955SN/A/***************************************************************************** 2955SN/A 31762SN/A Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4955SN/A more contributor license agreements. See the NOTICE file distributed 5955SN/A with this work for additional information regarding copyright ownership. 6955SN/A Accellera licenses this file to you under the Apache License, Version 2.0 7955SN/A (the "License"); you may not use this file except in compliance with the 8955SN/A License. You may obtain a copy of the License at 9955SN/A 10955SN/A http://www.apache.org/licenses/LICENSE-2.0 11955SN/A 12955SN/A Unless required by applicable law or agreed to in writing, software 13955SN/A distributed under the License is distributed on an "AS IS" BASIS, 14955SN/A WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15955SN/A implied. See the License for the specific language governing 16955SN/A permissions and limitations under the License. 17955SN/A 18955SN/A *****************************************************************************/ 19955SN/A 20955SN/A/***************************************************************************** 21955SN/A 22955SN/A scfx_mant.h - 23955SN/A 24955SN/A Original Author: Robert Graulich, Synopsys, Inc. 25955SN/A Martin Janssen, Synopsys, Inc. 26955SN/A 27955SN/A *****************************************************************************/ 282665Ssaidi@eecs.umich.edu 292665Ssaidi@eecs.umich.edu/***************************************************************************** 30955SN/A 31955SN/A MODIFICATION LOG - modifiers, enter your name, affiliation, date and 32955SN/A changes you are making here. 333583Sbinkertn@umich.edu 34955SN/A Name, Affiliation, Date: 35955SN/A Description of Modification: 36955SN/A 37955SN/A *****************************************************************************/ 38955SN/A 39955SN/A// $Log: scfx_mant.h,v $ 40955SN/A// Revision 1.2 2011/08/24 22:05:43 acg 41955SN/A// Torsten Maehne: initialization changes to remove warnings. 42955SN/A// 43955SN/A// Revision 1.1.1.1 2006/12/15 20:20:04 acg 44955SN/A// SystemC 2.3 45955SN/A// 46955SN/A// Revision 1.3 2006/01/13 18:53:58 acg 47955SN/A// Andy Goodrich: added $Log command so that CVS comments are reproduced in 482023SN/A// the source. 49955SN/A// 503089Ssaidi@eecs.umich.edu 51955SN/A#ifndef SCFX_MANT_H 52955SN/A#define SCFX_MANT_H 53955SN/A 54955SN/A 55955SN/A#include "sysc/datatypes/fx/scfx_ieee.h" 56955SN/A#include "sysc/datatypes/fx/scfx_utils.h" 57955SN/A#include "sysc/kernel/sc_macros.h" 58955SN/A 591031SN/A 60955SN/Anamespace sc_dt 611388SN/A{ 62955SN/A 63955SN/A// classes defined in this module 641296SN/Aclass scfx_mant; 65955SN/Aclass scfx_mant_ref; 66955SN/A 67955SN/A 68955SN/Atypedef unsigned int word; // Using int because of 64-bit machines. 69955SN/Atypedef unsigned short half_word; 70955SN/A 71955SN/A 72955SN/A// ---------------------------------------------------------------------------- 73955SN/A// CLASS : scfx_mant 74955SN/A// 75955SN/A// Mantissa class. 76955SN/A// ---------------------------------------------------------------------------- 773584Ssaidi@eecs.umich.edu 78955SN/Aclass scfx_mant 79955SN/A{ 80955SN/A 81955SN/A word* m_array; 82955SN/A int m_size; 83955SN/A 84955SN/Apublic: 852325SN/A 861717SN/A explicit scfx_mant( std::size_t ); 872652Ssaidi@eecs.umich.edu scfx_mant( const scfx_mant& ); 88955SN/A 892736Sktlim@umich.edu scfx_mant& operator = ( const scfx_mant& ); 902410SN/A 91955SN/A ~scfx_mant(); 922290SN/A 93955SN/A void clear(); 942683Sktlim@umich.edu 952683Sktlim@umich.edu void resize_to( int, int = 0 ); 962669Sktlim@umich.edu 972568SN/A int size() const; 982568SN/A 993012Ssaidi@eecs.umich.edu word operator [] ( int ) const; 1002462SN/A word& operator [] ( int ); 1012568SN/A 1022395SN/A half_word half_at( int ) const; 1032405SN/A half_word& half_at( int ); 1042914Ssaidi@eecs.umich.edu 105955SN/A half_word* half_addr( int = 0 ) const; 1062811Srdreslin@umich.edu 1072811Srdreslin@umich.eduprivate: 1082811Srdreslin@umich.edu 1092811Srdreslin@umich.edu static word* alloc( std::size_t ); 1102811Srdreslin@umich.edu static void free( word*, std::size_t ); 1112811Srdreslin@umich.edu 1122811Srdreslin@umich.edu static word* alloc_word( std::size_t size ); 1132811Srdreslin@umich.edu static void free_word( word* array, std::size_t size ); 1142811Srdreslin@umich.edu 1152811Srdreslin@umich.edu}; 1162811Srdreslin@umich.edu 1172811Srdreslin@umich.edu 1182811Srdreslin@umich.edu// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1192811Srdreslin@umich.edu 1202811Srdreslin@umich.eduinline 1212811Srdreslin@umich.eduint 1222814Srdreslin@umich.eduscfx_mant::size() const 1232811Srdreslin@umich.edu{ 1242811Srdreslin@umich.edu return m_size; 1252811Srdreslin@umich.edu} 1262811Srdreslin@umich.edu 1272811Srdreslin@umich.edu 1282811Srdreslin@umich.eduinline 1292811Srdreslin@umich.eduword* 1302813Srdreslin@umich.eduscfx_mant::alloc( std::size_t size ) 1312813Srdreslin@umich.edu{ 1323645Sbinkertn@umich.edu#if defined( SC_BIG_ENDIAN ) 1333624Sbinkertn@umich.edu return alloc_word( size ) + ( size - 1 ); 1343624Sbinkertn@umich.edu#elif defined( SC_LITTLE_ENDIAN ) 135955SN/A return alloc_word( size ); 136955SN/A#endif 137955SN/A} 1382090SN/A 139955SN/Ainline 140955SN/Avoid 1411696SN/Ascfx_mant::free( word* mant, std::size_t size ) 142955SN/A{ 143955SN/A#if defined( SC_BIG_ENDIAN ) 144955SN/A free_word( mant - ( size - 1 ), size ); 1451127SN/A#elif defined( SC_LITTLE_ENDIAN ) 146955SN/A free_word( mant, size ); 147955SN/A#endif 1482379SN/A} 149955SN/A 150955SN/Ainline 151955SN/Aword 1522422SN/Ascfx_mant::operator[]( int i ) const 1532422SN/A{ 1542422SN/A SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" ); 1552422SN/A#if defined( SC_BIG_ENDIAN ) 1562422SN/A return m_array[-i]; 1572422SN/A#elif defined( SC_LITTLE_ENDIAN ) 1582422SN/A return m_array[i]; 1592397SN/A#endif 1602397SN/A} 1612422SN/A 1622422SN/Ainline 163955SN/Aword& 164955SN/Ascfx_mant::operator[]( int i ) 165955SN/A{ 166955SN/A SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" ); 167955SN/A#if defined( SC_BIG_ENDIAN ) 168955SN/A return m_array[-i]; 169955SN/A#elif defined( SC_LITTLE_ENDIAN ) 170955SN/A return m_array[i]; 1711078SN/A#endif 172955SN/A} 173955SN/A 174955SN/Ainline 175955SN/Ascfx_mant::scfx_mant( std::size_t size ) 1761917SN/A: m_array(0), m_size(size) 177955SN/A{ 178955SN/A m_array = alloc( size ); 1791730SN/A} 180955SN/A 1812521SN/Ainline 1822521SN/Ascfx_mant::scfx_mant( const scfx_mant& rhs ) 1832507SN/A: m_array(0), m_size(rhs.m_size) 1842507SN/A{ 1852989Ssaidi@eecs.umich.edu m_array = alloc( m_size ); 1863408Ssaidi@eecs.umich.edu for( int i = 0; i < m_size; i ++ ) 1872507SN/A { 1882507SN/A (*this)[i] = rhs[i]; 1892507SN/A } 190955SN/A} 191955SN/A 192955SN/Ainline 193955SN/Ascfx_mant& 194955SN/Ascfx_mant::operator = ( const scfx_mant& rhs ) 195955SN/A{ 196955SN/A if( &rhs != this ) 197955SN/A { 1982520SN/A if( m_size != rhs.m_size ) 1992517SN/A { 2002253SN/A free( m_array, m_size ); 2012253SN/A m_array = alloc( m_size = rhs.m_size ); 2022253SN/A } 2032253SN/A 2042553SN/A for( int i = 0; i < m_size; i ++ ) 2052553SN/A { 2062553SN/A (*this)[i] = rhs[i]; 2072553SN/A } 2082507SN/A } 2092400SN/A return *this; 2102400SN/A} 211955SN/A 212955SN/Ainline 2132667Sstever@eecs.umich.eduscfx_mant::~scfx_mant() 2142667Sstever@eecs.umich.edu{ 2152667Sstever@eecs.umich.edu if( m_array != 0 ) 2162667Sstever@eecs.umich.edu { 2172667Sstever@eecs.umich.edu free( m_array, m_size ); 2182667Sstever@eecs.umich.edu } 2192037SN/A} 2202037SN/A 2212037SN/Ainline 2223534Sgblack@eecs.umich.eduvoid 2232139SN/Ascfx_mant::clear() 2243534Sgblack@eecs.umich.edu{ 2253534Sgblack@eecs.umich.edu for( int i = 0; i < m_size; i ++ ) 2263542Sgblack@eecs.umich.edu { 2273583Sbinkertn@umich.edu (*this)[i] = 0; 2283583Sbinkertn@umich.edu } 2293542Sgblack@eecs.umich.edu} 2303499Ssaidi@eecs.umich.edu 2313583Sbinkertn@umich.eduinline 2323583Sbinkertn@umich.eduvoid 2333547Sgblack@eecs.umich.eduscfx_mant::resize_to( int size, int restore ) 2342155SN/A{ 235955SN/A if( size == m_size ) 2362155SN/A { 237955SN/A return; 2383583Sbinkertn@umich.edu } 2393583Sbinkertn@umich.edu 2403583Sbinkertn@umich.edu if( ! m_array ) 2413583Sbinkertn@umich.edu { 2423583Sbinkertn@umich.edu m_array = alloc( m_size = size ); 243955SN/A } 244955SN/A else 245955SN/A { 246955SN/A word* p = alloc( size ); 247955SN/A 2481858SN/A if( restore ) 249955SN/A { 2501858SN/A int end = sc_min( size, m_size ); 2511858SN/A if( restore == 1 ) // msb resized -> align at 0 2521858SN/A { 2531085SN/A for( int i = 0; i < size; i ++ ) 254955SN/A { 255955SN/A if( i < end ) 256955SN/A { 257955SN/A#if defined( SC_BIG_ENDIAN ) 258955SN/A p[-i] = m_array[-i]; 259955SN/A#elif defined( SC_LITTLE_ENDIAN ) 260955SN/A p[i] = m_array[i]; 261955SN/A#endif 262955SN/A } 263955SN/A else 264955SN/A { 265955SN/A#if defined( SC_BIG_ENDIAN ) 2662667Sstever@eecs.umich.edu p[-i] = 0; 2671045SN/A#elif defined( SC_LITTLE_ENDIAN ) 268955SN/A p[i] = 0; 269955SN/A#endif 270955SN/A } 271955SN/A } 2721108SN/A } 273955SN/A else // lsb resized -> align at size-1 274955SN/A { 275955SN/A for( int i = 0; i < size; i ++ ) 276955SN/A { 277955SN/A if( i < end ) 278955SN/A { 279955SN/A#if defined( SC_BIG_ENDIAN ) 280955SN/A p[-size+1+i] = m_array[-m_size+1+i]; 281955SN/A#elif defined( SC_LITTLE_ENDIAN ) 282955SN/A p[size-1-i] = m_array[m_size-1-i]; 283955SN/A#endif 284955SN/A } 285955SN/A else 286955SN/A { 287955SN/A#if defined( SC_BIG_ENDIAN ) 288955SN/A p[-size+1+i] = 0; 2892655Sstever@eecs.umich.edu#elif defined( SC_LITTLE_ENDIAN ) 2902655Sstever@eecs.umich.edu p[size-1-i] = 0; 2912655Sstever@eecs.umich.edu#endif 2922655Sstever@eecs.umich.edu } 2932655Sstever@eecs.umich.edu } 2942655Sstever@eecs.umich.edu } 2952655Sstever@eecs.umich.edu } 2962655Sstever@eecs.umich.edu 2972655Sstever@eecs.umich.edu free( m_array, m_size ); 2982655Sstever@eecs.umich.edu m_array = p; 2992655Sstever@eecs.umich.edu m_size = size; 3002655Sstever@eecs.umich.edu } 3012655Sstever@eecs.umich.edu} 3022655Sstever@eecs.umich.edu 3032655Sstever@eecs.umich.eduinline 3042655Sstever@eecs.umich.eduhalf_word 3052655Sstever@eecs.umich.eduscfx_mant::half_at( int i ) const 3062655Sstever@eecs.umich.edu{ 3072655Sstever@eecs.umich.edu SC_ASSERT_( ( i >> 1 ) >= 0 && ( i >> 1 ) < m_size, 3082655Sstever@eecs.umich.edu "mantissa index out of range" ); 3092655Sstever@eecs.umich.edu#if defined( SC_BIG_ENDIAN ) 3102655Sstever@eecs.umich.edu return reinterpret_cast<half_word*>( m_array )[-i]; 311955SN/A#elif defined( SC_LITTLE_ENDIAN ) 3123515Ssaidi@eecs.umich.edu return reinterpret_cast<half_word*>( m_array )[i]; 3133515Ssaidi@eecs.umich.edu#endif 3143515Ssaidi@eecs.umich.edu} 3153515Ssaidi@eecs.umich.edu 3163515Ssaidi@eecs.umich.eduinline 3173515Ssaidi@eecs.umich.eduhalf_word& 3183515Ssaidi@eecs.umich.eduscfx_mant::half_at( int i ) 3192655Sstever@eecs.umich.edu{ 3203515Ssaidi@eecs.umich.edu SC_ASSERT_( ( i >> 1 ) >= 0 && ( i >> 1 ) < m_size, 3213619Sbinkertn@umich.edu "mantissa index out of range" ); 322955SN/A#if defined( SC_BIG_ENDIAN ) 323955SN/A return reinterpret_cast<half_word*>( m_array )[-i]; 3242655Sstever@eecs.umich.edu#elif defined( SC_LITTLE_ENDIAN ) 3253619Sbinkertn@umich.edu return reinterpret_cast<half_word*>( m_array )[i]; 3263619Sbinkertn@umich.edu#endif 327955SN/A} 328955SN/A 3292655Sstever@eecs.umich.eduinline 3302655Sstever@eecs.umich.eduhalf_word* 3313619Sbinkertn@umich.eduscfx_mant::half_addr( int i ) const 332955SN/A{ 333955SN/A SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" ); 3342655Sstever@eecs.umich.edu#if defined( SC_BIG_ENDIAN ) 3352655Sstever@eecs.umich.edu return reinterpret_cast<half_word*>( m_array - i ) + 1; 3363683Sstever@eecs.umich.edu#elif defined( SC_LITTLE_ENDIAN ) 3372655Sstever@eecs.umich.edu return reinterpret_cast<half_word*>( m_array + i ); 3381869SN/A#endif 3391869SN/A} 340 341 342// ---------------------------------------------------------------------------- 343// one's complement of a mantissa 344// ---------------------------------------------------------------------------- 345 346inline 347void 348complement( scfx_mant& target, const scfx_mant& source, int size ) 349{ 350 for( int i = 0; i < size; i ++ ) 351 { 352 target[i] = ~source[i]; 353 } 354} 355 356 357// ---------------------------------------------------------------------------- 358// increment mantissa 359// ---------------------------------------------------------------------------- 360 361inline 362void 363inc( scfx_mant& mant ) 364{ 365 for( int i = 0; i < mant.size(); i ++ ) 366 { 367 if( ++ mant[i] ) 368 { 369 break; 370 } 371 } 372} 373 374 375// ---------------------------------------------------------------------------- 376// CLASS : scfx_mant_ref 377// 378// Mantissa reference class. 379// ---------------------------------------------------------------------------- 380 381class scfx_mant_ref 382{ 383 384 scfx_mant* m_mant; 385 bool m_not_const; 386 387public: 388 389 scfx_mant_ref(); 390 scfx_mant_ref( const scfx_mant& ); 391 scfx_mant_ref( scfx_mant* ); 392 393 scfx_mant_ref& operator = ( const scfx_mant& ); 394 scfx_mant_ref& operator = ( scfx_mant* ); 395 396 ~scfx_mant_ref(); 397 398 operator scfx_mant&(); 399 400 word operator [] ( int ); 401 402private: 403 404 void remove_it(); 405 406 scfx_mant_ref( const scfx_mant_ref& ); 407 scfx_mant_ref& operator = ( const scfx_mant_ref& ); 408 409 void* operator new( std::size_t sz ) { return ::operator new( sz ); } 410 411}; 412 413 414// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 415 416inline 417void 418scfx_mant_ref::remove_it() 419{ 420 if( m_not_const ) 421 { 422 delete m_mant; 423 } 424} 425 426inline 427scfx_mant_ref::scfx_mant_ref() 428: m_mant( 0 ), m_not_const( false ) 429{} 430 431inline 432scfx_mant_ref::scfx_mant_ref( const scfx_mant& mant ) 433: m_mant( const_cast<scfx_mant*>( &mant ) ), m_not_const( false ) 434{} 435 436inline 437scfx_mant_ref::scfx_mant_ref( scfx_mant* mant ) 438: m_mant( mant ), m_not_const( true ) 439{} 440 441inline 442scfx_mant_ref& 443scfx_mant_ref::operator = ( const scfx_mant& mant ) 444{ 445 remove_it(); 446 447 m_mant = const_cast<scfx_mant*>( &mant ); 448 m_not_const = false; 449 450 return *this; 451} 452 453inline 454scfx_mant_ref& 455scfx_mant_ref::operator = ( scfx_mant* mant ) 456{ 457 remove_it(); 458 459 m_mant = mant; 460 m_not_const = true; 461 462 return *this; 463} 464 465inline 466scfx_mant_ref::~scfx_mant_ref() 467{ 468 remove_it(); 469} 470 471inline 472scfx_mant_ref::operator scfx_mant&() 473{ 474 // SC_ASSERT_( m_not_const, "not allowed to modify mant" ); 475 return *m_mant; 476} 477 478inline 479word 480scfx_mant_ref::operator [] ( int i ) 481{ 482 return (*m_mant)[i]; 483} 484 485} // namespace sc_dt 486 487 488#endif 489 490// Taf! 491