📄 real.c
字号:
abort ();#endif }#endif ediv (d2, d1, v); /* d1/d2 */ break; case MIN_EXPR: /* min (d1,d2) */ if (ecmp (d1, d2) < 0) emov (d1, v); else emov (d2, v); break; case MAX_EXPR: /* max (d1,d2) */ if (ecmp (d1, d2) > 0) emov (d1, v); else emov (d2, v); break; default: emov (ezero, v); break; }PUT_REAL (v, value);}/* Truncate REAL_VALUE_TYPE toward zero to signed HOST_WIDE_INT. implements REAL_VALUE_RNDZINT (x) (etrunci (x)). */REAL_VALUE_TYPE etrunci (x) REAL_VALUE_TYPE x;{ unsigned EMUSHORT f[NE], g[NE]; REAL_VALUE_TYPE r; HOST_WIDE_INT l; GET_REAL (&x, g);#ifdef NANS if (eisnan (g)) return (x);#endif eifrac (g, &l, f); ltoe (&l, g); PUT_REAL (g, &r); return (r);}/* Truncate REAL_VALUE_TYPE toward zero to unsigned HOST_WIDE_INT; implements REAL_VALUE_UNSIGNED_RNDZINT (x) (etruncui (x)). */REAL_VALUE_TYPE etruncui (x) REAL_VALUE_TYPE x;{ unsigned EMUSHORT f[NE], g[NE]; REAL_VALUE_TYPE r; unsigned HOST_WIDE_INT l; GET_REAL (&x, g);#ifdef NANS if (eisnan (g)) return (x);#endif euifrac (g, &l, f); ultoe (&l, g); PUT_REAL (g, &r); return (r);}/* This is the REAL_VALUE_ATOF function. It converts a decimal string to binary, rounding off as indicated by the machine_mode argument. Then it promotes the rounded value to REAL_VALUE_TYPE. */REAL_VALUE_TYPE ereal_atof (s, t) char *s; enum machine_mode t;{ unsigned EMUSHORT tem[NE], e[NE]; REAL_VALUE_TYPE r; switch (t) { case HFmode: case SFmode: asctoe24 (s, tem); e24toe (tem, e); break; case DFmode: asctoe53 (s, tem); e53toe (tem, e); break; case XFmode: asctoe64 (s, tem); e64toe (tem, e); break; case TFmode: asctoe113 (s, tem); e113toe (tem, e); break; default: asctoe (s, e); } PUT_REAL (e, &r); return (r);}/* Expansion of REAL_NEGATE. */REAL_VALUE_TYPE ereal_negate (x) REAL_VALUE_TYPE x;{ unsigned EMUSHORT e[NE]; REAL_VALUE_TYPE r; GET_REAL (&x, e); eneg (e); PUT_REAL (e, &r); return (r);}/* Round real toward zero to HOST_WIDE_INT; implements REAL_VALUE_FIX (x). */HOST_WIDE_INTefixi (x) REAL_VALUE_TYPE x;{ unsigned EMUSHORT f[NE], g[NE]; HOST_WIDE_INT l; GET_REAL (&x, f);#ifdef NANS if (eisnan (f)) { warning ("conversion from NaN to int"); return (-1); }#endif eifrac (f, &l, g); return l;}/* Round real toward zero to unsigned HOST_WIDE_INT implements REAL_VALUE_UNSIGNED_FIX (x). Negative input returns zero. */unsigned HOST_WIDE_INTefixui (x) REAL_VALUE_TYPE x;{ unsigned EMUSHORT f[NE], g[NE]; unsigned HOST_WIDE_INT l; GET_REAL (&x, f);#ifdef NANS if (eisnan (f)) { warning ("conversion from NaN to unsigned int"); return (-1); }#endif euifrac (f, &l, g); return l;}/* REAL_VALUE_FROM_INT macro. */void ereal_from_int (d, i, j) REAL_VALUE_TYPE *d; HOST_WIDE_INT i, j;{ unsigned EMUSHORT df[NE], dg[NE]; HOST_WIDE_INT low, high; int sign; sign = 0; low = i; if ((high = j) < 0) { sign = 1; /* complement and add 1 */ high = ~high; if (low) low = -low; else high += 1; } eldexp (eone, HOST_BITS_PER_WIDE_INT, df); ultoe ((unsigned HOST_WIDE_INT *) &high, dg); emul (dg, df, dg); ultoe ((unsigned HOST_WIDE_INT *) &low, df); eadd (df, dg, dg); if (sign) eneg (dg); PUT_REAL (dg, d);}/* REAL_VALUE_FROM_UNSIGNED_INT macro. */void ereal_from_uint (d, i, j) REAL_VALUE_TYPE *d; unsigned HOST_WIDE_INT i, j;{ unsigned EMUSHORT df[NE], dg[NE]; unsigned HOST_WIDE_INT low, high; low = i; high = j; eldexp (eone, HOST_BITS_PER_WIDE_INT, df); ultoe (&high, dg); emul (dg, df, dg); ultoe (&low, df); eadd (df, dg, dg); PUT_REAL (dg, d);}/* REAL_VALUE_TO_INT macro. */void ereal_to_int (low, high, rr) HOST_WIDE_INT *low, *high; REAL_VALUE_TYPE rr;{ unsigned EMUSHORT d[NE], df[NE], dg[NE], dh[NE]; int s; GET_REAL (&rr, d);#ifdef NANS if (eisnan (d)) { warning ("conversion from NaN to int"); *low = -1; *high = -1; return; }#endif /* convert positive value */ s = 0; if (eisneg (d)) { eneg (d); s = 1; } eldexp (eone, HOST_BITS_PER_WIDE_INT, df); ediv (df, d, dg); /* dg = d / 2^32 is the high word */ euifrac (dg, (unsigned HOST_WIDE_INT *) high, dh); emul (df, dh, dg); /* fractional part is the low word */ euifrac (dg, (unsigned HOST_WIDE_INT *)low, dh); if (s) { /* complement and add 1 */ *high = ~(*high); if (*low) *low = -(*low); else *high += 1; }}/* REAL_VALUE_LDEXP macro. */REAL_VALUE_TYPEereal_ldexp (x, n) REAL_VALUE_TYPE x; int n;{ unsigned EMUSHORT e[NE], y[NE]; REAL_VALUE_TYPE r; GET_REAL (&x, e);#ifdef NANS if (eisnan (e)) return (x);#endif eldexp (e, n, y); PUT_REAL (y, &r); return (r);}/* These routines are conditionally compiled because functions of the same names may be defined in fold-const.c. */#ifdef REAL_ARITHMETIC/* Check for infinity in a REAL_VALUE_TYPE. */inttarget_isinf (x) REAL_VALUE_TYPE x;{ unsigned EMUSHORT e[NE];#ifdef INFINITY GET_REAL (&x, e); return (eisinf (e));#else return 0;#endif}/* Check whether a REAL_VALUE_TYPE item is a NaN. */inttarget_isnan (x) REAL_VALUE_TYPE x;{ unsigned EMUSHORT e[NE];#ifdef NANS GET_REAL (&x, e); return (eisnan (e));#else return (0);#endif}/* Check for a negative REAL_VALUE_TYPE number. This just checks the sign bit, so that -0 counts as negative. */inttarget_negative (x) REAL_VALUE_TYPE x;{ return ereal_isneg (x);}/* Expansion of REAL_VALUE_TRUNCATE. The result is in floating point, rounded to nearest or even. */REAL_VALUE_TYPEreal_value_truncate (mode, arg) enum machine_mode mode; REAL_VALUE_TYPE arg;{ unsigned EMUSHORT e[NE], t[NE]; REAL_VALUE_TYPE r; GET_REAL (&arg, e);#ifdef NANS if (eisnan (e)) return (arg);#endif eclear (t); switch (mode) { case TFmode: etoe113 (e, t); e113toe (t, t); break; case XFmode: etoe64 (e, t); e64toe (t, t); break; case DFmode: etoe53 (e, t); e53toe (t, t); break; case HFmode: case SFmode: etoe24 (e, t); e24toe (t, t); break; case SImode: r = etrunci (arg); return (r); /* If an unsupported type was requested, presume that the machine files know something useful to do with the unmodified value. */ default: return (arg); } PUT_REAL (t, &r); return (r);}#endif /* REAL_ARITHMETIC defined *//* Used for debugging--print the value of R in human-readable format on stderr. */voiddebug_real (r) REAL_VALUE_TYPE r;{ char dstr[30]; REAL_VALUE_TO_DECIMAL (r, "%.20g", dstr); fprintf (stderr, "%s", dstr);} /* The following routines convert REAL_VALUE_TYPE to the various floating point formats that are meaningful to supported computers. The results are returned in 32-bit pieces, each piece stored in a `long'. This is so they can be printed by statements like fprintf (file, "%lx, %lx", L[0], L[1]); that will work on both narrow- and wide-word host computers. *//* Convert R to a 128-bit long double precision value. The output array L contains four 32-bit pieces of the result, in the order they would appear in memory. */void etartdouble (r, l) REAL_VALUE_TYPE r; long l[];{ unsigned EMUSHORT e[NE]; GET_REAL (&r, e); etoe113 (e, e); endian (e, l, TFmode);}/* Convert R to a double extended precision value. The output array L contains three 32-bit pieces of the result, in the order they would appear in memory. */void etarldouble (r, l) REAL_VALUE_TYPE r; long l[];{ unsigned EMUSHORT e[NE]; GET_REAL (&r, e); etoe64 (e, e); endian (e, l, XFmode);}/* Convert R to a double precision value. The output array L contains two 32-bit pieces of the result, in the order they would appear in memory. */void etardouble (r, l) REAL_VALUE_TYPE r; long l[];{ unsigned EMUSHORT e[NE]; GET_REAL (&r, e); etoe53 (e, e); endian (e, l, DFmode);}/* Convert R to a single precision float value stored in the least-significant bits of a `long'. */longetarsingle (r) REAL_VALUE_TYPE r;{ unsigned EMUSHORT e[NE]; long l; GET_REAL (&r, e); etoe24 (e, e); endian (e, &l, SFmode); return ((long) l);}/* Convert X to a decimal ASCII string S for output to an assembly language file. Note, there is no standard way to spell infinity or a NaN, so these values may require special treatment in the tm.h macros. */voidereal_to_decimal (x, s) REAL_VALUE_TYPE x; char *s;{ unsigned EMUSHORT e[NE]; GET_REAL (&x, e); etoasc (e, s, 20);}/* Compare X and Y. Return 1 if X > Y, 0 if X == Y, -1 if X < Y, or -2 if either is a NaN. */intereal_cmp (x, y) REAL_VALUE_TYPE x, y;{ unsigned EMUSHORT ex[NE], ey[NE]; GET_REAL (&x, ex); GET_REAL (&y, ey); return (ecmp (ex, ey));}/* Return 1 if the sign bit of X is set, else return 0. */intereal_isneg (x) REAL_VALUE_TYPE x;{ unsigned EMUSHORT ex[NE]; GET_REAL (&x, ex); return (eisneg (ex));}/* End of REAL_ARITHMETIC interface *//* Extended precision IEEE binary floating point arithmetic routines Numbers are stored in C language as arrays of 16-bit unsigned short integers. The arguments of the routines are pointers to the arrays. External e type data structure, similar to Intel 8087 chip temporary real format but possibly with a larger significand: NE-1 significand words (least significant word first, most significant bit is normally set) exponent (value = EXONE for 1.0, top bit is the sign) Internal exploded e-type data structure of a number (a "word" is 16 bits): ei[0] sign word (0 for positive, 0xffff for negative) ei[1] biased exponent (value = EXONE for the number 1.0) ei[2] high guard word (always zero after normalization) ei[3] to ei[NI-2] significand (NI-4 significand words, most significant word first, most significant bit is set) ei[NI-1] low guard word (0x8000 bit is rounding place) Routines for external format e-type numbers asctoe (string, e) ASCII string to extended double e type asctoe64 (string, &d) ASCII string to long double asctoe53 (string, &d) ASCII string to double asctoe24 (string, &f) ASCII string to single asctoeg (string, e, prec) ASCII string to specified precision e24toe (&f, e) IEEE single precision to e type e53toe (&d, e) IEEE double precision to e type e64toe (&d, e) IEEE long double precision to e type e113toe (&d, e) 128-bit long double precision to e type eabs (e) absolute value eadd (a, b, c) c = b + a eclear (e) e = 0 ecmp (a, b) Returns 1 if a > b, 0 if a == b, -1 if a < b, -2 if either a or b is a NaN. ediv (a, b, c) c = b / a efloor (a, b) truncate to integer, toward -infinity efrexp (a, exp, s) extract exponent and significand eifrac (e, &l, frac) e to HOST_WIDE_INT and e type fraction euifrac (e, &l, frac) e to unsigned HOST_WIDE_INT and e type fraction einfin (e) set e to infinity, leaving its sign alone eldexp (a, n, b) multiply by 2**n
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -