SystemC  2.3.1
Accellera SystemC proof-of-concept library
scfx_mant.h
Go to the documentation of this file.
1 /*****************************************************************************
2 
3  The following code is derived, directly or indirectly, from the SystemC
4  source code Copyright (c) 1996-2014 by all Contributors.
5  All Rights reserved.
6 
7  The contents of this file are subject to the restrictions and limitations
8  set forth in the SystemC Open Source License (the "License");
9  You may not use this file except in compliance with such restrictions and
10  limitations. You may obtain instructions on how to receive a copy of the
11  License at http://www.accellera.org/. Software distributed by Contributors
12  under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
13  ANY KIND, either express or implied. See the License for the specific
14  language governing rights and limitations under the License.
15 
16  *****************************************************************************/
17 
18 /*****************************************************************************
19 
20  scfx_mant.h -
21 
22  Original Author: Robert Graulich, Synopsys, Inc.
23  Martin Janssen, Synopsys, Inc.
24 
25  *****************************************************************************/
26 
27 /*****************************************************************************
28 
29  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
30  changes you are making here.
31 
32  Name, Affiliation, Date:
33  Description of Modification:
34 
35  *****************************************************************************/
36 
37 // $Log: scfx_mant.h,v $
38 // Revision 1.2 2011/08/24 22:05:43 acg
39 // Torsten Maehne: initialization changes to remove warnings.
40 //
41 // Revision 1.1.1.1 2006/12/15 20:20:04 acg
42 // SystemC 2.3
43 //
44 // Revision 1.3 2006/01/13 18:53:58 acg
45 // Andy Goodrich: added $Log command so that CVS comments are reproduced in
46 // the source.
47 //
48 
49 #ifndef SCFX_MANT_H
50 #define SCFX_MANT_H
51 
52 
55 #include "sysc/kernel/sc_macros.h"
56 
57 
58 namespace sc_dt
59 {
60 
61 // classes defined in this module
62 class scfx_mant;
64 
65 
66 typedef unsigned int word; // Using int because of 64-bit machines.
67 typedef unsigned short half_word;
68 
69 
70 // ----------------------------------------------------------------------------
71 // CLASS : scfx_mant
72 //
73 // Mantissa class.
74 // ----------------------------------------------------------------------------
75 
76 class scfx_mant
77 {
78 
79  word* m_array;
80  int m_size;
81 
82 public:
83 
84  explicit scfx_mant( std::size_t );
85  scfx_mant( const scfx_mant& );
86 
87  scfx_mant& operator = ( const scfx_mant& );
88 
89  ~scfx_mant();
90 
91  void clear();
92 
93  void resize_to( int, int = 0 );
94 
95  int size() const;
96 
97  word operator [] ( int ) const;
98  word& operator [] ( int );
99 
100  half_word half_at( int ) const;
101  half_word& half_at( int );
102 
103  half_word* half_addr( int = 0 ) const;
104 
105 private:
106 
107  static word* alloc( std::size_t );
108  static void free( word*, std::size_t );
109 
110  static word* alloc_word( std::size_t size );
111  static void free_word( word* array, std::size_t size );
112 
113 };
114 
115 
116 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
117 
118 inline
119 int
121 {
122  return m_size;
123 }
124 
125 
126 inline
127 word*
128 scfx_mant::alloc( std::size_t size )
129 {
130 #if defined( SC_BIG_ENDIAN )
131  return alloc_word( size ) + ( size - 1 );
132 #elif defined( SC_LITTLE_ENDIAN )
133  return alloc_word( size );
134 #endif
135 }
136 
137 inline
138 void
139 scfx_mant::free( word* mant, std::size_t size )
140 {
141 #if defined( SC_BIG_ENDIAN )
142  free_word( mant - ( size - 1 ), size );
143 #elif defined( SC_LITTLE_ENDIAN )
144  free_word( mant, size );
145 #endif
146 }
147 
148 inline
149 word
150 scfx_mant::operator[]( int i ) const
151 {
152  SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" );
153 #if defined( SC_BIG_ENDIAN )
154  return m_array[-i];
155 #elif defined( SC_LITTLE_ENDIAN )
156  return m_array[i];
157 #endif
158 }
159 
160 inline
161 word&
163 {
164  SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" );
165 #if defined( SC_BIG_ENDIAN )
166  return m_array[-i];
167 #elif defined( SC_LITTLE_ENDIAN )
168  return m_array[i];
169 #endif
170 }
171 
172 inline
173 scfx_mant::scfx_mant( std::size_t size )
174 : m_array(0), m_size(size)
175 {
176  m_array = alloc( size );
177 }
178 
179 inline
181 : m_array(0), m_size(rhs.m_size)
182 {
183  m_array = alloc( m_size );
184  for( int i = 0; i < m_size; i ++ )
185  {
186  (*this)[i] = rhs[i];
187  }
188 }
189 
190 inline
191 scfx_mant&
193 {
194  if( &rhs != this )
195  {
196  if( m_size != rhs.m_size )
197  {
198  free( m_array, m_size );
199  m_array = alloc( m_size = rhs.m_size );
200  }
201 
202  for( int i = 0; i < m_size; i ++ )
203  {
204  (*this)[i] = rhs[i];
205  }
206  }
207  return *this;
208 }
209 
210 inline
212 {
213  if( m_array != 0 )
214  {
215  free( m_array, m_size );
216  }
217 }
218 
219 inline
220 void
222 {
223  for( int i = 0; i < m_size; i ++ )
224  {
225  (*this)[i] = 0;
226  }
227 }
228 
229 inline
230 void
231 scfx_mant::resize_to( int size, int restore )
232 {
233  if( size == m_size )
234  {
235  return;
236  }
237 
238  if( ! m_array )
239  {
240  m_array = alloc( m_size = size );
241  }
242  else
243  {
244  word* p = alloc( size );
245 
246  if( restore )
247  {
248  int end = sc_min( size, m_size );
249  if( restore == 1 ) // msb resized -> align at 0
250  {
251  for( int i = 0; i < size; i ++ )
252  {
253  if( i < end )
254  {
255 #if defined( SC_BIG_ENDIAN )
256  p[-i] = m_array[-i];
257 #elif defined( SC_LITTLE_ENDIAN )
258  p[i] = m_array[i];
259 #endif
260  }
261  else
262  {
263 #if defined( SC_BIG_ENDIAN )
264  p[-i] = 0;
265 #elif defined( SC_LITTLE_ENDIAN )
266  p[i] = 0;
267 #endif
268  }
269  }
270  }
271  else // lsb resized -> align at size-1
272  {
273  for( int i = 0; i < size; i ++ )
274  {
275  if( i < end )
276  {
277 #if defined( SC_BIG_ENDIAN )
278  p[-size+1+i] = m_array[-m_size+1+i];
279 #elif defined( SC_LITTLE_ENDIAN )
280  p[size-1-i] = m_array[m_size-1-i];
281 #endif
282  }
283  else
284  {
285 #if defined( SC_BIG_ENDIAN )
286  p[-size+1+i] = 0;
287 #elif defined( SC_LITTLE_ENDIAN )
288  p[size-1-i] = 0;
289 #endif
290  }
291  }
292  }
293  }
294 
295  free( m_array, m_size );
296  m_array = p;
297  m_size = size;
298  }
299 }
300 
301 inline
302 half_word
303 scfx_mant::half_at( int i ) const
304 {
305  SC_ASSERT_( ( i >> 1 ) >= 0 && ( i >> 1 ) < m_size,
306  "mantissa index out of range" );
307 #if defined( SC_BIG_ENDIAN )
308  return reinterpret_cast<half_word*>( m_array )[-i];
309 #elif defined( SC_LITTLE_ENDIAN )
310  return reinterpret_cast<half_word*>( m_array )[i];
311 #endif
312 }
313 
314 inline
315 half_word&
317 {
318  SC_ASSERT_( ( i >> 1 ) >= 0 && ( i >> 1 ) < m_size,
319  "mantissa index out of range" );
320 #if defined( SC_BIG_ENDIAN )
321  return reinterpret_cast<half_word*>( m_array )[-i];
322 #elif defined( SC_LITTLE_ENDIAN )
323  return reinterpret_cast<half_word*>( m_array )[i];
324 #endif
325 }
326 
327 inline
328 half_word*
329 scfx_mant::half_addr( int i ) const
330 {
331  SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" );
332 #if defined( SC_BIG_ENDIAN )
333  return reinterpret_cast<half_word*>( m_array - i ) + 1;
334 #elif defined( SC_LITTLE_ENDIAN )
335  return reinterpret_cast<half_word*>( m_array + i );
336 #endif
337 }
338 
339 
340 // ----------------------------------------------------------------------------
341 // one's complement of a mantissa
342 // ----------------------------------------------------------------------------
343 
344 inline
345 void
346 complement( scfx_mant& target, const scfx_mant& source, int size )
347 {
348  for( int i = 0; i < size; i ++ )
349  {
350  target[i] = ~source[i];
351  }
352 }
353 
354 
355 // ----------------------------------------------------------------------------
356 // increment mantissa
357 // ----------------------------------------------------------------------------
358 
359 inline
360 void
361 inc( scfx_mant& mant )
362 {
363  for( int i = 0; i < mant.size(); i ++ )
364  {
365  if( ++ mant[i] )
366  {
367  break;
368  }
369  }
370 }
371 
372 
373 // ----------------------------------------------------------------------------
374 // CLASS : scfx_mant_ref
375 //
376 // Mantissa reference class.
377 // ----------------------------------------------------------------------------
378 
380 {
381 
382  scfx_mant* m_mant;
383  bool m_not_const;
384 
385 public:
386 
387  scfx_mant_ref();
388  scfx_mant_ref( const scfx_mant& );
390 
393 
394  ~scfx_mant_ref();
395 
396  operator scfx_mant&();
397 
398  word operator [] ( int );
399 
400 private:
401 
402  void remove_it();
403 
404  scfx_mant_ref( const scfx_mant_ref& );
406 
407  void* operator new( std::size_t sz ) { return ::operator new( sz ); }
408 
409 };
410 
411 
412 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
413 
414 inline
415 void
416 scfx_mant_ref::remove_it()
417 {
418  if( m_not_const )
419  {
420  delete m_mant;
421  }
422 }
423 
424 inline
426 : m_mant( 0 ), m_not_const( false )
427 {}
428 
429 inline
431 : m_mant( const_cast<scfx_mant*>( &mant ) ), m_not_const( false )
432 {}
433 
434 inline
436 : m_mant( mant ), m_not_const( true )
437 {}
438 
439 inline
442 {
443  remove_it();
444 
445  m_mant = const_cast<scfx_mant*>( &mant );
446  m_not_const = false;
447 
448  return *this;
449 }
450 
451 inline
454 {
455  remove_it();
456 
457  m_mant = mant;
458  m_not_const = true;
459 
460  return *this;
461 }
462 
463 inline
465 {
466  remove_it();
467 }
468 
469 inline
470 scfx_mant_ref::operator scfx_mant&()
471 {
472  // SC_ASSERT_( m_not_const, "not allowed to modify mant" );
473  return *m_mant;
474 }
475 
476 inline
477 word
479 {
480  return (*m_mant)[i];
481 }
482 
483 } // namespace sc_dt
484 
485 
486 #endif
487 
488 // Taf!
scfx_mant(std::size_t)
Definition: scfx_mant.h:173
word operator[](int) const
Definition: scfx_mant.h:150
word operator[](int)
Definition: scfx_mant.h:478
#define SC_ASSERT_(cnd, msg)
Definition: sc_fxdefs.h:254
int size() const
Definition: scfx_mant.h:120
void resize_to(int, int=0)
Definition: scfx_mant.h:231
unsigned int word
Definition: scfx_mant.h:63
const T sc_min(const T &a, const T &b)
Definition: sc_macros.h:37
half_word * half_addr(int=0) const
Definition: scfx_mant.h:329
unsigned short half_word
Definition: scfx_mant.h:67
scfx_mant_ref & operator=(const scfx_mant &)
Definition: scfx_mant.h:441
void complement(scfx_mant &target, const scfx_mant &source, int size)
Definition: scfx_mant.h:346
half_word half_at(int) const
Definition: scfx_mant.h:303
scfx_mant & operator=(const scfx_mant &)
Definition: scfx_mant.h:192
void inc(scfx_mant &mant)
Definition: scfx_mant.h:361