blob: 64a77b86c60e0772b759db31263aef7b821ec8c6 [file] [log] [blame]
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001/* float.c floating-point constant support for the Netwide Assembler
2 *
3 * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
4 * Julian Hall. All rights reserved. The software is
5 * redistributable under the licence given in the file "Licence"
6 * distributed in the NASM archive.
7 *
8 * initial version 13/ix/96 by Simon Tatham
9 */
10
H. Peter Anvinfe501952007-10-02 21:53:51 -070011#include "compiler.h"
12
H. Peter Anvinfe2177f2007-09-18 18:31:26 -070013#include <ctype.h>
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000014#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
Keith Kaniosb7a89542007-04-12 02:40:54 +000017#include <inttypes.h>
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000018
19#include "nasm.h"
20
21#define TRUE 1
22#define FALSE 0
23
H. Peter Anvine31747e2007-09-18 17:50:34 -070024#define MANT_WORDS 10 /* 112 bits + 48 for accuracy == 160 */
25#define MANT_DIGITS 49 /* 50 digits don't fit in 160 bits */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000026
27/*
28 * guaranteed top bit of from is set
29 * => we only have to worry about _one_ bit shift to the left
30 */
31
Keith Kaniosb7a89542007-04-12 02:40:54 +000032static int ieee_multiply(uint16_t *to, uint16_t *from)
H. Peter Anvineba20a72002-04-30 20:53:55 +000033{
Keith Kaniosb7a89542007-04-12 02:40:54 +000034 uint32_t temp[MANT_WORDS * 2];
H. Peter Anvine2c80182005-01-15 22:15:51 +000035 int i, j;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000036
H. Peter Anvine2c80182005-01-15 22:15:51 +000037 for (i = 0; i < MANT_WORDS * 2; i++)
38 temp[i] = 0;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000039
H. Peter Anvine2c80182005-01-15 22:15:51 +000040 for (i = 0; i < MANT_WORDS; i++)
41 for (j = 0; j < MANT_WORDS; j++) {
Keith Kaniosb7a89542007-04-12 02:40:54 +000042 uint32_t n;
43 n = (uint32_t)to[i] * (uint32_t)from[j];
H. Peter Anvine2c80182005-01-15 22:15:51 +000044 temp[i + j] += n >> 16;
45 temp[i + j + 1] += n & 0xFFFF;
46 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000047
H. Peter Anvine2c80182005-01-15 22:15:51 +000048 for (i = MANT_WORDS * 2; --i;) {
49 temp[i - 1] += temp[i] >> 16;
50 temp[i] &= 0xFFFF;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000051 }
52 if (temp[0] & 0x8000) {
H. Peter Anvine31747e2007-09-18 17:50:34 -070053 memcpy(to, temp, 2*MANT_WORDS);
54 return 0;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000055 } else {
H. Peter Anvine2c80182005-01-15 22:15:51 +000056 for (i = 0; i < MANT_WORDS; i++)
57 to[i] = (temp[i] << 1) + !!(temp[i + 1] & 0x8000);
58 return -1;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000059 }
60}
61
H. Peter Anvinfe2177f2007-09-18 18:31:26 -070062static int hexval(char c)
63{
64 if (c >= '0' && c <= '9')
65 return c-'0';
66 else if (c >= 'a' && c <= 'f')
67 return c-'a'+10;
68 else
69 return c-'A'+10;
70}
71
72static void ieee_flconvert_hex(char *string, uint16_t *mant,
73 int32_t *exponent, efunc error)
74{
75 static const int log2tbl[16] =
76 { -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 };
77 uint16_t mult[MANT_WORDS+1], *mp;
78 int ms;
79 int32_t twopwr;
80 int seendot, seendigit;
81 unsigned char c;
82
83 twopwr = 0;
84 seendot = seendigit = 0;
H. Peter Anvin82f9f632007-09-24 20:53:48 -070085 ms = 0;
86 mp = NULL;
H. Peter Anvinfe2177f2007-09-18 18:31:26 -070087
88 memset(mult, 0, sizeof mult);
89
90 while ((c = *string++) != '\0') {
91 if (c == '.') {
92 if (!seendot)
93 seendot = TRUE;
94 else {
95 error(ERR_NONFATAL,
96 "too many periods in floating-point constant");
97 return;
98 }
99 } else if (isxdigit(c)) {
100 int v = hexval(c);
101
102 if (!seendigit && v) {
103 int l = log2tbl[v];
104
105 seendigit = 1;
106 mp = mult;
107 ms = 15-l;
108
109 twopwr = seendot ? twopwr-4+l : l-3;
110 }
111
112 if (seendigit) {
113 if (ms <= 0) {
114 *mp |= v >> -ms;
115 mp++;
116 if (mp > &mult[MANT_WORDS])
117 mp = &mult[MANT_WORDS]; /* Guard slot */
118 ms += 16;
119 }
120 *mp |= v << ms;
121 ms -= 4;
122
123 if (!seendot)
124 twopwr += 4;
125 } else {
126 if (seendot)
127 twopwr -= 4;
128 }
129 } else if (c == 'p' || c == 'P') {
130 twopwr += atoi(string);
131 break;
132 } else {
133 error(ERR_NONFATAL,
134 "floating-point constant: `%c' is invalid character",
H. Peter Anvin26976a12007-09-18 18:33:17 -0700135 c);
H. Peter Anvinfe2177f2007-09-18 18:31:26 -0700136 return;
137 }
138 }
139
140 if (!seendigit) {
141 memset(mant, 0, 2*MANT_WORDS); /* Zero */
142 *exponent = 0;
143 } else {
144 memcpy(mant, mult, 2*MANT_WORDS);
145 *exponent = twopwr;
146 }
147}
148
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000149static void ieee_flconvert(char *string, uint16_t *mant,
Keith Kaniosb7a89542007-04-12 02:40:54 +0000150 int32_t *exponent, efunc error)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000151{
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000152 char digits[MANT_DIGITS];
153 char *p, *q, *r;
Keith Kaniosb7a89542007-04-12 02:40:54 +0000154 uint16_t mult[MANT_WORDS], bit;
155 uint16_t *m;
156 int32_t tenpwr, twopwr;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000157 int extratwos, started, seendot;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000158
H. Peter Anvinfe2177f2007-09-18 18:31:26 -0700159 if (string[0] == '0' && (string[1] == 'x' || string[1] == 'X')) {
160 ieee_flconvert_hex(string+2, mant, exponent, error);
161 return;
162 }
163
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000164 p = digits;
165 tenpwr = 0;
166 started = seendot = FALSE;
167 while (*string && *string != 'E' && *string != 'e') {
H. Peter Anvine2c80182005-01-15 22:15:51 +0000168 if (*string == '.') {
169 if (!seendot)
170 seendot = TRUE;
171 else {
172 error(ERR_NONFATAL,
173 "too many periods in floating-point constant");
174 return;
175 }
176 } else if (*string >= '0' && *string <= '9') {
177 if (*string == '0' && !started) {
178 if (seendot)
179 tenpwr--;
180 } else {
181 started = TRUE;
182 if (p < digits + sizeof(digits))
183 *p++ = *string - '0';
184 if (!seendot)
185 tenpwr++;
186 }
187 } else {
188 error(ERR_NONFATAL,
189 "floating-point constant: `%c' is invalid character",
190 *string);
191 return;
192 }
193 string++;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000194 }
195 if (*string) {
H. Peter Anvine2c80182005-01-15 22:15:51 +0000196 string++; /* eat the E */
197 tenpwr += atoi(string);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000198 }
199
200 /*
201 * At this point, the memory interval [digits,p) contains a
202 * series of decimal digits zzzzzzz such that our number X
203 * satisfies
204 *
205 * X = 0.zzzzzzz * 10^tenpwr
206 */
207
208 bit = 0x8000;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000209 for (m = mant; m < mant + MANT_WORDS; m++)
210 *m = 0;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000211 m = mant;
212 q = digits;
213 started = FALSE;
214 twopwr = 0;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000215 while (m < mant + MANT_WORDS) {
Keith Kaniosb7a89542007-04-12 02:40:54 +0000216 uint16_t carry = 0;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000217 while (p > q && !p[-1])
218 p--;
219 if (p <= q)
220 break;
221 for (r = p; r-- > q;) {
222 int i;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000223
H. Peter Anvine2c80182005-01-15 22:15:51 +0000224 i = 2 * *r + carry;
225 if (i >= 10)
226 carry = 1, i -= 10;
227 else
228 carry = 0;
229 *r = i;
230 }
231 if (carry)
232 *m |= bit, started = TRUE;
233 if (started) {
234 if (bit == 1)
235 bit = 0x8000, m++;
236 else
237 bit >>= 1;
238 } else
239 twopwr--;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000240 }
241 twopwr += tenpwr;
242
243 /*
244 * At this point the `mant' array contains the first six
245 * fractional places of a base-2^16 real number, which when
246 * multiplied by 2^twopwr and 5^tenpwr gives X. So now we
247 * really do multiply by 5^tenpwr.
248 */
249
250 if (tenpwr < 0) {
H. Peter Anvine2c80182005-01-15 22:15:51 +0000251 for (m = mult; m < mult + MANT_WORDS; m++)
252 *m = 0xCCCC;
253 extratwos = -2;
254 tenpwr = -tenpwr;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000255 } else if (tenpwr > 0) {
H. Peter Anvine2c80182005-01-15 22:15:51 +0000256 mult[0] = 0xA000;
257 for (m = mult + 1; m < mult + MANT_WORDS; m++)
258 *m = 0;
259 extratwos = 3;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000260 } else
H. Peter Anvine2c80182005-01-15 22:15:51 +0000261 extratwos = 0;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000262 while (tenpwr) {
H. Peter Anvine2c80182005-01-15 22:15:51 +0000263 if (tenpwr & 1)
264 twopwr += extratwos + ieee_multiply(mant, mult);
265 extratwos = extratwos * 2 + ieee_multiply(mult, mult);
266 tenpwr >>= 1;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000267 }
268
269 /*
270 * Conversion is done. The elements of `mant' contain the first
271 * fractional places of a base-2^16 real number in [0.5,1)
272 * which we can multiply by 2^twopwr to get X. Or, of course,
273 * it contains zero.
274 */
275 *exponent = twopwr;
276}
277
278/*
279 * Shift a mantissa to the right by i (i < 16) bits.
280 */
Keith Kaniosb7a89542007-04-12 02:40:54 +0000281static void ieee_shr(uint16_t *mant, int i)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000282{
Keith Kaniosb7a89542007-04-12 02:40:54 +0000283 uint16_t n = 0, m;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000284 int j;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000285
H. Peter Anvine2c80182005-01-15 22:15:51 +0000286 for (j = 0; j < MANT_WORDS; j++) {
287 m = (mant[j] << (16 - i)) & 0xFFFF;
288 mant[j] = (mant[j] >> i) | n;
289 n = m;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000290 }
291}
292
293/*
294 * Round a mantissa off after i words.
295 */
Keith Kaniosb7a89542007-04-12 02:40:54 +0000296static int ieee_round(uint16_t *mant, int i)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000297{
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000298 if (mant[i] & 0x8000) {
H. Peter Anvine2c80182005-01-15 22:15:51 +0000299 do {
300 ++mant[--i];
301 mant[i] &= 0xFFFF;
302 } while (i > 0 && !mant[i]);
303 return !i && !mant[i];
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000304 }
305 return 0;
306}
307
308#define put(a,b) ( (*(a)=(b)), ((a)[1]=(b)>>8) )
309
H. Peter Anvinf48bc6f2007-09-18 21:55:56 -0700310/* Set a bit, using *bigendian* bit numbering (0 = MSB) */
311static void set_bit(uint16_t *mant, int bit)
312{
313 mant[bit >> 4] |= 1 << (~bit & 15);
314}
315
H. Peter Anvine31747e2007-09-18 17:50:34 -0700316/* Produce standard IEEE formats, with implicit "1" bit; this makes
317 the following assumptions:
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000318
H. Peter Anvine31747e2007-09-18 17:50:34 -0700319 - the sign bit is the MSB, followed by the exponent.
320 - the sign bit plus exponent fit in 16 bits.
321 - the exponent bias is 2^(n-1)-1 for an n-bit exponent */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000322
H. Peter Anvine31747e2007-09-18 17:50:34 -0700323struct ieee_format {
324 int words;
325 int mantissa; /* Bits in the mantissa */
326 int exponent; /* Bits in the exponent */
327};
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000328
H. Peter Anvine31747e2007-09-18 17:50:34 -0700329static const struct ieee_format ieee_16 = { 1, 10, 5 };
330static const struct ieee_format ieee_32 = { 2, 23, 8 };
331static const struct ieee_format ieee_64 = { 4, 52, 11 };
332static const struct ieee_format ieee_128 = { 8, 112, 15 };
333
334/* Produce all the standard IEEE formats: 16, 32, 64, and 128 bits */
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000335static int to_float(char *str, int32_t sign, uint8_t *result,
H. Peter Anvine31747e2007-09-18 17:50:34 -0700336 const struct ieee_format *fmt, efunc error)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000337{
H. Peter Anvine31747e2007-09-18 17:50:34 -0700338 uint16_t mant[MANT_WORDS], *mp;
Keith Kaniosb7a89542007-04-12 02:40:54 +0000339 int32_t exponent;
H. Peter Anvine31747e2007-09-18 17:50:34 -0700340 int32_t expmax = 1 << (fmt->exponent-1);
341 uint16_t implicit_one = 0x8000 >> fmt->exponent;
342 int i;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000343
344 sign = (sign < 0 ? 0x8000L : 0L);
345
H. Peter Anvinf48bc6f2007-09-18 21:55:56 -0700346 if (str[0] == '_') {
347 /* NaN or Infinity */
348 int32_t expmask = (1 << fmt->exponent)-1;
H. Peter Anvine31747e2007-09-18 17:50:34 -0700349
H. Peter Anvinf48bc6f2007-09-18 21:55:56 -0700350 memset(mant, 0, sizeof mant);
351 mant[0] = expmask << (15-fmt->exponent); /* Exponent: all bits one */
H. Peter Anvine31747e2007-09-18 17:50:34 -0700352
H. Peter Anvinf48bc6f2007-09-18 21:55:56 -0700353 switch (str[2]) {
354 case 'n': /* __nan__ */
355 case 'N':
356 case 'q': /* __qnan__ */
357 case 'Q':
358 set_bit(mant, fmt->exponent+1); /* Highest bit in mantissa */
359 break;
360 case 's': /* __snan__ */
361 case 'S':
362 set_bit(mant, fmt->exponent+fmt->mantissa); /* Last bit */
363 break;
364 case 'i': /* __infinity__ */
365 case 'I':
366 break;
367 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000368 } else {
H. Peter Anvinf48bc6f2007-09-18 21:55:56 -0700369 ieee_flconvert(str, mant, &exponent, error);
370 if (mant[0] & 0x8000) {
371 /*
372 * Non-zero.
373 */
374 exponent--;
375 if (exponent >= 2-expmax && exponent <= expmax) {
376 /*
377 * Normalised.
378 */
379 exponent += expmax;
380 ieee_shr(mant, fmt->exponent);
381 ieee_round(mant, fmt->words);
382 /* did we scale up by one? */
383 if (mant[0] & (implicit_one << 1)) {
384 ieee_shr(mant, 1);
385 exponent++;
386 }
387
388 mant[0] &= (implicit_one-1); /* remove leading one */
389 mant[0] |= exponent << (15 - fmt->exponent);
390 } else if (exponent < 2-expmax &&
391 exponent >= 2-expmax-fmt->mantissa) {
392 /*
393 * Denormal.
394 */
395 int shift = -(exponent + expmax-2-fmt->exponent);
396 int sh = shift % 16, wds = shift / 16;
397 ieee_shr(mant, sh);
398 if (ieee_round(mant, fmt->words - wds)
399 || (sh > 0 && (mant[0] & (0x8000 >> (sh - 1))))) {
400 ieee_shr(mant, 1);
401 if (sh == 0)
402 mant[0] |= 0x8000;
403 exponent++;
404 }
405
406 if (wds) {
407 for (i = fmt->words-1; i >= wds; i--)
408 mant[i] = mant[i-wds];
409 for (; i >= 0; i--)
410 mant[i] = 0;
411 }
412 } else {
413 if (exponent > 0) {
414 error(ERR_NONFATAL, "overflow in floating-point constant");
415 return 0;
416 } else {
417 memset(mant, 0, 2*fmt->words);
418 }
419 }
420 } else {
421 /* Zero */
422 memset(mant, 0, 2*fmt->words);
423 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000424 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000425
H. Peter Anvine31747e2007-09-18 17:50:34 -0700426 mant[0] |= sign;
H. Peter Anvin141d7cf2007-09-18 16:39:03 -0700427
H. Peter Anvine31747e2007-09-18 17:50:34 -0700428 for (mp = &mant[fmt->words], i = 0; i < fmt->words; i++) {
429 uint16_t m = *--mp;
430 put(result, m);
431 result += 2;
H. Peter Anvin141d7cf2007-09-18 16:39:03 -0700432 }
H. Peter Anvine31747e2007-09-18 17:50:34 -0700433
434 return 1; /* success */
H. Peter Anvin141d7cf2007-09-18 16:39:03 -0700435}
436
437/* 80-bit format with 64-bit mantissa *including an explicit integer 1*
438 and 15-bit exponent. */
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000439static int to_ldoub(char *str, int32_t sign, uint8_t *result,
H. Peter Anvine2c80182005-01-15 22:15:51 +0000440 efunc error)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000441{
Keith Kaniosb7a89542007-04-12 02:40:54 +0000442 uint16_t mant[MANT_WORDS];
443 int32_t exponent;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000444
445 sign = (sign < 0 ? 0x8000L : 0L);
446
H. Peter Anvinf48bc6f2007-09-18 21:55:56 -0700447 if (str[0] == '_') {
448 uint16_t is_snan = 0, is_qnan = 0x8000;
449 switch (str[2]) {
450 case 'n':
451 case 'N':
452 case 'q':
453 case 'Q':
454 is_qnan = 0xc000;
455 break;
456 case 's':
457 case 'S':
458 is_snan = 1;
459 break;
460 case 'i':
461 case 'I':
462 break;
463 }
464 put(result + 0, is_snan);
465 put(result + 2, 0);
466 put(result + 4, 0);
467 put(result + 6, is_qnan);
468 put(result + 8, 0x7fff|sign);
469 return 1;
470 }
471
H. Peter Anvine2c80182005-01-15 22:15:51 +0000472 ieee_flconvert(str, mant, &exponent, error);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000473 if (mant[0] & 0x8000) {
H. Peter Anvine2c80182005-01-15 22:15:51 +0000474 /*
475 * Non-zero.
476 */
477 exponent--;
478 if (exponent >= -16383 && exponent <= 16384) {
479 /*
480 * Normalised.
481 */
482 exponent += 16383;
483 if (ieee_round(mant, 4)) /* did we scale up by one? */
484 ieee_shr(mant, 1), mant[0] |= 0x8000, exponent++;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000485 put(result + 0, mant[3]);
H. Peter Anvinf48bc6f2007-09-18 21:55:56 -0700486 put(result + 2, mant[2]);
487 put(result + 4, mant[1]);
488 put(result + 6, mant[0]);
489 put(result + 8, exponent | sign);
H. Peter Anvine2c80182005-01-15 22:15:51 +0000490 } else if (exponent < -16383 && exponent >= -16446) {
491 /*
492 * Denormal.
493 */
494 int shift = -(exponent + 16383);
495 int sh = shift % 16, wds = shift / 16;
496 ieee_shr(mant, sh);
497 if (ieee_round(mant, 4 - wds)
498 || (sh > 0 && (mant[0] & (0x8000 >> (sh - 1))))) {
499 ieee_shr(mant, 1);
500 if (sh == 0)
501 mant[0] |= 0x8000;
502 exponent++;
503 }
H. Peter Anvine2c80182005-01-15 22:15:51 +0000504 put(result + 0, (wds <= 3 ? mant[3 - wds] : 0));
H. Peter Anvinf48bc6f2007-09-18 21:55:56 -0700505 put(result + 2, (wds <= 2 ? mant[2 - wds] : 0));
506 put(result + 4, (wds <= 1 ? mant[1 - wds] : 0));
507 put(result + 6, (wds == 0 ? mant[0] : 0));
508 put(result + 8, sign);
H. Peter Anvine2c80182005-01-15 22:15:51 +0000509 } else {
510 if (exponent > 0) {
511 error(ERR_NONFATAL, "overflow in floating-point constant");
512 return 0;
H. Peter Anvinf48bc6f2007-09-18 21:55:56 -0700513 } else {
514 goto zero;
515 }
H. Peter Anvine2c80182005-01-15 22:15:51 +0000516 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000517 } else {
H. Peter Anvine2c80182005-01-15 22:15:51 +0000518 /*
519 * Zero.
520 */
H. Peter Anvinf48bc6f2007-09-18 21:55:56 -0700521 zero:
522 put(result + 0, 0);
523 put(result + 2, 0);
524 put(result + 4, 0);
525 put(result + 6, 0);
526 put(result + 8, sign);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000527 }
528 return 1;
529}
530
Keith Kaniosa6dfa782007-04-13 16:47:53 +0000531int float_const(char *number, int32_t sign, uint8_t *result, int bytes,
H. Peter Anvine2c80182005-01-15 22:15:51 +0000532 efunc error)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000533{
H. Peter Anvin141d7cf2007-09-18 16:39:03 -0700534 switch (bytes) {
535 case 2:
H. Peter Anvine31747e2007-09-18 17:50:34 -0700536 return to_float(number, sign, result, &ieee_16, error);
H. Peter Anvin141d7cf2007-09-18 16:39:03 -0700537 case 4:
H. Peter Anvine31747e2007-09-18 17:50:34 -0700538 return to_float(number, sign, result, &ieee_32, error);
H. Peter Anvin141d7cf2007-09-18 16:39:03 -0700539 case 8:
H. Peter Anvine31747e2007-09-18 17:50:34 -0700540 return to_float(number, sign, result, &ieee_64, error);
H. Peter Anvin141d7cf2007-09-18 16:39:03 -0700541 case 10:
H. Peter Anvine2c80182005-01-15 22:15:51 +0000542 return to_ldoub(number, sign, result, error);
H. Peter Anvine31747e2007-09-18 17:50:34 -0700543 case 16:
544 return to_float(number, sign, result, &ieee_128, error);
H. Peter Anvin141d7cf2007-09-18 16:39:03 -0700545 default:
H. Peter Anvine2c80182005-01-15 22:15:51 +0000546 error(ERR_PANIC, "strange value %d passed to float_const", bytes);
547 return 0;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000548 }
549}