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