Files
86Box/src/cpu/x87_ops_conv.h

70 lines
1.8 KiB
C
Raw Normal View History

2022-03-16 00:33:01 -03:00
#define BIAS80 16383
#define BIAS64 1023
typedef struct {
int16_t begin;
union {
2022-11-19 10:40:32 -05:00
double d;
2022-03-16 00:33:01 -03:00
uint64_t ll;
} eind;
} x87_conv_t;
2022-11-19 10:40:32 -05:00
static __inline double
x87_from80(x87_conv_t *test)
2022-03-16 00:33:01 -03:00
{
2022-11-19 10:40:32 -05:00
int64_t exp64;
int64_t blah;
int64_t exp64final;
int64_t mant64;
int64_t sign;
2022-03-16 00:33:01 -03:00
2022-11-19 10:40:32 -05:00
exp64 = (((test->begin & 0x7fff) - BIAS80));
blah = ((exp64 > 0) ? exp64 : -exp64) & 0x3ff;
exp64final = ((exp64 > 0) ? blah : -blah) + BIAS64;
2022-03-16 00:33:01 -03:00
2023-08-11 20:32:56 -04:00
mant64 = (test->eind.ll >> 11) & (0xfffffffffffffLL);
2022-11-19 10:40:32 -05:00
sign = (test->begin & 0x8000) ? 1 : 0;
2022-03-16 00:33:01 -03:00
2022-11-19 10:40:32 -05:00
if ((test->begin & 0x7fff) == 0x7fff)
exp64final = 0x7ff;
if ((test->begin & 0x7fff) == 0)
exp64final = 0;
if (test->eind.ll & 0x400)
mant64++;
2022-03-16 00:33:01 -03:00
2022-11-19 10:40:32 -05:00
test->eind.ll = (sign << 63) | (exp64final << 52) | mant64;
2022-03-16 00:33:01 -03:00
2022-11-19 10:40:32 -05:00
return test->eind.d;
2022-03-16 00:33:01 -03:00
}
2022-11-19 10:40:32 -05:00
static __inline void
x87_to80(double d, x87_conv_t *test)
2022-03-16 00:33:01 -03:00
{
2022-11-19 10:40:32 -05:00
int64_t sign80;
int64_t exp80;
int64_t exp80final;
int64_t mant80;
int64_t mant80final;
2022-03-16 00:33:01 -03:00
2022-11-19 10:40:32 -05:00
test->eind.d = d;
2022-03-16 00:33:01 -03:00
2023-08-11 20:32:56 -04:00
sign80 = (test->eind.ll & (0x8000000000000000LL)) ? 1 : 0;
exp80 = test->eind.ll & (0x7ff0000000000000LL);
2022-11-19 10:40:32 -05:00
exp80final = (exp80 >> 52);
2023-08-11 20:32:56 -04:00
mant80 = test->eind.ll & (0x000fffffffffffffLL);
2022-11-19 10:40:32 -05:00
mant80final = (mant80 << 11);
2022-03-16 00:33:01 -03:00
2022-11-19 10:40:32 -05:00
if (exp80final == 0x7ff) /*Infinity / Nan*/
{
exp80final = 0x7fff;
2023-08-11 20:32:56 -04:00
mant80final |= (0x8000000000000000LL);
2022-11-19 10:40:32 -05:00
} else if (d != 0) { /* Zero is a special case */
/* Elvira wants the 8 and tcalc doesn't */
2023-08-11 20:32:56 -04:00
mant80final |= (0x8000000000000000LL);
2022-11-19 10:40:32 -05:00
/* 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;
2022-03-16 00:33:01 -03:00
}