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