|
|
1.1 root 1:
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 STATUS_PARAM )
47: {
48:
49: STATUS(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:
1.1.1.2 ! root 71: int float32_is_nan( float32 a )
1.1 root 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:
1.1.1.2 ! root 83: int float32_is_signaling_nan( float32 a )
1.1 root 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 STATUS_PARAM )
97: {
98: commonNaNT z;
99:
100: if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
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 STATUS_PARAM)
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 STATUS_VAR);
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:
1.1.1.2 ! root 164: int float64_is_nan( float64 a )
1.1 root 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:
1.1.1.2 ! root 176: int float64_is_signaling_nan( float64 a )
1.1 root 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 STATUS_PARAM)
192: {
193: commonNaNT z;
194:
195: if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
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 STATUS_PARAM)
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 STATUS_VAR);
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:
1.1.1.2 ! root 267: int floatx80_is_nan( floatx80 a )
1.1 root 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:
1.1.1.2 ! root 279: int floatx80_is_signaling_nan( floatx80 a )
1.1 root 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 STATUS_PARAM)
298: {
299: commonNaNT z;
300:
301: if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
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 STATUS_PARAM)
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 STATUS_VAR);
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:
1.1.1.2 ! root 374: int float128_is_nan( float128 a )
1.1 root 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:
1.1.1.2 ! root 388: int float128_is_signaling_nan( float128 a )
1.1 root 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 STATUS_PARAM)
404: {
405: commonNaNT z;
406:
407: if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
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 STATUS_PARAM)
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 STATUS_VAR);
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.