Pristine Ack-5.5
[Ack-5.5.git] / mach / con_float
1 /*
2   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
3   See the copyright notice in the ACK home directory, in the file "Copyright".
4 */
5
6 /* $Id: con_float,v 2.11 1994/06/24 12:53:35 ceriel Exp $ */
7
8 /* 
9    #define CODE_GENERATOR for code generator
10    #define CODE_EXPANDER for code expander
11
12    #define IEEEFLOAT for machines using IEEE floating point format
13    #define PDPFLOAT for machines using the PDP-11 floating point format
14    If none of these are defined, the format of the machine on which the
15    code generator runs is used.
16    Returns 1 if sz has an illegal value, 2 in case of overflow,
17    and 0 if all went well.
18    If neither IEEEFLOAT nor PDPFLOAT are defined, the return value is not
19    trustworthy.
20
21    Unfortunately, the IEEE standard does not define the byte-order.
22    depends on the #defines
23         FL_MSL_AT_LOW_ADDRESS   1 if most significant long is at low address
24         FL_MSW_AT_LOW_ADDRESS   1 if most significant word is at low address
25         FL_MSB_AT_LOW_ADDRESS   1 if most significant byte is at low address
26 */
27 #ifdef IEEEFLOAT
28 #define USE_FLT
29 #endif
30 #ifdef PDPFLOAT
31 #define USE_FLT
32 #undef FL_MSL_AT_LOW_ADDRESS
33 #define FL_MSL_AT_LOW_ADDRESS 1
34 #undef FL_MSW_AT_LOW_ADDRESS
35 #define FL_MSW_AT_LOW_ADDRESS 1
36 #undef FL_MSB_AT_LOW_ADDRESS
37 #define FL_MSB_AT_LOW_ADDRESS 0
38 #endif
39
40 #define I0 ((FL_MSL_AT_LOW_ADDRESS ? 0 : 4) + (FL_MSW_AT_LOW_ADDRESS ? 0 : 2) \
41                 + (FL_MSB_AT_LOW_ADDRESS ? 0 : 1))
42 #define I1 ((FL_MSL_AT_LOW_ADDRESS ? 0 : 4) + (FL_MSW_AT_LOW_ADDRESS ? 0 : 2) \
43                 + (FL_MSB_AT_LOW_ADDRESS ? 1 : 0))
44 #define I2 ((FL_MSL_AT_LOW_ADDRESS ? 0 : 4) + (FL_MSW_AT_LOW_ADDRESS ? 2 : 0) \
45                 + (FL_MSB_AT_LOW_ADDRESS ? 0 : 1))
46 #define I3 ((FL_MSL_AT_LOW_ADDRESS ? 0 : 4) + (FL_MSW_AT_LOW_ADDRESS ? 2 : 0) \
47                 + (FL_MSB_AT_LOW_ADDRESS ? 1 : 0))
48 #define I4 ((FL_MSL_AT_LOW_ADDRESS ? 4 : 0) + (FL_MSW_AT_LOW_ADDRESS ? 0 : 2) \
49                 + (FL_MSB_AT_LOW_ADDRESS ? 0 : 1))
50 #define I5 ((FL_MSL_AT_LOW_ADDRESS ? 4 : 0) + (FL_MSW_AT_LOW_ADDRESS ? 0 : 2) \
51                 + (FL_MSB_AT_LOW_ADDRESS ? 1 : 0))
52 #define I6 ((FL_MSL_AT_LOW_ADDRESS ? 4 : 0) + (FL_MSW_AT_LOW_ADDRESS ? 2 : 0) \
53                 + (FL_MSB_AT_LOW_ADDRESS ? 0 : 1))
54 #define I7 ((FL_MSL_AT_LOW_ADDRESS ? 4 : 0) + (FL_MSW_AT_LOW_ADDRESS ? 2 : 0) \
55                 + (FL_MSB_AT_LOW_ADDRESS ? 1 : 0))
56
57 #ifndef USE_FLT
58 static int
59 float_cst(str, sz, buf)
60         char *str, *buf;
61         int sz;
62 {
63         int i;
64         char *p;
65         float fl;
66         double f;
67         double atof();
68
69         if (sz!= 4 && sz!= 8)   {
70                 return 1;
71         }
72         f = atof(str);
73         if (sz == 4) {
74                 fl = f;
75                 p = (char *) &fl;
76         }
77         else {
78                 p = (char *) &f;
79         }
80         for (i = sz; i; i--) {
81                 *buf++ = *p++;
82         }
83         return 0;
84 }
85 #else /* USE_FLT */
86
87 #include <ctype.h>
88 #include <flt_arith.h>
89
90 int
91 float_cst(str, sz, buf)
92         char *str, *buf;
93         int sz;
94 {
95         int overflow = 0;
96         flt_arith e;
97
98         if (sz!= 4 && sz!= 8)   {
99                 return 1;
100         }
101         flt_str2flt(str, &e);
102 #ifdef IEEEFLOAT
103         if (sz == 4) {
104 #endif
105 #ifdef PDPFLOAT
106                 e.flt_exp += 129;
107 #else
108                 e.flt_exp += 127;
109 #endif
110                 if (e.flt_mantissa.flt_h_32 == 0) e.flt_exp = 0;
111 #ifdef IEEEFLOAT
112                 if (e.flt_mantissa.flt_h_32 & 0x80) {
113                         /* rounding */
114                         if ((e.flt_mantissa.flt_h_32 & 0xffffff00) == 0xffffff00) {
115                                 e.flt_exp++;
116                                 e.flt_mantissa.flt_h_32 = 0x80000000;
117                         }
118                         else {
119                                 e.flt_mantissa.flt_h_32 += 0x80;
120                         }
121                 }
122                 if (e.flt_exp >= 255) {
123                         overflow = 1;
124                         e.flt_exp = 255;
125                         e.flt_mantissa.flt_h_32 = e.flt_mantissa.flt_l_32 = 0;
126                 }
127                 if (e.flt_exp <= 0) {
128                         flt_b64_sft(&(e.flt_mantissa), 1);
129                         if (e.flt_exp < 0) {
130                                 flt_b64_sft(&(e.flt_mantissa), -e.flt_exp);
131                                 e.flt_exp = 0;
132                         }
133                 }
134 #endif
135 #ifndef IEEEFLOAT
136                 if (sz == 4 && (e.flt_mantissa.flt_h_32 & 0x80)) {
137                         /* rounding */
138                         if ((e.flt_mantissa.flt_h_32 & 0xffffff00) == 0xffffff00) {
139                                 e.flt_exp++;
140                                 e.flt_mantissa.flt_h_32 = 0x80000000;
141                         }
142                         else {
143                                 e.flt_mantissa.flt_h_32 += 0x80;
144                         }
145                 }
146                 if (sz == 8 && (e.flt_mantissa.flt_l_32 & 0x80)) {
147                         /* rounding */
148                         if ((e.flt_mantissa.flt_l_32 & 0xffffff00) == 0xffffff00) {
149                                 e.flt_mantissa.flt_l_32 = 0;
150                                 if (e.flt_mantissa.flt_h_32 == 0xffffffff) {
151                                         e.flt_exp++;
152                                         e.flt_mantissa.flt_h_32 = 0x80000000;
153                                 }
154                                 else e.flt_mantissa.flt_h_32++;
155                         }
156                         else {
157                                 e.flt_mantissa.flt_l_32 += 0x80;
158                         }
159                 }
160                 if (e.flt_exp > 255) {
161                         overflow = 1;
162                         e.flt_exp = 255;
163                         e.flt_mantissa.flt_h_32 = e.flt_mantissa.flt_l_32 = 0xffffffff;
164                 }
165 #endif
166                 buf[I0] = (e.flt_sign << 7) | (e.flt_exp >> 1);
167                 buf[I1] = ((e.flt_exp&1) << 7) |
168                                 ((e.flt_mantissa.flt_h_32 & 0x7fffffff) >> 24);
169                 buf[I2] = e.flt_mantissa.flt_h_32 >> 16;
170                 buf[I3] = e.flt_mantissa.flt_h_32 >> 8;
171 #ifndef IEEEFLOAT
172                 if (sz == 8) {
173                         buf[I4] = e.flt_mantissa.flt_h_32;
174                         buf[I5] = e.flt_mantissa.flt_l_32 >> 24;
175                         buf[I6] = e.flt_mantissa.flt_l_32 >> 16;
176                         buf[I7] = e.flt_mantissa.flt_l_32 >> 8;
177                         flt_b64_sft(&(e.flt_mantissa), -56);
178                 }
179                 else
180 #endif
181                         flt_b64_sft(&(e.flt_mantissa), -24);
182 #ifdef IEEEFLOAT
183         }
184         else {
185                 e.flt_exp += 1023;
186                 if (e.flt_mantissa.flt_h_32 == 0) e.flt_exp = 0;
187                 if (e.flt_mantissa.flt_l_32 & 0x400) {
188                         /* rounding */
189                         if ((e.flt_mantissa.flt_l_32 & 0xfffff800) == 0xfffff800) {
190                                 e.flt_mantissa.flt_l_32 = 0;
191                                 if (e.flt_mantissa.flt_h_32 == 0xffffffff) {
192                                         e.flt_exp++;
193                                         e.flt_mantissa.flt_h_32 = 0x80000000;
194                                 }
195                                 else e.flt_mantissa.flt_h_32++;
196                         }
197                         else {
198                                 e.flt_mantissa.flt_l_32 += 0x400;
199                         }
200                 }
201                 if (e.flt_exp >= 2047) {
202                         overflow = 1;
203                         e.flt_exp = 2047;
204                         e.flt_mantissa.flt_h_32 = e.flt_mantissa.flt_l_32 = 0;
205                 }
206                 if (e.flt_exp <= 0) {
207                         flt_b64_sft(&(e.flt_mantissa), 1);
208                         if (e.flt_exp < 0) {
209                                 flt_b64_sft(&(e.flt_mantissa), -e.flt_exp);
210                                 e.flt_exp = 0;
211                         }
212                 }
213                 buf[I0] = (e.flt_sign << 7) | (e.flt_exp >> 4);
214                 buf[I1] = ((e.flt_exp & 017)<< 4) | ((e.flt_mantissa.flt_h_32 >> 27) & 017);
215                 buf[I2] = e.flt_mantissa.flt_h_32 >> 19;
216                 buf[I3] = e.flt_mantissa.flt_h_32 >> 11;
217                 buf[I4] = e.flt_mantissa.flt_h_32 >> 3;
218                 buf[I5] = (e.flt_mantissa.flt_h_32 << 5) | ((e.flt_mantissa.flt_l_32 >> 27) & 037);
219                 buf[I6] = e.flt_mantissa.flt_l_32 >> 19;
220                 buf[I7] = e.flt_mantissa.flt_l_32 >> 11;
221                 flt_b64_sft(&(e.flt_mantissa), -53);
222         }
223 #endif
224 #if ! FL_MSL_AT_LOW_ADDRESS
225         if (sz == 4) {
226                 buf[I4] = buf[I0];
227                 buf[I5] = buf[I1];
228                 buf[I6] = buf[I2];
229                 buf[I7] = buf[I3];
230         }
231 #endif
232         if (overflow) {
233                 return 2;
234         }
235         return 0;
236 }
237 #endif /* USE_FLT */
238
239 #ifdef CODE_GENERATOR
240 con_float()
241 {
242         char buf[8];
243         int rval = float_cst(str, (int)argval, buf);
244         int i;
245
246         if (rval == 1) {
247                 fprintf(stderr,"float constant size = %d\n",(int)argval);
248                 fatal("bad fcon size");
249         }
250         fprintf(codefile,"!float %s sz %d\n", str, (int)argval);
251         if (rval == 2) {
252                 fprintf(stderr, "Warning: overflow in floating point constant %s\n", str);
253         }
254         fprintf(codefile, ".data1 0%o", buf[0] & 0377);
255         for (i = 1; i < (int)argval; i++) {
256                 fprintf(codefile, ",0%o", buf[i] & 0377);
257         }
258         putc('\n', codefile);
259 }
260 #endif /* CODE_GENERATOR */
261
262 #ifdef CODE_EXPANDER
263 con_float(str, argval)
264         char *str;
265         arith argval;
266 {
267         char buf[8];
268         int rval = float_cst(str, (int)argval, buf);
269         int i;
270
271         if (rval == 1) {
272                 argval = 8;
273                 rval = float_cst(str, 8, buf);
274         }
275         for (i = 0; i < (int)argval; i++) {
276                 gen1(buf[i]);
277         }
278 }
279 #endif /* CODE_EXPANDER */