~vojtech-horky/helenos/numa

« back to all changes in this revision

Viewing changes to uspace/lib/softfloat/generic/softfloat.c

  • Committer: Martin Decky
  • Date: 2009-08-04 11:19:19 UTC
  • Revision ID: martin@uranus.dsrg.hide.ms.mff.cuni.cz-20090804111919-evyclddlr3v5lhmp
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
53
float __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
 
 
69
double __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
 
 
85
float __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
 
 
97
double __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
 
 
109
float __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
 
 
117
double __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
 
 
125
float __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
 
 
133
double __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
 
 
141
float __negsf2(float a)
 
142
{
 
143
        float32 fa;
 
144
        fa.f = a;
 
145
        fa.parts.sign = !fa.parts.sign;
 
146
        return fa.f;
 
147
}
 
148
 
 
149
double __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
 
 
159
double __extendsfdf2(float a) 
 
160
{
 
161
        float32 fa;
 
162
        fa.f = a;
 
163
        return convertFloat32ToFloat64(fa).d;
 
164
}
 
165
 
 
166
float __truncdfsf2(double a) 
 
167
{
 
168
        float64 da;
 
169
        da.d = a;
 
170
        return convertFloat64ToFloat32(da).f;
 
171
}
 
172
 
 
173
int __fixsfsi(float a)
 
174
{
 
175
        float32 fa;
 
176
        fa.f = a;
 
177
        
 
178
        return float32_to_int(fa);
 
179
}
 
180
int __fixdfsi(double a)
 
181
{
 
182
        float64 da;
 
183
        da.d = a;
 
184
        
 
185
        return float64_to_int(da);
 
186
}
 
187
 
 
188
long __fixsfdi(float a)
 
189
{
 
190
        float32 fa;
 
191
        fa.f = a;
 
192
        
 
193
        return float32_to_long(fa);
 
194
}
 
195
long __fixdfdi(double a)
 
196
{
 
197
        float64 da;
 
198
        da.d = a;
 
199
        
 
200
        return float64_to_long(da);
 
201
}
 
202
 
 
203
long long __fixsfti(float a)
 
204
{
 
205
        float32 fa;
 
206
        fa.f = a;
 
207
        
 
208
        return float32_to_longlong(fa);
 
209
}
 
210
long long __fixdfti(double a)
 
211
{
 
212
        float64 da;
 
213
        da.d = a;
 
214
        
 
215
        return float64_to_longlong(da);
 
216
}
 
217
 
 
218
unsigned int __fixunssfsi(float a)
 
219
{
 
220
        float32 fa;
 
221
        fa.f = a;
 
222
        
 
223
        return float32_to_uint(fa);
 
224
}
 
225
unsigned int __fixunsdfsi(double a)
 
226
{
 
227
        float64 da;
 
228
        da.d = a;
 
229
        
 
230
        return float64_to_uint(da);
 
231
}
 
232
 
 
233
unsigned long __fixunssfdi(float a)
 
234
{
 
235
        float32 fa;
 
236
        fa.f = a;
 
237
        
 
238
        return float32_to_ulong(fa);
 
239
}
 
240
unsigned long __fixunsdfdi(double a)
 
241
{
 
242
        float64 da;
 
243
        da.d = a;
 
244
        
 
245
        return float64_to_ulong(da);
 
246
}
 
247
 
 
248
unsigned long long __fixunssfti(float a)
 
249
{
 
250
        float32 fa;
 
251
        fa.f = a;
 
252
        
 
253
        return float32_to_ulonglong(fa);
 
254
}
 
255
unsigned long long __fixunsdfti(double a)
 
256
{
 
257
        float64 da;
 
258
        da.d = a;
 
259
        
 
260
        return float64_to_ulonglong(da);
 
261
}
 
262
 
 
263
float __floatsisf(int i)
 
264
{
 
265
        float32 fa;
 
266
        
 
267
        fa = int_to_float32(i);
 
268
        return fa.f;
 
269
}
 
270
double __floatsidf(int i)
 
271
{
 
272
        float64 da;
 
273
        
 
274
        da = int_to_float64(i);
 
275
        return da.d;
 
276
}
 
277
 
 
278
float __floatdisf(long i)
 
279
{
 
280
        float32 fa;
 
281
        
 
282
        fa = long_to_float32(i);
 
283
        return fa.f;
 
284
}
 
285
double __floatdidf(long i)
 
286
{
 
287
        float64 da;
 
288
        
 
289
        da = long_to_float64(i);
 
290
        return da.d;
 
291
}
 
292
 
 
293
float __floattisf(long long i)
 
294
{
 
295
        float32 fa;
 
296
        
 
297
        fa = longlong_to_float32(i);
 
298
        return fa.f;
 
299
}
 
300
double __floattidf(long long i)
 
301
{
 
302
        float64 da;
 
303
        
 
304
        da = longlong_to_float64(i);
 
305
        return da.d;
 
306
}
 
307
 
 
308
float __floatunsisf(unsigned int i)
 
309
{
 
310
        float32 fa;
 
311
        
 
312
        fa = uint_to_float32(i);
 
313
        return fa.f;
 
314
}
 
315
double __floatunsidf(unsigned int i)
 
316
{
 
317
        float64 da;
 
318
        
 
319
        da = uint_to_float64(i);
 
320
        return da.d;
 
321
}
 
322
 
 
323
float __floatundisf(unsigned long i)
 
324
{
 
325
        float32 fa;
 
326
        
 
327
        fa = ulong_to_float32(i);
 
328
        return fa.f;
 
329
}
 
330
double __floatundidf(unsigned long i)
 
331
{
 
332
        float64 da;
 
333
        
 
334
        da = ulong_to_float64(i);
 
335
        return da.d;
 
336
}
 
337
 
 
338
float __floatuntisf(unsigned long long i)
 
339
{
 
340
        float32 fa;
 
341
        
 
342
        fa = ulonglong_to_float32(i);
 
343
        return fa.f;
 
344
}
 
345
double __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
 
 
361
int __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
 
 
381
int __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
 * */
 
392
int __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 */
 
405
int __nesf2(float a, float b) 
 
406
{
 
407
        return __eqsf2(a, b);
 
408
}
 
409
 
 
410
/* return value >= 0 if a>=b and neither is NaN */
 
411
int __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*/
 
433
int __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 */
 
449
int __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*/
 
471
int __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
 
 
488
float __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