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
00098 #include <math.h>
00099
00100
00101
00102 #define FLOAT_IS_IEEE 1
00103
00108 inline double f2host(u64 val)
00109 {
00110 int s = (val & U64(0x8000000000000000)) ? 1 : 0;
00111 int e = (int) ((val & U64(0x7ff0000000000000)) >> 52);
00112 s64 f = (val & U64(0x000fffffffffffff));
00113 f |= U64(0x0010000000000000);
00114
00115 double res;
00116
00117 if(e == 0)
00118 res = 0.0;
00119 else
00120 res = (s ? -1.0 : 1.0) * pow((double) 2.0, e - 1024) * ((double) f / (double) (s64) U64(0x0020000000000000));
00121
00122 #if defined(DEBUG_FP_CONVERSION)
00123 printf("f/g->host: %016"LL "x -> %f \n", val, res);
00124 #endif
00125 return res;
00126 }
00127
00128 #define g2host f2host
00129
00134 inline double d2host(u64 val)
00135 {
00136 int s = (val & U64(0x8000000000000000)) ? 1 : 0;
00137 int e = (int) ((val & U64(0x7f80000000000000)) >> 55);
00138 s64 f = (val & U64(0x007fffffffffffff));
00139 f |= U64(0x0080000000000000);
00140
00141 double res;
00142
00143 if(e == 0)
00144 res = 0.0;
00145 else
00146 res = (s ? -1.0 : 1.0) * pow((double) 2.0, e - 128) * ((double) f / (double) (s64) U64(0x0100000000000000));
00147
00148 #if defined(DEBUG_FP_CONVERSION)
00149 printf("d->host: %016"LL "x -> %f \n", val, res);
00150 #endif
00151 return res;
00152 }
00153
00158 inline double s2host(u64 val)
00159 {
00160 double res;
00161
00162 #if defined(FLOAT_IS_IEEE)
00163 if(sizeof(double) == 8)
00164 {
00165 union s2h_conv
00166 {
00167 u64 a;
00168 double b;
00169 } f_ieee;
00170 f_ieee.a = val;
00171 res = f_ieee.b;
00172 }
00173 else
00174 #endif
00175 {
00176 int s = (val & U64(0x8000000000000000)) ? 1 : 0;
00177 int e = (int) ((val & U64(0x7ff0000000000000)) >> 52);
00178 s64 f = (val & U64(0x000fffffffffffff));
00179
00180 if(e == 2047)
00181 {
00182 if(f)
00183 res = (s ? -0.0 : 0.0) / 0.0;
00184 else
00185 res = (s ? -1.0 : 1.0) / 0.0;
00186 }
00187 else if(e == 0)
00188 {
00189 if(f)
00190 res = (s ? -1.0 : 1.0) * ldexp((double) f / (double) ((s64) U64(0x10000000000000)),
00191 -1022);
00192 else
00193 res = (s ? -1.0 : 1.0) * 0.0;
00194 }
00195 else
00196 {
00197 res = (s ? -1.0 : 1.0) * ldexp(1.0 + ((double) f / (double) ((s64) U64(0x0010000000000000))),
00198 e - 1023);
00199 }
00200 }
00201
00202 #if defined(DEBUG_FP_CONVERSION)
00203 printf("s/t->host: %016"LL "x -> %f \n", val, res);
00204 #endif
00205 return res;
00206 }
00207
00208 #define t2host s2host
00209
00213 inline bool i_isnan(u64 val)
00214 {
00215 int e = (int) ((val & U64(0x7ff0000000000000)) >> 52);
00216 s64 f = (val & U64(0x000fffffffffffff));
00217
00218 return(e == 2047) && f;
00219 }
00220
00225 inline u64 host2f(double val)
00226 {
00227 double fr;
00228 double v = val;
00229 int s = (v < 0.0) ? 1 : 0;
00230 if(s)
00231 v *= -1.0;
00232
00233 int e = (int) (log((double) v) / log((double) 2.0));
00234 bool exp_down = true;
00235
00236 if(val == 0.0)
00237 return 0;
00238
00239 fr = v / pow((double) 2.0, e);
00240
00241 while((fr >= 1.0 && e < 127) || e < -127)
00242 {
00243 e++;
00244 exp_down = false;
00245 fr = v / pow((double) 2.0, e);
00246 }
00247
00248 while(((fr < 0.5 && e > -127) || e > 127) && exp_down)
00249 {
00250 e--;
00251 fr = v / pow((double) 2.0, e);
00252 }
00253
00254 e += 1024;
00255
00256 u64 f = (u64) (fr * (double) U64(0x0020000000000000) + 0.5);
00257
00258 f = (s ? U64(0x8000000000000000) : 0) | (((u64) e << 52) & U64(0x7ff0000000000000)) | (f & U64(0x000fffffe0000000));
00259
00260 #if defined(DEBUG_FP_CONVERSION)
00261 printf("host->f: %f -> %016"LL "x \n", val, f);
00262 #endif
00263 return f;
00264 }
00265
00270 inline u64 host2g(double val)
00271 {
00272 double fr;
00273 double v = val;
00274 int s = (v < 0.0) ? 1 : 0;
00275 if(s)
00276 v *= -1.0;
00277
00278 int e = (int) (log((double) v) / log((double) 2.0));
00279 bool exp_down = true;
00280
00281 if(val == 0.0)
00282 return 0;
00283
00284 fr = v / pow((double) 2.0, e);
00285
00286 while((fr >= 1.0 && e < 1023) || e < -1023)
00287 {
00288 e++;
00289 exp_down = false;
00290 fr = v / pow((double) 2.0, e);
00291 }
00292
00293 while(((fr < 0.5 && e > -1023) || e > 1023) && exp_down)
00294 {
00295 e--;
00296 fr = v / pow((double) 2.0, e);
00297 }
00298
00299 e += 1024;
00300
00301 u64 f = (u64) (fr * (double) U64(0x0020000000000000) + 0.5);
00302
00303 f = (s ? U64(0x8000000000000000) : 0) | (((u64) e << 52) & U64(0x7ff0000000000000)) | (f & U64(0x000fffffffffffff));
00304
00305 #if defined(DEBUG_FP_CONVERSION)
00306 printf("host->g: %f -> %016"LL "x \n", val, f);
00307 #endif
00308 return f;
00309 }
00310
00315 inline u64 host2d(double val)
00316 {
00317 double fr;
00318 double v = val;
00319 int s = (v < 0.0) ? 1 : 0;
00320 if(s)
00321 v *= -1.0;
00322
00323 int e = (int) (log((double) v) / log((double) 2.0));
00324 bool exp_down = true;
00325
00326 if(val == 0.0)
00327 return 0;
00328
00329 fr = v / pow((double) 2.0, e);
00330
00331 while((fr >= 1.0 && e < 127) || e < -127)
00332 {
00333 e++;
00334 exp_down = false;
00335 fr = v / pow((double) 2.0, e);
00336 }
00337
00338 while(((fr < 0.5 && e > -127) || e > 127) && exp_down)
00339 {
00340 e--;
00341 fr = v / pow((double) 2.0, e);
00342 }
00343
00344 e += 128;
00345
00346 u64 f = (u64) (fr * (double) U64(0x0100000000000000) + 0.5);
00347
00348 f = (s ? U64(0x8000000000000000) : 0) | (((u64) e << 55) & U64(0x7f80000000000000)) | (f & U64(0x007fffffffffffff));
00349
00350 #if defined(DEBUG_FP_CONVERSION)
00351 printf("host->d: %f -> %016"LL "x \n", val, f);
00352 #endif
00353 return f;
00354 }
00355
00359 inline u32 map_s(u32 val)
00360 {
00361 if(val == 0)
00362 return 0;
00363 else if(val == 0xff)
00364 return 0x7ff;
00365 else if(val & 0x80)
00366 return(val & 0x7f) | 0x400;
00367 else
00368 return(val & 0x7f) | 0x380;
00369 }
00370
00375 inline u64 host2s(double val)
00376 {
00377 u64 f;
00378 int s;
00379 int e;
00380 #if defined(FLOAT_IS_IEEE)
00381 if(sizeof(float) == 4)
00382 {
00383 union h2s_conv
00384 {
00385 u32 a;
00386 float b;
00387 } f_ieee;
00388 f_ieee.b = (float) val;
00389 s = (f_ieee.a >> 31) & 1;
00390 e = (f_ieee.a >> 23) & 0xff;
00391 f = (u64) (f_ieee.a >> 0 & 0x7fffff) << 29;
00392 }
00393 else
00394 #endif
00395 {
00396 double v = val;
00397 s = (v < 0.0) ? 1 : 0;
00398 if(s)
00399 v *= -1.0;
00400 e = (int) (log((double) v) / log((double) 2.0));
00401
00402 double fr;
00403 bool exp_down = true;
00404
00405 if(val == 0.0)
00406 return 0;
00407
00408 fr = v / pow((double) 2.0, e);
00409
00410 while((fr >= 2.0 && e < 127) || e < -127)
00411 {
00412 e++;
00413 exp_down = false;
00414 fr = v / pow((double) 2.0, e);
00415 }
00416
00417 while(((fr < 1.0 && e > -127) || e > 127) && exp_down)
00418 {
00419 e--;
00420 fr = v / pow((double) 2.0, e);
00421 }
00422
00423 e += 255;
00424
00425 if(e == 0)
00426 fr = v / pow((double) 2.0, -126);
00427
00428 f = (u64) (fr * (double) U64(0x0010000000000000) + 0.5);
00429 }
00430
00431 e = map_s(e);
00432
00433 f = (s ? U64(0x800000000000000) : 0) | (((u64) e << 52) & U64(0x7ff0000000000000)) | (f & U64(0x000fffffe0000000));
00434
00435 #if defined(DEBUG_FP_CONVERSION)
00436 printf("host->s: %f -> %016"LL "x \n", val, f);
00437 #endif
00438 return f;
00439 }
00440
00445 inline u64 host2t(double val)
00446 {
00447 u64 f;
00448 #if defined(FLOAT_IS_IEEE)
00449 if(sizeof(double) == 8)
00450 {
00451 union h2t_conv
00452 {
00453 u64 a;
00454 double b;
00455 } f_ieee;
00456 f_ieee.b = val;
00457 f = f_ieee.a;
00458 }
00459 else
00460 #endif
00461 {
00462 double v = val;
00463 int s = (v < 0.0) ? 1 : 0;
00464 if(s)
00465 v *= -1.0;
00466
00467 int e = (int) (log((double) v) / log((double) 2.0));
00468 double fr;
00469 bool exp_down = true;
00470
00471 if(val == 0.0)
00472 return 0;
00473
00474 fr = v / pow((double) 2.0, e);
00475
00476 while((fr >= 2.0 && e < 1023) || e < -1023)
00477 {
00478 e++;
00479 exp_down = false;
00480 fr = v / pow((double) 2.0, e);
00481 }
00482
00483 while(((fr < 1.0 && e > -1023) || e > 1023) && exp_down)
00484 {
00485 e--;
00486 fr = v / pow((double) 2.0, e);
00487 }
00488
00489 e += 1023;
00490
00491 if(e == 0)
00492 fr = v / pow((double) 2.0, -1022);
00493
00494 f = (u64) (fr * (double) U64(0x0010000000000000) + 0.5);
00495
00496 f = (s ? U64(0x800000000000000) : 0) |
00497 (((u64) e << 52) & U64(0x7ff0000000000000)) |
00498 (f & U64(0x000fffffffffffff));
00499 }
00500
00501 #if defined(DEBUG_FP_CONVERSION)
00502 printf("host->t: %f -> %016"LL "x \n", val, f);
00503 #endif
00504 return f;
00505 }
00506
00511 inline u32 store_f(u64 val)
00512 {
00513 u64 retval = (val & U64(0x00001fffe0000000)) >> 13;
00514 retval |= (val & U64(0xc000000000000000)) >> 48;
00515 retval |= (val & U64(0x07ffe00000000000)) >> 45;
00516
00517 #if defined(DEBUG_FP_LOADSTORE)
00518 printf("f->mem: %016"LL "x -> %08x \n", val, retval);
00519 #endif
00520 return(u32) retval;
00521 }
00522
00527 inline u64 store_g(u64 val)
00528 {
00529 u64 retval = (val >> 48) & U64(0x000000000000ffff);
00530 retval |= (val >> 16) & U64(0x00000000ffff0000);
00531 retval |= (val << 48) & U64(0xffff000000000000);
00532 retval |= (val << 16) & U64(0x0000ffff00000000);
00533
00534 #if defined(DEBUG_FP_LOADSTORE)
00535 printf("g->mem: %016"LL "x -> %016"LL "x \n", val, retval);
00536 #endif
00537 return retval;
00538 }
00539
00544 inline u64 load_f(u32 val)
00545 {
00546 u64 retval = (u64) (val & 0xffff0000) << 13;
00547 retval |= (u64) (val & 0x0000c000) << 48;
00548 retval |= (u64) (val & 0x00003fff) << 45;
00549 if(((val & 0x00004000) == 0) && ((val & 0x00003f80) != 0))
00550 retval |= U64(0x3800000000000000);
00551
00552 #if defined(DEBUG_FP_LOADSTORE)
00553 printf("mem->f: %08x -> %016"LL "x \n", val, retval);
00554 #endif
00555 return retval;
00556 }
00557
00562 inline u64 itof_f(u64 val)
00563 {
00564 u64 retval = (val & U64(0x3fffffff)) << 29;
00565 retval |= (val & U64(0xc0000000)) << 32;
00566 if(((val & U64(0x40000000)) == 0) && ((val & U64(0x3f800000)) != 0))
00567 retval |= U64(0x3800000000000000);
00568
00569 #if defined(DEBUG_FP_LOADSTORE)
00570 printf("reg->f: %08x -> %016"LL "x \n", val, retval);
00571 #endif
00572 return retval;
00573 }
00574
00579 inline u64 load_g(u64 val)
00580 {
00581 u64 retval = (val & U64(0x000000000000ffff)) << 48;
00582 retval |= (val & U64(0x00000000ffff0000)) << 16;
00583 retval |= (val & U64(0x0000ffff00000000)) >> 16;
00584 retval |= (val & U64(0xffff000000000000)) >> 48;
00585
00586 #if defined(DEBUG_FP_LOADSTORE)
00587 printf("mem->g: %016"LL "x -> %016"LL "x \n", val, retval);
00588 #endif
00589 return retval;
00590 }
00591
00596 inline u64 load_s(u32 val)
00597 {
00598 return((val & U64(0x80000000)) << 32)
00599 | ((u64) map_s((val >> 23) & 0xff) << 52)
00600 | ((val & U64(0x7fffff)) << 29);
00601 }
00602
00607 inline u32 store_s(u64 val)
00608 {
00609 return((u32) (val >> 32) & 0xc0000000) | ((u32) (val >> 29) & 0x3fffffff);
00610 }