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