scfx_utils.hh revision 13197
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_utils.h - 23 24 Original Author: Martin Janssen, Synopsys, Inc. 25 26 *****************************************************************************/ 27 28/***************************************************************************** 29 30 MODIFICATION LOG - modifiers, enter your name, affiliation, date and 31 changes you are making here. 32 33 Name, Affiliation, Date: 34 Description of Modification: 35 36 *****************************************************************************/ 37 38// $Log: scfx_utils.h,v $ 39// Revision 1.2 2009/02/28 00:26:20 acg 40// Andy Goodrich: bug fixes. 41// 42// Revision 1.1.1.1 2006/12/15 20:31:36 acg 43// SystemC 2.2 44// 45// Revision 1.3 2006/01/13 18:53:58 acg 46// Andy Goodrich: added $Log command so that CVS comments are reproduced in 47// the source. 48// 49 50#ifndef __SYSTEMC_EXT_DT_FX_SCFX_UTILS_HH__ 51#define __SYSTEMC_EXT_DT_FX_SCFX_UTILS_HH__ 52 53#include "sc_fxdefs.hh" 54#include "scfx_params.hh" 55#include "scfx_string.hh" 56 57namespace sc_dt 58{ 59 60// ---------------------------------------------------------------------------- 61// Find the most and least significant non-zero bits in a unsigned long 62// ---------------------------------------------------------------------------- 63 64#define MSB_STATEMENT(n) if (x >> n) { x >>= n; i += n; } 65 66inline int 67scfx_find_msb(unsigned long x) 68{ 69 int i = 0; 70# if SC_LONG_64 71 MSB_STATEMENT(32); 72# endif // SC_LONG_64 73 MSB_STATEMENT(16); 74 MSB_STATEMENT(8); 75 MSB_STATEMENT(4); 76 MSB_STATEMENT(2); 77 MSB_STATEMENT(1); 78 return i; 79} 80 81#undef MSB_STATEMENT 82 83#define LSB_STATEMENT(n) if (x << n) { x <<= n; i -= n; } 84 85inline int 86scfx_find_lsb(unsigned long x) 87{ 88 int i; 89# if SC_LONG_64 90 i = 63; 91 LSB_STATEMENT(32); 92# else 93 i = 31; 94# endif // SC_LONG_64 95 LSB_STATEMENT(16); 96 LSB_STATEMENT(8); 97 LSB_STATEMENT(4); 98 LSB_STATEMENT(2); 99 LSB_STATEMENT(1); 100 return i; 101} 102 103#undef LSB_STATEMENT 104 105 106// ---------------------------------------------------------------------------- 107// Utilities for parsing a character string number 108// ---------------------------------------------------------------------------- 109 110inline int 111scfx_parse_sign(const char *&s, bool &sign_char) 112{ 113 int sign = 1; 114 115 if (*s == '+') { 116 ++s; 117 sign_char = true; 118 } else if (*s == '-' ) { 119 sign = -1; 120 ++s; 121 sign_char = true; 122 } else { 123 sign_char = false; 124 } 125 126 return sign; 127} 128 129inline sc_numrep 130scfx_parse_prefix(const char *&s) 131{ 132 if (s[0] == '0') { 133 switch (s[1]) { 134 case 'b': 135 case 'B': 136 { 137 if ((s[2] == 'u' || s[2] == 'U') && 138 (s[3] == 's' || s[3] == 'S')) { 139 s += 4; 140 return SC_BIN_US; 141 } 142 if ((s[2] == 's' || s[2] == 'S') && 143 (s[3] == 'm' || s[3] == 'M')) { 144 s += 4; 145 return SC_BIN_SM; 146 } 147 s += 2; 148 return SC_BIN; 149 } 150 case 'o': 151 case 'O': 152 { 153 if ((s[2] == 'u' || s[2] == 'U') && 154 (s[3] == 's' || s[3] == 'S')) { 155 s += 4; 156 return SC_OCT_US; 157 } 158 if ((s[2] == 's' || s[2] == 'S') && 159 (s[3] == 'm' || s[3] == 'M')) { 160 s += 4; 161 return SC_OCT_SM; 162 } 163 s += 2; 164 return SC_OCT; 165 } 166 case 'x': 167 case 'X': 168 { 169 if ((s[2] == 'u' || s[2] == 'U') && 170 (s[3] == 's' || s[3] == 'S')) { 171 s += 4; 172 return SC_HEX_US; 173 } 174 if ((s[2] == 's' || s[2] == 'S') && 175 (s[3] == 'm' || s[3] == 'M')) { 176 s += 4; 177 return SC_HEX_SM; 178 } 179 s += 2; 180 return SC_HEX; 181 } 182 case 'd': 183 case 'D': 184 { 185 s += 2; 186 return SC_DEC; 187 } 188 case 'c': 189 case 'C': 190 { 191 if ((s[2] == 's' || s[2] == 'S') && 192 (s[3] == 'd' || s[3] == 'D')) { 193 s += 4; 194 return SC_CSD; 195 } 196 break; 197 } 198 default: 199 break; 200 } 201 } 202 203 return SC_DEC; 204} 205 206inline int 207scfx_parse_base(const char *&s) 208{ 209 const char *s1 = s + 1; 210 211 int base = 10; 212 213 if (*s == '0') { 214 switch (*s1) { 215 case 'b': 216 case 'B': base = 2; s += 2; break; 217 case 'o': 218 case 'O': base = 8; s += 2; break; 219 case 'd': 220 case 'D': base = 10; s += 2; break; 221 case 'x': 222 case 'X': base = 16; s += 2; break; 223 } 224 } 225 226 return base; 227} 228 229inline bool 230scfx_is_equal(const char *a, const char *b) 231{ 232 while (*a != 0 && *b != 0 && *a == *b) { 233 ++ a; 234 ++ b; 235 } 236 return (*a == 0 && *b == 0); 237} 238 239inline bool 240scfx_is_nan(const char *s) 241{ 242 return scfx_is_equal(s, "NaN"); 243} 244 245inline bool 246scfx_is_inf(const char *s) 247{ 248 return (scfx_is_equal(s, "Inf") || scfx_is_equal(s, "Infinity")); 249} 250 251inline bool 252scfx_exp_start(const char *s) 253{ 254 if (*s == 'e' || *s == 'E') { 255 ++s; 256 if (*s == '+' || *s == '-') 257 return true; 258 } 259 return false; 260} 261 262inline bool 263scfx_is_digit(char c, sc_numrep numrep) 264{ 265 bool is_digit; 266 267 switch(numrep) { 268 case SC_DEC: 269 { 270 switch(c) { 271 case '0': case '1': case '2': case '3': case '4': 272 case '5': case '6': case '7': case '8': case '9': 273 { 274 is_digit = true; 275 break; 276 } 277 default: 278 is_digit = false; 279 } 280 break; 281 } 282 case SC_BIN: 283 case SC_BIN_US: 284 case SC_BIN_SM: 285 { 286 switch(c) { 287 case '0': case '1': 288 { 289 is_digit = true; 290 break; 291 } 292 default: 293 is_digit = false; 294 } 295 break; 296 } 297 case SC_OCT: 298 case SC_OCT_US: 299 case SC_OCT_SM: 300 { 301 switch(c) { 302 case '0': case '1': case '2': case '3': 303 case '4': case '5': case '6': case '7': 304 { 305 is_digit = true; 306 break; 307 } 308 default: 309 is_digit = false; 310 } 311 break; 312 } 313 case SC_HEX: 314 case SC_HEX_US: 315 case SC_HEX_SM: 316 { 317 switch (c) { 318 case '0': case '1': case '2': case '3': case '4': 319 case '5': case '6': case '7': case '8': case '9': 320 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': 321 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': 322 { 323 is_digit = true; 324 break; 325 } 326 default: 327 is_digit = false; 328 } 329 break; 330 } 331 case SC_CSD: 332 { 333 switch (c) { 334 case '0': case '1': case '-': 335 { 336 is_digit = true; 337 break; 338 } 339 default: 340 is_digit = false; 341 } 342 break; 343 } 344 default: 345 is_digit = false; 346 } 347 348 return is_digit; 349} 350 351inline int 352scfx_to_digit(char c, sc_numrep numrep) 353{ 354 int to_digit; 355 356 switch (numrep) { 357 case SC_DEC: 358 case SC_BIN: 359 case SC_BIN_US: 360 case SC_BIN_SM: 361 case SC_OCT: 362 case SC_OCT_US: 363 case SC_OCT_SM: 364 { 365 to_digit = c - '0'; 366 break; 367 } 368 case SC_HEX: 369 case SC_HEX_US: 370 case SC_HEX_SM: 371 { 372 switch (c) { 373 case '0': case '1': case '2': case '3': case '4': 374 case '5': case '6': case '7': case '8': case '9': 375 to_digit = c - '0'; 376 break; 377 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': 378 to_digit = c - 'a' + 10; 379 break; 380 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': 381 to_digit = c - 'A' + 10; 382 break; 383 default: 384 to_digit = -2; 385 } 386 break; 387 } 388 case SC_CSD: 389 { 390 if (c == '-') 391 to_digit = -1; 392 else 393 to_digit = c - '0'; 394 break; 395 } 396 default: 397 to_digit = -2; 398 } 399 400 return to_digit; 401} 402 403 404// ---------------------------------------------------------------------------- 405// Utilities for printing a character string number 406// ---------------------------------------------------------------------------- 407 408inline void scfx_print_nan(scfx_string &s) { s += "NaN"; } 409inline void 410scfx_print_inf(scfx_string &s, bool negative) 411{ 412 if (negative) 413 s += "-Inf"; 414 else 415 s += "Inf"; 416} 417 418inline void 419scfx_print_prefix(scfx_string &s, sc_numrep numrep) 420{ 421 switch (numrep) { 422 case SC_DEC: 423 s += "0d"; 424 break; 425 case SC_BIN: 426 s += "0b"; 427 break; 428 case SC_BIN_US: 429 s += "0bus"; 430 break; 431 case SC_BIN_SM: 432 s += "0bsm"; 433 break; 434 case SC_OCT: 435 s += "0o"; 436 break; 437 case SC_OCT_US: 438 s += "0ous"; 439 break; 440 case SC_OCT_SM: 441 s += "0osm"; 442 break; 443 case SC_HEX: 444 s += "0x"; 445 break; 446 case SC_HEX_US: 447 s += "0xus"; 448 break; 449 case SC_HEX_SM: 450 s += "0xsm"; 451 break; 452 case SC_CSD: 453 s += "0csd"; 454 break; 455 default: 456 s += "unknown"; 457 } 458} 459 460inline void 461scfx_print_exp(scfx_string &s, int exp) 462{ 463 if (exp != 0) { 464 s += 'e'; 465 466 if (exp < 0) { 467 exp = - exp; 468 s += '-'; 469 } else { 470 s += '+'; 471 } 472 473 bool first = true; 474 int scale = 1000000000; 475 do { 476 int digit = exp / scale; 477 exp = exp % scale; 478 if (digit != 0 || !first) { 479 s += static_cast<char>(digit + '0'); 480 first = false; 481 } 482 scale /= 10; 483 } 484 while (scale > 0); 485 } 486} 487 488void scfx_tc2csd(scfx_string &, int); 489void scfx_csd2tc(scfx_string &); 490 491} // namespace sc_dt 492 493#endif // __SYSTEMC_EXT_DT_FX_SCFX_UTILS_HH__ 494