aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/fp-bit.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/fp-bit.c')
-rw-r--r--gcc/config/fp-bit.c271
1 files changed, 238 insertions, 33 deletions
diff --git a/gcc/config/fp-bit.c b/gcc/config/fp-bit.c
index 7ec20ecf9f2..aeb40e44c18 100644
--- a/gcc/config/fp-bit.c
+++ b/gcc/config/fp-bit.c
@@ -1,6 +1,6 @@
/* This is a software floating point library which can be used
for targets without hardware floating point.
- Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002
+ Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
This file is free software; you can redistribute it and/or modify it
@@ -130,6 +130,10 @@ void __lttf2 (void) { abort(); }
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
@@ -141,7 +145,9 @@ static fp_number_type *
nan (void)
{
/* Discard the const qualifier... */
-#ifdef FLOAT
+#ifdef TFLOAT
+ return (fp_number_type *) (& __thenan_tf);
+#elif defined FLOAT
return (fp_number_type *) (& __thenan_sf);
#else
return (fp_number_type *) (& __thenan_df);
@@ -180,7 +186,7 @@ flip_sign ( fp_number_type * x)
extern FLO_type pack_d ( fp_number_type * );
-#if defined(L_pack_df) || defined(L_pack_sf)
+#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf)
FLO_type
pack_d ( fp_number_type * src)
{
@@ -316,24 +322,92 @@ pack_d ( fp_number_type * src)
dst.bits.exp = exp;
dst.bits.sign = sign;
#else
+# if defined TFLOAT && defined HALFFRACBITS
+ {
+ halffractype high, low;
+
+ high = (fraction >> (FRACBITS - HALFFRACBITS));
+ high &= (((fractype)1) << HALFFRACBITS) - 1;
+ high |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << HALFFRACBITS;
+ high |= ((fractype) (sign & 1)) << (HALFFRACBITS | EXPBITS);
+
+ low = (halffractype)fraction &
+ ((((halffractype)1) << (FRACBITS - HALFFRACBITS)) - 1);
+
+ if (exp == EXPMAX || exp == 0 || low == 0)
+ low = 0;
+ else
+ {
+ exp -= HALFFRACBITS + 1;
+
+ while (exp > 0
+ && low < ((halffractype)1 << HALFFRACBITS))
+ {
+ low <<= 1;
+ exp--;
+ }
+
+ if (exp <= 0)
+ {
+ halffractype roundmsb, round;
+
+ exp = -exp + 1;
+
+ roundmsb = (1 << (exp - 1));
+ round = low & ((roundmsb << 1) - 1);
+
+ low >>= exp;
+ exp = 0;
+
+ if (round > roundmsb || (round == roundmsb && (low & 1)))
+ {
+ low++;
+ if (low >= ((halffractype)1 << HALFFRACBITS))
+ /* We don't shift left, since it has just become the
+ smallest normal number, whose implicit 1 bit is
+ now indicated by the non-zero exponent. */
+ exp++;
+ }
+ }
+
+ low &= ((halffractype)1 << HALFFRACBITS) - 1;
+ low |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << HALFFRACBITS;
+ low |= ((fractype) (sign & 1)) << (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)
+#if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf)
void
unpack_d (FLO_union_type * src, fp_number_type * dst)
{
@@ -347,8 +421,15 @@ unpack_d (FLO_union_type * src, fp_number_type * dst)
#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
@@ -357,9 +438,42 @@ unpack_d (FLO_union_type * src, fp_number_type * dst)
exp = src->bits.exp;
sign = src->bits.sign;
#else
- fraction = src->value_raw & ((((fractype)1) << FRACBITS) - (fractype)1);
+# 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 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;
+ fraction += xlow;
+ }
+ }
+# 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;
@@ -427,7 +541,7 @@ unpack_d (FLO_union_type * src, fp_number_type * dst)
}
#endif /* L_unpack_df || L_unpack_sf */
-#if defined(L_addsub_sf) || defined(L_addsub_df)
+#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,
@@ -611,7 +725,7 @@ sub (FLO_type arg_a, FLO_type arg_b)
}
#endif /* L_addsub_sf || L_addsub_df */
-#if defined(L_mul_sf) || defined(L_mul_df)
+#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,
@@ -660,7 +774,7 @@ _fpmul_parts ( fp_number_type * a,
/* Calculate the mantissa by multiplying both numbers to get a
twice-as-wide number. */
{
-#if defined(NO_DI_MODE)
+#if defined(NO_DI_MODE) || defined(TFLOAT)
{
fractype x = a->fraction.ll;
fractype ylow = b->fraction.ll;
@@ -723,13 +837,9 @@ _fpmul_parts ( fp_number_type * a,
#endif
}
- tmp->normal_exp = a->normal_exp + b->normal_exp;
+ tmp->normal_exp = a->normal_exp + b->normal_exp
+ + FRAC_NBITS - (FRACBITS + NGARDS);
tmp->sign = a->sign != b->sign;
-#ifdef FLOAT
- tmp->normal_exp += 2; /* ??????????????? */
-#else
- tmp->normal_exp += 4; /* ??????????????? */
-#endif
while (high >= IMPLICIT_2)
{
tmp->normal_exp++;
@@ -803,7 +913,7 @@ multiply (FLO_type arg_a, FLO_type arg_b)
}
#endif /* L_mul_sf || L_mul_df */
-#if defined(L_div_sf) || defined(L_div_df)
+#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)
@@ -913,7 +1023,8 @@ divide (FLO_type arg_a, FLO_type arg_b)
}
#endif /* L_div_sf || L_div_df */
-#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df)
+#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \
+ || defined(L_fpcmp_parts_tf)
/* according to the demo, fpcmp returns a comparison with 0... thus
a<b -> -1
a==b -> 0
@@ -998,7 +1109,7 @@ __fpcmp_parts (fp_number_type * a, fp_number_type * b)
}
#endif
-#if defined(L_compare_sf) || defined(L_compare_df)
+#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf)
CMPtype
compare (FLO_type arg_a, FLO_type arg_b)
{
@@ -1020,7 +1131,7 @@ compare (FLO_type arg_a, FLO_type arg_b)
/* These should be optimized for their specific tasks someday. */
-#if defined(L_eq_sf) || defined(L_eq_df)
+#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf)
CMPtype
_eq_f2 (FLO_type arg_a, FLO_type arg_b)
{
@@ -1041,7 +1152,7 @@ _eq_f2 (FLO_type arg_a, FLO_type arg_b)
}
#endif /* L_eq_sf || L_eq_df */
-#if defined(L_ne_sf) || defined(L_ne_df)
+#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf)
CMPtype
_ne_f2 (FLO_type arg_a, FLO_type arg_b)
{
@@ -1062,7 +1173,7 @@ _ne_f2 (FLO_type arg_a, FLO_type arg_b)
}
#endif /* L_ne_sf || L_ne_df */
-#if defined(L_gt_sf) || defined(L_gt_df)
+#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf)
CMPtype
_gt_f2 (FLO_type arg_a, FLO_type arg_b)
{
@@ -1083,7 +1194,7 @@ _gt_f2 (FLO_type arg_a, FLO_type arg_b)
}
#endif /* L_gt_sf || L_gt_df */
-#if defined(L_ge_sf) || defined(L_ge_df)
+#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf)
CMPtype
_ge_f2 (FLO_type arg_a, FLO_type arg_b)
{
@@ -1103,7 +1214,7 @@ _ge_f2 (FLO_type arg_a, FLO_type arg_b)
}
#endif /* L_ge_sf || L_ge_df */
-#if defined(L_lt_sf) || defined(L_lt_df)
+#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf)
CMPtype
_lt_f2 (FLO_type arg_a, FLO_type arg_b)
{
@@ -1124,7 +1235,7 @@ _lt_f2 (FLO_type arg_a, FLO_type arg_b)
}
#endif /* L_lt_sf || L_lt_df */
-#if defined(L_le_sf) || defined(L_le_df)
+#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf)
CMPtype
_le_f2 (FLO_type arg_a, FLO_type arg_b)
{
@@ -1147,7 +1258,7 @@ _le_f2 (FLO_type arg_a, FLO_type arg_b)
#endif /* ! US_SOFTWARE_GOFAST */
-#if defined(L_unord_sf) || defined(L_unord_df)
+#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf)
CMPtype
_unord_f2 (FLO_type arg_a, FLO_type arg_b)
{
@@ -1165,7 +1276,7 @@ _unord_f2 (FLO_type arg_a, FLO_type arg_b)
}
#endif /* L_unord_sf || L_unord_df */
-#if defined(L_si_to_sf) || defined(L_si_to_df)
+#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf)
FLO_type
si_to_float (SItype arg_a)
{
@@ -1193,7 +1304,7 @@ si_to_float (SItype arg_a)
else
in.fraction.ll = arg_a;
- while (in.fraction.ll < (1LL << (FRACBITS + NGARDS)))
+ while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
{
in.fraction.ll <<= 1;
in.normal_exp -= 1;
@@ -1203,7 +1314,7 @@ si_to_float (SItype arg_a)
}
#endif /* L_si_to_sf || L_si_to_df */
-#if defined(L_usi_to_sf) || defined(L_usi_to_df)
+#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf)
FLO_type
usi_to_float (USItype arg_a)
{
@@ -1220,12 +1331,12 @@ usi_to_float (USItype arg_a)
in.normal_exp = FRACBITS + NGARDS;
in.fraction.ll = arg_a;
- while (in.fraction.ll > (1LL << (FRACBITS + NGARDS)))
+ while (in.fraction.ll > ((fractype)1 << (FRACBITS + NGARDS)))
{
in.fraction.ll >>= 1;
in.normal_exp += 1;
}
- while (in.fraction.ll < (1LL << (FRACBITS + NGARDS)))
+ while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
{
in.fraction.ll <<= 1;
in.normal_exp -= 1;
@@ -1235,7 +1346,7 @@ usi_to_float (USItype arg_a)
}
#endif
-#if defined(L_sf_to_si) || defined(L_df_to_si)
+#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si)
SItype
float_to_si (FLO_type arg_a)
{
@@ -1263,8 +1374,8 @@ float_to_si (FLO_type arg_a)
}
#endif /* L_sf_to_si || L_df_to_si */
-#if defined(L_sf_to_usi) || defined(L_df_to_usi)
-#ifdef US_SOFTWARE_GOFAST
+#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)
/* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines,
we also define them for GOFAST because the ones in libgcc2.c have the
wrong names and I'd rather define these here and keep GOFAST CYG-LOC's
@@ -1303,7 +1414,7 @@ float_to_usi (FLO_type arg_a)
#endif /* US_SOFTWARE_GOFAST */
#endif /* L_sf_to_usi || L_df_to_usi */
-#if defined(L_negate_sf) || defined(L_negate_df)
+#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf)
FLO_type
negate (FLO_type arg_a)
{
@@ -1359,6 +1470,21 @@ sf_to_df (SFtype arg_a)
}
#endif /* L_sf_to_df */
+#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 /* L_sf_to_df */
+
#endif /* ! FLOAT_ONLY */
#endif /* FLOAT */
@@ -1402,5 +1528,84 @@ df_to_sf (DFtype arg_a)
}
#endif /* L_df_to_sf */
+#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 /* L_sf_to_df */
+
+#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 /* L_make_tf */
+
+#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;
+
+ /* We set the lowest guard bit in SFFRAC if we discarded any non
+ zero bits. */
+ 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 /* L_tf_to_df */
+
+#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;
+
+ /* We set the lowest guard bit in SFFRAC if we discarded any non
+ zero bits. */
+ 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 /* L_tf_to_sf */
+#endif /* TFLOAT */
+
#endif /* ! FLOAT */
#endif /* !EXTENDED_FLOAT_STUBS */