source: mainline/uspace/app/pcc/cc/ccom/softfloat.c@ a7de7182

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a7de7182 was a7de7182, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 14 years ago

Added pcc source tree (contents of pcc-1.0.0.tgz)

  • Property mode set to 100644
File size: 6.8 KB
RevLine 
[a7de7182]1/* $Id: softfloat.c,v 1.4 2009/07/29 12:32:34 ragge Exp $ */
2
3/*
4 * Copyright (c) 2008 Anders Magnusson. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifdef SOFTFLOAT
30
31#include "pass1.h"
32
33
34/*
35 * Floating point emulation to be used when cross-compiling.
36 * Currently only supports F- and D-float, used in DEC machines.
37 * Should be trivial to add other emulations.
38 *
39 * XXX - assumes that:
40 * - long long is (at least) 64 bits
41 * - int is at least 32 bits.
42 * - short is 16 bits.
43 */
44
45#ifdef FDFLOAT
46
47/*
48 * Useful macros to manipulate the float.
49 */
50#define DSIGN(w) (((w).fd1 >> 15) & 1)
51#define DSIGNSET(w,s) ((w).fd1 = (s << 15) | ((w).fd1 & 077777))
52#define DEXP(w) (((w).fd1 >> 7) & 0377)
53#define DEXPSET(w,e) ((w).fd1 = (((e) & 0377) << 7) | ((w).fd1 & 0100177))
54#define DMANTH(w) ((w).fd1 & 0177)
55#define DMANTHSET(w,m) ((w).fd1 = ((m) & 0177) | ((w).fd1 & 0177600))
56
57typedef unsigned int lword;
58typedef unsigned long long dword;
59
60#define MAXMANT 0x100000000000000LL
61
62/*
63 * Returns a zero dfloat.
64 */
65static SF
66nulldf(void)
67{
68 SF rv;
69
70 rv.fd1 = rv.fd2 = rv.fd3 = rv.fd4 = 0;
71 return rv;
72}
73
74/*
75 * Convert a (u)longlong to dfloat.
76 * XXX - fails on too large (> 55 bits) numbers.
77 */
78SF
79soft_cast(CONSZ ll, TWORD t)
80{
81 int i;
82 SF rv;
83
84 rv = nulldf();
85 if (ll == 0)
86 return rv; /* fp is zero */
87 if (ll < 0)
88 DSIGNSET(rv,1), ll = -ll;
89 for (i = 0; ll > 0; i++, ll <<= 1)
90 ;
91 DEXPSET(rv, 192-i);
92 DMANTHSET(rv, ll >> 56);
93 rv.fd2 = ll >> 40;
94 rv.fd3 = ll >> 24;
95 rv.fd4 = ll >> 8;
96 return rv;
97}
98
99/*
100 * multiply two dfloat. Use chop, not round.
101 */
102SF
103soft_mul(SF p1, SF p2)
104{
105 SF rv;
106 lword a1[2], a2[2], res[4];
107 dword sum;
108
109 res[0] = res[1] = res[2] = res[3] = 0;
110
111 /* move mantissa into lwords */
112 a1[0] = p1.fd4 | (p1.fd3 << 16);
113 a1[1] = p1.fd2 | DMANTH(p1) << 16 | 0x800000;
114
115 a2[0] = p2.fd4 | (p2.fd3 << 16);
116 a2[1] = p2.fd2 | DMANTH(p2) << 16 | 0x800000;
117
118#define MULONE(x,y,r) sum += (dword)a1[x] * (dword)a2[y]; sum += res[r]; \
119 res[r] = sum; sum >>= 32;
120
121 sum = 0;
122 MULONE(0, 0, 0);
123 MULONE(1, 0, 1);
124 res[2] = sum;
125 sum = 0;
126 MULONE(0, 1, 1);
127 MULONE(1, 1, 2);
128 res[3] = sum;
129
130 rv.fd1 = 0;
131 DSIGNSET(rv, DSIGN(p1) ^ DSIGN(p2));
132 DEXPSET(rv, DEXP(p1) + DEXP(p2) - 128);
133 if (res[3] & 0x8000) {
134 res[3] = (res[3] << 8) | (res[2] >> 24);
135 res[2] = (res[2] << 8) | (res[1] >> 24);
136 } else {
137 DEXPSET(rv, DEXP(rv) - 1);
138 res[3] = (res[3] << 9) | (res[2] >> 23);
139 res[2] = (res[2] << 9) | (res[1] >> 23);
140 }
141 DMANTHSET(rv, res[3] >> 16);
142 rv.fd2 = res[3];
143 rv.fd3 = res[2] >> 16;
144 rv.fd4 = res[2];
145 return rv;
146}
147
148SF
149soft_div(SF t, SF n)
150{
151 SF rv;
152 dword T, N, K;
153 int c;
154
155#define SHL(x,b) ((dword)(x) << b)
156 T = SHL(1,55) | SHL(DMANTH(t), 48) |
157 SHL(t.fd2, 32) | SHL(t.fd3, 16) | t.fd4;
158 N = SHL(1,55) | SHL(DMANTH(n), 48) |
159 SHL(n.fd2, 32) | SHL(n.fd3, 16) | n.fd4;
160
161 c = T > N;
162 for (K = 0; (K & 0x80000000000000ULL) == 0; ) {
163 if (T >= N) {
164 T -= N;
165 K |= 1;
166 }
167 T <<= 1;
168 K <<= 1;
169 }
170 rv.fd1 = 0;
171 DSIGNSET(rv, DSIGN(t) ^ DSIGN(n));
172 DEXPSET(rv, DEXP(t) - DEXP(n) + 128 + c);
173 DMANTHSET(rv, K >> 48);
174 rv.fd2 = K >> 32;
175 rv.fd3 = K >> 16;
176 rv.fd4 = K;
177 return rv;
178}
179
180/*
181 * Negate a float number. Easy.
182 */
183SF
184soft_neg(SF sf)
185{
186 int sign = DSIGN(sf) == 0;
187 DSIGNSET(sf, sign);
188 return sf;
189}
190
191/*
192 * Return true if fp number is zero.
193 */
194int
195soft_isz(SF sf)
196{
197 return (DEXP(sf) == 0);
198}
199
200int
201soft_cmp_eq(SF x1, SF x2)
202{
203 cerror("soft_cmp_eq");
204 return 0;
205}
206
207int
208soft_cmp_ne(SF x1, SF x2)
209{
210 cerror("soft_cmp_ne");
211 return 0;
212}
213
214int
215soft_cmp_le(SF x1, SF x2)
216{
217 cerror("soft_cmp_le");
218 return 0;
219}
220
221int
222soft_cmp_lt(SF x1, SF x2)
223{
224 cerror("soft_cmp_lt");
225 return 0;
226}
227
228int
229soft_cmp_ge(SF x1, SF x2)
230{
231 cerror("soft_cmp_ge");
232 return 0;
233}
234
235int
236soft_cmp_gt(SF x1, SF x2)
237{
238 cerror("soft_cmp_gt");
239 return 0;
240}
241
242/*
243 * Convert a fp number to a CONSZ.
244 */
245CONSZ
246soft_val(SF sf)
247{
248 CONSZ mant;
249 int exp = DEXP(sf) - 128;
250
251 mant = SHL(1,55) | SHL(DMANTH(sf), 48) |
252 SHL(sf.fd2, 32) | SHL(sf.fd3, 16) | sf.fd4;
253
254 while (exp < 0)
255 mant >>= 1, exp++;
256 while (exp > 0)
257 mant <<= 1, exp--;
258 return mant;
259}
260
261SF
262soft_plus(SF x1, SF x2)
263{
264 cerror("soft_plus");
265 return x1;
266}
267
268SF
269soft_minus(SF x1, SF x2)
270{
271 cerror("soft_minus");
272 return x1;
273}
274
275/*
276 * Convert a hex constant to floating point number.
277 */
278NODE *
279fhexcon(char *s)
280{
281 cerror("fhexcon");
282 return NULL;
283}
284
285/*
286 * Convert a floating-point constant to D-float and store it in a NODE.
287 */
288NODE *
289floatcon(char *s)
290{
291 NODE *p;
292 dword mant;
293 SF fl, flexp, exp5;
294 int exp, negexp, bexp;
295
296 exp = 0;
297 mant = 0;
298#define ADDTO(sum, val) sum = sum * 10 + val - '0'
299 for (; *s >= '0' && *s <= '9'; s++) {
300 if (mant<MAXMANT)
301 ADDTO(mant, *s);
302 else
303 exp++;
304 }
305 if (*s == '.') {
306 for (s++; *s >= '0' && *s <= '9'; s++) {
307 if (mant<MAXMANT) {
308 ADDTO(mant, *s);
309 exp--;
310 }
311 }
312 }
313
314 if ((*s == 'E') || (*s == 'e')) {
315 int eexp = 0, sign = 0;
316 s++;
317 if (*s == '+')
318 s++;
319 else if (*s=='-')
320 sign = 1, s++;
321
322 for (; *s >= '0' && *s <= '9'; s++)
323 ADDTO(eexp, *s);
324 if (sign)
325 eexp = -eexp;
326 exp = exp + eexp;
327 }
328
329 negexp = 1;
330 if (exp<0) {
331 negexp = -1;
332 exp = -exp;
333 }
334
335
336 flexp = soft_cast(1, INT);
337 exp5 = soft_cast(5, INT);
338 bexp = exp;
339 fl = soft_cast(mant, INT);
340
341 for (; exp; exp >>= 1) {
342 if (exp&01)
343 flexp = soft_mul(flexp, exp5);
344 exp5 = soft_mul(exp5, exp5);
345 }
346 if (negexp<0)
347 fl = soft_div(fl, flexp);
348 else
349 fl = soft_mul(fl, flexp);
350
351 DEXPSET(fl, DEXP(fl) + negexp*bexp);
352 p = block(FCON, NIL, NIL, DOUBLE, 0, MKSUE(DOUBLE)); /* XXX type */
353 p->n_dcon = fl;
354 return p;
355}
356#else
357#error missing softfloat definition
358#endif
359#endif
Note: See TracBrowser for help on using the repository browser.