📄 900-nios2.patch
字号:
+ {+ tmp->normal_exp--;++ high <<= 1;+ if (low & FRACHIGH)+ high |= 1;+ low <<= 1;+ }+ /* rounding is tricky. if we only round if it won't make us round later. */+#if 0+ if (low & FRACHIGH2)+ {+ if (((high & GARDMASK) != GARDMSB)+ && (((high + 1) & GARDMASK) == GARDMSB))+ {+ /* don't round, it gets done again later. */+ }+ else+ {+ high++;+ }+ }+#endif+ if (!ROUND_TOWARDS_ZERO && (high & GARDMASK) == GARDMSB)+ {+ if (high & (1 << NGARDS))+ {+ /* half way, so round to even */+ high += GARDROUND + 1;+ }+ else if (low)+ {+ /* but we really weren't half way */+ high += GARDROUND + 1;+ }+ }+ 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 /* L_mul_sf || L_mul_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)+{+ 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;+ }++ /* 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. */+
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -