| /***************************************************************************** | |
| 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_utils.h - | |
| Original Author: 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_utils.h,v $ | |
| // Revision 1.2 2009/02/28 00:26:20 acg | |
| // Andy Goodrich: bug fixes. | |
| // | |
| // Revision 1.1.1.1 2006/12/15 20:31:36 acg | |
| // SystemC 2.2 | |
| // | |
| // 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_UTILS_HH__ | |
| #define __SYSTEMC_EXT_DT_FX_SCFX_UTILS_HH__ | |
| #include "sc_fxdefs.hh" | |
| #include "scfx_params.hh" | |
| #include "scfx_string.hh" | |
| namespace sc_dt | |
| { | |
| // ---------------------------------------------------------------------------- | |
| // Find the most and least significant non-zero bits in a unsigned long | |
| // ---------------------------------------------------------------------------- | |
| #define MSB_STATEMENT(n) if (x >> n) { x >>= n; i += n; } | |
| inline int | |
| scfx_find_msb(unsigned long x) | |
| { | |
| int i = 0; | |
| # if SC_LONG_64 | |
| MSB_STATEMENT(32); | |
| # endif // SC_LONG_64 | |
| MSB_STATEMENT(16); | |
| MSB_STATEMENT(8); | |
| MSB_STATEMENT(4); | |
| MSB_STATEMENT(2); | |
| MSB_STATEMENT(1); | |
| return i; | |
| } | |
| #undef MSB_STATEMENT | |
| #define LSB_STATEMENT(n) if (x << n) { x <<= n; i -= n; } | |
| inline int | |
| scfx_find_lsb(unsigned long x) | |
| { | |
| int i; | |
| # if SC_LONG_64 | |
| i = 63; | |
| LSB_STATEMENT(32); | |
| # else | |
| i = 31; | |
| # endif // SC_LONG_64 | |
| LSB_STATEMENT(16); | |
| LSB_STATEMENT(8); | |
| LSB_STATEMENT(4); | |
| LSB_STATEMENT(2); | |
| LSB_STATEMENT(1); | |
| return i; | |
| } | |
| #undef LSB_STATEMENT | |
| // ---------------------------------------------------------------------------- | |
| // Utilities for parsing a character string number | |
| // ---------------------------------------------------------------------------- | |
| inline int | |
| scfx_parse_sign(const char *&s, bool &sign_char) | |
| { | |
| int sign = 1; | |
| if (*s == '+') { | |
| ++s; | |
| sign_char = true; | |
| } else if (*s == '-' ) { | |
| sign = -1; | |
| ++s; | |
| sign_char = true; | |
| } else { | |
| sign_char = false; | |
| } | |
| return sign; | |
| } | |
| inline sc_numrep | |
| scfx_parse_prefix(const char *&s) | |
| { | |
| if (s[0] == '0') { | |
| switch (s[1]) { | |
| case 'b': | |
| case 'B': | |
| { | |
| if ((s[2] == 'u' || s[2] == 'U') && | |
| (s[3] == 's' || s[3] == 'S')) { | |
| s += 4; | |
| return SC_BIN_US; | |
| } | |
| if ((s[2] == 's' || s[2] == 'S') && | |
| (s[3] == 'm' || s[3] == 'M')) { | |
| s += 4; | |
| return SC_BIN_SM; | |
| } | |
| s += 2; | |
| return SC_BIN; | |
| } | |
| case 'o': | |
| case 'O': | |
| { | |
| if ((s[2] == 'u' || s[2] == 'U') && | |
| (s[3] == 's' || s[3] == 'S')) { | |
| s += 4; | |
| return SC_OCT_US; | |
| } | |
| if ((s[2] == 's' || s[2] == 'S') && | |
| (s[3] == 'm' || s[3] == 'M')) { | |
| s += 4; | |
| return SC_OCT_SM; | |
| } | |
| s += 2; | |
| return SC_OCT; | |
| } | |
| case 'x': | |
| case 'X': | |
| { | |
| if ((s[2] == 'u' || s[2] == 'U') && | |
| (s[3] == 's' || s[3] == 'S')) { | |
| s += 4; | |
| return SC_HEX_US; | |
| } | |
| if ((s[2] == 's' || s[2] == 'S') && | |
| (s[3] == 'm' || s[3] == 'M')) { | |
| s += 4; | |
| return SC_HEX_SM; | |
| } | |
| s += 2; | |
| return SC_HEX; | |
| } | |
| case 'd': | |
| case 'D': | |
| { | |
| s += 2; | |
| return SC_DEC; | |
| } | |
| case 'c': | |
| case 'C': | |
| { | |
| if ((s[2] == 's' || s[2] == 'S') && | |
| (s[3] == 'd' || s[3] == 'D')) { | |
| s += 4; | |
| return SC_CSD; | |
| } | |
| break; | |
| } | |
| default: | |
| break; | |
| } | |
| } | |
| return SC_DEC; | |
| } | |
| inline int | |
| scfx_parse_base(const char *&s) | |
| { | |
| const char *s1 = s + 1; | |
| int base = 10; | |
| if (*s == '0') { | |
| switch (*s1) { | |
| case 'b': | |
| case 'B': base = 2; s += 2; break; | |
| case 'o': | |
| case 'O': base = 8; s += 2; break; | |
| case 'd': | |
| case 'D': base = 10; s += 2; break; | |
| case 'x': | |
| case 'X': base = 16; s += 2; break; | |
| } | |
| } | |
| return base; | |
| } | |
| inline bool | |
| scfx_is_equal(const char *a, const char *b) | |
| { | |
| while (*a != 0 && *b != 0 && *a == *b) { | |
| ++ a; | |
| ++ b; | |
| } | |
| return (*a == 0 && *b == 0); | |
| } | |
| inline bool | |
| scfx_is_nan(const char *s) | |
| { | |
| return scfx_is_equal(s, "NaN"); | |
| } | |
| inline bool | |
| scfx_is_inf(const char *s) | |
| { | |
| return (scfx_is_equal(s, "Inf") || scfx_is_equal(s, "Infinity")); | |
| } | |
| inline bool | |
| scfx_exp_start(const char *s) | |
| { | |
| if (*s == 'e' || *s == 'E') { | |
| ++s; | |
| if (*s == '+' || *s == '-') | |
| return true; | |
| } | |
| return false; | |
| } | |
| inline bool | |
| scfx_is_digit(char c, sc_numrep numrep) | |
| { | |
| bool is_digit; | |
| switch(numrep) { | |
| case SC_DEC: | |
| { | |
| switch(c) { | |
| case '0': case '1': case '2': case '3': case '4': | |
| case '5': case '6': case '7': case '8': case '9': | |
| { | |
| is_digit = true; | |
| break; | |
| } | |
| default: | |
| is_digit = false; | |
| } | |
| break; | |
| } | |
| case SC_BIN: | |
| case SC_BIN_US: | |
| case SC_BIN_SM: | |
| { | |
| switch(c) { | |
| case '0': case '1': | |
| { | |
| is_digit = true; | |
| break; | |
| } | |
| default: | |
| is_digit = false; | |
| } | |
| break; | |
| } | |
| case SC_OCT: | |
| case SC_OCT_US: | |
| case SC_OCT_SM: | |
| { | |
| switch(c) { | |
| case '0': case '1': case '2': case '3': | |
| case '4': case '5': case '6': case '7': | |
| { | |
| is_digit = true; | |
| break; | |
| } | |
| default: | |
| is_digit = false; | |
| } | |
| break; | |
| } | |
| case SC_HEX: | |
| case SC_HEX_US: | |
| case SC_HEX_SM: | |
| { | |
| switch (c) { | |
| case '0': case '1': case '2': case '3': case '4': | |
| case '5': case '6': case '7': case '8': case '9': | |
| case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': | |
| case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': | |
| { | |
| is_digit = true; | |
| break; | |
| } | |
| default: | |
| is_digit = false; | |
| } | |
| break; | |
| } | |
| case SC_CSD: | |
| { | |
| switch (c) { | |
| case '0': case '1': case '-': | |
| { | |
| is_digit = true; | |
| break; | |
| } | |
| default: | |
| is_digit = false; | |
| } | |
| break; | |
| } | |
| default: | |
| is_digit = false; | |
| } | |
| return is_digit; | |
| } | |
| inline int | |
| scfx_to_digit(char c, sc_numrep numrep) | |
| { | |
| int to_digit; | |
| switch (numrep) { | |
| case SC_DEC: | |
| case SC_BIN: | |
| case SC_BIN_US: | |
| case SC_BIN_SM: | |
| case SC_OCT: | |
| case SC_OCT_US: | |
| case SC_OCT_SM: | |
| { | |
| to_digit = c - '0'; | |
| break; | |
| } | |
| case SC_HEX: | |
| case SC_HEX_US: | |
| case SC_HEX_SM: | |
| { | |
| switch (c) { | |
| case '0': case '1': case '2': case '3': case '4': | |
| case '5': case '6': case '7': case '8': case '9': | |
| to_digit = c - '0'; | |
| break; | |
| case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': | |
| to_digit = c - 'a' + 10; | |
| break; | |
| case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': | |
| to_digit = c - 'A' + 10; | |
| break; | |
| default: | |
| to_digit = -2; | |
| } | |
| break; | |
| } | |
| case SC_CSD: | |
| { | |
| if (c == '-') | |
| to_digit = -1; | |
| else | |
| to_digit = c - '0'; | |
| break; | |
| } | |
| default: | |
| to_digit = -2; | |
| } | |
| return to_digit; | |
| } | |
| // ---------------------------------------------------------------------------- | |
| // Utilities for printing a character string number | |
| // ---------------------------------------------------------------------------- | |
| inline void scfx_print_nan(scfx_string &s) { s += "NaN"; } | |
| inline void | |
| scfx_print_inf(scfx_string &s, bool negative) | |
| { | |
| if (negative) | |
| s += "-Inf"; | |
| else | |
| s += "Inf"; | |
| } | |
| inline void | |
| scfx_print_prefix(scfx_string &s, sc_numrep numrep) | |
| { | |
| switch (numrep) { | |
| case SC_DEC: | |
| s += "0d"; | |
| break; | |
| case SC_BIN: | |
| s += "0b"; | |
| break; | |
| case SC_BIN_US: | |
| s += "0bus"; | |
| break; | |
| case SC_BIN_SM: | |
| s += "0bsm"; | |
| break; | |
| case SC_OCT: | |
| s += "0o"; | |
| break; | |
| case SC_OCT_US: | |
| s += "0ous"; | |
| break; | |
| case SC_OCT_SM: | |
| s += "0osm"; | |
| break; | |
| case SC_HEX: | |
| s += "0x"; | |
| break; | |
| case SC_HEX_US: | |
| s += "0xus"; | |
| break; | |
| case SC_HEX_SM: | |
| s += "0xsm"; | |
| break; | |
| case SC_CSD: | |
| s += "0csd"; | |
| break; | |
| default: | |
| s += "unknown"; | |
| } | |
| } | |
| inline void | |
| scfx_print_exp(scfx_string &s, int exp) | |
| { | |
| if (exp != 0) { | |
| s += 'e'; | |
| if (exp < 0) { | |
| exp = - exp; | |
| s += '-'; | |
| } else { | |
| s += '+'; | |
| } | |
| bool first = true; | |
| int scale = 1000000000; | |
| do { | |
| int digit = exp / scale; | |
| exp = exp % scale; | |
| if (digit != 0 || !first) { | |
| s += static_cast<char>(digit + '0'); | |
| first = false; | |
| } | |
| scale /= 10; | |
| } | |
| while (scale > 0); | |
| } | |
| } | |
| void scfx_tc2csd(scfx_string &, int); | |
| void scfx_csd2tc(scfx_string &); | |
| } // namespace sc_dt | |
| #endif // __SYSTEMC_EXT_DT_FX_SCFX_UTILS_HH__ |