scfx_mant.hh revision 12853
16145SN/A/***************************************************************************** 26145SN/A 36145SN/A Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 46145SN/A more contributor license agreements. See the NOTICE file distributed 56145SN/A with this work for additional information regarding copyright ownership. 66145SN/A Accellera licenses this file to you under the Apache License, Version 2.0 76145SN/A (the "License"); you may not use this file except in compliance with the 86145SN/A License. You may obtain a copy of the License at 96145SN/A 106145SN/A http://www.apache.org/licenses/LICENSE-2.0 116145SN/A 126145SN/A Unless required by applicable law or agreed to in writing, software 136145SN/A distributed under the License is distributed on an "AS IS" BASIS, 146145SN/A WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 156145SN/A implied. See the License for the specific language governing 166145SN/A permissions and limitations under the License. 176145SN/A 186145SN/A *****************************************************************************/ 196145SN/A 206145SN/A/***************************************************************************** 216145SN/A 226145SN/A scfx_mant.h - 236145SN/A 246145SN/A Original Author: Robert Graulich, Synopsys, Inc. 256145SN/A Martin Janssen, Synopsys, Inc. 266145SN/A 276145SN/A *****************************************************************************/ 286145SN/A 2910441Snilay@cs.wisc.edu/***************************************************************************** 3010441Snilay@cs.wisc.edu 316145SN/A MODIFICATION LOG - modifiers, enter your name, affiliation, date and 327055SN/A changes you are making here. 337055SN/A 347455SN/A Name, Affiliation, Date: 356154SN/A Description of Modification: 366145SN/A 376145SN/A *****************************************************************************/ 387039SN/A 397039SN/A// $Log: scfx_mant.h,v $ 407039SN/A// Revision 1.2 2011/08/24 22:05:43 acg 417039SN/A// Torsten Maehne: initialization changes to remove warnings. 427039SN/A// 437039SN/A// Revision 1.1.1.1 2006/12/15 20:20:04 acg 447039SN/A// SystemC 2.3 456145SN/A// 467039SN/A// Revision 1.3 2006/01/13 18:53:58 acg 477039SN/A// Andy Goodrich: added $Log command so that CVS comments are reproduced in 487039SN/A// the source. 497039SN/A// 507039SN/A 517039SN/A#ifndef __SYSTEMC_EXT_DT_FX_SCFX_MANT_HH__ 527039SN/A#define __SYSTEMC_EXT_DT_FX_SCFX_MANT_HH__ 537039SN/A 546145SN/A#include "../../utils/endian.hh" 557839SN/A#include "../../utils/functions.hh" 566145SN/A#include "scfx_ieee.hh" 577039SN/A#include "scfx_utils.hh" 587055SN/A 596145SN/Anamespace sc_dt 607039SN/A{ 617039SN/A 627039SN/A// classes defined in this module 637039SN/Aclass scfx_mant; 646145SN/Aclass scfx_mant_ref; 657039SN/A 667455SN/Atypedef unsigned int word; // Using int because of 64-bit machines. 676145SN/Atypedef unsigned short half_word; 687039SN/A 697039SN/A// ---------------------------------------------------------------------------- 706145SN/A// CLASS : scfx_mant 716145SN/A// 726145SN/A// Mantissa class. 737055SN/A// ---------------------------------------------------------------------------- 747055SN/A 756145SN/Aclass scfx_mant 767039SN/A{ 777055SN/A word *m_array; 787039SN/A int m_size; 796145SN/A 806145SN/A public: 816145SN/A explicit scfx_mant(std::size_t); 827039SN/A scfx_mant(const scfx_mant &); 837039SN/A 846145SN/A scfx_mant &operator = (const scfx_mant &); 857039SN/A 867039SN/A ~scfx_mant(); 877455SN/A 886145SN/A void clear(); 896145SN/A 906145SN/A void resize_to(int, int=0); 917039SN/A 927039SN/A int size() const; 936145SN/A 947455SN/A word operator [] (int) const; 957039SN/A word &operator [] (int); 967455SN/A 977039SN/A half_word half_at(int) const; 987039SN/A half_word &half_at(int); 997039SN/A 1007039SN/A half_word *half_addr(int=0) const; 1017039SN/A 1027039SN/A private: 1037455SN/A static word *alloc(std::size_t); 1047039SN/A static void free(word *, std::size_t); 1057039SN/A 1066145SN/A static word *alloc_word(std::size_t size); 1076145SN/A static void free_word(word *array, std::size_t size); 1086145SN/A}; 1096145SN/A 1107839SN/A 1117039SN/A// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1126145SN/A 1137839SN/Ainline int scfx_mant::size() const { return m_size; } 1147839SN/A 1156145SN/Ainline word * 1166145SN/Ascfx_mant::alloc(std::size_t size) 1176145SN/A{ 1186145SN/A#if defined(SC_BOOST_BIG_ENDIAN ) 1197039SN/A return alloc_word(size) + (size - 1); 1207055SN/A#elif defined(SC_BOOST_LITTLE_ENDIAN) 1216145SN/A return alloc_word(size); 1226145SN/A#endif 1236145SN/A} 12410441Snilay@cs.wisc.edu 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