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