source: mainline/softfloat/generic/softfloat.c@ aa59fa0

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since aa59fa0 was aa59fa0, checked in by Josef Cejka <malyzelenyhnus@…>, 19 years ago

SoftFloat integrated into HelenOS uspace.

  • Property mode set to 100644
File size: 7.8 KB
Line 
1/*
2 * Copyright (C) 2005 Josef Cejka
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - 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 * - 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#include<softfloat.h>
30#include<sftypes.h>
31
32#include<add.h>
33#include<sub.h>
34#include<mul.h>
35#include<div.h>
36
37#include<conversion.h>
38#include<comparison.h>
39#include<other.h>
40
41#include<functions.h>
42
43/* Arithmetic functions */
44
45float __addsf3(float a, float b)
46{
47 float32 fa, fb;
48 fa.f = a;
49 fb.f = b;
50 if (fa.parts.sign != fb.parts.sign) {
51 if (fa.parts.sign) {
52 fa.parts.sign = 0;
53 return subFloat32(fb, fa).f;
54 };
55 fb.parts.sign = 0;
56 return subFloat32(fa, fb).f;
57 }
58 return addFloat32(fa, fb).f;
59}
60
61double __adddf3(double a, double b)
62{
63 float64 da, db;
64 da.d = a;
65 db.d = b;
66 if (da.parts.sign != db.parts.sign) {
67 if (da.parts.sign) {
68 da.parts.sign = 0;
69 return subFloat64(db, da).d;
70 };
71 db.parts.sign = 0;
72 return subFloat64(da, db).d;
73 }
74 return addFloat64(da, db).d;
75}
76
77float __subsf3(float a, float b)
78{
79 float32 fa, fb;
80 fa.f = a;
81 fb.f = b;
82 if (fa.parts.sign != fb.parts.sign) {
83 fb.parts.sign = !fb.parts.sign;
84 return addFloat32(fa, fb).f;
85 }
86 return subFloat32(fa, fb).f;
87}
88
89double __subdf3(double a, double b)
90{
91 float64 da, db;
92 da.d = a;
93 db.d = b;
94 if (da.parts.sign != db.parts.sign) {
95 db.parts.sign = !db.parts.sign;
96 return addFloat64(da, db).d;
97 }
98 return subFloat64(da, db).d;
99}
100
101float __mulsf3(float a, float b)
102{
103 float32 fa, fb;
104 fa.f = a;
105 fb.f = b;
106 return mulFloat32(fa, fb).f;
107}
108
109double __muldf3(double a, double b)
110{
111 float64 da, db;
112 da.d = a;
113 db.d = b;
114 return mulFloat64(da, db).d;
115}
116
117float __divsf3(float a, float b)
118{
119 float32 fa, fb;
120 fa.f = a;
121 fb.f = b;
122 return divFloat32(fa, fb).f;
123}
124
125double __divdf3(double a, double b)
126{
127 float64 da, db;
128 da.d = a;
129 db.d = b;
130 return divFloat64(da, db).d;
131}
132
133float __negsf2(float a)
134{
135 float32 fa;
136 fa.f = a;
137 fa.parts.sign = !fa.parts.sign;
138 return fa.f;
139}
140
141double __negdf2(double a)
142{
143 float64 fa;
144 fa.d = a;
145 fa.parts.sign = !fa.parts.sign;
146 return fa.d;
147}
148
149/* Conversion functions */
150
151double __extendsfdf2(float a)
152{
153 float32 fa;
154 fa.f = a;
155 return convertFloat32ToFloat64(fa).d;
156}
157
158float __truncdfsf2(double a)
159{
160 float64 da;
161 da.d = a;
162 return convertFloat64ToFloat32(da).f;
163}
164
165int __fixsfsi(float a)
166{
167 float32 fa;
168 fa.f = a;
169
170 return float32_to_int(fa);
171}
172int __fixdfsi(double a)
173{
174 float64 da;
175 da.d = a;
176
177 return float64_to_int(da);
178}
179
180long __fixsfdi(float a)
181{
182 float32 fa;
183 fa.f = a;
184
185 return float32_to_long(fa);
186}
187long __fixdfdi(double a)
188{
189 float64 da;
190 da.d = a;
191
192 return float64_to_long(da);
193}
194
195long long __fixsfti(float a)
196{
197 float32 fa;
198 fa.f = a;
199
200 return float32_to_longlong(fa);
201}
202long long __fixdfti(double a)
203{
204 float64 da;
205 da.d = a;
206
207 return float64_to_longlong(da);
208}
209
210unsigned int __fixunssfsi(float a)
211{
212 float32 fa;
213 fa.f = a;
214
215 return float32_to_uint(fa);
216}
217unsigned int __fixunsdfsi(double a)
218{
219 float64 da;
220 da.d = a;
221
222 return float64_to_uint(da);
223}
224
225unsigned long __fixunssfdi(float a)
226{
227 float32 fa;
228 fa.f = a;
229
230 return float32_to_ulong(fa);
231}
232unsigned long __fixunsdfdi(double a)
233{
234 float64 da;
235 da.d = a;
236
237 return float64_to_ulong(da);
238}
239
240unsigned long long __fixunssfti(float a)
241{
242 float32 fa;
243 fa.f = a;
244
245 return float32_to_ulonglong(fa);
246}
247unsigned long long __fixunsdfti(double a)
248{
249 float64 da;
250 da.d = a;
251
252 return float64_to_ulonglong(da);
253}
254
255float __floatsisf(int i)
256{
257 float32 fa;
258
259 fa = int_to_float32(i);
260 return fa.f;
261}
262double __floatsidf(int i)
263{
264 float64 da;
265
266 da = int_to_float64(i);
267 return da.d;
268}
269
270float __floatdisf(long i)
271{
272 float32 fa;
273
274 fa = long_to_float32(i);
275 return fa.f;
276}
277double __floatdidf(long i)
278{
279 float64 da;
280
281 da = long_to_float64(i);
282 return da.d;
283}
284
285float __floattisf(long long i)
286{
287 float32 fa;
288
289 fa = longlong_to_float32(i);
290 return fa.f;
291}
292double __floattidf(long long i)
293{
294 float64 da;
295
296 da = longlong_to_float64(i);
297 return da.d;
298}
299
300float __floatunsisf(unsigned int i)
301{
302 float32 fa;
303
304 fa = uint_to_float32(i);
305 return fa.f;
306}
307double __floatunsidf(unsigned int i)
308{
309 float64 da;
310
311 da = uint_to_float64(i);
312 return da.d;
313}
314
315float __floatundisf(unsigned long i)
316{
317 float32 fa;
318
319 fa = ulong_to_float32(i);
320 return fa.f;
321}
322double __floatundidf(unsigned long i)
323{
324 float64 da;
325
326 da = ulong_to_float64(i);
327 return da.d;
328}
329
330float __floatuntisf(unsigned long long i)
331{
332 float32 fa;
333
334 fa = ulonglong_to_float32(i);
335 return fa.f;
336}
337double __floatuntidf(unsigned long long i)
338{
339 float64 da;
340
341 da = ulonglong_to_float64(i);
342 return da.d;
343}
344
345/* Comparison functions */
346/* Comparison functions */
347
348/* a<b .. -1
349 * a=b .. 0
350 * a>b .. 1
351 * */
352
353int __cmpsf2(float a, float b)
354{
355 float32 fa, fb;
356 fa.f = a;
357 fb.f = b;
358 if ( (isFloat32NaN(fa)) || (isFloat32NaN(fb)) ) {
359 return 1; /* no special constant for unordered - maybe signaled? */
360 };
361
362
363 if (isFloat32eq(fa, fb)) {
364 return 0;
365 };
366
367 if (isFloat32lt(fa, fb)) {
368 return -1;
369 };
370 return 1;
371}
372
373int __unordsf2(float a, float b)
374{
375 float32 fa, fb;
376 fa.f = a;
377 fb.f = b;
378 return ( (isFloat32NaN(fa)) || (isFloat32NaN(fb)) );
379}
380
381/**
382 * @return zero, if neither argument is a NaN and are equal
383 * */
384int __eqsf2(float a, float b)
385{
386 float32 fa, fb;
387 fa.f = a;
388 fb.f = b;
389 if ( (isFloat32NaN(fa)) || (isFloat32NaN(fb)) ) {
390 /* TODO: sigNaNs*/
391 return 1;
392 };
393 return isFloat32eq(fa, fb) - 1;
394}
395
396/* strange behavior, but it was in gcc documentation */
397int __nesf2(float a, float b)
398{
399 return __eqsf2(a, b);
400}
401
402/* return value >= 0 if a>=b and neither is NaN */
403int __gesf2(float a, float b)
404{
405 float32 fa, fb;
406 fa.f = a;
407 fb.f = b;
408 if ( (isFloat32NaN(fa)) || (isFloat32NaN(fb)) ) {
409 /* TODO: sigNaNs*/
410 return -1;
411 };
412
413 if (isFloat32eq(fa, fb)) {
414 return 0;
415 };
416
417 if (isFloat32gt(fa, fb)) {
418 return 1;
419 };
420
421 return -1;
422}
423
424/** Return negative value, if a<b and neither is NaN*/
425int __ltsf2(float a, float b)
426{
427 float32 fa, fb;
428 fa.f = a;
429 fb.f = b;
430 if ( (isFloat32NaN(fa)) || (isFloat32NaN(fb)) ) {
431 /* TODO: sigNaNs*/
432 return 1;
433 };
434 if (isFloat32lt(fa, fb)) {
435 return -1;
436 };
437 return 0;
438}
439
440/* return value <= 0 if a<=b and neither is NaN */
441int __lesf2(float a, float b)
442{
443 float32 fa, fb;
444 fa.f = a;
445 fb.f = b;
446 if ( (isFloat32NaN(fa)) || (isFloat32NaN(fb)) ) {
447 /* TODO: sigNaNs*/
448 return 1;
449 };
450
451 if (isFloat32eq(fa, fb)) {
452 return 0;
453 };
454
455 if (isFloat32lt(fa, fb)) {
456 return -1;
457 };
458
459 return 1;
460}
461
462/** Return positive value, if a>b and neither is NaN*/
463int __gtsf2(float a, float b)
464{
465 float32 fa, fb;
466 fa.f = a;
467 fb.f = b;
468 if ( (isFloat32NaN(fa)) || (isFloat32NaN(fb)) ) {
469 /* TODO: sigNaNs*/
470 return -1;
471 };
472 if (isFloat32gt(fa, fb)) {
473 return 1;
474 };
475 return 0;
476}
477
478/* Other functions */
479
480float __powisf2(float a, int b)
481{
482/* TODO: */
483}
484
Note: See TracBrowser for help on using the repository browser.