Commit | Line | Data |
---|---|---|
252b5132 | 1 | /* atof_vax.c - turn a Flonum into a VAX floating point number |
2571583a | 2 | Copyright (C) 1987-2017 Free Software Foundation, Inc. |
252b5132 RH |
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 | |
ec2655a6 | 8 | the Free Software Foundation; either version 3, or (at your option) |
252b5132 RH |
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 | |
4b4da160 NC |
18 | Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA |
19 | 02110-1301, USA. */ | |
252b5132 RH |
20 | |
21 | #include "as.h" | |
22 | ||
4a1805b1 | 23 | /* Precision in LittleNums. */ |
4d5f9b2a NC |
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 | |
252b5132 | 29 | |
4a1805b1 | 30 | /* Length in LittleNums of guard bits. */ |
d2c5f73e | 31 | #define GUARD 2 |
252b5132 | 32 | |
4d5f9b2a | 33 | int flonum_gen2vax (int, FLONUM_TYPE *, LITTLENUM_TYPE *); |
252b5132 | 34 | |
4a1805b1 | 35 | /* Number of chars in flonum type 'letter'. */ |
4d5f9b2a | 36 | |
541d2ffd | 37 | static unsigned int |
4d5f9b2a | 38 | atof_vax_sizeof (int letter) |
252b5132 RH |
39 | { |
40 | int return_value; | |
41 | ||
4d5f9b2a NC |
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! */ | |
252b5132 RH |
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 | } | |
4d5f9b2a NC |
68 | |
69 | return return_value; | |
70 | } | |
252b5132 RH |
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 | \f | |
109 | ||
4d5f9b2a | 110 | /* Shared between flonum_gen2vax and next_bits. */ |
252b5132 RH |
111 | static int bits_left_in_littlenum; |
112 | static LITTLENUM_TYPE *littlenum_pointer; | |
113 | static LITTLENUM_TYPE *littlenum_end; | |
114 | ||
115 | static int | |
4d5f9b2a | 116 | next_bits (int number_of_bits) |
252b5132 RH |
117 | { |
118 | int return_value; | |
119 | ||
120 | if (littlenum_pointer < littlenum_end) | |
121 | return 0; | |
122 | if (number_of_bits >= bits_left_in_littlenum) | |
123 | { | |
124 | return_value = mask[bits_left_in_littlenum] & *littlenum_pointer; | |
125 | number_of_bits -= bits_left_in_littlenum; | |
126 | return_value <<= number_of_bits; | |
127 | bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits; | |
128 | littlenum_pointer--; | |
129 | if (littlenum_pointer >= littlenum_end) | |
130 | return_value |= ((*littlenum_pointer) >> (bits_left_in_littlenum)) & mask[number_of_bits]; | |
131 | } | |
132 | else | |
133 | { | |
134 | bits_left_in_littlenum -= number_of_bits; | |
135 | return_value = mask[number_of_bits] & ((*littlenum_pointer) >> bits_left_in_littlenum); | |
136 | } | |
4d5f9b2a | 137 | return return_value; |
252b5132 RH |
138 | } |
139 | ||
140 | static void | |
4d5f9b2a | 141 | make_invalid_floating_point_number (LITTLENUM_TYPE *words) |
252b5132 | 142 | { |
4d5f9b2a | 143 | *words = 0x8000; /* Floating Reserved Operand Code. */ |
252b5132 | 144 | } |
4d5f9b2a | 145 | |
252b5132 | 146 | \f |
4a1805b1 | 147 | static int /* 0 means letter is OK. */ |
4d5f9b2a NC |
148 | what_kind_of_float (int letter, /* In: lowercase please. What kind of float? */ |
149 | int *precisionP, /* Number of 16-bit words in the float. */ | |
150 | long *exponent_bitsP) /* Number of exponent bits. */ | |
252b5132 | 151 | { |
4d5f9b2a | 152 | int retval; |
252b5132 RH |
153 | |
154 | retval = 0; | |
155 | switch (letter) | |
156 | { | |
157 | case 'f': | |
158 | *precisionP = F_PRECISION; | |
159 | *exponent_bitsP = 8; | |
160 | break; | |
161 | ||
162 | case 'd': | |
163 | *precisionP = D_PRECISION; | |
164 | *exponent_bitsP = 8; | |
165 | break; | |
166 | ||
167 | case 'g': | |
168 | *precisionP = G_PRECISION; | |
169 | *exponent_bitsP = 11; | |
170 | break; | |
171 | ||
172 | case 'h': | |
173 | *precisionP = H_PRECISION; | |
174 | *exponent_bitsP = 15; | |
175 | break; | |
176 | ||
177 | default: | |
178 | retval = 69; | |
179 | break; | |
180 | } | |
4d5f9b2a | 181 | return retval; |
252b5132 RH |
182 | } |
183 | \f | |
4d5f9b2a NC |
184 | /* Warning: this returns 16-bit LITTLENUMs, because that is |
185 | what the VAX thinks in. It is up to the caller to figure | |
186 | out any alignment problems and to conspire for the bytes/word | |
187 | to be emitted in the right order. Bigendians beware! */ | |
188 | ||
189 | static char * | |
190 | atof_vax (char *str, /* Text to convert to binary. */ | |
191 | int what_kind, /* 'd', 'f', 'g', 'h' */ | |
192 | LITTLENUM_TYPE *words) /* Build the binary here. */ | |
252b5132 RH |
193 | { |
194 | FLONUM_TYPE f; | |
195 | LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD]; | |
4d5f9b2a NC |
196 | /* Extra bits for zeroed low-order bits. |
197 | The 1st MAX_PRECISION are zeroed, | |
198 | the last contain flonum bits. */ | |
252b5132 | 199 | char *return_value; |
4a1805b1 | 200 | int precision; /* Number of 16-bit words in the format. */ |
252b5132 RH |
201 | long exponent_bits; |
202 | ||
203 | return_value = str; | |
204 | f.low = bits + MAX_PRECISION; | |
205 | f.high = NULL; | |
206 | f.leader = NULL; | |
207 | f.exponent = 0; | |
208 | f.sign = '\0'; | |
209 | ||
210 | if (what_kind_of_float (what_kind, &precision, &exponent_bits)) | |
211 | { | |
4d5f9b2a | 212 | return_value = NULL; |
252b5132 RH |
213 | make_invalid_floating_point_number (words); |
214 | } | |
215 | ||
216 | if (return_value) | |
217 | { | |
218 | memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION); | |
219 | ||
4d5f9b2a NC |
220 | /* Use more LittleNums than seems |
221 | necessary: the highest flonum may have | |
222 | 15 leading 0 bits, so could be useless. */ | |
252b5132 RH |
223 | f.high = f.low + precision - 1 + GUARD; |
224 | ||
225 | if (atof_generic (&return_value, ".", "eE", &f)) | |
226 | { | |
227 | make_invalid_floating_point_number (words); | |
4d5f9b2a | 228 | return_value = NULL; |
252b5132 | 229 | } |
4d5f9b2a NC |
230 | else if (flonum_gen2vax (what_kind, &f, words)) |
231 | return_value = NULL; | |
252b5132 | 232 | } |
4d5f9b2a NC |
233 | |
234 | return return_value; | |
235 | } | |
252b5132 | 236 | \f |
4d5f9b2a NC |
237 | /* In: a flonum, a vax floating point format. |
238 | Out: a vax floating-point bit pattern. */ | |
239 | ||
240 | int | |
241 | flonum_gen2vax (int format_letter, /* One of 'd' 'f' 'g' 'h'. */ | |
242 | FLONUM_TYPE *f, | |
243 | LITTLENUM_TYPE *words) /* Deliver answer here. */ | |
252b5132 RH |
244 | { |
245 | LITTLENUM_TYPE *lp; | |
246 | int precision; | |
247 | long exponent_bits; | |
4a1805b1 | 248 | int return_value; /* 0 == OK. */ |
252b5132 RH |
249 | |
250 | return_value = what_kind_of_float (format_letter, &precision, &exponent_bits); | |
251 | ||
252 | if (return_value != 0) | |
4d5f9b2a NC |
253 | make_invalid_floating_point_number (words); |
254 | ||
252b5132 RH |
255 | else |
256 | { | |
257 | if (f->low > f->leader) | |
4d5f9b2a NC |
258 | /* 0.0e0 seen. */ |
259 | memset (words, '\0', sizeof (LITTLENUM_TYPE) * precision); | |
260 | ||
252b5132 RH |
261 | else |
262 | { | |
263 | long exponent_1; | |
264 | long exponent_2; | |
265 | long exponent_3; | |
266 | long exponent_4; | |
267 | int exponent_skippage; | |
268 | LITTLENUM_TYPE word1; | |
269 | ||
4d5f9b2a | 270 | /* JF: Deal with new Nan, +Inf and -Inf codes. */ |
252b5132 RH |
271 | if (f->sign != '-' && f->sign != '+') |
272 | { | |
273 | make_invalid_floating_point_number (words); | |
274 | return return_value; | |
275 | } | |
4d5f9b2a NC |
276 | |
277 | /* All vaxen floating_point formats (so far) have: | |
278 | Bit 15 is sign bit. | |
279 | Bits 14:n are excess-whatever exponent. | |
280 | Bits n-1:0 (if any) are most significant bits of fraction. | |
281 | Bits 15:0 of the next word are the next most significant bits. | |
282 | And so on for each other word. | |
283 | ||
284 | All this to be compatible with a KF11?? (Which is still faster | |
285 | than lots of vaxen I can think of, but it also has higher | |
286 | maintenance costs ... sigh). | |
287 | ||
288 | So we need: number of bits of exponent, number of bits of | |
289 | mantissa. */ | |
252b5132 RH |
290 | |
291 | bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS; | |
292 | littlenum_pointer = f->leader; | |
293 | littlenum_end = f->low; | |
4d5f9b2a | 294 | /* Seek (and forget) 1st significant bit. */ |
252b5132 RH |
295 | for (exponent_skippage = 0; |
296 | !next_bits (1); | |
5bb3703f | 297 | exponent_skippage++); |
252b5132 RH |
298 | |
299 | exponent_1 = f->exponent + f->leader + 1 - f->low; | |
4a1805b1 | 300 | /* Radix LITTLENUM_RADIX, point just higher than f->leader. */ |
252b5132 | 301 | exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS; |
4a1805b1 | 302 | /* Radix 2. */ |
252b5132 | 303 | exponent_3 = exponent_2 - exponent_skippage; |
4a1805b1 | 304 | /* Forget leading zeros, forget 1st bit. */ |
252b5132 | 305 | exponent_4 = exponent_3 + (1 << (exponent_bits - 1)); |
4a1805b1 | 306 | /* Offset exponent. */ |
252b5132 RH |
307 | |
308 | if (exponent_4 & ~mask[exponent_bits]) | |
309 | { | |
4d5f9b2a | 310 | /* Exponent overflow. Lose immediately. */ |
252b5132 RH |
311 | make_invalid_floating_point_number (words); |
312 | ||
4d5f9b2a NC |
313 | /* We leave return_value alone: admit we read the |
314 | number, but return a floating exception | |
315 | because we can't encode the number. */ | |
252b5132 RH |
316 | } |
317 | else | |
318 | { | |
319 | lp = words; | |
320 | ||
4d5f9b2a NC |
321 | /* Word 1. Sign, exponent and perhaps high bits. |
322 | Assume 2's complement integers. */ | |
252b5132 RH |
323 | word1 = (((exponent_4 & mask[exponent_bits]) << (15 - exponent_bits)) |
324 | | ((f->sign == '+') ? 0 : 0x8000) | |
325 | | next_bits (15 - exponent_bits)); | |
326 | *lp++ = word1; | |
327 | ||
4a1805b1 | 328 | /* The rest of the words are just mantissa bits. */ |
252b5132 | 329 | for (; lp < words + precision; lp++) |
4d5f9b2a | 330 | *lp = next_bits (LITTLENUM_NUMBER_OF_BITS); |
252b5132 RH |
331 | |
332 | if (next_bits (1)) | |
333 | { | |
4d5f9b2a NC |
334 | /* Since the NEXT bit is a 1, round UP the mantissa. |
335 | The cunning design of these hidden-1 floats permits | |
336 | us to let the mantissa overflow into the exponent, and | |
337 | it 'does the right thing'. However, we lose if the | |
338 | highest-order bit of the lowest-order word flips. | |
339 | Is that clear? */ | |
252b5132 RH |
340 | unsigned long carry; |
341 | ||
342 | /* | |
4d5f9b2a NC |
343 | #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2) |
344 | Please allow at least 1 more bit in carry than is in a LITTLENUM. | |
345 | We need that extra bit to hold a carry during a LITTLENUM carry | |
346 | propagation. Another extra bit (kept 0) will assure us that we | |
347 | don't get a sticky sign bit after shifting right, and that | |
348 | permits us to propagate the carry without any masking of bits. | |
349 | #endif */ | |
252b5132 RH |
350 | for (carry = 1, lp--; |
351 | carry && (lp >= words); | |
352 | lp--) | |
353 | { | |
354 | carry = *lp + carry; | |
355 | *lp = carry; | |
356 | carry >>= LITTLENUM_NUMBER_OF_BITS; | |
357 | } | |
358 | ||
359 | if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1))) | |
360 | { | |
361 | make_invalid_floating_point_number (words); | |
4d5f9b2a NC |
362 | /* We leave return_value alone: admit we read the |
363 | number, but return a floating exception | |
364 | because we can't encode the number. */ | |
252b5132 | 365 | } |
4d5f9b2a NC |
366 | } |
367 | } | |
368 | } | |
369 | } | |
370 | return return_value; | |
371 | } | |
372 | ||
373 | /* JF this used to be in vax.c but this looks like a better place for it. */ | |
374 | ||
375 | /* In: input_line_pointer->the 1st character of a floating-point | |
376 | number. | |
377 | 1 letter denoting the type of statement that wants a | |
378 | binary floating point number returned. | |
379 | Address of where to build floating point literal. | |
380 | Assumed to be 'big enough'. | |
381 | Address of where to return size of literal (in chars). | |
3739860c | 382 | |
4d5f9b2a NC |
383 | Out: Input_line_pointer->of next char after floating number. |
384 | Error message, or 0. | |
385 | Floating point literal. | |
386 | Number of chars we used for the literal. */ | |
387 | ||
388 | #define MAXIMUM_NUMBER_OF_LITTLENUMS 8 /* For .hfloats. */ | |
252b5132 | 389 | |
6d4af3c2 | 390 | const char * |
499ac353 NC |
391 | vax_md_atof (int what_statement_type, |
392 | char *literalP, | |
393 | int *sizeP) | |
252b5132 RH |
394 | { |
395 | LITTLENUM_TYPE words[MAXIMUM_NUMBER_OF_LITTLENUMS]; | |
4d5f9b2a | 396 | char kind_of_float; |
541d2ffd | 397 | unsigned int number_of_chars; |
4d5f9b2a | 398 | LITTLENUM_TYPE *littlenumP; |
252b5132 RH |
399 | |
400 | switch (what_statement_type) | |
401 | { | |
4d5f9b2a NC |
402 | case 'F': |
403 | case 'f': | |
252b5132 RH |
404 | kind_of_float = 'f'; |
405 | break; | |
406 | ||
4d5f9b2a NC |
407 | case 'D': |
408 | case 'd': | |
252b5132 RH |
409 | kind_of_float = 'd'; |
410 | break; | |
411 | ||
4d5f9b2a | 412 | case 'g': |
252b5132 RH |
413 | kind_of_float = 'g'; |
414 | break; | |
415 | ||
4d5f9b2a | 416 | case 'h': |
252b5132 RH |
417 | kind_of_float = 'h'; |
418 | break; | |
419 | ||
420 | default: | |
421 | kind_of_float = 0; | |
422 | break; | |
423 | }; | |
424 | ||
425 | if (kind_of_float) | |
426 | { | |
4d5f9b2a | 427 | LITTLENUM_TYPE *limit; |
252b5132 RH |
428 | |
429 | input_line_pointer = atof_vax (input_line_pointer, | |
430 | kind_of_float, | |
431 | words); | |
4d5f9b2a NC |
432 | /* The atof_vax() builds up 16-bit numbers. |
433 | Since the assembler may not be running on | |
434 | a little-endian machine, be very careful about | |
435 | converting words to chars. */ | |
252b5132 | 436 | number_of_chars = atof_vax_sizeof (kind_of_float); |
541d2ffd | 437 | know (number_of_chars <= MAXIMUM_NUMBER_OF_LITTLENUMS * sizeof (LITTLENUM_TYPE)); |
252b5132 RH |
438 | limit = words + (number_of_chars / sizeof (LITTLENUM_TYPE)); |
439 | for (littlenumP = words; littlenumP < limit; littlenumP++) | |
440 | { | |
441 | md_number_to_chars (literalP, *littlenumP, sizeof (LITTLENUM_TYPE)); | |
442 | literalP += sizeof (LITTLENUM_TYPE); | |
443 | }; | |
444 | } | |
445 | else | |
4d5f9b2a | 446 | number_of_chars = 0; |
252b5132 RH |
447 | |
448 | *sizeP = number_of_chars; | |
499ac353 | 449 | return kind_of_float ? NULL : _("Unrecognized or unsupported floating point constant"); |
252b5132 | 450 | } |