1 /* ----------------------------------------------------------------------- *
2  *
3  *   Copyright 1996-2018 The NASM Authors - All Rights Reserved
4  *   See the file AUTHORS included with the NASM distribution for
5  *   the specific copyright holders.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following
9  *   conditions are met:
10  *
11  *   * Redistributions of source code must retain the above copyright
12  *     notice, this list of conditions and the following disclaimer.
13  *   * Redistributions in binary form must reproduce the above
14  *     copyright notice, this list of conditions and the following
15  *     disclaimer in the documentation and/or other materials provided
16  *     with the distribution.
17  *
18  *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19  *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20  *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21  *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23  *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * ----------------------------------------------------------------------- */
33 
34 /*
35  * float.c     floating-point constant support for the Netwide Assembler
36  */
37 
38 #include "compiler.h"
39 
40 #include "nctype.h"
41 
42 #include "nasm.h"
43 #include "floats.h"
44 #include "error.h"
45 
46 /*
47  * -----------------
48  *  local variables
49  * -----------------
50  */
51 static bool daz = false;        /* denormals as zero */
52 static enum float_round rc = FLOAT_RC_NEAR;     /* rounding control */
53 
54 /*
55  * -----------
56  *  constants
57  * -----------
58  */
59 
60 /* "A limb is like a digit but bigger */
61 typedef uint32_t fp_limb;
62 typedef uint64_t fp_2limb;
63 
64 #define LIMB_BITS       32
65 #define LIMB_BYTES      (LIMB_BITS/8)
66 #define LIMB_TOP_BIT    ((fp_limb)1 << (LIMB_BITS-1))
67 #define LIMB_MASK       ((fp_limb)(~0))
68 #define LIMB_ALL_BYTES  ((fp_limb)0x01010101)
69 #define LIMB_BYTE(x)    ((x)*LIMB_ALL_BYTES)
70 
71 /* 112 bits + 64 bits for accuracy + 16 bits for rounding */
72 #define MANT_LIMBS 6
73 
74 /* 52 digits fit in 176 bits because 10^53 > 2^176 > 10^52 */
75 #define MANT_DIGITS 52
76 
77 /* the format and the argument list depend on MANT_LIMBS */
78 #define MANT_FMT "%08x_%08x_%08x_%08x_%08x_%08x"
79 #define MANT_ARG SOME_ARG(mant, 0)
80 
81 #define SOME_ARG(a,i) (a)[(i)+0], (a)[(i)+1], (a)[(i)+2], \
82                       (a)[(i)+3], (a)[(i)+4], (a)[(i)+5]
83 
84 /*
85  * ---------------------------------------------------------------------------
86  *  emit a printf()-like debug message... but only if DEBUG_FLOAT was defined
87  * ---------------------------------------------------------------------------
88  */
89 
90 #ifdef DEBUG_FLOAT
91 #define dprintf(x) printf x
92 #else
93 #define dprintf(x) do { } while (0)
94 #endif
95 
96 /*
97  * ---------------------------------------------------------------------------
98  *  multiply
99  * ---------------------------------------------------------------------------
100  */
float_multiply(fp_limb * to,fp_limb * from)101 static int float_multiply(fp_limb *to, fp_limb *from)
102 {
103     fp_2limb temp[MANT_LIMBS * 2];
104     int i, j;
105 
106     /*
107      * guaranteed that top bit of 'from' is set -- so we only have
108      * to worry about _one_ bit shift to the left
109      */
110     dprintf(("%s=" MANT_FMT "\n", "mul1", SOME_ARG(to, 0)));
111     dprintf(("%s=" MANT_FMT "\n", "mul2", SOME_ARG(from, 0)));
112 
113     memset(temp, 0, sizeof temp);
114 
115     for (i = 0; i < MANT_LIMBS; i++) {
116         for (j = 0; j < MANT_LIMBS; j++) {
117             fp_2limb n;
118             n = (fp_2limb) to[i] * (fp_2limb) from[j];
119             temp[i + j] += n >> LIMB_BITS;
120             temp[i + j + 1] += (fp_limb)n;
121         }
122     }
123 
124     for (i = MANT_LIMBS * 2; --i;) {
125         temp[i - 1] += temp[i] >> LIMB_BITS;
126         temp[i] &= LIMB_MASK;
127     }
128 
129     dprintf(("%s=" MANT_FMT "_" MANT_FMT "\n", "temp", SOME_ARG(temp, 0),
130              SOME_ARG(temp, MANT_LIMBS)));
131 
132     if (temp[0] & LIMB_TOP_BIT) {
133         for (i = 0; i < MANT_LIMBS; i++) {
134             to[i] = temp[i] & LIMB_MASK;
135         }
136         dprintf(("%s=" MANT_FMT " (%i)\n", "prod", SOME_ARG(to, 0), 0));
137         return 0;
138     } else {
139         for (i = 0; i < MANT_LIMBS; i++) {
140             to[i] = (temp[i] << 1) + !!(temp[i + 1] & LIMB_TOP_BIT);
141         }
142         dprintf(("%s=" MANT_FMT " (%i)\n", "prod", SOME_ARG(to, 0), -1));
143         return -1;
144     }
145 }
146 
147 /*
148  * ---------------------------------------------------------------------------
149  *  read an exponent; returns INT32_MAX on error
150  * ---------------------------------------------------------------------------
151  */
read_exponent(const char * string,int32_t max)152 static int32_t read_exponent(const char *string, int32_t max)
153 {
154     int32_t i = 0;
155     bool neg = false;
156 
157     if (*string == '+') {
158         string++;
159     } else if (*string == '-') {
160         neg = true;
161         string++;
162     }
163     while (*string) {
164         if (*string >= '0' && *string <= '9') {
165             i = (i * 10) + (*string - '0');
166 
167             /*
168              * To ensure that underflows and overflows are
169              * handled properly we must avoid wraparounds of
170              * the signed integer value that is used to hold
171              * the exponent. Therefore we cap the exponent at
172              * +/-5000, which is slightly more/less than
173              * what's required for normal and denormal numbers
174              * in single, double, and extended precision, but
175              * sufficient to avoid signed integer wraparound.
176              */
177             if (i > max)
178                 i = max;
179         } else if (*string == '_') {
180             /* do nothing */
181         } else {
182             nasm_nonfatal("invalid character in floating-point constant %s: '%c'",
183                           "exponent", *string);
184             return INT32_MAX;
185         }
186         string++;
187     }
188 
189     return neg ? -i : i;
190 }
191 
192 /*
193  * ---------------------------------------------------------------------------
194  *  convert
195  * ---------------------------------------------------------------------------
196  */
ieee_flconvert(const char * string,fp_limb * mant,int32_t * exponent)197 static bool ieee_flconvert(const char *string, fp_limb *mant,
198                            int32_t * exponent)
199 {
200     char digits[MANT_DIGITS];
201     char *p, *q, *r;
202     fp_limb mult[MANT_LIMBS], bit;
203     fp_limb *m;
204     int32_t tenpwr, twopwr;
205     int32_t extratwos;
206     bool started, seendot, warned;
207 
208     warned = false;
209     p = digits;
210     tenpwr = 0;
211     started = seendot = false;
212 
213     while (*string && *string != 'E' && *string != 'e') {
214         if (*string == '.') {
215             if (!seendot) {
216                 seendot = true;
217             } else {
218                 nasm_nonfatal("too many periods in floating-point constant");
219                 return false;
220             }
221         } else if (*string >= '0' && *string <= '9') {
222             if (*string == '0' && !started) {
223                 if (seendot) {
224                     tenpwr--;
225                 }
226             } else {
227                 started = true;
228                 if (p < digits + sizeof(digits)) {
229                     *p++ = *string - '0';
230                 } else {
231                     if (!warned) {
232                         /*!
233                          *!float-toolong [on] too many digits in floating-point number
234                          *!  warns about too many digits in floating-point numbers.
235                          */
236                         nasm_warn(WARN_FLOAT_TOOLONG|ERR_PASS2,
237                                    "floating-point constant significand contains "
238                                    "more than %i digits", MANT_DIGITS);
239                         warned = true;
240                     }
241                 }
242                 if (!seendot) {
243                     tenpwr++;
244                 }
245             }
246         } else if (*string == '_') {
247             /* do nothing */
248         } else {
249             nasm_nonfatalf(ERR_PASS2,
250                            "invalid character in floating-point constant %s: '%c'",
251                            "significand", *string);
252             return false;
253         }
254         string++;
255     }
256 
257     if (*string) {
258         int32_t e;
259 
260         string++;               /* eat the E */
261         e = read_exponent(string, 5000);
262         if (e == INT32_MAX)
263             return false;
264         tenpwr += e;
265     }
266 
267     /*
268      * At this point, the memory interval [digits,p) contains a
269      * series of decimal digits zzzzzzz, such that our number X
270      * satisfies X = 0.zzzzzzz * 10^tenpwr.
271      */
272     q = digits;
273     dprintf(("X = 0."));
274     while (q < p) {
275         dprintf(("%c", *q + '0'));
276         q++;
277     }
278     dprintf((" * 10^%i\n", tenpwr));
279 
280     /*
281      * Now convert [digits,p) to our internal representation.
282      */
283     bit = LIMB_TOP_BIT;
284     for (m = mant; m < mant + MANT_LIMBS; m++) {
285         *m = 0;
286     }
287     m = mant;
288     q = digits;
289     started = false;
290     twopwr = 0;
291     while (m < mant + MANT_LIMBS) {
292         fp_limb carry = 0;
293         while (p > q && !p[-1]) {
294             p--;
295         }
296         if (p <= q) {
297             break;
298         }
299         for (r = p; r-- > q;) {
300             int32_t i;
301             i = 2 * *r + carry;
302             if (i >= 10) {
303                 carry = 1;
304                 i -= 10;
305             } else {
306                 carry = 0;
307             }
308             *r = i;
309         }
310         if (carry) {
311             *m |= bit;
312             started = true;
313         }
314         if (started) {
315             if (bit == 1) {
316                 bit = LIMB_TOP_BIT;
317                 m++;
318             } else {
319                 bit >>= 1;
320             }
321         } else {
322             twopwr--;
323         }
324     }
325     twopwr += tenpwr;
326 
327     /*
328      * At this point, the 'mant' array contains the first frac-
329      * tional places of a base-2^16 real number which when mul-
330      * tiplied by 2^twopwr and 5^tenpwr gives X.
331      */
332     dprintf(("X = " MANT_FMT " * 2^%i * 5^%i\n", MANT_ARG, twopwr,
333              tenpwr));
334 
335     /*
336      * Now multiply 'mant' by 5^tenpwr.
337      */
338     if (tenpwr < 0) {           /* mult = 5^-1 = 0.2 */
339         for (m = mult; m < mult + MANT_LIMBS - 1; m++) {
340             *m = LIMB_BYTE(0xcc);
341         }
342         mult[MANT_LIMBS - 1] = LIMB_BYTE(0xcc)+1;
343         extratwos = -2;
344         tenpwr = -tenpwr;
345 
346         /*
347          * If tenpwr was 1000...000b, then it becomes 1000...000b. See
348          * the "ANSI C" comment below for more details on that case.
349          *
350          * Because we already truncated tenpwr to +5000...-5000 inside
351          * the exponent parsing code, this shouldn't happen though.
352          */
353     } else if (tenpwr > 0) {    /* mult = 5^+1 = 5.0 */
354         mult[0] = (fp_limb)5 << (LIMB_BITS-3); /* 0xA000... */
355         for (m = mult + 1; m < mult + MANT_LIMBS; m++) {
356             *m = 0;
357         }
358         extratwos = 3;
359     } else {
360         extratwos = 0;
361     }
362     while (tenpwr) {
363         dprintf(("loop=" MANT_FMT " * 2^%i * 5^%i (%i)\n", MANT_ARG,
364                  twopwr, tenpwr, extratwos));
365         if (tenpwr & 1) {
366             dprintf(("mant*mult\n"));
367             twopwr += extratwos + float_multiply(mant, mult);
368         }
369         dprintf(("mult*mult\n"));
370         extratwos = extratwos * 2 + float_multiply(mult, mult);
371         tenpwr >>= 1;
372 
373         /*
374          * In ANSI C, the result of right-shifting a signed integer is
375          * considered implementation-specific. To ensure that the loop
376          * terminates even if tenpwr was 1000...000b to begin with, we
377          * manually clear the MSB, in case a 1 was shifted in.
378          *
379          * Because we already truncated tenpwr to +5000...-5000 inside
380          * the exponent parsing code, this shouldn't matter; neverthe-
381          * less it is the right thing to do here.
382          */
383         tenpwr &= (uint32_t) - 1 >> 1;
384     }
385 
386     /*
387      * At this point, the 'mant' array contains the first frac-
388      * tional places of a base-2^16 real number in [0.5,1) that
389      * when multiplied by 2^twopwr gives X. Or it contains zero
390      * of course. We are done.
391      */
392     *exponent = twopwr;
393     return true;
394 }
395 
396 /*
397  * ---------------------------------------------------------------------------
398  *  operations of specific bits
399  * ---------------------------------------------------------------------------
400  */
401 
402 /* Set a bit, using *bigendian* bit numbering (0 = MSB) */
set_bit(fp_limb * mant,int bit)403 static void set_bit(fp_limb *mant, int bit)
404 {
405     mant[bit/LIMB_BITS] |= LIMB_TOP_BIT >> (bit & (LIMB_BITS-1));
406 }
407 
408 /* Test a single bit */
test_bit(const fp_limb * mant,int bit)409 static int test_bit(const fp_limb *mant, int bit)
410 {
411     return (mant[bit/LIMB_BITS] >> (~bit & (LIMB_BITS-1))) & 1;
412 }
413 
414 /* Report if the mantissa value is all zero */
is_zero(const fp_limb * mant)415 static bool is_zero(const fp_limb *mant)
416 {
417     int i;
418 
419     for (i = 0; i < MANT_LIMBS; i++)
420         if (mant[i])
421             return false;
422 
423     return true;
424 }
425 
426 /*
427  * ---------------------------------------------------------------------------
428  *  round a mantissa off after i words
429  * ---------------------------------------------------------------------------
430  */
431 
432 #define ROUND_COLLECT_BITS                      \
433     do {                                        \
434         m = mant[i] & (2*bit-1);                \
435         for (j = i+1; j < MANT_LIMBS; j++)      \
436             m = m | mant[j];                    \
437     } while (0)
438 
439 #define ROUND_ABS_DOWN                          \
440     do {                                        \
441         mant[i] &= ~(bit-1);                    \
442         for (j = i+1; j < MANT_LIMBS; j++)      \
443             mant[j] = 0;                        \
444         return false;                           \
445     } while (0)
446 
447 #define ROUND_ABS_UP                            \
448     do {                                        \
449         mant[i] = (mant[i] & ~(bit-1)) + bit;   \
450         for (j = i+1; j < MANT_LIMBS; j++)      \
451             mant[j] = 0;                        \
452         while (i > 0 && !mant[i])               \
453             ++mant[--i];                        \
454         return !mant[0];                        \
455     } while (0)
456 
ieee_round(bool minus,fp_limb * mant,int bits)457 static bool ieee_round(bool minus, fp_limb *mant, int bits)
458 {
459     fp_limb m = 0;
460     int32_t j;
461     int i = bits / LIMB_BITS;
462     int p = bits % LIMB_BITS;
463     fp_limb bit = LIMB_TOP_BIT >> p;
464 
465     if (rc == FLOAT_RC_NEAR) {
466         if (mant[i] & bit) {
467             mant[i] &= ~bit;
468             ROUND_COLLECT_BITS;
469             mant[i] |= bit;
470             if (m) {
471                 ROUND_ABS_UP;
472             } else {
473                 if (test_bit(mant, bits-1)) {
474                     ROUND_ABS_UP;
475                 } else {
476                     ROUND_ABS_DOWN;
477                 }
478             }
479         } else {
480             ROUND_ABS_DOWN;
481         }
482     } else if (rc == FLOAT_RC_ZERO ||
483                rc == (minus ? FLOAT_RC_UP : FLOAT_RC_DOWN)) {
484         ROUND_ABS_DOWN;
485     } else {
486         /* rc == (minus ? FLOAT_RC_DOWN : FLOAT_RC_UP) */
487         /* Round toward +/- infinity */
488         ROUND_COLLECT_BITS;
489         if (m) {
490             ROUND_ABS_UP;
491         } else {
492             ROUND_ABS_DOWN;
493         }
494     }
495     return false;
496 }
497 
498 /* Returns a value >= 16 if not a valid hex digit */
hexval(char c)499 static unsigned int hexval(char c)
500 {
501     unsigned int v = (unsigned char) c;
502 
503     if (v >= '0' && v <= '9')
504         return v - '0';
505     else
506         return (v|0x20) - 'a' + 10;
507 }
508 
509 /* Handle floating-point numbers with radix 2^bits and binary exponent */
ieee_flconvert_bin(const char * string,int bits,fp_limb * mant,int32_t * exponent)510 static bool ieee_flconvert_bin(const char *string, int bits,
511                                fp_limb *mant, int32_t *exponent)
512 {
513     static const int log2tbl[16] =
514         { -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 };
515     fp_limb mult[MANT_LIMBS + 1], *mp;
516     int ms;
517     int32_t twopwr;
518     bool seendot, seendigit;
519     unsigned char c;
520     const int radix = 1 << bits;
521     fp_limb v;
522 
523     twopwr = 0;
524     seendot = seendigit = false;
525     ms = 0;
526     mp = NULL;
527 
528     memset(mult, 0, sizeof mult);
529 
530     while ((c = *string++) != '\0') {
531         if (c == '.') {
532             if (!seendot)
533                 seendot = true;
534             else {
535                 nasm_nonfatal("too many periods in floating-point constant");
536                 return false;
537             }
538         } else if ((v = hexval(c)) < (unsigned int)radix) {
539             if (!seendigit && v) {
540                 int l = log2tbl[v];
541 
542                 seendigit = true;
543                 mp = mult;
544                 ms = (LIMB_BITS-1)-l;
545 
546                 twopwr += l+1-bits;
547             }
548 
549             if (seendigit) {
550                 if (ms < 0) {
551                     /* Cast to fp_2limb as ms == -LIMB_BITS is possible. */
552                     *mp |= (fp_2limb)v >> -ms;
553                     mp++;
554                     if (mp > &mult[MANT_LIMBS])
555                         mp = &mult[MANT_LIMBS]; /* Guard slot */
556                     ms += LIMB_BITS;
557                 }
558                 *mp |= v << ms;
559                 ms -= bits;
560 
561                 if (!seendot)
562                     twopwr += bits;
563             } else {
564                 if (seendot)
565                     twopwr -= bits;
566             }
567         } else if (c == 'p' || c == 'P') {
568             int32_t e;
569             e = read_exponent(string, 20000);
570             if (e == INT32_MAX)
571                 return false;
572             twopwr += e;
573             break;
574         } else if (c == '_') {
575             /* ignore */
576         } else {
577             nasm_nonfatal("floating-point constant: `%c' is invalid character", c);
578             return false;
579         }
580     }
581 
582     if (!seendigit) {
583         memset(mant, 0, MANT_LIMBS*sizeof(fp_limb)); /* Zero */
584         *exponent = 0;
585     } else {
586         memcpy(mant, mult, MANT_LIMBS*sizeof(fp_limb));
587         *exponent = twopwr;
588     }
589 
590     return true;
591 }
592 
593 /*
594  * Shift a mantissa to the right by i bits.
595  */
ieee_shr(fp_limb * mant,int i)596 static void ieee_shr(fp_limb *mant, int i)
597 {
598     fp_limb n, m;
599     int j = 0;
600     int sr, sl, offs;
601 
602     sr = i % LIMB_BITS; sl = LIMB_BITS-sr;
603     offs = i/LIMB_BITS;
604 
605     if (sr == 0) {
606         if (offs)
607             for (j = MANT_LIMBS-1; j >= offs; j--)
608                 mant[j] = mant[j-offs];
609     } else if (MANT_LIMBS-1-offs < 0) {
610         j = MANT_LIMBS-1;
611     } else {
612         n = mant[MANT_LIMBS-1-offs] >> sr;
613         for (j = MANT_LIMBS-1; j > offs; j--) {
614             m = mant[j-offs-1];
615             mant[j] = (m << sl) | n;
616             n = m >> sr;
617         }
618         mant[j--] = n;
619     }
620     while (j >= 0)
621         mant[j--] = 0;
622 }
623 
624 /* Produce standard IEEE formats, with implicit or explicit integer
625    bit; this makes the following assumptions:
626 
627    - the sign bit is the MSB, followed by the exponent,
628      followed by the integer bit if present.
629    - the sign bit plus exponent fit in 16 bits.
630    - the exponent bias is 2^(n-1)-1 for an n-bit exponent */
631 
632 struct ieee_format {
633     int bytes;
634     int mantissa;               /* Fractional bits in the mantissa */
635     int explicit;               /* Explicit integer */
636     int exponent;               /* Bits in the exponent */
637 };
638 
639 /*
640  * The 16- and 128-bit formats are expected to be in IEEE 754r.
641  * AMD SSE5 uses the 16-bit format.
642  *
643  * The 32- and 64-bit formats are the original IEEE 754 formats.
644  *
645  * The 80-bit format is x87-specific, but widely used.
646  *
647  * The 8-bit format appears to be the consensus 8-bit floating-point
648  * format.  It is apparently used in graphics applications.
649  */
650 static const struct ieee_format ieee_8   = {  1,   3, 0,  4 };
651 static const struct ieee_format ieee_16  = {  2,  10, 0,  5 };
652 static const struct ieee_format ieee_32  = {  4,  23, 0,  8 };
653 static const struct ieee_format ieee_64  = {  8,  52, 0, 11 };
654 static const struct ieee_format ieee_80  = { 10,  63, 1, 15 };
655 static const struct ieee_format ieee_128 = { 16, 112, 0, 15 };
656 
657 /* Types of values we can generate */
658 enum floats {
659     FL_ZERO,
660     FL_DENORMAL,
661     FL_NORMAL,
662     FL_INFINITY,
663     FL_QNAN,
664     FL_SNAN
665 };
666 
to_packed_bcd(const char * str,const char * p,int s,uint8_t * result,const struct ieee_format * fmt)667 static int to_packed_bcd(const char *str, const char *p,
668                          int s, uint8_t *result,
669                          const struct ieee_format *fmt)
670 {
671     int n = 0;
672     char c;
673     int tv = -1;
674 
675     if (fmt != &ieee_80) {
676         nasm_nonfatal("packed BCD requires an 80-bit format");
677         return 0;
678     }
679 
680     while (p >= str) {
681         c = *p--;
682         if (c >= '0' && c <= '9') {
683             if (tv < 0) {
684                 if (n == 9)
685                     nasm_warn(WARN_OTHER|ERR_PASS2, "packed BCD truncated to 18 digits");
686                 tv = c-'0';
687             } else {
688                 if (n < 9)
689                     *result++ = tv + ((c-'0') << 4);
690                 n++;
691                 tv = -1;
692             }
693         } else if (c == '_') {
694             /* do nothing */
695         } else {
696             nasm_nonfatal("invalid character `%c' in packed BCD constant", c);
697             return 0;
698         }
699     }
700     if (tv >= 0) {
701         if (n < 9)
702             *result++ = tv;
703         n++;
704     }
705     while (n < 9) {
706         *result++ = 0;
707         n++;
708     }
709     *result = (s < 0) ? 0x80 : 0;
710 
711     return 1;                   /* success */
712 }
713 
to_float(const char * str,int s,uint8_t * result,const struct ieee_format * fmt)714 static int to_float(const char *str, int s, uint8_t *result,
715                     const struct ieee_format *fmt)
716 {
717     fp_limb mant[MANT_LIMBS];
718     int32_t exponent = 0;
719     const int32_t expmax = 1 << (fmt->exponent - 1);
720     fp_limb one_mask = LIMB_TOP_BIT >>
721         ((fmt->exponent+fmt->explicit) % LIMB_BITS);
722     const int one_pos = (fmt->exponent+fmt->explicit)/LIMB_BITS;
723     int i;
724     int shift;
725     enum floats type;
726     bool ok;
727     const bool minus = s < 0;
728     const int bits = fmt->bytes * 8;
729     const char *strend;
730 
731     nasm_assert(str[0]);
732 
733     strend = strchr(str, '\0');
734     if (strend[-1] == 'P' || strend[-1] == 'p')
735         return to_packed_bcd(str, strend-2, s, result, fmt);
736 
737     if (str[0] == '_') {
738         /* Special tokens */
739 
740         switch (str[3]) {
741         case 'n':              /* __?nan?__ */
742         case 'N':
743         case 'q':              /* __?qnan?__ */
744         case 'Q':
745             type = FL_QNAN;
746             break;
747         case 's':              /* __?snan?__ */
748         case 'S':
749             type = FL_SNAN;
750             break;
751         case 'i':              /* __?infinity?__ */
752         case 'I':
753             type = FL_INFINITY;
754             break;
755         default:
756             nasm_nonfatal("internal error: unknown FP constant token `%s'", str);
757             type = FL_QNAN;
758             break;
759         }
760     } else {
761         if (str[0] == '0') {
762             switch (str[1]) {
763             case 'x': case 'X':
764             case 'h': case 'H':
765                 ok = ieee_flconvert_bin(str+2, 4, mant, &exponent);
766                 break;
767             case 'o': case 'O':
768             case 'q': case 'Q':
769                 ok = ieee_flconvert_bin(str+2, 3, mant, &exponent);
770                 break;
771             case 'b': case 'B':
772             case 'y': case 'Y':
773                 ok = ieee_flconvert_bin(str+2, 1, mant, &exponent);
774                 break;
775             case 'd': case 'D':
776             case 't': case 'T':
777                 ok = ieee_flconvert(str+2, mant, &exponent);
778                 break;
779             case 'p': case 'P':
780                 return to_packed_bcd(str+2, strend-1, s, result, fmt);
781             default:
782                 /* Leading zero was just a zero? */
783                 ok = ieee_flconvert(str, mant, &exponent);
784                 break;
785             }
786         } else if (str[0] == '$') {
787             ok = ieee_flconvert_bin(str+1, 4, mant, &exponent);
788         } else {
789             ok = ieee_flconvert(str, mant, &exponent);
790         }
791 
792         if (!ok) {
793             type = FL_QNAN;
794         } else if (mant[0] & LIMB_TOP_BIT) {
795             /*
796              * Non-zero.
797              */
798             exponent--;
799             if (exponent >= 2 - expmax && exponent <= expmax) {
800                 type = FL_NORMAL;
801             } else if (exponent > 0) {
802                 nasm_warn(WARN_FLOAT_OVERFLOW|ERR_PASS2,
803                            "overflow in floating-point constant");
804                 type = FL_INFINITY;
805             } else {
806                 /* underflow or denormal; the denormal code handles
807                    actual underflow. */
808                 type = FL_DENORMAL;
809             }
810         } else {
811             /* Zero */
812             type = FL_ZERO;
813         }
814     }
815 
816     switch (type) {
817     case FL_ZERO:
818     zero:
819         memset(mant, 0, sizeof mant);
820         break;
821 
822     case FL_DENORMAL:
823     {
824         shift = -(exponent + expmax - 2 - fmt->exponent)
825             + fmt->explicit;
826         ieee_shr(mant, shift);
827         ieee_round(minus, mant, bits);
828         if (mant[one_pos] & one_mask) {
829             /* One's position is set, we rounded up into normal range */
830             exponent = 1;
831             if (!fmt->explicit)
832                 mant[one_pos] &= ~one_mask;     /* remove explicit one */
833             mant[0] |= exponent << (LIMB_BITS-1 - fmt->exponent);
834         } else {
835             if (daz || is_zero(mant)) {
836                 /*!
837                  *!float-underflow [off] floating point underflow
838                  *!  warns about floating point underflow (a nonzero
839                  *!  constant rounded to zero.)
840                  */
841                 nasm_warn(WARN_FLOAT_UNDERFLOW|ERR_PASS2,
842                            "underflow in floating-point constant");
843                 goto zero;
844             } else {
845                 /*!
846                  *!float-denorm [off] floating point denormal
847                  *!  warns about denormal floating point constants.
848                  */
849                 nasm_warn(WARN_FLOAT_DENORM|ERR_PASS2,
850                            "denormal floating-point constant");
851             }
852         }
853         break;
854     }
855 
856     case FL_NORMAL:
857         exponent += expmax - 1;
858         ieee_shr(mant, fmt->exponent+fmt->explicit);
859         ieee_round(minus, mant, bits);
860         /* did we scale up by one? */
861         if (test_bit(mant, fmt->exponent+fmt->explicit-1)) {
862             ieee_shr(mant, 1);
863             exponent++;
864             if (exponent >= (expmax << 1)-1) {
865                 /*!
866                  *!float-overflow [on] floating point overflow
867                  *!  warns about floating point underflow.
868                  */
869                 nasm_warn(WARN_FLOAT_OVERFLOW|ERR_PASS2,
870                            "overflow in floating-point constant");
871                 type = FL_INFINITY;
872                 goto overflow;
873             }
874         }
875 
876         if (!fmt->explicit)
877             mant[one_pos] &= ~one_mask; /* remove explicit one */
878         mant[0] |= exponent << (LIMB_BITS-1 - fmt->exponent);
879         break;
880 
881     case FL_INFINITY:
882     case FL_QNAN:
883     case FL_SNAN:
884     overflow:
885         memset(mant, 0, sizeof mant);
886         mant[0] = (((fp_limb)1 << fmt->exponent)-1)
887             << (LIMB_BITS-1 - fmt->exponent);
888         if (fmt->explicit)
889             mant[one_pos] |= one_mask;
890         if (type == FL_QNAN)
891             set_bit(mant, fmt->exponent+fmt->explicit+1);
892         else if (type == FL_SNAN)
893             set_bit(mant, fmt->exponent+fmt->explicit+fmt->mantissa);
894         break;
895     }
896 
897     mant[0] |= minus ? LIMB_TOP_BIT : 0;
898 
899     for (i = fmt->bytes - 1; i >= 0; i--)
900         *result++ = mant[i/LIMB_BYTES] >> (((LIMB_BYTES-1)-(i%LIMB_BYTES))*8);
901 
902     return 1;                   /* success */
903 }
904 
float_const(const char * number,int sign,uint8_t * result,int bytes)905 int float_const(const char *number, int sign, uint8_t *result, int bytes)
906 {
907     switch (bytes) {
908     case 1:
909         return to_float(number, sign, result, &ieee_8);
910     case 2:
911         return to_float(number, sign, result, &ieee_16);
912     case 4:
913         return to_float(number, sign, result, &ieee_32);
914     case 8:
915         return to_float(number, sign, result, &ieee_64);
916     case 10:
917         return to_float(number, sign, result, &ieee_80);
918     case 16:
919         return to_float(number, sign, result, &ieee_128);
920     default:
921         nasm_panic("strange value %d passed to float_const", bytes);
922         return 0;
923     }
924 }
925 
926 /* Set floating-point options */
float_option(const char * option)927 int float_option(const char *option)
928 {
929     if (!nasm_stricmp(option, "daz")) {
930         daz = true;
931         return 0;
932     } else if (!nasm_stricmp(option, "nodaz")) {
933         daz = false;
934         return 0;
935     } else if (!nasm_stricmp(option, "near")) {
936         rc = FLOAT_RC_NEAR;
937         return 0;
938     } else if (!nasm_stricmp(option, "down")) {
939         rc = FLOAT_RC_DOWN;
940         return 0;
941     } else if (!nasm_stricmp(option, "up")) {
942         rc = FLOAT_RC_UP;
943         return 0;
944     } else if (!nasm_stricmp(option, "zero")) {
945         rc = FLOAT_RC_ZERO;
946         return 0;
947     } else if (!nasm_stricmp(option, "default")) {
948         rc = FLOAT_RC_NEAR;
949         daz = false;
950         return 0;
951     } else {
952         return -1;              /* Unknown option */
953     }
954 }
955