📄 900-nios2.patch
字号:
+ 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;+ }++ /* Calculate the mantissa by multiplying both 64bit numbers to get a+ 128 bit number */+ {+ /* quotient =+ ( numerator / denominator) * 2^(numerator exponent - denominator exponent)+ */++ a->normal_exp = a->normal_exp - b->normal_exp;+ numerator = a->fraction.ll;+ denominator = b->fraction.ll;++ if (numerator < denominator)+ {+ /* Fraction will be less than 1.0 */+ numerator *= 2;+ a->normal_exp--;+ }+ bit = IMPLICIT_1;+ quotient = 0;+ /* ??? Does divide one bit at a time. Optimize. */+ while (bit)+ {+ if (numerator >= denominator)+ {+ quotient |= bit;+ numerator -= denominator;+ }+ bit >>= 1;+ numerator *= 2;+ }++ if (!ROUND_TOWARDS_ZERO && (quotient & GARDMASK) == GARDMSB)+ {+ if (quotient & (1 << NGARDS))+ {+ /* half way, so round to even */+ quotient += GARDROUND + 1;+ }+ else if (numerator)+ {+ /* but we really weren't half way, more bits exist */+ quotient += GARDROUND + 1;+ }+ }++ 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 /* L_div_sf || L_div_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+ a>b -> +1+ */++int+__fpcmp_parts (fp_number_type * a, fp_number_type * b)+{+#if 0+ /* either nan -> unordered. Must be checked outside of this routine. */+ if (isnan (a) && isnan (b))+ {+ return 1; /* still unordered! */+ }+#endif++ if (isnan (a) || isnan (b))+ {+ return 1; /* how to indicate unordered compare? */+ }+ if (isinf (a) && isinf (b))+ {+ /* +inf > -inf, but +inf != +inf */+ /* b \a| +inf(0)| -inf(1)+ ______\+--------+--------+ +inf(0)| a==b(0)| a<b(-1)+ -------+--------+--------+ -inf(1)| a>b(1) | a==b(0)+ -------+--------+--------+ So since unordered must be nonzero, just line up the columns...+ */+ return b->sign - a->sign;+ }+ /* but not both... */+ 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;+ }+ /* now both are "normal". */+ if (a->sign != b->sign)+ {+ /* opposite signs */+ return a->sign ? -1 : 1;+ }+ /* same sign; exponents? */+ if (a->normal_exp > b->normal_exp)+ {+ return a->sign ? -1 : 1;+ }+ if (a->normal_exp < b->normal_exp)+ {+ return a->sign ? 1 : -1;+ }+ /* same exponents; check size. */+ if (a->fraction.ll > b->fraction.ll)+ {+ return a->sign ? -1 : 1;+ }+ if (a->fraction.ll < b->fraction.ll)+ {+ return a->sign ? 1 : -1;+ }+ /* after all that, they're equal. */+ 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 /* L_compare_sf || L_compare_df */++#ifndef US_SOFTWARE_GOFAST++/* These should be optimized for their specific tasks someday. */++#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; /* false, truth == 0 */++ return __fpcmp_parts (&a, &b) ;+}+#endif /* L_eq_sf || L_eq_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)+{+ 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; /* true, truth != 0 */++ return __fpcmp_parts (&a, &b) ;+}+#endif /* L_ne_sf || L_ne_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)+{+ 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; /* false, truth > 0 */++ return __fpcmp_parts (&a, &b);+}+#endif /* L_gt_sf || L_gt_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)+{+ 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; /* false, truth >= 0 */+ return __fpcmp_parts (&a, &b) ;+}+#endif /* L_ge_sf || L_ge_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)+{+ 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; /* false, truth < 0 */++ return __fpcmp_parts (&a, &b);+}+#endif /* L_lt_sf || L_lt_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)+{+ 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; /* false, truth <= 0 */++ return __fpcmp_parts (&a, &b) ;+}+#endif /* L_le_sf || L_le_df */++#endif /* ! US_SOFTWARE_GOFAST */++#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 /* L_unord_sf || L_unord_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)+{+ fp_number_type in;++ in.class = CLASS_NUMBER;+ in.sign = arg_a < 0;+ if (!arg_a)+ {+ in.class = CLASS_ZERO;+ }+ else+ {+ in.normal_exp = FRACBITS + NGARDS;+ if (in.sign) + {+ /* Special case for minint, since there is no +ve integer+ representation for it */+ if (arg_a == (- MAX_SI_INT - 1))+ {+ return (FLO_type)(- MAX_SI_INT - 1);+ }+ in.fraction.ll = (-arg_a);+ }+ else+ in.fraction.ll = arg_a;++ while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))+ {+ in.fraction.ll <<= 1;+ in.normal_exp -= 1;+ }+ }+ return pack_d (&in);+}+#endif /* L_si_to_sf || L_si_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)+{+ fp_number_type in;++ in.sign = 0;+ if (!arg_a)+ {+ in.class = CLASS_ZERO;+ }+ else+ {+ in.class = CLASS_NUMBER;+ in.normal_exp = FRACBITS + NGARDS;+ in.fraction.ll = arg_a;++ while (in.fraction.ll > ((fractype)1 << (FRACBITS + NGARDS)))+ {+ in.fraction.ll >>= 1;+ in.normal_exp += 1;+ }+ while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))+ {+ in.fraction.ll <<= 1;+ in.normal_exp -= 1;+ }+ }+ 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;+ /* get reasonable MAX_SI_INT... */+ if (isinf (&a))+ return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;+ /* it is a number, but a small one */+ 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 /* L_sf_to_si || L_df_to_si */++#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+ out of libgcc2.c. We can't define these here if not GOFAST because then+ there'd be duplicate copies. */++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;+ /* it is a negative number */+ if (a.sign)+ return 0;+ /* get reasonable MAX_USI_INT... */+ if (isinf (&a))+ return MAX_USI_INT;+ /* it is a number, but a small one */+ 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 /* US_SOFTWARE_GOFAST */+#endif /* L_sf_to_usi || L_df_to_usi */++#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 /* L_negate_sf || L_negate_df */++#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 /* L_make_sf */++#ifndef FLOAT_ONLY++/* This enables one to build an fp library that supports float but not double.+ Otherwise, we would get an undefined reference to __make_dp.+ This is needed for some 8-bit ports that can't handle well values that+ are 8-bytes in size, so we just don't support double for them at all. */++#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);+}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -