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