annotate src/libsys/sprintf/float.c @ 134:7d50d8d13711

FFS code sync with Magnetite + gcc version fix This change brings the new flash autodetection for FC and Pirelli targets from Magnetite, and should also fix the gcc version for C1xx and gtamodem targets, which were previously broken because they used TI's original flash autodetect code (which operates at address 0) while the boot ROM is mapped there.
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 11 Dec 2018 08:43:25 +0000
parents 425ab6d987f3
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
86
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
2 * Embedded [v]sprintf() implementation by Mychaela Falconia,
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
3 * loosely based on the 4.3BSD-Tahoe version.
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
4 *
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
5 * This module contains the floating point conversion functions.
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
6 */
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
7
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
8 #include <sys/types.h>
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9 #include <ctype.h>
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10 #include "defs.h"
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12 extern double modf();
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14 extern u_char * _sprintf_field(u_char *op, int width, int flags, int sign,
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15 u_char *body, int size, int dprec, int fpprec);
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
17 #define MAX_INT_DIGITS 10 /* 2^32-1 in decimal */
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18 #define MAXFRACT 16 /* max sensible for 64-bit double */
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
19 #define DEFPREC 6
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
20
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
21 static char *
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
22 emit_integer_portion(unsigned number, char *endp)
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
23 {
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
24 char *t = endp;
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
25
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
26 do {
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
27 *--t = tochar(number % 10);
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
28 number /= 10;
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
29 } while (number);
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
30 return (t);
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
31 }
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
32
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
33 static int
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
34 f_round(double fract, char *start, char *end, int sign)
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
35 {
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
36 double tmp;
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
37
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
38 (void)modf(fract * 10, &tmp);
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39 if (tmp > 4)
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
40 for (;; --end) {
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
41 if (*end == '.')
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
42 --end;
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43 if (++*end <= '9')
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
44 break;
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
45 *end = '0';
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
46 if (end == start) {
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
47 *--end = '1';
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
48 return(1);
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
49 }
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50 }
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 /* ``"%.3f", (double)-0.0004'' gives you a negative 0. */
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
52 else if (sign == '-')
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
53 for (;; --end) {
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
54 if (*end == '.')
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
55 --end;
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
56 if (*end != '0')
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
57 break;
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
58 if (end == start)
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
59 return(-1); /* clear the -ve */
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60 }
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
61 return(0);
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
62 }
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
63
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
64 u_char *
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
65 _sprintf_percent_f(u_char *op, int width, int flags, int sign,
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
66 double number, int prec)
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
67 {
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
68 char buf[MAX_INT_DIGITS + 1 + MAXFRACT];
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
69 int extra_prec = 0;
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70 int origsign = sign;
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
71 int round_stat;
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
72 double fract, tmp;
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
73 char *start, *t;
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
74
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
75 /* first order of business: weed out infinities and NaNs */
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
76 if (isinf(number)) {
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
77 if (number < 0)
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
78 sign = '-';
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
79 return _sprintf_field(op, width, flags, sign, "Inf", 3, 0, 0);
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
80 }
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
81 if (isnan(number))
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
82 return _sprintf_field(op, width, flags, sign, "NaN", 3, 0, 0);
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
83 /* OK, we know it's a valid real like in the good old VAX days */
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
84 if (number < 0) {
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
85 sign = '-';
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
86 number = -number;
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
87 }
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
88 fract = modf(number, &tmp);
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
89 if (tmp > (double) 0xFFFFFFFF)
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
90 return _sprintf_field(op, width, flags, sign, "Toobig", 6,
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
91 0, 0);
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
92 start = emit_integer_portion((unsigned) tmp, buf + MAX_INT_DIGITS);
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
93 if (prec > MAXFRACT) {
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
94 extra_prec = prec - MAXFRACT;
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
95 prec = MAXFRACT;
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
96 } else if (prec == -1)
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
97 prec = DEFPREC;
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
98 t = buf + MAX_INT_DIGITS;
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
99 /*
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
100 * if precision required or alternate flag set, add in a
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
101 * decimal point.
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
102 */
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
103 if (prec || flags&ALT)
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
104 *t++ = '.';
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
105 /* if requires more precision and some fraction left */
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
106 if (fract) {
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
107 if (prec)
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
108 do {
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
109 fract = modf(fract * 10, &tmp);
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
110 *t++ = tochar((int)tmp);
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
111 } while (--prec && fract);
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
112 if (fract) {
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
113 round_stat = f_round(fract, start, t - 1, sign);
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
114 if (round_stat == 1)
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
115 start--;
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
116 else if (round_stat == -1)
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
117 sign = origsign;
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
118 }
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
119 }
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
120 return _sprintf_field(op, width, flags, sign, start, t - start,
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
121 0, prec + extra_prec);
425ab6d987f3 src/libsys: pieced together from Citrine
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
122 }