00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #ifndef SCFX_UTILS_H
00049 #define SCFX_UTILS_H
00050
00051
00052 #include "sysc/datatypes/fx/sc_fxdefs.h"
00053 #include "sysc/datatypes/fx/scfx_params.h"
00054 #include "sysc/datatypes/fx/scfx_string.h"
00055
00056
00057 namespace sc_dt
00058 {
00059
00060
00061
00062
00063
00064 #define MSB_STATEMENT(n) if( x >> n ) { x >>= n; i += n; }
00065
00066 inline
00067 int
00068 scfx_find_msb( unsigned long x )
00069 {
00070 int i = 0;
00071 # if defined(SC_LONG_64)
00072 MSB_STATEMENT( 32 );
00073 # endif // defined(SC_LONG_64)
00074 MSB_STATEMENT( 16 );
00075 MSB_STATEMENT( 8 );
00076 MSB_STATEMENT( 4 );
00077 MSB_STATEMENT( 2 );
00078 MSB_STATEMENT( 1 );
00079 return i;
00080 }
00081
00082 #undef MSB_STATEMENT
00083
00084 #define LSB_STATEMENT(n) if( x << n ) { x <<= n; i -= n; }
00085
00086 inline
00087 int
00088 scfx_find_lsb( unsigned long x )
00089 {
00090 int i;
00091 # if defined(SC_LONG_64)
00092 i = 63;
00093 LSB_STATEMENT( 32 );
00094 # else
00095 i = 31;
00096 # endif // defined(SC_LONG_64)
00097 LSB_STATEMENT( 16 );
00098 LSB_STATEMENT( 8 );
00099 LSB_STATEMENT( 4 );
00100 LSB_STATEMENT( 2 );
00101 LSB_STATEMENT( 1 );
00102 return i;
00103 }
00104
00105 #undef LSB_STATEMENT
00106
00107
00108
00109
00110
00111
00112 inline
00113 int
00114 scfx_parse_sign( const char*& s, bool& sign_char )
00115 {
00116 int sign = 1;
00117
00118 if( *s == '+' )
00119 {
00120 ++ s;
00121 sign_char = true;
00122 }
00123 else if( *s == '-' )
00124 {
00125 sign = -1;
00126 ++ s;
00127 sign_char = true;
00128 }
00129 else
00130 sign_char = false;
00131
00132 return sign;
00133 }
00134
00135 inline
00136 sc_numrep
00137 scfx_parse_prefix( const char*& s )
00138 {
00139 if( s[0] == '0' ) {
00140 switch( s[1] )
00141 {
00142 case 'b':
00143 case 'B':
00144 {
00145 if( (s[2] == 'u' || s[2] == 'U') && (s[3] == 's' || s[3] == 'S') ) {
00146 s += 4;
00147 return SC_BIN_US;
00148 }
00149 if( (s[2] == 's' || s[2] == 'S') && (s[3] == 'm' || s[3] == 'M') ) {
00150 s += 4;
00151 return SC_BIN_SM;
00152 }
00153 s += 2;
00154 return SC_BIN;
00155 }
00156 case 'o':
00157 case 'O':
00158 {
00159 if( (s[2] == 'u' || s[2] == 'U') && (s[3] == 's' || s[3] == 'S') ) {
00160 s += 4;
00161 return SC_OCT_US;
00162 }
00163 if( (s[2] == 's' || s[2] == 'S') && (s[3] == 'm' || s[3] == 'M') ) {
00164 s += 4;
00165 return SC_OCT_SM;
00166 }
00167 s += 2;
00168 return SC_OCT;
00169 }
00170 case 'x':
00171 case 'X':
00172 {
00173 if( (s[2] == 'u' || s[2] == 'U') && (s[3] == 's' || s[3] == 'S') ) {
00174 s += 4;
00175 return SC_HEX_US;
00176 }
00177 if( (s[2] == 's' || s[2] == 'S') && (s[3] == 'm' || s[3] == 'M') ) {
00178 s += 4;
00179 return SC_HEX_SM;
00180 }
00181 s += 2;
00182 return SC_HEX;
00183 }
00184 case 'd':
00185 case 'D':
00186 {
00187 s += 2;
00188 return SC_DEC;
00189 }
00190 case 'c':
00191 case 'C':
00192 {
00193 if( (s[2] == 's' || s[2] == 'S') && (s[3] == 'd' || s[3] == 'D') ) {
00194 s += 4;
00195 return SC_CSD;
00196 }
00197 break;
00198 }
00199 default:
00200 break;
00201 }
00202 }
00203
00204 return SC_DEC;
00205 }
00206
00207
00208 inline
00209 int
00210 scfx_parse_base( const char*& s )
00211 {
00212 const char* s1 = s + 1;
00213
00214 int base = 10;
00215
00216 if( *s == '0' )
00217 {
00218 switch( *s1 )
00219 {
00220 case 'b':
00221 case 'B': base = 2; s += 2; break;
00222 case 'o':
00223 case 'O': base = 8; s += 2; break;
00224 case 'd':
00225 case 'D': base = 10; s += 2; break;
00226 case 'x':
00227 case 'X': base = 16; s += 2; break;
00228 }
00229 }
00230
00231 return base;
00232 }
00233
00234 inline
00235 bool
00236 scfx_is_equal( const char* a, const char* b )
00237 {
00238 while( *a != 0 && *b != 0 && *a == *b )
00239 {
00240 ++ a;
00241 ++ b;
00242 }
00243 return ( *a == 0 && *b == 0 );
00244 }
00245
00246 inline
00247 bool
00248 scfx_is_nan( const char* s )
00249 {
00250 return scfx_is_equal( s, "NaN" );
00251 }
00252
00253 inline
00254 bool
00255 scfx_is_inf( const char* s )
00256 {
00257 return ( scfx_is_equal( s, "Inf" ) || scfx_is_equal( s, "Infinity" ) );
00258 }
00259
00260 inline
00261 bool
00262 scfx_exp_start( const char* s )
00263 {
00264 if( *s == 'e' || *s == 'E' )
00265 {
00266 ++ s;
00267 if( *s == '+' || *s == '-' )
00268 return true;
00269 }
00270 return false;
00271 }
00272
00273 inline
00274 bool
00275 scfx_is_digit( char c, sc_numrep numrep )
00276 {
00277 bool is_digit;
00278
00279 switch( numrep )
00280 {
00281 case SC_DEC:
00282 {
00283 switch( c )
00284 {
00285 case '0': case '1': case '2': case '3': case '4':
00286 case '5': case '6': case '7': case '8': case '9':
00287 {
00288 is_digit = true;
00289 break;
00290 }
00291 default:
00292 is_digit = false;
00293 }
00294 break;
00295 }
00296 case SC_BIN:
00297 case SC_BIN_US:
00298 case SC_BIN_SM:
00299 {
00300 switch( c )
00301 {
00302 case '0': case '1':
00303 {
00304 is_digit = true;
00305 break;
00306 }
00307 default:
00308 is_digit = false;
00309 }
00310 break;
00311 }
00312 case SC_OCT:
00313 case SC_OCT_US:
00314 case SC_OCT_SM:
00315 {
00316 switch( c )
00317 {
00318 case '0': case '1': case '2': case '3':
00319 case '4': case '5': case '6': case '7':
00320 {
00321 is_digit = true;
00322 break;
00323 }
00324 default:
00325 is_digit = false;
00326 }
00327 break;
00328 }
00329 case SC_HEX:
00330 case SC_HEX_US:
00331 case SC_HEX_SM:
00332 {
00333 switch( c )
00334 {
00335 case '0': case '1': case '2': case '3': case '4':
00336 case '5': case '6': case '7': case '8': case '9':
00337 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
00338 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
00339 {
00340 is_digit = true;
00341 break;
00342 }
00343 default:
00344 is_digit = false;
00345 }
00346 break;
00347 }
00348 case SC_CSD:
00349 {
00350 switch( c )
00351 {
00352 case '0': case '1': case '-':
00353 {
00354 is_digit = true;
00355 break;
00356 }
00357 default:
00358 is_digit = false;
00359 }
00360 break;
00361 }
00362 default:
00363 is_digit = false;
00364 }
00365
00366 return is_digit;
00367 }
00368
00369 inline
00370 int
00371 scfx_to_digit( char c, sc_numrep numrep )
00372 {
00373 int to_digit;
00374
00375 switch( numrep )
00376 {
00377 case SC_DEC:
00378 case SC_BIN:
00379 case SC_BIN_US:
00380 case SC_BIN_SM:
00381 case SC_OCT:
00382 case SC_OCT_US:
00383 case SC_OCT_SM:
00384 {
00385 to_digit = c - '0';
00386 break;
00387 }
00388 case SC_HEX:
00389 case SC_HEX_US:
00390 case SC_HEX_SM:
00391 {
00392 switch( c )
00393 {
00394 case '0': case '1': case '2': case '3': case '4':
00395 case '5': case '6': case '7': case '8': case '9':
00396 to_digit = c - '0';
00397 break;
00398 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
00399 to_digit = c - 'a' + 10;
00400 break;
00401 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
00402 to_digit = c - 'A' + 10;
00403 break;
00404 default:
00405 to_digit = -2;
00406 }
00407 break;
00408 }
00409 case SC_CSD:
00410 {
00411 if( c == '-' )
00412 to_digit = -1;
00413 else
00414 to_digit = c - '0';
00415 break;
00416 }
00417 default:
00418 to_digit = -2;
00419 }
00420
00421 return to_digit;
00422 }
00423
00424
00425
00426
00427
00428
00429 inline
00430 void
00431 scfx_print_nan( scfx_string& s )
00432 {
00433 s += "NaN";
00434 }
00435
00436 inline
00437 void
00438 scfx_print_inf( scfx_string& s, bool negative )
00439 {
00440 if( negative )
00441 s += "-Inf";
00442 else
00443 s += "Inf";
00444 }
00445
00446 inline
00447 void
00448 scfx_print_prefix( scfx_string& s, sc_numrep numrep )
00449 {
00450 switch( numrep )
00451 {
00452 case SC_DEC:
00453 s += "0d";
00454 break;
00455 case SC_BIN:
00456 s += "0b";
00457 break;
00458 case SC_BIN_US:
00459 s += "0bus";
00460 break;
00461 case SC_BIN_SM:
00462 s += "0bsm";
00463 break;
00464 case SC_OCT:
00465 s += "0o";
00466 break;
00467 case SC_OCT_US:
00468 s += "0ous";
00469 break;
00470 case SC_OCT_SM:
00471 s += "0osm";
00472 break;
00473 case SC_HEX:
00474 s += "0x";
00475 break;
00476 case SC_HEX_US:
00477 s += "0xus";
00478 break;
00479 case SC_HEX_SM:
00480 s += "0xsm";
00481 break;
00482 case SC_CSD:
00483 s += "0csd";
00484 break;
00485 default:
00486 s += "unknown";
00487 }
00488 }
00489
00490 inline
00491 void
00492 scfx_print_exp( scfx_string& s, int exp )
00493 {
00494 if( exp != 0 )
00495 {
00496 s += 'e';
00497
00498 if( exp < 0 )
00499 {
00500 exp = - exp;
00501 s += '-';
00502 }
00503 else
00504 s += '+';
00505
00506 bool first = true;
00507 int scale = 1000000000;
00508 do
00509 {
00510 int digit = exp / scale;
00511 exp = exp % scale;
00512 if( digit != 0 || ! first )
00513 {
00514 s += static_cast<char>( digit + '0' );
00515 first = false;
00516 }
00517 scale /= 10;
00518 }
00519 while( scale > 0 );
00520 }
00521 }
00522
00523
00524 void scfx_tc2csd( scfx_string&, int );
00525 void scfx_csd2tc( scfx_string& );
00526
00527 }
00528
00529
00530 #endif
00531
00532