xref: /dflybsd-src/contrib/gcc-4.7/libiberty/floatformat.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1*e4b17023SJohn Marino /* IEEE floating point support routines, for GDB, the GNU Debugger.
2*e4b17023SJohn Marino    Copyright 1991, 1994, 1999, 2000, 2003, 2005, 2006, 2010
3*e4b17023SJohn Marino    Free Software Foundation, Inc.
4*e4b17023SJohn Marino 
5*e4b17023SJohn Marino This file is part of GDB.
6*e4b17023SJohn Marino 
7*e4b17023SJohn Marino This program is free software; you can redistribute it and/or modify
8*e4b17023SJohn Marino it under the terms of the GNU General Public License as published by
9*e4b17023SJohn Marino the Free Software Foundation; either version 2 of the License, or
10*e4b17023SJohn Marino (at your option) any later version.
11*e4b17023SJohn Marino 
12*e4b17023SJohn Marino This program is distributed in the hope that it will be useful,
13*e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
14*e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*e4b17023SJohn Marino GNU General Public License for more details.
16*e4b17023SJohn Marino 
17*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
18*e4b17023SJohn Marino along with this program; if not, write to the Free Software
19*e4b17023SJohn Marino Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
20*e4b17023SJohn Marino 
21*e4b17023SJohn Marino /* This is needed to pick up the NAN macro on some systems.  */
22*e4b17023SJohn Marino #define _GNU_SOURCE
23*e4b17023SJohn Marino 
24*e4b17023SJohn Marino #ifdef HAVE_CONFIG_H
25*e4b17023SJohn Marino #include "config.h"
26*e4b17023SJohn Marino #endif
27*e4b17023SJohn Marino 
28*e4b17023SJohn Marino #include <math.h>
29*e4b17023SJohn Marino 
30*e4b17023SJohn Marino #ifdef HAVE_STRING_H
31*e4b17023SJohn Marino #include <string.h>
32*e4b17023SJohn Marino #endif
33*e4b17023SJohn Marino 
34*e4b17023SJohn Marino /* On some platforms, <float.h> provides DBL_QNAN.  */
35*e4b17023SJohn Marino #ifdef STDC_HEADERS
36*e4b17023SJohn Marino #include <float.h>
37*e4b17023SJohn Marino #endif
38*e4b17023SJohn Marino 
39*e4b17023SJohn Marino #include "ansidecl.h"
40*e4b17023SJohn Marino #include "libiberty.h"
41*e4b17023SJohn Marino #include "floatformat.h"
42*e4b17023SJohn Marino 
43*e4b17023SJohn Marino #ifndef INFINITY
44*e4b17023SJohn Marino #ifdef HUGE_VAL
45*e4b17023SJohn Marino #define INFINITY HUGE_VAL
46*e4b17023SJohn Marino #else
47*e4b17023SJohn Marino #define INFINITY (1.0 / 0.0)
48*e4b17023SJohn Marino #endif
49*e4b17023SJohn Marino #endif
50*e4b17023SJohn Marino 
51*e4b17023SJohn Marino #ifndef NAN
52*e4b17023SJohn Marino #ifdef DBL_QNAN
53*e4b17023SJohn Marino #define NAN DBL_QNAN
54*e4b17023SJohn Marino #else
55*e4b17023SJohn Marino #define NAN (0.0 / 0.0)
56*e4b17023SJohn Marino #endif
57*e4b17023SJohn Marino #endif
58*e4b17023SJohn Marino 
59*e4b17023SJohn Marino static int mant_bits_set (const struct floatformat *, const unsigned char *);
60*e4b17023SJohn Marino static unsigned long get_field (const unsigned char *,
61*e4b17023SJohn Marino                                 enum floatformat_byteorders,
62*e4b17023SJohn Marino                                 unsigned int,
63*e4b17023SJohn Marino                                 unsigned int,
64*e4b17023SJohn Marino                                 unsigned int);
65*e4b17023SJohn Marino static int floatformat_always_valid (const struct floatformat *fmt,
66*e4b17023SJohn Marino                                      const void *from);
67*e4b17023SJohn Marino 
68*e4b17023SJohn Marino static int
floatformat_always_valid(const struct floatformat * fmt ATTRIBUTE_UNUSED,const void * from ATTRIBUTE_UNUSED)69*e4b17023SJohn Marino floatformat_always_valid (const struct floatformat *fmt ATTRIBUTE_UNUSED,
70*e4b17023SJohn Marino                           const void *from ATTRIBUTE_UNUSED)
71*e4b17023SJohn Marino {
72*e4b17023SJohn Marino   return 1;
73*e4b17023SJohn Marino }
74*e4b17023SJohn Marino 
75*e4b17023SJohn Marino /* The odds that CHAR_BIT will be anything but 8 are low enough that I'm not
76*e4b17023SJohn Marino    going to bother with trying to muck around with whether it is defined in
77*e4b17023SJohn Marino    a system header, what we do if not, etc.  */
78*e4b17023SJohn Marino #define FLOATFORMAT_CHAR_BIT 8
79*e4b17023SJohn Marino 
80*e4b17023SJohn Marino /* floatformats for IEEE half, single and double, big and little endian.  */
81*e4b17023SJohn Marino const struct floatformat floatformat_ieee_half_big =
82*e4b17023SJohn Marino {
83*e4b17023SJohn Marino   floatformat_big, 16, 0, 1, 5, 15, 31, 6, 10,
84*e4b17023SJohn Marino   floatformat_intbit_no,
85*e4b17023SJohn Marino   "floatformat_ieee_half_big",
86*e4b17023SJohn Marino   floatformat_always_valid,
87*e4b17023SJohn Marino   NULL
88*e4b17023SJohn Marino };
89*e4b17023SJohn Marino const struct floatformat floatformat_ieee_half_little =
90*e4b17023SJohn Marino {
91*e4b17023SJohn Marino   floatformat_little, 16, 0, 1, 5, 15, 31, 6, 10,
92*e4b17023SJohn Marino   floatformat_intbit_no,
93*e4b17023SJohn Marino   "floatformat_ieee_half_little",
94*e4b17023SJohn Marino   floatformat_always_valid,
95*e4b17023SJohn Marino   NULL
96*e4b17023SJohn Marino };
97*e4b17023SJohn Marino const struct floatformat floatformat_ieee_single_big =
98*e4b17023SJohn Marino {
99*e4b17023SJohn Marino   floatformat_big, 32, 0, 1, 8, 127, 255, 9, 23,
100*e4b17023SJohn Marino   floatformat_intbit_no,
101*e4b17023SJohn Marino   "floatformat_ieee_single_big",
102*e4b17023SJohn Marino   floatformat_always_valid,
103*e4b17023SJohn Marino   NULL
104*e4b17023SJohn Marino };
105*e4b17023SJohn Marino const struct floatformat floatformat_ieee_single_little =
106*e4b17023SJohn Marino {
107*e4b17023SJohn Marino   floatformat_little, 32, 0, 1, 8, 127, 255, 9, 23,
108*e4b17023SJohn Marino   floatformat_intbit_no,
109*e4b17023SJohn Marino   "floatformat_ieee_single_little",
110*e4b17023SJohn Marino   floatformat_always_valid,
111*e4b17023SJohn Marino   NULL
112*e4b17023SJohn Marino };
113*e4b17023SJohn Marino const struct floatformat floatformat_ieee_double_big =
114*e4b17023SJohn Marino {
115*e4b17023SJohn Marino   floatformat_big, 64, 0, 1, 11, 1023, 2047, 12, 52,
116*e4b17023SJohn Marino   floatformat_intbit_no,
117*e4b17023SJohn Marino   "floatformat_ieee_double_big",
118*e4b17023SJohn Marino   floatformat_always_valid,
119*e4b17023SJohn Marino   NULL
120*e4b17023SJohn Marino };
121*e4b17023SJohn Marino const struct floatformat floatformat_ieee_double_little =
122*e4b17023SJohn Marino {
123*e4b17023SJohn Marino   floatformat_little, 64, 0, 1, 11, 1023, 2047, 12, 52,
124*e4b17023SJohn Marino   floatformat_intbit_no,
125*e4b17023SJohn Marino   "floatformat_ieee_double_little",
126*e4b17023SJohn Marino   floatformat_always_valid,
127*e4b17023SJohn Marino   NULL
128*e4b17023SJohn Marino };
129*e4b17023SJohn Marino 
130*e4b17023SJohn Marino /* floatformat for IEEE double, little endian byte order, with big endian word
131*e4b17023SJohn Marino    ordering, as on the ARM.  */
132*e4b17023SJohn Marino 
133*e4b17023SJohn Marino const struct floatformat floatformat_ieee_double_littlebyte_bigword =
134*e4b17023SJohn Marino {
135*e4b17023SJohn Marino   floatformat_littlebyte_bigword, 64, 0, 1, 11, 1023, 2047, 12, 52,
136*e4b17023SJohn Marino   floatformat_intbit_no,
137*e4b17023SJohn Marino   "floatformat_ieee_double_littlebyte_bigword",
138*e4b17023SJohn Marino   floatformat_always_valid,
139*e4b17023SJohn Marino   NULL
140*e4b17023SJohn Marino };
141*e4b17023SJohn Marino 
142*e4b17023SJohn Marino /* floatformat for VAX.  Not quite IEEE, but close enough.  */
143*e4b17023SJohn Marino 
144*e4b17023SJohn Marino const struct floatformat floatformat_vax_f =
145*e4b17023SJohn Marino {
146*e4b17023SJohn Marino   floatformat_vax, 32, 0, 1, 8, 129, 0, 9, 23,
147*e4b17023SJohn Marino   floatformat_intbit_no,
148*e4b17023SJohn Marino   "floatformat_vax_f",
149*e4b17023SJohn Marino   floatformat_always_valid,
150*e4b17023SJohn Marino   NULL
151*e4b17023SJohn Marino };
152*e4b17023SJohn Marino const struct floatformat floatformat_vax_d =
153*e4b17023SJohn Marino {
154*e4b17023SJohn Marino   floatformat_vax, 64, 0, 1, 8, 129, 0, 9, 55,
155*e4b17023SJohn Marino   floatformat_intbit_no,
156*e4b17023SJohn Marino   "floatformat_vax_d",
157*e4b17023SJohn Marino   floatformat_always_valid,
158*e4b17023SJohn Marino   NULL
159*e4b17023SJohn Marino };
160*e4b17023SJohn Marino const struct floatformat floatformat_vax_g =
161*e4b17023SJohn Marino {
162*e4b17023SJohn Marino   floatformat_vax, 64, 0, 1, 11, 1025, 0, 12, 52,
163*e4b17023SJohn Marino   floatformat_intbit_no,
164*e4b17023SJohn Marino   "floatformat_vax_g",
165*e4b17023SJohn Marino   floatformat_always_valid,
166*e4b17023SJohn Marino   NULL
167*e4b17023SJohn Marino };
168*e4b17023SJohn Marino 
169*e4b17023SJohn Marino static int floatformat_i387_ext_is_valid (const struct floatformat *fmt,
170*e4b17023SJohn Marino 					  const void *from);
171*e4b17023SJohn Marino 
172*e4b17023SJohn Marino static int
floatformat_i387_ext_is_valid(const struct floatformat * fmt,const void * from)173*e4b17023SJohn Marino floatformat_i387_ext_is_valid (const struct floatformat *fmt, const void *from)
174*e4b17023SJohn Marino {
175*e4b17023SJohn Marino   /* In the i387 double-extended format, if the exponent is all ones,
176*e4b17023SJohn Marino      then the integer bit must be set.  If the exponent is neither 0
177*e4b17023SJohn Marino      nor ~0, the intbit must also be set.  Only if the exponent is
178*e4b17023SJohn Marino      zero can it be zero, and then it must be zero.  */
179*e4b17023SJohn Marino   unsigned long exponent, int_bit;
180*e4b17023SJohn Marino   const unsigned char *ufrom = (const unsigned char *) from;
181*e4b17023SJohn Marino 
182*e4b17023SJohn Marino   exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
183*e4b17023SJohn Marino 			fmt->exp_start, fmt->exp_len);
184*e4b17023SJohn Marino   int_bit = get_field (ufrom, fmt->byteorder, fmt->totalsize,
185*e4b17023SJohn Marino 		       fmt->man_start, 1);
186*e4b17023SJohn Marino 
187*e4b17023SJohn Marino   if ((exponent == 0) != (int_bit == 0))
188*e4b17023SJohn Marino     return 0;
189*e4b17023SJohn Marino   else
190*e4b17023SJohn Marino     return 1;
191*e4b17023SJohn Marino }
192*e4b17023SJohn Marino 
193*e4b17023SJohn Marino const struct floatformat floatformat_i387_ext =
194*e4b17023SJohn Marino {
195*e4b17023SJohn Marino   floatformat_little, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64,
196*e4b17023SJohn Marino   floatformat_intbit_yes,
197*e4b17023SJohn Marino   "floatformat_i387_ext",
198*e4b17023SJohn Marino   floatformat_i387_ext_is_valid,
199*e4b17023SJohn Marino   NULL
200*e4b17023SJohn Marino };
201*e4b17023SJohn Marino const struct floatformat floatformat_m68881_ext =
202*e4b17023SJohn Marino {
203*e4b17023SJohn Marino   /* Note that the bits from 16 to 31 are unused.  */
204*e4b17023SJohn Marino   floatformat_big, 96, 0, 1, 15, 0x3fff, 0x7fff, 32, 64,
205*e4b17023SJohn Marino   floatformat_intbit_yes,
206*e4b17023SJohn Marino   "floatformat_m68881_ext",
207*e4b17023SJohn Marino   floatformat_always_valid,
208*e4b17023SJohn Marino   NULL
209*e4b17023SJohn Marino };
210*e4b17023SJohn Marino const struct floatformat floatformat_i960_ext =
211*e4b17023SJohn Marino {
212*e4b17023SJohn Marino   /* Note that the bits from 0 to 15 are unused.  */
213*e4b17023SJohn Marino   floatformat_little, 96, 16, 17, 15, 0x3fff, 0x7fff, 32, 64,
214*e4b17023SJohn Marino   floatformat_intbit_yes,
215*e4b17023SJohn Marino   "floatformat_i960_ext",
216*e4b17023SJohn Marino   floatformat_always_valid,
217*e4b17023SJohn Marino   NULL
218*e4b17023SJohn Marino };
219*e4b17023SJohn Marino const struct floatformat floatformat_m88110_ext =
220*e4b17023SJohn Marino {
221*e4b17023SJohn Marino   floatformat_big, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64,
222*e4b17023SJohn Marino   floatformat_intbit_yes,
223*e4b17023SJohn Marino   "floatformat_m88110_ext",
224*e4b17023SJohn Marino   floatformat_always_valid,
225*e4b17023SJohn Marino   NULL
226*e4b17023SJohn Marino };
227*e4b17023SJohn Marino const struct floatformat floatformat_m88110_harris_ext =
228*e4b17023SJohn Marino {
229*e4b17023SJohn Marino   /* Harris uses raw format 128 bytes long, but the number is just an ieee
230*e4b17023SJohn Marino      double, and the last 64 bits are wasted. */
231*e4b17023SJohn Marino   floatformat_big,128, 0, 1, 11,  0x3ff,  0x7ff, 12, 52,
232*e4b17023SJohn Marino   floatformat_intbit_no,
233*e4b17023SJohn Marino   "floatformat_m88110_ext_harris",
234*e4b17023SJohn Marino   floatformat_always_valid,
235*e4b17023SJohn Marino   NULL
236*e4b17023SJohn Marino };
237*e4b17023SJohn Marino const struct floatformat floatformat_arm_ext_big =
238*e4b17023SJohn Marino {
239*e4b17023SJohn Marino   /* Bits 1 to 16 are unused.  */
240*e4b17023SJohn Marino   floatformat_big, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64,
241*e4b17023SJohn Marino   floatformat_intbit_yes,
242*e4b17023SJohn Marino   "floatformat_arm_ext_big",
243*e4b17023SJohn Marino   floatformat_always_valid,
244*e4b17023SJohn Marino   NULL
245*e4b17023SJohn Marino };
246*e4b17023SJohn Marino const struct floatformat floatformat_arm_ext_littlebyte_bigword =
247*e4b17023SJohn Marino {
248*e4b17023SJohn Marino   /* Bits 1 to 16 are unused.  */
249*e4b17023SJohn Marino   floatformat_littlebyte_bigword, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64,
250*e4b17023SJohn Marino   floatformat_intbit_yes,
251*e4b17023SJohn Marino   "floatformat_arm_ext_littlebyte_bigword",
252*e4b17023SJohn Marino   floatformat_always_valid,
253*e4b17023SJohn Marino   NULL
254*e4b17023SJohn Marino };
255*e4b17023SJohn Marino const struct floatformat floatformat_ia64_spill_big =
256*e4b17023SJohn Marino {
257*e4b17023SJohn Marino   floatformat_big, 128, 0, 1, 17, 65535, 0x1ffff, 18, 64,
258*e4b17023SJohn Marino   floatformat_intbit_yes,
259*e4b17023SJohn Marino   "floatformat_ia64_spill_big",
260*e4b17023SJohn Marino   floatformat_always_valid,
261*e4b17023SJohn Marino   NULL
262*e4b17023SJohn Marino };
263*e4b17023SJohn Marino const struct floatformat floatformat_ia64_spill_little =
264*e4b17023SJohn Marino {
265*e4b17023SJohn Marino   floatformat_little, 128, 0, 1, 17, 65535, 0x1ffff, 18, 64,
266*e4b17023SJohn Marino   floatformat_intbit_yes,
267*e4b17023SJohn Marino   "floatformat_ia64_spill_little",
268*e4b17023SJohn Marino   floatformat_always_valid,
269*e4b17023SJohn Marino   NULL
270*e4b17023SJohn Marino };
271*e4b17023SJohn Marino const struct floatformat floatformat_ia64_quad_big =
272*e4b17023SJohn Marino {
273*e4b17023SJohn Marino   floatformat_big, 128, 0, 1, 15, 16383, 0x7fff, 16, 112,
274*e4b17023SJohn Marino   floatformat_intbit_no,
275*e4b17023SJohn Marino   "floatformat_ia64_quad_big",
276*e4b17023SJohn Marino   floatformat_always_valid,
277*e4b17023SJohn Marino   NULL
278*e4b17023SJohn Marino };
279*e4b17023SJohn Marino const struct floatformat floatformat_ia64_quad_little =
280*e4b17023SJohn Marino {
281*e4b17023SJohn Marino   floatformat_little, 128, 0, 1, 15, 16383, 0x7fff, 16, 112,
282*e4b17023SJohn Marino   floatformat_intbit_no,
283*e4b17023SJohn Marino   "floatformat_ia64_quad_little",
284*e4b17023SJohn Marino   floatformat_always_valid,
285*e4b17023SJohn Marino   NULL
286*e4b17023SJohn Marino };
287*e4b17023SJohn Marino 
288*e4b17023SJohn Marino static int
floatformat_ibm_long_double_is_valid(const struct floatformat * fmt,const void * from)289*e4b17023SJohn Marino floatformat_ibm_long_double_is_valid (const struct floatformat *fmt,
290*e4b17023SJohn Marino 				      const void *from)
291*e4b17023SJohn Marino {
292*e4b17023SJohn Marino   const unsigned char *ufrom = (const unsigned char *) from;
293*e4b17023SJohn Marino   const struct floatformat *hfmt = fmt->split_half;
294*e4b17023SJohn Marino   long top_exp, bot_exp;
295*e4b17023SJohn Marino   int top_nan = 0;
296*e4b17023SJohn Marino 
297*e4b17023SJohn Marino   top_exp = get_field (ufrom, hfmt->byteorder, hfmt->totalsize,
298*e4b17023SJohn Marino 		       hfmt->exp_start, hfmt->exp_len);
299*e4b17023SJohn Marino   bot_exp = get_field (ufrom + 8, hfmt->byteorder, hfmt->totalsize,
300*e4b17023SJohn Marino 		       hfmt->exp_start, hfmt->exp_len);
301*e4b17023SJohn Marino 
302*e4b17023SJohn Marino   if ((unsigned long) top_exp == hfmt->exp_nan)
303*e4b17023SJohn Marino     top_nan = mant_bits_set (hfmt, ufrom);
304*e4b17023SJohn Marino 
305*e4b17023SJohn Marino   /* A NaN is valid with any low part.  */
306*e4b17023SJohn Marino   if (top_nan)
307*e4b17023SJohn Marino     return 1;
308*e4b17023SJohn Marino 
309*e4b17023SJohn Marino   /* An infinity, zero or denormal requires low part 0 (positive or
310*e4b17023SJohn Marino      negative).  */
311*e4b17023SJohn Marino   if ((unsigned long) top_exp == hfmt->exp_nan || top_exp == 0)
312*e4b17023SJohn Marino     {
313*e4b17023SJohn Marino       if (bot_exp != 0)
314*e4b17023SJohn Marino 	return 0;
315*e4b17023SJohn Marino 
316*e4b17023SJohn Marino       return !mant_bits_set (hfmt, ufrom + 8);
317*e4b17023SJohn Marino     }
318*e4b17023SJohn Marino 
319*e4b17023SJohn Marino   /* The top part is now a finite normal value.  The long double value
320*e4b17023SJohn Marino      is the sum of the two parts, and the top part must equal the
321*e4b17023SJohn Marino      result of rounding the long double value to nearest double.  Thus
322*e4b17023SJohn Marino      the bottom part must be <= 0.5ulp of the top part in absolute
323*e4b17023SJohn Marino      value, and if it is < 0.5ulp then the long double is definitely
324*e4b17023SJohn Marino      valid.  */
325*e4b17023SJohn Marino   if (bot_exp < top_exp - 53)
326*e4b17023SJohn Marino     return 1;
327*e4b17023SJohn Marino   if (bot_exp > top_exp - 53 && bot_exp != 0)
328*e4b17023SJohn Marino     return 0;
329*e4b17023SJohn Marino   if (bot_exp == 0)
330*e4b17023SJohn Marino     {
331*e4b17023SJohn Marino       /* The bottom part is 0 or denormal.  Determine which, and if
332*e4b17023SJohn Marino 	 denormal the first two set bits.  */
333*e4b17023SJohn Marino       int first_bit = -1, second_bit = -1, cur_bit;
334*e4b17023SJohn Marino       for (cur_bit = 0; (unsigned int) cur_bit < hfmt->man_len; cur_bit++)
335*e4b17023SJohn Marino 	if (get_field (ufrom + 8, hfmt->byteorder, hfmt->totalsize,
336*e4b17023SJohn Marino 		       hfmt->man_start + cur_bit, 1))
337*e4b17023SJohn Marino 	  {
338*e4b17023SJohn Marino 	    if (first_bit == -1)
339*e4b17023SJohn Marino 	      first_bit = cur_bit;
340*e4b17023SJohn Marino 	    else
341*e4b17023SJohn Marino 	      {
342*e4b17023SJohn Marino 		second_bit = cur_bit;
343*e4b17023SJohn Marino 		break;
344*e4b17023SJohn Marino 	      }
345*e4b17023SJohn Marino 	  }
346*e4b17023SJohn Marino       /* Bottom part 0 is OK.  */
347*e4b17023SJohn Marino       if (first_bit == -1)
348*e4b17023SJohn Marino 	return 1;
349*e4b17023SJohn Marino       /* The real exponent of the bottom part is -first_bit.  */
350*e4b17023SJohn Marino       if (-first_bit < top_exp - 53)
351*e4b17023SJohn Marino 	return 1;
352*e4b17023SJohn Marino       if (-first_bit > top_exp - 53)
353*e4b17023SJohn Marino 	return 0;
354*e4b17023SJohn Marino       /* The bottom part is at least 0.5ulp of the top part.  For this
355*e4b17023SJohn Marino 	 to be OK, the bottom part must be exactly 0.5ulp (i.e. no
356*e4b17023SJohn Marino 	 more bits set) and the top part must have last bit 0.  */
357*e4b17023SJohn Marino       if (second_bit != -1)
358*e4b17023SJohn Marino 	return 0;
359*e4b17023SJohn Marino       return !get_field (ufrom, hfmt->byteorder, hfmt->totalsize,
360*e4b17023SJohn Marino 			 hfmt->man_start + hfmt->man_len - 1, 1);
361*e4b17023SJohn Marino     }
362*e4b17023SJohn Marino   else
363*e4b17023SJohn Marino     {
364*e4b17023SJohn Marino       /* The bottom part is at least 0.5ulp of the top part.  For this
365*e4b17023SJohn Marino 	 to be OK, it must be exactly 0.5ulp (i.e. no explicit bits
366*e4b17023SJohn Marino 	 set) and the top part must have last bit 0.  */
367*e4b17023SJohn Marino       if (get_field (ufrom, hfmt->byteorder, hfmt->totalsize,
368*e4b17023SJohn Marino 		     hfmt->man_start + hfmt->man_len - 1, 1))
369*e4b17023SJohn Marino 	return 0;
370*e4b17023SJohn Marino       return !mant_bits_set (hfmt, ufrom + 8);
371*e4b17023SJohn Marino     }
372*e4b17023SJohn Marino }
373*e4b17023SJohn Marino 
374*e4b17023SJohn Marino const struct floatformat floatformat_ibm_long_double =
375*e4b17023SJohn Marino {
376*e4b17023SJohn Marino   floatformat_big, 128, 0, 1, 11, 1023, 2047, 12, 52,
377*e4b17023SJohn Marino   floatformat_intbit_no,
378*e4b17023SJohn Marino   "floatformat_ibm_long_double",
379*e4b17023SJohn Marino   floatformat_ibm_long_double_is_valid,
380*e4b17023SJohn Marino   &floatformat_ieee_double_big
381*e4b17023SJohn Marino };
382*e4b17023SJohn Marino 
383*e4b17023SJohn Marino 
384*e4b17023SJohn Marino #ifndef min
385*e4b17023SJohn Marino #define min(a, b) ((a) < (b) ? (a) : (b))
386*e4b17023SJohn Marino #endif
387*e4b17023SJohn Marino 
388*e4b17023SJohn Marino /* Return 1 if any bits are explicitly set in the mantissa of UFROM,
389*e4b17023SJohn Marino    format FMT, 0 otherwise.  */
390*e4b17023SJohn Marino static int
mant_bits_set(const struct floatformat * fmt,const unsigned char * ufrom)391*e4b17023SJohn Marino mant_bits_set (const struct floatformat *fmt, const unsigned char *ufrom)
392*e4b17023SJohn Marino {
393*e4b17023SJohn Marino   unsigned int mant_bits, mant_off;
394*e4b17023SJohn Marino   int mant_bits_left;
395*e4b17023SJohn Marino 
396*e4b17023SJohn Marino   mant_off = fmt->man_start;
397*e4b17023SJohn Marino   mant_bits_left = fmt->man_len;
398*e4b17023SJohn Marino   while (mant_bits_left > 0)
399*e4b17023SJohn Marino     {
400*e4b17023SJohn Marino       mant_bits = min (mant_bits_left, 32);
401*e4b17023SJohn Marino 
402*e4b17023SJohn Marino       if (get_field (ufrom, fmt->byteorder, fmt->totalsize,
403*e4b17023SJohn Marino 		     mant_off, mant_bits) != 0)
404*e4b17023SJohn Marino 	return 1;
405*e4b17023SJohn Marino 
406*e4b17023SJohn Marino       mant_off += mant_bits;
407*e4b17023SJohn Marino       mant_bits_left -= mant_bits;
408*e4b17023SJohn Marino     }
409*e4b17023SJohn Marino   return 0;
410*e4b17023SJohn Marino }
411*e4b17023SJohn Marino 
412*e4b17023SJohn Marino /* Extract a field which starts at START and is LEN bits long.  DATA and
413*e4b17023SJohn Marino    TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER.  */
414*e4b17023SJohn Marino static unsigned long
get_field(const unsigned char * data,enum floatformat_byteorders order,unsigned int total_len,unsigned int start,unsigned int len)415*e4b17023SJohn Marino get_field (const unsigned char *data, enum floatformat_byteorders order,
416*e4b17023SJohn Marino            unsigned int total_len, unsigned int start, unsigned int len)
417*e4b17023SJohn Marino {
418*e4b17023SJohn Marino   unsigned long result = 0;
419*e4b17023SJohn Marino   unsigned int cur_byte;
420*e4b17023SJohn Marino   int lo_bit, hi_bit, cur_bitshift = 0;
421*e4b17023SJohn Marino   int nextbyte = (order == floatformat_little) ? 1 : -1;
422*e4b17023SJohn Marino 
423*e4b17023SJohn Marino   /* Start is in big-endian bit order!  Fix that first.  */
424*e4b17023SJohn Marino   start = total_len - (start + len);
425*e4b17023SJohn Marino 
426*e4b17023SJohn Marino   /* Start at the least significant part of the field.  */
427*e4b17023SJohn Marino   if (order == floatformat_little)
428*e4b17023SJohn Marino     cur_byte = start / FLOATFORMAT_CHAR_BIT;
429*e4b17023SJohn Marino   else
430*e4b17023SJohn Marino     cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT;
431*e4b17023SJohn Marino 
432*e4b17023SJohn Marino   lo_bit = start % FLOATFORMAT_CHAR_BIT;
433*e4b17023SJohn Marino   hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT);
434*e4b17023SJohn Marino 
435*e4b17023SJohn Marino   do
436*e4b17023SJohn Marino     {
437*e4b17023SJohn Marino       unsigned int shifted = *(data + cur_byte) >> lo_bit;
438*e4b17023SJohn Marino       unsigned int bits = hi_bit - lo_bit;
439*e4b17023SJohn Marino       unsigned int mask = (1 << bits) - 1;
440*e4b17023SJohn Marino       result |= (shifted & mask) << cur_bitshift;
441*e4b17023SJohn Marino       len -= bits;
442*e4b17023SJohn Marino       cur_bitshift += bits;
443*e4b17023SJohn Marino       cur_byte += nextbyte;
444*e4b17023SJohn Marino       lo_bit = 0;
445*e4b17023SJohn Marino       hi_bit = min (len, FLOATFORMAT_CHAR_BIT);
446*e4b17023SJohn Marino     }
447*e4b17023SJohn Marino   while (len != 0);
448*e4b17023SJohn Marino 
449*e4b17023SJohn Marino   return result;
450*e4b17023SJohn Marino }
451*e4b17023SJohn Marino 
452*e4b17023SJohn Marino /* Convert from FMT to a double.
453*e4b17023SJohn Marino    FROM is the address of the extended float.
454*e4b17023SJohn Marino    Store the double in *TO.  */
455*e4b17023SJohn Marino 
456*e4b17023SJohn Marino void
floatformat_to_double(const struct floatformat * fmt,const void * from,double * to)457*e4b17023SJohn Marino floatformat_to_double (const struct floatformat *fmt,
458*e4b17023SJohn Marino                        const void *from, double *to)
459*e4b17023SJohn Marino {
460*e4b17023SJohn Marino   const unsigned char *ufrom = (const unsigned char *) from;
461*e4b17023SJohn Marino   double dto;
462*e4b17023SJohn Marino   long exponent;
463*e4b17023SJohn Marino   unsigned long mant;
464*e4b17023SJohn Marino   unsigned int mant_bits, mant_off;
465*e4b17023SJohn Marino   int mant_bits_left;
466*e4b17023SJohn Marino   int special_exponent;		/* It's a NaN, denorm or zero */
467*e4b17023SJohn Marino 
468*e4b17023SJohn Marino   /* Split values are not handled specially, since the top half has
469*e4b17023SJohn Marino      the correctly rounded double value (in the only supported case of
470*e4b17023SJohn Marino      split values).  */
471*e4b17023SJohn Marino 
472*e4b17023SJohn Marino   exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
473*e4b17023SJohn Marino 			fmt->exp_start, fmt->exp_len);
474*e4b17023SJohn Marino 
475*e4b17023SJohn Marino   /* If the exponent indicates a NaN, we don't have information to
476*e4b17023SJohn Marino      decide what to do.  So we handle it like IEEE, except that we
477*e4b17023SJohn Marino      don't try to preserve the type of NaN.  FIXME.  */
478*e4b17023SJohn Marino   if ((unsigned long) exponent == fmt->exp_nan)
479*e4b17023SJohn Marino     {
480*e4b17023SJohn Marino       int nan = mant_bits_set (fmt, ufrom);
481*e4b17023SJohn Marino 
482*e4b17023SJohn Marino       /* On certain systems (such as GNU/Linux), the use of the
483*e4b17023SJohn Marino 	 INFINITY macro below may generate a warning that can not be
484*e4b17023SJohn Marino 	 silenced due to a bug in GCC (PR preprocessor/11931).  The
485*e4b17023SJohn Marino 	 preprocessor fails to recognise the __extension__ keyword in
486*e4b17023SJohn Marino 	 conjunction with the GNU/C99 extension for hexadecimal
487*e4b17023SJohn Marino 	 floating point constants and will issue a warning when
488*e4b17023SJohn Marino 	 compiling with -pedantic.  */
489*e4b17023SJohn Marino       if (nan)
490*e4b17023SJohn Marino 	dto = NAN;
491*e4b17023SJohn Marino       else
492*e4b17023SJohn Marino 	dto = INFINITY;
493*e4b17023SJohn Marino 
494*e4b17023SJohn Marino       if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
495*e4b17023SJohn Marino 	dto = -dto;
496*e4b17023SJohn Marino 
497*e4b17023SJohn Marino       *to = dto;
498*e4b17023SJohn Marino 
499*e4b17023SJohn Marino       return;
500*e4b17023SJohn Marino     }
501*e4b17023SJohn Marino 
502*e4b17023SJohn Marino   mant_bits_left = fmt->man_len;
503*e4b17023SJohn Marino   mant_off = fmt->man_start;
504*e4b17023SJohn Marino   dto = 0.0;
505*e4b17023SJohn Marino 
506*e4b17023SJohn Marino   special_exponent = exponent == 0 || (unsigned long) exponent == fmt->exp_nan;
507*e4b17023SJohn Marino 
508*e4b17023SJohn Marino   /* Don't bias zero's, denorms or NaNs.  */
509*e4b17023SJohn Marino   if (!special_exponent)
510*e4b17023SJohn Marino     exponent -= fmt->exp_bias;
511*e4b17023SJohn Marino 
512*e4b17023SJohn Marino   /* Build the result algebraically.  Might go infinite, underflow, etc;
513*e4b17023SJohn Marino      who cares. */
514*e4b17023SJohn Marino 
515*e4b17023SJohn Marino   /* If this format uses a hidden bit, explicitly add it in now.  Otherwise,
516*e4b17023SJohn Marino      increment the exponent by one to account for the integer bit.  */
517*e4b17023SJohn Marino 
518*e4b17023SJohn Marino   if (!special_exponent)
519*e4b17023SJohn Marino     {
520*e4b17023SJohn Marino       if (fmt->intbit == floatformat_intbit_no)
521*e4b17023SJohn Marino 	dto = ldexp (1.0, exponent);
522*e4b17023SJohn Marino       else
523*e4b17023SJohn Marino 	exponent++;
524*e4b17023SJohn Marino     }
525*e4b17023SJohn Marino 
526*e4b17023SJohn Marino   while (mant_bits_left > 0)
527*e4b17023SJohn Marino     {
528*e4b17023SJohn Marino       mant_bits = min (mant_bits_left, 32);
529*e4b17023SJohn Marino 
530*e4b17023SJohn Marino       mant = get_field (ufrom, fmt->byteorder, fmt->totalsize,
531*e4b17023SJohn Marino 			 mant_off, mant_bits);
532*e4b17023SJohn Marino 
533*e4b17023SJohn Marino       /* Handle denormalized numbers.  FIXME: What should we do for
534*e4b17023SJohn Marino 	 non-IEEE formats?  */
535*e4b17023SJohn Marino       if (special_exponent && exponent == 0 && mant != 0)
536*e4b17023SJohn Marino 	dto += ldexp ((double)mant,
537*e4b17023SJohn Marino 		      (- fmt->exp_bias
538*e4b17023SJohn Marino 		       - mant_bits
539*e4b17023SJohn Marino 		       - (mant_off - fmt->man_start)
540*e4b17023SJohn Marino 		       + 1));
541*e4b17023SJohn Marino       else
542*e4b17023SJohn Marino 	dto += ldexp ((double)mant, exponent - mant_bits);
543*e4b17023SJohn Marino       if (exponent != 0)
544*e4b17023SJohn Marino 	exponent -= mant_bits;
545*e4b17023SJohn Marino       mant_off += mant_bits;
546*e4b17023SJohn Marino       mant_bits_left -= mant_bits;
547*e4b17023SJohn Marino     }
548*e4b17023SJohn Marino 
549*e4b17023SJohn Marino   /* Negate it if negative.  */
550*e4b17023SJohn Marino   if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
551*e4b17023SJohn Marino     dto = -dto;
552*e4b17023SJohn Marino   *to = dto;
553*e4b17023SJohn Marino }
554*e4b17023SJohn Marino 
555*e4b17023SJohn Marino static void put_field (unsigned char *, enum floatformat_byteorders,
556*e4b17023SJohn Marino                        unsigned int,
557*e4b17023SJohn Marino                        unsigned int,
558*e4b17023SJohn Marino                        unsigned int,
559*e4b17023SJohn Marino                        unsigned long);
560*e4b17023SJohn Marino 
561*e4b17023SJohn Marino /* Set a field which starts at START and is LEN bits long.  DATA and
562*e4b17023SJohn Marino    TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER.  */
563*e4b17023SJohn Marino static void
put_field(unsigned char * data,enum floatformat_byteorders order,unsigned int total_len,unsigned int start,unsigned int len,unsigned long stuff_to_put)564*e4b17023SJohn Marino put_field (unsigned char *data, enum floatformat_byteorders order,
565*e4b17023SJohn Marino            unsigned int total_len, unsigned int start, unsigned int len,
566*e4b17023SJohn Marino            unsigned long stuff_to_put)
567*e4b17023SJohn Marino {
568*e4b17023SJohn Marino   unsigned int cur_byte;
569*e4b17023SJohn Marino   int lo_bit, hi_bit;
570*e4b17023SJohn Marino   int nextbyte = (order == floatformat_little) ? 1 : -1;
571*e4b17023SJohn Marino 
572*e4b17023SJohn Marino   /* Start is in big-endian bit order!  Fix that first.  */
573*e4b17023SJohn Marino   start = total_len - (start + len);
574*e4b17023SJohn Marino 
575*e4b17023SJohn Marino   /* Start at the least significant part of the field.  */
576*e4b17023SJohn Marino   if (order == floatformat_little)
577*e4b17023SJohn Marino     cur_byte = start / FLOATFORMAT_CHAR_BIT;
578*e4b17023SJohn Marino   else
579*e4b17023SJohn Marino     cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT;
580*e4b17023SJohn Marino 
581*e4b17023SJohn Marino   lo_bit = start % FLOATFORMAT_CHAR_BIT;
582*e4b17023SJohn Marino   hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT);
583*e4b17023SJohn Marino 
584*e4b17023SJohn Marino   do
585*e4b17023SJohn Marino     {
586*e4b17023SJohn Marino       unsigned char *byte_ptr = data + cur_byte;
587*e4b17023SJohn Marino       unsigned int bits = hi_bit - lo_bit;
588*e4b17023SJohn Marino       unsigned int mask = ((1 << bits) - 1) << lo_bit;
589*e4b17023SJohn Marino       *byte_ptr = (*byte_ptr & ~mask) | ((stuff_to_put << lo_bit) & mask);
590*e4b17023SJohn Marino       stuff_to_put >>= bits;
591*e4b17023SJohn Marino       len -= bits;
592*e4b17023SJohn Marino       cur_byte += nextbyte;
593*e4b17023SJohn Marino       lo_bit = 0;
594*e4b17023SJohn Marino       hi_bit = min (len, FLOATFORMAT_CHAR_BIT);
595*e4b17023SJohn Marino     }
596*e4b17023SJohn Marino   while (len != 0);
597*e4b17023SJohn Marino }
598*e4b17023SJohn Marino 
599*e4b17023SJohn Marino /* The converse: convert the double *FROM to an extended float
600*e4b17023SJohn Marino    and store where TO points.  Neither FROM nor TO have any alignment
601*e4b17023SJohn Marino    restrictions.  */
602*e4b17023SJohn Marino 
603*e4b17023SJohn Marino void
floatformat_from_double(const struct floatformat * fmt,const double * from,void * to)604*e4b17023SJohn Marino floatformat_from_double (const struct floatformat *fmt,
605*e4b17023SJohn Marino                          const double *from, void *to)
606*e4b17023SJohn Marino {
607*e4b17023SJohn Marino   double dfrom;
608*e4b17023SJohn Marino   int exponent;
609*e4b17023SJohn Marino   double mant;
610*e4b17023SJohn Marino   unsigned int mant_bits, mant_off;
611*e4b17023SJohn Marino   int mant_bits_left;
612*e4b17023SJohn Marino   unsigned char *uto = (unsigned char *) to;
613*e4b17023SJohn Marino 
614*e4b17023SJohn Marino   dfrom = *from;
615*e4b17023SJohn Marino   memset (uto, 0, fmt->totalsize / FLOATFORMAT_CHAR_BIT);
616*e4b17023SJohn Marino 
617*e4b17023SJohn Marino   /* Split values are not handled specially, since a bottom half of
618*e4b17023SJohn Marino      zero is correct for any value representable as double (in the
619*e4b17023SJohn Marino      only supported case of split values).  */
620*e4b17023SJohn Marino 
621*e4b17023SJohn Marino   /* If negative, set the sign bit.  */
622*e4b17023SJohn Marino   if (dfrom < 0)
623*e4b17023SJohn Marino     {
624*e4b17023SJohn Marino       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1);
625*e4b17023SJohn Marino       dfrom = -dfrom;
626*e4b17023SJohn Marino     }
627*e4b17023SJohn Marino 
628*e4b17023SJohn Marino   if (dfrom == 0)
629*e4b17023SJohn Marino     {
630*e4b17023SJohn Marino       /* 0.0.  */
631*e4b17023SJohn Marino       return;
632*e4b17023SJohn Marino     }
633*e4b17023SJohn Marino 
634*e4b17023SJohn Marino   if (dfrom != dfrom)
635*e4b17023SJohn Marino     {
636*e4b17023SJohn Marino       /* NaN.  */
637*e4b17023SJohn Marino       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
638*e4b17023SJohn Marino 		 fmt->exp_len, fmt->exp_nan);
639*e4b17023SJohn Marino       /* Be sure it's not infinity, but NaN value is irrelevant.  */
640*e4b17023SJohn Marino       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
641*e4b17023SJohn Marino 		 32, 1);
642*e4b17023SJohn Marino       return;
643*e4b17023SJohn Marino     }
644*e4b17023SJohn Marino 
645*e4b17023SJohn Marino   if (dfrom + dfrom == dfrom)
646*e4b17023SJohn Marino     {
647*e4b17023SJohn Marino       /* This can only happen for an infinite value (or zero, which we
648*e4b17023SJohn Marino 	 already handled above).  */
649*e4b17023SJohn Marino       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
650*e4b17023SJohn Marino 		 fmt->exp_len, fmt->exp_nan);
651*e4b17023SJohn Marino       return;
652*e4b17023SJohn Marino     }
653*e4b17023SJohn Marino 
654*e4b17023SJohn Marino   mant = frexp (dfrom, &exponent);
655*e4b17023SJohn Marino   if (exponent + fmt->exp_bias - 1 > 0)
656*e4b17023SJohn Marino     put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
657*e4b17023SJohn Marino 	       fmt->exp_len, exponent + fmt->exp_bias - 1);
658*e4b17023SJohn Marino   else
659*e4b17023SJohn Marino     {
660*e4b17023SJohn Marino       /* Handle a denormalized number.  FIXME: What should we do for
661*e4b17023SJohn Marino 	 non-IEEE formats?  */
662*e4b17023SJohn Marino       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
663*e4b17023SJohn Marino 		 fmt->exp_len, 0);
664*e4b17023SJohn Marino       mant = ldexp (mant, exponent + fmt->exp_bias - 1);
665*e4b17023SJohn Marino     }
666*e4b17023SJohn Marino 
667*e4b17023SJohn Marino   mant_bits_left = fmt->man_len;
668*e4b17023SJohn Marino   mant_off = fmt->man_start;
669*e4b17023SJohn Marino   while (mant_bits_left > 0)
670*e4b17023SJohn Marino     {
671*e4b17023SJohn Marino       unsigned long mant_long;
672*e4b17023SJohn Marino       mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;
673*e4b17023SJohn Marino 
674*e4b17023SJohn Marino       mant *= 4294967296.0;
675*e4b17023SJohn Marino       mant_long = (unsigned long)mant;
676*e4b17023SJohn Marino       mant -= mant_long;
677*e4b17023SJohn Marino 
678*e4b17023SJohn Marino       /* If the integer bit is implicit, and we are not creating a
679*e4b17023SJohn Marino 	 denormalized number, then we need to discard it.  */
680*e4b17023SJohn Marino       if ((unsigned int) mant_bits_left == fmt->man_len
681*e4b17023SJohn Marino 	  && fmt->intbit == floatformat_intbit_no
682*e4b17023SJohn Marino 	  && exponent + fmt->exp_bias - 1 > 0)
683*e4b17023SJohn Marino 	{
684*e4b17023SJohn Marino 	  mant_long &= 0x7fffffff;
685*e4b17023SJohn Marino 	  mant_bits -= 1;
686*e4b17023SJohn Marino 	}
687*e4b17023SJohn Marino       else if (mant_bits < 32)
688*e4b17023SJohn Marino 	{
689*e4b17023SJohn Marino 	  /* The bits we want are in the most significant MANT_BITS bits of
690*e4b17023SJohn Marino 	     mant_long.  Move them to the least significant.  */
691*e4b17023SJohn Marino 	  mant_long >>= 32 - mant_bits;
692*e4b17023SJohn Marino 	}
693*e4b17023SJohn Marino 
694*e4b17023SJohn Marino       put_field (uto, fmt->byteorder, fmt->totalsize,
695*e4b17023SJohn Marino 		 mant_off, mant_bits, mant_long);
696*e4b17023SJohn Marino       mant_off += mant_bits;
697*e4b17023SJohn Marino       mant_bits_left -= mant_bits;
698*e4b17023SJohn Marino     }
699*e4b17023SJohn Marino }
700*e4b17023SJohn Marino 
701*e4b17023SJohn Marino /* Return non-zero iff the data at FROM is a valid number in format FMT.  */
702*e4b17023SJohn Marino 
703*e4b17023SJohn Marino int
floatformat_is_valid(const struct floatformat * fmt,const void * from)704*e4b17023SJohn Marino floatformat_is_valid (const struct floatformat *fmt, const void *from)
705*e4b17023SJohn Marino {
706*e4b17023SJohn Marino   return fmt->is_valid (fmt, from);
707*e4b17023SJohn Marino }
708*e4b17023SJohn Marino 
709*e4b17023SJohn Marino 
710*e4b17023SJohn Marino #ifdef IEEE_DEBUG
711*e4b17023SJohn Marino 
712*e4b17023SJohn Marino #include <stdio.h>
713*e4b17023SJohn Marino 
714*e4b17023SJohn Marino /* This is to be run on a host which uses IEEE floating point.  */
715*e4b17023SJohn Marino 
716*e4b17023SJohn Marino void
ieee_test(double n)717*e4b17023SJohn Marino ieee_test (double n)
718*e4b17023SJohn Marino {
719*e4b17023SJohn Marino   double result;
720*e4b17023SJohn Marino 
721*e4b17023SJohn Marino   floatformat_to_double (&floatformat_ieee_double_little, &n, &result);
722*e4b17023SJohn Marino   if ((n != result && (! isnan (n) || ! isnan (result)))
723*e4b17023SJohn Marino       || (n < 0 && result >= 0)
724*e4b17023SJohn Marino       || (n >= 0 && result < 0))
725*e4b17023SJohn Marino     printf ("Differ(to): %.20g -> %.20g\n", n, result);
726*e4b17023SJohn Marino 
727*e4b17023SJohn Marino   floatformat_from_double (&floatformat_ieee_double_little, &n, &result);
728*e4b17023SJohn Marino   if ((n != result && (! isnan (n) || ! isnan (result)))
729*e4b17023SJohn Marino       || (n < 0 && result >= 0)
730*e4b17023SJohn Marino       || (n >= 0 && result < 0))
731*e4b17023SJohn Marino     printf ("Differ(from): %.20g -> %.20g\n", n, result);
732*e4b17023SJohn Marino 
733*e4b17023SJohn Marino #if 0
734*e4b17023SJohn Marino   {
735*e4b17023SJohn Marino     char exten[16];
736*e4b17023SJohn Marino 
737*e4b17023SJohn Marino     floatformat_from_double (&floatformat_m68881_ext, &n, exten);
738*e4b17023SJohn Marino     floatformat_to_double (&floatformat_m68881_ext, exten, &result);
739*e4b17023SJohn Marino     if (n != result)
740*e4b17023SJohn Marino       printf ("Differ(to+from): %.20g -> %.20g\n", n, result);
741*e4b17023SJohn Marino   }
742*e4b17023SJohn Marino #endif
743*e4b17023SJohn Marino 
744*e4b17023SJohn Marino #if IEEE_DEBUG > 1
745*e4b17023SJohn Marino   /* This is to be run on a host which uses 68881 format.  */
746*e4b17023SJohn Marino   {
747*e4b17023SJohn Marino     long double ex = *(long double *)exten;
748*e4b17023SJohn Marino     if (ex != n)
749*e4b17023SJohn Marino       printf ("Differ(from vs. extended): %.20g\n", n);
750*e4b17023SJohn Marino   }
751*e4b17023SJohn Marino #endif
752*e4b17023SJohn Marino }
753*e4b17023SJohn Marino 
754*e4b17023SJohn Marino int
main(void)755*e4b17023SJohn Marino main (void)
756*e4b17023SJohn Marino {
757*e4b17023SJohn Marino   ieee_test (0.0);
758*e4b17023SJohn Marino   ieee_test (0.5);
759*e4b17023SJohn Marino   ieee_test (256.0);
760*e4b17023SJohn Marino   ieee_test (0.12345);
761*e4b17023SJohn Marino   ieee_test (234235.78907234);
762*e4b17023SJohn Marino   ieee_test (-512.0);
763*e4b17023SJohn Marino   ieee_test (-0.004321);
764*e4b17023SJohn Marino   ieee_test (1.2E-70);
765*e4b17023SJohn Marino   ieee_test (1.2E-316);
766*e4b17023SJohn Marino   ieee_test (4.9406564584124654E-324);
767*e4b17023SJohn Marino   ieee_test (- 4.9406564584124654E-324);
768*e4b17023SJohn Marino   ieee_test (- 0.0);
769*e4b17023SJohn Marino   ieee_test (- INFINITY);
770*e4b17023SJohn Marino   ieee_test (- NAN);
771*e4b17023SJohn Marino   ieee_test (INFINITY);
772*e4b17023SJohn Marino   ieee_test (NAN);
773*e4b17023SJohn Marino   return 0;
774*e4b17023SJohn Marino }
775*e4b17023SJohn Marino #endif
776