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