source: mainline/uspace/softfloat/generic/softfloat.c@ df4ed85

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since df4ed85 was df4ed85, checked in by Jakub Jermar <jakub@…>, 18 years ago

© versus ©

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