diff options
author | Gabe Black <gabeblack@google.com> | 2018-05-22 02:21:17 -0700 |
---|---|---|
committer | Gabe Black <gabeblack@google.com> | 2018-08-08 10:08:12 +0000 |
commit | 5ee040a534d422ee08918ef49d55620184df7120 (patch) | |
tree | 1688e050dec6abf1a36fc92070b151e6b0682fdd /src/systemc/ext/dt/fx/scfx_mant.hh | |
parent | 7adb1b250b712920ea5d685f146ad6df55346393 (diff) | |
download | gem5-5ee040a534d422ee08918ef49d55620184df7120.tar.xz |
Systemc: Port over all of the systemc "datatype" headers.
These are the headers originally written by Accellera with a few
modifications. Most significantly, I went through and mostly (but not
entirely) manually editted them to conform to gem5 style and to be
more self consistent. Second, I resolved some macros which optionally
select features. I removed support for deprecated functions, and
otherwise enabled everything.
The actual implementation behind these headers will also be ported
over, but in a subsequent change.
Change-Id: I203d3f6c8a3af9120b946001d01defbb0643a6b6
Reviewed-on: https://gem5-review.googlesource.com/10843
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
Diffstat (limited to 'src/systemc/ext/dt/fx/scfx_mant.hh')
-rw-r--r-- | src/systemc/ext/dt/fx/scfx_mant.hh | 415 |
1 files changed, 415 insertions, 0 deletions
diff --git a/src/systemc/ext/dt/fx/scfx_mant.hh b/src/systemc/ext/dt/fx/scfx_mant.hh new file mode 100644 index 000000000..ff2033ba9 --- /dev/null +++ b/src/systemc/ext/dt/fx/scfx_mant.hh @@ -0,0 +1,415 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_mant.h - + + Original Author: Robert Graulich, Synopsys, Inc. + Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: scfx_mant.h,v $ +// Revision 1.2 2011/08/24 22:05:43 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef __SYSTEMC_EXT_DT_FX_SCFX_MANT_HH__ +#define __SYSTEMC_EXT_DT_FX_SCFX_MANT_HH__ + +#include "../../utils/endian.hh" +#include "../../utils/functions.hh" +#include "scfx_ieee.hh" +#include "scfx_utils.hh" + +namespace sc_dt +{ + +// classes defined in this module +class scfx_mant; +class scfx_mant_ref; + +typedef unsigned int word; // Using int because of 64-bit machines. +typedef unsigned short half_word; + +// ---------------------------------------------------------------------------- +// CLASS : scfx_mant +// +// Mantissa class. +// ---------------------------------------------------------------------------- + +class scfx_mant +{ + word *m_array; + int m_size; + + public: + explicit scfx_mant(std::size_t); + scfx_mant(const scfx_mant &); + + scfx_mant &operator = (const scfx_mant &); + + ~scfx_mant(); + + void clear(); + + void resize_to(int, int=0); + + int size() const; + + word operator [] (int) const; + word &operator [] (int); + + half_word half_at(int) const; + half_word &half_at(int); + + half_word *half_addr(int=0) const; + + private: + static word *alloc(std::size_t); + static void free(word *, std::size_t); + + static word *alloc_word(std::size_t size); + static void free_word(word *array, std::size_t size); +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +inline int scfx_mant::size() const { return m_size; } + +inline word * +scfx_mant::alloc(std::size_t size) +{ +#if defined(SC_BOOST_BIG_ENDIAN ) + return alloc_word(size) + (size - 1); +#elif defined(SC_BOOST_LITTLE_ENDIAN) + return alloc_word(size); +#endif +} + +inline void +scfx_mant::free(word *mant, std::size_t size) +{ +#if defined(SC_BOOST_BIG_ENDIAN) + free_word(mant - (size - 1), size); +#elif defined(SC_BOOST_LITTLE_ENDIAN) + free_word(mant, size); +#endif +} + +inline word +scfx_mant::operator [] (int i) const +{ + SC_ASSERT_(i >= 0 && i < m_size, "mantissa index out of range"); +#if defined(SC_BOOST_BIG_ENDIAN) + return m_array[-i]; +#elif defined(SC_BOOST_LITTLE_ENDIAN) + return m_array[i]; +#endif +} + +inline word & +scfx_mant::operator [] (int i) +{ + SC_ASSERT_(i >= 0 && i < m_size, "mantissa index out of range"); +#if defined(SC_BOOST_BIG_ENDIAN) + return m_array[-i]; +#elif defined(SC_BOOST_LITTLE_ENDIAN) + return m_array[i]; +#endif +} + +inline scfx_mant::scfx_mant(std::size_t size_) : m_array(0), m_size(size_) +{ + m_array = alloc(size_); +} + +inline scfx_mant::scfx_mant(const scfx_mant &rhs) : + m_array(0), m_size(rhs.m_size) +{ + m_array = alloc(m_size); + for (int i = 0; i < m_size; i++) { + (*this)[i] = rhs[i]; + } +} + +inline scfx_mant & +scfx_mant::operator = (const scfx_mant &rhs) +{ + if (&rhs != this) { + if (m_size != rhs.m_size) { + free(m_array, m_size); + m_array = alloc(m_size = rhs.m_size); + } + + for (int i = 0; i < m_size; i++) { + (*this)[i] = rhs[i]; + } + } + return *this; +} + +inline scfx_mant::~scfx_mant() +{ + if (m_array != 0) { + free(m_array, m_size); + } +} + +inline void +scfx_mant::clear() +{ + for (int i = 0; i < m_size; i++) { + (*this)[i] = 0; + } +} + +inline void +scfx_mant::resize_to(int size, int restore) +{ + if (size == m_size) { + return; + } + + if (!m_array) { + m_array = alloc(m_size = size); + } else { + word* p = alloc(size); + + if (restore) { + int end = sc_min(size, m_size); + if (restore == 1) { // msb resized -> align at 0 + for (int i = 0; i < size; i++) { + if (i < end) { +#if defined(SC_BOOST_BIG_ENDIAN) + p[-i] = m_array[-i]; +#elif defined(SC_BOOST_LITTLE_ENDIAN) + p[i] = m_array[i]; +#endif + } else { +#if defined(SC_BOOST_BIG_ENDIAN) + p[-i] = 0; +#elif defined(SC_BOOST_LITTLE_ENDIAN) + p[i] = 0; +#endif + } + } + } else { // lsb resized -> align at size - 1 + for (int i = 0; i < size; i++) { + if (i < end) { +#if defined(SC_BOOST_BIG_ENDIAN) + p[-size + 1 + i] = m_array[-m_size + 1 + i]; +#elif defined(SC_BOOST_LITTLE_ENDIAN) + p[size - 1 - i] = m_array[m_size - 1 - i]; +#endif + } else { +#if defined(SC_BOOST_BIG_ENDIAN) + p[-size + 1 + i] = 0; +#elif defined(SC_BOOST_LITTLE_ENDIAN) + p[size - 1 - i] = 0; +#endif + } + } + } + } + + free(m_array, m_size); + m_array = p; + m_size = size; + } +} + +inline half_word +scfx_mant::half_at(int i) const +{ + SC_ASSERT_((i >> 1) >= 0 && (i >> 1) < m_size, + "mantissa index out of range"); +#if defined(SC_BOOST_BIG_ENDIAN) + return reinterpret_cast<half_word *>(m_array)[-i]; +#elif defined(SC_BOOST_LITTLE_ENDIAN ) + return reinterpret_cast<half_word *>(m_array)[i]; +#endif +} + +inline half_word & +scfx_mant::half_at(int i) +{ + SC_ASSERT_((i >> 1) >= 0 && (i >> 1) < m_size, + "mantissa index out of range" ); +#if defined(SC_BOOST_BIG_ENDIAN) + return reinterpret_cast<half_word *>(m_array)[-i]; +#elif defined(SC_BOOST_LITTLE_ENDIAN) + return reinterpret_cast<half_word *>(m_array)[i]; +#endif +} + +inline half_word * +scfx_mant::half_addr(int i) const +{ + SC_ASSERT_(i >= 0 && i < m_size, "mantissa index out of range"); +#if defined(SC_BOOST_BIG_ENDIAN) + return reinterpret_cast<half_word *>(m_array - i) + 1; +#elif defined(SC_BOOST_LITTLE_ENDIAN) + return reinterpret_cast<half_word *>(m_array + i); +#endif +} + +// ---------------------------------------------------------------------------- +// one's complement of a mantissa +// ---------------------------------------------------------------------------- + +inline void +complement(scfx_mant &target, const scfx_mant &source, int size) +{ + for (int i = 0; i < size; i++) { + target[i] = ~source[i]; + } +} + +// ---------------------------------------------------------------------------- +// increment mantissa +// ---------------------------------------------------------------------------- + +inline void +inc(scfx_mant &mant) +{ + for (int i = 0; i < mant.size(); i++) { + if (++mant[i]) { + break; + } + } +} + +// ---------------------------------------------------------------------------- +// CLASS : scfx_mant_ref +// +// Mantissa reference class. +// ---------------------------------------------------------------------------- + +class scfx_mant_ref +{ + scfx_mant *m_mant; + bool m_not_const; + + public: + scfx_mant_ref(); + scfx_mant_ref(const scfx_mant &); + scfx_mant_ref(scfx_mant *); + + scfx_mant_ref &operator = (const scfx_mant &); + scfx_mant_ref &operator = (scfx_mant *); + + ~scfx_mant_ref(); + + operator scfx_mant & (); + + word operator [] (int); + + private: + void remove_it(); + + scfx_mant_ref(const scfx_mant_ref &); + scfx_mant_ref &operator = (const scfx_mant_ref &); + + void *operator new(std::size_t sz) { return ::operator new (sz); } + +}; + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +inline void +scfx_mant_ref::remove_it() +{ + if (m_not_const) { + delete m_mant; + } +} + +inline scfx_mant_ref::scfx_mant_ref() : m_mant(0), m_not_const(false) {} + +inline scfx_mant_ref::scfx_mant_ref(const scfx_mant &mant) : + m_mant(const_cast<scfx_mant *>(& mant)), m_not_const(false) +{} + +inline scfx_mant_ref::scfx_mant_ref(scfx_mant *mant) : + m_mant(mant), m_not_const(true) +{} + +inline scfx_mant_ref & +scfx_mant_ref::operator = (const scfx_mant &mant) +{ + remove_it(); + + m_mant = const_cast<scfx_mant *>(&mant); + m_not_const = false; + + return *this; +} + +inline scfx_mant_ref & +scfx_mant_ref::operator = (scfx_mant *mant) +{ + remove_it(); + + m_mant = mant; + m_not_const = true; + + return *this; +} + +inline scfx_mant_ref::~scfx_mant_ref() +{ + remove_it(); +} + +inline scfx_mant_ref::operator scfx_mant & () +{ + // SC_ASSERT_(m_not_const, "not allowed to modify mant"); + return *m_mant; +} + +inline word +scfx_mant_ref::operator [] (int i) +{ + return (*m_mant)[i]; +} + +} // namespace sc_dt + + +#endif // __SYSTEMC_EXT_DT_FX_SCFX_MANT_HH__ |