~martin-decky/helenos/rcu

« back to all changes in this revision

Viewing changes to uspace/lib/softfloat/generic/conversion.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       
 
30
 * @{
 
31
 */
 
32
/** @file
 
33
 */
 
34
 
 
35
#include "sftypes.h"
 
36
#include "conversion.h"
 
37
#include "comparison.h"
 
38
#include "common.h"
 
39
 
 
40
float64 convertFloat32ToFloat64(float32 a) 
 
41
{
 
42
        float64 result;
 
43
        uint64_t frac;
 
44
        
 
45
        result.parts.sign = a.parts.sign;
 
46
        result.parts.fraction = a.parts.fraction;
 
47
        result.parts.fraction <<= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE );
 
48
        
 
49
        if ((isFloat32Infinity(a))||(isFloat32NaN(a))) {
 
50
                result.parts.exp = 0x7FF;
 
51
                /* TODO; check if its correct for SigNaNs*/
 
52
                return result;
 
53
        };
 
54
        
 
55
        result.parts.exp = a.parts.exp + ( (int)FLOAT64_BIAS - FLOAT32_BIAS );
 
56
        if (a.parts.exp == 0) {
 
57
                /* normalize denormalized numbers */
 
58
 
 
59
                if (result.parts.fraction == 0ll) { /* fix zero */
 
60
                        result.parts.exp = 0ll;
 
61
                        return result;
 
62
                }
 
63
                        
 
64
                frac = result.parts.fraction;
 
65
                
 
66
                while (!(frac & (0x10000000000000ll))) {
 
67
                        frac <<= 1;
 
68
                        --result.parts.exp;
 
69
                };
 
70
                
 
71
                ++result.parts.exp;
 
72
                result.parts.fraction = frac;
 
73
        };
 
74
        
 
75
        return result;
 
76
        
 
77
}
 
78
 
 
79
float32 convertFloat64ToFloat32(float64 a) 
 
80
{
 
81
        float32 result;
 
82
        int32_t exp;
 
83
        uint64_t frac;
 
84
        
 
85
        result.parts.sign = a.parts.sign;
 
86
        
 
87
        if (isFloat64NaN(a)) {
 
88
                
 
89
                result.parts.exp = 0xFF;
 
90
                
 
91
                if (isFloat64SigNaN(a)) {
 
92
                        result.parts.fraction = 0x400000; /* set first bit of fraction nonzero */
 
93
                        return result;
 
94
                }
 
95
        
 
96
                result.parts.fraction = 0x1; /* fraction nonzero but its first bit is zero */
 
97
                return result;
 
98
        };
 
99
 
 
100
        if (isFloat64Infinity(a)) {
 
101
                result.parts.fraction = 0;
 
102
                result.parts.exp = 0xFF;
 
103
                return result;
 
104
        };
 
105
 
 
106
        exp = (int)a.parts.exp - FLOAT64_BIAS + FLOAT32_BIAS;
 
107
        
 
108
        if (exp >= 0xFF) {
 
109
                /*FIXME: overflow*/
 
110
                result.parts.fraction = 0;
 
111
                result.parts.exp = 0xFF;
 
112
                return result;
 
113
                
 
114
        } else if (exp <= 0 ) {
 
115
                
 
116
                /* underflow or denormalized */
 
117
                
 
118
                result.parts.exp = 0;
 
119
                
 
120
                exp *= -1;      
 
121
                if (exp > FLOAT32_FRACTION_SIZE ) {
 
122
                        /* FIXME: underflow */
 
123
                        result.parts.fraction = 0;
 
124
                        return result;
 
125
                };
 
126
                
 
127
                /* denormalized */
 
128
                
 
129
                frac = a.parts.fraction; 
 
130
                frac |= 0x10000000000000ll; /* denormalize and set hidden bit */
 
131
                
 
132
                frac >>= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1);
 
133
                
 
134
                while (exp > 0) {
 
135
                        --exp;
 
136
                        frac >>= 1;
 
137
                };
 
138
                result.parts.fraction = frac;
 
139
                
 
140
                return result;
 
141
        };
 
142
 
 
143
        result.parts.exp = exp;
 
144
        result.parts.fraction = a.parts.fraction >> (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE);
 
145
        return result;
 
146
}
 
147
 
 
148
 
 
149
/** Helping procedure for converting float32 to uint32
 
150
 * @param a floating point number in normalized form (no NaNs or Inf are checked )
 
151
 * @return unsigned integer
 
152
 */
 
153
static uint32_t _float32_to_uint32_helper(float32 a)
 
154
{
 
155
        uint32_t frac;
 
156
        
 
157
        if (a.parts.exp < FLOAT32_BIAS) {
 
158
                /*TODO: rounding*/
 
159
                return 0;
 
160
        }
 
161
        
 
162
        frac = a.parts.fraction;
 
163
        
 
164
        frac |= FLOAT32_HIDDEN_BIT_MASK;
 
165
        /* shift fraction to left so hidden bit will be the most significant bit */
 
166
        frac <<= 32 - FLOAT32_FRACTION_SIZE - 1; 
 
167
 
 
168
        frac >>= 32 - (a.parts.exp - FLOAT32_BIAS) - 1;
 
169
        if ((a.parts.sign == 1) && (frac != 0)) {
 
170
                frac = ~frac;
 
171
                ++frac;
 
172
        }
 
173
        
 
174
        return frac;
 
175
}
 
176
 
 
177
/* Convert float to unsigned int32
 
178
 * FIXME: Im not sure what to return if overflow/underflow happens 
 
179
 *      - now its the biggest or the smallest int
 
180
 */ 
 
181
uint32_t float32_to_uint32(float32 a)
 
182
{
 
183
        if (isFloat32NaN(a)) {
 
184
                return MAX_UINT32;
 
185
        }
 
186
        
 
187
        if (isFloat32Infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS)))  {
 
188
                if (a.parts.sign) {
 
189
                        return MIN_UINT32;
 
190
                }
 
191
                return MAX_UINT32;
 
192
        }
 
193
        
 
194
        return _float32_to_uint32_helper(a);    
 
195
}
 
196
 
 
197
/* Convert float to signed int32
 
198
 * FIXME: Im not sure what to return if overflow/underflow happens 
 
199
 *      - now its the biggest or the smallest int
 
200
 */ 
 
201
int32_t float32_to_int32(float32 a)
 
202
{
 
203
        if (isFloat32NaN(a)) {
 
204
                return MAX_INT32;
 
205
        }
 
206
        
 
207
        if (isFloat32Infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS)))  {
 
208
                if (a.parts.sign) {
 
209
                        return MIN_INT32;
 
210
                }
 
211
                return MAX_INT32;
 
212
        }
 
213
        return _float32_to_uint32_helper(a);
 
214
}       
 
215
 
 
216
 
 
217
/** Helping procedure for converting float64 to uint64
 
218
 * @param a floating point number in normalized form (no NaNs or Inf are checked )
 
219
 * @return unsigned integer
 
220
 */
 
221
static uint64_t _float64_to_uint64_helper(float64 a)
 
222
{
 
223
        uint64_t frac;
 
224
        
 
225
        if (a.parts.exp < FLOAT64_BIAS) {
 
226
                /*TODO: rounding*/
 
227
                return 0;
 
228
        }
 
229
        
 
230
        frac = a.parts.fraction;
 
231
        
 
232
        frac |= FLOAT64_HIDDEN_BIT_MASK;
 
233
        /* shift fraction to left so hidden bit will be the most significant bit */
 
234
        frac <<= 64 - FLOAT64_FRACTION_SIZE - 1; 
 
235
 
 
236
        frac >>= 64 - (a.parts.exp - FLOAT64_BIAS) - 1;
 
237
        if ((a.parts.sign == 1) && (frac != 0)) {
 
238
                frac = ~frac;
 
239
                ++frac;
 
240
        }
 
241
        
 
242
        return frac;
 
243
}
 
244
 
 
245
/* Convert float to unsigned int64
 
246
 * FIXME: Im not sure what to return if overflow/underflow happens 
 
247
 *      - now its the biggest or the smallest int
 
248
 */ 
 
249
uint64_t float64_to_uint64(float64 a)
 
250
{
 
251
        if (isFloat64NaN(a)) {
 
252
                return MAX_UINT64;
 
253
        }
 
254
        
 
255
        if (isFloat64Infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS)))  {
 
256
                if (a.parts.sign) {
 
257
                        return MIN_UINT64;
 
258
                }
 
259
                return MAX_UINT64;
 
260
        }
 
261
        
 
262
        return _float64_to_uint64_helper(a);    
 
263
}
 
264
 
 
265
/* Convert float to signed int64
 
266
 * FIXME: Im not sure what to return if overflow/underflow happens 
 
267
 *      - now its the biggest or the smallest int
 
268
 */ 
 
269
int64_t float64_to_int64(float64 a)
 
270
{
 
271
        if (isFloat64NaN(a)) {
 
272
                return MAX_INT64;
 
273
        }
 
274
        
 
275
        if (isFloat64Infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS)))  {
 
276
                if (a.parts.sign) {
 
277
                        return MIN_INT64;
 
278
                }
 
279
                return MAX_INT64;
 
280
        }
 
281
        return _float64_to_uint64_helper(a);
 
282
}       
 
283
 
 
284
 
 
285
 
 
286
 
 
287
 
 
288
/** Helping procedure for converting float32 to uint64
 
289
 * @param a floating point number in normalized form (no NaNs or Inf are checked )
 
290
 * @return unsigned integer
 
291
 */
 
292
static uint64_t _float32_to_uint64_helper(float32 a)
 
293
{
 
294
        uint64_t frac;
 
295
        
 
296
        if (a.parts.exp < FLOAT32_BIAS) {
 
297
                /*TODO: rounding*/
 
298
                return 0;
 
299
        }
 
300
        
 
301
        frac = a.parts.fraction;
 
302
        
 
303
        frac |= FLOAT32_HIDDEN_BIT_MASK;
 
304
        /* shift fraction to left so hidden bit will be the most significant bit */
 
305
        frac <<= 64 - FLOAT32_FRACTION_SIZE - 1; 
 
306
 
 
307
        frac >>= 64 - (a.parts.exp - FLOAT32_BIAS) - 1;
 
308
        if ((a.parts.sign == 1) && (frac != 0)) {
 
309
                frac = ~frac;
 
310
                ++frac;
 
311
        }
 
312
        
 
313
        return frac;
 
314
}
 
315
 
 
316
/* Convert float to unsigned int64
 
317
 * FIXME: Im not sure what to return if overflow/underflow happens 
 
318
 *      - now its the biggest or the smallest int
 
319
 */ 
 
320
uint64_t float32_to_uint64(float32 a)
 
321
{
 
322
        if (isFloat32NaN(a)) {
 
323
                return MAX_UINT64;
 
324
        }
 
325
        
 
326
        if (isFloat32Infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS)))  {
 
327
                if (a.parts.sign) {
 
328
                        return MIN_UINT64;
 
329
                }
 
330
                return MAX_UINT64;
 
331
        }
 
332
        
 
333
        return _float32_to_uint64_helper(a);    
 
334
}
 
335
 
 
336
/* Convert float to signed int64
 
337
 * FIXME: Im not sure what to return if overflow/underflow happens 
 
338
 *      - now its the biggest or the smallest int
 
339
 */ 
 
340
int64_t float32_to_int64(float32 a)
 
341
{
 
342
        if (isFloat32NaN(a)) {
 
343
                return MAX_INT64;
 
344
        }
 
345
        
 
346
        if (isFloat32Infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS)))  {
 
347
                if (a.parts.sign) {
 
348
                        return (MIN_INT64);
 
349
                }
 
350
                return MAX_INT64;
 
351
        }
 
352
        return _float32_to_uint64_helper(a);
 
353
}       
 
354
 
 
355
 
 
356
/* Convert float64 to unsigned int32
 
357
 * FIXME: Im not sure what to return if overflow/underflow happens 
 
358
 *      - now its the biggest or the smallest int
 
359
 */ 
 
360
uint32_t float64_to_uint32(float64 a)
 
361
{
 
362
        if (isFloat64NaN(a)) {
 
363
                return MAX_UINT32;
 
364
        }
 
365
        
 
366
        if (isFloat64Infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS)))  {
 
367
                if (a.parts.sign) {
 
368
                        return MIN_UINT32;
 
369
                }
 
370
                return MAX_UINT32;
 
371
        }
 
372
        
 
373
        return (uint32_t)_float64_to_uint64_helper(a);  
 
374
}
 
375
 
 
376
/* Convert float64 to signed int32
 
377
 * FIXME: Im not sure what to return if overflow/underflow happens 
 
378
 *      - now its the biggest or the smallest int
 
379
 */ 
 
380
int32_t float64_to_int32(float64 a)
 
381
{
 
382
        if (isFloat64NaN(a)) {
 
383
                return MAX_INT32;
 
384
        }
 
385
        
 
386
        if (isFloat64Infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS)))  {
 
387
                if (a.parts.sign) {
 
388
                        return MIN_INT32;
 
389
                }
 
390
                return MAX_INT32;
 
391
        }
 
392
        return (int32_t)_float64_to_uint64_helper(a);
 
393
}       
 
394
 
 
395
/** Convert unsigned integer to float32
 
396
 *
 
397
 *
 
398
 */
 
399
float32 uint32_to_float32(uint32_t i)
 
400
{
 
401
        int counter;
 
402
        int32_t exp;
 
403
        float32 result;
 
404
        
 
405
        result.parts.sign = 0;
 
406
        result.parts.fraction = 0;
 
407
 
 
408
        counter = countZeroes32(i);
 
409
 
 
410
        exp = FLOAT32_BIAS + 32 - counter - 1;
 
411
        
 
412
        if (counter == 32) {
 
413
                result.binary = 0;
 
414
                return result;
 
415
        }
 
416
        
 
417
        if (counter > 0) {
 
418
                i <<= counter - 1;
 
419
        } else {
 
420
                i >>= 1;
 
421
        }
 
422
 
 
423
        roundFloat32(&exp, &i);
 
424
 
 
425
        result.parts.fraction = i >> 7;
 
426
        result.parts.exp = exp;
 
427
 
 
428
        return result;
 
429
}
 
430
 
 
431
float32 int32_to_float32(int32_t i) 
 
432
{
 
433
        float32 result;
 
434
 
 
435
        if (i < 0) {
 
436
                result = uint32_to_float32((uint32_t)(-i));
 
437
        } else {
 
438
                result = uint32_to_float32((uint32_t)i);
 
439
        }
 
440
        
 
441
        result.parts.sign = i < 0;
 
442
 
 
443
        return result;
 
444
}
 
445
 
 
446
 
 
447
float32 uint64_to_float32(uint64_t i) 
 
448
{
 
449
        int counter;
 
450
        int32_t exp;
 
451
        uint32_t j;
 
452
        float32 result;
 
453
        
 
454
        result.parts.sign = 0;
 
455
        result.parts.fraction = 0;
 
456
 
 
457
        counter = countZeroes64(i);
 
458
 
 
459
        exp = FLOAT32_BIAS + 64 - counter - 1;
 
460
        
 
461
        if (counter == 64) {
 
462
                result.binary = 0;
 
463
                return result;
 
464
        }
 
465
        
 
466
        /* Shift all to the first 31 bits (31. will be hidden 1)*/
 
467
        if (counter > 33) {
 
468
                i <<= counter - 1 - 32;
 
469
        } else {
 
470
                i >>= 1 + 32 - counter;
 
471
        }
 
472
        
 
473
        j = (uint32_t)i;
 
474
        roundFloat32(&exp, &j);
 
475
 
 
476
        result.parts.fraction = j >> 7;
 
477
        result.parts.exp = exp;
 
478
        return result;
 
479
}
 
480
 
 
481
float32 int64_to_float32(int64_t i) 
 
482
{
 
483
        float32 result;
 
484
 
 
485
        if (i < 0) {
 
486
                result = uint64_to_float32((uint64_t)(-i));
 
487
        } else {
 
488
                result = uint64_to_float32((uint64_t)i);
 
489
        }
 
490
        
 
491
        result.parts.sign = i < 0;
 
492
 
 
493
        return result;
 
494
}
 
495
 
 
496
/** Convert unsigned integer to float64
 
497
 *
 
498
 *
 
499
 */
 
500
float64 uint32_to_float64(uint32_t i)
 
501
{
 
502
        int counter;
 
503
        int32_t exp;
 
504
        float64 result;
 
505
        uint64_t frac;
 
506
        
 
507
        result.parts.sign = 0;
 
508
        result.parts.fraction = 0;
 
509
 
 
510
        counter = countZeroes32(i);
 
511
 
 
512
        exp = FLOAT64_BIAS + 32 - counter - 1;
 
513
        
 
514
        if (counter == 32) {
 
515
                result.binary = 0;
 
516
                return result;
 
517
        }
 
518
        
 
519
        frac = i;
 
520
        frac <<= counter + 32 - 1; 
 
521
 
 
522
        roundFloat64(&exp, &frac);
 
523
 
 
524
        result.parts.fraction = frac >> 10;
 
525
        result.parts.exp = exp;
 
526
 
 
527
        return result;
 
528
}
 
529
 
 
530
float64 int32_to_float64(int32_t i) 
 
531
{
 
532
        float64 result;
 
533
 
 
534
        if (i < 0) {
 
535
                result = uint32_to_float64((uint32_t)(-i));
 
536
        } else {
 
537
                result = uint32_to_float64((uint32_t)i);
 
538
        }
 
539
        
 
540
        result.parts.sign = i < 0;
 
541
 
 
542
        return result;
 
543
}
 
544
 
 
545
 
 
546
float64 uint64_to_float64(uint64_t i) 
 
547
{
 
548
        int counter;
 
549
        int32_t exp;
 
550
        float64 result;
 
551
        
 
552
        result.parts.sign = 0;
 
553
        result.parts.fraction = 0;
 
554
 
 
555
        counter = countZeroes64(i);
 
556
 
 
557
        exp = FLOAT64_BIAS + 64 - counter - 1;
 
558
        
 
559
        if (counter == 64) {
 
560
                result.binary = 0;
 
561
                return result;
 
562
        }
 
563
        
 
564
        if (counter > 0) {
 
565
                i <<= counter - 1;
 
566
        } else {
 
567
                i >>= 1;
 
568
        }
 
569
 
 
570
        roundFloat64(&exp, &i);
 
571
 
 
572
        result.parts.fraction = i >> 10;
 
573
        result.parts.exp = exp;
 
574
        return result;
 
575
}
 
576
 
 
577
float64 int64_to_float64(int64_t i) 
 
578
{
 
579
        float64 result;
 
580
 
 
581
        if (i < 0) {
 
582
                result = uint64_to_float64((uint64_t)(-i));
 
583
        } else {
 
584
                result = uint64_to_float64((uint64_t)i);
 
585
        }
 
586
        
 
587
        result.parts.sign = i < 0;
 
588
 
 
589
        return result;
 
590
}
 
591
 
 
592
/** @}
 
593
 */