OpenCores
URL https://opencores.org/ocsvn/fpu100/fpu100/trunk

Subversion Repositories fpu100

[/] [fpu100/] [tags/] [arelease/] [test_bench/] [SoftFloat/] [softfloat/] [bits64/] [386-Win32-GCC/] [softfloat-specialize] - Blame information for rev 27

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 jidan
 
2
/*============================================================================
3
 
4
This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
5
Arithmetic Package, Release 2b.
6
 
7
Written by John R. Hauser.  This work was made possible in part by the
8
International Computer Science Institute, located at Suite 600, 1947 Center
9
Street, Berkeley, California 94704.  Funding was partially provided by the
10
National Science Foundation under grant MIP-9311980.  The original version
11
of this code was written as part of a project to build a fixed-point vector
12
processor in collaboration with the University of California at Berkeley,
13
overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
14
is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
15
arithmetic/SoftFloat.html'.
16
 
17
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort has
18
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
19
RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
20
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
21
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
22
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
23
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
24
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
25
 
26
Derivative works are acceptable, even for commercial purposes, so long as
27
(1) the source code for the derivative work includes prominent notice that
28
the work is derivative, and (2) the source code includes prominent notice with
29
these four paragraphs for those parts of this code that are retained.
30
 
31
=============================================================================*/
32
 
33
/*----------------------------------------------------------------------------
34
| Underflow tininess-detection mode, statically initialized to default value.
35
| (The declaration in `softfloat.h' must match the `int8' type here.)
36
*----------------------------------------------------------------------------*/
37
int8 float_detect_tininess = float_tininess_after_rounding;
38
 
39
/*----------------------------------------------------------------------------
40
| Raises the exceptions specified by `flags'.  Floating-point traps can be
41
| defined here if desired.  It is currently not possible for such a trap
42
| to substitute a result value.  If traps are not implemented, this routine
43
| should be simply `float_exception_flags |= flags;'.
44
*----------------------------------------------------------------------------*/
45
 
46
void float_raise( int8 flags )
47
{
48
 
49
    float_exception_flags |= flags;
50
 
51
}
52
 
53
/*----------------------------------------------------------------------------
54
| Internal canonical NaN format.
55
*----------------------------------------------------------------------------*/
56
typedef struct {
57
    flag sign;
58
    bits64 high, low;
59
} commonNaNT;
60
 
61
/*----------------------------------------------------------------------------
62
| The pattern for a default generated single-precision NaN.
63
*----------------------------------------------------------------------------*/
64
#define float32_default_nan 0xFFC00000
65
 
66
/*----------------------------------------------------------------------------
67
| Returns 1 if the single-precision floating-point value `a' is a NaN;
68
| otherwise returns 0.
69
*----------------------------------------------------------------------------*/
70
 
71
flag float32_is_nan( float32 a )
72
{
73
 
74
    return ( 0xFF000000 < (bits32) ( a<<1 ) );
75
 
76
}
77
 
78
/*----------------------------------------------------------------------------
79
| Returns 1 if the single-precision floating-point value `a' is a signaling
80
| NaN; otherwise returns 0.
81
*----------------------------------------------------------------------------*/
82
 
83
flag float32_is_signaling_nan( float32 a )
84
{
85
 
86
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
87
 
88
}
89
 
90
/*----------------------------------------------------------------------------
91
| Returns the result of converting the single-precision floating-point NaN
92
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
93
| exception is raised.
94
*----------------------------------------------------------------------------*/
95
 
96
static commonNaNT float32ToCommonNaN( float32 a )
97
{
98
    commonNaNT z;
99
 
100
    if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
101
    z.sign = a>>31;
102
    z.low = 0;
103
    z.high = ( (bits64) a )<<41;
104
    return z;
105
 
106
}
107
 
108
/*----------------------------------------------------------------------------
109
| Returns the result of converting the canonical NaN `a' to the single-
110
| precision floating-point format.
111
*----------------------------------------------------------------------------*/
112
 
113
static float32 commonNaNToFloat32( commonNaNT a )
114
{
115
 
116
    return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
117
 
118
}
119
 
120
/*----------------------------------------------------------------------------
121
| Takes two single-precision floating-point values `a' and `b', one of which
122
| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
123
| signaling NaN, the invalid exception is raised.
124
*----------------------------------------------------------------------------*/
125
 
126
static float32 propagateFloat32NaN( float32 a, float32 b )
127
{
128
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
129
 
130
    aIsNaN = float32_is_nan( a );
131
    aIsSignalingNaN = float32_is_signaling_nan( a );
132
    bIsNaN = float32_is_nan( b );
133
    bIsSignalingNaN = float32_is_signaling_nan( b );
134
    a |= 0x00400000;
135
    b |= 0x00400000;
136
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
137
    if ( aIsSignalingNaN ) {
138
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
139
        return bIsNaN ? b : a;
140
    }
141
    else if ( aIsNaN ) {
142
        if ( bIsSignalingNaN | ! bIsNaN ) return a;
143
 returnLargerSignificand:
144
        if ( (bits32) ( a<<1 ) < (bits32) ( b<<1 ) ) return b;
145
        if ( (bits32) ( b<<1 ) < (bits32) ( a<<1 ) ) return a;
146
        return ( a < b ) ? a : b;
147
    }
148
    else {
149
        return b;
150
    }
151
 
152
}
153
 
154
/*----------------------------------------------------------------------------
155
| The pattern for a default generated double-precision NaN.
156
*----------------------------------------------------------------------------*/
157
#define float64_default_nan LIT64( 0xFFF8000000000000 )
158
 
159
/*----------------------------------------------------------------------------
160
| Returns 1 if the double-precision floating-point value `a' is a NaN;
161
| otherwise returns 0.
162
*----------------------------------------------------------------------------*/
163
 
164
flag float64_is_nan( float64 a )
165
{
166
 
167
    return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
168
 
169
}
170
 
171
/*----------------------------------------------------------------------------
172
| Returns 1 if the double-precision floating-point value `a' is a signaling
173
| NaN; otherwise returns 0.
174
*----------------------------------------------------------------------------*/
175
 
176
flag float64_is_signaling_nan( float64 a )
177
{
178
 
179
    return
180
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
181
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
182
 
183
}
184
 
185
/*----------------------------------------------------------------------------
186
| Returns the result of converting the double-precision floating-point NaN
187
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
188
| exception is raised.
189
*----------------------------------------------------------------------------*/
190
 
191
static commonNaNT float64ToCommonNaN( float64 a )
192
{
193
    commonNaNT z;
194
 
195
    if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
196
    z.sign = a>>63;
197
    z.low = 0;
198
    z.high = a<<12;
199
    return z;
200
 
201
}
202
 
203
/*----------------------------------------------------------------------------
204
| Returns the result of converting the canonical NaN `a' to the double-
205
| precision floating-point format.
206
*----------------------------------------------------------------------------*/
207
 
208
static float64 commonNaNToFloat64( commonNaNT a )
209
{
210
 
211
    return
212
          ( ( (bits64) a.sign )<<63 )
213
        | LIT64( 0x7FF8000000000000 )
214
        | ( a.high>>12 );
215
 
216
}
217
 
218
/*----------------------------------------------------------------------------
219
| Takes two double-precision floating-point values `a' and `b', one of which
220
| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
221
| signaling NaN, the invalid exception is raised.
222
*----------------------------------------------------------------------------*/
223
 
224
static float64 propagateFloat64NaN( float64 a, float64 b )
225
{
226
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
227
 
228
    aIsNaN = float64_is_nan( a );
229
    aIsSignalingNaN = float64_is_signaling_nan( a );
230
    bIsNaN = float64_is_nan( b );
231
    bIsSignalingNaN = float64_is_signaling_nan( b );
232
    a |= LIT64( 0x0008000000000000 );
233
    b |= LIT64( 0x0008000000000000 );
234
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
235
    if ( aIsSignalingNaN ) {
236
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
237
        return bIsNaN ? b : a;
238
    }
239
    else if ( aIsNaN ) {
240
        if ( bIsSignalingNaN | ! bIsNaN ) return a;
241
 returnLargerSignificand:
242
        if ( (bits64) ( a<<1 ) < (bits64) ( b<<1 ) ) return b;
243
        if ( (bits64) ( b<<1 ) < (bits64) ( a<<1 ) ) return a;
244
        return ( a < b ) ? a : b;
245
    }
246
    else {
247
        return b;
248
    }
249
 
250
}
251
 
252
#ifdef FLOATX80
253
 
254
/*----------------------------------------------------------------------------
255
| The pattern for a default generated extended double-precision NaN.  The
256
| `high' and `low' values hold the most- and least-significant bits,
257
| respectively.
258
*----------------------------------------------------------------------------*/
259
#define floatx80_default_nan_high 0xFFFF
260
#define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
261
 
262
/*----------------------------------------------------------------------------
263
| Returns 1 if the extended double-precision floating-point value `a' is a
264
| NaN; otherwise returns 0.
265
*----------------------------------------------------------------------------*/
266
 
267
flag floatx80_is_nan( floatx80 a )
268
{
269
 
270
    return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
271
 
272
}
273
 
274
/*----------------------------------------------------------------------------
275
| Returns 1 if the extended double-precision floating-point value `a' is a
276
| signaling NaN; otherwise returns 0.
277
*----------------------------------------------------------------------------*/
278
 
279
flag floatx80_is_signaling_nan( floatx80 a )
280
{
281
    bits64 aLow;
282
 
283
    aLow = a.low & ~ LIT64( 0x4000000000000000 );
284
    return
285
           ( ( a.high & 0x7FFF ) == 0x7FFF )
286
        && (bits64) ( aLow<<1 )
287
        && ( a.low == aLow );
288
 
289
}
290
 
291
/*----------------------------------------------------------------------------
292
| Returns the result of converting the extended double-precision floating-
293
| point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
294
| invalid exception is raised.
295
*----------------------------------------------------------------------------*/
296
 
297
static commonNaNT floatx80ToCommonNaN( floatx80 a )
298
{
299
    commonNaNT z;
300
 
301
    if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
302
    z.sign = a.high>>15;
303
    z.low = 0;
304
    z.high = a.low<<1;
305
    return z;
306
 
307
}
308
 
309
/*----------------------------------------------------------------------------
310
| Returns the result of converting the canonical NaN `a' to the extended
311
| double-precision floating-point format.
312
*----------------------------------------------------------------------------*/
313
 
314
static floatx80 commonNaNToFloatx80( commonNaNT a )
315
{
316
    floatx80 z;
317
 
318
    z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
319
    z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
320
    return z;
321
 
322
}
323
 
324
/*----------------------------------------------------------------------------
325
| Takes two extended double-precision floating-point values `a' and `b', one
326
| of which is a NaN, and returns the appropriate NaN result.  If either `a' or
327
| `b' is a signaling NaN, the invalid exception is raised.
328
*----------------------------------------------------------------------------*/
329
 
330
static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
331
{
332
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
333
 
334
    aIsNaN = floatx80_is_nan( a );
335
    aIsSignalingNaN = floatx80_is_signaling_nan( a );
336
    bIsNaN = floatx80_is_nan( b );
337
    bIsSignalingNaN = floatx80_is_signaling_nan( b );
338
    a.low |= LIT64( 0xC000000000000000 );
339
    b.low |= LIT64( 0xC000000000000000 );
340
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
341
    if ( aIsSignalingNaN ) {
342
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
343
        return bIsNaN ? b : a;
344
    }
345
    else if ( aIsNaN ) {
346
        if ( bIsSignalingNaN | ! bIsNaN ) return a;
347
 returnLargerSignificand:
348
        if ( a.low < b.low ) return b;
349
        if ( b.low < a.low ) return a;
350
        return ( a.high < b.high ) ? a : b;
351
    }
352
    else {
353
        return b;
354
    }
355
 
356
}
357
 
358
#endif
359
 
360
#ifdef FLOAT128
361
 
362
/*----------------------------------------------------------------------------
363
| The pattern for a default generated quadruple-precision NaN.  The `high' and
364
| `low' values hold the most- and least-significant bits, respectively.
365
*----------------------------------------------------------------------------*/
366
#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
367
#define float128_default_nan_low  LIT64( 0x0000000000000000 )
368
 
369
/*----------------------------------------------------------------------------
370
| Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
371
| otherwise returns 0.
372
*----------------------------------------------------------------------------*/
373
 
374
flag float128_is_nan( float128 a )
375
{
376
 
377
    return
378
           ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
379
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
380
 
381
}
382
 
383
/*----------------------------------------------------------------------------
384
| Returns 1 if the quadruple-precision floating-point value `a' is a
385
| signaling NaN; otherwise returns 0.
386
*----------------------------------------------------------------------------*/
387
 
388
flag float128_is_signaling_nan( float128 a )
389
{
390
 
391
    return
392
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
393
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
394
 
395
}
396
 
397
/*----------------------------------------------------------------------------
398
| Returns the result of converting the quadruple-precision floating-point NaN
399
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
400
| exception is raised.
401
*----------------------------------------------------------------------------*/
402
 
403
static commonNaNT float128ToCommonNaN( float128 a )
404
{
405
    commonNaNT z;
406
 
407
    if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
408
    z.sign = a.high>>63;
409
    shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
410
    return z;
411
 
412
}
413
 
414
/*----------------------------------------------------------------------------
415
| Returns the result of converting the canonical NaN `a' to the quadruple-
416
| precision floating-point format.
417
*----------------------------------------------------------------------------*/
418
 
419
static float128 commonNaNToFloat128( commonNaNT a )
420
{
421
    float128 z;
422
 
423
    shift128Right( a.high, a.low, 16, &z.high, &z.low );
424
    z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
425
    return z;
426
 
427
}
428
 
429
/*----------------------------------------------------------------------------
430
| Takes two quadruple-precision floating-point values `a' and `b', one of
431
| which is a NaN, and returns the appropriate NaN result.  If either `a' or
432
| `b' is a signaling NaN, the invalid exception is raised.
433
*----------------------------------------------------------------------------*/
434
 
435
static float128 propagateFloat128NaN( float128 a, float128 b )
436
{
437
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
438
 
439
    aIsNaN = float128_is_nan( a );
440
    aIsSignalingNaN = float128_is_signaling_nan( a );
441
    bIsNaN = float128_is_nan( b );
442
    bIsSignalingNaN = float128_is_signaling_nan( b );
443
    a.high |= LIT64( 0x0000800000000000 );
444
    b.high |= LIT64( 0x0000800000000000 );
445
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
446
    if ( aIsSignalingNaN ) {
447
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
448
        return bIsNaN ? b : a;
449
    }
450
    else if ( aIsNaN ) {
451
        if ( bIsSignalingNaN | ! bIsNaN ) return a;
452
 returnLargerSignificand:
453
        if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
454
        if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
455
        return ( a.high < b.high ) ? a : b;
456
    }
457
    else {
458
        return b;
459
    }
460
 
461
}
462
 
463
#endif
464
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.