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 59namespace sc_dt 60{ 61 62// classes defined in this module 63class scfx_mant; 64class scfx_mant_ref; 65 66typedef unsigned int word; // Using int because of 64-bit machines. 67typedef unsigned short half_word; 68 69// ---------------------------------------------------------------------------- 70// CLASS : scfx_mant 71// 72// Mantissa class. 73// ---------------------------------------------------------------------------- 74 75class 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 84 scfx_mant &operator = (const scfx_mant &); 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 113inline int scfx_mant::size() const { return m_size; } 114 115inline word * 116scfx_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 125inline void 126scfx_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 135inline word 136scfx_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 146inline word & 147scfx_mant::operator [] (int i) 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 157inline scfx_mant::scfx_mant(std::size_t size_) : m_array(0), m_size(size_) 158{ 159 m_array = alloc(size_); 160} 161 162inline 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 171inline scfx_mant & 172scfx_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 187inline scfx_mant::~scfx_mant() 188{ 189 if (m_array != 0) { 190 free(m_array, m_size); 191 } 192} 193 194inline void 195scfx_mant::clear() 196{ 197 for (int i = 0; i < m_size; i++) { 198 (*this)[i] = 0; 199 } 200} 201 202inline void 203scfx_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 257inline half_word 258scfx_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 269inline half_word & 270scfx_mant::half_at(int i) 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 281inline half_word * 282scfx_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 296inline void 297complement(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 308inline void 309inc(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 324class 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 &); 332 scfx_mant_ref(scfx_mant *); 333 334 scfx_mant_ref &operator = (const scfx_mant &); 335 scfx_mant_ref &operator = (scfx_mant *); 336 337 ~scfx_mant_ref(); 338 339 operator scfx_mant & (); 340 341 word operator [] (int); 342 343 private: 344 void remove_it(); 345 346 scfx_mant_ref(const scfx_mant_ref &); 347 scfx_mant_ref &operator = (const scfx_mant_ref &); 348 349 void *operator new(std::size_t sz) { return ::operator new (sz); } 350 351}; 352 353// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 354 355inline void 356scfx_mant_ref::remove_it() 357{ 358 if (m_not_const) { 359 delete m_mant; 360 } 361} 362 363inline scfx_mant_ref::scfx_mant_ref() : m_mant(0), m_not_const(false) {} 364 365inline scfx_mant_ref::scfx_mant_ref(const scfx_mant &mant) : 366 m_mant(const_cast<scfx_mant *>(& mant)), m_not_const(false) 367{} 368 369inline scfx_mant_ref::scfx_mant_ref(scfx_mant *mant) : 370 m_mant(mant), m_not_const(true) 371{} 372 373inline scfx_mant_ref & 374scfx_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 384inline scfx_mant_ref & 385scfx_mant_ref::operator = (scfx_mant *mant) 386{ 387 remove_it(); 388 389 m_mant = mant; 390 m_not_const = true; 391 392 return *this; 393} 394 395inline scfx_mant_ref::~scfx_mant_ref() 396{ 397 remove_it(); 398} 399 400inline scfx_mant_ref::operator scfx_mant & () 401{ 402 // SC_ASSERT_(m_not_const, "not allowed to modify mant"); 403 return *m_mant; 404} 405 406inline word 407scfx_mant_ref::operator [] (int i) 408{ 409 return (*m_mant)[i]; 410} 411 412} // namespace sc_dt 413 414 415#endif // __SYSTEMC_EXT_DT_FX_SCFX_MANT_HH__ 416