#include "tconfig.h"
#include "coretypes.h"
#include "tm.h"
#include "config/fp-bit.h"
#ifdef DECLARE_LIBRARY_RENAMES
DECLARE_LIBRARY_RENAMES
#endif
#ifdef EXTENDED_FLOAT_STUBS
extern void abort (void);
void __extendsfxf2 (void) { abort(); }
void __extenddfxf2 (void) { abort(); }
void __truncxfdf2 (void) { abort(); }
void __truncxfsf2 (void) { abort(); }
void __fixxfsi (void) { abort(); }
void __floatsixf (void) { abort(); }
void __addxf3 (void) { abort(); }
void __subxf3 (void) { abort(); }
void __mulxf3 (void) { abort(); }
void __divxf3 (void) { abort(); }
void __negxf2 (void) { abort(); }
void __eqxf2 (void) { abort(); }
void __nexf2 (void) { abort(); }
void __gtxf2 (void) { abort(); }
void __gexf2 (void) { abort(); }
void __lexf2 (void) { abort(); }
void __ltxf2 (void) { abort(); }
void __extendsftf2 (void) { abort(); }
void __extenddftf2 (void) { abort(); }
void __trunctfdf2 (void) { abort(); }
void __trunctfsf2 (void) { abort(); }
void __fixtfsi (void) { abort(); }
void __floatsitf (void) { abort(); }
void __addtf3 (void) { abort(); }
void __subtf3 (void) { abort(); }
void __multf3 (void) { abort(); }
void __divtf3 (void) { abort(); }
void __negtf2 (void) { abort(); }
void __eqtf2 (void) { abort(); }
void __netf2 (void) { abort(); }
void __gttf2 (void) { abort(); }
void __getf2 (void) { abort(); }
void __letf2 (void) { abort(); }
void __lttf2 (void) { abort(); }
#else
#ifdef NO_NANS
#define nan() 0
#define isnan(x) 0
#define isinf(x) 0
#else
#if defined L_thenan_sf
const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
#elif defined L_thenan_df
const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} };
#elif defined L_thenan_tf
const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
#elif defined TFLOAT
extern const fp_number_type __thenan_tf;
#elif defined FLOAT
extern const fp_number_type __thenan_sf;
#else
extern const fp_number_type __thenan_df;
#endif
INLINE
static fp_number_type *
nan (void)
{
#ifdef TFLOAT
return (fp_number_type *) (& __thenan_tf);
#elif defined FLOAT
return (fp_number_type *) (& __thenan_sf);
#else
return (fp_number_type *) (& __thenan_df);
#endif
}
INLINE
static int
isnan ( fp_number_type * x)
{
return __builtin_expect (x->class == CLASS_SNAN || x->class == CLASS_QNAN,
0);
}
INLINE
static int
isinf ( fp_number_type * x)
{
return __builtin_expect (x->class == CLASS_INFINITY, 0);
}
#endif
INLINE
static int
iszero ( fp_number_type * x)
{
return x->class == CLASS_ZERO;
}
INLINE
static void
flip_sign ( fp_number_type * x)
{
x->sign = !x->sign;
}
INLINE
static int
clzusi (USItype n)
{
extern int __clzsi2 (USItype);
if (sizeof (USItype) == sizeof (unsigned int))
return __builtin_clz (n);
else if (sizeof (USItype) == sizeof (unsigned long))
return __builtin_clzl (n);
else if (sizeof (USItype) == sizeof (unsigned long long))
return __builtin_clzll (n);
else
return __clzsi2 (n);
}
extern FLO_type pack_d ( fp_number_type * );
#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf)
FLO_type
pack_d ( fp_number_type * src)
{
FLO_union_type dst;
fractype fraction = src->fraction.ll;
int sign = src->sign;
int exp = 0;
if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && (isnan (src) || isinf (src)))
{
exp = EXPMAX;
fraction = ((fractype) 1 << FRACBITS) - 1;
}
else if (isnan (src))
{
exp = EXPMAX;
if (src->class == CLASS_QNAN || 1)
{
#ifdef QUIET_NAN_NEGATED
fraction |= QUIET_NAN - 1;
#else
fraction |= QUIET_NAN;
#endif
}
}
else if (isinf (src))
{
exp = EXPMAX;
fraction = 0;
}
else if (iszero (src))
{
exp = 0;
fraction = 0;
}
else if (fraction == 0)
{
exp = 0;
}
else
{
if (__builtin_expect (src->normal_exp < NORMAL_EXPMIN, 0))
{
#ifdef NO_DENORMALS
exp = 0;
fraction = 0;
#else
int shift = NORMAL_EXPMIN - src->normal_exp;
exp = 0;
if (shift > FRAC_NBITS - NGARDS)
{
fraction = 0;
}
else
{
int lowbit = (fraction & (((fractype)1 << shift) - 1)) ? 1 : 0;
fraction = (fraction >> shift) | lowbit;
}
if ((fraction & GARDMASK) == GARDMSB)
{
if ((fraction & (1 << NGARDS)))
fraction += GARDROUND + 1;
}
else
{
fraction += GARDROUND;
}
if (fraction >= IMPLICIT_1)
{
exp += 1;
}
fraction >>= NGARDS;
#endif
}
else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS)
&& __builtin_expect (src->normal_exp > EXPBIAS, 0))
{
exp = EXPMAX;
fraction = 0;
}
else
{
exp = src->normal_exp + EXPBIAS;
if (!ROUND_TOWARDS_ZERO)
{
if ((fraction & GARDMASK) == GARDMSB)
{
if (fraction & (1 << NGARDS))
fraction += GARDROUND + 1;
}
else
{
fraction += GARDROUND;
}
if (fraction >= IMPLICIT_2)
{
fraction >>= 1;
exp += 1;
}
}
fraction >>= NGARDS;
if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp > EXPMAX)
{
exp = EXPMAX;
fraction = ((fractype) 1 << FRACBITS) - 1;
}
}
}
#ifdef FLOAT_BIT_ORDER_MISMATCH
dst.bits.fraction = fraction;
dst.bits.exp = exp;
dst.bits.sign = sign;
#else
# if defined TFLOAT && defined HALFFRACBITS
{
halffractype high, low, unity;
int lowsign, lowexp;
unity = (halffractype) 1 << HALFFRACBITS;
high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1);
low = fraction & (unity * 2 - 1);
lowexp = exp - HALFFRACBITS - 1;
lowsign = sign;
if (exp < EXPMAX)
if (low > unity || (low == unity && (high & 1) == 1))
{
high++;
if (high == unity)
{
high = 0;
exp++;
}
low = unity * 2 - low;
lowsign ^= 1;
}
high |= (halffractype) exp << HALFFRACBITS;
high |= (halffractype) sign << (HALFFRACBITS + EXPBITS);
if (exp == EXPMAX || exp == 0 || low == 0)
low = 0;
else
{
while (lowexp > 0 && low < unity)
{
low <<= 1;
lowexp--;
}
if (lowexp <= 0)
{
halffractype roundmsb, round;
int shift;
shift = 1 - lowexp;
roundmsb = (1 << (shift - 1));
round = low & ((roundmsb << 1) - 1);
low >>= shift;
lowexp = 0;
if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
{
low++;
if (low == unity)
lowexp++;
}
}
low &= unity - 1;
low |= (halffractype) lowexp << HALFFRACBITS;
low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
}
dst.value_raw = ((fractype) high << HALFSHIFT) | low;
}
# else
dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS;
dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS);
# endif
#endif
#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
#ifdef TFLOAT
{
qrtrfractype tmp1 = dst.words[0];
qrtrfractype tmp2 = dst.words[1];
dst.words[0] = dst.words[3];
dst.words[1] = dst.words[2];
dst.words[2] = tmp2;
dst.words[3] = tmp1;
}
#else
{
halffractype tmp = dst.words[0];
dst.words[0] = dst.words[1];
dst.words[1] = tmp;
}
#endif
#endif
return dst.value;
}
#endif
#if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf)
void
unpack_d (FLO_union_type * src, fp_number_type * dst)
{
fractype fraction;
int exp;
int sign;
#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
FLO_union_type swapped;
#ifdef TFLOAT
swapped.words[0] = src->words[3];
swapped.words[1] = src->words[2];
swapped.words[2] = src->words[1];
swapped.words[3] = src->words[0];
#else
swapped.words[0] = src->words[1];
swapped.words[1] = src->words[0];
#endif
src = &swapped;
#endif
#ifdef FLOAT_BIT_ORDER_MISMATCH
fraction = src->bits.fraction;
exp = src->bits.exp;
sign = src->bits.sign;
#else
# if defined TFLOAT && defined HALFFRACBITS
{
halffractype high, low;
high = src->value_raw >> HALFSHIFT;
low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1);
fraction = high & ((((fractype)1) << HALFFRACBITS) - 1);
fraction <<= FRACBITS - HALFFRACBITS;
exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1;
if (exp != EXPMAX && exp != 0 && low != 0)
{
int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1;
int shift;
fractype xlow;
xlow = low & ((((fractype)1) << HALFFRACBITS) - 1);
if (lowexp)
xlow |= (((halffractype)1) << HALFFRACBITS);
else
lowexp = 1;
shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp);
if (shift > 0)
xlow <<= shift;
else if (shift < 0)
xlow >>= -shift;
if (sign == lowsign)
fraction += xlow;
else if (fraction >= xlow)
fraction -= xlow;
else
{
fraction = (((fractype) 1 << FRACBITS) - xlow) << 1;
exp--;
}
}
}
# else
fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1);
exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1);
sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1;
# endif
#endif
dst->sign = sign;
if (exp == 0)
{
if (fraction == 0
#ifdef NO_DENORMALS
|| 1
#endif
)
{
dst->class = CLASS_ZERO;
}
else
{
dst->normal_exp = exp - EXPBIAS + 1;
fraction <<= NGARDS;
dst->class = CLASS_NUMBER;
#if 1
while (fraction < IMPLICIT_1)
{
fraction <<= 1;
dst->normal_exp--;
}
#endif
dst->fraction.ll = fraction;
}
}
else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS)
&& __builtin_expect (exp == EXPMAX, 0))
{
if (fraction == 0)
{
dst->class = CLASS_INFINITY;
}
else
{
#ifdef QUIET_NAN_NEGATED
if ((fraction & QUIET_NAN) == 0)
#else
if (fraction & QUIET_NAN)
#endif
{
dst->class = CLASS_QNAN;
}
else
{
dst->class = CLASS_SNAN;
}
dst->fraction.ll = fraction;
}
}
else
{
dst->normal_exp = exp - EXPBIAS;
dst->class = CLASS_NUMBER;
dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
}
}
#endif
#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf)
static fp_number_type *
_fpadd_parts (fp_number_type * a,
fp_number_type * b,
fp_number_type * tmp)
{
intfrac tfraction;
int a_normal_exp;
int b_normal_exp;
fractype a_fraction;
fractype b_fraction;
if (isnan (a))
{
return a;
}
if (isnan (b))
{
return b;
}
if (isinf (a))
{
if (isinf (b) && a->sign != b->sign)
return nan ();
return a;
}
if (isinf (b))
{
return b;
}
if (iszero (b))
{
if (iszero (a))
{
*tmp = *a;
tmp->sign = a->sign & b->sign;
return tmp;
}
return a;
}
if (iszero (a))
{
return b;
}
{
int diff;
int sdiff;
a_normal_exp = a->normal_exp;
b_normal_exp = b->normal_exp;
a_fraction = a->fraction.ll;
b_fraction = b->fraction.ll;
diff = a_normal_exp - b_normal_exp;
sdiff = diff;
if (diff < 0)
diff = -diff;
if (diff < FRAC_NBITS)
{
if (sdiff > 0)
{
b_normal_exp += diff;
LSHIFT (b_fraction, diff);
}
else if (sdiff < 0)
{
a_normal_exp += diff;
LSHIFT (a_fraction, diff);
}
}
else
{
if (a_normal_exp > b_normal_exp)
{
b_normal_exp = a_normal_exp;
b_fraction = 0;
}
else
{
a_normal_exp = b_normal_exp;
a_fraction = 0;
}
}
}
if (a->sign != b->sign)
{
if (a->sign)
{
tfraction = -a_fraction + b_fraction;
}
else
{
tfraction = a_fraction - b_fraction;
}
if (tfraction >= 0)
{
tmp->sign = 0;
tmp->normal_exp = a_normal_exp;
tmp->fraction.ll = tfraction;
}
else
{
tmp->sign = 1;
tmp->normal_exp = a_normal_exp;
tmp->fraction.ll = -tfraction;
}
while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll)
{
tmp->fraction.ll <<= 1;
tmp->normal_exp--;
}
}
else
{
tmp->sign = a->sign;
tmp->normal_exp = a_normal_exp;
tmp->fraction.ll = a_fraction + b_fraction;
}
tmp->class = CLASS_NUMBER;
if (tmp->fraction.ll >= IMPLICIT_2)
{
LSHIFT (tmp->fraction.ll, 1);
tmp->normal_exp++;
}
return tmp;
}
FLO_type
add (FLO_type arg_a, FLO_type arg_b)
{
fp_number_type a;
fp_number_type b;
fp_number_type tmp;
fp_number_type *res;
FLO_union_type au, bu;
au.value = arg_a;
bu.value = arg_b;
unpack_d (&au, &a);
unpack_d (&bu, &b);
res = _fpadd_parts (&a, &b, &tmp);
return pack_d (res);
}
FLO_type
sub (FLO_type arg_a, FLO_type arg_b)
{
fp_number_type a;
fp_number_type b;
fp_number_type tmp;
fp_number_type *res;
FLO_union_type au, bu;
au.value = arg_a;
bu.value = arg_b;
unpack_d (&au, &a);
unpack_d (&bu, &b);
b.sign ^= 1;
res = _fpadd_parts (&a, &b, &tmp);
return pack_d (res);
}
#endif
#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf)
static inline __attribute__ ((__always_inline__)) fp_number_type *
_fpmul_parts ( fp_number_type * a,
fp_number_type * b,
fp_number_type * tmp)
{
fractype low = 0;
fractype high = 0;
if (isnan (a))
{
a->sign = a->sign != b->sign;
return a;
}
if (isnan (b))
{
b->sign = a->sign != b->sign;
return b;
}
if (isinf (a))
{
if (iszero (b))
return nan ();
a->sign = a->sign != b->sign;
return a;
}
if (isinf (b))
{
if (iszero (a))
{
return nan ();
}
b->sign = a->sign != b->sign;
return b;
}
if (iszero (a))
{
a->sign = a->sign != b->sign;
return a;
}
if (iszero (b))
{
b->sign = a->sign != b->sign;
return b;
}
{
#if defined(NO_DI_MODE) || defined(TFLOAT)
{
fractype x = a->fraction.ll;
fractype ylow = b->fraction.ll;
fractype yhigh = 0;
int bit;
for (bit = 0; bit < FRAC_NBITS; bit++)
{
int carry;
if (x & 1)
{
carry = (low += ylow) < ylow;
high += yhigh + carry;
}
yhigh <<= 1;
if (ylow & FRACHIGH)
{
yhigh |= 1;
}
ylow <<= 1;
x >>= 1;
}
}
#elif defined(FLOAT)
{
UDItype answer = (UDItype)a->fraction.ll * (UDItype)b->fraction.ll;
high = answer >> BITS_PER_SI;
low = answer;
}
#else
{
USItype nl = a->fraction.ll;
USItype nh = a->fraction.ll >> BITS_PER_SI;
USItype ml = b->fraction.ll;
USItype mh = b->fraction.ll >> BITS_PER_SI;
UDItype pp_ll = (UDItype) ml * nl;
UDItype pp_hl = (UDItype) mh * nl;
UDItype pp_lh = (UDItype) ml * nh;
UDItype pp_hh = (UDItype) mh * nh;
UDItype res2 = 0;
UDItype res0 = 0;
UDItype ps_hh__ = pp_hl + pp_lh;
if (ps_hh__ < pp_hl)
res2 += (UDItype)1 << BITS_PER_SI;
pp_hl = (UDItype)(USItype)ps_hh__ << BITS_PER_SI;
res0 = pp_ll + pp_hl;
if (res0 < pp_ll)
res2++;
res2 += (ps_hh__ >> BITS_PER_SI) + pp_hh;
high = res2;
low = res0;
}
#endif
}
tmp->normal_exp = a->normal_exp + b->normal_exp
+ FRAC_NBITS - (FRACBITS + NGARDS);
tmp->sign = a->sign != b->sign;
while (high >= IMPLICIT_2)
{
tmp->normal_exp++;
if (high & 1)
{
low >>= 1;
low |= FRACHIGH;
}
high >>= 1;
}
while (high < IMPLICIT_1)
{
tmp->normal_exp--;
high <<= 1;
if (low & FRACHIGH)
high |= 1;
low <<= 1;
}
if (!ROUND_TOWARDS_ZERO && (high & GARDMASK) == GARDMSB)
{
if (high & (1 << NGARDS))
{
}
else if (low)
{
high += GARDROUND + 1;
high &= ~(fractype) GARDMASK;
}
}
tmp->fraction.ll = high;
tmp->class = CLASS_NUMBER;
return tmp;
}
FLO_type
multiply (FLO_type arg_a, FLO_type arg_b)
{
fp_number_type a;
fp_number_type b;
fp_number_type tmp;
fp_number_type *res;
FLO_union_type au, bu;
au.value = arg_a;
bu.value = arg_b;
unpack_d (&au, &a);
unpack_d (&bu, &b);
res = _fpmul_parts (&a, &b, &tmp);
return pack_d (res);
}
#endif
#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf)
static inline __attribute__ ((__always_inline__)) fp_number_type *
_fpdiv_parts (fp_number_type * a,
fp_number_type * b)
{
fractype bit;
fractype numerator;
fractype denominator;
fractype quotient;
if (isnan (a))
{
return a;
}
if (isnan (b))
{
return b;
}
a->sign = a->sign ^ b->sign;
if (isinf (a) || iszero (a))
{
if (a->class == b->class)
return nan ();
return a;
}
if (isinf (b))
{
a->fraction.ll = 0;
a->normal_exp = 0;
return a;
}
if (iszero (b))
{
a->class = CLASS_INFINITY;
return a;
}
{
a->normal_exp = a->normal_exp - b->normal_exp;
numerator = a->fraction.ll;
denominator = b->fraction.ll;
if (numerator < denominator)
{
numerator *= 2;
a->normal_exp--;
}
bit = IMPLICIT_1;
quotient = 0;
while (bit)
{
if (numerator >= denominator)
{
quotient |= bit;
numerator -= denominator;
}
bit >>= 1;
numerator *= 2;
}
if (!ROUND_TOWARDS_ZERO && (quotient & GARDMASK) == GARDMSB)
{
if (quotient & (1 << NGARDS))
{
}
else if (numerator)
{
quotient += GARDROUND + 1;
quotient &= ~(fractype) GARDMASK;
}
}
a->fraction.ll = quotient;
return (a);
}
}
FLO_type
divide (FLO_type arg_a, FLO_type arg_b)
{
fp_number_type a;
fp_number_type b;
fp_number_type *res;
FLO_union_type au, bu;
au.value = arg_a;
bu.value = arg_b;
unpack_d (&au, &a);
unpack_d (&bu, &b);
res = _fpdiv_parts (&a, &b);
return pack_d (res);
}
#endif
#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \
|| defined(L_fpcmp_parts_tf)
int
__fpcmp_parts (fp_number_type * a, fp_number_type * b)
{
#if 0
if (isnan (a) && isnan (b))
{
return 1;
}
#endif
if (isnan (a) || isnan (b))
{
return 1;
}
if (isinf (a) && isinf (b))
{
return b->sign - a->sign;
}
if (isinf (a))
{
return a->sign ? -1 : 1;
}
if (isinf (b))
{
return b->sign ? 1 : -1;
}
if (iszero (a) && iszero (b))
{
return 0;
}
if (iszero (a))
{
return b->sign ? 1 : -1;
}
if (iszero (b))
{
return a->sign ? -1 : 1;
}
if (a->sign != b->sign)
{
return a->sign ? -1 : 1;
}
if (a->normal_exp > b->normal_exp)
{
return a->sign ? -1 : 1;
}
if (a->normal_exp < b->normal_exp)
{
return a->sign ? 1 : -1;
}
if (a->fraction.ll > b->fraction.ll)
{
return a->sign ? -1 : 1;
}
if (a->fraction.ll < b->fraction.ll)
{
return a->sign ? 1 : -1;
}
return 0;
}
#endif
#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf)
CMPtype
compare (FLO_type arg_a, FLO_type arg_b)
{
fp_number_type a;
fp_number_type b;
FLO_union_type au, bu;
au.value = arg_a;
bu.value = arg_b;
unpack_d (&au, &a);
unpack_d (&bu, &b);
return __fpcmp_parts (&a, &b);
}
#endif
#ifndef US_SOFTWARE_GOFAST
#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf)
CMPtype
_eq_f2 (FLO_type arg_a, FLO_type arg_b)
{
fp_number_type a;
fp_number_type b;
FLO_union_type au, bu;
au.value = arg_a;
bu.value = arg_b;
unpack_d (&au, &a);
unpack_d (&bu, &b);
if (isnan (&a) || isnan (&b))
return 1;
return __fpcmp_parts (&a, &b) ;
}
#endif
#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf)
CMPtype
_ne_f2 (FLO_type arg_a, FLO_type arg_b)
{
fp_number_type a;
fp_number_type b;
FLO_union_type au, bu;
au.value = arg_a;
bu.value = arg_b;
unpack_d (&au, &a);
unpack_d (&bu, &b);
if (isnan (&a) || isnan (&b))
return 1;
return __fpcmp_parts (&a, &b) ;
}
#endif
#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf)
CMPtype
_gt_f2 (FLO_type arg_a, FLO_type arg_b)
{
fp_number_type a;
fp_number_type b;
FLO_union_type au, bu;
au.value = arg_a;
bu.value = arg_b;
unpack_d (&au, &a);
unpack_d (&bu, &b);
if (isnan (&a) || isnan (&b))
return -1;
return __fpcmp_parts (&a, &b);
}
#endif
#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf)
CMPtype
_ge_f2 (FLO_type arg_a, FLO_type arg_b)
{
fp_number_type a;
fp_number_type b;
FLO_union_type au, bu;
au.value = arg_a;
bu.value = arg_b;
unpack_d (&au, &a);
unpack_d (&bu, &b);
if (isnan (&a) || isnan (&b))
return -1;
return __fpcmp_parts (&a, &b) ;
}
#endif
#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf)
CMPtype
_lt_f2 (FLO_type arg_a, FLO_type arg_b)
{
fp_number_type a;
fp_number_type b;
FLO_union_type au, bu;
au.value = arg_a;
bu.value = arg_b;
unpack_d (&au, &a);
unpack_d (&bu, &b);
if (isnan (&a) || isnan (&b))
return 1;
return __fpcmp_parts (&a, &b);
}
#endif
#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf)
CMPtype
_le_f2 (FLO_type arg_a, FLO_type arg_b)
{
fp_number_type a;
fp_number_type b;
FLO_union_type au, bu;
au.value = arg_a;
bu.value = arg_b;
unpack_d (&au, &a);
unpack_d (&bu, &b);
if (isnan (&a) || isnan (&b))
return 1;
return __fpcmp_parts (&a, &b) ;
}
#endif
#endif
#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf)
CMPtype
_unord_f2 (FLO_type arg_a, FLO_type arg_b)
{
fp_number_type a;
fp_number_type b;
FLO_union_type au, bu;
au.value = arg_a;
bu.value = arg_b;
unpack_d (&au, &a);
unpack_d (&bu, &b);
return (isnan (&a) || isnan (&b));
}
#endif
#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf)
FLO_type
si_to_float (SItype arg_a)
{
fp_number_type in;
in.class = CLASS_NUMBER;
in.sign = arg_a < 0;
if (!arg_a)
{
in.class = CLASS_ZERO;
}
else
{
USItype uarg;
int shift;
in.normal_exp = FRACBITS + NGARDS;
if (in.sign)
{
if (arg_a == (- MAX_SI_INT - 1))
{
return (FLO_type)(- MAX_SI_INT - 1);
}
uarg = (-arg_a);
}
else
uarg = arg_a;
in.fraction.ll = uarg;
shift = clzusi (uarg) - (BITS_PER_SI - 1 - FRACBITS - NGARDS);
if (shift > 0)
{
in.fraction.ll <<= shift;
in.normal_exp -= shift;
}
}
return pack_d (&in);
}
#endif
#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf)
FLO_type
usi_to_float (USItype arg_a)
{
fp_number_type in;
in.sign = 0;
if (!arg_a)
{
in.class = CLASS_ZERO;
}
else
{
int shift;
in.class = CLASS_NUMBER;
in.normal_exp = FRACBITS + NGARDS;
in.fraction.ll = arg_a;
shift = clzusi (arg_a) - (BITS_PER_SI - 1 - FRACBITS - NGARDS);
if (shift < 0)
{
fractype guard = in.fraction.ll & (((fractype)1 << -shift) - 1);
in.fraction.ll >>= -shift;
in.fraction.ll |= (guard != 0);
in.normal_exp -= shift;
}
else if (shift > 0)
{
in.fraction.ll <<= shift;
in.normal_exp -= shift;
}
}
return pack_d (&in);
}
#endif
#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si)
SItype
float_to_si (FLO_type arg_a)
{
fp_number_type a;
SItype tmp;
FLO_union_type au;
au.value = arg_a;
unpack_d (&au, &a);
if (iszero (&a))
return 0;
if (isnan (&a))
return 0;
if (isinf (&a))
return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
if (a.normal_exp < 0)
return 0;
if (a.normal_exp > BITS_PER_SI - 2)
return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
return a.sign ? (-tmp) : (tmp);
}
#endif
#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi)
#if defined US_SOFTWARE_GOFAST || defined(L_tf_to_usi)
USItype
float_to_usi (FLO_type arg_a)
{
fp_number_type a;
FLO_union_type au;
au.value = arg_a;
unpack_d (&au, &a);
if (iszero (&a))
return 0;
if (isnan (&a))
return 0;
if (a.sign)
return 0;
if (isinf (&a))
return MAX_USI_INT;
if (a.normal_exp < 0)
return 0;
if (a.normal_exp > BITS_PER_SI - 1)
return MAX_USI_INT;
else if (a.normal_exp > (FRACBITS + NGARDS))
return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS));
else
return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
}
#endif
#endif
#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf)
FLO_type
negate (FLO_type arg_a)
{
fp_number_type a;
FLO_union_type au;
au.value = arg_a;
unpack_d (&au, &a);
flip_sign (&a);
return pack_d (&a);
}
#endif
#ifdef FLOAT
#if defined(L_make_sf)
SFtype
__make_fp(fp_class_type class,
unsigned int sign,
int exp,
USItype frac)
{
fp_number_type in;
in.class = class;
in.sign = sign;
in.normal_exp = exp;
in.fraction.ll = frac;
return pack_d (&in);
}
#endif
#ifndef FLOAT_ONLY
#if defined(L_sf_to_df)
DFtype
sf_to_df (SFtype arg_a)
{
fp_number_type in;
FLO_union_type au;
au.value = arg_a;
unpack_d (&au, &in);
return __make_dp (in.class, in.sign, in.normal_exp,
((UDItype) in.fraction.ll) << F_D_BITOFF);
}
#endif
#if defined(L_sf_to_tf) && defined(TMODES)
TFtype
sf_to_tf (SFtype arg_a)
{
fp_number_type in;
FLO_union_type au;
au.value = arg_a;
unpack_d (&au, &in);
return __make_tp (in.class, in.sign, in.normal_exp,
((UTItype) in.fraction.ll) << F_T_BITOFF);
}
#endif
#endif
#endif
#ifndef FLOAT
extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
#if defined(L_make_df)
DFtype
__make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
{
fp_number_type in;
in.class = class;
in.sign = sign;
in.normal_exp = exp;
in.fraction.ll = frac;
return pack_d (&in);
}
#endif
#if defined(L_df_to_sf)
SFtype
df_to_sf (DFtype arg_a)
{
fp_number_type in;
USItype sffrac;
FLO_union_type au;
au.value = arg_a;
unpack_d (&au, &in);
sffrac = in.fraction.ll >> F_D_BITOFF;
if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0)
sffrac |= 1;
return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
}
#endif
#if defined(L_df_to_tf) && defined(TMODES) \
&& !defined(FLOAT) && !defined(TFLOAT)
TFtype
df_to_tf (DFtype arg_a)
{
fp_number_type in;
FLO_union_type au;
au.value = arg_a;
unpack_d (&au, &in);
return __make_tp (in.class, in.sign, in.normal_exp,
((UTItype) in.fraction.ll) << D_T_BITOFF);
}
#endif
#ifdef TFLOAT
#if defined(L_make_tf)
TFtype
__make_tp(fp_class_type class,
unsigned int sign,
int exp,
UTItype frac)
{
fp_number_type in;
in.class = class;
in.sign = sign;
in.normal_exp = exp;
in.fraction.ll = frac;
return pack_d (&in);
}
#endif
#if defined(L_tf_to_df)
DFtype
tf_to_df (TFtype arg_a)
{
fp_number_type in;
UDItype sffrac;
FLO_union_type au;
au.value = arg_a;
unpack_d (&au, &in);
sffrac = in.fraction.ll >> D_T_BITOFF;
if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0)
sffrac |= 1;
return __make_dp (in.class, in.sign, in.normal_exp, sffrac);
}
#endif
#if defined(L_tf_to_sf)
SFtype
tf_to_sf (TFtype arg_a)
{
fp_number_type in;
USItype sffrac;
FLO_union_type au;
au.value = arg_a;
unpack_d (&au, &in);
sffrac = in.fraction.ll >> F_T_BITOFF;
if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0)
sffrac |= 1;
return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
}
#endif
#endif
#endif
#endif