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