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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [softfloat/] [softfloat-specialize] - Blame information for rev 233

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 233 julius
 
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 to
42
| 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 0xFFFFFFFF
65
#define float32_default_nan 0xFFC00000
66
 
67
/*----------------------------------------------------------------------------
68
| Returns 1 if the single-precision floating-point value `a' is a NaN;
69
| otherwise returns 0.
70
*----------------------------------------------------------------------------*/
71
 
72
flag float32_is_nan( float32 a )
73
{
74
 
75
    return ( 0xFF000000 < (bits32) ( a<<1 ) );
76
 
77
}
78
 
79
/*----------------------------------------------------------------------------
80
| Returns 1 if the single-precision floating-point value `a' is a signaling
81
| NaN; otherwise returns 0.
82
*----------------------------------------------------------------------------*/
83
 
84
flag float32_is_signaling_nan( float32 a )
85
{
86
 
87
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
88
 
89
}
90
 
91
/*----------------------------------------------------------------------------
92
| Returns the result of converting the single-precision floating-point NaN
93
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
94
| exception is raised.
95
*----------------------------------------------------------------------------*/
96
 
97
static commonNaNT float32ToCommonNaN( float32 a )
98
{
99
    commonNaNT z;
100
 
101
    if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
102
    z.sign = a>>31;
103
    z.low = 0;
104
    z.high = ( (bits64) a )<<41;
105
    return z;
106
 
107
}
108
 
109
/*----------------------------------------------------------------------------
110
| Returns the result of converting the canonical NaN `a' to the single-
111
| precision floating-point format.
112
*----------------------------------------------------------------------------*/
113
 
114
static float32 commonNaNToFloat32( commonNaNT a )
115
{
116
 
117
    return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
118
 
119
}
120
 
121
/*----------------------------------------------------------------------------
122
| Takes two single-precision floating-point values `a' and `b', one of which
123
| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
124
| signaling NaN, the invalid exception is raised.
125
*----------------------------------------------------------------------------*/
126
 
127
static float32 propagateFloat32NaN( float32 a, float32 b )
128
{
129
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
130
 
131
    aIsNaN = float32_is_nan( a );
132
    aIsSignalingNaN = float32_is_signaling_nan( a );
133
    bIsNaN = float32_is_nan( b );
134
    bIsSignalingNaN = float32_is_signaling_nan( b );
135
    a |= 0x00400000;
136
    b |= 0x00400000;
137
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
138
    if ( aIsNaN ) {
139
        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
140
    }
141
    else {
142
        return b;
143
    }
144
 
145
}
146
 
147
/*----------------------------------------------------------------------------
148
| The pattern for a default generated double-precision NaN.
149
*----------------------------------------------------------------------------*/
150
#define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF )
151
 
152
/*----------------------------------------------------------------------------
153
| Returns 1 if the double-precision floating-point value `a' is a NaN;
154
| otherwise returns 0.
155
*----------------------------------------------------------------------------*/
156
 
157
flag float64_is_nan( float64 a )
158
{
159
 
160
    return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
161
 
162
}
163
 
164
/*----------------------------------------------------------------------------
165
| Returns 1 if the double-precision floating-point value `a' is a signaling
166
| NaN; otherwise returns 0.
167
*----------------------------------------------------------------------------*/
168
 
169
flag float64_is_signaling_nan( float64 a )
170
{
171
 
172
    return
173
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
174
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
175
 
176
}
177
 
178
/*----------------------------------------------------------------------------
179
| Returns the result of converting the double-precision floating-point NaN
180
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
181
| exception is raised.
182
*----------------------------------------------------------------------------*/
183
 
184
static commonNaNT float64ToCommonNaN( float64 a )
185
{
186
    commonNaNT z;
187
 
188
    if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
189
    z.sign = a>>63;
190
    z.low = 0;
191
    z.high = a<<12;
192
    return z;
193
 
194
}
195
 
196
/*----------------------------------------------------------------------------
197
| Returns the result of converting the canonical NaN `a' to the double-
198
| precision floating-point format.
199
*----------------------------------------------------------------------------*/
200
 
201
static float64 commonNaNToFloat64( commonNaNT a )
202
{
203
 
204
    return
205
          ( ( (bits64) a.sign )<<63 )
206
        | LIT64( 0x7FF8000000000000 )
207
        | ( a.high>>12 );
208
 
209
}
210
 
211
/*----------------------------------------------------------------------------
212
| Takes two double-precision floating-point values `a' and `b', one of which
213
| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
214
| signaling NaN, the invalid exception is raised.
215
*----------------------------------------------------------------------------*/
216
 
217
static float64 propagateFloat64NaN( float64 a, float64 b )
218
{
219
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
220
 
221
    aIsNaN = float64_is_nan( a );
222
    aIsSignalingNaN = float64_is_signaling_nan( a );
223
    bIsNaN = float64_is_nan( b );
224
    bIsSignalingNaN = float64_is_signaling_nan( b );
225
    a |= LIT64( 0x0008000000000000 );
226
    b |= LIT64( 0x0008000000000000 );
227
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
228
    if ( aIsNaN ) {
229
        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
230
    }
231
    else {
232
        return b;
233
    }
234
 
235
}
236
 
237
#ifdef FLOATX80
238
 
239
/*----------------------------------------------------------------------------
240
| The pattern for a default generated extended double-precision NaN.  The
241
| `high' and `low' values hold the most- and least-significant bits,
242
| respectively.
243
*----------------------------------------------------------------------------*/
244
#define floatx80_default_nan_high 0xFFFF
245
#define floatx80_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
246
 
247
/*----------------------------------------------------------------------------
248
| Returns 1 if the extended double-precision floating-point value `a' is a
249
| NaN; otherwise returns 0.
250
*----------------------------------------------------------------------------*/
251
 
252
flag floatx80_is_nan( floatx80 a )
253
{
254
 
255
    return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
256
 
257
}
258
 
259
/*----------------------------------------------------------------------------
260
| Returns 1 if the extended double-precision floating-point value `a' is a
261
| signaling NaN; otherwise returns 0.
262
*----------------------------------------------------------------------------*/
263
 
264
flag floatx80_is_signaling_nan( floatx80 a )
265
{
266
    bits64 aLow;
267
 
268
    aLow = a.low & ~ LIT64( 0x4000000000000000 );
269
    return
270
           ( ( a.high & 0x7FFF ) == 0x7FFF )
271
        && (bits64) ( aLow<<1 )
272
        && ( a.low == aLow );
273
 
274
}
275
 
276
/*----------------------------------------------------------------------------
277
| Returns the result of converting the extended double-precision floating-
278
| point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
279
| invalid exception is raised.
280
*----------------------------------------------------------------------------*/
281
 
282
static commonNaNT floatx80ToCommonNaN( floatx80 a )
283
{
284
    commonNaNT z;
285
 
286
    if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
287
    z.sign = a.high>>15;
288
    z.low = 0;
289
    z.high = a.low<<1;
290
    return z;
291
 
292
}
293
 
294
/*----------------------------------------------------------------------------
295
| Returns the result of converting the canonical NaN `a' to the extended
296
| double-precision floating-point format.
297
*----------------------------------------------------------------------------*/
298
 
299
static floatx80 commonNaNToFloatx80( commonNaNT a )
300
{
301
    floatx80 z;
302
 
303
    z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
304
    z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
305
    return z;
306
 
307
}
308
 
309
/*----------------------------------------------------------------------------
310
| Takes two extended double-precision floating-point values `a' and `b', one
311
| of which is a NaN, and returns the appropriate NaN result.  If either `a' or
312
| `b' is a signaling NaN, the invalid exception is raised.
313
*----------------------------------------------------------------------------*/
314
 
315
static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
316
{
317
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
318
 
319
    aIsNaN = floatx80_is_nan( a );
320
    aIsSignalingNaN = floatx80_is_signaling_nan( a );
321
    bIsNaN = floatx80_is_nan( b );
322
    bIsSignalingNaN = floatx80_is_signaling_nan( b );
323
    a.low |= LIT64( 0xC000000000000000 );
324
    b.low |= LIT64( 0xC000000000000000 );
325
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
326
    if ( aIsNaN ) {
327
        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
328
    }
329
    else {
330
        return b;
331
    }
332
 
333
}
334
 
335
#endif
336
 
337
#ifdef FLOAT128
338
 
339
/*----------------------------------------------------------------------------
340
| The pattern for a default generated quadruple-precision NaN.  The `high' and
341
| `low' values hold the most- and least-significant bits, respectively.
342
*----------------------------------------------------------------------------*/
343
#define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF )
344
#define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
345
 
346
/*----------------------------------------------------------------------------
347
| Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
348
| otherwise returns 0.
349
*----------------------------------------------------------------------------*/
350
 
351
flag float128_is_nan( float128 a )
352
{
353
 
354
    return
355
           ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
356
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
357
 
358
}
359
 
360
/*----------------------------------------------------------------------------
361
| Returns 1 if the quadruple-precision floating-point value `a' is a
362
| signaling NaN; otherwise returns 0.
363
*----------------------------------------------------------------------------*/
364
 
365
flag float128_is_signaling_nan( float128 a )
366
{
367
 
368
    return
369
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
370
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
371
 
372
}
373
 
374
/*----------------------------------------------------------------------------
375
| Returns the result of converting the quadruple-precision floating-point NaN
376
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
377
| exception is raised.
378
*----------------------------------------------------------------------------*/
379
 
380
static commonNaNT float128ToCommonNaN( float128 a )
381
{
382
    commonNaNT z;
383
 
384
    if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
385
    z.sign = a.high>>63;
386
    shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
387
    return z;
388
 
389
}
390
 
391
/*----------------------------------------------------------------------------
392
| Returns the result of converting the canonical NaN `a' to the quadruple-
393
| precision floating-point format.
394
*----------------------------------------------------------------------------*/
395
 
396
static float128 commonNaNToFloat128( commonNaNT a )
397
{
398
    float128 z;
399
 
400
    shift128Right( a.high, a.low, 16, &z.high, &z.low );
401
    z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
402
    return z;
403
 
404
}
405
 
406
/*----------------------------------------------------------------------------
407
| Takes two quadruple-precision floating-point values `a' and `b', one of
408
| which is a NaN, and returns the appropriate NaN result.  If either `a' or
409
| `b' is a signaling NaN, the invalid exception is raised.
410
*----------------------------------------------------------------------------*/
411
 
412
static float128 propagateFloat128NaN( float128 a, float128 b )
413
{
414
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
415
 
416
    aIsNaN = float128_is_nan( a );
417
    aIsSignalingNaN = float128_is_signaling_nan( a );
418
    bIsNaN = float128_is_nan( b );
419
    bIsSignalingNaN = float128_is_signaling_nan( b );
420
    a.high |= LIT64( 0x0000800000000000 );
421
    b.high |= LIT64( 0x0000800000000000 );
422
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
423
    if ( aIsNaN ) {
424
        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
425
    }
426
    else {
427
        return b;
428
    }
429
 
430
}
431
 
432
#endif
433
 

powered by: WebSVN 2.1.0

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