SystemC  Recoding Infrastructure for SystemC v0.6.2 derived from Accellera 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 #include <pthread.h> // 08/03/2015 GL: to implement scfx_mant_free_words_lock
58 
59 
60 namespace sc_dt
61 {
62 
63 // classes defined in this module
64 class scfx_mant;
66 
67 
68 typedef unsigned int word; // Using int because of 64-bit machines.
69 typedef unsigned short half_word;
70 
74 // 08/03/2015 GL.
76  static pthread_mutex_t m_mutex;
77  explicit scfx_mant_free_words_lock();
79 };
80 
81 
82 // ----------------------------------------------------------------------------
83 // CLASS : scfx_mant
84 //
85 // Mantissa class.
86 // ----------------------------------------------------------------------------
87 
88 class scfx_mant
89 {
90 
91  word* m_array;
92  int m_size;
93 
94 public:
95 
96  explicit scfx_mant( std::size_t );
97  scfx_mant( const scfx_mant& );
98 
99  scfx_mant& operator = ( const scfx_mant& );
100 
101  ~scfx_mant();
102 
103  void clear();
104 
105  void resize_to( int, int = 0 );
106 
107  int size() const;
108 
109  word operator [] ( int ) const;
110  word& operator [] ( int );
111 
112  half_word half_at( int ) const;
113  half_word& half_at( int );
114 
115  half_word* half_addr( int = 0 ) const;
116 
117 private:
118 
119  static word* alloc( std::size_t );
120  static void free( word*, std::size_t );
121 
122  static word* alloc_word( std::size_t size );
123  static void free_word( word* array, std::size_t size );
124 
125 };
126 
127 
128 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
129 
130 inline
131 int
133 {
134  return m_size;
135 }
136 
137 
138 inline
139 word*
140 scfx_mant::alloc( std::size_t size )
141 {
142 #if defined( SC_BIG_ENDIAN )
143  return alloc_word( size ) + ( size - 1 );
144 #elif defined( SC_LITTLE_ENDIAN )
145  return alloc_word( size );
146 #endif
147 }
148 
149 inline
150 void
151 scfx_mant::free( word* mant, std::size_t size )
152 {
153 #if defined( SC_BIG_ENDIAN )
154  free_word( mant - ( size - 1 ), size );
155 #elif defined( SC_LITTLE_ENDIAN )
156  free_word( mant, size );
157 #endif
158 }
159 
160 inline
161 word
162 scfx_mant::operator[]( int i ) const
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 word&
175 {
176  SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" );
177 #if defined( SC_BIG_ENDIAN )
178  return m_array[-i];
179 #elif defined( SC_LITTLE_ENDIAN )
180  return m_array[i];
181 #endif
182 }
183 
184 inline
185 scfx_mant::scfx_mant( std::size_t size )
186 : m_array(0), m_size(size)
187 {
188  m_array = alloc( size );
189 }
190 
191 inline
193 : m_array(0), m_size(rhs.m_size)
194 {
195  m_array = alloc( m_size );
196  for( int i = 0; i < m_size; i ++ )
197  {
198  (*this)[i] = rhs[i];
199  }
200 }
201 
202 inline
203 scfx_mant&
205 {
206  if( &rhs != this )
207  {
208  if( m_size != rhs.m_size )
209  {
210  free( m_array, m_size );
211  m_array = alloc( m_size = rhs.m_size );
212  }
213 
214  for( int i = 0; i < m_size; i ++ )
215  {
216  (*this)[i] = rhs[i];
217  }
218  }
219  return *this;
220 }
221 
222 inline
224 {
225  if( m_array != 0 )
226  {
227  free( m_array, m_size );
228  }
229 }
230 
231 inline
232 void
234 {
235  for( int i = 0; i < m_size; i ++ )
236  {
237  (*this)[i] = 0;
238  }
239 }
240 
241 inline
242 void
243 scfx_mant::resize_to( int size, int restore )
244 {
245  if( size == m_size )
246  {
247  return;
248  }
249 
250  if( ! m_array )
251  {
252  m_array = alloc( m_size = size );
253  }
254  else
255  {
256  word* p = alloc( size );
257 
258  if( restore )
259  {
260  int end = sc_min( size, m_size );
261  if( restore == 1 ) // msb resized -> align at 0
262  {
263  for( int i = 0; i < size; i ++ )
264  {
265  if( i < end )
266  {
267 #if defined( SC_BIG_ENDIAN )
268  p[-i] = m_array[-i];
269 #elif defined( SC_LITTLE_ENDIAN )
270  p[i] = m_array[i];
271 #endif
272  }
273  else
274  {
275 #if defined( SC_BIG_ENDIAN )
276  p[-i] = 0;
277 #elif defined( SC_LITTLE_ENDIAN )
278  p[i] = 0;
279 #endif
280  }
281  }
282  }
283  else // lsb resized -> align at size-1
284  {
285  for( int i = 0; i < size; i ++ )
286  {
287  if( i < end )
288  {
289 #if defined( SC_BIG_ENDIAN )
290  p[-size+1+i] = m_array[-m_size+1+i];
291 #elif defined( SC_LITTLE_ENDIAN )
292  p[size-1-i] = m_array[m_size-1-i];
293 #endif
294  }
295  else
296  {
297 #if defined( SC_BIG_ENDIAN )
298  p[-size+1+i] = 0;
299 #elif defined( SC_LITTLE_ENDIAN )
300  p[size-1-i] = 0;
301 #endif
302  }
303  }
304  }
305  }
306 
307  free( m_array, m_size );
308  m_array = p;
309  m_size = size;
310  }
311 }
312 
313 inline
314 half_word
315 scfx_mant::half_at( int i ) const
316 {
317  SC_ASSERT_( ( i >> 1 ) >= 0 && ( i >> 1 ) < m_size,
318  "mantissa index out of range" );
319 #if defined( SC_BIG_ENDIAN )
320  return reinterpret_cast<half_word*>( m_array )[-i];
321 #elif defined( SC_LITTLE_ENDIAN )
322  return reinterpret_cast<half_word*>( m_array )[i];
323 #endif
324 }
325 
326 inline
327 half_word&
329 {
330  SC_ASSERT_( ( i >> 1 ) >= 0 && ( i >> 1 ) < m_size,
331  "mantissa index out of range" );
332 #if defined( SC_BIG_ENDIAN )
333  return reinterpret_cast<half_word*>( m_array )[-i];
334 #elif defined( SC_LITTLE_ENDIAN )
335  return reinterpret_cast<half_word*>( m_array )[i];
336 #endif
337 }
338 
339 inline
340 half_word*
341 scfx_mant::half_addr( int i ) const
342 {
343  SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" );
344 #if defined( SC_BIG_ENDIAN )
345  return reinterpret_cast<half_word*>( m_array - i ) + 1;
346 #elif defined( SC_LITTLE_ENDIAN )
347  return reinterpret_cast<half_word*>( m_array + i );
348 #endif
349 }
350 
351 
352 // ----------------------------------------------------------------------------
353 // one's complement of a mantissa
354 // ----------------------------------------------------------------------------
355 
356 inline
357 void
358 complement( scfx_mant& target, const scfx_mant& source, int size )
359 {
360  for( int i = 0; i < size; i ++ )
361  {
362  target[i] = ~source[i];
363  }
364 }
365 
366 
367 // ----------------------------------------------------------------------------
368 // increment mantissa
369 // ----------------------------------------------------------------------------
370 
371 inline
372 void
373 inc( scfx_mant& mant )
374 {
375  for( int i = 0; i < mant.size(); i ++ )
376  {
377  if( ++ mant[i] )
378  {
379  break;
380  }
381  }
382 }
383 
384 
385 // ----------------------------------------------------------------------------
386 // CLASS : scfx_mant_ref
387 //
388 // Mantissa reference class.
389 // ----------------------------------------------------------------------------
390 
392 {
393 
394  scfx_mant* m_mant;
395  bool m_not_const;
396 
397 public:
398 
399  scfx_mant_ref();
400  scfx_mant_ref( const scfx_mant& );
402 
405 
406  ~scfx_mant_ref();
407 
408  operator scfx_mant&();
409 
410  word operator [] ( int );
411 
412 private:
413 
414  void remove_it();
415 
416  scfx_mant_ref( const scfx_mant_ref& );
418 
419  void* operator new( std::size_t sz ) { return ::operator new( sz ); }
420 
421 };
422 
423 
424 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
425 
426 inline
427 void
428 scfx_mant_ref::remove_it()
429 {
430  if( m_not_const )
431  {
432  delete m_mant;
433  }
434 }
435 
436 inline
438 : m_mant( 0 ), m_not_const( false )
439 {}
440 
441 inline
443 : m_mant( const_cast<scfx_mant*>( &mant ) ), m_not_const( false )
444 {}
445 
446 inline
448 : m_mant( mant ), m_not_const( true )
449 {}
450 
451 inline
454 {
455  remove_it();
456 
457  m_mant = const_cast<scfx_mant*>( &mant );
458  m_not_const = false;
459 
460  return *this;
461 }
462 
463 inline
466 {
467  remove_it();
468 
469  m_mant = mant;
470  m_not_const = true;
471 
472  return *this;
473 }
474 
475 inline
477 {
478  remove_it();
479 }
480 
481 inline
482 scfx_mant_ref::operator scfx_mant&()
483 {
484  // SC_ASSERT_( m_not_const, "not allowed to modify mant" );
485  return *m_mant;
486 }
487 
488 inline
489 word
491 {
492  return (*m_mant)[i];
493 }
494 
495 } // namespace sc_dt
496 
497 
498 #endif
499 
500 // Taf!
void inc(scfx_mant &mant)
Definition: scfx_mant.h:373
#define SC_ASSERT_(cnd, msg)
Definition: sc_fxdefs.h:254
scfx_mant & operator=(const scfx_mant &)
Definition: scfx_mant.h:204
scfx_mant_ref & operator=(const scfx_mant &)
Definition: scfx_mant.h:453
word operator[](int) const
Definition: scfx_mant.h:162
int size() const
Definition: scfx_mant.h:132
static pthread_mutex_t m_mutex
Definition: scfx_mant.h:76
A scoped mutex for static word_list* free_words.
Definition: scfx_mant.h:75
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:341
unsigned int word
Definition: scfx_mant.h:65
scfx_mant(std::size_t)
Definition: scfx_mant.h:185
void resize_to(int, int=0)
Definition: scfx_mant.h:243
unsigned short half_word
Definition: scfx_mant.h:69
void complement(scfx_mant &target, const scfx_mant &source, int size)
Definition: scfx_mant.h:358
word operator[](int)
Definition: scfx_mant.h:490
half_word half_at(int) const
Definition: scfx_mant.h:315