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