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