1/***************************************************************************** 2 3 Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 more contributor license agreements. See the NOTICE file distributed 5 with this work for additional information regarding copyright ownership. 6 Accellera licenses this file to you under the Apache License, Version 2.0 7 (the "License"); you may not use this file except in compliance with the 8 License. You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12 Unless required by applicable law or agreed to in writing, software 13 distributed under the License is distributed on an "AS IS" BASIS, 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 implied. See the License for the specific language governing 16 permissions and limitations under the License. 17 18 *****************************************************************************/ 19 20/***************************************************************************** 21 22 scfx_mant.h - 23 24 Original Author: Robert Graulich, Synopsys, Inc. 25 Martin Janssen, Synopsys, Inc. 26 27 *****************************************************************************/ 28 29/***************************************************************************** 30 31 MODIFICATION LOG - modifiers, enter your name, affiliation, date and 32 changes you are making here. 33 34 Name, Affiliation, Date: 35 Description of Modification: 36 37 *****************************************************************************/ 38 39// $Log: scfx_mant.h,v $ 40// Revision 1.2 2011/08/24 22:05:43 acg 41// Torsten Maehne: initialization changes to remove warnings. 42// 43// Revision 1.1.1.1 2006/12/15 20:20:04 acg 44// SystemC 2.3 45// 46// Revision 1.3 2006/01/13 18:53:58 acg 47// Andy Goodrich: added $Log command so that CVS comments are reproduced in 48// the source. 49// 50 51#ifndef SCFX_MANT_H 52#define SCFX_MANT_H 53 54 55#include "sysc/datatypes/fx/scfx_ieee.h" 56#include "sysc/datatypes/fx/scfx_utils.h" 57#include "sysc/kernel/sc_macros.h" 58 59 60namespace sc_dt 61{ 62 63// classes defined in this module 64class scfx_mant; 65class scfx_mant_ref; 66 67 68typedef unsigned int word; // Using int because of 64-bit machines. 69typedef unsigned short half_word; 70 71 72// ---------------------------------------------------------------------------- 73// CLASS : scfx_mant 74// 75// Mantissa class. 76// ---------------------------------------------------------------------------- 77 78class scfx_mant 79{ 80 81 word* m_array; 82 int m_size; 83 84public: 85 86 explicit scfx_mant( std::size_t ); 87 scfx_mant( const scfx_mant& ); 88 89 scfx_mant& operator = ( const scfx_mant& ); 90 91 ~scfx_mant(); 92 93 void clear(); 94 95 void resize_to( int, int = 0 ); 96 97 int size() const; 98 99 word operator [] ( int ) const; 100 word& operator [] ( int ); 101 102 half_word half_at( int ) const; 103 half_word& half_at( int ); 104 105 half_word* half_addr( int = 0 ) const; 106 107private: 108 109 static word* alloc( std::size_t ); 110 static void free( word*, std::size_t ); 111 112 static word* alloc_word( std::size_t size ); 113 static void free_word( word* array, std::size_t size ); 114 115}; 116 117 118// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 119 120inline 121int 122scfx_mant::size() const 123{ 124 return m_size; 125} 126 127 128inline 129word* 130scfx_mant::alloc( std::size_t size ) 131{ 132#if defined( SC_BIG_ENDIAN ) 133 return alloc_word( size ) + ( size - 1 ); 134#elif defined( SC_LITTLE_ENDIAN ) 135 return alloc_word( size ); 136#endif 137} 138 139inline 140void 141scfx_mant::free( word* mant, std::size_t size ) 142{ 143#if defined( SC_BIG_ENDIAN ) 144 free_word( mant - ( size - 1 ), size ); 145#elif defined( SC_LITTLE_ENDIAN ) 146 free_word( mant, size ); 147#endif 148} 149 150inline 151word 152scfx_mant::operator[]( int i ) const 153{ 154 SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" ); 155#if defined( SC_BIG_ENDIAN ) 156 return m_array[-i]; 157#elif defined( SC_LITTLE_ENDIAN ) 158 return m_array[i]; 159#endif 160} 161 162inline 163word& 164scfx_mant::operator[]( int i ) 165{ 166 SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" ); 167#if defined( SC_BIG_ENDIAN ) 168 return m_array[-i]; 169#elif defined( SC_LITTLE_ENDIAN ) 170 return m_array[i]; 171#endif 172} 173 174inline 175scfx_mant::scfx_mant( std::size_t size ) 176: m_array(0), m_size(size) 177{ 178 m_array = alloc( size ); 179} 180 181inline 182scfx_mant::scfx_mant( const scfx_mant& rhs ) 183: m_array(0), m_size(rhs.m_size) 184{ 185 m_array = alloc( m_size ); 186 for( int i = 0; i < m_size; i ++ ) 187 { 188 (*this)[i] = rhs[i]; 189 } 190} 191 192inline 193scfx_mant& 194scfx_mant::operator = ( const scfx_mant& rhs ) 195{ 196 if( &rhs != this ) 197 { 198 if( m_size != rhs.m_size ) 199 { 200 free( m_array, m_size ); 201 m_array = alloc( m_size = rhs.m_size ); 202 } 203 204 for( int i = 0; i < m_size; i ++ ) 205 { 206 (*this)[i] = rhs[i]; 207 } 208 } 209 return *this; 210} 211 212inline 213scfx_mant::~scfx_mant() 214{ 215 if( m_array != 0 ) 216 { 217 free( m_array, m_size ); 218 } 219} 220 221inline 222void 223scfx_mant::clear() 224{ 225 for( int i = 0; i < m_size; i ++ ) 226 { 227 (*this)[i] = 0; 228 } 229} 230 231inline 232void 233scfx_mant::resize_to( int size, int restore ) 234{ 235 if( size == m_size ) 236 { 237 return; 238 } 239 240 if( ! m_array ) 241 { 242 m_array = alloc( m_size = size ); 243 } 244 else 245 { 246 word* p = alloc( size ); 247 248 if( restore ) 249 { 250 int end = sc_min( size, m_size ); 251 if( restore == 1 ) // msb resized -> align at 0 252 { 253 for( int i = 0; i < size; i ++ ) 254 { 255 if( i < end ) 256 { 257#if defined( SC_BIG_ENDIAN ) 258 p[-i] = m_array[-i]; 259#elif defined( SC_LITTLE_ENDIAN ) 260 p[i] = m_array[i]; 261#endif 262 } 263 else 264 { 265#if defined( SC_BIG_ENDIAN ) 266 p[-i] = 0; 267#elif defined( SC_LITTLE_ENDIAN ) 268 p[i] = 0; 269#endif 270 } 271 } 272 } 273 else // lsb resized -> align at size-1 274 { 275 for( int i = 0; i < size; i ++ ) 276 { 277 if( i < end ) 278 { 279#if defined( SC_BIG_ENDIAN ) 280 p[-size+1+i] = m_array[-m_size+1+i]; 281#elif defined( SC_LITTLE_ENDIAN ) 282 p[size-1-i] = m_array[m_size-1-i]; 283#endif 284 } 285 else 286 { 287#if defined( SC_BIG_ENDIAN ) 288 p[-size+1+i] = 0; 289#elif defined( SC_LITTLE_ENDIAN ) 290 p[size-1-i] = 0; 291#endif 292 } 293 } 294 } 295 } 296 297 free( m_array, m_size ); 298 m_array = p; 299 m_size = size; 300 } 301} 302 303inline 304half_word 305scfx_mant::half_at( int i ) const 306{ 307 SC_ASSERT_( ( i >> 1 ) >= 0 && ( i >> 1 ) < m_size, 308 "mantissa index out of range" ); 309#if defined( SC_BIG_ENDIAN ) 310 return reinterpret_cast<half_word*>( m_array )[-i]; 311#elif defined( SC_LITTLE_ENDIAN ) 312 return reinterpret_cast<half_word*>( m_array )[i]; 313#endif 314} 315 316inline 317half_word& 318scfx_mant::half_at( int i ) 319{ 320 SC_ASSERT_( ( i >> 1 ) >= 0 && ( i >> 1 ) < m_size, 321 "mantissa index out of range" ); 322#if defined( SC_BIG_ENDIAN ) 323 return reinterpret_cast<half_word*>( m_array )[-i]; 324#elif defined( SC_LITTLE_ENDIAN ) 325 return reinterpret_cast<half_word*>( m_array )[i]; 326#endif 327} 328 329inline 330half_word* 331scfx_mant::half_addr( int i ) const 332{ 333 SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" ); 334#if defined( SC_BIG_ENDIAN ) 335 return reinterpret_cast<half_word*>( m_array - i ) + 1; 336#elif defined( SC_LITTLE_ENDIAN ) 337 return reinterpret_cast<half_word*>( m_array + i ); 338#endif 339} 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