1 1.1 christos /* atof_vax.c - turn a Flonum into a VAX floating point number 2 1.10 christos Copyright (C) 1987-2025 Free Software Foundation, Inc. 3 1.1 christos 4 1.1 christos This file is part of GAS, the GNU Assembler. 5 1.1 christos 6 1.1 christos GAS is free software; you can redistribute it and/or modify 7 1.1 christos it under the terms of the GNU General Public License as published by 8 1.1 christos the Free Software Foundation; either version 3, or (at your option) 9 1.1 christos any later version. 10 1.1 christos 11 1.1 christos GAS is distributed in the hope that it will be useful, 12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 christos GNU General Public License for more details. 15 1.1 christos 16 1.1 christos You should have received a copy of the GNU General Public License 17 1.1 christos along with GAS; see the file COPYING. If not, write to the Free 18 1.1 christos Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 19 1.1 christos 02110-1301, USA. */ 20 1.1 christos 21 1.1 christos #include "as.h" 22 1.1 christos 23 1.1 christos /* Precision in LittleNums. */ 24 1.1 christos #define MAX_PRECISION 8 25 1.1 christos #define H_PRECISION 8 26 1.1 christos #define G_PRECISION 4 27 1.1 christos #define D_PRECISION 4 28 1.1 christos #define F_PRECISION 2 29 1.1 christos 30 1.1 christos /* Length in LittleNums of guard bits. */ 31 1.1 christos #define GUARD 2 32 1.1 christos 33 1.1 christos int flonum_gen2vax (int, FLONUM_TYPE *, LITTLENUM_TYPE *); 34 1.1 christos 35 1.1 christos /* Number of chars in flonum type 'letter'. */ 36 1.1 christos 37 1.1 christos static unsigned int 38 1.1 christos atof_vax_sizeof (int letter) 39 1.1 christos { 40 1.1 christos int return_value; 41 1.1 christos 42 1.1 christos /* Permitting uppercase letters is probably a bad idea. 43 1.1 christos Please use only lower-cased letters in case the upper-cased 44 1.1 christos ones become unsupported! */ 45 1.1 christos switch (letter) 46 1.1 christos { 47 1.1 christos case 'f': 48 1.1 christos case 'F': 49 1.1 christos return_value = 4; 50 1.1 christos break; 51 1.1 christos 52 1.1 christos case 'd': 53 1.1 christos case 'D': 54 1.1 christos case 'g': 55 1.1 christos case 'G': 56 1.1 christos return_value = 8; 57 1.1 christos break; 58 1.1 christos 59 1.1 christos case 'h': 60 1.1 christos case 'H': 61 1.1 christos return_value = 16; 62 1.1 christos break; 63 1.1 christos 64 1.1 christos default: 65 1.1 christos return_value = 0; 66 1.1 christos break; 67 1.1 christos } 68 1.1 christos 69 1.1 christos return return_value; 70 1.1 christos } 71 1.1 christos 72 1.1 christos static const long mask[] = 73 1.1 christos { 74 1.1 christos 0x00000000, 75 1.1 christos 0x00000001, 76 1.1 christos 0x00000003, 77 1.1 christos 0x00000007, 78 1.1 christos 0x0000000f, 79 1.1 christos 0x0000001f, 80 1.1 christos 0x0000003f, 81 1.1 christos 0x0000007f, 82 1.1 christos 0x000000ff, 83 1.1 christos 0x000001ff, 84 1.1 christos 0x000003ff, 85 1.1 christos 0x000007ff, 86 1.1 christos 0x00000fff, 87 1.1 christos 0x00001fff, 88 1.1 christos 0x00003fff, 89 1.1 christos 0x00007fff, 90 1.1 christos 0x0000ffff, 91 1.1 christos 0x0001ffff, 92 1.1 christos 0x0003ffff, 93 1.1 christos 0x0007ffff, 94 1.1 christos 0x000fffff, 95 1.1 christos 0x001fffff, 96 1.1 christos 0x003fffff, 97 1.1 christos 0x007fffff, 98 1.1 christos 0x00ffffff, 99 1.1 christos 0x01ffffff, 100 1.1 christos 0x03ffffff, 101 1.1 christos 0x07ffffff, 102 1.1 christos 0x0fffffff, 103 1.1 christos 0x1fffffff, 104 1.1 christos 0x3fffffff, 105 1.1 christos 0x7fffffff, 106 1.1 christos 0xffffffff 107 1.1 christos }; 108 1.1 christos 109 1.1 christos 111 1.1 christos /* Shared between flonum_gen2vax and next_bits. */ 112 1.1 christos static int bits_left_in_littlenum; 113 1.1 christos static LITTLENUM_TYPE *littlenum_pointer; 114 1.1 christos static LITTLENUM_TYPE *littlenum_end; 115 1.1 christos 116 1.1 christos static int 117 1.1 christos next_bits (int number_of_bits) 118 1.1 christos { 119 1.1 christos int return_value; 120 1.1 christos 121 1.1 christos if (littlenum_pointer < littlenum_end) 122 1.1 christos return 0; 123 1.1 christos if (number_of_bits >= bits_left_in_littlenum) 124 1.1 christos { 125 1.1 christos return_value = mask[bits_left_in_littlenum] & *littlenum_pointer; 126 1.1 christos number_of_bits -= bits_left_in_littlenum; 127 1.1 christos return_value <<= number_of_bits; 128 1.1 christos bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits; 129 1.1 christos littlenum_pointer--; 130 1.1 christos if (littlenum_pointer >= littlenum_end) 131 1.1 christos return_value |= ((*littlenum_pointer) >> (bits_left_in_littlenum)) & mask[number_of_bits]; 132 1.1 christos } 133 1.1 christos else 134 1.1 christos { 135 1.1 christos bits_left_in_littlenum -= number_of_bits; 136 1.1 christos return_value = mask[number_of_bits] & ((*littlenum_pointer) >> bits_left_in_littlenum); 137 1.1 christos } 138 1.1 christos return return_value; 139 1.1 christos } 140 1.1 christos 141 1.1 christos static void 142 1.1 christos make_invalid_floating_point_number (LITTLENUM_TYPE *words) 143 1.1 christos { 144 1.1 christos *words = 0x8000; /* Floating Reserved Operand Code. */ 145 1.1 christos } 146 1.1 christos 147 1.1 christos 148 1.1 christos static int /* 0 means letter is OK. */ 150 1.1 christos what_kind_of_float (int letter, /* In: lowercase please. What kind of float? */ 151 1.1 christos int *precisionP, /* Number of 16-bit words in the float. */ 152 1.1 christos long *exponent_bitsP) /* Number of exponent bits. */ 153 1.1 christos { 154 1.1 christos int retval; 155 1.1 christos 156 1.1 christos retval = 0; 157 1.1 christos switch (letter) 158 1.1 christos { 159 1.1 christos case 'f': 160 1.1 christos *precisionP = F_PRECISION; 161 1.1 christos *exponent_bitsP = 8; 162 1.1 christos break; 163 1.1 christos 164 1.1 christos case 'd': 165 1.1 christos *precisionP = D_PRECISION; 166 1.1 christos *exponent_bitsP = 8; 167 1.1 christos break; 168 1.1 christos 169 1.1 christos case 'g': 170 1.1 christos *precisionP = G_PRECISION; 171 1.1 christos *exponent_bitsP = 11; 172 1.1 christos break; 173 1.1 christos 174 1.1 christos case 'h': 175 1.1 christos *precisionP = H_PRECISION; 176 1.1 christos *exponent_bitsP = 15; 177 1.1 christos break; 178 1.1 christos 179 1.1 christos default: 180 1.1 christos retval = 69; 181 1.1 christos break; 182 1.1 christos } 183 1.1 christos return retval; 184 1.1 christos } 185 1.1 christos 186 1.1 christos /* Warning: this returns 16-bit LITTLENUMs, because that is 188 1.1 christos what the VAX thinks in. It is up to the caller to figure 189 1.1 christos out any alignment problems and to conspire for the bytes/word 190 1.1 christos to be emitted in the right order. Bigendians beware! */ 191 1.1 christos 192 1.1 christos static char * 193 1.1 christos atof_vax (char *str, /* Text to convert to binary. */ 194 1.1 christos int what_kind, /* 'd', 'f', 'g', 'h' */ 195 1.1 christos LITTLENUM_TYPE *words) /* Build the binary here. */ 196 1.1 christos { 197 1.1 christos FLONUM_TYPE f; 198 1.1 christos LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD]; 199 1.1 christos /* Extra bits for zeroed low-order bits. 200 1.1 christos The 1st MAX_PRECISION are zeroed, 201 1.1 christos the last contain flonum bits. */ 202 1.1 christos char *return_value; 203 1.1 christos int precision; /* Number of 16-bit words in the format. */ 204 1.1 christos long exponent_bits; 205 1.1 christos 206 1.1 christos return_value = str; 207 1.1 christos f.low = bits + MAX_PRECISION; 208 1.1 christos f.high = NULL; 209 1.1 christos f.leader = NULL; 210 1.1 christos f.exponent = 0; 211 1.1 christos f.sign = '\0'; 212 1.1 christos 213 1.1 christos if (what_kind_of_float (what_kind, &precision, &exponent_bits)) 214 1.1 christos { 215 1.1 christos return_value = NULL; 216 1.1 christos make_invalid_floating_point_number (words); 217 1.1 christos } 218 1.1 christos 219 1.1 christos if (return_value) 220 1.1 christos { 221 1.1 christos memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION); 222 1.1 christos 223 1.1 christos /* Use more LittleNums than seems 224 1.1 christos necessary: the highest flonum may have 225 1.1 christos 15 leading 0 bits, so could be useless. */ 226 1.1 christos f.high = f.low + precision - 1 + GUARD; 227 1.1 christos 228 1.1 christos if (atof_generic (&return_value, ".", "eE", &f)) 229 1.1 christos { 230 1.1 christos make_invalid_floating_point_number (words); 231 1.1 christos return_value = NULL; 232 1.1 christos } 233 1.1 christos else if (flonum_gen2vax (what_kind, &f, words)) 234 1.1 christos return_value = NULL; 235 1.1 christos } 236 1.1 christos 237 1.1 christos return return_value; 238 1.1 christos } 239 1.1 christos 240 1.1 christos /* In: a flonum, a vax floating point format. 242 1.1 christos Out: a vax floating-point bit pattern. */ 243 1.1 christos 244 1.1 christos int 245 1.1 christos flonum_gen2vax (int format_letter, /* One of 'd' 'f' 'g' 'h'. */ 246 1.1 christos FLONUM_TYPE *f, 247 1.1 christos LITTLENUM_TYPE *words) /* Deliver answer here. */ 248 1.1 christos { 249 1.1 christos LITTLENUM_TYPE *lp; 250 1.1 christos int precision; 251 1.1 christos long exponent_bits; 252 1.1 christos int return_value; /* 0 == OK. */ 253 1.1 christos 254 1.1 christos return_value = what_kind_of_float (format_letter, &precision, &exponent_bits); 255 1.1 christos 256 1.1 christos if (return_value != 0) 257 1.1 christos make_invalid_floating_point_number (words); 258 1.1 christos 259 1.1 christos else 260 1.1 christos { 261 1.1 christos if (f->low > f->leader) 262 1.1 christos /* 0.0e0 seen. */ 263 1.1 christos memset (words, '\0', sizeof (LITTLENUM_TYPE) * precision); 264 1.1 christos 265 1.1 christos else 266 1.1 christos { 267 1.1 christos long exponent_1; 268 1.1 christos long exponent_2; 269 1.1 christos long exponent_3; 270 1.1 christos long exponent_4; 271 1.1 christos int exponent_skippage; 272 1.1 christos LITTLENUM_TYPE word1; 273 1.1 christos 274 1.1 christos if (f->sign != '-' && f->sign != '+') 275 1.1 christos { 276 1.1 christos if (f->sign == 0) 277 1.1 christos { 278 1.1 christos /* All NaNs are 0. */ 279 1.1 christos memset (words, 0x00, sizeof (LITTLENUM_TYPE) * precision); 280 1.1 christos } 281 1.1 christos else if (f->sign == 'P') 282 1.1 christos { 283 1.1 christos /* Positive Infinity. */ 284 1.1 christos memset (words, 0xff, sizeof (LITTLENUM_TYPE) * precision); 285 1.1 christos words[0] &= 0x7fff; 286 1.1 christos } 287 1.1 christos else if (f->sign == 'N') 288 1.1 christos { 289 1.1 christos /* Negative Infinity. */ 290 1.1 christos memset (words, 0x00, sizeof (LITTLENUM_TYPE) * precision); 291 1.1 christos words[0] = 0x0080; 292 1.1 christos } 293 1.1 christos else 294 1.1 christos make_invalid_floating_point_number (words); 295 1.1 christos return return_value; 296 1.1 christos } 297 1.1 christos 298 1.1 christos /* All vaxen floating_point formats (so far) have: 299 1.1 christos Bit 15 is sign bit. 300 1.1 christos Bits 14:n are excess-whatever exponent. 301 1.1 christos Bits n-1:0 (if any) are most significant bits of fraction. 302 1.1 christos Bits 15:0 of the next word are the next most significant bits. 303 1.1 christos And so on for each other word. 304 1.1 christos 305 1.1 christos All this to be compatible with a KF11?? (Which is still faster 306 1.1 christos than lots of vaxen I can think of, but it also has higher 307 1.1 christos maintenance costs ... sigh). 308 1.1 christos 309 1.1 christos So we need: number of bits of exponent, number of bits of 310 1.1 christos mantissa. */ 311 1.1 christos 312 1.1 christos bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS; 313 1.1 christos littlenum_pointer = f->leader; 314 1.3 christos littlenum_end = f->low; 315 1.1 christos /* Seek (and forget) 1st significant bit. */ 316 1.1 christos for (exponent_skippage = 0; 317 1.1 christos !next_bits (1); 318 1.1 christos exponent_skippage++); 319 1.1 christos 320 1.1 christos exponent_1 = f->exponent + f->leader + 1 - f->low; 321 1.1 christos /* Radix LITTLENUM_RADIX, point just higher than f->leader. */ 322 1.1 christos exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS; 323 1.1 christos /* Radix 2. */ 324 1.1 christos exponent_3 = exponent_2 - exponent_skippage; 325 1.1 christos /* Forget leading zeros, forget 1st bit. */ 326 1.1 christos exponent_4 = exponent_3 + (1 << (exponent_bits - 1)); 327 1.1 christos /* Offset exponent. */ 328 1.1 christos 329 1.1 christos if (exponent_4 & ~mask[exponent_bits]) 330 1.1 christos { 331 1.1 christos /* Exponent overflow. Lose immediately. */ 332 1.1 christos make_invalid_floating_point_number (words); 333 1.1 christos 334 1.1 christos /* We leave return_value alone: admit we read the 335 1.1 christos number, but return a floating exception 336 1.1 christos because we can't encode the number. */ 337 1.1 christos } 338 1.1 christos else 339 1.1 christos { 340 1.1 christos lp = words; 341 1.1 christos 342 1.1 christos /* Word 1. Sign, exponent and perhaps high bits. 343 1.1 christos Assume 2's complement integers. */ 344 1.1 christos word1 = (((exponent_4 & mask[exponent_bits]) << (15 - exponent_bits)) 345 1.1 christos | ((f->sign == '+') ? 0 : 0x8000) 346 1.1 christos | next_bits (15 - exponent_bits)); 347 1.1 christos *lp++ = word1; 348 1.1 christos 349 1.1 christos /* The rest of the words are just mantissa bits. */ 350 1.1 christos for (; lp < words + precision; lp++) 351 1.1 christos *lp = next_bits (LITTLENUM_NUMBER_OF_BITS); 352 1.1 christos 353 1.1 christos if (next_bits (1)) 354 1.1 christos { 355 1.1 christos /* Since the NEXT bit is a 1, round UP the mantissa. 356 1.1 christos The cunning design of these hidden-1 floats permits 357 1.1 christos us to let the mantissa overflow into the exponent, and 358 1.1 christos it 'does the right thing'. However, we lose if the 359 1.1 christos highest-order bit of the lowest-order word flips. 360 1.1 christos Is that clear? */ 361 1.1 christos unsigned long carry; 362 1.1 christos 363 1.1 christos /* 364 1.1 christos #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2) 365 1.1 christos Please allow at least 1 more bit in carry than is in a LITTLENUM. 366 1.1 christos We need that extra bit to hold a carry during a LITTLENUM carry 367 1.1 christos propagation. Another extra bit (kept 0) will assure us that we 368 1.1 christos don't get a sticky sign bit after shifting right, and that 369 1.1 christos permits us to propagate the carry without any masking of bits. 370 1.1 christos #endif */ 371 1.1 christos for (carry = 1, lp--; 372 1.1 christos carry && (lp >= words); 373 1.1 christos lp--) 374 1.1 christos { 375 1.1 christos carry = *lp + carry; 376 1.1 christos *lp = carry; 377 1.1 christos carry >>= LITTLENUM_NUMBER_OF_BITS; 378 1.1 christos } 379 1.1 christos 380 1.1 christos if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1))) 381 1.1 christos { 382 1.1 christos make_invalid_floating_point_number (words); 383 1.1 christos /* We leave return_value alone: admit we read the 384 1.1 christos number, but return a floating exception 385 1.1 christos because we can't encode the number. */ 386 1.1 christos } 387 1.1 christos } 388 1.1 christos } 389 1.1 christos } 390 1.1 christos } 391 1.1 christos return return_value; 392 1.1 christos } 393 1.1 christos 394 1.1 christos /* JF this used to be in vax.c but this looks like a better place for it. */ 395 1.1 christos 396 1.1 christos /* In: input_line_pointer->the 1st character of a floating-point 397 1.1 christos number. 398 1.1 christos 1 letter denoting the type of statement that wants a 399 1.3 christos binary floating point number returned. 400 1.1 christos Address of where to build floating point literal. 401 1.1 christos Assumed to be 'big enough'. 402 1.1 christos Address of where to return size of literal (in chars). 403 1.1 christos 404 1.1 christos Out: Input_line_pointer->of next char after floating number. 405 1.1 christos Error message, or 0. 406 1.1 christos Floating point literal. 407 1.5 christos Number of chars we used for the literal. */ 408 1.1 christos 409 1.1 christos #define MAXIMUM_NUMBER_OF_LITTLENUMS 8 /* For .hfloats. */ 410 1.1 christos 411 1.1 christos const char * 412 1.1 christos vax_md_atof (int what_statement_type, 413 1.1 christos char *literalP, 414 1.1 christos int *sizeP) 415 1.1 christos { 416 1.1 christos LITTLENUM_TYPE words[MAXIMUM_NUMBER_OF_LITTLENUMS]; 417 1.1 christos char kind_of_float; 418 1.1 christos unsigned int number_of_chars; 419 1.1 christos LITTLENUM_TYPE *littlenumP; 420 1.1 christos 421 1.1 christos switch (what_statement_type) 422 1.1 christos { 423 1.1 christos case 'F': 424 1.1 christos case 'f': 425 1.1 christos kind_of_float = 'f'; 426 1.1 christos break; 427 1.1 christos 428 1.1 christos case 'D': 429 1.1 christos case 'd': 430 1.1 christos kind_of_float = 'd'; 431 1.1 christos break; 432 1.1 christos 433 1.1 christos case 'g': 434 1.1 christos kind_of_float = 'g'; 435 1.1 christos break; 436 1.1 christos 437 1.1 christos case 'h': 438 1.1 christos kind_of_float = 'h'; 439 1.1 christos break; 440 1.1 christos 441 1.1 christos default: 442 1.1 christos kind_of_float = 0; 443 1.1 christos break; 444 1.1 christos }; 445 1.1 christos 446 1.1 christos if (kind_of_float) 447 1.1 christos { 448 1.1 christos LITTLENUM_TYPE *limit; 449 1.1 christos 450 1.1 christos input_line_pointer = atof_vax (input_line_pointer, 451 1.1 christos kind_of_float, 452 1.1 christos words); 453 1.1 christos /* The atof_vax() builds up 16-bit numbers. 454 1.1 christos Since the assembler may not be running on 455 1.1 christos a little-endian machine, be very careful about 456 1.1 christos converting words to chars. */ 457 1.1 christos number_of_chars = atof_vax_sizeof (kind_of_float); 458 1.1 christos know (number_of_chars <= MAXIMUM_NUMBER_OF_LITTLENUMS * sizeof (LITTLENUM_TYPE)); 459 1.1 christos limit = words + (number_of_chars / sizeof (LITTLENUM_TYPE)); 460 1.1 christos for (littlenumP = words; littlenumP < limit; littlenumP++) 461 1.1 christos { 462 1.1 christos md_number_to_chars (literalP, *littlenumP, sizeof (LITTLENUM_TYPE)); 463 1.1 christos literalP += sizeof (LITTLENUM_TYPE); 464 1.1 christos }; 465 1.1 christos } 466 1.1 christos else 467 1.1 christos number_of_chars = 0; 468 469 *sizeP = number_of_chars; 470 return kind_of_float ? NULL : _("Unrecognized or unsupported floating point constant"); 471 } 472