gas:
[deliverable/binutils-gdb.git] / gas / config / atof-vax.c
CommitLineData
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 34int flonum_gen2vax (int, FLONUM_TYPE *, LITTLENUM_TYPE *);
252b5132 35
4a1805b1 36/* Number of chars in flonum type 'letter'. */
4d5f9b2a 37
541d2ffd 38static unsigned int
4d5f9b2a 39atof_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
73static 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
112static int bits_left_in_littlenum;
113static LITTLENUM_TYPE *littlenum_pointer;
114static LITTLENUM_TYPE *littlenum_end;
115
116static int
4d5f9b2a 117next_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
141static void
4d5f9b2a 142make_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 148static int /* 0 means letter is OK. */
4d5f9b2a
NC
149what_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
190static char *
191atof_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
241int
242flonum_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
391char *
499ac353
NC
392vax_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}
This page took 0.536075 seconds and 4 git commands to generate.