aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/old/convert_numeric.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/old/convert_numeric.c')
-rw-r--r--src/plugins/old/convert_numeric.c423
1 files changed, 211 insertions, 212 deletions
diff --git a/src/plugins/old/convert_numeric.c b/src/plugins/old/convert_numeric.c
index b345014..35bd65a 100644
--- a/src/plugins/old/convert_numeric.c
+++ b/src/plugins/old/convert_numeric.c
@@ -61,45 +61,44 @@ static unsigned long get_field (const unsigned char *,
61 unsigned int, 61 unsigned int,
62 unsigned int, 62 unsigned int,
63 unsigned int); 63 unsigned int);
64
64static int floatformat_always_valid (const struct EXTRACTOR_floatformat *fmt, 65static int floatformat_always_valid (const struct EXTRACTOR_floatformat *fmt,
65 const void *from); 66 const void *from);
66 67
67static int 68static int
68floatformat_always_valid (const struct EXTRACTOR_floatformat *fmt /*ATTRIBUTE_UNUSED*/, 69floatformat_always_valid (const struct
70 EXTRACTOR_floatformat *fmt /*ATTRIBUTE_UNUSED*/,
69 const void *from /*ATTRIBUTE_UNUSED*/) 71 const void *from /*ATTRIBUTE_UNUSED*/)
70{ 72{
71 return 1; 73 return 1;
72} 74}
73 75
76
74/* The odds that CHAR_BIT will be anything but 8 are low enough that I'm not 77/* The odds that CHAR_BIT will be anything but 8 are low enough that I'm not
75 going to bother with trying to muck around with whether it is defined in 78 going to bother with trying to muck around with whether it is defined in
76 a system header, what we do if not, etc. */ 79 a system header, what we do if not, etc. */
77#define FLOATFORMAT_CHAR_BIT 8 80#define FLOATFORMAT_CHAR_BIT 8
78 81
79/* floatformats for IEEE single and double, big and little endian. */ 82/* floatformats for IEEE single and double, big and little endian. */
80const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ieee_single_big = 83const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ieee_single_big = {
81{
82 floatformat_big, 32, 0, 1, 8, 127, 255, 9, 23, 84 floatformat_big, 32, 0, 1, 8, 127, 255, 9, 23,
83 floatformat_intbit_no, 85 floatformat_intbit_no,
84 "floatformat_ieee_single_big", 86 "floatformat_ieee_single_big",
85 floatformat_always_valid 87 floatformat_always_valid
86}; 88};
87const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ieee_single_little = 89const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ieee_single_little = {
88{
89 floatformat_little, 32, 0, 1, 8, 127, 255, 9, 23, 90 floatformat_little, 32, 0, 1, 8, 127, 255, 9, 23,
90 floatformat_intbit_no, 91 floatformat_intbit_no,
91 "floatformat_ieee_single_little", 92 "floatformat_ieee_single_little",
92 floatformat_always_valid 93 floatformat_always_valid
93}; 94};
94const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ieee_double_big = 95const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ieee_double_big = {
95{
96 floatformat_big, 64, 0, 1, 11, 1023, 2047, 12, 52, 96 floatformat_big, 64, 0, 1, 11, 1023, 2047, 12, 52,
97 floatformat_intbit_no, 97 floatformat_intbit_no,
98 "floatformat_ieee_double_big", 98 "floatformat_ieee_double_big",
99 floatformat_always_valid 99 floatformat_always_valid
100}; 100};
101const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ieee_double_little = 101const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ieee_double_little = {
102{
103 floatformat_little, 64, 0, 1, 11, 1023, 2047, 12, 52, 102 floatformat_little, 64, 0, 1, 11, 1023, 2047, 12, 52,
104 floatformat_intbit_no, 103 floatformat_intbit_no,
105 "floatformat_ieee_double_little", 104 "floatformat_ieee_double_little",
@@ -109,8 +108,8 @@ const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ieee_double_little =
109/* floatformat for IEEE double, little endian byte order, with big endian word 108/* floatformat for IEEE double, little endian byte order, with big endian word
110 ordering, as on the ARM. */ 109 ordering, as on the ARM. */
111 110
112const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ieee_double_littlebyte_bigword = 111const struct EXTRACTOR_floatformat
113{ 112 EXTRACTOR_floatformat_ieee_double_littlebyte_bigword = {
114 floatformat_littlebyte_bigword, 64, 0, 1, 11, 1023, 2047, 12, 52, 113 floatformat_littlebyte_bigword, 64, 0, 1, 11, 1023, 2047, 12, 52,
115 floatformat_intbit_no, 114 floatformat_intbit_no,
116 "floatformat_ieee_double_littlebyte_bigword", 115 "floatformat_ieee_double_littlebyte_bigword",
@@ -119,33 +118,32 @@ const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ieee_double_littlebyte_
119 118
120/* floatformat for VAX. Not quite IEEE, but close enough. */ 119/* floatformat for VAX. Not quite IEEE, but close enough. */
121 120
122const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_vax_f = 121const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_vax_f = {
123{
124 floatformat_vax, 32, 0, 1, 8, 129, 0, 9, 23, 122 floatformat_vax, 32, 0, 1, 8, 129, 0, 9, 23,
125 floatformat_intbit_no, 123 floatformat_intbit_no,
126 "floatformat_vax_f", 124 "floatformat_vax_f",
127 floatformat_always_valid 125 floatformat_always_valid
128}; 126};
129const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_vax_d = 127const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_vax_d = {
130{
131 floatformat_vax, 64, 0, 1, 8, 129, 0, 9, 55, 128 floatformat_vax, 64, 0, 1, 8, 129, 0, 9, 55,
132 floatformat_intbit_no, 129 floatformat_intbit_no,
133 "floatformat_vax_d", 130 "floatformat_vax_d",
134 floatformat_always_valid 131 floatformat_always_valid
135}; 132};
136const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_vax_g = 133const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_vax_g = {
137{
138 floatformat_vax, 64, 0, 1, 11, 1025, 0, 12, 52, 134 floatformat_vax, 64, 0, 1, 11, 1025, 0, 12, 52,
139 floatformat_intbit_no, 135 floatformat_intbit_no,
140 "floatformat_vax_g", 136 "floatformat_vax_g",
141 floatformat_always_valid 137 floatformat_always_valid
142}; 138};
143 139
144static int floatformat_i387_ext_is_valid (const struct EXTRACTOR_floatformat *fmt, 140static int floatformat_i387_ext_is_valid (const struct
145 const void *from); 141 EXTRACTOR_floatformat *fmt,
142 const void *from);
146 143
147static int 144static int
148floatformat_i387_ext_is_valid (const struct EXTRACTOR_floatformat *fmt, const void *from) 145floatformat_i387_ext_is_valid (const struct EXTRACTOR_floatformat *fmt, const
146 void *from)
149{ 147{
150 /* In the i387 double-extended format, if the exponent is all ones, 148 /* In the i387 double-extended format, if the exponent is all ones,
151 then the integer bit must be set. If the exponent is neither 0 149 then the integer bit must be set. If the exponent is neither 0
@@ -155,9 +153,9 @@ floatformat_i387_ext_is_valid (const struct EXTRACTOR_floatformat *fmt, const vo
155 const unsigned char *ufrom = (const unsigned char *) from; 153 const unsigned char *ufrom = (const unsigned char *) from;
156 154
157 exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize, 155 exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
158 fmt->exp_start, fmt->exp_len); 156 fmt->exp_start, fmt->exp_len);
159 int_bit = get_field (ufrom, fmt->byteorder, fmt->totalsize, 157 int_bit = get_field (ufrom, fmt->byteorder, fmt->totalsize,
160 fmt->man_start, 1); 158 fmt->man_start, 1);
161 159
162 if ((exponent == 0) != (int_bit == 0)) 160 if ((exponent == 0) != (int_bit == 0))
163 return 0; 161 return 0;
@@ -165,38 +163,34 @@ floatformat_i387_ext_is_valid (const struct EXTRACTOR_floatformat *fmt, const vo
165 return 1; 163 return 1;
166} 164}
167 165
168const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_i387_ext = 166
169{ 167const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_i387_ext = {
170 floatformat_little, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64, 168 floatformat_little, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64,
171 floatformat_intbit_yes, 169 floatformat_intbit_yes,
172 "floatformat_i387_ext", 170 "floatformat_i387_ext",
173 floatformat_i387_ext_is_valid 171 floatformat_i387_ext_is_valid
174}; 172};
175const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_m68881_ext = 173const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_m68881_ext = {
176{
177 /* Note that the bits from 16 to 31 are unused. */ 174 /* Note that the bits from 16 to 31 are unused. */
178 floatformat_big, 96, 0, 1, 15, 0x3fff, 0x7fff, 32, 64, 175 floatformat_big, 96, 0, 1, 15, 0x3fff, 0x7fff, 32, 64,
179 floatformat_intbit_yes, 176 floatformat_intbit_yes,
180 "floatformat_m68881_ext", 177 "floatformat_m68881_ext",
181 floatformat_always_valid 178 floatformat_always_valid
182}; 179};
183const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_i960_ext = 180const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_i960_ext = {
184{
185 /* Note that the bits from 0 to 15 are unused. */ 181 /* Note that the bits from 0 to 15 are unused. */
186 floatformat_little, 96, 16, 17, 15, 0x3fff, 0x7fff, 32, 64, 182 floatformat_little, 96, 16, 17, 15, 0x3fff, 0x7fff, 32, 64,
187 floatformat_intbit_yes, 183 floatformat_intbit_yes,
188 "floatformat_i960_ext", 184 "floatformat_i960_ext",
189 floatformat_always_valid 185 floatformat_always_valid
190}; 186};
191const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_m88110_ext = 187const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_m88110_ext = {
192{
193 floatformat_big, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64, 188 floatformat_big, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64,
194 floatformat_intbit_yes, 189 floatformat_intbit_yes,
195 "floatformat_m88110_ext", 190 "floatformat_m88110_ext",
196 floatformat_always_valid 191 floatformat_always_valid
197}; 192};
198const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_m88110_harris_ext = 193const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_m88110_harris_ext = {
199{
200 /* Harris uses raw format 128 bytes long, but the number is just an ieee 194 /* Harris uses raw format 128 bytes long, but the number is just an ieee
201 double, and the last 64 bits are wasted. */ 195 double, and the last 64 bits are wasted. */
202 floatformat_big,128, 0, 1, 11, 0x3ff, 0x7ff, 12, 52, 196 floatformat_big,128, 0, 1, 11, 0x3ff, 0x7ff, 12, 52,
@@ -204,45 +198,40 @@ const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_m88110_harris_ext =
204 "floatformat_m88110_ext_harris", 198 "floatformat_m88110_ext_harris",
205 floatformat_always_valid 199 floatformat_always_valid
206}; 200};
207const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_arm_ext_big = 201const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_arm_ext_big = {
208{
209 /* Bits 1 to 16 are unused. */ 202 /* Bits 1 to 16 are unused. */
210 floatformat_big, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64, 203 floatformat_big, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64,
211 floatformat_intbit_yes, 204 floatformat_intbit_yes,
212 "floatformat_arm_ext_big", 205 "floatformat_arm_ext_big",
213 floatformat_always_valid 206 floatformat_always_valid
214}; 207};
215const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_arm_ext_littlebyte_bigword = 208const struct EXTRACTOR_floatformat
216{ 209 EXTRACTOR_floatformat_arm_ext_littlebyte_bigword = {
217 /* Bits 1 to 16 are unused. */ 210 /* Bits 1 to 16 are unused. */
218 floatformat_littlebyte_bigword, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64, 211 floatformat_littlebyte_bigword, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64,
219 floatformat_intbit_yes, 212 floatformat_intbit_yes,
220 "floatformat_arm_ext_littlebyte_bigword", 213 "floatformat_arm_ext_littlebyte_bigword",
221 floatformat_always_valid 214 floatformat_always_valid
222}; 215};
223const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ia64_spill_big = 216const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ia64_spill_big = {
224{
225 floatformat_big, 128, 0, 1, 17, 65535, 0x1ffff, 18, 64, 217 floatformat_big, 128, 0, 1, 17, 65535, 0x1ffff, 18, 64,
226 floatformat_intbit_yes, 218 floatformat_intbit_yes,
227 "floatformat_ia64_spill_big", 219 "floatformat_ia64_spill_big",
228 floatformat_always_valid 220 floatformat_always_valid
229}; 221};
230const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ia64_spill_little = 222const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ia64_spill_little = {
231{
232 floatformat_little, 128, 0, 1, 17, 65535, 0x1ffff, 18, 64, 223 floatformat_little, 128, 0, 1, 17, 65535, 0x1ffff, 18, 64,
233 floatformat_intbit_yes, 224 floatformat_intbit_yes,
234 "floatformat_ia64_spill_little", 225 "floatformat_ia64_spill_little",
235 floatformat_always_valid 226 floatformat_always_valid
236}; 227};
237const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ia64_quad_big = 228const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ia64_quad_big = {
238{
239 floatformat_big, 128, 0, 1, 15, 16383, 0x7fff, 16, 112, 229 floatformat_big, 128, 0, 1, 15, 16383, 0x7fff, 16, 112,
240 floatformat_intbit_no, 230 floatformat_intbit_no,
241 "floatformat_ia64_quad_big", 231 "floatformat_ia64_quad_big",
242 floatformat_always_valid 232 floatformat_always_valid
243}; 233};
244const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ia64_quad_little = 234const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ia64_quad_little = {
245{
246 floatformat_little, 128, 0, 1, 15, 16383, 0x7fff, 16, 112, 235 floatformat_little, 128, 0, 1, 15, 16383, 0x7fff, 16, 112,
247 floatformat_intbit_no, 236 floatformat_intbit_no,
248 "floatformat_ia64_quad_little", 237 "floatformat_ia64_quad_little",
@@ -257,7 +246,8 @@ const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ia64_quad_little =
257/* Extract a field which starts at START and is LEN bits long. DATA and 246/* Extract a field which starts at START and is LEN bits long. DATA and
258 TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */ 247 TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */
259static unsigned long 248static unsigned long
260get_field (const unsigned char *data, enum EXTRACTOR_floatformat_byteorders order, 249get_field (const unsigned char *data, enum EXTRACTOR_floatformat_byteorders
250 order,
261 unsigned int total_len, unsigned int start, unsigned int len) 251 unsigned int total_len, unsigned int start, unsigned int len)
262{ 252{
263 unsigned long result = 0; 253 unsigned long result = 0;
@@ -278,29 +268,30 @@ get_field (const unsigned char *data, enum EXTRACTOR_floatformat_byteorders orde
278 hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT); 268 hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT);
279 269
280 do 270 do
281 { 271 {
282 unsigned int shifted = *(data + cur_byte) >> lo_bit; 272 unsigned int shifted = *(data + cur_byte) >> lo_bit;
283 unsigned int bits = hi_bit - lo_bit; 273 unsigned int bits = hi_bit - lo_bit;
284 unsigned int mask = (1 << bits) - 1; 274 unsigned int mask = (1 << bits) - 1;
285 result |= (shifted & mask) << cur_bitshift; 275 result |= (shifted & mask) << cur_bitshift;
286 len -= bits; 276 len -= bits;
287 cur_bitshift += bits; 277 cur_bitshift += bits;
288 cur_byte += nextbyte; 278 cur_byte += nextbyte;
289 lo_bit = 0; 279 lo_bit = 0;
290 hi_bit = min (len, FLOATFORMAT_CHAR_BIT); 280 hi_bit = min (len, FLOATFORMAT_CHAR_BIT);
291 } 281 }
292 while (len != 0); 282 while (len != 0);
293 283
294 return result; 284 return result;
295} 285}
296 286
287
297/* Convert from FMT to a double. 288/* Convert from FMT to a double.
298 FROM is the address of the extended float. 289 FROM is the address of the extended float.
299 Store the double in *TO. */ 290 Store the double in *TO. */
300 291
301void 292void
302EXTRACTOR_common_floatformat_to_double (const struct EXTRACTOR_floatformat *fmt, 293EXTRACTOR_common_floatformat_to_double (const struct EXTRACTOR_floatformat *fmt,
303 const void *from, double *to) 294 const void *from, double *to)
304{ 295{
305 const unsigned char *ufrom = (const unsigned char *) from; 296 const unsigned char *ufrom = (const unsigned char *) from;
306 double dto; 297 double dto;
@@ -308,65 +299,65 @@ EXTRACTOR_common_floatformat_to_double (const struct EXTRACTOR_floatformat *fmt,
308 unsigned long mant; 299 unsigned long mant;
309 unsigned int mant_bits, mant_off; 300 unsigned int mant_bits, mant_off;
310 int mant_bits_left; 301 int mant_bits_left;
311 int special_exponent; /* It's a NaN, denorm or zero */ 302 int special_exponent; /* It's a NaN, denorm or zero */
312 303
313 exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize, 304 exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
314 fmt->exp_start, fmt->exp_len); 305 fmt->exp_start, fmt->exp_len);
315 306
316 /* If the exponent indicates a NaN, we don't have information to 307 /* If the exponent indicates a NaN, we don't have information to
317 decide what to do. So we handle it like IEEE, except that we 308 decide what to do. So we handle it like IEEE, except that we
318 don't try to preserve the type of NaN. FIXME. */ 309 don't try to preserve the type of NaN. FIXME. */
319 if ((unsigned long) exponent == fmt->exp_nan) 310 if ((unsigned long) exponent == fmt->exp_nan)
311 {
312 int nan;
313
314 mant_off = fmt->man_start;
315 mant_bits_left = fmt->man_len;
316 nan = 0;
317 while (mant_bits_left > 0)
320 { 318 {
321 int nan; 319 mant_bits = min (mant_bits_left, 32);
322 320
323 mant_off = fmt->man_start; 321 if (get_field (ufrom, fmt->byteorder, fmt->totalsize,
324 mant_bits_left = fmt->man_len; 322 mant_off, mant_bits) != 0)
325 nan = 0; 323 {
326 while (mant_bits_left > 0) 324 /* This is a NaN. */
327 { 325 nan = 1;
328 mant_bits = min (mant_bits_left, 32); 326 break;
329 327 }
330 if (get_field (ufrom, fmt->byteorder, fmt->totalsize, 328
331 mant_off, mant_bits) != 0) 329 mant_off += mant_bits;
332 { 330 mant_bits_left -= mant_bits;
333 /* This is a NaN. */
334 nan = 1;
335 break;
336 }
337
338 mant_off += mant_bits;
339 mant_bits_left -= mant_bits;
340 }
341
342 /* On certain systems (such as GNU/Linux), the use of the
343 INFINITY macro below may generate a warning that can not be
344 silenced due to a bug in GCC (PR preprocessor/11931). The
345 preprocessor fails to recognise the __extension__ keyword in
346 conjunction with the GNU/C99 extension for hexadecimal
347 floating point constants and will issue a warning when
348 compiling with -pedantic. */
349 if (nan)
350 dto = NAN;
351 else
352 dto = INFINITY;
353
354 if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
355 dto = -dto;
356
357 *to = dto;
358
359 return;
360 } 331 }
361 332
333 /* On certain systems (such as GNU/Linux), the use of the
334 INFINITY macro below may generate a warning that can not be
335 silenced due to a bug in GCC (PR preprocessor/11931). The
336 preprocessor fails to recognise the __extension__ keyword in
337 conjunction with the GNU/C99 extension for hexadecimal
338 floating point constants and will issue a warning when
339 compiling with -pedantic. */if (nan)
340 dto = NAN;
341 else
342 dto = INFINITY;
343
344 if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
345 dto = -dto;
346
347 *to = dto;
348
349 return;
350 }
351
362 mant_bits_left = fmt->man_len; 352 mant_bits_left = fmt->man_len;
363 mant_off = fmt->man_start; 353 mant_off = fmt->man_start;
364 dto = 0.0; 354 dto = 0.0;
365 355
366 special_exponent = (exponent == 0) || ((unsigned long) exponent == fmt->exp_nan); 356 special_exponent = (exponent == 0) || ((unsigned long) exponent ==
357 fmt->exp_nan);
367 358
368 /* Don't bias zero's, denorms or NaNs. */ 359 /* Don't bias zero's, denorms or NaNs. */
369 if (!special_exponent) 360 if (! special_exponent)
370 exponent -= fmt->exp_bias; 361 exponent -= fmt->exp_bias;
371 362
372 /* Build the result algebraically. Might go infinite, underflow, etc; 363 /* Build the result algebraically. Might go infinite, underflow, etc;
@@ -375,36 +366,36 @@ EXTRACTOR_common_floatformat_to_double (const struct EXTRACTOR_floatformat *fmt,
375 /* If this format uses a hidden bit, explicitly add it in now. Otherwise, 366 /* If this format uses a hidden bit, explicitly add it in now. Otherwise,
376 increment the exponent by one to account for the integer bit. */ 367 increment the exponent by one to account for the integer bit. */
377 368
378 if (!special_exponent) 369 if (! special_exponent)
379 { 370 {
380 if (fmt->intbit == floatformat_intbit_no) 371 if (fmt->intbit == floatformat_intbit_no)
381 dto = ldexp (1.0, exponent); 372 dto = ldexp (1.0, exponent);
382 else 373 else
383 exponent++; 374 exponent++;
384 } 375 }
385 376
386 while (mant_bits_left > 0) 377 while (mant_bits_left > 0)
387 { 378 {
388 mant_bits = min (mant_bits_left, 32); 379 mant_bits = min (mant_bits_left, 32);
389 380
390 mant = get_field (ufrom, fmt->byteorder, fmt->totalsize, 381 mant = get_field (ufrom, fmt->byteorder, fmt->totalsize,
391 mant_off, mant_bits); 382 mant_off, mant_bits);
392 383
393 /* Handle denormalized numbers. FIXME: What should we do for 384 /* Handle denormalized numbers. FIXME: What should we do for
394 non-IEEE formats? */ 385 non-IEEE formats? */
395 if (special_exponent && exponent == 0 && mant != 0) 386 if (special_exponent && (exponent == 0) && (mant != 0) )
396 dto += ldexp ((double)mant, 387 dto += ldexp ((double) mant,
397 (- fmt->exp_bias 388 (-fmt->exp_bias
398 - mant_bits 389 - mant_bits
399 - (mant_off - fmt->man_start) 390 - (mant_off - fmt->man_start)
400 + 1)); 391 + 1));
401 else 392 else
402 dto += ldexp ((double)mant, exponent - mant_bits); 393 dto += ldexp ((double) mant, exponent - mant_bits);
403 if (exponent != 0) 394 if (exponent != 0)
404 exponent -= mant_bits; 395 exponent -= mant_bits;
405 mant_off += mant_bits; 396 mant_off += mant_bits;
406 mant_bits_left -= mant_bits; 397 mant_bits_left -= mant_bits;
407 } 398 }
408 399
409 /* Negate it if negative. */ 400 /* Negate it if negative. */
410 if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1)) 401 if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
@@ -412,6 +403,7 @@ EXTRACTOR_common_floatformat_to_double (const struct EXTRACTOR_floatformat *fmt,
412 *to = dto; 403 *to = dto;
413} 404}
414 405
406
415static void put_field (unsigned char *, enum EXTRACTOR_floatformat_byteorders, 407static void put_field (unsigned char *, enum EXTRACTOR_floatformat_byteorders,
416 unsigned int, 408 unsigned int,
417 unsigned int, 409 unsigned int,
@@ -442,27 +434,29 @@ put_field (unsigned char *data, enum EXTRACTOR_floatformat_byteorders order,
442 hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT); 434 hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT);
443 435
444 do 436 do
445 { 437 {
446 unsigned char *byte_ptr = data + cur_byte; 438 unsigned char *byte_ptr = data + cur_byte;
447 unsigned int bits = hi_bit - lo_bit; 439 unsigned int bits = hi_bit - lo_bit;
448 unsigned int mask = ((1 << bits) - 1) << lo_bit; 440 unsigned int mask = ((1 << bits) - 1) << lo_bit;
449 *byte_ptr = (*byte_ptr & ~mask) | ((stuff_to_put << lo_bit) & mask); 441 *byte_ptr = (*byte_ptr & ~mask) | ((stuff_to_put << lo_bit) & mask);
450 stuff_to_put >>= bits; 442 stuff_to_put >>= bits;
451 len -= bits; 443 len -= bits;
452 cur_byte += nextbyte; 444 cur_byte += nextbyte;
453 lo_bit = 0; 445 lo_bit = 0;
454 hi_bit = min (len, FLOATFORMAT_CHAR_BIT); 446 hi_bit = min (len, FLOATFORMAT_CHAR_BIT);
455 } 447 }
456 while (len != 0); 448 while (len != 0);
457} 449}
458 450
451
459/* The converse: convert the double *FROM to an extended float 452/* The converse: convert the double *FROM to an extended float
460 and store where TO points. Neither FROM nor TO have any alignment 453 and store where TO points. Neither FROM nor TO have any alignment
461 restrictions. */ 454 restrictions. */
462 455
463void 456void
464EXTRACTOR_common_floatformat_from_double (const struct EXTRACTOR_floatformat *fmt, 457EXTRACTOR_common_floatformat_from_double (const struct
465 const double *from, void *to) 458 EXTRACTOR_floatformat *fmt,
459 const double *from, void *to)
466{ 460{
467 double dfrom; 461 double dfrom;
468 int exponent; 462 int exponent;
@@ -476,88 +470,90 @@ EXTRACTOR_common_floatformat_from_double (const struct EXTRACTOR_floatformat *fm
476 470
477 /* If negative, set the sign bit. */ 471 /* If negative, set the sign bit. */
478 if (dfrom < 0) 472 if (dfrom < 0)
479 { 473 {
480 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1); 474 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1);
481 dfrom = -dfrom; 475 dfrom = -dfrom;
482 } 476 }
483 477
484 if (dfrom == 0) 478 if (dfrom == 0)
485 { 479 {
486 /* 0.0. */ 480 /* 0.0. */
487 return; 481 return;
488 } 482 }
489 483
490 if (dfrom != dfrom) 484 if (dfrom != dfrom)
491 { 485 {
492 /* NaN. */ 486 /* NaN. */
493 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, 487 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
494 fmt->exp_len, fmt->exp_nan); 488 fmt->exp_len, fmt->exp_nan);
495 /* Be sure it's not infinity, but NaN value is irrelevant. */ 489 /* Be sure it's not infinity, but NaN value is irrelevant. */
496 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start, 490 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
497 32, 1); 491 32, 1);
498 return; 492 return;
499 } 493 }
500 494
501 if (dfrom + dfrom == dfrom) 495 if (dfrom + dfrom == dfrom)
502 { 496 {
503 /* This can only happen for an infinite value (or zero, which we 497 /* This can only happen for an infinite value (or zero, which we
504 already handled above). */ 498 already handled above). */
505 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, 499 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
506 fmt->exp_len, fmt->exp_nan); 500 fmt->exp_len, fmt->exp_nan);
507 return; 501 return;
508 } 502 }
509 503
510 mant = frexp (dfrom, &exponent); 504 mant = frexp (dfrom, &exponent);
511 if (exponent + fmt->exp_bias - 1 > 0) 505 if (exponent + fmt->exp_bias - 1 > 0)
512 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, 506 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
513 fmt->exp_len, exponent + fmt->exp_bias - 1); 507 fmt->exp_len, exponent + fmt->exp_bias - 1);
514 else 508 else
515 { 509 {
516 /* Handle a denormalized number. FIXME: What should we do for 510 /* Handle a denormalized number. FIXME: What should we do for
517 non-IEEE formats? */ 511 non-IEEE formats? */
518 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, 512 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
519 fmt->exp_len, 0); 513 fmt->exp_len, 0);
520 mant = ldexp (mant, exponent + fmt->exp_bias - 1); 514 mant = ldexp (mant, exponent + fmt->exp_bias - 1);
521 } 515 }
522 516
523 mant_bits_left = fmt->man_len; 517 mant_bits_left = fmt->man_len;
524 mant_off = fmt->man_start; 518 mant_off = fmt->man_start;
525 while (mant_bits_left > 0) 519 while (mant_bits_left > 0)
520 {
521 unsigned long mant_long;
522 mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;
523
524 mant *= 4294967296.0;
525 mant_long = (unsigned long) mant;
526 mant -= mant_long;
527
528 /* If the integer bit is implicit, and we are not creating a
529 denormalized number, then we need to discard it. */
530 if (( (unsigned int) mant_bits_left == fmt->man_len)
531 && (fmt->intbit == floatformat_intbit_no)
532 && (exponent + fmt->exp_bias - 1 > 0) )
526 { 533 {
527 unsigned long mant_long; 534 mant_long &= 0x7fffffff;
528 mant_bits = mant_bits_left < 32 ? mant_bits_left : 32; 535 mant_bits -= 1;
529
530 mant *= 4294967296.0;
531 mant_long = (unsigned long)mant;
532 mant -= mant_long;
533
534 /* If the integer bit is implicit, and we are not creating a
535 denormalized number, then we need to discard it. */
536 if ((unsigned int) mant_bits_left == fmt->man_len
537 && fmt->intbit == floatformat_intbit_no
538 && exponent + fmt->exp_bias - 1 > 0)
539 {
540 mant_long &= 0x7fffffff;
541 mant_bits -= 1;
542 }
543 else if (mant_bits < 32)
544 {
545 /* The bits we want are in the most significant MANT_BITS bits of
546 mant_long. Move them to the least significant. */
547 mant_long >>= 32 - mant_bits;
548 }
549
550 put_field (uto, fmt->byteorder, fmt->totalsize,
551 mant_off, mant_bits, mant_long);
552 mant_off += mant_bits;
553 mant_bits_left -= mant_bits;
554 } 536 }
537 else if (mant_bits < 32)
538 {
539 /* The bits we want are in the most significant MANT_BITS bits of
540 mant_long. Move them to the least significant. */
541 mant_long >>= 32 - mant_bits;
542 }
543
544 put_field (uto, fmt->byteorder, fmt->totalsize,
545 mant_off, mant_bits, mant_long);
546 mant_off += mant_bits;
547 mant_bits_left -= mant_bits;
548 }
555} 549}
556 550
551
557/* Return non-zero iff the data at FROM is a valid number in format FMT. */ 552/* Return non-zero iff the data at FROM is a valid number in format FMT. */
558 553
559int 554int
560EXTRACTOR_common_floatformat_is_valid (const struct EXTRACTOR_floatformat *fmt, const void *from) 555EXTRACTOR_common_floatformat_is_valid (const struct EXTRACTOR_floatformat *fmt,
556 const void *from)
561{ 557{
562 return fmt->is_valid (fmt, from); 558 return fmt->is_valid (fmt, from);
563} 559}
@@ -575,15 +571,15 @@ ieee_test (double n)
575 double result; 571 double result;
576 572
577 floatformat_to_double (&floatformat_ieee_double_little, &n, &result); 573 floatformat_to_double (&floatformat_ieee_double_little, &n, &result);
578 if ((n != result && (! isnan (n) || ! isnan (result))) 574 if (((n != result) && (! isnan (n) || ! isnan (result)))
579 || (n < 0 && result >= 0) 575 || ((n < 0) && (result >= 0))
580 || (n >= 0 && result < 0)) 576 || ((n >= 0) && (result < 0)))
581 printf ("Differ(to): %.20g -> %.20g\n", n, result); 577 printf ("Differ(to): %.20g -> %.20g\n", n, result);
582 578
583 floatformat_from_double (&floatformat_ieee_double_little, &n, &result); 579 floatformat_from_double (&floatformat_ieee_double_little, &n, &result);
584 if ((n != result && (! isnan (n) || ! isnan (result))) 580 if (((n != result) && (! isnan (n) || ! isnan (result)))
585 || (n < 0 && result >= 0) 581 || ((n < 0) && (result >= 0))
586 || (n >= 0 && result < 0)) 582 || ((n >= 0) && (result < 0)))
587 printf ("Differ(from): %.20g -> %.20g\n", n, result); 583 printf ("Differ(from): %.20g -> %.20g\n", n, result);
588 584
589#if 0 585#if 0
@@ -600,13 +596,14 @@ ieee_test (double n)
600#if IEEE_DEBUG > 1 596#if IEEE_DEBUG > 1
601 /* This is to be run on a host which uses 68881 format. */ 597 /* This is to be run on a host which uses 68881 format. */
602 { 598 {
603 long double ex = *(long double *)exten; 599 long double ex = *(long double *) exten;
604 if (ex != n) 600 if (ex != n)
605 printf ("Differ(from vs. extended): %.20g\n", n); 601 printf ("Differ(from vs. extended): %.20g\n", n);
606 } 602 }
607#endif 603#endif
608} 604}
609 605
606
610int 607int
611main (void) 608main (void)
612{ 609{
@@ -620,12 +617,14 @@ main (void)
620 ieee_test (1.2E-70); 617 ieee_test (1.2E-70);
621 ieee_test (1.2E-316); 618 ieee_test (1.2E-316);
622 ieee_test (4.9406564584124654E-324); 619 ieee_test (4.9406564584124654E-324);
623 ieee_test (- 4.9406564584124654E-324); 620 ieee_test (-4.9406564584124654E-324);
624 ieee_test (- 0.0); 621 ieee_test (-0.0);
625 ieee_test (- INFINITY); 622 ieee_test (-INFINITY);
626 ieee_test (- NAN); 623 ieee_test (-NAN);
627 ieee_test (INFINITY); 624 ieee_test (INFINITY);
628 ieee_test (NAN); 625 ieee_test (NAN);
629 return 0; 626 return 0;
630} 627}
628
629
631#endif 630#endif