SystemC 3.0.0
Accellera SystemC proof-of-concept library
scfx_mant.h
Go to the documentation of this file.
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
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
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
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
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&
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
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
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
214{
215 if( m_array != 0 )
216 {
217 free( m_array, m_size );
218 }
219}
220
221inline
222void
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
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
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
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
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
382{
383
384 scfx_mant* m_mant;
385 bool m_not_const;
386
387public:
388
390 scfx_mant_ref( const scfx_mant& );
392
393 scfx_mant_ref& operator = ( const scfx_mant& );
394 scfx_mant_ref& operator = ( scfx_mant* );
395
397
398 operator scfx_mant&();
399
400 word operator [] ( int );
401
402private:
403
404 void remove_it();
405
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
428: m_mant( 0 ), m_not_const( false )
429{}
430
431inline
433: m_mant( const_cast<scfx_mant*>( &mant ) ), m_not_const( false )
434{}
435
436inline
438: m_mant( mant ), m_not_const( true )
439{}
440
441inline
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
456{
457 remove_it();
458
459 m_mant = mant;
460 m_not_const = true;
461
462 return *this;
463}
464
465inline
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
481{
482 return (*m_mant)[i];
483}
484
485} // namespace sc_dt
486
487
488#endif
489
490// Taf!
#define SC_ASSERT_(cnd, msg)
Definition: sc_fxdefs.h:262
#define SC_API
Definition: sc_cmnhdr.h:148
void complement(scfx_mant &target, const scfx_mant &source, int size)
Definition: scfx_mant.h:348
unsigned short half_word
Definition: scfx_mant.h:69
const T sc_min(const T &a, const T &b)
Definition: sc_macros.h:40
void inc(scfx_mant &mant)
Definition: scfx_mant.h:363
unsigned int word
Definition: scfx_mant.h:68
scfx_mant & operator=(const scfx_mant &)
Definition: scfx_mant.h:194
word operator[](int) const
Definition: scfx_mant.h:152
half_word half_at(int) const
Definition: scfx_mant.h:305
half_word * half_addr(int=0) const
Definition: scfx_mant.h:331
int size() const
Definition: scfx_mant.h:122
void resize_to(int, int=0)
Definition: scfx_mant.h:233
scfx_mant(std::size_t)
Definition: scfx_mant.h:175
word operator[](int)
Definition: scfx_mant.h:480
scfx_mant_ref & operator=(const scfx_mant &)
Definition: scfx_mant.h:443