SystemC  2.3.2
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 
57 #include "sysc/kernel/sc_macros.h"
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 
71 
79 {
80 
81  word* m_array;
82  int m_size;
83 
84 public:
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 
107 private:
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 
120 inline
121 int
123 {
124  return m_size;
125 }
126 
127 
128 inline
129 word*
130 scfx_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 
139 inline
140 void
141 scfx_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 
150 inline
151 word
152 scfx_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 
162 inline
163 word&
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 
174 inline
175 scfx_mant::scfx_mant( std::size_t size_ )
176 : m_array(0), m_size(size_)
177 {
178  m_array = alloc( size_ );
179 }
180 
181 inline
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 
192 inline
193 scfx_mant&
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 
212 inline
214 {
215  if( m_array != 0 )
216  {
217  free( m_array, m_size );
218  }
219 }
220 
221 inline
222 void
224 {
225  for( int i = 0; i < m_size; i ++ )
226  {
227  (*this)[i] = 0;
228  }
229 }
230 
231 inline
232 void
233 scfx_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 
303 inline
304 half_word
305 scfx_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 
316 inline
317 half_word&
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 
329 inline
330 half_word*
331 scfx_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 
346 inline
347 void
348 complement( 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 
361 inline
362 void
363 inc( 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 
382 {
383 
384  scfx_mant* m_mant;
385  bool m_not_const;
386 
387 public:
388 
389  scfx_mant_ref();
390  scfx_mant_ref( const scfx_mant& );
392 
395 
396  ~scfx_mant_ref();
397 
398  operator scfx_mant&();
399 
400  word operator [] ( int );
401 
402 private:
403 
404  void remove_it();
405 
406  scfx_mant_ref( const scfx_mant_ref& );
408 
409  void* operator new( std::size_t sz ) { return ::operator new( sz ); }
410 
411 };
412 
413 
414 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
415 
416 inline
417 void
418 scfx_mant_ref::remove_it()
419 {
420  if( m_not_const )
421  {
422  delete m_mant;
423  }
424 }
425 
426 inline
428 : m_mant( 0 ), m_not_const( false )
429 {}
430 
431 inline
433 : m_mant( const_cast<scfx_mant*>( &mant ) ), m_not_const( false )
434 {}
435 
436 inline
438 : m_mant( mant ), m_not_const( true )
439 {}
440 
441 inline
444 {
445  remove_it();
446 
447  m_mant = const_cast<scfx_mant*>( &mant );
448  m_not_const = false;
449 
450  return *this;
451 }
452 
453 inline
456 {
457  remove_it();
458 
459  m_mant = mant;
460  m_not_const = true;
461 
462  return *this;
463 }
464 
465 inline
467 {
468  remove_it();
469 }
470 
471 inline
472 scfx_mant_ref::operator scfx_mant&()
473 {
474  // SC_ASSERT_( m_not_const, "not allowed to modify mant" );
475  return *m_mant;
476 }
477 
478 inline
479 word
481 {
482  return (*m_mant)[i];
483 }
484 
485 } // namespace sc_dt
486 
487 
488 #endif
489 
490 // Taf!
unsigned short half_word
Definition: scfx_mant.h:69
half_word half_at(int) const
Definition: scfx_mant.h:305
const T sc_min(const T &a, const T &b)
Definition: sc_macros.h:43
void inc(scfx_mant &mant)
Definition: scfx_mant.h:363
Mantissa reference class.
Definition: scfx_mant.h:381
Mantissa class.
Definition: scfx_mant.h:78
void complement(scfx_mant &target, const scfx_mant &source, int size)
Definition: scfx_mant.h:348
Miscellaneous definitions that are needed by the headers.
half_word * half_addr(int=0) const
Definition: scfx_mant.h:331
word operator[](int) const
Definition: scfx_mant.h:152
int size() const
Definition: scfx_mant.h:122
word operator[](int)
Definition: scfx_mant.h:480
unsigned int word
Definition: scfx_mant.h:65
void resize_to(int, int=0)
Definition: scfx_mant.h:233
#define SC_ASSERT_(cnd, msg)
Definition: sc_fxdefs.h:263
scfx_mant & operator=(const scfx_mant &)
Definition: scfx_mant.h:194
scfx_mant_ref & operator=(const scfx_mant &)
Definition: scfx_mant.h:443
scfx_mant(std::size_t)
Definition: scfx_mant.h:175
#define SC_API
Definition: sc_cmnhdr.h:168