diff options
Diffstat (limited to 'gcc/config/fp-bit.c')
-rw-r--r-- | gcc/config/fp-bit.c | 271 |
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 */ |