#include "lint.h"
#include "base_conversion.h"
#define HEXVAL(c) (('0' <= c && c <= '9')? c - '0' : \
10 + (('a' <= c && c <= 'f')? c - 'a' : c - 'A'))
static void
__hex_to_unpacked(decimal_record *pd, unpacked *pu)
{
int i, n;
pu->sign = pd->sign;
pu->fpclass = pd->fpclass;
pu->exponent = pd->exponent + (pd->ndigits << 2) - 1;
for (i = 0; i < 5; i++)
pu->significand[i] = 0;
n = pd->ndigits;
if (n > 30)
n = 30;
for (i = 0; i < n; i++) {
pu->significand[i >> 3] |= HEXVAL(pd->ds[i]) <<
((7 - (i & 7)) << 2);
}
if (pu->significand[0] == 0) {
pu->fpclass = fp_zero;
return;
}
while (pu->significand[0] < 0x80000000u) {
pu->significand[0] = (pu->significand[0] << 1) |
(pu->significand[1] >> 31);
pu->significand[1] = (pu->significand[1] << 1) |
(pu->significand[2] >> 31);
pu->significand[2] = (pu->significand[2] << 1) |
(pu->significand[3] >> 31);
pu->significand[3] <<= 1;
pu->exponent--;
}
if (pd->ndigits > 30 || pd->more)
pu->significand[4] = 1;
}
void
__hex_to_single(decimal_record *pd, enum fp_direction_type rd, single *px,
fp_exception_field_type *ps)
{
single_equivalence kluge;
unpacked u;
*ps = 0;
if (pd->fpclass == fp_zero) {
kluge.f.msw.sign = pd->sign? 1 : 0;
kluge.f.msw.exponent = 0;
kluge.f.msw.significand = 0;
*px = kluge.x;
} else {
__hex_to_unpacked(pd, &u);
__pack_single(&u, px, rd, ps);
if (*ps != 0)
__base_conversion_set_exception(*ps);
}
}
void
__hex_to_double(decimal_record *pd, enum fp_direction_type rd, double *px,
fp_exception_field_type *ps)
{
double_equivalence kluge;
unpacked u;
*ps = 0;
if (pd->fpclass == fp_zero) {
kluge.f.msw.sign = pd->sign? 1 : 0;
kluge.f.msw.exponent = 0;
kluge.f.msw.significand = 0;
kluge.f.significand2 = 0;
*px = kluge.x;
} else {
__hex_to_unpacked(pd, &u);
__pack_double(&u, px, rd, ps);
if (*ps != 0)
__base_conversion_set_exception(*ps);
}
}
#if defined(__sparc)
void
__hex_to_quadruple(decimal_record *pd, enum fp_direction_type rd, quadruple *px,
fp_exception_field_type *ps)
{
quadruple_equivalence kluge;
unpacked u;
*ps = 0;
if (pd->fpclass == fp_zero) {
kluge.f.msw.sign = pd->sign? 1 : 0;
kluge.f.msw.exponent = 0;
kluge.f.msw.significand = 0;
kluge.f.significand2 = 0;
kluge.f.significand3 = 0;
kluge.f.significand4 = 0;
*px = kluge.x;
} else {
__hex_to_unpacked(pd, &u);
__pack_quadruple(&u, px, rd, ps);
if (*ps != 0)
__base_conversion_set_exception(*ps);
}
}
#elif defined(__i386) || defined(__amd64)
void
__hex_to_extended(decimal_record *pd, enum fp_direction_type rd, extended *px,
fp_exception_field_type *ps)
{
extended_equivalence kluge;
unpacked u;
*ps = 0;
if (pd->fpclass == fp_zero) {
kluge.f.msw.sign = pd->sign? 1 : 0;
kluge.f.msw.exponent = 0;
kluge.f.significand = 0;
kluge.f.significand2 = 0;
(*px)[0] = kluge.x[0];
(*px)[1] = kluge.x[1];
(*px)[2] = kluge.x[2];
} else {
__hex_to_unpacked(pd, &u);
__pack_extended(&u, px, rd, ps);
if (*ps != 0)
__base_conversion_set_exception(*ps);
}
}
#else
#error Unknown architecture
#endif