#define BIAS80 16383 #define BIAS64 1023 typedef struct { int16_t begin; union { double d; uint64_t ll; } eind; } x87_conv_t; static __inline double x87_from80(x87_conv_t *test) { int64_t exp64; int64_t blah; int64_t exp64final; int64_t mant64; int64_t sign; exp64 = (((test->begin & 0x7fff) - BIAS80)); blah = ((exp64 > 0) ? exp64 : -exp64) & 0x3ff; exp64final = ((exp64 > 0) ? blah : -blah) + BIAS64; mant64 = (test->eind.ll >> 11) & (0xfffffffffffffLL); sign = (test->begin & 0x8000) ? 1 : 0; if ((test->begin & 0x7fff) == 0x7fff) exp64final = 0x7ff; if ((test->begin & 0x7fff) == 0) exp64final = 0; if (test->eind.ll & 0x400) mant64++; test->eind.ll = (sign << 63) | (exp64final << 52) | mant64; return test->eind.d; } static __inline void x87_to80(double d, x87_conv_t *test) { int64_t sign80; int64_t exp80; int64_t exp80final; int64_t mant80; int64_t mant80final; test->eind.d = d; sign80 = (test->eind.ll & (0x8000000000000000LL)) ? 1 : 0; exp80 = test->eind.ll & (0x7ff0000000000000LL); exp80final = (exp80 >> 52); mant80 = test->eind.ll & (0x000fffffffffffffLL); mant80final = (mant80 << 11); if (exp80final == 0x7ff) /*Infinity / Nan*/ { exp80final = 0x7fff; mant80final |= (0x8000000000000000LL); } else if (d != 0) { /* Zero is a special case */ /* Elvira wants the 8 and tcalc doesn't */ mant80final |= (0x8000000000000000LL); /* Ca-cyber doesn't like this when result is zero. */ exp80final += (BIAS80 - BIAS64); } test->begin = (((int16_t) sign80) << 15) | (int16_t) exp80final; test->eind.ll = mant80final; }