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