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