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