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