gem5  v20.1.0.0
scfx_mant.hh
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 __SYSTEMC_EXT_DT_FX_SCFX_MANT_HH__
52 #define __SYSTEMC_EXT_DT_FX_SCFX_MANT_HH__
53 
54 #include "../../utils/endian.hh"
55 #include "../../utils/functions.hh"
56 #include "scfx_ieee.hh"
57 #include "scfx_utils.hh"
58 
59 namespace sc_dt
60 {
61 
62 // classes defined in this module
63 class scfx_mant;
64 class scfx_mant_ref;
65 
66 typedef unsigned int word; // Using int because of 64-bit machines.
67 typedef unsigned short half_word;
68 
69 // ----------------------------------------------------------------------------
70 // CLASS : scfx_mant
71 //
72 // Mantissa class.
73 // ----------------------------------------------------------------------------
74 
75 class scfx_mant
76 {
77  word *m_array;
78  int m_size;
79 
80  public:
81  explicit scfx_mant(std::size_t);
82  scfx_mant(const scfx_mant &);
83 
85 
86  ~scfx_mant();
87 
88  void clear();
89 
90  void resize_to(int, int=0);
91 
92  int size() const;
93 
94  word operator [] (int) const;
95  word &operator [] (int);
96 
97  half_word half_at(int) const;
98  half_word &half_at(int);
99 
100  half_word *half_addr(int=0) const;
101 
102  private:
103  static word *alloc(std::size_t);
104  static void free(word *, std::size_t);
105 
106  static word *alloc_word(std::size_t size);
107  static void free_word(word *array, std::size_t size);
108 };
109 
110 
111 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
112 
113 inline int scfx_mant::size() const { return m_size; }
114 
115 inline word *
116 scfx_mant::alloc(std::size_t size)
117 {
118 #if defined(SC_BOOST_BIG_ENDIAN )
119  return alloc_word(size) + (size - 1);
120 #elif defined(SC_BOOST_LITTLE_ENDIAN)
121  return alloc_word(size);
122 #endif
123 }
124 
125 inline void
126 scfx_mant::free(word *mant, std::size_t size)
127 {
128 #if defined(SC_BOOST_BIG_ENDIAN)
129  free_word(mant - (size - 1), size);
130 #elif defined(SC_BOOST_LITTLE_ENDIAN)
131  free_word(mant, size);
132 #endif
133 }
134 
135 inline word
136 scfx_mant::operator [] (int i) const
137 {
138  SC_ASSERT_(i >= 0 && i < m_size, "mantissa index out of range");
139 #if defined(SC_BOOST_BIG_ENDIAN)
140  return m_array[-i];
141 #elif defined(SC_BOOST_LITTLE_ENDIAN)
142  return m_array[i];
143 #endif
144 }
145 
146 inline word &
148 {
149  SC_ASSERT_(i >= 0 && i < m_size, "mantissa index out of range");
150 #if defined(SC_BOOST_BIG_ENDIAN)
151  return m_array[-i];
152 #elif defined(SC_BOOST_LITTLE_ENDIAN)
153  return m_array[i];
154 #endif
155 }
156 
157 inline scfx_mant::scfx_mant(std::size_t size_) : m_array(0), m_size(size_)
158 {
159  m_array = alloc(size_);
160 }
161 
162 inline scfx_mant::scfx_mant(const scfx_mant &rhs) :
163  m_array(0), m_size(rhs.m_size)
164 {
165  m_array = alloc(m_size);
166  for (int i = 0; i < m_size; i++) {
167  (*this)[i] = rhs[i];
168  }
169 }
170 
171 inline scfx_mant &
172 scfx_mant::operator = (const scfx_mant &rhs)
173 {
174  if (&rhs != this) {
175  if (m_size != rhs.m_size) {
176  free(m_array, m_size);
177  m_array = alloc(m_size = rhs.m_size);
178  }
179 
180  for (int i = 0; i < m_size; i++) {
181  (*this)[i] = rhs[i];
182  }
183  }
184  return *this;
185 }
186 
187 inline scfx_mant::~scfx_mant()
188 {
189  if (m_array != 0) {
190  free(m_array, m_size);
191  }
192 }
193 
194 inline void
196 {
197  for (int i = 0; i < m_size; i++) {
198  (*this)[i] = 0;
199  }
200 }
201 
202 inline void
203 scfx_mant::resize_to(int size, int restore)
204 {
205  if (size == m_size) {
206  return;
207  }
208 
209  if (!m_array) {
210  m_array = alloc(m_size = size);
211  } else {
212  word* p = alloc(size);
213 
214  if (restore) {
215  int end = sc_min(size, m_size);
216  if (restore == 1) { // msb resized -> align at 0
217  for (int i = 0; i < size; i++) {
218  if (i < end) {
219 #if defined(SC_BOOST_BIG_ENDIAN)
220  p[-i] = m_array[-i];
221 #elif defined(SC_BOOST_LITTLE_ENDIAN)
222  p[i] = m_array[i];
223 #endif
224  } else {
225 #if defined(SC_BOOST_BIG_ENDIAN)
226  p[-i] = 0;
227 #elif defined(SC_BOOST_LITTLE_ENDIAN)
228  p[i] = 0;
229 #endif
230  }
231  }
232  } else { // lsb resized -> align at size - 1
233  for (int i = 0; i < size; i++) {
234  if (i < end) {
235 #if defined(SC_BOOST_BIG_ENDIAN)
236  p[-size + 1 + i] = m_array[-m_size + 1 + i];
237 #elif defined(SC_BOOST_LITTLE_ENDIAN)
238  p[size - 1 - i] = m_array[m_size - 1 - i];
239 #endif
240  } else {
241 #if defined(SC_BOOST_BIG_ENDIAN)
242  p[-size + 1 + i] = 0;
243 #elif defined(SC_BOOST_LITTLE_ENDIAN)
244  p[size - 1 - i] = 0;
245 #endif
246  }
247  }
248  }
249  }
250 
251  free(m_array, m_size);
252  m_array = p;
253  m_size = size;
254  }
255 }
256 
257 inline half_word
258 scfx_mant::half_at(int i) const
259 {
260  SC_ASSERT_((i >> 1) >= 0 && (i >> 1) < m_size,
261  "mantissa index out of range");
262 #if defined(SC_BOOST_BIG_ENDIAN)
263  return reinterpret_cast<half_word *>(m_array)[-i];
264 #elif defined(SC_BOOST_LITTLE_ENDIAN )
265  return reinterpret_cast<half_word *>(m_array)[i];
266 #endif
267 }
268 
269 inline half_word &
271 {
272  SC_ASSERT_((i >> 1) >= 0 && (i >> 1) < m_size,
273  "mantissa index out of range" );
274 #if defined(SC_BOOST_BIG_ENDIAN)
275  return reinterpret_cast<half_word *>(m_array)[-i];
276 #elif defined(SC_BOOST_LITTLE_ENDIAN)
277  return reinterpret_cast<half_word *>(m_array)[i];
278 #endif
279 }
280 
281 inline half_word *
282 scfx_mant::half_addr(int i) const
283 {
284  SC_ASSERT_(i >= 0 && i < m_size, "mantissa index out of range");
285 #if defined(SC_BOOST_BIG_ENDIAN)
286  return reinterpret_cast<half_word *>(m_array - i) + 1;
287 #elif defined(SC_BOOST_LITTLE_ENDIAN)
288  return reinterpret_cast<half_word *>(m_array + i);
289 #endif
290 }
291 
292 // ----------------------------------------------------------------------------
293 // one's complement of a mantissa
294 // ----------------------------------------------------------------------------
295 
296 inline void
297 complement(scfx_mant &target, const scfx_mant &source, int size)
298 {
299  for (int i = 0; i < size; i++) {
300  target[i] = ~source[i];
301  }
302 }
303 
304 // ----------------------------------------------------------------------------
305 // increment mantissa
306 // ----------------------------------------------------------------------------
307 
308 inline void
309 inc(scfx_mant &mant)
310 {
311  for (int i = 0; i < mant.size(); i++) {
312  if (++mant[i]) {
313  break;
314  }
315  }
316 }
317 
318 // ----------------------------------------------------------------------------
319 // CLASS : scfx_mant_ref
320 //
321 // Mantissa reference class.
322 // ----------------------------------------------------------------------------
323 
324 class scfx_mant_ref
325 {
326  scfx_mant *m_mant;
327  bool m_not_const;
328 
329  public:
330  scfx_mant_ref();
331  scfx_mant_ref(const scfx_mant &);
333 
336 
337  ~scfx_mant_ref();
338 
339  operator scfx_mant & ();
340 
342 
343  private:
344  void remove_it();
345 
346  scfx_mant_ref(const scfx_mant_ref &);
348 
349  void *operator new(std::size_t sz) { return ::operator new (sz); }
350 
351 };
352 
353 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
354 
355 inline void
357 {
358  if (m_not_const) {
359  delete m_mant;
360  }
361 }
362 
363 inline scfx_mant_ref::scfx_mant_ref() : m_mant(0), m_not_const(false) {}
364 
365 inline scfx_mant_ref::scfx_mant_ref(const scfx_mant &mant) :
366  m_mant(const_cast<scfx_mant *>(& mant)), m_not_const(false)
367 {}
368 
369 inline scfx_mant_ref::scfx_mant_ref(scfx_mant *mant) :
370  m_mant(mant), m_not_const(true)
371 {}
372 
373 inline scfx_mant_ref &
374 scfx_mant_ref::operator = (const scfx_mant &mant)
375 {
376  remove_it();
377 
378  m_mant = const_cast<scfx_mant *>(&mant);
379  m_not_const = false;
380 
381  return *this;
382 }
383 
384 inline scfx_mant_ref &
386 {
387  remove_it();
388 
389  m_mant = mant;
390  m_not_const = true;
391 
392  return *this;
393 }
394 
396 {
398 }
399 
400 inline scfx_mant_ref::operator scfx_mant & ()
401 {
402  // SC_ASSERT_(m_not_const, "not allowed to modify mant");
403  return *m_mant;
404 }
405 
406 inline word
408 {
409  return (*m_mant)[i];
410 }
411 
412 } // namespace sc_dt
413 
414 
415 #endif // __SYSTEMC_EXT_DT_FX_SCFX_MANT_HH__
sc_dt::scfx_mant::clear
void clear()
Definition: scfx_mant.hh:227
sc_dt::word
unsigned int word
Definition: scfx_mant.hh:96
sc_dt::scfx_mant_ref::m_mant
scfx_mant * m_mant
Definition: scfx_mant.hh:358
sc_dt::scfx_mant::scfx_mant
scfx_mant(std::size_t)
Definition: scfx_mant.hh:189
sc_dt::scfx_mant::size
int size() const
Definition: scfx_mant.hh:145
sc_dt
Definition: sc_bit.cc:67
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
sc_dt::scfx_mant::free
static void free(word *, std::size_t)
Definition: scfx_mant.hh:158
sc_dt::scfx_mant::alloc
static word * alloc(std::size_t)
Definition: scfx_mant.hh:148
sc_dt::scfx_mant_ref::remove_it
void remove_it()
Definition: scfx_mant.hh:388
sc_dt::inc
void inc(scfx_mant &mant)
Definition: scfx_mant.hh:341
sc_dt::scfx_mant_ref::scfx_mant_ref
scfx_mant_ref()
Definition: scfx_mant.hh:395
sc_dt::scfx_mant::~scfx_mant
~scfx_mant()
Definition: scfx_mant.hh:219
sc_dt::complement
void complement(scfx_mant &target, const scfx_mant &source, int size)
Definition: scfx_mant.hh:329
sc_dt::scfx_mant::m_size
int m_size
Definition: scfx_mant.hh:110
sc_dt::scfx_mant_ref::operator[]
word operator[](int)
Definition: scfx_mant.hh:439
sc_dt::scfx_mant::resize_to
void resize_to(int, int=0)
Definition: scfx_mant.hh:235
sc_dt::scfx_mant::free_word
static void free_word(word *array, std::size_t size)
Definition: scfx_mant.cc:138
sc_dt::scfx_mant_ref::operator=
scfx_mant_ref & operator=(const scfx_mant &)
Definition: scfx_mant.hh:406
sc_dt::scfx_mant::operator=
scfx_mant & operator=(const scfx_mant &)
Definition: scfx_mant.hh:204
sc_dt::scfx_mant
Definition: scfx_mant.hh:107
sc_dt::scfx_mant::m_array
word * m_array
Definition: scfx_mant.hh:109
sc_dt::half_word
unsigned short half_word
Definition: scfx_mant.hh:99
sc_dt::scfx_mant_ref::~scfx_mant_ref
~scfx_mant_ref()
Definition: scfx_mant.hh:427
sc_dt::sc_min
const T sc_min(const T &a, const T &b)
Definition: functions.hh:59
sc_dt::scfx_mant::operator[]
word operator[](int) const
Definition: scfx_mant.hh:168
scfx_utils.hh
sc_dt::scfx_mant::alloc_word
static word * alloc_word(std::size_t size)
Definition: scfx_mant.cc:114
sc_dt::scfx_mant::half_addr
half_word * half_addr(int=0) const
Definition: scfx_mant.hh:314
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
sc_dt::scfx_mant_ref
Definition: scfx_mant.hh:356
sc_dt::scfx_mant_ref::m_not_const
bool m_not_const
Definition: scfx_mant.hh:359
sc_dt::scfx_mant::half_at
half_word half_at(int) const
Definition: scfx_mant.hh:290
SC_ASSERT_
#define SC_ASSERT_(cnd, msg)
Definition: sc_fxdefs.hh:248
scfx_ieee.hh

Generated on Wed Sep 30 2020 14:02:15 for gem5 by doxygen 1.8.17