* config/tc-mips.c (mips_ip): Permit non constant expressions in
[deliverable/binutils-gdb.git] / gas / config / atof-ns32k.c
CommitLineData
c82711bd
RP
1/* atof_ns32k.c - turn a Flonum into a ns32k floating point number
2 Copyright (C) 1987 Free Software Foundation, Inc.
3
4This file is part of GAS, the GNU Assembler.
5
6GAS is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 1, or (at your option)
9any later version.
10
11GAS is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GAS; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20/* this is atof-m68k.c hacked for ns32k */
21
22#include "as.h"
23
355afbcd 24extern FLONUM_TYPE generic_floating_point_number; /* Flonums returned here. */
c82711bd 25
587c4264 26extern const char EXP_CHARS[];
355afbcd 27/* Precision in LittleNums. */
c82711bd
RP
28#define MAX_PRECISION (4)
29#define F_PRECISION (2)
30#define D_PRECISION (4)
31
355afbcd 32/* Length in LittleNums of guard bits. */
c82711bd
RP
33#define GUARD (2)
34
35int /* Number of chars in flonum type 'letter'. */
36atof_sizeof (letter)
37 char letter;
38{
355afbcd 39 int return_value;
c82711bd
RP
40
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 */
46 switch (letter)
47 {
48 case 'f':
49 return_value = F_PRECISION;
50 break;
51
52 case 'd':
53 return_value = D_PRECISION;
54 break;
55
56 default:
57 return_value = 0;
58 break;
59 }
60 return (return_value);
61}
62
355afbcd
KR
63static unsigned long int mask[] =
64{
c82711bd
RP
65 0x00000000,
66 0x00000001,
67 0x00000003,
68 0x00000007,
69 0x0000000f,
70 0x0000001f,
71 0x0000003f,
72 0x0000007f,
73 0x000000ff,
74 0x000001ff,
75 0x000003ff,
76 0x000007ff,
77 0x00000fff,
78 0x00001fff,
79 0x00003fff,
80 0x00007fff,
81 0x0000ffff,
82 0x0001ffff,
83 0x0003ffff,
84 0x0007ffff,
85 0x000fffff,
86 0x001fffff,
87 0x003fffff,
88 0x007fffff,
89 0x00ffffff,
90 0x01ffffff,
91 0x03ffffff,
92 0x07ffffff,
93 0x0fffffff,
94 0x1fffffff,
95 0x3fffffff,
96 0x7fffffff,
97 0xffffffff
355afbcd 98};
c82711bd
RP
99\f
100static int bits_left_in_littlenum;
101static int littlenums_left;
355afbcd 102static LITTLENUM_TYPE *littlenum_pointer;
c82711bd
RP
103
104static int
105next_bits (number_of_bits)
355afbcd 106 int number_of_bits;
c82711bd 107{
355afbcd 108 int return_value;
c82711bd 109
355afbcd
KR
110 if (!littlenums_left)
111 return 0;
c82711bd
RP
112 if (number_of_bits >= bits_left_in_littlenum)
113 {
355afbcd 114 return_value = mask[bits_left_in_littlenum] & *littlenum_pointer;
c82711bd
RP
115 number_of_bits -= bits_left_in_littlenum;
116 return_value <<= number_of_bits;
355afbcd
KR
117 if (littlenums_left)
118 {
119 bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits;
120 littlenum_pointer--;
121 --littlenums_left;
122 return_value |= (*littlenum_pointer >> bits_left_in_littlenum) & mask[number_of_bits];
123 }
c82711bd
RP
124 }
125 else
126 {
127 bits_left_in_littlenum -= number_of_bits;
355afbcd 128 return_value = mask[number_of_bits] & (*littlenum_pointer >> bits_left_in_littlenum);
c82711bd
RP
129 }
130 return (return_value);
131}
132
133static void
134make_invalid_floating_point_number (words)
355afbcd 135 LITTLENUM_TYPE *words;
c82711bd 136{
355afbcd
KR
137 words[0] = ((unsigned) -1) >> 1; /* Zero the leftmost bit */
138 words[1] = -1;
139 words[2] = -1;
140 words[3] = -1;
c82711bd
RP
141}
142\f
143/***********************************************************************\
144* *
145* Warning: this returns 16-bit LITTLENUMs, because that is *
146* what the VAX thinks in. It is up to the caller to figure *
147* out any alignment problems and to conspire for the bytes/word *
148* to be emitted in the right order. Bigendians beware! *
149* *
150\***********************************************************************/
151
152char * /* Return pointer past text consumed. */
153atof_ns32k (str, what_kind, words)
355afbcd
KR
154 char *str; /* Text to convert to binary. */
155 char what_kind; /* 'd', 'f', 'g', 'h' */
156 LITTLENUM_TYPE *words; /* Build the binary here. */
c82711bd 157{
355afbcd
KR
158 FLONUM_TYPE f;
159 LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
160 /* Extra bits for zeroed low-order bits. */
161 /* The 1st MAX_PRECISION are zeroed, */
162 /* the last contain flonum bits. */
163 char *return_value;
164 int precision; /* Number of 16-bit words in the format. */
165 long int exponent_bits;
166
167 long int exponent_1;
168 long int exponent_2;
169 long int exponent_3;
170 long int exponent_4;
171 int exponent_skippage;
172 LITTLENUM_TYPE word1;
173 LITTLENUM_TYPE *lp;
174
175 return_value = str;
176 f.low = bits + MAX_PRECISION;
177 f.high = NULL;
178 f.leader = NULL;
179 f.exponent = NULL;
180 f.sign = '\0';
181
182 /* Use more LittleNums than seems */
183 /* necessary: the highest flonum may have */
184 /* 15 leading 0 bits, so could be useless. */
185
186 bzero (bits, sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
187
188 switch (what_kind)
189 {
190 case 'f':
191 precision = F_PRECISION;
192 exponent_bits = 8;
193 break;
c82711bd 194
355afbcd
KR
195 case 'd':
196 precision = D_PRECISION;
197 exponent_bits = 11;
198 break;
c82711bd 199
355afbcd
KR
200 default:
201 make_invalid_floating_point_number (words);
202 return NULL;
203 }
c82711bd 204
355afbcd 205 f.high = f.low + precision - 1 + GUARD;
c82711bd 206
355afbcd
KR
207 if (atof_generic (&return_value, ".", EXP_CHARS, &f))
208 {
209 as_warn ("Error converting floating point number (Exponent overflow?)");
210 make_invalid_floating_point_number (words);
211 return NULL;
212 }
213
214 if (f.low > f.leader)
215 {
216 /* 0.0e0 seen. */
217 bzero (words, sizeof (LITTLENUM_TYPE) * precision);
218 return return_value;
219 }
220
221 if (f.sign != '+' && f.sign != '-')
222 {
223 make_invalid_floating_point_number (words);
224 return NULL;
225 }
c82711bd
RP
226
227
355afbcd 228 /*
c82711bd
RP
229 * All vaxen floating_point formats (so far) have:
230 * Bit 15 is sign bit.
231 * Bits 14:n are excess-whatever exponent.
232 * Bits n-1:0 (if any) are most significant bits of fraction.
233 * Bits 15:0 of the next word are the next most significant bits.
234 * And so on for each other word.
235 *
236 * So we need: number of bits of exponent, number of bits of
237 * mantissa.
238 */
355afbcd
KR
239 bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
240 littlenum_pointer = f.leader;
241 littlenums_left = 1 + f.leader - f.low;
242 /* Seek (and forget) 1st significant bit */
243 for (exponent_skippage = 0; !next_bits (1); exponent_skippage++)
244 ;
245 exponent_1 = f.exponent + f.leader + 1 - f.low;
246 /* Radix LITTLENUM_RADIX, point just higher than f.leader. */
247 exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
248 /* Radix 2. */
249 exponent_3 = exponent_2 - exponent_skippage;
250 /* Forget leading zeros, forget 1st bit. */
251 exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2);
252 /* Offset exponent. */
253
254 if (exponent_4 & ~mask[exponent_bits])
255 {
256 /*
c82711bd
RP
257 * Exponent overflow. Lose immediately.
258 */
259
355afbcd 260 /*
c82711bd
RP
261 * We leave return_value alone: admit we read the
262 * number, but return a floating exception
263 * because we can't encode the number.
264 */
265
355afbcd
KR
266 as_warn ("Exponent overflow in floating-point number");
267 make_invalid_floating_point_number (words);
268 return return_value;
269 }
270 lp = words;
c82711bd 271
355afbcd
KR
272 /* Word 1. Sign, exponent and perhaps high bits. */
273 /* Assume 2's complement integers. */
274 word1 = ((exponent_4 & mask[exponent_bits]) << (15 - exponent_bits)) |
275 ((f.sign == '+') ? 0 : 0x8000) | next_bits (15 - exponent_bits);
276 *lp++ = word1;
c82711bd 277
355afbcd
KR
278 /* The rest of the words are just mantissa bits. */
279 for (; lp < words + precision; lp++)
280 *lp = next_bits (LITTLENUM_NUMBER_OF_BITS);
c82711bd 281
355afbcd
KR
282 if (next_bits (1))
283 {
284 unsigned long int carry;
285 /*
c82711bd
RP
286 * Since the NEXT bit is a 1, round UP the mantissa.
287 * The cunning design of these hidden-1 floats permits
288 * us to let the mantissa overflow into the exponent, and
289 * it 'does the right thing'. However, we lose if the
290 * highest-order bit of the lowest-order word flips.
291 * Is that clear?
292 */
293
294
355afbcd 295 /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
c82711bd
RP
296 Please allow at least 1 more bit in carry than is in a LITTLENUM.
297 We need that extra bit to hold a carry during a LITTLENUM carry
298 propagation. Another extra bit (kept 0) will assure us that we
299 don't get a sticky sign bit after shifting right, and that
300 permits us to propagate the carry without any masking of bits.
301#endif */
355afbcd
KR
302 for (carry = 1, lp--; carry && (lp >= words); lp--)
303 {
304 carry = *lp + carry;
305 *lp = carry;
306 carry >>= LITTLENUM_NUMBER_OF_BITS;
307 }
308 if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)))
309 {
310 /* We leave return_value alone: admit we read the
c82711bd
RP
311 * number, but return a floating exception
312 * because we can't encode the number.
313 */
355afbcd
KR
314 make_invalid_floating_point_number (words);
315 return return_value;
c82711bd 316 }
355afbcd
KR
317 }
318 return (return_value);
c82711bd
RP
319}
320
321/* This is really identical to atof_ns32k except for some details */
322
355afbcd
KR
323gen_to_words (words, precision, exponent_bits)
324 LITTLENUM_TYPE *words;
325 long int exponent_bits;
c82711bd 326{
355afbcd 327 int return_value = 0;
c82711bd 328
355afbcd
KR
329 long int exponent_1;
330 long int exponent_2;
331 long int exponent_3;
332 long int exponent_4;
333 int exponent_skippage;
334 LITTLENUM_TYPE word1;
335 LITTLENUM_TYPE *lp;
336
337 if (generic_floating_point_number.low > generic_floating_point_number.leader)
338 {
339 /* 0.0e0 seen. */
340 bzero (words, sizeof (LITTLENUM_TYPE) * precision);
341 return return_value;
342 }
343
344 /*
c82711bd
RP
345 * All vaxen floating_point formats (so far) have:
346 * Bit 15 is sign bit.
347 * Bits 14:n are excess-whatever exponent.
348 * Bits n-1:0 (if any) are most significant bits of fraction.
349 * Bits 15:0 of the next word are the next most significant bits.
350 * And so on for each other word.
351 *
352 * So we need: number of bits of exponent, number of bits of
353 * mantissa.
354 */
355afbcd
KR
355 bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
356 littlenum_pointer = generic_floating_point_number.leader;
357 littlenums_left = 1 + generic_floating_point_number.leader - generic_floating_point_number.low;
358 /* Seek (and forget) 1st significant bit */
359 for (exponent_skippage = 0; !next_bits (1); exponent_skippage++)
360 ;
361 exponent_1 = generic_floating_point_number.exponent + generic_floating_point_number.leader + 1 -
362 generic_floating_point_number.low;
363 /* Radix LITTLENUM_RADIX, point just higher than generic_floating_point_number.leader. */
364 exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
365 /* Radix 2. */
366 exponent_3 = exponent_2 - exponent_skippage;
367 /* Forget leading zeros, forget 1st bit. */
368 exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2);
369 /* Offset exponent. */
370
371 if (exponent_4 & ~mask[exponent_bits])
372 {
373 /*
c82711bd
RP
374 * Exponent overflow. Lose immediately.
375 */
376
355afbcd 377 /*
c82711bd
RP
378 * We leave return_value alone: admit we read the
379 * number, but return a floating exception
380 * because we can't encode the number.
381 */
382
355afbcd
KR
383 make_invalid_floating_point_number (words);
384 return return_value;
385 }
386 lp = words;
c82711bd 387
355afbcd
KR
388 /* Word 1. Sign, exponent and perhaps high bits. */
389 /* Assume 2's complement integers. */
390 word1 = ((exponent_4 & mask[exponent_bits]) << (15 - exponent_bits)) |
391 ((generic_floating_point_number.sign == '+') ? 0 : 0x8000) | next_bits (15 - exponent_bits);
392 *lp++ = word1;
c82711bd 393
355afbcd
KR
394 /* The rest of the words are just mantissa bits. */
395 for (; lp < words + precision; lp++)
396 *lp = next_bits (LITTLENUM_NUMBER_OF_BITS);
c82711bd 397
355afbcd
KR
398 if (next_bits (1))
399 {
400 unsigned long int carry;
401 /*
c82711bd
RP
402 * Since the NEXT bit is a 1, round UP the mantissa.
403 * The cunning design of these hidden-1 floats permits
404 * us to let the mantissa overflow into the exponent, and
405 * it 'does the right thing'. However, we lose if the
406 * highest-order bit of the lowest-order word flips.
407 * Is that clear?
408 */
409
410
355afbcd 411 /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
c82711bd
RP
412 Please allow at least 1 more bit in carry than is in a LITTLENUM.
413 We need that extra bit to hold a carry during a LITTLENUM carry
414 propagation. Another extra bit (kept 0) will assure us that we
415 don't get a sticky sign bit after shifting right, and that
416 permits us to propagate the carry without any masking of bits.
417#endif */
355afbcd
KR
418 for (carry = 1, lp--; carry && (lp >= words); lp--)
419 {
420 carry = *lp + carry;
421 *lp = carry;
422 carry >>= LITTLENUM_NUMBER_OF_BITS;
423 }
424 if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)))
425 {
426 /* We leave return_value alone: admit we read the
c82711bd
RP
427 * number, but return a floating exception
428 * because we can't encode the number.
429 */
355afbcd
KR
430 make_invalid_floating_point_number (words);
431 return return_value;
c82711bd 432 }
355afbcd
KR
433 }
434 return (return_value);
c82711bd
RP
435}
436
437/* This routine is a real kludge. Someone really should do it better, but
438 I'm too lazy, and I don't understand this stuff all too well anyway
439 (JF)
440 */
355afbcd
KR
441void
442int_to_gen (x)
443 long x;
c82711bd 444{
355afbcd
KR
445 char buf[20];
446 char *bufp;
c82711bd 447
355afbcd
KR
448 sprintf (buf, "%ld", x);
449 bufp = &buf[0];
450 if (atof_generic (&bufp, ".", EXP_CHARS, &generic_floating_point_number))
451 as_warn ("Error converting number to floating point (Exponent overflow?)");
c82711bd 452}
This page took 0.157239 seconds and 4 git commands to generate.