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