|
|
1.1 root 1: /* real.c - implementation of REAL_ARITHMETIC, REAL_VALUE_ATOF,
2: and support for XFmode IEEE extended real floating point arithmetic.
3: Contributed by Stephen L. Moshier ([email protected]).
4:
5: Copyright (C) 1993 Free Software Foundation, Inc.
6:
7: This file is part of GNU CC.
8:
9: GNU CC is free software; you can redistribute it and/or modify
10: it under the terms of the GNU General Public License as published by
11: the Free Software Foundation; either version 2, or (at your option)
12: any later version.
13:
14: GNU CC is distributed in the hope that it will be useful,
15: but WITHOUT ANY WARRANTY; without even the implied warranty of
16: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17: GNU General Public License for more details.
18:
19: You should have received a copy of the GNU General Public License
20: along with GNU CC; see the file COPYING. If not, write to
21: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
22:
23: #include <stdio.h>
24: #include <errno.h>
25: #include "config.h"
26: #include "tree.h"
27:
28: #ifndef errno
29: extern int errno;
30: #endif
31:
32: /* To enable support of XFmode extended real floating point, define
33: LONG_DOUBLE_TYPE_SIZE 96 in the tm.h file (m68k.h or i386.h).
34:
35: To support cross compilation between IEEE, VAX and IBM floating
36: point formats, define REAL_ARITHMETIC in the tm.h file.
37:
38: In either case the machine files (tm.h) must not contain any code
39: that tries to use host floating point arithmetic to convert
40: REAL_VALUE_TYPEs from `double' to `float', pass them to fprintf,
41: etc. In cross-compile situations a REAL_VALUE_TYPE may not
42: be intelligible to the host computer's native arithmetic.
43:
44: The emulator defaults to the host's floating point format so that
45: its decimal conversion functions can be used if desired (see
46: real.h).
47:
48: The first part of this file interfaces gcc to ieee.c, which is a
49: floating point arithmetic suite that was not written with gcc in
50: mind. The interface is followed by ieee.c itself and related
51: items. Avoid changing ieee.c unless you have suitable test
52: programs available. A special version of the PARANOIA floating
53: point arithmetic tester, modified for this purpose, can be found
54: on usc.edu : /pub/C-numanal/ieeetest.zoo. Some tutorial
55: information on ieee.c is given in my book: S. L. Moshier,
56: _Methods and Programs for Mathematical Functions_, Prentice-Hall
57: or Simon & Schuster Int'l, 1989. A library of XFmode elementary
58: transcendental functions can be obtained by ftp from
59: research.att.com: netlib/cephes/ldouble.shar.Z */
60:
61: /* Type of computer arithmetic.
62: * Only one of DEC, IBM, MIEEE, IBMPC, or UNK should get defined.
63: */
64:
65: /* `MIEEE' refers generically to big-endian IEEE floating-point data
66: structure. This definition should work in SFmode `float' type and
67: DFmode `double' type on virtually all big-endian IEEE machines.
68: If LONG_DOUBLE_TYPE_SIZE has been defined to be 96, then MIEEE
69: also invokes the particular XFmode (`long double' type) data
70: structure used by the Motorola 680x0 series processors.
71:
72: `IBMPC' refers generally to little-endian IEEE machines. In this
73: case, if LONG_DOUBLE_TYPE_SIZE has been defined to be 96, then
74: IBMPC also invokes the particular XFmode `long double' data
75: structure used by the Intel 80x86 series processors.
76:
77: `DEC' refers specifically to the Digital Equipment Corp PDP-11
78: and VAX floating point data structure. This model currently
79: supports no type wider than DFmode.
80:
81: `IBM' refers specifically to the IBM System/370 and compatible
82: floating point data structure. This model currently supports
83: no type wider than DFmode. The IBM conversions were contributed by
84: [email protected] (Frank Crawford).
85:
86: If LONG_DOUBLE_TYPE_SIZE = 64 (the default, unless tm.h defines it)
87: then `long double' and `double' are both implemented, but they
88: both mean DFmode. In this case, the software floating-point
89: support available here is activated by writing
90: #define REAL_ARITHMETIC
91: in tm.h.
92:
93: The case LONG_DOUBLE_TYPE_SIZE = 128 activates TFmode support
94: and may deactivate XFmode since `long double' is used to refer
95: to both modes.
96:
97: The macros FLOAT_WORDS_BIG_ENDIAN, HOST_FLOAT_WORDS_BIG_ENDIAN,
98: contributed by Richard Earnshaw <[email protected]>,
99: separate the floating point unit's endian-ness from that of
100: the integer addressing. This permits one to define a big-endian
101: FPU on a little-endian machine (e.g., ARM). An extension to
102: BYTES_BIG_ENDIAN may be required for some machines in the future.
103: These optional macros may be defined in tm.h. In real.h, they
104: default to WORDS_BIG_ENDIAN, etc., so there is no need to define
105: them for any normal host or target machine on which the floats
106: and the integers have the same endian-ness. */
107:
108:
109: /* The following converts gcc macros into the ones used by this file. */
110:
111: /* REAL_ARITHMETIC defined means that macros in real.h are
112: defined to call emulator functions. */
113: #ifdef REAL_ARITHMETIC
114:
115: #if TARGET_FLOAT_FORMAT == VAX_FLOAT_FORMAT
116: /* PDP-11, Pro350, VAX: */
117: #define DEC 1
118: #else /* it's not VAX */
119: #if TARGET_FLOAT_FORMAT == IBM_FLOAT_FORMAT
120: /* IBM System/370 style */
121: #define IBM 1
122: #else /* it's also not an IBM */
123: #if TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
124: #if FLOAT_WORDS_BIG_ENDIAN
125: /* Motorola IEEE, high order words come first (Sun workstation): */
126: #define MIEEE 1
127: #else /* not big-endian */
128: /* Intel IEEE, low order words come first:
129: */
130: #define IBMPC 1
131: #endif /* big-endian */
132: #else /* it's not IEEE either */
133: /* UNKnown arithmetic. We don't support this and can't go on. */
134: unknown arithmetic type
135: #define UNK 1
136: #endif /* not IEEE */
137: #endif /* not IBM */
138: #endif /* not VAX */
139:
140: #else
141: /* REAL_ARITHMETIC not defined means that the *host's* data
142: structure will be used. It may differ by endian-ness from the
143: target machine's structure and will get its ends swapped
144: accordingly (but not here). Probably only the decimal <-> binary
145: functions in this file will actually be used in this case. */
146: #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
147: #define DEC 1
148: #else /* it's not VAX */
149: #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
150: /* IBM System/370 style */
151: #define IBM 1
152: #else /* it's also not an IBM */
153: #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
154: #if HOST_FLOAT_WORDS_BIG_ENDIAN
155: #define MIEEE 1
156: #else /* not big-endian */
157: #define IBMPC 1
158: #endif /* big-endian */
159: #else /* it's not IEEE either */
160: unknown arithmetic type
161: #define UNK 1
162: #endif /* not IEEE */
163: #endif /* not IBM */
164: #endif /* not VAX */
165:
166: #endif /* REAL_ARITHMETIC not defined */
167:
168: /* Define INFINITY for support of infinity.
169: Define NANS for support of Not-a-Number's (NaN's). */
170: #if !defined(DEC) && !defined(IBM)
171: #define INFINITY
172: #define NANS
173: #endif
174:
175: /* Support of NaNs requires support of infinity. */
176: #ifdef NANS
177: #ifndef INFINITY
178: #define INFINITY
179: #endif
180: #endif
181:
182: /* Find a host integer type that is at least 16 bits wide,
183: and another type at least twice whatever that size is. */
184:
185: #if HOST_BITS_PER_CHAR >= 16
186: #define EMUSHORT char
187: #define EMUSHORT_SIZE HOST_BITS_PER_CHAR
188: #define EMULONG_SIZE (2 * HOST_BITS_PER_CHAR)
189: #else
190: #if HOST_BITS_PER_SHORT >= 16
191: #define EMUSHORT short
192: #define EMUSHORT_SIZE HOST_BITS_PER_SHORT
193: #define EMULONG_SIZE (2 * HOST_BITS_PER_SHORT)
194: #else
195: #if HOST_BITS_PER_INT >= 16
196: #define EMUSHORT int
197: #define EMUSHORT_SIZE HOST_BITS_PER_INT
198: #define EMULONG_SIZE (2 * HOST_BITS_PER_INT)
199: #else
200: #if HOST_BITS_PER_LONG >= 16
201: #define EMUSHORT long
202: #define EMUSHORT_SIZE HOST_BITS_PER_LONG
203: #define EMULONG_SIZE (2 * HOST_BITS_PER_LONG)
204: #else
205: /* You will have to modify this program to have a smaller unit size. */
206: #define EMU_NON_COMPILE
207: #endif
208: #endif
209: #endif
210: #endif
211:
212: #if HOST_BITS_PER_SHORT >= EMULONG_SIZE
213: #define EMULONG short
214: #else
215: #if HOST_BITS_PER_INT >= EMULONG_SIZE
216: #define EMULONG int
217: #else
218: #if HOST_BITS_PER_LONG >= EMULONG_SIZE
219: #define EMULONG long
220: #else
221: #if HOST_BITS_PER_LONG_LONG >= EMULONG_SIZE
222: #define EMULONG long long int
223: #else
224: /* You will have to modify this program to have a smaller unit size. */
225: #define EMU_NON_COMPILE
226: #endif
227: #endif
228: #endif
229: #endif
230:
231:
232: /* The host interface doesn't work if no 16-bit size exists. */
233: #if EMUSHORT_SIZE != 16
234: #define EMU_NON_COMPILE
235: #endif
236:
237: /* OK to continue compilation. */
238: #ifndef EMU_NON_COMPILE
239:
240: /* Construct macros to translate between REAL_VALUE_TYPE and e type.
241: In GET_REAL and PUT_REAL, r and e are pointers.
242: A REAL_VALUE_TYPE is guaranteed to occupy contiguous locations
243: in memory, with no holes. */
244:
245: #if LONG_DOUBLE_TYPE_SIZE == 96
246: /* Number of 16 bit words in external e type format */
247: #define NE 6
248: #define MAXDECEXP 4932
249: #define MINDECEXP -4956
250: #define GET_REAL(r,e) bcopy (r, e, 2*NE)
251: #define PUT_REAL(e,r) bcopy (e, r, 2*NE)
252: #else /* no XFmode */
253: #if LONG_DOUBLE_TYPE_SIZE == 128
254: #define NE 10
255: #define MAXDECEXP 4932
256: #define MINDECEXP -4977
257: #define GET_REAL(r,e) bcopy (r, e, 2*NE)
258: #define PUT_REAL(e,r) bcopy (e, r, 2*NE)
259: #else
260: #define NE 6
261: #define MAXDECEXP 4932
262: #define MINDECEXP -4956
263: #ifdef REAL_ARITHMETIC
264: /* Emulator uses target format internally
265: but host stores it in host endian-ness. */
266:
267: #if HOST_FLOAT_WORDS_BIG_ENDIAN == FLOAT_WORDS_BIG_ENDIAN
268: #define GET_REAL(r,e) e53toe ((r), (e))
269: #define PUT_REAL(e,r) etoe53 ((e), (r))
270:
271: #else /* endian-ness differs */
272: /* emulator uses target endian-ness internally */
273: #define GET_REAL(r,e) \
274: do { EMUSHORT w[4]; \
275: w[3] = ((EMUSHORT *) r)[0]; \
276: w[2] = ((EMUSHORT *) r)[1]; \
277: w[1] = ((EMUSHORT *) r)[2]; \
278: w[0] = ((EMUSHORT *) r)[3]; \
279: e53toe (w, (e)); } while (0)
280:
281: #define PUT_REAL(e,r) \
282: do { EMUSHORT w[4]; \
283: etoe53 ((e), w); \
284: *((EMUSHORT *) r) = w[3]; \
285: *((EMUSHORT *) r + 1) = w[2]; \
286: *((EMUSHORT *) r + 2) = w[1]; \
287: *((EMUSHORT *) r + 3) = w[0]; } while (0)
288:
289: #endif /* endian-ness differs */
290:
291: #else /* not REAL_ARITHMETIC */
292:
293: /* emulator uses host format */
294: #define GET_REAL(r,e) e53toe ((r), (e))
295: #define PUT_REAL(e,r) etoe53 ((e), (r))
296:
297: #endif /* not REAL_ARITHMETIC */
298: #endif /* not TFmode */
299: #endif /* no XFmode */
300:
301:
302: /* Number of 16 bit words in internal format */
303: #define NI (NE+3)
304:
305: /* Array offset to exponent */
306: #define E 1
307:
308: /* Array offset to high guard word */
309: #define M 2
310:
311: /* Number of bits of precision */
312: #define NBITS ((NI-4)*16)
313:
314: /* Maximum number of decimal digits in ASCII conversion
315: * = NBITS*log10(2)
316: */
317: #define NDEC (NBITS*8/27)
318:
319: /* The exponent of 1.0 */
320: #define EXONE (0x3fff)
321:
322: void warning ();
323: extern int extra_warnings;
324: int ecmp (), enormlz (), eshift ();
325: int eisneg (), eisinf (), eisnan (), eiisinf (), eiisnan ();
326: void eadd (), esub (), emul (), ediv ();
327: void eshup1 (), eshup8 (), eshup6 (), eshdn1 (), eshdn8 (), eshdn6 ();
328: void eabs (), eneg (), emov (), eclear (), einfin (), efloor ();
329: void eldexp (), efrexp (), eifrac (), euifrac (), ltoe (), ultoe ();
330: void ereal_to_decimal (), eiinfin (), einan ();
331: void esqrt (), elog (), eexp (), etanh (), epow ();
332: void asctoe (), asctoe24 (), asctoe53 (), asctoe64 (), asctoe113 ();
333: void etoasc (), e24toasc (), e53toasc (), e64toasc (), e113toasc ();
334: void etoe64 (), etoe53 (), etoe24 (), e64toe (), e53toe (), e24toe ();
335: void etoe113 (), e113toe ();
336: void mtherr (), make_nan ();
337: void enan ();
338: extern unsigned EMUSHORT ezero[], ehalf[], eone[], etwo[];
339: extern unsigned EMUSHORT elog2[], esqrt2[];
340:
341: /* Copy 32-bit numbers obtained from array containing 16-bit numbers,
342: swapping ends if required, into output array of longs. The
343: result is normally passed to fprintf by the ASM_OUTPUT_ macros. */
344: void
345: endian (e, x, mode)
346: unsigned EMUSHORT e[];
347: long x[];
348: enum machine_mode mode;
349: {
350: unsigned long th, t;
351:
352: #if FLOAT_WORDS_BIG_ENDIAN
353: switch (mode)
354: {
355:
356: case TFmode:
357: /* Swap halfwords in the fourth long. */
358: th = (unsigned long) e[6] & 0xffff;
359: t = (unsigned long) e[7] & 0xffff;
360: t |= th << 16;
361: x[3] = (long) t;
362:
363: case XFmode:
364:
365: /* Swap halfwords in the third long. */
366: th = (unsigned long) e[4] & 0xffff;
367: t = (unsigned long) e[5] & 0xffff;
368: t |= th << 16;
369: x[2] = (long) t;
370: /* fall into the double case */
371:
372: case DFmode:
373:
374: /* swap halfwords in the second word */
375: th = (unsigned long) e[2] & 0xffff;
376: t = (unsigned long) e[3] & 0xffff;
377: t |= th << 16;
378: x[1] = (long) t;
379: /* fall into the float case */
380:
381: case SFmode:
382:
383: /* swap halfwords in the first word */
384: th = (unsigned long) e[0] & 0xffff;
385: t = (unsigned long) e[1] & 0xffff;
386: t |= th << 16;
387: x[0] = t;
388: break;
389:
390: default:
391: abort ();
392: }
393:
394: #else
395:
396: /* Pack the output array without swapping. */
397:
398: switch (mode)
399: {
400:
401: case TFmode:
402:
403: /* Pack the fourth long. */
404: th = (unsigned long) e[7] & 0xffff;
405: t = (unsigned long) e[6] & 0xffff;
406: t |= th << 16;
407: x[3] = (long) t;
408:
409: case XFmode:
410:
411: /* Pack the third long.
412: Each element of the input REAL_VALUE_TYPE array has 16 useful bits
413: in it. */
414: th = (unsigned long) e[5] & 0xffff;
415: t = (unsigned long) e[4] & 0xffff;
416: t |= th << 16;
417: x[2] = (long) t;
418: /* fall into the double case */
419:
420: case DFmode:
421:
422: /* pack the second long */
423: th = (unsigned long) e[3] & 0xffff;
424: t = (unsigned long) e[2] & 0xffff;
425: t |= th << 16;
426: x[1] = (long) t;
427: /* fall into the float case */
428:
429: case SFmode:
430:
431: /* pack the first long */
432: th = (unsigned long) e[1] & 0xffff;
433: t = (unsigned long) e[0] & 0xffff;
434: t |= th << 16;
435: x[0] = t;
436: break;
437:
438: default:
439: abort ();
440: }
441:
442: #endif
443: }
444:
445:
446: /* This is the implementation of the REAL_ARITHMETIC macro.
447: */
448: void
449: earith (value, icode, r1, r2)
450: REAL_VALUE_TYPE *value;
451: int icode;
452: REAL_VALUE_TYPE *r1;
453: REAL_VALUE_TYPE *r2;
454: {
455: unsigned EMUSHORT d1[NE], d2[NE], v[NE];
456: enum tree_code code;
457:
458: GET_REAL (r1, d1);
459: GET_REAL (r2, d2);
460: #ifdef NANS
461: /* Return NaN input back to the caller. */
462: if (eisnan (d1))
463: {
464: PUT_REAL (d1, value);
465: return;
466: }
467: if (eisnan (d2))
468: {
469: PUT_REAL (d2, value);
470: return;
471: }
472: #endif
473: code = (enum tree_code) icode;
474: switch (code)
475: {
476: case PLUS_EXPR:
477: eadd (d2, d1, v);
478: break;
479:
480: case MINUS_EXPR:
481: esub (d2, d1, v); /* d1 - d2 */
482: break;
483:
484: case MULT_EXPR:
485: emul (d2, d1, v);
486: break;
487:
488: case RDIV_EXPR:
489: #ifndef REAL_INFINITY
490: if (ecmp (d2, ezero) == 0)
491: {
492: #ifdef NANS
493: enan (v);
494: break;
495: #else
496: abort ();
497: #endif
498: }
499: #endif
500: ediv (d2, d1, v); /* d1/d2 */
501: break;
502:
503: case MIN_EXPR: /* min (d1,d2) */
504: if (ecmp (d1, d2) < 0)
505: emov (d1, v);
506: else
507: emov (d2, v);
508: break;
509:
510: case MAX_EXPR: /* max (d1,d2) */
511: if (ecmp (d1, d2) > 0)
512: emov (d1, v);
513: else
514: emov (d2, v);
515: break;
516: default:
517: emov (ezero, v);
518: break;
519: }
520: PUT_REAL (v, value);
521: }
522:
523:
524: /* Truncate REAL_VALUE_TYPE toward zero to signed HOST_WIDE_INT
525: * implements REAL_VALUE_RNDZINT (x) (etrunci (x))
526: */
527: REAL_VALUE_TYPE
528: etrunci (x)
529: REAL_VALUE_TYPE x;
530: {
531: unsigned EMUSHORT f[NE], g[NE];
532: REAL_VALUE_TYPE r;
533: HOST_WIDE_INT l;
534:
535: GET_REAL (&x, g);
536: #ifdef NANS
537: if (eisnan (g))
538: return (x);
539: #endif
540: eifrac (g, &l, f);
541: ltoe (&l, g);
542: PUT_REAL (g, &r);
543: return (r);
544: }
545:
546:
547: /* Truncate REAL_VALUE_TYPE toward zero to unsigned HOST_WIDE_INT
548: * implements REAL_VALUE_UNSIGNED_RNDZINT (x) (etruncui (x))
549: */
550: REAL_VALUE_TYPE
551: etruncui (x)
552: REAL_VALUE_TYPE x;
553: {
554: unsigned EMUSHORT f[NE], g[NE];
555: REAL_VALUE_TYPE r;
556: unsigned HOST_WIDE_INT l;
557:
558: GET_REAL (&x, g);
559: #ifdef NANS
560: if (eisnan (g))
561: return (x);
562: #endif
563: euifrac (g, &l, f);
564: ultoe (&l, g);
565: PUT_REAL (g, &r);
566: return (r);
567: }
568:
569:
570: /* This is the REAL_VALUE_ATOF function.
571: * It converts a decimal string to binary, rounding off
572: * as indicated by the machine_mode argument. Then it
573: * promotes the rounded value to REAL_VALUE_TYPE.
574: */
575: REAL_VALUE_TYPE
576: ereal_atof (s, t)
577: char *s;
578: enum machine_mode t;
579: {
580: unsigned EMUSHORT tem[NE], e[NE];
581: REAL_VALUE_TYPE r;
582:
583: switch (t)
584: {
585: case SFmode:
586: asctoe24 (s, tem);
587: e24toe (tem, e);
588: break;
589: case DFmode:
590: asctoe53 (s, tem);
591: e53toe (tem, e);
592: break;
593: case XFmode:
594: asctoe64 (s, tem);
595: e64toe (tem, e);
596: break;
597: case TFmode:
598: asctoe113 (s, tem);
599: e113toe (tem, e);
600: break;
601: default:
602: asctoe (s, e);
603: }
604: PUT_REAL (e, &r);
605: return (r);
606: }
607:
608:
609: /* Expansion of REAL_NEGATE.
610: */
611: REAL_VALUE_TYPE
612: ereal_negate (x)
613: REAL_VALUE_TYPE x;
614: {
615: unsigned EMUSHORT e[NE];
616: REAL_VALUE_TYPE r;
617:
618: GET_REAL (&x, e);
619: #ifdef NANS
620: if (eisnan (e))
621: return (x);
622: #endif
623: eneg (e);
624: PUT_REAL (e, &r);
625: return (r);
626: }
627:
628:
629: /* Round real toward zero to HOST_WIDE_INT
630: * implements REAL_VALUE_FIX (x).
631: */
632: HOST_WIDE_INT
633: efixi (x)
634: REAL_VALUE_TYPE x;
635: {
636: unsigned EMUSHORT f[NE], g[NE];
637: HOST_WIDE_INT l;
638:
639: GET_REAL (&x, f);
640: #ifdef NANS
641: if (eisnan (f))
642: {
643: warning ("conversion from NaN to int");
644: return (-1);
645: }
646: #endif
647: eifrac (f, &l, g);
648: return l;
649: }
650:
651: /* Round real toward zero to unsigned HOST_WIDE_INT
652: * implements REAL_VALUE_UNSIGNED_FIX (x).
653: * Negative input returns zero.
654: */
655: unsigned HOST_WIDE_INT
656: efixui (x)
657: REAL_VALUE_TYPE x;
658: {
659: unsigned EMUSHORT f[NE], g[NE];
660: unsigned HOST_WIDE_INT l;
661:
662: GET_REAL (&x, f);
663: #ifdef NANS
664: if (eisnan (f))
665: {
666: warning ("conversion from NaN to unsigned int");
667: return (-1);
668: }
669: #endif
670: euifrac (f, &l, g);
671: return l;
672: }
673:
674:
675: /* REAL_VALUE_FROM_INT macro.
676: */
677: void
678: ereal_from_int (d, i, j)
679: REAL_VALUE_TYPE *d;
680: HOST_WIDE_INT i, j;
681: {
682: unsigned EMUSHORT df[NE], dg[NE];
683: HOST_WIDE_INT low, high;
684: int sign;
685:
686: sign = 0;
687: low = i;
688: if ((high = j) < 0)
689: {
690: sign = 1;
691: /* complement and add 1 */
692: high = ~high;
693: if (low)
694: low = -low;
695: else
696: high += 1;
697: }
698: eldexp (eone, HOST_BITS_PER_WIDE_INT, df);
699: ultoe (&high, dg);
700: emul (dg, df, dg);
701: ultoe (&low, df);
702: eadd (df, dg, dg);
703: if (sign)
704: eneg (dg);
705: PUT_REAL (dg, d);
706: }
707:
708:
709: /* REAL_VALUE_FROM_UNSIGNED_INT macro.
710: */
711: void
712: ereal_from_uint (d, i, j)
713: REAL_VALUE_TYPE *d;
714: unsigned HOST_WIDE_INT i, j;
715: {
716: unsigned EMUSHORT df[NE], dg[NE];
717: unsigned HOST_WIDE_INT low, high;
718:
719: low = i;
720: high = j;
721: eldexp (eone, HOST_BITS_PER_WIDE_INT, df);
722: ultoe (&high, dg);
723: emul (dg, df, dg);
724: ultoe (&low, df);
725: eadd (df, dg, dg);
726: PUT_REAL (dg, d);
727: }
728:
729:
730: /* REAL_VALUE_TO_INT macro
731: */
732: void
733: ereal_to_int (low, high, rr)
734: HOST_WIDE_INT *low, *high;
735: REAL_VALUE_TYPE rr;
736: {
737: unsigned EMUSHORT d[NE], df[NE], dg[NE], dh[NE];
738: int s;
739:
740: GET_REAL (&rr, d);
741: #ifdef NANS
742: if (eisnan (d))
743: {
744: warning ("conversion from NaN to int");
745: *low = -1;
746: *high = -1;
747: return;
748: }
749: #endif
750: /* convert positive value */
751: s = 0;
752: if (eisneg (d))
753: {
754: eneg (d);
755: s = 1;
756: }
757: eldexp (eone, HOST_BITS_PER_WIDE_INT, df);
758: ediv (df, d, dg); /* dg = d / 2^32 is the high word */
759: euifrac (dg, high, dh);
760: emul (df, dh, dg); /* fractional part is the low word */
761: euifrac (dg, low, dh);
762: if (s)
763: {
764: /* complement and add 1 */
765: *high = ~(*high);
766: if (*low)
767: *low = -(*low);
768: else
769: *high += 1;
770: }
771: }
772:
773:
774: /* REAL_VALUE_LDEXP macro.
775: */
776: REAL_VALUE_TYPE
777: ereal_ldexp (x, n)
778: REAL_VALUE_TYPE x;
779: int n;
780: {
781: unsigned EMUSHORT e[NE], y[NE];
782: REAL_VALUE_TYPE r;
783:
784: GET_REAL (&x, e);
785: #ifdef NANS
786: if (eisnan (e))
787: return (x);
788: #endif
789: eldexp (e, n, y);
790: PUT_REAL (y, &r);
791: return (r);
792: }
793:
794: /* These routines are conditionally compiled because functions
795: * of the same names may be defined in fold-const.c. */
796: #ifdef REAL_ARITHMETIC
797:
798: /* Check for infinity in a REAL_VALUE_TYPE. */
799: int
800: target_isinf (x)
801: REAL_VALUE_TYPE x;
802: {
803: unsigned EMUSHORT e[NE];
804:
805: #ifdef INFINITY
806: GET_REAL (&x, e);
807: return (eisinf (e));
808: #else
809: return 0;
810: #endif
811: }
812:
813:
814: /* Check whether a REAL_VALUE_TYPE item is a NaN. */
815:
816: int
817: target_isnan (x)
818: REAL_VALUE_TYPE x;
819: {
820: unsigned EMUSHORT e[NE];
821:
822: #ifdef NANS
823: GET_REAL (&x, e);
824: return (eisnan (e));
825: #else
826: return (0);
827: #endif
828: }
829:
830:
831: /* Check for a negative REAL_VALUE_TYPE number.
832: * this means strictly less than zero, not -0.
833: */
834:
835: int
836: target_negative (x)
837: REAL_VALUE_TYPE x;
838: {
839: unsigned EMUSHORT e[NE];
840:
841: GET_REAL (&x, e);
842: if (ecmp (e, ezero) == -1)
843: return (1);
844: return (0);
845: }
846:
847: /* Expansion of REAL_VALUE_TRUNCATE.
848: * The result is in floating point, rounded to nearest or even.
849: */
850: REAL_VALUE_TYPE
851: real_value_truncate (mode, arg)
852: enum machine_mode mode;
853: REAL_VALUE_TYPE arg;
854: {
855: unsigned EMUSHORT e[NE], t[NE];
856: REAL_VALUE_TYPE r;
857:
858: GET_REAL (&arg, e);
859: #ifdef NANS
860: if (eisnan (e))
861: return (arg);
862: #endif
863: eclear (t);
864: switch (mode)
865: {
866: case TFmode:
867: etoe113 (e, t);
868: e113toe (t, t);
869: break;
870:
871: case XFmode:
872: etoe64 (e, t);
873: e64toe (t, t);
874: break;
875:
876: case DFmode:
877: etoe53 (e, t);
878: e53toe (t, t);
879: break;
880:
881: case SFmode:
882: etoe24 (e, t);
883: e24toe (t, t);
884: break;
885:
886: case SImode:
887: r = etrunci (arg);
888: return (r);
889:
890: default:
891: abort ();
892: }
893: PUT_REAL (t, &r);
894: return (r);
895: }
896:
897: #endif /* REAL_ARITHMETIC defined */
898:
899: /* Used for debugging--print the value of R in human-readable format
900: on stderr. */
901:
902: void
903: debug_real (r)
904: REAL_VALUE_TYPE r;
905: {
906: char dstr[30];
907:
908: REAL_VALUE_TO_DECIMAL (r, "%.20g", dstr);
909: fprintf (stderr, "%s", dstr);
910: }
911:
912:
913: /* Target values are arrays of host longs. A long is guaranteed
914: to be at least 32 bits wide. */
915:
916: /* 128-bit long double */
917: void
918: etartdouble (r, l)
919: REAL_VALUE_TYPE r;
920: long l[];
921: {
922: unsigned EMUSHORT e[NE];
923:
924: GET_REAL (&r, e);
925: etoe113 (e, e);
926: endian (e, l, TFmode);
927: }
928:
929: /* 80-bit long double */
930: void
931: etarldouble (r, l)
932: REAL_VALUE_TYPE r;
933: long l[];
934: {
935: unsigned EMUSHORT e[NE];
936:
937: GET_REAL (&r, e);
938: etoe64 (e, e);
939: endian (e, l, XFmode);
940: }
941:
942: void
943: etardouble (r, l)
944: REAL_VALUE_TYPE r;
945: long l[];
946: {
947: unsigned EMUSHORT e[NE];
948:
949: GET_REAL (&r, e);
950: etoe53 (e, e);
951: endian (e, l, DFmode);
952: }
953:
954: long
955: etarsingle (r)
956: REAL_VALUE_TYPE r;
957: {
958: unsigned EMUSHORT e[NE];
959: unsigned long l;
960:
961: GET_REAL (&r, e);
962: etoe24 (e, e);
963: endian (e, &l, SFmode);
964: return ((long) l);
965: }
966:
967: void
968: ereal_to_decimal (x, s)
969: REAL_VALUE_TYPE x;
970: char *s;
971: {
972: unsigned EMUSHORT e[NE];
973:
974: GET_REAL (&x, e);
975: etoasc (e, s, 20);
976: }
977:
978: int
979: ereal_cmp (x, y)
980: REAL_VALUE_TYPE x, y;
981: {
982: unsigned EMUSHORT ex[NE], ey[NE];
983:
984: GET_REAL (&x, ex);
985: GET_REAL (&y, ey);
986: return (ecmp (ex, ey));
987: }
988:
989: int
990: ereal_isneg (x)
991: REAL_VALUE_TYPE x;
992: {
993: unsigned EMUSHORT ex[NE];
994:
995: GET_REAL (&x, ex);
996: return (eisneg (ex));
997: }
998:
999: /* End of REAL_ARITHMETIC interface */
1000:
1001: /* ieee.c
1002: *
1003: * Extended precision IEEE binary floating point arithmetic routines
1004: *
1005: * Numbers are stored in C language as arrays of 16-bit unsigned
1006: * short integers. The arguments of the routines are pointers to
1007: * the arrays.
1008: *
1009: *
1010: * External e type data structure, simulates Intel 8087 chip
1011: * temporary real format but possibly with a larger significand:
1012: *
1013: * NE-1 significand words (least significant word first,
1014: * most significant bit is normally set)
1015: * exponent (value = EXONE for 1.0,
1016: * top bit is the sign)
1017: *
1018: *
1019: * Internal data structure of a number (a "word" is 16 bits):
1020: *
1021: * ei[0] sign word (0 for positive, 0xffff for negative)
1022: * ei[1] biased exponent (value = EXONE for the number 1.0)
1023: * ei[2] high guard word (always zero after normalization)
1024: * ei[3]
1025: * to ei[NI-2] significand (NI-4 significand words,
1026: * most significant word first,
1027: * most significant bit is set)
1028: * ei[NI-1] low guard word (0x8000 bit is rounding place)
1029: *
1030: *
1031: *
1032: * Routines for external format numbers
1033: *
1034: * asctoe (string, e) ASCII string to extended double e type
1035: * asctoe64 (string, &d) ASCII string to long double
1036: * asctoe53 (string, &d) ASCII string to double
1037: * asctoe24 (string, &f) ASCII string to single
1038: * asctoeg (string, e, prec) ASCII string to specified precision
1039: * e24toe (&f, e) IEEE single precision to e type
1040: * e53toe (&d, e) IEEE double precision to e type
1041: * e64toe (&d, e) IEEE long double precision to e type
1042: * e113toe (&d, e) 128-bit long double precision to e type
1043: * eabs (e) absolute value
1044: * eadd (a, b, c) c = b + a
1045: * eclear (e) e = 0
1046: * ecmp (a, b) Returns 1 if a > b, 0 if a == b,
1047: * -1 if a < b, -2 if either a or b is a NaN.
1048: * ediv (a, b, c) c = b / a
1049: * efloor (a, b) truncate to integer, toward -infinity
1050: * efrexp (a, exp, s) extract exponent and significand
1051: * eifrac (e, &l, frac) e to HOST_WIDE_INT and e type fraction
1052: * euifrac (e, &l, frac) e to unsigned HOST_WIDE_INT and e type fraction
1053: * einfin (e) set e to infinity, leaving its sign alone
1054: * eldexp (a, n, b) multiply by 2**n
1055: * emov (a, b) b = a
1056: * emul (a, b, c) c = b * a
1057: * eneg (e) e = -e
1058: * eround (a, b) b = nearest integer value to a
1059: * esub (a, b, c) c = b - a
1060: * e24toasc (&f, str, n) single to ASCII string, n digits after decimal
1061: * e53toasc (&d, str, n) double to ASCII string, n digits after decimal
1062: * e64toasc (&d, str, n) 80-bit long double to ASCII string
1063: * e113toasc (&d, str, n) 128-bit long double to ASCII string
1064: * etoasc (e, str, n) e to ASCII string, n digits after decimal
1065: * etoe24 (e, &f) convert e type to IEEE single precision
1066: * etoe53 (e, &d) convert e type to IEEE double precision
1067: * etoe64 (e, &d) convert e type to IEEE long double precision
1068: * ltoe (&l, e) HOST_WIDE_INT to e type
1069: * ultoe (&l, e) unsigned HOST_WIDE_INT to e type
1070: * eisneg (e) 1 if sign bit of e != 0, else 0
1071: * eisinf (e) 1 if e has maximum exponent (non-IEEE)
1072: * or is infinite (IEEE)
1073: * eisnan (e) 1 if e is a NaN
1074: *
1075: *
1076: * Routines for internal format numbers
1077: *
1078: * eaddm (ai, bi) add significands, bi = bi + ai
1079: * ecleaz (ei) ei = 0
1080: * ecleazs (ei) set ei = 0 but leave its sign alone
1081: * ecmpm (ai, bi) compare significands, return 1, 0, or -1
1082: * edivm (ai, bi) divide significands, bi = bi / ai
1083: * emdnorm (ai,l,s,exp) normalize and round off
1084: * emovi (a, ai) convert external a to internal ai
1085: * emovo (ai, a) convert internal ai to external a
1086: * emovz (ai, bi) bi = ai, low guard word of bi = 0
1087: * emulm (ai, bi) multiply significands, bi = bi * ai
1088: * enormlz (ei) left-justify the significand
1089: * eshdn1 (ai) shift significand and guards down 1 bit
1090: * eshdn8 (ai) shift down 8 bits
1091: * eshdn6 (ai) shift down 16 bits
1092: * eshift (ai, n) shift ai n bits up (or down if n < 0)
1093: * eshup1 (ai) shift significand and guards up 1 bit
1094: * eshup8 (ai) shift up 8 bits
1095: * eshup6 (ai) shift up 16 bits
1096: * esubm (ai, bi) subtract significands, bi = bi - ai
1097: * eiisinf (ai) 1 if infinite
1098: * eiisnan (ai) 1 if a NaN
1099: * einan (ai) set ai = NaN
1100: * eiinfin (ai) set ai = infinity
1101: *
1102: *
1103: * The result is always normalized and rounded to NI-4 word precision
1104: * after each arithmetic operation.
1105: *
1106: * Exception flags are NOT fully supported.
1107: *
1108: * Signaling NaN's are NOT supported; they are treated the same
1109: * as quiet NaN's.
1110: *
1111: * Define INFINITY for support of infinity; otherwise a
1112: * saturation arithmetic is implemented.
1113: *
1114: * Define NANS for support of Not-a-Number items; otherwise the
1115: * arithmetic will never produce a NaN output, and might be confused
1116: * by a NaN input.
1117: * If NaN's are supported, the output of `ecmp (a,b)' is -2 if
1118: * either a or b is a NaN. This means asking `if (ecmp (a,b) < 0)'
1119: * may not be legitimate. Use `if (ecmp (a,b) == -1)' for `less than'
1120: * if in doubt.
1121: *
1122: * Denormals are always supported here where appropriate (e.g., not
1123: * for conversion to DEC numbers).
1124: *
1125: */
1126:
1127:
1128: /* mconf.h
1129: *
1130: * Common include file for math routines
1131: *
1132: *
1133: *
1134: * SYNOPSIS:
1135: *
1136: * #include "mconf.h"
1137: *
1138: *
1139: *
1140: * DESCRIPTION:
1141: *
1142: * This file contains definitions for error codes that are
1143: * passed to the common error handling routine mtherr
1144: * (which see).
1145: *
1146: * The file also includes a conditional assembly definition
1147: * for the type of computer arithmetic (Intel IEEE, DEC, Motorola
1148: * IEEE, or UNKnown).
1149: *
1150: * For Digital Equipment PDP-11 and VAX computers, certain
1151: * IBM systems, and others that use numbers with a 56-bit
1152: * significand, the symbol DEC should be defined. In this
1153: * mode, most floating point constants are given as arrays
1154: * of octal integers to eliminate decimal to binary conversion
1155: * errors that might be introduced by the compiler.
1156: *
1157: * For computers, such as IBM PC, that follow the IEEE
1158: * Standard for Binary Floating Point Arithmetic (ANSI/IEEE
1159: * Std 754-1985), the symbol IBMPC or MIEEE should be defined.
1160: * These numbers have 53-bit significands. In this mode, constants
1161: * are provided as arrays of hexadecimal 16 bit integers.
1162: *
1163: * To accommodate other types of computer arithmetic, all
1164: * constants are also provided in a normal decimal radix
1165: * which one can hope are correctly converted to a suitable
1166: * format by the available C language compiler. To invoke
1167: * this mode, the symbol UNK is defined.
1168: *
1169: * An important difference among these modes is a predefined
1170: * set of machine arithmetic constants for each. The numbers
1171: * MACHEP (the machine roundoff error), MAXNUM (largest number
1172: * represented), and several other parameters are preset by
1173: * the configuration symbol. Check the file const.c to
1174: * ensure that these values are correct for your computer.
1175: *
1176: * For ANSI C compatibility, define ANSIC equal to 1. Currently
1177: * this affects only the atan2 function and others that use it.
1178: */
1179:
1180: /* Constant definitions for math error conditions. */
1181:
1182: #define DOMAIN 1 /* argument domain error */
1183: #define SING 2 /* argument singularity */
1184: #define OVERFLOW 3 /* overflow range error */
1185: #define UNDERFLOW 4 /* underflow range error */
1186: #define TLOSS 5 /* total loss of precision */
1187: #define PLOSS 6 /* partial loss of precision */
1188: #define INVALID 7 /* NaN-producing operation */
1189:
1190: /* e type constants used by high precision check routines */
1191:
1192: #if LONG_DOUBLE_TYPE_SIZE == 128
1193: /* 0.0 */
1194: unsigned EMUSHORT ezero[NE] =
1195: {0x0000, 0x0000, 0x0000, 0x0000,
1196: 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,};
1197: extern unsigned EMUSHORT ezero[];
1198:
1199: /* 5.0E-1 */
1200: unsigned EMUSHORT ehalf[NE] =
1201: {0x0000, 0x0000, 0x0000, 0x0000,
1202: 0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x3ffe,};
1203: extern unsigned EMUSHORT ehalf[];
1204:
1205: /* 1.0E0 */
1206: unsigned EMUSHORT eone[NE] =
1207: {0x0000, 0x0000, 0x0000, 0x0000,
1208: 0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x3fff,};
1209: extern unsigned EMUSHORT eone[];
1210:
1211: /* 2.0E0 */
1212: unsigned EMUSHORT etwo[NE] =
1213: {0x0000, 0x0000, 0x0000, 0x0000,
1214: 0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x4000,};
1215: extern unsigned EMUSHORT etwo[];
1216:
1217: /* 3.2E1 */
1218: unsigned EMUSHORT e32[NE] =
1219: {0x0000, 0x0000, 0x0000, 0x0000,
1220: 0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x4004,};
1221: extern unsigned EMUSHORT e32[];
1222:
1223: /* 6.93147180559945309417232121458176568075500134360255E-1 */
1224: unsigned EMUSHORT elog2[NE] =
1225: {0x40f3, 0xf6af, 0x03f2, 0xb398,
1226: 0xc9e3, 0x79ab, 0150717, 0013767, 0130562, 0x3ffe,};
1227: extern unsigned EMUSHORT elog2[];
1228:
1229: /* 1.41421356237309504880168872420969807856967187537695E0 */
1230: unsigned EMUSHORT esqrt2[NE] =
1231: {0x1d6f, 0xbe9f, 0x754a, 0x89b3,
1232: 0x597d, 0x6484, 0174736, 0171463, 0132404, 0x3fff,};
1233: extern unsigned EMUSHORT esqrt2[];
1234:
1235: /* 3.14159265358979323846264338327950288419716939937511E0 */
1236: unsigned EMUSHORT epi[NE] =
1237: {0x2902, 0x1cd1, 0x80dc, 0x628b,
1238: 0xc4c6, 0xc234, 0020550, 0155242, 0144417, 0040000,};
1239: extern unsigned EMUSHORT epi[];
1240:
1241: #else
1242: /* LONG_DOUBLE_TYPE_SIZE is other than 128 */
1243: unsigned EMUSHORT ezero[NE] =
1244: {0, 0000000, 0000000, 0000000, 0000000, 0000000,};
1245: unsigned EMUSHORT ehalf[NE] =
1246: {0, 0000000, 0000000, 0000000, 0100000, 0x3ffe,};
1247: unsigned EMUSHORT eone[NE] =
1248: {0, 0000000, 0000000, 0000000, 0100000, 0x3fff,};
1249: unsigned EMUSHORT etwo[NE] =
1250: {0, 0000000, 0000000, 0000000, 0100000, 0040000,};
1251: unsigned EMUSHORT e32[NE] =
1252: {0, 0000000, 0000000, 0000000, 0100000, 0040004,};
1253: unsigned EMUSHORT elog2[NE] =
1254: {0xc9e4, 0x79ab, 0150717, 0013767, 0130562, 0x3ffe,};
1255: unsigned EMUSHORT esqrt2[NE] =
1256: {0x597e, 0x6484, 0174736, 0171463, 0132404, 0x3fff,};
1257: unsigned EMUSHORT epi[NE] =
1258: {0xc4c6, 0xc234, 0020550, 0155242, 0144417, 0040000,};
1259: #endif
1260:
1261:
1262:
1263: /* Control register for rounding precision.
1264: * This can be set to 113 (if NE=10), 80 (if NE=6), 64, 56, 53, or 24 bits.
1265: */
1266: int rndprc = NBITS;
1267: extern int rndprc;
1268:
1269: void eaddm (), esubm (), emdnorm (), asctoeg ();
1270: static void toe24 (), toe53 (), toe64 (), toe113 ();
1271: void eremain (), einit (), eiremain ();
1272: int ecmpm (), edivm (), emulm ();
1273: void emovi (), emovo (), emovz (), ecleaz (), ecleazs (), eadd1 ();
1274: #ifdef DEC
1275: void etodec (), todec (), dectoe ();
1276: #endif
1277: #ifdef IBM
1278: void etoibm (), toibm (), ibmtoe ();
1279: #endif
1280:
1281:
1282: void
1283: einit ()
1284: {
1285: }
1286:
1287: /*
1288: ; Clear out entire external format number.
1289: ;
1290: ; unsigned EMUSHORT x[];
1291: ; eclear (x);
1292: */
1293:
1294: void
1295: eclear (x)
1296: register unsigned EMUSHORT *x;
1297: {
1298: register int i;
1299:
1300: for (i = 0; i < NE; i++)
1301: *x++ = 0;
1302: }
1303:
1304:
1305:
1306: /* Move external format number from a to b.
1307: *
1308: * emov (a, b);
1309: */
1310:
1311: void
1312: emov (a, b)
1313: register unsigned EMUSHORT *a, *b;
1314: {
1315: register int i;
1316:
1317: for (i = 0; i < NE; i++)
1318: *b++ = *a++;
1319: }
1320:
1321:
1322: /*
1323: ; Absolute value of external format number
1324: ;
1325: ; EMUSHORT x[NE];
1326: ; eabs (x);
1327: */
1328:
1329: void
1330: eabs (x)
1331: unsigned EMUSHORT x[]; /* x is the memory address of a short */
1332: {
1333:
1334: x[NE - 1] &= 0x7fff; /* sign is top bit of last word of external format */
1335: }
1336:
1337:
1338:
1339:
1340: /*
1341: ; Negate external format number
1342: ;
1343: ; unsigned EMUSHORT x[NE];
1344: ; eneg (x);
1345: */
1346:
1347: void
1348: eneg (x)
1349: unsigned EMUSHORT x[];
1350: {
1351:
1352: #ifdef NANS
1353: if (eisnan (x))
1354: return;
1355: #endif
1356: x[NE - 1] ^= 0x8000; /* Toggle the sign bit */
1357: }
1358:
1359:
1360:
1361: /* Return 1 if external format number is negative,
1362: * else return zero, including when it is a NaN.
1363: */
1364: int
1365: eisneg (x)
1366: unsigned EMUSHORT x[];
1367: {
1368:
1369: #ifdef NANS
1370: if (eisnan (x))
1371: return (0);
1372: #endif
1373: if (x[NE - 1] & 0x8000)
1374: return (1);
1375: else
1376: return (0);
1377: }
1378:
1379:
1380: /* Return 1 if external format number is infinity.
1381: * else return zero.
1382: */
1383: int
1384: eisinf (x)
1385: unsigned EMUSHORT x[];
1386: {
1387:
1388: #ifdef NANS
1389: if (eisnan (x))
1390: return (0);
1391: #endif
1392: if ((x[NE - 1] & 0x7fff) == 0x7fff)
1393: return (1);
1394: else
1395: return (0);
1396: }
1397:
1398:
1399: /* Check if e-type number is not a number.
1400: The bit pattern is one that we defined, so we know for sure how to
1401: detect it. */
1402:
1403: int
1404: eisnan (x)
1405: unsigned EMUSHORT x[];
1406: {
1407:
1408: #ifdef NANS
1409: int i;
1410: /* NaN has maximum exponent */
1411: if ((x[NE - 1] & 0x7fff) != 0x7fff)
1412: return (0);
1413: /* ... and non-zero significand field. */
1414: for (i = 0; i < NE - 1; i++)
1415: {
1416: if (*x++ != 0)
1417: return (1);
1418: }
1419: #endif
1420: return (0);
1421: }
1422:
1423: /* Fill external format number with infinity pattern (IEEE)
1424: or largest possible number (non-IEEE). */
1425:
1426: void
1427: einfin (x)
1428: register unsigned EMUSHORT *x;
1429: {
1430: register int i;
1431:
1432: #ifdef INFINITY
1433: for (i = 0; i < NE - 1; i++)
1434: *x++ = 0;
1435: *x |= 32767;
1436: #else
1437: for (i = 0; i < NE - 1; i++)
1438: *x++ = 0xffff;
1439: *x |= 32766;
1440: if (rndprc < NBITS)
1441: {
1442: if (rndprc == 113)
1443: {
1444: *(x - 9) = 0;
1445: *(x - 8) = 0;
1446: }
1447: if (rndprc == 64)
1448: {
1449: *(x - 5) = 0;
1450: }
1451: if (rndprc == 53)
1452: {
1453: *(x - 4) = 0xf800;
1454: }
1455: else
1456: {
1457: *(x - 4) = 0;
1458: *(x - 3) = 0;
1459: *(x - 2) = 0xff00;
1460: }
1461: }
1462: #endif
1463: }
1464:
1465:
1466: /* Output an e-type NaN.
1467: This generates Intel's quiet NaN pattern for extended real.
1468: The exponent is 7fff, the leading mantissa word is c000. */
1469:
1470: void
1471: enan (x)
1472: register unsigned EMUSHORT *x;
1473: {
1474: register int i;
1475:
1476: for (i = 0; i < NE - 2; i++)
1477: *x++ = 0;
1478: *x++ = 0xc000;
1479: *x = 0x7fff;
1480: }
1481:
1482:
1483: /* Move in external format number,
1484: * converting it to internal format.
1485: */
1486: void
1487: emovi (a, b)
1488: unsigned EMUSHORT *a, *b;
1489: {
1490: register unsigned EMUSHORT *p, *q;
1491: int i;
1492:
1493: q = b;
1494: p = a + (NE - 1); /* point to last word of external number */
1495: /* get the sign bit */
1496: if (*p & 0x8000)
1497: *q++ = 0xffff;
1498: else
1499: *q++ = 0;
1500: /* get the exponent */
1501: *q = *p--;
1502: *q++ &= 0x7fff; /* delete the sign bit */
1503: #ifdef INFINITY
1504: if ((*(q - 1) & 0x7fff) == 0x7fff)
1505: {
1506: #ifdef NANS
1507: if (eisnan (a))
1508: {
1509: *q++ = 0;
1510: for (i = 3; i < NI; i++)
1511: *q++ = *p--;
1512: return;
1513: }
1514: #endif
1515: for (i = 2; i < NI; i++)
1516: *q++ = 0;
1517: return;
1518: }
1519: #endif
1520: /* clear high guard word */
1521: *q++ = 0;
1522: /* move in the significand */
1523: for (i = 0; i < NE - 1; i++)
1524: *q++ = *p--;
1525: /* clear low guard word */
1526: *q = 0;
1527: }
1528:
1529:
1530: /* Move internal format number out,
1531: * converting it to external format.
1532: */
1533: void
1534: emovo (a, b)
1535: unsigned EMUSHORT *a, *b;
1536: {
1537: register unsigned EMUSHORT *p, *q;
1538: unsigned EMUSHORT i;
1539:
1540: p = a;
1541: q = b + (NE - 1); /* point to output exponent */
1542: /* combine sign and exponent */
1543: i = *p++;
1544: if (i)
1545: *q-- = *p++ | 0x8000;
1546: else
1547: *q-- = *p++;
1548: #ifdef INFINITY
1549: if (*(p - 1) == 0x7fff)
1550: {
1551: #ifdef NANS
1552: if (eiisnan (a))
1553: {
1554: enan (b);
1555: return;
1556: }
1557: #endif
1558: einfin (b);
1559: return;
1560: }
1561: #endif
1562: /* skip over guard word */
1563: ++p;
1564: /* move the significand */
1565: for (i = 0; i < NE - 1; i++)
1566: *q-- = *p++;
1567: }
1568:
1569:
1570:
1571:
1572: /* Clear out internal format number.
1573: */
1574:
1575: void
1576: ecleaz (xi)
1577: register unsigned EMUSHORT *xi;
1578: {
1579: register int i;
1580:
1581: for (i = 0; i < NI; i++)
1582: *xi++ = 0;
1583: }
1584:
1585:
1586: /* same, but don't touch the sign. */
1587:
1588: void
1589: ecleazs (xi)
1590: register unsigned EMUSHORT *xi;
1591: {
1592: register int i;
1593:
1594: ++xi;
1595: for (i = 0; i < NI - 1; i++)
1596: *xi++ = 0;
1597: }
1598:
1599:
1600:
1601: /* Move internal format number from a to b.
1602: */
1603: void
1604: emovz (a, b)
1605: register unsigned EMUSHORT *a, *b;
1606: {
1607: register int i;
1608:
1609: for (i = 0; i < NI - 1; i++)
1610: *b++ = *a++;
1611: /* clear low guard word */
1612: *b = 0;
1613: }
1614:
1615: /* Generate internal format NaN.
1616: The explicit pattern for this is maximum exponent and
1617: top two significand bits set. */
1618:
1619: void
1620: einan (x)
1621: unsigned EMUSHORT x[];
1622: {
1623:
1624: ecleaz (x);
1625: x[E] = 0x7fff;
1626: x[M + 1] = 0xc000;
1627: }
1628:
1629: /* Return nonzero if internal format number is a NaN. */
1630:
1631: int
1632: eiisnan (x)
1633: unsigned EMUSHORT x[];
1634: {
1635: int i;
1636:
1637: if ((x[E] & 0x7fff) == 0x7fff)
1638: {
1639: for (i = M + 1; i < NI; i++)
1640: {
1641: if (x[i] != 0)
1642: return (1);
1643: }
1644: }
1645: return (0);
1646: }
1647:
1648: /* Fill internal format number with infinity pattern.
1649: This has maximum exponent and significand all zeros. */
1650:
1651: void
1652: eiinfin (x)
1653: unsigned EMUSHORT x[];
1654: {
1655:
1656: ecleaz (x);
1657: x[E] = 0x7fff;
1658: }
1659:
1660: /* Return nonzero if internal format number is infinite. */
1661:
1662: int
1663: eiisinf (x)
1664: unsigned EMUSHORT x[];
1665: {
1666:
1667: #ifdef NANS
1668: if (eiisnan (x))
1669: return (0);
1670: #endif
1671: if ((x[E] & 0x7fff) == 0x7fff)
1672: return (1);
1673: return (0);
1674: }
1675:
1676:
1677: /*
1678: ; Compare significands of numbers in internal format.
1679: ; Guard words are included in the comparison.
1680: ;
1681: ; unsigned EMUSHORT a[NI], b[NI];
1682: ; cmpm (a, b);
1683: ;
1684: ; for the significands:
1685: ; returns +1 if a > b
1686: ; 0 if a == b
1687: ; -1 if a < b
1688: */
1689: int
1690: ecmpm (a, b)
1691: register unsigned EMUSHORT *a, *b;
1692: {
1693: int i;
1694:
1695: a += M; /* skip up to significand area */
1696: b += M;
1697: for (i = M; i < NI; i++)
1698: {
1699: if (*a++ != *b++)
1700: goto difrnt;
1701: }
1702: return (0);
1703:
1704: difrnt:
1705: if (*(--a) > *(--b))
1706: return (1);
1707: else
1708: return (-1);
1709: }
1710:
1711:
1712: /*
1713: ; Shift significand down by 1 bit
1714: */
1715:
1716: void
1717: eshdn1 (x)
1718: register unsigned EMUSHORT *x;
1719: {
1720: register unsigned EMUSHORT bits;
1721: int i;
1722:
1723: x += M; /* point to significand area */
1724:
1725: bits = 0;
1726: for (i = M; i < NI; i++)
1727: {
1728: if (*x & 1)
1729: bits |= 1;
1730: *x >>= 1;
1731: if (bits & 2)
1732: *x |= 0x8000;
1733: bits <<= 1;
1734: ++x;
1735: }
1736: }
1737:
1738:
1739:
1740: /*
1741: ; Shift significand up by 1 bit
1742: */
1743:
1744: void
1745: eshup1 (x)
1746: register unsigned EMUSHORT *x;
1747: {
1748: register unsigned EMUSHORT bits;
1749: int i;
1750:
1751: x += NI - 1;
1752: bits = 0;
1753:
1754: for (i = M; i < NI; i++)
1755: {
1756: if (*x & 0x8000)
1757: bits |= 1;
1758: *x <<= 1;
1759: if (bits & 2)
1760: *x |= 1;
1761: bits <<= 1;
1762: --x;
1763: }
1764: }
1765:
1766:
1767:
1768: /*
1769: ; Shift significand down by 8 bits
1770: */
1771:
1772: void
1773: eshdn8 (x)
1774: register unsigned EMUSHORT *x;
1775: {
1776: register unsigned EMUSHORT newbyt, oldbyt;
1777: int i;
1778:
1779: x += M;
1780: oldbyt = 0;
1781: for (i = M; i < NI; i++)
1782: {
1783: newbyt = *x << 8;
1784: *x >>= 8;
1785: *x |= oldbyt;
1786: oldbyt = newbyt;
1787: ++x;
1788: }
1789: }
1790:
1791: /*
1792: ; Shift significand up by 8 bits
1793: */
1794:
1795: void
1796: eshup8 (x)
1797: register unsigned EMUSHORT *x;
1798: {
1799: int i;
1800: register unsigned EMUSHORT newbyt, oldbyt;
1801:
1802: x += NI - 1;
1803: oldbyt = 0;
1804:
1805: for (i = M; i < NI; i++)
1806: {
1807: newbyt = *x >> 8;
1808: *x <<= 8;
1809: *x |= oldbyt;
1810: oldbyt = newbyt;
1811: --x;
1812: }
1813: }
1814:
1815: /*
1816: ; Shift significand up by 16 bits
1817: */
1818:
1819: void
1820: eshup6 (x)
1821: register unsigned EMUSHORT *x;
1822: {
1823: int i;
1824: register unsigned EMUSHORT *p;
1825:
1826: p = x + M;
1827: x += M + 1;
1828:
1829: for (i = M; i < NI - 1; i++)
1830: *p++ = *x++;
1831:
1832: *p = 0;
1833: }
1834:
1835: /*
1836: ; Shift significand down by 16 bits
1837: */
1838:
1839: void
1840: eshdn6 (x)
1841: register unsigned EMUSHORT *x;
1842: {
1843: int i;
1844: register unsigned EMUSHORT *p;
1845:
1846: x += NI - 1;
1847: p = x + 1;
1848:
1849: for (i = M; i < NI - 1; i++)
1850: *(--p) = *(--x);
1851:
1852: *(--p) = 0;
1853: }
1854:
1855: /*
1856: ; Add significands
1857: ; x + y replaces y
1858: */
1859:
1860: void
1861: eaddm (x, y)
1862: unsigned EMUSHORT *x, *y;
1863: {
1864: register unsigned EMULONG a;
1865: int i;
1866: unsigned int carry;
1867:
1868: x += NI - 1;
1869: y += NI - 1;
1870: carry = 0;
1871: for (i = M; i < NI; i++)
1872: {
1873: a = (unsigned EMULONG) (*x) + (unsigned EMULONG) (*y) + carry;
1874: if (a & 0x10000)
1875: carry = 1;
1876: else
1877: carry = 0;
1878: *y = (unsigned EMUSHORT) a;
1879: --x;
1880: --y;
1881: }
1882: }
1883:
1884: /*
1885: ; Subtract significands
1886: ; y - x replaces y
1887: */
1888:
1889: void
1890: esubm (x, y)
1891: unsigned EMUSHORT *x, *y;
1892: {
1893: unsigned EMULONG a;
1894: int i;
1895: unsigned int carry;
1896:
1897: x += NI - 1;
1898: y += NI - 1;
1899: carry = 0;
1900: for (i = M; i < NI; i++)
1901: {
1902: a = (unsigned EMULONG) (*y) - (unsigned EMULONG) (*x) - carry;
1903: if (a & 0x10000)
1904: carry = 1;
1905: else
1906: carry = 0;
1907: *y = (unsigned EMUSHORT) a;
1908: --x;
1909: --y;
1910: }
1911: }
1912:
1913:
1914: static unsigned EMUSHORT equot[NI];
1915:
1916:
1917: #if 0
1918: /* Radix 2 shift-and-add versions of multiply and divide */
1919:
1920:
1921: /* Divide significands */
1922:
1923: int
1924: edivm (den, num)
1925: unsigned EMUSHORT den[], num[];
1926: {
1927: int i;
1928: register unsigned EMUSHORT *p, *q;
1929: unsigned EMUSHORT j;
1930:
1931: p = &equot[0];
1932: *p++ = num[0];
1933: *p++ = num[1];
1934:
1935: for (i = M; i < NI; i++)
1936: {
1937: *p++ = 0;
1938: }
1939:
1940: /* Use faster compare and subtraction if denominator
1941: * has only 15 bits of significance.
1942: */
1943: p = &den[M + 2];
1944: if (*p++ == 0)
1945: {
1946: for (i = M + 3; i < NI; i++)
1947: {
1948: if (*p++ != 0)
1949: goto fulldiv;
1950: }
1951: if ((den[M + 1] & 1) != 0)
1952: goto fulldiv;
1953: eshdn1 (num);
1954: eshdn1 (den);
1955:
1956: p = &den[M + 1];
1957: q = &num[M + 1];
1958:
1959: for (i = 0; i < NBITS + 2; i++)
1960: {
1961: if (*p <= *q)
1962: {
1963: *q -= *p;
1964: j = 1;
1965: }
1966: else
1967: {
1968: j = 0;
1969: }
1970: eshup1 (equot);
1971: equot[NI - 2] |= j;
1972: eshup1 (num);
1973: }
1974: goto divdon;
1975: }
1976:
1977: /* The number of quotient bits to calculate is
1978: * NBITS + 1 scaling guard bit + 1 roundoff bit.
1979: */
1980: fulldiv:
1981:
1982: p = &equot[NI - 2];
1983: for (i = 0; i < NBITS + 2; i++)
1984: {
1985: if (ecmpm (den, num) <= 0)
1986: {
1987: esubm (den, num);
1988: j = 1; /* quotient bit = 1 */
1989: }
1990: else
1991: j = 0;
1992: eshup1 (equot);
1993: *p |= j;
1994: eshup1 (num);
1995: }
1996:
1997: divdon:
1998:
1999: eshdn1 (equot);
2000: eshdn1 (equot);
2001:
2002: /* test for nonzero remainder after roundoff bit */
2003: p = &num[M];
2004: j = 0;
2005: for (i = M; i < NI; i++)
2006: {
2007: j |= *p++;
2008: }
2009: if (j)
2010: j = 1;
2011:
2012:
2013: for (i = 0; i < NI; i++)
2014: num[i] = equot[i];
2015: return ((int) j);
2016: }
2017:
2018:
2019: /* Multiply significands */
2020: int
2021: emulm (a, b)
2022: unsigned EMUSHORT a[], b[];
2023: {
2024: unsigned EMUSHORT *p, *q;
2025: int i, j, k;
2026:
2027: equot[0] = b[0];
2028: equot[1] = b[1];
2029: for (i = M; i < NI; i++)
2030: equot[i] = 0;
2031:
2032: p = &a[NI - 2];
2033: k = NBITS;
2034: while (*p == 0) /* significand is not supposed to be all zero */
2035: {
2036: eshdn6 (a);
2037: k -= 16;
2038: }
2039: if ((*p & 0xff) == 0)
2040: {
2041: eshdn8 (a);
2042: k -= 8;
2043: }
2044:
2045: q = &equot[NI - 1];
2046: j = 0;
2047: for (i = 0; i < k; i++)
2048: {
2049: if (*p & 1)
2050: eaddm (b, equot);
2051: /* remember if there were any nonzero bits shifted out */
2052: if (*q & 1)
2053: j |= 1;
2054: eshdn1 (a);
2055: eshdn1 (equot);
2056: }
2057:
2058: for (i = 0; i < NI; i++)
2059: b[i] = equot[i];
2060:
2061: /* return flag for lost nonzero bits */
2062: return (j);
2063: }
2064:
2065: #else
2066:
2067: /* Radix 65536 versions of multiply and divide */
2068:
2069:
2070: /* Multiply significand of e-type number b
2071: by 16-bit quantity a, e-type result to c. */
2072:
2073: void
2074: m16m (a, b, c)
2075: unsigned short a;
2076: unsigned short b[], c[];
2077: {
2078: register unsigned short *pp;
2079: register unsigned long carry;
2080: unsigned short *ps;
2081: unsigned short p[NI];
2082: unsigned long aa, m;
2083: int i;
2084:
2085: aa = a;
2086: pp = &p[NI-2];
2087: *pp++ = 0;
2088: *pp = 0;
2089: ps = &b[NI-1];
2090:
2091: for (i=M+1; i<NI; i++)
2092: {
2093: if (*ps == 0)
2094: {
2095: --ps;
2096: --pp;
2097: *(pp-1) = 0;
2098: }
2099: else
2100: {
2101: m = (unsigned long) aa * *ps--;
2102: carry = (m & 0xffff) + *pp;
2103: *pp-- = (unsigned short)carry;
2104: carry = (carry >> 16) + (m >> 16) + *pp;
2105: *pp = (unsigned short)carry;
2106: *(pp-1) = carry >> 16;
2107: }
2108: }
2109: for (i=M; i<NI; i++)
2110: c[i] = p[i];
2111: }
2112:
2113:
2114: /* Divide significands. Neither the numerator nor the denominator
2115: is permitted to have its high guard word nonzero. */
2116:
2117: int
2118: edivm (den, num)
2119: unsigned short den[], num[];
2120: {
2121: int i;
2122: register unsigned short *p;
2123: unsigned long tnum;
2124: unsigned short j, tdenm, tquot;
2125: unsigned short tprod[NI+1];
2126:
2127: p = &equot[0];
2128: *p++ = num[0];
2129: *p++ = num[1];
2130:
2131: for (i=M; i<NI; i++)
2132: {
2133: *p++ = 0;
2134: }
2135: eshdn1 (num);
2136: tdenm = den[M+1];
2137: for (i=M; i<NI; i++)
2138: {
2139: /* Find trial quotient digit (the radix is 65536). */
2140: tnum = (((unsigned long) num[M]) << 16) + num[M+1];
2141:
2142: /* Do not execute the divide instruction if it will overflow. */
2143: if ((tdenm * 0xffffL) < tnum)
2144: tquot = 0xffff;
2145: else
2146: tquot = tnum / tdenm;
2147: /* Multiply denominator by trial quotient digit. */
2148: m16m (tquot, den, tprod);
2149: /* The quotient digit may have been overestimated. */
2150: if (ecmpm (tprod, num) > 0)
2151: {
2152: tquot -= 1;
2153: esubm (den, tprod);
2154: if (ecmpm (tprod, num) > 0)
2155: {
2156: tquot -= 1;
2157: esubm (den, tprod);
2158: }
2159: }
2160: esubm (tprod, num);
2161: equot[i] = tquot;
2162: eshup6(num);
2163: }
2164: /* test for nonzero remainder after roundoff bit */
2165: p = &num[M];
2166: j = 0;
2167: for (i=M; i<NI; i++)
2168: {
2169: j |= *p++;
2170: }
2171: if (j)
2172: j = 1;
2173:
2174: for (i=0; i<NI; i++)
2175: num[i] = equot[i];
2176:
2177: return ((int)j);
2178: }
2179:
2180:
2181:
2182: /* Multiply significands */
2183: int
2184: emulm (a, b)
2185: unsigned short a[], b[];
2186: {
2187: unsigned short *p, *q;
2188: unsigned short pprod[NI];
2189: unsigned short j;
2190: int i;
2191:
2192: equot[0] = b[0];
2193: equot[1] = b[1];
2194: for (i=M; i<NI; i++)
2195: equot[i] = 0;
2196:
2197: j = 0;
2198: p = &a[NI-1];
2199: q = &equot[NI-1];
2200: for (i=M+1; i<NI; i++)
2201: {
2202: if (*p == 0)
2203: {
2204: --p;
2205: }
2206: else
2207: {
2208: m16m (*p--, b, pprod);
2209: eaddm(pprod, equot);
2210: }
2211: j |= *q;
2212: eshdn6(equot);
2213: }
2214:
2215: for (i=0; i<NI; i++)
2216: b[i] = equot[i];
2217:
2218: /* return flag for lost nonzero bits */
2219: return ((int)j);
2220: }
2221: #endif
2222:
2223:
2224: /*
2225: * Normalize and round off.
2226: *
2227: * The internal format number to be rounded is "s".
2228: * Input "lost" indicates whether or not the number is exact.
2229: * This is the so-called sticky bit.
2230: *
2231: * Input "subflg" indicates whether the number was obtained
2232: * by a subtraction operation. In that case if lost is nonzero
2233: * then the number is slightly smaller than indicated.
2234: *
2235: * Input "exp" is the biased exponent, which may be negative.
2236: * the exponent field of "s" is ignored but is replaced by
2237: * "exp" as adjusted by normalization and rounding.
2238: *
2239: * Input "rcntrl" is the rounding control.
2240: */
2241:
2242: /* For future reference: In order for emdnorm to round off denormal
2243: significands at the right point, the input exponent must be
2244: adjusted to be the actual value it would have after conversion to
2245: the final floating point type. This adjustment has been
2246: implemented for all type conversions (etoe53, etc.) and decimal
2247: conversions, but not for the arithmetic functions (eadd, etc.).
2248: Data types having standard 15-bit exponents are not affected by
2249: this, but SFmode and DFmode are affected. For example, ediv with
2250: rndprc = 24 will not round correctly to 24-bit precision if the
2251: result is denormal. */
2252:
2253: static int rlast = -1;
2254: static int rw = 0;
2255: static unsigned EMUSHORT rmsk = 0;
2256: static unsigned EMUSHORT rmbit = 0;
2257: static unsigned EMUSHORT rebit = 0;
2258: static int re = 0;
2259: static unsigned EMUSHORT rbit[NI];
2260:
2261: void
2262: emdnorm (s, lost, subflg, exp, rcntrl)
2263: unsigned EMUSHORT s[];
2264: int lost;
2265: int subflg;
2266: EMULONG exp;
2267: int rcntrl;
2268: {
2269: int i, j;
2270: unsigned EMUSHORT r;
2271:
2272: /* Normalize */
2273: j = enormlz (s);
2274:
2275: /* a blank significand could mean either zero or infinity. */
2276: #ifndef INFINITY
2277: if (j > NBITS)
2278: {
2279: ecleazs (s);
2280: return;
2281: }
2282: #endif
2283: exp -= j;
2284: #ifndef INFINITY
2285: if (exp >= 32767L)
2286: goto overf;
2287: #else
2288: if ((j > NBITS) && (exp < 32767))
2289: {
2290: ecleazs (s);
2291: return;
2292: }
2293: #endif
2294: if (exp < 0L)
2295: {
2296: if (exp > (EMULONG) (-NBITS - 1))
2297: {
2298: j = (int) exp;
2299: i = eshift (s, j);
2300: if (i)
2301: lost = 1;
2302: }
2303: else
2304: {
2305: ecleazs (s);
2306: return;
2307: }
2308: }
2309: /* Round off, unless told not to by rcntrl. */
2310: if (rcntrl == 0)
2311: goto mdfin;
2312: /* Set up rounding parameters if the control register changed. */
2313: if (rndprc != rlast)
2314: {
2315: ecleaz (rbit);
2316: switch (rndprc)
2317: {
2318: default:
2319: case NBITS:
2320: rw = NI - 1; /* low guard word */
2321: rmsk = 0xffff;
2322: rmbit = 0x8000;
2323: re = rw - 1;
2324: rebit = 1;
2325: break;
2326: case 113:
2327: rw = 10;
2328: rmsk = 0x7fff;
2329: rmbit = 0x4000;
2330: rebit = 0x8000;
2331: re = rw;
2332: break;
2333: case 64:
2334: rw = 7;
2335: rmsk = 0xffff;
2336: rmbit = 0x8000;
2337: re = rw - 1;
2338: rebit = 1;
2339: break;
2340: /* For DEC or IBM arithmetic */
2341: case 56:
2342: rw = 6;
2343: rmsk = 0xff;
2344: rmbit = 0x80;
2345: rebit = 0x100;
2346: re = rw;
2347: break;
2348: case 53:
2349: rw = 6;
2350: rmsk = 0x7ff;
2351: rmbit = 0x0400;
2352: rebit = 0x800;
2353: re = rw;
2354: break;
2355: case 24:
2356: rw = 4;
2357: rmsk = 0xff;
2358: rmbit = 0x80;
2359: rebit = 0x100;
2360: re = rw;
2361: break;
2362: }
2363: rbit[re] = rebit;
2364: rlast = rndprc;
2365: }
2366:
2367: /* Shift down 1 temporarily if the data structure has an implied
2368: most significant bit and the number is denormal. */
2369: if ((exp <= 0) && (rndprc != 64) && (rndprc != NBITS))
2370: {
2371: lost |= s[NI - 1] & 1;
2372: eshdn1 (s);
2373: }
2374: /* Clear out all bits below the rounding bit,
2375: remembering in r if any were nonzero. */
2376: r = s[rw] & rmsk;
2377: if (rndprc < NBITS)
2378: {
2379: i = rw + 1;
2380: while (i < NI)
2381: {
2382: if (s[i])
2383: r |= 1;
2384: s[i] = 0;
2385: ++i;
2386: }
2387: }
2388: s[rw] &= ~rmsk;
2389: if ((r & rmbit) != 0)
2390: {
2391: if (r == rmbit)
2392: {
2393: if (lost == 0)
2394: { /* round to even */
2395: if ((s[re] & rebit) == 0)
2396: goto mddone;
2397: }
2398: else
2399: {
2400: if (subflg != 0)
2401: goto mddone;
2402: }
2403: }
2404: eaddm (rbit, s);
2405: }
2406: mddone:
2407: if ((exp <= 0) && (rndprc != 64) && (rndprc != NBITS))
2408: {
2409: eshup1 (s);
2410: }
2411: if (s[2] != 0)
2412: { /* overflow on roundoff */
2413: eshdn1 (s);
2414: exp += 1;
2415: }
2416: mdfin:
2417: s[NI - 1] = 0;
2418: if (exp >= 32767L)
2419: {
2420: #ifndef INFINITY
2421: overf:
2422: #endif
2423: #ifdef INFINITY
2424: s[1] = 32767;
2425: for (i = 2; i < NI - 1; i++)
2426: s[i] = 0;
2427: if (extra_warnings)
2428: warning ("floating point overflow");
2429: #else
2430: s[1] = 32766;
2431: s[2] = 0;
2432: for (i = M + 1; i < NI - 1; i++)
2433: s[i] = 0xffff;
2434: s[NI - 1] = 0;
2435: if ((rndprc < 64) || (rndprc == 113))
2436: {
2437: s[rw] &= ~rmsk;
2438: if (rndprc == 24)
2439: {
2440: s[5] = 0;
2441: s[6] = 0;
2442: }
2443: }
2444: #endif
2445: return;
2446: }
2447: if (exp < 0)
2448: s[1] = 0;
2449: else
2450: s[1] = (unsigned EMUSHORT) exp;
2451: }
2452:
2453:
2454:
2455: /*
2456: ; Subtract external format numbers.
2457: ;
2458: ; unsigned EMUSHORT a[NE], b[NE], c[NE];
2459: ; esub (a, b, c); c = b - a
2460: */
2461:
2462: static int subflg = 0;
2463:
2464: void
2465: esub (a, b, c)
2466: unsigned EMUSHORT *a, *b, *c;
2467: {
2468:
2469: #ifdef NANS
2470: if (eisnan (a))
2471: {
2472: emov (a, c);
2473: return;
2474: }
2475: if (eisnan (b))
2476: {
2477: emov (b, c);
2478: return;
2479: }
2480: /* Infinity minus infinity is a NaN.
2481: Test for subtracting infinities of the same sign. */
2482: if (eisinf (a) && eisinf (b)
2483: && ((eisneg (a) ^ eisneg (b)) == 0))
2484: {
2485: mtherr ("esub", INVALID);
2486: enan (c);
2487: return;
2488: }
2489: #endif
2490: subflg = 1;
2491: eadd1 (a, b, c);
2492: }
2493:
2494:
2495: /*
2496: ; Add.
2497: ;
2498: ; unsigned EMUSHORT a[NE], b[NE], c[NE];
2499: ; eadd (a, b, c); c = b + a
2500: */
2501: void
2502: eadd (a, b, c)
2503: unsigned EMUSHORT *a, *b, *c;
2504: {
2505:
2506: #ifdef NANS
2507: /* NaN plus anything is a NaN. */
2508: if (eisnan (a))
2509: {
2510: emov (a, c);
2511: return;
2512: }
2513: if (eisnan (b))
2514: {
2515: emov (b, c);
2516: return;
2517: }
2518: /* Infinity minus infinity is a NaN.
2519: Test for adding infinities of opposite signs. */
2520: if (eisinf (a) && eisinf (b)
2521: && ((eisneg (a) ^ eisneg (b)) != 0))
2522: {
2523: mtherr ("esub", INVALID);
2524: enan (c);
2525: return;
2526: }
2527: #endif
2528: subflg = 0;
2529: eadd1 (a, b, c);
2530: }
2531:
2532: void
2533: eadd1 (a, b, c)
2534: unsigned EMUSHORT *a, *b, *c;
2535: {
2536: unsigned EMUSHORT ai[NI], bi[NI], ci[NI];
2537: int i, lost, j, k;
2538: EMULONG lt, lta, ltb;
2539:
2540: #ifdef INFINITY
2541: if (eisinf (a))
2542: {
2543: emov (a, c);
2544: if (subflg)
2545: eneg (c);
2546: return;
2547: }
2548: if (eisinf (b))
2549: {
2550: emov (b, c);
2551: return;
2552: }
2553: #endif
2554: emovi (a, ai);
2555: emovi (b, bi);
2556: if (subflg)
2557: ai[0] = ~ai[0];
2558:
2559: /* compare exponents */
2560: lta = ai[E];
2561: ltb = bi[E];
2562: lt = lta - ltb;
2563: if (lt > 0L)
2564: { /* put the larger number in bi */
2565: emovz (bi, ci);
2566: emovz (ai, bi);
2567: emovz (ci, ai);
2568: ltb = bi[E];
2569: lt = -lt;
2570: }
2571: lost = 0;
2572: if (lt != 0L)
2573: {
2574: if (lt < (EMULONG) (-NBITS - 1))
2575: goto done; /* answer same as larger addend */
2576: k = (int) lt;
2577: lost = eshift (ai, k); /* shift the smaller number down */
2578: }
2579: else
2580: {
2581: /* exponents were the same, so must compare significands */
2582: i = ecmpm (ai, bi);
2583: if (i == 0)
2584: { /* the numbers are identical in magnitude */
2585: /* if different signs, result is zero */
2586: if (ai[0] != bi[0])
2587: {
2588: eclear (c);
2589: return;
2590: }
2591: /* if same sign, result is double */
2592: /* double denomalized tiny number */
2593: if ((bi[E] == 0) && ((bi[3] & 0x8000) == 0))
2594: {
2595: eshup1 (bi);
2596: goto done;
2597: }
2598: /* add 1 to exponent unless both are zero! */
2599: for (j = 1; j < NI - 1; j++)
2600: {
2601: if (bi[j] != 0)
2602: {
2603: /* This could overflow, but let emovo take care of that. */
2604: ltb += 1;
2605: break;
2606: }
2607: }
2608: bi[E] = (unsigned EMUSHORT) ltb;
2609: goto done;
2610: }
2611: if (i > 0)
2612: { /* put the larger number in bi */
2613: emovz (bi, ci);
2614: emovz (ai, bi);
2615: emovz (ci, ai);
2616: }
2617: }
2618: if (ai[0] == bi[0])
2619: {
2620: eaddm (ai, bi);
2621: subflg = 0;
2622: }
2623: else
2624: {
2625: esubm (ai, bi);
2626: subflg = 1;
2627: }
2628: emdnorm (bi, lost, subflg, ltb, 64);
2629:
2630: done:
2631: emovo (bi, c);
2632: }
2633:
2634:
2635:
2636: /*
2637: ; Divide.
2638: ;
2639: ; unsigned EMUSHORT a[NE], b[NE], c[NE];
2640: ; ediv (a, b, c); c = b / a
2641: */
2642: void
2643: ediv (a, b, c)
2644: unsigned EMUSHORT *a, *b, *c;
2645: {
2646: unsigned EMUSHORT ai[NI], bi[NI];
2647: int i;
2648: EMULONG lt, lta, ltb;
2649:
2650: #ifdef NANS
2651: /* Return any NaN input. */
2652: if (eisnan (a))
2653: {
2654: emov (a, c);
2655: return;
2656: }
2657: if (eisnan (b))
2658: {
2659: emov (b, c);
2660: return;
2661: }
2662: /* Zero over zero, or infinity over infinity, is a NaN. */
2663: if (((ecmp (a, ezero) == 0) && (ecmp (b, ezero) == 0))
2664: || (eisinf (a) && eisinf (b)))
2665: {
2666: mtherr ("ediv", INVALID);
2667: enan (c);
2668: return;
2669: }
2670: #endif
2671: /* Infinity over anything else is infinity. */
2672: #ifdef INFINITY
2673: if (eisinf (b))
2674: {
2675: if (eisneg (a) ^ eisneg (b))
2676: *(c + (NE - 1)) = 0x8000;
2677: else
2678: *(c + (NE - 1)) = 0;
2679: einfin (c);
2680: return;
2681: }
2682: /* Anything else over infinity is zero. */
2683: if (eisinf (a))
2684: {
2685: eclear (c);
2686: return;
2687: }
2688: #endif
2689: emovi (a, ai);
2690: emovi (b, bi);
2691: lta = ai[E];
2692: ltb = bi[E];
2693: if (bi[E] == 0)
2694: { /* See if numerator is zero. */
2695: for (i = 1; i < NI - 1; i++)
2696: {
2697: if (bi[i] != 0)
2698: {
2699: ltb -= enormlz (bi);
2700: goto dnzro1;
2701: }
2702: }
2703: eclear (c);
2704: return;
2705: }
2706: dnzro1:
2707:
2708: if (ai[E] == 0)
2709: { /* possible divide by zero */
2710: for (i = 1; i < NI - 1; i++)
2711: {
2712: if (ai[i] != 0)
2713: {
2714: lta -= enormlz (ai);
2715: goto dnzro2;
2716: }
2717: }
2718: if (ai[0] == bi[0])
2719: *(c + (NE - 1)) = 0;
2720: else
2721: *(c + (NE - 1)) = 0x8000;
2722: /* Divide by zero is not an invalid operation.
2723: It is a divide-by-zero operation! */
2724: einfin (c);
2725: mtherr ("ediv", SING);
2726: return;
2727: }
2728: dnzro2:
2729:
2730: i = edivm (ai, bi);
2731: /* calculate exponent */
2732: lt = ltb - lta + EXONE;
2733: emdnorm (bi, i, 0, lt, 64);
2734: /* set the sign */
2735: if (ai[0] == bi[0])
2736: bi[0] = 0;
2737: else
2738: bi[0] = 0Xffff;
2739: emovo (bi, c);
2740: }
2741:
2742:
2743:
2744: /*
2745: ; Multiply.
2746: ;
2747: ; unsigned EMUSHORT a[NE], b[NE], c[NE];
2748: ; emul (a, b, c); c = b * a
2749: */
2750: void
2751: emul (a, b, c)
2752: unsigned EMUSHORT *a, *b, *c;
2753: {
2754: unsigned EMUSHORT ai[NI], bi[NI];
2755: int i, j;
2756: EMULONG lt, lta, ltb;
2757:
2758: #ifdef NANS
2759: /* NaN times anything is the same NaN. */
2760: if (eisnan (a))
2761: {
2762: emov (a, c);
2763: return;
2764: }
2765: if (eisnan (b))
2766: {
2767: emov (b, c);
2768: return;
2769: }
2770: /* Zero times infinity is a NaN. */
2771: if ((eisinf (a) && (ecmp (b, ezero) == 0))
2772: || (eisinf (b) && (ecmp (a, ezero) == 0)))
2773: {
2774: mtherr ("emul", INVALID);
2775: enan (c);
2776: return;
2777: }
2778: #endif
2779: /* Infinity times anything else is infinity. */
2780: #ifdef INFINITY
2781: if (eisinf (a) || eisinf (b))
2782: {
2783: if (eisneg (a) ^ eisneg (b))
2784: *(c + (NE - 1)) = 0x8000;
2785: else
2786: *(c + (NE - 1)) = 0;
2787: einfin (c);
2788: return;
2789: }
2790: #endif
2791: emovi (a, ai);
2792: emovi (b, bi);
2793: lta = ai[E];
2794: ltb = bi[E];
2795: if (ai[E] == 0)
2796: {
2797: for (i = 1; i < NI - 1; i++)
2798: {
2799: if (ai[i] != 0)
2800: {
2801: lta -= enormlz (ai);
2802: goto mnzer1;
2803: }
2804: }
2805: eclear (c);
2806: return;
2807: }
2808: mnzer1:
2809:
2810: if (bi[E] == 0)
2811: {
2812: for (i = 1; i < NI - 1; i++)
2813: {
2814: if (bi[i] != 0)
2815: {
2816: ltb -= enormlz (bi);
2817: goto mnzer2;
2818: }
2819: }
2820: eclear (c);
2821: return;
2822: }
2823: mnzer2:
2824:
2825: /* Multiply significands */
2826: j = emulm (ai, bi);
2827: /* calculate exponent */
2828: lt = lta + ltb - (EXONE - 1);
2829: emdnorm (bi, j, 0, lt, 64);
2830: /* calculate sign of product */
2831: if (ai[0] == bi[0])
2832: bi[0] = 0;
2833: else
2834: bi[0] = 0xffff;
2835: emovo (bi, c);
2836: }
2837:
2838:
2839:
2840:
2841: /*
2842: ; Convert IEEE double precision to e type
2843: ; double d;
2844: ; unsigned EMUSHORT x[N+2];
2845: ; e53toe (&d, x);
2846: */
2847: void
2848: e53toe (pe, y)
2849: unsigned EMUSHORT *pe, *y;
2850: {
2851: #ifdef DEC
2852:
2853: dectoe (pe, y); /* see etodec.c */
2854:
2855: #else
2856: #ifdef IBM
2857:
2858: ibmtoe (pe, y, DFmode);
2859:
2860: #else
2861: register unsigned EMUSHORT r;
2862: register unsigned EMUSHORT *e, *p;
2863: unsigned EMUSHORT yy[NI];
2864: int denorm, k;
2865:
2866: e = pe;
2867: denorm = 0; /* flag if denormalized number */
2868: ecleaz (yy);
2869: #ifdef IBMPC
2870: e += 3;
2871: #endif
2872: r = *e;
2873: yy[0] = 0;
2874: if (r & 0x8000)
2875: yy[0] = 0xffff;
2876: yy[M] = (r & 0x0f) | 0x10;
2877: r &= ~0x800f; /* strip sign and 4 significand bits */
2878: #ifdef INFINITY
2879: if (r == 0x7ff0)
2880: {
2881: #ifdef NANS
2882: #ifdef IBMPC
2883: if (((pe[3] & 0xf) != 0) || (pe[2] != 0)
2884: || (pe[1] != 0) || (pe[0] != 0))
2885: {
2886: enan (y);
2887: return;
2888: }
2889: #else
2890: if (((pe[0] & 0xf) != 0) || (pe[1] != 0)
2891: || (pe[2] != 0) || (pe[3] != 0))
2892: {
2893: enan (y);
2894: return;
2895: }
2896: #endif
2897: #endif /* NANS */
2898: eclear (y);
2899: einfin (y);
2900: if (yy[0])
2901: eneg (y);
2902: return;
2903: }
2904: #endif /* INFINITY */
2905: r >>= 4;
2906: /* If zero exponent, then the significand is denormalized.
2907: * So, take back the understood high significand bit. */
2908: if (r == 0)
2909: {
2910: denorm = 1;
2911: yy[M] &= ~0x10;
2912: }
2913: r += EXONE - 01777;
2914: yy[E] = r;
2915: p = &yy[M + 1];
2916: #ifdef IBMPC
2917: *p++ = *(--e);
2918: *p++ = *(--e);
2919: *p++ = *(--e);
2920: #endif
2921: #ifdef MIEEE
2922: ++e;
2923: *p++ = *e++;
2924: *p++ = *e++;
2925: *p++ = *e++;
2926: #endif
2927: eshift (yy, -5);
2928: if (denorm)
2929: { /* if zero exponent, then normalize the significand */
2930: if ((k = enormlz (yy)) > NBITS)
2931: ecleazs (yy);
2932: else
2933: yy[E] -= (unsigned EMUSHORT) (k - 1);
2934: }
2935: emovo (yy, y);
2936: #endif /* not IBM */
2937: #endif /* not DEC */
2938: }
2939:
2940: void
2941: e64toe (pe, y)
2942: unsigned EMUSHORT *pe, *y;
2943: {
2944: unsigned EMUSHORT yy[NI];
2945: unsigned EMUSHORT *e, *p, *q;
2946: int i;
2947:
2948: e = pe;
2949: p = yy;
2950: for (i = 0; i < NE - 5; i++)
2951: *p++ = 0;
2952: #ifdef IBMPC
2953: for (i = 0; i < 5; i++)
2954: *p++ = *e++;
2955: #endif
2956: /* This precision is not ordinarily supported on DEC or IBM. */
2957: #ifdef DEC
2958: for (i = 0; i < 5; i++)
2959: *p++ = *e++;
2960: #endif
2961: #ifdef IBM
2962: p = &yy[0] + (NE - 1);
2963: *p-- = *e++;
2964: ++e;
2965: for (i = 0; i < 5; i++)
2966: *p-- = *e++;
2967: #endif
2968: #ifdef MIEEE
2969: p = &yy[0] + (NE - 1);
2970: *p-- = *e++;
2971: ++e;
2972: for (i = 0; i < 4; i++)
2973: *p-- = *e++;
2974: #endif
2975: p = yy;
2976: q = y;
2977: #ifdef INFINITY
2978: if (*p == 0x7fff)
2979: {
2980: #ifdef NANS
2981: #ifdef IBMPC
2982: for (i = 0; i < 4; i++)
2983: {
2984: if (pe[i] != 0)
2985: {
2986: enan (y);
2987: return;
2988: }
2989: }
2990: #else
2991: for (i = 1; i <= 4; i++)
2992: {
2993: if (pe[i] != 0)
2994: {
2995: enan (y);
2996: return;
2997: }
2998: }
2999: #endif
3000: #endif /* NANS */
3001: eclear (y);
3002: einfin (y);
3003: if (*p & 0x8000)
3004: eneg (y);
3005: return;
3006: }
3007: #endif /* INFINITY */
3008: for (i = 0; i < NE; i++)
3009: *q++ = *p++;
3010: }
3011:
3012:
3013: void
3014: e113toe (pe, y)
3015: unsigned EMUSHORT *pe, *y;
3016: {
3017: register unsigned EMUSHORT r;
3018: unsigned EMUSHORT *e, *p;
3019: unsigned EMUSHORT yy[NI];
3020: int denorm, i;
3021:
3022: e = pe;
3023: denorm = 0;
3024: ecleaz (yy);
3025: #ifdef IBMPC
3026: e += 7;
3027: #endif
3028: r = *e;
3029: yy[0] = 0;
3030: if (r & 0x8000)
3031: yy[0] = 0xffff;
3032: r &= 0x7fff;
3033: #ifdef INFINITY
3034: if (r == 0x7fff)
3035: {
3036: #ifdef NANS
3037: #ifdef IBMPC
3038: for (i = 0; i < 7; i++)
3039: {
3040: if (pe[i] != 0)
3041: {
3042: enan (y);
3043: return;
3044: }
3045: }
3046: #else
3047: for (i = 1; i < 8; i++)
3048: {
3049: if (pe[i] != 0)
3050: {
3051: enan (y);
3052: return;
3053: }
3054: }
3055: #endif
3056: #endif /* NANS */
3057: eclear (y);
3058: einfin (y);
3059: if (yy[0])
3060: eneg (y);
3061: return;
3062: }
3063: #endif /* INFINITY */
3064: yy[E] = r;
3065: p = &yy[M + 1];
3066: #ifdef IBMPC
3067: for (i = 0; i < 7; i++)
3068: *p++ = *(--e);
3069: #endif
3070: #ifdef MIEEE
3071: ++e;
3072: for (i = 0; i < 7; i++)
3073: *p++ = *e++;
3074: #endif
3075: /* If denormal, remove the implied bit; else shift down 1. */
3076: if (r == 0)
3077: {
3078: yy[M] = 0;
3079: }
3080: else
3081: {
3082: yy[M] = 1;
3083: eshift (yy, -1);
3084: }
3085: emovo (yy, y);
3086: }
3087:
3088:
3089: /*
3090: ; Convert IEEE single precision to e type
3091: ; float d;
3092: ; unsigned EMUSHORT x[N+2];
3093: ; dtox (&d, x);
3094: */
3095: void
3096: e24toe (pe, y)
3097: unsigned EMUSHORT *pe, *y;
3098: {
3099: #ifdef IBM
3100:
3101: ibmtoe (pe, y, SFmode);
3102:
3103: #else
3104: register unsigned EMUSHORT r;
3105: register unsigned EMUSHORT *e, *p;
3106: unsigned EMUSHORT yy[NI];
3107: int denorm, k;
3108:
3109: e = pe;
3110: denorm = 0; /* flag if denormalized number */
3111: ecleaz (yy);
3112: #ifdef IBMPC
3113: e += 1;
3114: #endif
3115: #ifdef DEC
3116: e += 1;
3117: #endif
3118: r = *e;
3119: yy[0] = 0;
3120: if (r & 0x8000)
3121: yy[0] = 0xffff;
3122: yy[M] = (r & 0x7f) | 0200;
3123: r &= ~0x807f; /* strip sign and 7 significand bits */
3124: #ifdef INFINITY
3125: if (r == 0x7f80)
3126: {
3127: #ifdef NANS
3128: #ifdef MIEEE
3129: if (((pe[0] & 0x7f) != 0) || (pe[1] != 0))
3130: {
3131: enan (y);
3132: return;
3133: }
3134: #else
3135: if (((pe[1] & 0x7f) != 0) || (pe[0] != 0))
3136: {
3137: enan (y);
3138: return;
3139: }
3140: #endif
3141: #endif /* NANS */
3142: eclear (y);
3143: einfin (y);
3144: if (yy[0])
3145: eneg (y);
3146: return;
3147: }
3148: #endif /* INFINITY */
3149: r >>= 7;
3150: /* If zero exponent, then the significand is denormalized.
3151: * So, take back the understood high significand bit. */
3152: if (r == 0)
3153: {
3154: denorm = 1;
3155: yy[M] &= ~0200;
3156: }
3157: r += EXONE - 0177;
3158: yy[E] = r;
3159: p = &yy[M + 1];
3160: #ifdef IBMPC
3161: *p++ = *(--e);
3162: #endif
3163: #ifdef DEC
3164: *p++ = *(--e);
3165: #endif
3166: #ifdef MIEEE
3167: ++e;
3168: *p++ = *e++;
3169: #endif
3170: eshift (yy, -8);
3171: if (denorm)
3172: { /* if zero exponent, then normalize the significand */
3173: if ((k = enormlz (yy)) > NBITS)
3174: ecleazs (yy);
3175: else
3176: yy[E] -= (unsigned EMUSHORT) (k - 1);
3177: }
3178: emovo (yy, y);
3179: #endif /* not IBM */
3180: }
3181:
3182:
3183: void
3184: etoe113 (x, e)
3185: unsigned EMUSHORT *x, *e;
3186: {
3187: unsigned EMUSHORT xi[NI];
3188: EMULONG exp;
3189: int rndsav;
3190:
3191: #ifdef NANS
3192: if (eisnan (x))
3193: {
3194: make_nan (e, TFmode);
3195: return;
3196: }
3197: #endif
3198: emovi (x, xi);
3199: exp = (EMULONG) xi[E];
3200: #ifdef INFINITY
3201: if (eisinf (x))
3202: goto nonorm;
3203: #endif
3204: /* round off to nearest or even */
3205: rndsav = rndprc;
3206: rndprc = 113;
3207: emdnorm (xi, 0, 0, exp, 64);
3208: rndprc = rndsav;
3209: nonorm:
3210: toe113 (xi, e);
3211: }
3212:
3213: /* move out internal format to ieee long double */
3214: static void
3215: toe113 (a, b)
3216: unsigned EMUSHORT *a, *b;
3217: {
3218: register unsigned EMUSHORT *p, *q;
3219: unsigned EMUSHORT i;
3220:
3221: #ifdef NANS
3222: if (eiisnan (a))
3223: {
3224: make_nan (b, TFmode);
3225: return;
3226: }
3227: #endif
3228: p = a;
3229: #ifdef MIEEE
3230: q = b;
3231: #else
3232: q = b + 7; /* point to output exponent */
3233: #endif
3234:
3235: /* If not denormal, delete the implied bit. */
3236: if (a[E] != 0)
3237: {
3238: eshup1 (a);
3239: }
3240: /* combine sign and exponent */
3241: i = *p++;
3242: #ifdef MIEEE
3243: if (i)
3244: *q++ = *p++ | 0x8000;
3245: else
3246: *q++ = *p++;
3247: #else
3248: if (i)
3249: *q-- = *p++ | 0x8000;
3250: else
3251: *q-- = *p++;
3252: #endif
3253: /* skip over guard word */
3254: ++p;
3255: /* move the significand */
3256: #ifdef MIEEE
3257: for (i = 0; i < 7; i++)
3258: *q++ = *p++;
3259: #else
3260: for (i = 0; i < 7; i++)
3261: *q-- = *p++;
3262: #endif
3263: }
3264:
3265: void
3266: etoe64 (x, e)
3267: unsigned EMUSHORT *x, *e;
3268: {
3269: unsigned EMUSHORT xi[NI];
3270: EMULONG exp;
3271: int rndsav;
3272:
3273: #ifdef NANS
3274: if (eisnan (x))
3275: {
3276: make_nan (e, XFmode);
3277: return;
3278: }
3279: #endif
3280: emovi (x, xi);
3281: /* adjust exponent for offset */
3282: exp = (EMULONG) xi[E];
3283: #ifdef INFINITY
3284: if (eisinf (x))
3285: goto nonorm;
3286: #endif
3287: /* round off to nearest or even */
3288: rndsav = rndprc;
3289: rndprc = 64;
3290: emdnorm (xi, 0, 0, exp, 64);
3291: rndprc = rndsav;
3292: nonorm:
3293: toe64 (xi, e);
3294: }
3295:
3296: /* move out internal format to ieee long double */
3297: static void
3298: toe64 (a, b)
3299: unsigned EMUSHORT *a, *b;
3300: {
3301: register unsigned EMUSHORT *p, *q;
3302: unsigned EMUSHORT i;
3303:
3304: #ifdef NANS
3305: if (eiisnan (a))
3306: {
3307: make_nan (b, XFmode);
3308: return;
3309: }
3310: #endif
3311: p = a;
3312: #if defined(MIEEE) || defined(IBM)
3313: q = b;
3314: #else
3315: q = b + 4; /* point to output exponent */
3316: #if LONG_DOUBLE_TYPE_SIZE == 96
3317: /* Clear the last two bytes of 12-byte Intel format */
3318: *(q+1) = 0;
3319: #endif
3320: #endif
3321:
3322: /* combine sign and exponent */
3323: i = *p++;
3324: #if defined(MIEEE) || defined(IBM)
3325: if (i)
3326: *q++ = *p++ | 0x8000;
3327: else
3328: *q++ = *p++;
3329: *q++ = 0;
3330: #else
3331: if (i)
3332: *q-- = *p++ | 0x8000;
3333: else
3334: *q-- = *p++;
3335: #endif
3336: /* skip over guard word */
3337: ++p;
3338: /* move the significand */
3339: #if defined(MIEEE) || defined(IBM)
3340: for (i = 0; i < 4; i++)
3341: *q++ = *p++;
3342: #else
3343: for (i = 0; i < 4; i++)
3344: *q-- = *p++;
3345: #endif
3346: }
3347:
3348:
3349: /*
3350: ; e type to IEEE double precision
3351: ; double d;
3352: ; unsigned EMUSHORT x[NE];
3353: ; etoe53 (x, &d);
3354: */
3355:
3356: #ifdef DEC
3357:
3358: void
3359: etoe53 (x, e)
3360: unsigned EMUSHORT *x, *e;
3361: {
3362: etodec (x, e); /* see etodec.c */
3363: }
3364:
3365: static void
3366: toe53 (x, y)
3367: unsigned EMUSHORT *x, *y;
3368: {
3369: todec (x, y);
3370: }
3371:
3372: #else
3373: #ifdef IBM
3374:
3375: void
3376: etoe53 (x, e)
3377: unsigned EMUSHORT *x, *e;
3378: {
3379: etoibm (x, e, DFmode);
3380: }
3381:
3382: static void
3383: toe53 (x, y)
3384: unsigned EMUSHORT *x, *y;
3385: {
3386: toibm (x, y, DFmode);
3387: }
3388:
3389: #else /* it's neither DEC nor IBM */
3390:
3391: void
3392: etoe53 (x, e)
3393: unsigned EMUSHORT *x, *e;
3394: {
3395: unsigned EMUSHORT xi[NI];
3396: EMULONG exp;
3397: int rndsav;
3398:
3399: #ifdef NANS
3400: if (eisnan (x))
3401: {
3402: make_nan (e, DFmode);
3403: return;
3404: }
3405: #endif
3406: emovi (x, xi);
3407: /* adjust exponent for offsets */
3408: exp = (EMULONG) xi[E] - (EXONE - 0x3ff);
3409: #ifdef INFINITY
3410: if (eisinf (x))
3411: goto nonorm;
3412: #endif
3413: /* round off to nearest or even */
3414: rndsav = rndprc;
3415: rndprc = 53;
3416: emdnorm (xi, 0, 0, exp, 64);
3417: rndprc = rndsav;
3418: nonorm:
3419: toe53 (xi, e);
3420: }
3421:
3422:
3423: static void
3424: toe53 (x, y)
3425: unsigned EMUSHORT *x, *y;
3426: {
3427: unsigned EMUSHORT i;
3428: unsigned EMUSHORT *p;
3429:
3430: #ifdef NANS
3431: if (eiisnan (x))
3432: {
3433: make_nan (y, DFmode);
3434: return;
3435: }
3436: #endif
3437: p = &x[0];
3438: #ifdef IBMPC
3439: y += 3;
3440: #endif
3441: *y = 0; /* output high order */
3442: if (*p++)
3443: *y = 0x8000; /* output sign bit */
3444:
3445: i = *p++;
3446: if (i >= (unsigned int) 2047)
3447: { /* Saturate at largest number less than infinity. */
3448: #ifdef INFINITY
3449: *y |= 0x7ff0;
3450: #ifdef IBMPC
3451: *(--y) = 0;
3452: *(--y) = 0;
3453: *(--y) = 0;
3454: #endif
3455: #ifdef MIEEE
3456: ++y;
3457: *y++ = 0;
3458: *y++ = 0;
3459: *y++ = 0;
3460: #endif
3461: #else
3462: *y |= (unsigned EMUSHORT) 0x7fef;
3463: #ifdef IBMPC
3464: *(--y) = 0xffff;
3465: *(--y) = 0xffff;
3466: *(--y) = 0xffff;
3467: #endif
3468: #ifdef MIEEE
3469: ++y;
3470: *y++ = 0xffff;
3471: *y++ = 0xffff;
3472: *y++ = 0xffff;
3473: #endif
3474: #endif
3475: return;
3476: }
3477: if (i == 0)
3478: {
3479: eshift (x, 4);
3480: }
3481: else
3482: {
3483: i <<= 4;
3484: eshift (x, 5);
3485: }
3486: i |= *p++ & (unsigned EMUSHORT) 0x0f; /* *p = xi[M] */
3487: *y |= (unsigned EMUSHORT) i; /* high order output already has sign bit set */
3488: #ifdef IBMPC
3489: *(--y) = *p++;
3490: *(--y) = *p++;
3491: *(--y) = *p;
3492: #endif
3493: #ifdef MIEEE
3494: ++y;
3495: *y++ = *p++;
3496: *y++ = *p++;
3497: *y++ = *p++;
3498: #endif
3499: }
3500:
3501: #endif /* not IBM */
3502: #endif /* not DEC */
3503:
3504:
3505:
3506: /*
3507: ; e type to IEEE single precision
3508: ; float d;
3509: ; unsigned EMUSHORT x[N+2];
3510: ; xtod (x, &d);
3511: */
3512: #ifdef IBM
3513:
3514: void
3515: etoe24 (x, e)
3516: unsigned EMUSHORT *x, *e;
3517: {
3518: etoibm (x, e, SFmode);
3519: }
3520:
3521: static void
3522: toe24 (x, y)
3523: unsigned EMUSHORT *x, *y;
3524: {
3525: toibm (x, y, SFmode);
3526: }
3527:
3528: #else
3529:
3530: void
3531: etoe24 (x, e)
3532: unsigned EMUSHORT *x, *e;
3533: {
3534: EMULONG exp;
3535: unsigned EMUSHORT xi[NI];
3536: int rndsav;
3537:
3538: #ifdef NANS
3539: if (eisnan (x))
3540: {
3541: make_nan (e, SFmode);
3542: return;
3543: }
3544: #endif
3545: emovi (x, xi);
3546: /* adjust exponent for offsets */
3547: exp = (EMULONG) xi[E] - (EXONE - 0177);
3548: #ifdef INFINITY
3549: if (eisinf (x))
3550: goto nonorm;
3551: #endif
3552: /* round off to nearest or even */
3553: rndsav = rndprc;
3554: rndprc = 24;
3555: emdnorm (xi, 0, 0, exp, 64);
3556: rndprc = rndsav;
3557: nonorm:
3558: toe24 (xi, e);
3559: }
3560:
3561: static void
3562: toe24 (x, y)
3563: unsigned EMUSHORT *x, *y;
3564: {
3565: unsigned EMUSHORT i;
3566: unsigned EMUSHORT *p;
3567:
3568: #ifdef NANS
3569: if (eiisnan (x))
3570: {
3571: make_nan (y, SFmode);
3572: return;
3573: }
3574: #endif
3575: p = &x[0];
3576: #ifdef IBMPC
3577: y += 1;
3578: #endif
3579: #ifdef DEC
3580: y += 1;
3581: #endif
3582: *y = 0; /* output high order */
3583: if (*p++)
3584: *y = 0x8000; /* output sign bit */
3585:
3586: i = *p++;
3587: /* Handle overflow cases. */
3588: if (i >= 255)
3589: {
3590: #ifdef INFINITY
3591: *y |= (unsigned EMUSHORT) 0x7f80;
3592: #ifdef IBMPC
3593: *(--y) = 0;
3594: #endif
3595: #ifdef DEC
3596: *(--y) = 0;
3597: #endif
3598: #ifdef MIEEE
3599: ++y;
3600: *y = 0;
3601: #endif
3602: #else /* no INFINITY */
3603: *y |= (unsigned EMUSHORT) 0x7f7f;
3604: #ifdef IBMPC
3605: *(--y) = 0xffff;
3606: #endif
3607: #ifdef DEC
3608: *(--y) = 0xffff;
3609: #endif
3610: #ifdef MIEEE
3611: ++y;
3612: *y = 0xffff;
3613: #endif
3614: #ifdef ERANGE
3615: errno = ERANGE;
3616: #endif
3617: #endif /* no INFINITY */
3618: return;
3619: }
3620: if (i == 0)
3621: {
3622: eshift (x, 7);
3623: }
3624: else
3625: {
3626: i <<= 7;
3627: eshift (x, 8);
3628: }
3629: i |= *p++ & (unsigned EMUSHORT) 0x7f; /* *p = xi[M] */
3630: *y |= i; /* high order output already has sign bit set */
3631: #ifdef IBMPC
3632: *(--y) = *p;
3633: #endif
3634: #ifdef DEC
3635: *(--y) = *p;
3636: #endif
3637: #ifdef MIEEE
3638: ++y;
3639: *y = *p;
3640: #endif
3641: }
3642: #endif /* not IBM */
3643:
3644: /* Compare two e type numbers.
3645: *
3646: * unsigned EMUSHORT a[NE], b[NE];
3647: * ecmp (a, b);
3648: *
3649: * returns +1 if a > b
3650: * 0 if a == b
3651: * -1 if a < b
3652: * -2 if either a or b is a NaN.
3653: */
3654: int
3655: ecmp (a, b)
3656: unsigned EMUSHORT *a, *b;
3657: {
3658: unsigned EMUSHORT ai[NI], bi[NI];
3659: register unsigned EMUSHORT *p, *q;
3660: register int i;
3661: int msign;
3662:
3663: #ifdef NANS
3664: if (eisnan (a) || eisnan (b))
3665: return (-2);
3666: #endif
3667: emovi (a, ai);
3668: p = ai;
3669: emovi (b, bi);
3670: q = bi;
3671:
3672: if (*p != *q)
3673: { /* the signs are different */
3674: /* -0 equals + 0 */
3675: for (i = 1; i < NI - 1; i++)
3676: {
3677: if (ai[i] != 0)
3678: goto nzro;
3679: if (bi[i] != 0)
3680: goto nzro;
3681: }
3682: return (0);
3683: nzro:
3684: if (*p == 0)
3685: return (1);
3686: else
3687: return (-1);
3688: }
3689: /* both are the same sign */
3690: if (*p == 0)
3691: msign = 1;
3692: else
3693: msign = -1;
3694: i = NI - 1;
3695: do
3696: {
3697: if (*p++ != *q++)
3698: {
3699: goto diff;
3700: }
3701: }
3702: while (--i > 0);
3703:
3704: return (0); /* equality */
3705:
3706:
3707:
3708: diff:
3709:
3710: if (*(--p) > *(--q))
3711: return (msign); /* p is bigger */
3712: else
3713: return (-msign); /* p is littler */
3714: }
3715:
3716:
3717:
3718:
3719: /* Find nearest integer to x = floor (x + 0.5)
3720: *
3721: * unsigned EMUSHORT x[NE], y[NE]
3722: * eround (x, y);
3723: */
3724: void
3725: eround (x, y)
3726: unsigned EMUSHORT *x, *y;
3727: {
3728: eadd (ehalf, x, y);
3729: efloor (y, y);
3730: }
3731:
3732:
3733:
3734:
3735: /*
3736: ; convert HOST_WIDE_INT to e type
3737: ;
3738: ; HOST_WIDE_INT l;
3739: ; unsigned EMUSHORT x[NE];
3740: ; ltoe (&l, x);
3741: ; note &l is the memory address of l
3742: */
3743: void
3744: ltoe (lp, y)
3745: HOST_WIDE_INT *lp;
3746: unsigned EMUSHORT *y;
3747: {
3748: unsigned EMUSHORT yi[NI];
3749: unsigned HOST_WIDE_INT ll;
3750: int k;
3751:
3752: ecleaz (yi);
3753: if (*lp < 0)
3754: {
3755: /* make it positive */
3756: ll = (unsigned HOST_WIDE_INT) (-(*lp));
3757: yi[0] = 0xffff; /* put correct sign in the e type number */
3758: }
3759: else
3760: {
3761: ll = (unsigned HOST_WIDE_INT) (*lp);
3762: }
3763: /* move the long integer to yi significand area */
3764: #if HOST_BITS_PER_WIDE_INT == 64
3765: yi[M] = (unsigned EMUSHORT) (ll >> 48);
3766: yi[M + 1] = (unsigned EMUSHORT) (ll >> 32);
3767: yi[M + 2] = (unsigned EMUSHORT) (ll >> 16);
3768: yi[M + 3] = (unsigned EMUSHORT) ll;
3769: yi[E] = EXONE + 47; /* exponent if normalize shift count were 0 */
3770: #else
3771: yi[M] = (unsigned EMUSHORT) (ll >> 16);
3772: yi[M + 1] = (unsigned EMUSHORT) ll;
3773: yi[E] = EXONE + 15; /* exponent if normalize shift count were 0 */
3774: #endif
3775:
3776: if ((k = enormlz (yi)) > NBITS)/* normalize the significand */
3777: ecleaz (yi); /* it was zero */
3778: else
3779: yi[E] -= (unsigned EMUSHORT) k;/* subtract shift count from exponent */
3780: emovo (yi, y); /* output the answer */
3781: }
3782:
3783: /*
3784: ; convert unsigned HOST_WIDE_INT to e type
3785: ;
3786: ; unsigned HOST_WIDE_INT l;
3787: ; unsigned EMUSHORT x[NE];
3788: ; ltox (&l, x);
3789: ; note &l is the memory address of l
3790: */
3791: void
3792: ultoe (lp, y)
3793: unsigned HOST_WIDE_INT *lp;
3794: unsigned EMUSHORT *y;
3795: {
3796: unsigned EMUSHORT yi[NI];
3797: unsigned HOST_WIDE_INT ll;
3798: int k;
3799:
3800: ecleaz (yi);
3801: ll = *lp;
3802:
3803: /* move the long integer to ayi significand area */
3804: #if HOST_BITS_PER_WIDE_INT == 64
3805: yi[M] = (unsigned EMUSHORT) (ll >> 48);
3806: yi[M + 1] = (unsigned EMUSHORT) (ll >> 32);
3807: yi[M + 2] = (unsigned EMUSHORT) (ll >> 16);
3808: yi[M + 3] = (unsigned EMUSHORT) ll;
3809: yi[E] = EXONE + 47; /* exponent if normalize shift count were 0 */
3810: #else
3811: yi[M] = (unsigned EMUSHORT) (ll >> 16);
3812: yi[M + 1] = (unsigned EMUSHORT) ll;
3813: yi[E] = EXONE + 15; /* exponent if normalize shift count were 0 */
3814: #endif
3815:
3816: if ((k = enormlz (yi)) > NBITS)/* normalize the significand */
3817: ecleaz (yi); /* it was zero */
3818: else
3819: yi[E] -= (unsigned EMUSHORT) k; /* subtract shift count from exponent */
3820: emovo (yi, y); /* output the answer */
3821: }
3822:
3823:
3824: /*
3825: ; Find signed HOST_WIDE_INT integer and floating point fractional parts
3826:
3827: ; HOST_WIDE_INT i;
3828: ; unsigned EMUSHORT x[NE], frac[NE];
3829: ; xifrac (x, &i, frac);
3830:
3831: The integer output has the sign of the input. The fraction is
3832: the positive fractional part of abs (x).
3833: */
3834: void
3835: eifrac (x, i, frac)
3836: unsigned EMUSHORT *x;
3837: HOST_WIDE_INT *i;
3838: unsigned EMUSHORT *frac;
3839: {
3840: unsigned EMUSHORT xi[NI];
3841: int j, k;
3842: unsigned HOST_WIDE_INT ll;
3843:
3844: emovi (x, xi);
3845: k = (int) xi[E] - (EXONE - 1);
3846: if (k <= 0)
3847: {
3848: /* if exponent <= 0, integer = 0 and real output is fraction */
3849: *i = 0L;
3850: emovo (xi, frac);
3851: return;
3852: }
3853: if (k > (HOST_BITS_PER_WIDE_INT - 1))
3854: {
3855: /* long integer overflow: output large integer
3856: and correct fraction */
3857: if (xi[0])
3858: *i = ((unsigned HOST_WIDE_INT) 1) << (HOST_BITS_PER_WIDE_INT - 1);
3859: else
3860: *i = (((unsigned HOST_WIDE_INT) 1) << (HOST_BITS_PER_WIDE_INT - 1)) - 1;
3861: eshift (xi, k);
3862: if (extra_warnings)
3863: warning ("overflow on truncation to integer");
3864: }
3865: else if (k > 16)
3866: {
3867: /* Shift more than 16 bits: first shift up k-16 mod 16,
3868: then shift up by 16's. */
3869: j = k - ((k >> 4) << 4);
3870: eshift (xi, j);
3871: ll = xi[M];
3872: k -= j;
3873: do
3874: {
3875: eshup6 (xi);
3876: ll = (ll << 16) | xi[M];
3877: }
3878: while ((k -= 16) > 0);
3879: *i = ll;
3880: if (xi[0])
3881: *i = -(*i);
3882: }
3883: else
3884: {
3885: /* shift not more than 16 bits */
3886: eshift (xi, k);
3887: *i = (HOST_WIDE_INT) xi[M] & 0xffff;
3888: if (xi[0])
3889: *i = -(*i);
3890: }
3891: xi[0] = 0;
3892: xi[E] = EXONE - 1;
3893: xi[M] = 0;
3894: if ((k = enormlz (xi)) > NBITS)
3895: ecleaz (xi);
3896: else
3897: xi[E] -= (unsigned EMUSHORT) k;
3898:
3899: emovo (xi, frac);
3900: }
3901:
3902:
3903: /* Find unsigned HOST_WIDE_INT integer and floating point fractional parts.
3904: A negative e type input yields integer output = 0
3905: but correct fraction. */
3906:
3907: void
3908: euifrac (x, i, frac)
3909: unsigned EMUSHORT *x;
3910: unsigned HOST_WIDE_INT *i;
3911: unsigned EMUSHORT *frac;
3912: {
3913: unsigned HOST_WIDE_INT ll;
3914: unsigned EMUSHORT xi[NI];
3915: int j, k;
3916:
3917: emovi (x, xi);
3918: k = (int) xi[E] - (EXONE - 1);
3919: if (k <= 0)
3920: {
3921: /* if exponent <= 0, integer = 0 and argument is fraction */
3922: *i = 0L;
3923: emovo (xi, frac);
3924: return;
3925: }
3926: if (k > HOST_BITS_PER_WIDE_INT)
3927: {
3928: /* Long integer overflow: output large integer
3929: and correct fraction.
3930: Note, the BSD microvax compiler says that ~(0UL)
3931: is a syntax error. */
3932: *i = ~(0L);
3933: eshift (xi, k);
3934: if (extra_warnings)
3935: warning ("overflow on truncation to unsigned integer");
3936: }
3937: else if (k > 16)
3938: {
3939: /* Shift more than 16 bits: first shift up k-16 mod 16,
3940: then shift up by 16's. */
3941: j = k - ((k >> 4) << 4);
3942: eshift (xi, j);
3943: ll = xi[M];
3944: k -= j;
3945: do
3946: {
3947: eshup6 (xi);
3948: ll = (ll << 16) | xi[M];
3949: }
3950: while ((k -= 16) > 0);
3951: *i = ll;
3952: }
3953: else
3954: {
3955: /* shift not more than 16 bits */
3956: eshift (xi, k);
3957: *i = (HOST_WIDE_INT) xi[M] & 0xffff;
3958: }
3959:
3960: if (xi[0]) /* A negative value yields unsigned integer 0. */
3961: *i = 0L;
3962:
3963: xi[0] = 0;
3964: xi[E] = EXONE - 1;
3965: xi[M] = 0;
3966: if ((k = enormlz (xi)) > NBITS)
3967: ecleaz (xi);
3968: else
3969: xi[E] -= (unsigned EMUSHORT) k;
3970:
3971: emovo (xi, frac);
3972: }
3973:
3974:
3975:
3976: /*
3977: ; Shift significand
3978: ;
3979: ; Shifts significand area up or down by the number of bits
3980: ; given by the variable sc.
3981: */
3982: int
3983: eshift (x, sc)
3984: unsigned EMUSHORT *x;
3985: int sc;
3986: {
3987: unsigned EMUSHORT lost;
3988: unsigned EMUSHORT *p;
3989:
3990: if (sc == 0)
3991: return (0);
3992:
3993: lost = 0;
3994: p = x + NI - 1;
3995:
3996: if (sc < 0)
3997: {
3998: sc = -sc;
3999: while (sc >= 16)
4000: {
4001: lost |= *p; /* remember lost bits */
4002: eshdn6 (x);
4003: sc -= 16;
4004: }
4005:
4006: while (sc >= 8)
4007: {
4008: lost |= *p & 0xff;
4009: eshdn8 (x);
4010: sc -= 8;
4011: }
4012:
4013: while (sc > 0)
4014: {
4015: lost |= *p & 1;
4016: eshdn1 (x);
4017: sc -= 1;
4018: }
4019: }
4020: else
4021: {
4022: while (sc >= 16)
4023: {
4024: eshup6 (x);
4025: sc -= 16;
4026: }
4027:
4028: while (sc >= 8)
4029: {
4030: eshup8 (x);
4031: sc -= 8;
4032: }
4033:
4034: while (sc > 0)
4035: {
4036: eshup1 (x);
4037: sc -= 1;
4038: }
4039: }
4040: if (lost)
4041: lost = 1;
4042: return ((int) lost);
4043: }
4044:
4045:
4046:
4047: /*
4048: ; normalize
4049: ;
4050: ; Shift normalizes the significand area pointed to by argument
4051: ; shift count (up = positive) is returned.
4052: */
4053: int
4054: enormlz (x)
4055: unsigned EMUSHORT x[];
4056: {
4057: register unsigned EMUSHORT *p;
4058: int sc;
4059:
4060: sc = 0;
4061: p = &x[M];
4062: if (*p != 0)
4063: goto normdn;
4064: ++p;
4065: if (*p & 0x8000)
4066: return (0); /* already normalized */
4067: while (*p == 0)
4068: {
4069: eshup6 (x);
4070: sc += 16;
4071: /* With guard word, there are NBITS+16 bits available.
4072: * return true if all are zero.
4073: */
4074: if (sc > NBITS)
4075: return (sc);
4076: }
4077: /* see if high byte is zero */
4078: while ((*p & 0xff00) == 0)
4079: {
4080: eshup8 (x);
4081: sc += 8;
4082: }
4083: /* now shift 1 bit at a time */
4084: while ((*p & 0x8000) == 0)
4085: {
4086: eshup1 (x);
4087: sc += 1;
4088: if (sc > NBITS)
4089: {
4090: mtherr ("enormlz", UNDERFLOW);
4091: return (sc);
4092: }
4093: }
4094: return (sc);
4095:
4096: /* Normalize by shifting down out of the high guard word
4097: of the significand */
4098: normdn:
4099:
4100: if (*p & 0xff00)
4101: {
4102: eshdn8 (x);
4103: sc -= 8;
4104: }
4105: while (*p != 0)
4106: {
4107: eshdn1 (x);
4108: sc -= 1;
4109:
4110: if (sc < -NBITS)
4111: {
4112: mtherr ("enormlz", OVERFLOW);
4113: return (sc);
4114: }
4115: }
4116: return (sc);
4117: }
4118:
4119:
4120:
4121:
4122: /* Convert e type number to decimal format ASCII string.
4123: * The constants are for 64 bit precision.
4124: */
4125:
4126: #define NTEN 12
4127: #define MAXP 4096
4128:
4129: #if LONG_DOUBLE_TYPE_SIZE == 128
4130: static unsigned EMUSHORT etens[NTEN + 1][NE] =
4131: {
4132: {0x6576, 0x4a92, 0x804a, 0x153f,
4133: 0xc94c, 0x979a, 0x8a20, 0x5202, 0xc460, 0x7525,}, /* 10**4096 */
4134: {0x6a32, 0xce52, 0x329a, 0x28ce,
4135: 0xa74d, 0x5de4, 0xc53d, 0x3b5d, 0x9e8b, 0x5a92,}, /* 10**2048 */
4136: {0x526c, 0x50ce, 0xf18b, 0x3d28,
4137: 0x650d, 0x0c17, 0x8175, 0x7586, 0xc976, 0x4d48,},
4138: {0x9c66, 0x58f8, 0xbc50, 0x5c54,
4139: 0xcc65, 0x91c6, 0xa60e, 0xa0ae, 0xe319, 0x46a3,},
4140: {0x851e, 0xeab7, 0x98fe, 0x901b,
4141: 0xddbb, 0xde8d, 0x9df9, 0xebfb, 0xaa7e, 0x4351,},
4142: {0x0235, 0x0137, 0x36b1, 0x336c,
4143: 0xc66f, 0x8cdf, 0x80e9, 0x47c9, 0x93ba, 0x41a8,},
4144: {0x50f8, 0x25fb, 0xc76b, 0x6b71,
4145: 0x3cbf, 0xa6d5, 0xffcf, 0x1f49, 0xc278, 0x40d3,},
4146: {0x0000, 0x0000, 0x0000, 0x0000,
4147: 0xf020, 0xb59d, 0x2b70, 0xada8, 0x9dc5, 0x4069,},
4148: {0x0000, 0x0000, 0x0000, 0x0000,
4149: 0x0000, 0x0000, 0x0400, 0xc9bf, 0x8e1b, 0x4034,},
4150: {0x0000, 0x0000, 0x0000, 0x0000,
4151: 0x0000, 0x0000, 0x0000, 0x2000, 0xbebc, 0x4019,},
4152: {0x0000, 0x0000, 0x0000, 0x0000,
4153: 0x0000, 0x0000, 0x0000, 0x0000, 0x9c40, 0x400c,},
4154: {0x0000, 0x0000, 0x0000, 0x0000,
4155: 0x0000, 0x0000, 0x0000, 0x0000, 0xc800, 0x4005,},
4156: {0x0000, 0x0000, 0x0000, 0x0000,
4157: 0x0000, 0x0000, 0x0000, 0x0000, 0xa000, 0x4002,}, /* 10**1 */
4158: };
4159:
4160: static unsigned EMUSHORT emtens[NTEN + 1][NE] =
4161: {
4162: {0x2030, 0xcffc, 0xa1c3, 0x8123,
4163: 0x2de3, 0x9fde, 0xd2ce, 0x04c8, 0xa6dd, 0x0ad8,}, /* 10**-4096 */
4164: {0x8264, 0xd2cb, 0xf2ea, 0x12d4,
4165: 0x4925, 0x2de4, 0x3436, 0x534f, 0xceae, 0x256b,}, /* 10**-2048 */
4166: {0xf53f, 0xf698, 0x6bd3, 0x0158,
4167: 0x87a6, 0xc0bd, 0xda57, 0x82a5, 0xa2a6, 0x32b5,},
4168: {0xe731, 0x04d4, 0xe3f2, 0xd332,
4169: 0x7132, 0xd21c, 0xdb23, 0xee32, 0x9049, 0x395a,},
4170: {0xa23e, 0x5308, 0xfefb, 0x1155,
4171: 0xfa91, 0x1939, 0x637a, 0x4325, 0xc031, 0x3cac,},
4172: {0xe26d, 0xdbde, 0xd05d, 0xb3f6,
4173: 0xac7c, 0xe4a0, 0x64bc, 0x467c, 0xddd0, 0x3e55,},
4174: {0x2a20, 0x6224, 0x47b3, 0x98d7,
4175: 0x3f23, 0xe9a5, 0xa539, 0xea27, 0xa87f, 0x3f2a,},
4176: {0x0b5b, 0x4af2, 0xa581, 0x18ed,
4177: 0x67de, 0x94ba, 0x4539, 0x1ead, 0xcfb1, 0x3f94,},
4178: {0xbf71, 0xa9b3, 0x7989, 0xbe68,
4179: 0x4c2e, 0xe15b, 0xc44d, 0x94be, 0xe695, 0x3fc9,},
4180: {0x3d4d, 0x7c3d, 0x36ba, 0x0d2b,
4181: 0xfdc2, 0xcefc, 0x8461, 0x7711, 0xabcc, 0x3fe4,},
4182: {0xc155, 0xa4a8, 0x404e, 0x6113,
4183: 0xd3c3, 0x652b, 0xe219, 0x1758, 0xd1b7, 0x3ff1,},
4184: {0xd70a, 0x70a3, 0x0a3d, 0xa3d7,
4185: 0x3d70, 0xd70a, 0x70a3, 0x0a3d, 0xa3d7, 0x3ff8,},
4186: {0xcccd, 0xcccc, 0xcccc, 0xcccc,
4187: 0xcccc, 0xcccc, 0xcccc, 0xcccc, 0xcccc, 0x3ffb,}, /* 10**-1 */
4188: };
4189: #else
4190: /* LONG_DOUBLE_TYPE_SIZE is other than 128 */
4191: static unsigned EMUSHORT etens[NTEN + 1][NE] =
4192: {
4193: {0xc94c, 0x979a, 0x8a20, 0x5202, 0xc460, 0x7525,}, /* 10**4096 */
4194: {0xa74d, 0x5de4, 0xc53d, 0x3b5d, 0x9e8b, 0x5a92,}, /* 10**2048 */
4195: {0x650d, 0x0c17, 0x8175, 0x7586, 0xc976, 0x4d48,},
4196: {0xcc65, 0x91c6, 0xa60e, 0xa0ae, 0xe319, 0x46a3,},
4197: {0xddbc, 0xde8d, 0x9df9, 0xebfb, 0xaa7e, 0x4351,},
4198: {0xc66f, 0x8cdf, 0x80e9, 0x47c9, 0x93ba, 0x41a8,},
4199: {0x3cbf, 0xa6d5, 0xffcf, 0x1f49, 0xc278, 0x40d3,},
4200: {0xf020, 0xb59d, 0x2b70, 0xada8, 0x9dc5, 0x4069,},
4201: {0x0000, 0x0000, 0x0400, 0xc9bf, 0x8e1b, 0x4034,},
4202: {0x0000, 0x0000, 0x0000, 0x2000, 0xbebc, 0x4019,},
4203: {0x0000, 0x0000, 0x0000, 0x0000, 0x9c40, 0x400c,},
4204: {0x0000, 0x0000, 0x0000, 0x0000, 0xc800, 0x4005,},
4205: {0x0000, 0x0000, 0x0000, 0x0000, 0xa000, 0x4002,}, /* 10**1 */
4206: };
4207:
4208: static unsigned EMUSHORT emtens[NTEN + 1][NE] =
4209: {
4210: {0x2de4, 0x9fde, 0xd2ce, 0x04c8, 0xa6dd, 0x0ad8,}, /* 10**-4096 */
4211: {0x4925, 0x2de4, 0x3436, 0x534f, 0xceae, 0x256b,}, /* 10**-2048 */
4212: {0x87a6, 0xc0bd, 0xda57, 0x82a5, 0xa2a6, 0x32b5,},
4213: {0x7133, 0xd21c, 0xdb23, 0xee32, 0x9049, 0x395a,},
4214: {0xfa91, 0x1939, 0x637a, 0x4325, 0xc031, 0x3cac,},
4215: {0xac7d, 0xe4a0, 0x64bc, 0x467c, 0xddd0, 0x3e55,},
4216: {0x3f24, 0xe9a5, 0xa539, 0xea27, 0xa87f, 0x3f2a,},
4217: {0x67de, 0x94ba, 0x4539, 0x1ead, 0xcfb1, 0x3f94,},
4218: {0x4c2f, 0xe15b, 0xc44d, 0x94be, 0xe695, 0x3fc9,},
4219: {0xfdc2, 0xcefc, 0x8461, 0x7711, 0xabcc, 0x3fe4,},
4220: {0xd3c3, 0x652b, 0xe219, 0x1758, 0xd1b7, 0x3ff1,},
4221: {0x3d71, 0xd70a, 0x70a3, 0x0a3d, 0xa3d7, 0x3ff8,},
4222: {0xcccd, 0xcccc, 0xcccc, 0xcccc, 0xcccc, 0x3ffb,}, /* 10**-1 */
4223: };
4224: #endif
4225:
4226: void
4227: e24toasc (x, string, ndigs)
4228: unsigned EMUSHORT x[];
4229: char *string;
4230: int ndigs;
4231: {
4232: unsigned EMUSHORT w[NI];
4233:
4234: e24toe (x, w);
4235: etoasc (w, string, ndigs);
4236: }
4237:
4238:
4239: void
4240: e53toasc (x, string, ndigs)
4241: unsigned EMUSHORT x[];
4242: char *string;
4243: int ndigs;
4244: {
4245: unsigned EMUSHORT w[NI];
4246:
4247: e53toe (x, w);
4248: etoasc (w, string, ndigs);
4249: }
4250:
4251:
4252: void
4253: e64toasc (x, string, ndigs)
4254: unsigned EMUSHORT x[];
4255: char *string;
4256: int ndigs;
4257: {
4258: unsigned EMUSHORT w[NI];
4259:
4260: e64toe (x, w);
4261: etoasc (w, string, ndigs);
4262: }
4263:
4264: void
4265: e113toasc (x, string, ndigs)
4266: unsigned EMUSHORT x[];
4267: char *string;
4268: int ndigs;
4269: {
4270: unsigned EMUSHORT w[NI];
4271:
4272: e113toe (x, w);
4273: etoasc (w, string, ndigs);
4274: }
4275:
4276:
4277: static char wstring[80]; /* working storage for ASCII output */
4278:
4279: void
4280: etoasc (x, string, ndigs)
4281: unsigned EMUSHORT x[];
4282: char *string;
4283: int ndigs;
4284: {
4285: EMUSHORT digit;
4286: unsigned EMUSHORT y[NI], t[NI], u[NI], w[NI];
4287: unsigned EMUSHORT *p, *r, *ten;
4288: unsigned EMUSHORT sign;
4289: int i, j, k, expon, rndsav;
4290: char *s, *ss;
4291: unsigned EMUSHORT m;
4292:
4293:
4294: rndsav = rndprc;
4295: ss = string;
4296: s = wstring;
4297: *ss = '\0';
4298: *s = '\0';
4299: #ifdef NANS
4300: if (eisnan (x))
4301: {
4302: sprintf (wstring, " NaN ");
4303: goto bxit;
4304: }
4305: #endif
4306: rndprc = NBITS; /* set to full precision */
4307: emov (x, y); /* retain external format */
4308: if (y[NE - 1] & 0x8000)
4309: {
4310: sign = 0xffff;
4311: y[NE - 1] &= 0x7fff;
4312: }
4313: else
4314: {
4315: sign = 0;
4316: }
4317: expon = 0;
4318: ten = &etens[NTEN][0];
4319: emov (eone, t);
4320: /* Test for zero exponent */
4321: if (y[NE - 1] == 0)
4322: {
4323: for (k = 0; k < NE - 1; k++)
4324: {
4325: if (y[k] != 0)
4326: goto tnzro; /* denormalized number */
4327: }
4328: goto isone; /* legal all zeros */
4329: }
4330: tnzro:
4331:
4332: /* Test for infinity. */
4333: if (y[NE - 1] == 0x7fff)
4334: {
4335: if (sign)
4336: sprintf (wstring, " -Infinity ");
4337: else
4338: sprintf (wstring, " Infinity ");
4339: goto bxit;
4340: }
4341:
4342: /* Test for exponent nonzero but significand denormalized.
4343: * This is an error condition.
4344: */
4345: if ((y[NE - 1] != 0) && ((y[NE - 2] & 0x8000) == 0))
4346: {
4347: mtherr ("etoasc", DOMAIN);
4348: sprintf (wstring, "NaN");
4349: goto bxit;
4350: }
4351:
4352: /* Compare to 1.0 */
4353: i = ecmp (eone, y);
4354: if (i == 0)
4355: goto isone;
4356:
4357: if (i == -2)
4358: abort ();
4359:
4360: if (i < 0)
4361: { /* Number is greater than 1 */
4362: /* Convert significand to an integer and strip trailing decimal zeros. */
4363: emov (y, u);
4364: u[NE - 1] = EXONE + NBITS - 1;
4365:
4366: p = &etens[NTEN - 4][0];
4367: m = 16;
4368: do
4369: {
4370: ediv (p, u, t);
4371: efloor (t, w);
4372: for (j = 0; j < NE - 1; j++)
4373: {
4374: if (t[j] != w[j])
4375: goto noint;
4376: }
4377: emov (t, u);
4378: expon += (int) m;
4379: noint:
4380: p += NE;
4381: m >>= 1;
4382: }
4383: while (m != 0);
4384:
4385: /* Rescale from integer significand */
4386: u[NE - 1] += y[NE - 1] - (unsigned int) (EXONE + NBITS - 1);
4387: emov (u, y);
4388: /* Find power of 10 */
4389: emov (eone, t);
4390: m = MAXP;
4391: p = &etens[0][0];
4392: /* An unordered compare result shouldn't happen here. */
4393: while (ecmp (ten, u) <= 0)
4394: {
4395: if (ecmp (p, u) <= 0)
4396: {
4397: ediv (p, u, u);
4398: emul (p, t, t);
4399: expon += (int) m;
4400: }
4401: m >>= 1;
4402: if (m == 0)
4403: break;
4404: p += NE;
4405: }
4406: }
4407: else
4408: { /* Number is less than 1.0 */
4409: /* Pad significand with trailing decimal zeros. */
4410: if (y[NE - 1] == 0)
4411: {
4412: while ((y[NE - 2] & 0x8000) == 0)
4413: {
4414: emul (ten, y, y);
4415: expon -= 1;
4416: }
4417: }
4418: else
4419: {
4420: emovi (y, w);
4421: for (i = 0; i < NDEC + 1; i++)
4422: {
4423: if ((w[NI - 1] & 0x7) != 0)
4424: break;
4425: /* multiply by 10 */
4426: emovz (w, u);
4427: eshdn1 (u);
4428: eshdn1 (u);
4429: eaddm (w, u);
4430: u[1] += 3;
4431: while (u[2] != 0)
4432: {
4433: eshdn1 (u);
4434: u[1] += 1;
4435: }
4436: if (u[NI - 1] != 0)
4437: break;
4438: if (eone[NE - 1] <= u[1])
4439: break;
4440: emovz (u, w);
4441: expon -= 1;
4442: }
4443: emovo (w, y);
4444: }
4445: k = -MAXP;
4446: p = &emtens[0][0];
4447: r = &etens[0][0];
4448: emov (y, w);
4449: emov (eone, t);
4450: while (ecmp (eone, w) > 0)
4451: {
4452: if (ecmp (p, w) >= 0)
4453: {
4454: emul (r, w, w);
4455: emul (r, t, t);
4456: expon += k;
4457: }
4458: k /= 2;
4459: if (k == 0)
4460: break;
4461: p += NE;
4462: r += NE;
4463: }
4464: ediv (t, eone, t);
4465: }
4466: isone:
4467: /* Find the first (leading) digit. */
4468: emovi (t, w);
4469: emovz (w, t);
4470: emovi (y, w);
4471: emovz (w, y);
4472: eiremain (t, y);
4473: digit = equot[NI - 1];
4474: while ((digit == 0) && (ecmp (y, ezero) != 0))
4475: {
4476: eshup1 (y);
4477: emovz (y, u);
4478: eshup1 (u);
4479: eshup1 (u);
4480: eaddm (u, y);
4481: eiremain (t, y);
4482: digit = equot[NI - 1];
4483: expon -= 1;
4484: }
4485: s = wstring;
4486: if (sign)
4487: *s++ = '-';
4488: else
4489: *s++ = ' ';
4490: /* Examine number of digits requested by caller. */
4491: if (ndigs < 0)
4492: ndigs = 0;
4493: if (ndigs > NDEC)
4494: ndigs = NDEC;
4495: if (digit == 10)
4496: {
4497: *s++ = '1';
4498: *s++ = '.';
4499: if (ndigs > 0)
4500: {
4501: *s++ = '0';
4502: ndigs -= 1;
4503: }
4504: expon += 1;
4505: }
4506: else
4507: {
4508: *s++ = (char)digit + '0';
4509: *s++ = '.';
4510: }
4511: /* Generate digits after the decimal point. */
4512: for (k = 0; k <= ndigs; k++)
4513: {
4514: /* multiply current number by 10, without normalizing */
4515: eshup1 (y);
4516: emovz (y, u);
4517: eshup1 (u);
4518: eshup1 (u);
4519: eaddm (u, y);
4520: eiremain (t, y);
4521: *s++ = (char) equot[NI - 1] + '0';
4522: }
4523: digit = equot[NI - 1];
4524: --s;
4525: ss = s;
4526: /* round off the ASCII string */
4527: if (digit > 4)
4528: {
4529: /* Test for critical rounding case in ASCII output. */
4530: if (digit == 5)
4531: {
4532: emovo (y, t);
4533: if (ecmp (t, ezero) != 0)
4534: goto roun; /* round to nearest */
4535: if ((*(s - 1) & 1) == 0)
4536: goto doexp; /* round to even */
4537: }
4538: /* Round up and propagate carry-outs */
4539: roun:
4540: --s;
4541: k = *s & 0x7f;
4542: /* Carry out to most significant digit? */
4543: if (k == '.')
4544: {
4545: --s;
4546: k = *s;
4547: k += 1;
4548: *s = (char) k;
4549: /* Most significant digit carries to 10? */
4550: if (k > '9')
4551: {
4552: expon += 1;
4553: *s = '1';
4554: }
4555: goto doexp;
4556: }
4557: /* Round up and carry out from less significant digits */
4558: k += 1;
4559: *s = (char) k;
4560: if (k > '9')
4561: {
4562: *s = '0';
4563: goto roun;
4564: }
4565: }
4566: doexp:
4567: /*
4568: if (expon >= 0)
4569: sprintf (ss, "e+%d", expon);
4570: else
4571: sprintf (ss, "e%d", expon);
4572: */
4573: sprintf (ss, "e%d", expon);
4574: bxit:
4575: rndprc = rndsav;
4576: /* copy out the working string */
4577: s = string;
4578: ss = wstring;
4579: while (*ss == ' ') /* strip possible leading space */
4580: ++ss;
4581: while ((*s++ = *ss++) != '\0')
4582: ;
4583: }
4584:
4585:
4586:
4587:
4588: /*
4589: ; ASCTOQ
4590: ; ASCTOQ.MAC LATEST REV: 11 JAN 84
4591: ; SLM, 3 JAN 78
4592: ;
4593: ; Convert ASCII string to quadruple precision floating point
4594: ;
4595: ; Numeric input is free field decimal number
4596: ; with max of 15 digits with or without
4597: ; decimal point entered as ASCII from teletype.
4598: ; Entering E after the number followed by a second
4599: ; number causes the second number to be interpreted
4600: ; as a power of 10 to be multiplied by the first number
4601: ; (i.e., "scientific" notation).
4602: ;
4603: ; Usage:
4604: ; asctoq (string, q);
4605: */
4606:
4607: /* ASCII to single */
4608: void
4609: asctoe24 (s, y)
4610: char *s;
4611: unsigned EMUSHORT *y;
4612: {
4613: asctoeg (s, y, 24);
4614: }
4615:
4616:
4617: /* ASCII to double */
4618: void
4619: asctoe53 (s, y)
4620: char *s;
4621: unsigned EMUSHORT *y;
4622: {
4623: #if defined(DEC) || defined(IBM)
4624: asctoeg (s, y, 56);
4625: #else
4626: asctoeg (s, y, 53);
4627: #endif
4628: }
4629:
4630:
4631: /* ASCII to long double */
4632: void
4633: asctoe64 (s, y)
4634: char *s;
4635: unsigned EMUSHORT *y;
4636: {
4637: asctoeg (s, y, 64);
4638: }
4639:
4640: /* ASCII to 128-bit long double */
4641: void
4642: asctoe113 (s, y)
4643: char *s;
4644: unsigned EMUSHORT *y;
4645: {
4646: asctoeg (s, y, 113);
4647: }
4648:
4649: /* ASCII to super double */
4650: void
4651: asctoe (s, y)
4652: char *s;
4653: unsigned EMUSHORT *y;
4654: {
4655: asctoeg (s, y, NBITS);
4656: }
4657:
4658:
4659: /* ASCII to e type, with specified rounding precision = oprec. */
4660: void
4661: asctoeg (ss, y, oprec)
4662: char *ss;
4663: unsigned EMUSHORT *y;
4664: int oprec;
4665: {
4666: unsigned EMUSHORT yy[NI], xt[NI], tt[NI];
4667: int esign, decflg, sgnflg, nexp, exp, prec, lost;
4668: int k, trail, c, rndsav;
4669: EMULONG lexp;
4670: unsigned EMUSHORT nsign, *p;
4671: char *sp, *s, *lstr;
4672:
4673: /* Copy the input string. */
4674: lstr = (char *) alloca (strlen (ss) + 1);
4675: s = ss;
4676: while (*s == ' ') /* skip leading spaces */
4677: ++s;
4678: sp = lstr;
4679: while ((*sp++ = *s++) != '\0')
4680: ;
4681: s = lstr;
4682:
4683: rndsav = rndprc;
4684: rndprc = NBITS; /* Set to full precision */
4685: lost = 0;
4686: nsign = 0;
4687: decflg = 0;
4688: sgnflg = 0;
4689: nexp = 0;
4690: exp = 0;
4691: prec = 0;
4692: ecleaz (yy);
4693: trail = 0;
4694:
4695: nxtcom:
4696: k = *s - '0';
4697: if ((k >= 0) && (k <= 9))
4698: {
4699: /* Ignore leading zeros */
4700: if ((prec == 0) && (decflg == 0) && (k == 0))
4701: goto donchr;
4702: /* Identify and strip trailing zeros after the decimal point. */
4703: if ((trail == 0) && (decflg != 0))
4704: {
4705: sp = s;
4706: while ((*sp >= '0') && (*sp <= '9'))
4707: ++sp;
4708: /* Check for syntax error */
4709: c = *sp & 0x7f;
4710: if ((c != 'e') && (c != 'E') && (c != '\0')
4711: && (c != '\n') && (c != '\r') && (c != ' ')
4712: && (c != ','))
4713: goto error;
4714: --sp;
4715: while (*sp == '0')
4716: *sp-- = 'z';
4717: trail = 1;
4718: if (*s == 'z')
4719: goto donchr;
4720: }
4721: /* If enough digits were given to more than fill up the yy register,
4722: * continuing until overflow into the high guard word yy[2]
4723: * guarantees that there will be a roundoff bit at the top
4724: * of the low guard word after normalization.
4725: */
4726: if (yy[2] == 0)
4727: {
4728: if (decflg)
4729: nexp += 1; /* count digits after decimal point */
4730: eshup1 (yy); /* multiply current number by 10 */
4731: emovz (yy, xt);
4732: eshup1 (xt);
4733: eshup1 (xt);
4734: eaddm (xt, yy);
4735: ecleaz (xt);
4736: xt[NI - 2] = (unsigned EMUSHORT) k;
4737: eaddm (xt, yy);
4738: }
4739: else
4740: {
4741: /* Mark any lost non-zero digit. */
4742: lost |= k;
4743: /* Count lost digits before the decimal point. */
4744: if (decflg == 0)
4745: nexp -= 1;
4746: }
4747: prec += 1;
4748: goto donchr;
4749: }
4750:
4751: switch (*s)
4752: {
4753: case 'z':
4754: break;
4755: case 'E':
4756: case 'e':
4757: goto expnt;
4758: case '.': /* decimal point */
4759: if (decflg)
4760: goto error;
4761: ++decflg;
4762: break;
4763: case '-':
4764: nsign = 0xffff;
4765: if (sgnflg)
4766: goto error;
4767: ++sgnflg;
4768: break;
4769: case '+':
4770: if (sgnflg)
4771: goto error;
4772: ++sgnflg;
4773: break;
4774: case ',':
4775: case ' ':
4776: case '\0':
4777: case '\n':
4778: case '\r':
4779: goto daldone;
4780: case 'i':
4781: case 'I':
4782: goto infinite;
4783: default:
4784: error:
4785: #ifdef NANS
4786: einan (yy);
4787: #else
4788: mtherr ("asctoe", DOMAIN);
4789: eclear (yy);
4790: #endif
4791: goto aexit;
4792: }
4793: donchr:
4794: ++s;
4795: goto nxtcom;
4796:
4797: /* Exponent interpretation */
4798: expnt:
4799:
4800: esign = 1;
4801: exp = 0;
4802: ++s;
4803: /* check for + or - */
4804: if (*s == '-')
4805: {
4806: esign = -1;
4807: ++s;
4808: }
4809: if (*s == '+')
4810: ++s;
4811: while ((*s >= '0') && (*s <= '9'))
4812: {
4813: exp *= 10;
4814: exp += *s++ - '0';
4815: if (exp > -(MINDECEXP))
4816: {
4817: if (esign < 0)
4818: goto zero;
4819: else
4820: goto infinite;
4821: }
4822: }
4823: if (esign < 0)
4824: exp = -exp;
4825: if (exp > MAXDECEXP)
4826: {
4827: infinite:
4828: ecleaz (yy);
4829: yy[E] = 0x7fff; /* infinity */
4830: goto aexit;
4831: }
4832: if (exp < MINDECEXP)
4833: {
4834: zero:
4835: ecleaz (yy);
4836: goto aexit;
4837: }
4838:
4839: daldone:
4840: nexp = exp - nexp;
4841: /* Pad trailing zeros to minimize power of 10, per IEEE spec. */
4842: while ((nexp > 0) && (yy[2] == 0))
4843: {
4844: emovz (yy, xt);
4845: eshup1 (xt);
4846: eshup1 (xt);
4847: eaddm (yy, xt);
4848: eshup1 (xt);
4849: if (xt[2] != 0)
4850: break;
4851: nexp -= 1;
4852: emovz (xt, yy);
4853: }
4854: if ((k = enormlz (yy)) > NBITS)
4855: {
4856: ecleaz (yy);
4857: goto aexit;
4858: }
4859: lexp = (EXONE - 1 + NBITS) - k;
4860: emdnorm (yy, lost, 0, lexp, 64);
4861: /* convert to external format */
4862:
4863:
4864: /* Multiply by 10**nexp. If precision is 64 bits,
4865: * the maximum relative error incurred in forming 10**n
4866: * for 0 <= n <= 324 is 8.2e-20, at 10**180.
4867: * For 0 <= n <= 999, the peak relative error is 1.4e-19 at 10**947.
4868: * For 0 >= n >= -999, it is -1.55e-19 at 10**-435.
4869: */
4870: lexp = yy[E];
4871: if (nexp == 0)
4872: {
4873: k = 0;
4874: goto expdon;
4875: }
4876: esign = 1;
4877: if (nexp < 0)
4878: {
4879: nexp = -nexp;
4880: esign = -1;
4881: if (nexp > 4096)
4882: { /* Punt. Can't handle this without 2 divides. */
4883: emovi (etens[0], tt);
4884: lexp -= tt[E];
4885: k = edivm (tt, yy);
4886: lexp += EXONE;
4887: nexp -= 4096;
4888: }
4889: }
4890: p = &etens[NTEN][0];
4891: emov (eone, xt);
4892: exp = 1;
4893: do
4894: {
4895: if (exp & nexp)
4896: emul (p, xt, xt);
4897: p -= NE;
4898: exp = exp + exp;
4899: }
4900: while (exp <= MAXP);
4901:
4902: emovi (xt, tt);
4903: if (esign < 0)
4904: {
4905: lexp -= tt[E];
4906: k = edivm (tt, yy);
4907: lexp += EXONE;
4908: }
4909: else
4910: {
4911: lexp += tt[E];
4912: k = emulm (tt, yy);
4913: lexp -= EXONE - 1;
4914: }
4915:
4916: expdon:
4917:
4918: /* Round and convert directly to the destination type */
4919: if (oprec == 53)
4920: lexp -= EXONE - 0x3ff;
4921: #ifdef IBM
4922: else if (oprec == 24 || oprec == 56)
4923: lexp -= EXONE - (0x41 << 2);
4924: #else
4925: else if (oprec == 24)
4926: lexp -= EXONE - 0177;
4927: #endif
4928: #ifdef DEC
4929: else if (oprec == 56)
4930: lexp -= EXONE - 0201;
4931: #endif
4932: rndprc = oprec;
4933: emdnorm (yy, k, 0, lexp, 64);
4934:
4935: aexit:
4936:
4937: rndprc = rndsav;
4938: yy[0] = nsign;
4939: switch (oprec)
4940: {
4941: #ifdef DEC
4942: case 56:
4943: todec (yy, y); /* see etodec.c */
4944: break;
4945: #endif
4946: #ifdef IBM
4947: case 56:
4948: toibm (yy, y, DFmode);
4949: break;
4950: #endif
4951: case 53:
4952: toe53 (yy, y);
4953: break;
4954: case 24:
4955: toe24 (yy, y);
4956: break;
4957: case 64:
4958: toe64 (yy, y);
4959: break;
4960: case 113:
4961: toe113 (yy, y);
4962: break;
4963: case NBITS:
4964: emovo (yy, y);
4965: break;
4966: }
4967: }
4968:
4969:
4970:
4971: /* y = largest integer not greater than x
4972: * (truncated toward minus infinity)
4973: *
4974: * unsigned EMUSHORT x[NE], y[NE]
4975: *
4976: * efloor (x, y);
4977: */
4978: static unsigned EMUSHORT bmask[] =
4979: {
4980: 0xffff,
4981: 0xfffe,
4982: 0xfffc,
4983: 0xfff8,
4984: 0xfff0,
4985: 0xffe0,
4986: 0xffc0,
4987: 0xff80,
4988: 0xff00,
4989: 0xfe00,
4990: 0xfc00,
4991: 0xf800,
4992: 0xf000,
4993: 0xe000,
4994: 0xc000,
4995: 0x8000,
4996: 0x0000,
4997: };
4998:
4999: void
5000: efloor (x, y)
5001: unsigned EMUSHORT x[], y[];
5002: {
5003: register unsigned EMUSHORT *p;
5004: int e, expon, i;
5005: unsigned EMUSHORT f[NE];
5006:
5007: emov (x, f); /* leave in external format */
5008: expon = (int) f[NE - 1];
5009: e = (expon & 0x7fff) - (EXONE - 1);
5010: if (e <= 0)
5011: {
5012: eclear (y);
5013: goto isitneg;
5014: }
5015: /* number of bits to clear out */
5016: e = NBITS - e;
5017: emov (f, y);
5018: if (e <= 0)
5019: return;
5020:
5021: p = &y[0];
5022: while (e >= 16)
5023: {
5024: *p++ = 0;
5025: e -= 16;
5026: }
5027: /* clear the remaining bits */
5028: *p &= bmask[e];
5029: /* truncate negatives toward minus infinity */
5030: isitneg:
5031:
5032: if ((unsigned EMUSHORT) expon & (unsigned EMUSHORT) 0x8000)
5033: {
5034: for (i = 0; i < NE - 1; i++)
5035: {
5036: if (f[i] != y[i])
5037: {
5038: esub (eone, y, y);
5039: break;
5040: }
5041: }
5042: }
5043: }
5044:
5045:
5046: /* unsigned EMUSHORT x[], s[];
5047: * int *exp;
5048: *
5049: * efrexp (x, exp, s);
5050: *
5051: * Returns s and exp such that s * 2**exp = x and .5 <= s < 1.
5052: * For example, 1.1 = 0.55 * 2**1
5053: * Handles denormalized numbers properly using long integer exp.
5054: */
5055: void
5056: efrexp (x, exp, s)
5057: unsigned EMUSHORT x[];
5058: int *exp;
5059: unsigned EMUSHORT s[];
5060: {
5061: unsigned EMUSHORT xi[NI];
5062: EMULONG li;
5063:
5064: emovi (x, xi);
5065: li = (EMULONG) ((EMUSHORT) xi[1]);
5066:
5067: if (li == 0)
5068: {
5069: li -= enormlz (xi);
5070: }
5071: xi[1] = 0x3ffe;
5072: emovo (xi, s);
5073: *exp = (int) (li - 0x3ffe);
5074: }
5075:
5076:
5077:
5078: /* unsigned EMUSHORT x[], y[];
5079: * int pwr2;
5080: *
5081: * eldexp (x, pwr2, y);
5082: *
5083: * Returns y = x * 2**pwr2.
5084: */
5085: void
5086: eldexp (x, pwr2, y)
5087: unsigned EMUSHORT x[];
5088: int pwr2;
5089: unsigned EMUSHORT y[];
5090: {
5091: unsigned EMUSHORT xi[NI];
5092: EMULONG li;
5093: int i;
5094:
5095: emovi (x, xi);
5096: li = xi[1];
5097: li += pwr2;
5098: i = 0;
5099: emdnorm (xi, i, i, li, 64);
5100: emovo (xi, y);
5101: }
5102:
5103:
5104: /* c = remainder after dividing b by a
5105: * Least significant integer quotient bits left in equot[].
5106: */
5107: void
5108: eremain (a, b, c)
5109: unsigned EMUSHORT a[], b[], c[];
5110: {
5111: unsigned EMUSHORT den[NI], num[NI];
5112:
5113: #ifdef NANS
5114: if (eisinf (b)
5115: || (ecmp (a, ezero) == 0)
5116: || eisnan (a)
5117: || eisnan (b))
5118: {
5119: enan (c);
5120: return;
5121: }
5122: #endif
5123: if (ecmp (a, ezero) == 0)
5124: {
5125: mtherr ("eremain", SING);
5126: eclear (c);
5127: return;
5128: }
5129: emovi (a, den);
5130: emovi (b, num);
5131: eiremain (den, num);
5132: /* Sign of remainder = sign of quotient */
5133: if (a[0] == b[0])
5134: num[0] = 0;
5135: else
5136: num[0] = 0xffff;
5137: emovo (num, c);
5138: }
5139:
5140: void
5141: eiremain (den, num)
5142: unsigned EMUSHORT den[], num[];
5143: {
5144: EMULONG ld, ln;
5145: unsigned EMUSHORT j;
5146:
5147: ld = den[E];
5148: ld -= enormlz (den);
5149: ln = num[E];
5150: ln -= enormlz (num);
5151: ecleaz (equot);
5152: while (ln >= ld)
5153: {
5154: if (ecmpm (den, num) <= 0)
5155: {
5156: esubm (den, num);
5157: j = 1;
5158: }
5159: else
5160: {
5161: j = 0;
5162: }
5163: eshup1 (equot);
5164: equot[NI - 1] |= j;
5165: eshup1 (num);
5166: ln -= 1;
5167: }
5168: emdnorm (num, 0, 0, ln, 0);
5169: }
5170:
5171: /* mtherr.c
5172: *
5173: * Library common error handling routine
5174: *
5175: *
5176: *
5177: * SYNOPSIS:
5178: *
5179: * char *fctnam;
5180: * int code;
5181: * void mtherr ();
5182: *
5183: * mtherr (fctnam, code);
5184: *
5185: *
5186: *
5187: * DESCRIPTION:
5188: *
5189: * This routine may be called to report one of the following
5190: * error conditions (in the include file mconf.h).
5191: *
5192: * Mnemonic Value Significance
5193: *
5194: * DOMAIN 1 argument domain error
5195: * SING 2 function singularity
5196: * OVERFLOW 3 overflow range error
5197: * UNDERFLOW 4 underflow range error
5198: * TLOSS 5 total loss of precision
5199: * PLOSS 6 partial loss of precision
5200: * INVALID 7 NaN - producing operation
5201: * EDOM 33 Unix domain error code
5202: * ERANGE 34 Unix range error code
5203: *
5204: * The default version of the file prints the function name,
5205: * passed to it by the pointer fctnam, followed by the
5206: * error condition. The display is directed to the standard
5207: * output device. The routine then returns to the calling
5208: * program. Users may wish to modify the program to abort by
5209: * calling exit under severe error conditions such as domain
5210: * errors.
5211: *
5212: * Since all error conditions pass control to this function,
5213: * the display may be easily changed, eliminated, or directed
5214: * to an error logging device.
5215: *
5216: * SEE ALSO:
5217: *
5218: * mconf.h
5219: *
5220: */
5221:
5222: /*
5223: Cephes Math Library Release 2.0: April, 1987
5224: Copyright 1984, 1987 by Stephen L. Moshier
5225: Direct inquiries to 30 Frost Street, Cambridge, MA 02140
5226: */
5227:
5228: /* include "mconf.h" */
5229:
5230: /* Notice: the order of appearance of the following
5231: * messages is bound to the error codes defined
5232: * in mconf.h.
5233: */
5234: #define NMSGS 8
5235: static char *ermsg[NMSGS] =
5236: {
5237: "unknown", /* error code 0 */
5238: "domain", /* error code 1 */
5239: "singularity", /* et seq. */
5240: "overflow",
5241: "underflow",
5242: "total loss of precision",
5243: "partial loss of precision",
5244: "invalid operation"
5245: };
5246:
5247: int merror = 0;
5248: extern int merror;
5249:
5250: void
5251: mtherr (name, code)
5252: char *name;
5253: int code;
5254: {
5255: char errstr[80];
5256:
5257: /* Display string passed by calling program,
5258: * which is supposed to be the name of the
5259: * function in which the error occurred.
5260: */
5261:
5262: /* Display error message defined
5263: * by the code argument.
5264: */
5265: if ((code <= 0) || (code >= NMSGS))
5266: code = 0;
5267: sprintf (errstr, " %s %s error", name, ermsg[code]);
5268: if (extra_warnings)
5269: warning (errstr);
5270: /* Set global error message word */
5271: merror = code + 1;
5272:
5273: /* Return to calling
5274: * program
5275: */
5276: }
5277:
5278: #ifdef DEC
5279: /* Here is etodec.c .
5280: *
5281: */
5282:
5283: /*
5284: ; convert DEC double precision to e type
5285: ; double d;
5286: ; EMUSHORT e[NE];
5287: ; dectoe (&d, e);
5288: */
5289: void
5290: dectoe (d, e)
5291: unsigned EMUSHORT *d;
5292: unsigned EMUSHORT *e;
5293: {
5294: unsigned EMUSHORT y[NI];
5295: register unsigned EMUSHORT r, *p;
5296:
5297: ecleaz (y); /* start with a zero */
5298: p = y; /* point to our number */
5299: r = *d; /* get DEC exponent word */
5300: if (*d & (unsigned int) 0x8000)
5301: *p = 0xffff; /* fill in our sign */
5302: ++p; /* bump pointer to our exponent word */
5303: r &= 0x7fff; /* strip the sign bit */
5304: if (r == 0) /* answer = 0 if high order DEC word = 0 */
5305: goto done;
5306:
5307:
5308: r >>= 7; /* shift exponent word down 7 bits */
5309: r += EXONE - 0201; /* subtract DEC exponent offset */
5310: /* add our e type exponent offset */
5311: *p++ = r; /* to form our exponent */
5312:
5313: r = *d++; /* now do the high order mantissa */
5314: r &= 0177; /* strip off the DEC exponent and sign bits */
5315: r |= 0200; /* the DEC understood high order mantissa bit */
5316: *p++ = r; /* put result in our high guard word */
5317:
5318: *p++ = *d++; /* fill in the rest of our mantissa */
5319: *p++ = *d++;
5320: *p = *d;
5321:
5322: eshdn8 (y); /* shift our mantissa down 8 bits */
5323: done:
5324: emovo (y, e);
5325: }
5326:
5327:
5328:
5329: /*
5330: ; convert e type to DEC double precision
5331: ; double d;
5332: ; EMUSHORT e[NE];
5333: ; etodec (e, &d);
5334: */
5335:
5336: void
5337: etodec (x, d)
5338: unsigned EMUSHORT *x, *d;
5339: {
5340: unsigned EMUSHORT xi[NI];
5341: EMULONG exp;
5342: int rndsav;
5343:
5344: emovi (x, xi);
5345: exp = (EMULONG) xi[E] - (EXONE - 0201); /* adjust exponent for offsets */
5346: /* round off to nearest or even */
5347: rndsav = rndprc;
5348: rndprc = 56;
5349: emdnorm (xi, 0, 0, exp, 64);
5350: rndprc = rndsav;
5351: todec (xi, d);
5352: }
5353:
5354: void
5355: todec (x, y)
5356: unsigned EMUSHORT *x, *y;
5357: {
5358: unsigned EMUSHORT i;
5359: unsigned EMUSHORT *p;
5360:
5361: p = x;
5362: *y = 0;
5363: if (*p++)
5364: *y = 0100000;
5365: i = *p++;
5366: if (i == 0)
5367: {
5368: *y++ = 0;
5369: *y++ = 0;
5370: *y++ = 0;
5371: *y++ = 0;
5372: return;
5373: }
5374: if (i > 0377)
5375: {
5376: *y++ |= 077777;
5377: *y++ = 0xffff;
5378: *y++ = 0xffff;
5379: *y++ = 0xffff;
5380: #ifdef ERANGE
5381: errno = ERANGE;
5382: #endif
5383: return;
5384: }
5385: i &= 0377;
5386: i <<= 7;
5387: eshup8 (x);
5388: x[M] &= 0177;
5389: i |= x[M];
5390: *y++ |= i;
5391: *y++ = x[M + 1];
5392: *y++ = x[M + 2];
5393: *y++ = x[M + 3];
5394: }
5395: #endif /* DEC */
5396:
5397: #ifdef IBM
5398: /* Here is etoibm
5399: *
5400: */
5401:
5402: /*
5403: ; convert IBM single/double precision to e type
5404: ; single/double d;
5405: ; EMUSHORT e[NE];
5406: ; enum machine_mode mode; SFmode/DFmode
5407: ; ibmtoe (&d, e, mode);
5408: */
5409: void
5410: ibmtoe (d, e, mode)
5411: unsigned EMUSHORT *d;
5412: unsigned EMUSHORT *e;
5413: enum machine_mode mode;
5414: {
5415: unsigned EMUSHORT y[NI];
5416: register unsigned EMUSHORT r, *p;
5417: int rndsav;
5418:
5419: ecleaz (y); /* start with a zero */
5420: p = y; /* point to our number */
5421: r = *d; /* get IBM exponent word */
5422: if (*d & (unsigned int) 0x8000)
5423: *p = 0xffff; /* fill in our sign */
5424: ++p; /* bump pointer to our exponent word */
5425: r &= 0x7f00; /* strip the sign bit */
5426: r >>= 6; /* shift exponent word down 6 bits */
5427: /* in fact shift by 8 right and 2 left */
5428: r += EXONE - (0x41 << 2); /* subtract IBM exponent offset */
5429: /* add our e type exponent offset */
5430: *p++ = r; /* to form our exponent */
5431:
5432: *p++ = *d++ & 0xff; /* now do the high order mantissa */
5433: /* strip off the IBM exponent and sign bits */
5434: if (mode != SFmode) /* there are only 2 words in SFmode */
5435: {
5436: *p++ = *d++; /* fill in the rest of our mantissa */
5437: *p++ = *d++;
5438: }
5439: *p = *d;
5440:
5441: if (y[M] == 0 && y[M+1] == 0 && y[M+2] == 0 && y[M+3] == 0)
5442: y[0] = y[E] = 0;
5443: else
5444: y[E] -= 5 + enormlz (y); /* now normalise the mantissa */
5445: /* handle change in RADIX */
5446: emovo (y, e);
5447: }
5448:
5449:
5450:
5451: /*
5452: ; convert e type to IBM single/double precision
5453: ; single/double d;
5454: ; EMUSHORT e[NE];
5455: ; enum machine_mode mode; SFmode/DFmode
5456: ; etoibm (e, &d, mode);
5457: */
5458:
5459: void
5460: etoibm (x, d, mode)
5461: unsigned EMUSHORT *x, *d;
5462: enum machine_mode mode;
5463: {
5464: unsigned EMUSHORT xi[NI];
5465: EMULONG exp;
5466: int rndsav;
5467:
5468: emovi (x, xi);
5469: exp = (EMULONG) xi[E] - (EXONE - (0x41 << 2)); /* adjust exponent for offsets */
5470: /* round off to nearest or even */
5471: rndsav = rndprc;
5472: rndprc = 56;
5473: emdnorm (xi, 0, 0, exp, 64);
5474: rndprc = rndsav;
5475: toibm (xi, d, mode);
5476: }
5477:
5478: void
5479: toibm (x, y, mode)
5480: unsigned EMUSHORT *x, *y;
5481: enum machine_mode mode;
5482: {
5483: unsigned EMUSHORT i;
5484: unsigned EMUSHORT *p;
5485: int r;
5486:
5487: p = x;
5488: *y = 0;
5489: if (*p++)
5490: *y = 0x8000;
5491: i = *p++;
5492: if (i == 0)
5493: {
5494: *y++ = 0;
5495: *y++ = 0;
5496: if (mode != SFmode)
5497: {
5498: *y++ = 0;
5499: *y++ = 0;
5500: }
5501: return;
5502: }
5503: r = i & 0x3;
5504: i >>= 2;
5505: if (i > 0x7f)
5506: {
5507: *y++ |= 0x7fff;
5508: *y++ = 0xffff;
5509: if (mode != SFmode)
5510: {
5511: *y++ = 0xffff;
5512: *y++ = 0xffff;
5513: }
5514: #ifdef ERANGE
5515: errno = ERANGE;
5516: #endif
5517: return;
5518: }
5519: i &= 0x7f;
5520: *y |= (i << 8);
5521: eshift (x, r + 5);
5522: *y++ |= x[M];
5523: *y++ = x[M + 1];
5524: if (mode != SFmode)
5525: {
5526: *y++ = x[M + 2];
5527: *y++ = x[M + 3];
5528: }
5529: }
5530: #endif /* IBM */
5531:
5532: /* Output a binary NaN bit pattern in the target machine's format. */
5533:
5534: /* If special NaN bit patterns are required, define them in tm.h
5535: as arrays of unsigned 16-bit shorts. Otherwise, use the default
5536: patterns here. */
5537: #ifdef TFMODE_NAN
5538: TFMODE_NAN;
5539: #else
5540: #ifdef MIEEE
5541: unsigned EMUSHORT TFnan[8] =
5542: {0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff};
5543: #endif
5544: #ifdef IBMPC
5545: unsigned EMUSHORT TFnan[8] = {0, 0, 0, 0, 0, 0, 0x8000, 0xffff};
5546: #endif
5547: #endif
5548:
5549: #ifdef XFMODE_NAN
5550: XFMODE_NAN;
5551: #else
5552: #ifdef MIEEE
5553: unsigned EMUSHORT XFnan[6] = {0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff};
5554: #endif
5555: #ifdef IBMPC
5556: unsigned EMUSHORT XFnan[6] = {0, 0, 0, 0xc000, 0xffff, 0};
5557: #endif
5558: #endif
5559:
5560: #ifdef DFMODE_NAN
5561: DFMODE_NAN;
5562: #else
5563: #ifdef MIEEE
5564: unsigned EMUSHORT DFnan[4] = {0x7fff, 0xffff, 0xffff, 0xffff};
5565: #endif
5566: #ifdef IBMPC
5567: unsigned EMUSHORT DFnan[4] = {0, 0, 0, 0xfff8};
5568: #endif
5569: #endif
5570:
5571: #ifdef SFMODE_NAN
5572: SFMODE_NAN;
5573: #else
5574: #ifdef MIEEE
5575: unsigned EMUSHORT SFnan[2] = {0x7fff, 0xffff};
5576: #endif
5577: #ifdef IBMPC
5578: unsigned EMUSHORT SFnan[2] = {0, 0xffc0};
5579: #endif
5580: #endif
5581:
5582:
5583: void
5584: make_nan (nan, mode)
5585: unsigned EMUSHORT *nan;
5586: enum machine_mode mode;
5587: {
5588: int i, n;
5589: unsigned EMUSHORT *p;
5590:
5591: n = 0;
5592: switch (mode)
5593: {
5594: /* Possibly the `reserved operand' patterns on a VAX can be
5595: used like NaN's, but probably not in the same way as IEEE. */
5596: #if !defined(DEC) && !defined(IBM)
5597: case TFmode:
5598: n = 8;
5599: p = TFnan;
5600: break;
5601: case XFmode:
5602: n = 6;
5603: p = XFnan;
5604: break;
5605: case DFmode:
5606: n = 4;
5607: p = DFnan;
5608: break;
5609: case SFmode:
5610: n = 2;
5611: p = SFnan;
5612: break;
5613: #endif
5614: default:
5615: abort ();
5616: }
5617: for (i=0; i < n; i++)
5618: *nan++ = *p++;
5619: }
5620:
5621: /* Convert an SFmode target `float' value to a REAL_VALUE_TYPE.
5622: This is the inverse of the function `etarsingle' invoked by
5623: REAL_VALUE_TO_TARGET_SINGLE. */
5624:
5625: REAL_VALUE_TYPE
5626: ereal_from_float (f)
5627: unsigned long f;
5628: {
5629: REAL_VALUE_TYPE r;
5630: unsigned EMUSHORT s[2];
5631: unsigned EMUSHORT e[NE];
5632:
5633: /* Convert 32 bit integer to array of 16 bit pieces in target machine order.
5634: This is the inverse operation to what the function `endian' does. */
5635: #if FLOAT_WORDS_BIG_ENDIAN
5636: s[0] = (unsigned EMUSHORT) (f >> 16);
5637: s[1] = (unsigned EMUSHORT) f;
5638: #else
5639: s[0] = (unsigned EMUSHORT) f;
5640: s[1] = (unsigned EMUSHORT) (f >> 16);
5641: #endif
5642: /* Convert and promote the target float to E-type. */
5643: e24toe (s, e);
5644: /* Output E-type to REAL_VALUE_TYPE. */
5645: PUT_REAL (e, &r);
5646: return r;
5647: }
5648:
5649:
5650: /* Convert a DFmode target `double' value to a REAL_VALUE_TYPE.
5651: This is the inverse of the function `etardouble' invoked by
5652: REAL_VALUE_TO_TARGET_DOUBLE.
5653:
5654: The DFmode is stored as an array of long ints
5655: with 32 bits of the value per each long. The first element
5656: of the input array holds the bits that would come first in the
5657: target computer's memory. */
5658:
5659: REAL_VALUE_TYPE
5660: ereal_from_double (d)
5661: unsigned long d[];
5662: {
5663: REAL_VALUE_TYPE r;
5664: unsigned EMUSHORT s[4];
5665: unsigned EMUSHORT e[NE];
5666:
5667: /* Convert array of 32 bit pieces to equivalent array of 16 bit pieces.
5668: This is the inverse of `endian'. */
5669: #if FLOAT_WORDS_BIG_ENDIAN
5670: s[0] = (unsigned EMUSHORT) (d[0] >> 16);
5671: s[1] = (unsigned EMUSHORT) d[0];
5672: s[2] = (unsigned EMUSHORT) (d[1] >> 16);
5673: s[3] = (unsigned EMUSHORT) d[1];
5674: #else
5675: s[0] = (unsigned EMUSHORT) d[0];
5676: s[1] = (unsigned EMUSHORT) (d[0] >> 16);
5677: s[2] = (unsigned EMUSHORT) d[1];
5678: s[3] = (unsigned EMUSHORT) (d[1] >> 16);
5679: #endif
5680: /* Convert target double to E-type. */
5681: e53toe (s, e);
5682: /* Output E-type to REAL_VALUE_TYPE. */
5683: PUT_REAL (e, &r);
5684: return r;
5685: }
5686:
5687:
5688: /* Convert target computer unsigned 64-bit integer to e-type.
5689: The endian-ness of DImode follows the convention for integers,
5690: so we use WORDS_BIG_ENDIAN here, not FLOAT_WORDS_BIG_ENDIAN. */
5691:
5692: void
5693: uditoe (di, e)
5694: unsigned EMUSHORT *di; /* Address of the 64-bit int. */
5695: unsigned EMUSHORT *e;
5696: {
5697: unsigned EMUSHORT yi[NI];
5698: int k;
5699:
5700: ecleaz (yi);
5701: #if WORDS_BIG_ENDIAN
5702: for (k = M; k < M + 4; k++)
5703: yi[k] = *di++;
5704: #else
5705: for (k = M + 3; k >= M; k--)
5706: yi[k] = *di++;
5707: #endif
5708: yi[E] = EXONE + 47; /* exponent if normalize shift count were 0 */
5709: if ((k = enormlz (yi)) > NBITS)/* normalize the significand */
5710: ecleaz (yi); /* it was zero */
5711: else
5712: yi[E] -= (unsigned EMUSHORT) k;/* subtract shift count from exponent */
5713: emovo (yi, e);
5714: }
5715:
5716: /* Convert target computer signed 64-bit integer to e-type. */
5717:
5718: void
5719: ditoe (di, e)
5720: unsigned EMUSHORT *di; /* Address of the 64-bit int. */
5721: unsigned EMUSHORT *e;
5722: {
5723: unsigned EMULONG acc;
5724: unsigned EMUSHORT yi[NI];
5725: unsigned EMUSHORT carry;
5726: int k, sign;
5727:
5728: ecleaz (yi);
5729: #if WORDS_BIG_ENDIAN
5730: for (k = M; k < M + 4; k++)
5731: yi[k] = *di++;
5732: #else
5733: for (k = M + 3; k >= M; k--)
5734: yi[k] = *di++;
5735: #endif
5736: /* Take absolute value */
5737: sign = 0;
5738: if (yi[M] & 0x8000)
5739: {
5740: sign = 1;
5741: carry = 0;
5742: for (k = M + 3; k >= M; k--)
5743: {
5744: acc = (unsigned EMULONG) (~yi[k] & 0xffff) + carry;
5745: yi[k] = acc;
5746: carry = 0;
5747: if (acc & 0x10000)
5748: carry = 1;
5749: }
5750: }
5751: yi[E] = EXONE + 47; /* exponent if normalize shift count were 0 */
5752: if ((k = enormlz (yi)) > NBITS)/* normalize the significand */
5753: ecleaz (yi); /* it was zero */
5754: else
5755: yi[E] -= (unsigned EMUSHORT) k;/* subtract shift count from exponent */
5756: emovo (yi, e);
5757: if (sign)
5758: eneg (e);
5759: }
5760:
5761:
5762: /* Convert e-type to unsigned 64-bit int. */
5763:
5764: void
5765: etoudi (x, i)
5766: unsigned EMUSHORT *x;
5767: unsigned EMUSHORT *i;
5768: {
5769: unsigned EMUSHORT xi[NI];
5770: int j, k;
5771:
5772: emovi (x, xi);
5773: if (xi[0])
5774: {
5775: xi[M] = 0;
5776: goto noshift;
5777: }
5778: k = (int) xi[E] - (EXONE - 1);
5779: if (k <= 0)
5780: {
5781: for (j = 0; j < 4; j++)
5782: *i++ = 0;
5783: return;
5784: }
5785: if (k > 64)
5786: {
5787: for (j = 0; j < 4; j++)
5788: *i++ = 0xffff;
5789: if (extra_warnings)
5790: warning ("overflow on truncation to integer");
5791: return;
5792: }
5793: if (k > 16)
5794: {
5795: /* Shift more than 16 bits: first shift up k-16 mod 16,
5796: then shift up by 16's. */
5797: j = k - ((k >> 4) << 4);
5798: if (j == 0)
5799: j = 16;
5800: eshift (xi, j);
5801: #if WORDS_BIG_ENDIAN
5802: *i++ = xi[M];
5803: #else
5804: i += 3;
5805: *i-- = xi[M];
5806: #endif
5807: k -= j;
5808: do
5809: {
5810: eshup6 (xi);
5811: #if WORDS_BIG_ENDIAN
5812: *i++ = xi[M];
5813: #else
5814: *i-- = xi[M];
5815: #endif
5816: }
5817: while ((k -= 16) > 0);
5818: }
5819: else
5820: {
5821: /* shift not more than 16 bits */
5822: eshift (xi, k);
5823:
5824: noshift:
5825:
5826: #if WORDS_BIG_ENDIAN
5827: i += 3;
5828: *i-- = xi[M];
5829: *i-- = 0;
5830: *i-- = 0;
5831: *i = 0;
5832: #else
5833: *i++ = xi[M];
5834: *i++ = 0;
5835: *i++ = 0;
5836: *i = 0;
5837: #endif
5838: }
5839: }
5840:
5841:
5842: /* Convert e-type to signed 64-bit int. */
5843:
5844: void
5845: etodi (x, i)
5846: unsigned EMUSHORT *x;
5847: unsigned EMUSHORT *i;
5848: {
5849: unsigned EMULONG acc;
5850: unsigned EMUSHORT xi[NI];
5851: unsigned EMUSHORT carry;
5852: unsigned EMUSHORT *isave;
5853: int j, k;
5854:
5855: emovi (x, xi);
5856: k = (int) xi[E] - (EXONE - 1);
5857: if (k <= 0)
5858: {
5859: for (j = 0; j < 4; j++)
5860: *i++ = 0;
5861: return;
5862: }
5863: if (k > 64)
5864: {
5865: for (j = 0; j < 4; j++)
5866: *i++ = 0xffff;
5867: if (extra_warnings)
5868: warning ("overflow on truncation to integer");
5869: return;
5870: }
5871: isave = i;
5872: if (k > 16)
5873: {
5874: /* Shift more than 16 bits: first shift up k-16 mod 16,
5875: then shift up by 16's. */
5876: j = k - ((k >> 4) << 4);
5877: if (j == 0)
5878: j = 16;
5879: eshift (xi, j);
5880: #if WORDS_BIG_ENDIAN
5881: *i++ = xi[M];
5882: #else
5883: i += 3;
5884: *i-- = xi[M];
5885: #endif
5886: k -= j;
5887: do
5888: {
5889: eshup6 (xi);
5890: #if WORDS_BIG_ENDIAN
5891: *i++ = xi[M];
5892: #else
5893: *i-- = xi[M];
5894: #endif
5895: }
5896: while ((k -= 16) > 0);
5897: }
5898: else
5899: {
5900: /* shift not more than 16 bits */
5901: eshift (xi, k);
5902:
5903: #if WORDS_BIG_ENDIAN
5904: i += 3;
5905: *i = xi[M];
5906: *i-- = 0;
5907: *i-- = 0;
5908: *i = 0;
5909: #else
5910: *i++ = xi[M];
5911: *i++ = 0;
5912: *i++ = 0;
5913: *i = 0;
5914: #endif
5915: }
5916: /* Negate if negative */
5917: if (xi[0])
5918: {
5919: carry = 0;
5920: #if WORDS_BIG_ENDIAN
5921: isave += 3;
5922: #endif
5923: for (k = 0; k < 4; k++)
5924: {
5925: acc = (unsigned EMULONG) (~(*isave) & 0xffff) + carry;
5926: #if WORDS_BIG_ENDIAN
5927: *isave-- = acc;
5928: #else
5929: *isave++ = acc;
5930: #endif
5931: carry = 0;
5932: if (acc & 0x10000)
5933: carry = 1;
5934: }
5935: }
5936: }
5937:
5938:
5939: /* Longhand square root routine. */
5940:
5941:
5942: static int esqinited = 0;
5943: static unsigned short sqrndbit[NI];
5944:
5945: void
5946: esqrt (x, y)
5947: unsigned EMUSHORT *x, *y;
5948: {
5949: unsigned EMUSHORT temp[NI], num[NI], sq[NI], xx[NI];
5950: EMULONG m, exp;
5951: int i, j, k, n, nlups;
5952:
5953: if (esqinited == 0)
5954: {
5955: ecleaz (sqrndbit);
5956: sqrndbit[NI - 2] = 1;
5957: esqinited = 1;
5958: }
5959: /* Check for arg <= 0 */
5960: i = ecmp (x, ezero);
5961: if (i <= 0)
5962: {
5963: #ifdef NANS
5964: if (i == -2)
5965: {
5966: enan (y);
5967: return;
5968: }
5969: #endif
5970: eclear (y);
5971: if (i < 0)
5972: mtherr ("esqrt", DOMAIN);
5973: return;
5974: }
5975:
5976: #ifdef INFINITY
5977: if (eisinf (x))
5978: {
5979: eclear (y);
5980: einfin (y);
5981: return;
5982: }
5983: #endif
5984: /* Bring in the arg and renormalize if it is denormal. */
5985: emovi (x, xx);
5986: m = (EMULONG) xx[1]; /* local long word exponent */
5987: if (m == 0)
5988: m -= enormlz (xx);
5989:
5990: /* Divide exponent by 2 */
5991: m -= 0x3ffe;
5992: exp = (unsigned short) ((m / 2) + 0x3ffe);
5993:
5994: /* Adjust if exponent odd */
5995: if ((m & 1) != 0)
5996: {
5997: if (m > 0)
5998: exp += 1;
5999: eshdn1 (xx);
6000: }
6001:
6002: ecleaz (sq);
6003: ecleaz (num);
6004: n = 8; /* get 8 bits of result per inner loop */
6005: nlups = rndprc;
6006: j = 0;
6007:
6008: while (nlups > 0)
6009: {
6010: /* bring in next word of arg */
6011: if (j < NE)
6012: num[NI - 1] = xx[j + 3];
6013: /* Do additional bit on last outer loop, for roundoff. */
6014: if (nlups <= 8)
6015: n = nlups + 1;
6016: for (i = 0; i < n; i++)
6017: {
6018: /* Next 2 bits of arg */
6019: eshup1 (num);
6020: eshup1 (num);
6021: /* Shift up answer */
6022: eshup1 (sq);
6023: /* Make trial divisor */
6024: for (k = 0; k < NI; k++)
6025: temp[k] = sq[k];
6026: eshup1 (temp);
6027: eaddm (sqrndbit, temp);
6028: /* Subtract and insert answer bit if it goes in */
6029: if (ecmpm (temp, num) <= 0)
6030: {
6031: esubm (temp, num);
6032: sq[NI - 2] |= 1;
6033: }
6034: }
6035: nlups -= n;
6036: j += 1;
6037: }
6038:
6039: /* Adjust for extra, roundoff loop done. */
6040: exp += (NBITS - 1) - rndprc;
6041:
6042: /* Sticky bit = 1 if the remainder is nonzero. */
6043: k = 0;
6044: for (i = 3; i < NI; i++)
6045: k |= (int) num[i];
6046:
6047: /* Renormalize and round off. */
6048: emdnorm (sq, k, 0, exp, 64);
6049: emovo (sq, y);
6050: }
6051:
6052: #endif /* EMU_NON_COMPILE not defined */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.