|
|
1.1 root 1: /*
2: * QEMU float support
3: *
4: * The code in this source file is derived from release 2a of the SoftFloat
5: * IEC/IEEE Floating-point Arithmetic Package. Those parts of the code (and
6: * some later contributions) are provided under that license, as detailed below.
7: * It has subsequently been modified by contributors to the QEMU Project,
8: * so some portions are provided under:
9: * the SoftFloat-2a license
10: * the BSD license
11: * GPL-v2-or-later
12: *
13: * Any future contributions to this file after December 1st 2014 will be
14: * taken to be licensed under the Softfloat-2a license unless specifically
15: * indicated otherwise.
16: */
17:
18: /*
19: ===============================================================================
20: This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
21: Arithmetic Package, Release 2a.
22:
23: Written by John R. Hauser. This work was made possible in part by the
24: International Computer Science Institute, located at Suite 600, 1947 Center
25: Street, Berkeley, California 94704. Funding was partially provided by the
26: National Science Foundation under grant MIP-9311980. The original version
27: of this code was written as part of a project to build a fixed-point vector
28: processor in collaboration with the University of California at Berkeley,
29: overseen by Profs. Nelson Morgan and John Wawrzynek. More information
30: is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
31: arithmetic/SoftFloat.html'.
32:
33: THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
34: has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
35: TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
36: PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
37: AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
38:
39: Derivative works are acceptable, even for commercial purposes, so long as
40: (1) they include prominent notice that the work is derivative, and (2) they
41: include prominent notice akin to these four paragraphs for those parts of
42: this code that are retained.
43:
44: ===============================================================================
45: */
46:
47: /* BSD licensing:
48: * Copyright (c) 2006, Fabrice Bellard
49: * All rights reserved.
50: *
51: * Redistribution and use in source and binary forms, with or without
52: * modification, are permitted provided that the following conditions are met:
53: *
54: * 1. Redistributions of source code must retain the above copyright notice,
55: * this list of conditions and the following disclaimer.
56: *
57: * 2. Redistributions in binary form must reproduce the above copyright notice,
58: * this list of conditions and the following disclaimer in the documentation
59: * and/or other materials provided with the distribution.
60: *
61: * 3. Neither the name of the copyright holder nor the names of its contributors
62: * may be used to endorse or promote products derived from this software without
63: * specific prior written permission.
64: *
65: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
66: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
67: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
68: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
69: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
70: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
71: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
72: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
73: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
74: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
75: * THE POSSIBILITY OF SUCH DAMAGE.
76: */
77:
78: /* Portions of this work are licensed under the terms of the GNU GPL,
79: * version 2 or later. See the COPYING file in the top-level directory.
80: */
81:
82: /*----------------------------------------------------------------------------
83: | Returns 1 if the extended double-precision floating-point value `a' is a
84: | NaN; otherwise returns 0.
85: *----------------------------------------------------------------------------*/
86:
87: static inline flag floatx80_is_nan( floatx80 a )
88: {
89:
90: return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (uint64_t) ( a.low<<1 );
91:
92: }
93:
94: /*----------------------------------------------------------------------------
95: | The pattern for a default generated extended double-precision NaN.
96: *----------------------------------------------------------------------------*/
97: static inline floatx80 floatx80_default_nan(float_status *status)
98: {
99: floatx80 r;
100: r.high = 0x7FFF;
101: r.low = LIT64( 0xFFFFFFFFFFFFFFFF );
102: return r;
103: }
104:
105: /*----------------------------------------------------------------------------
106: | Raises the exceptions specified by `flags'. Floating-point traps can be
107: | defined here if desired. It is currently not possible for such a trap
108: | to substitute a result value. If traps are not implemented, this routine
109: | should be simply `float_exception_flags |= flags;'.
110: *----------------------------------------------------------------------------*/
111:
112: static inline void float_raise(uint8_t flags, float_status *status)
113: {
114: status->float_exception_flags |= flags;
115: }
116:
117: /*----------------------------------------------------------------------------
118: | Internal canonical NaN format.
119: *----------------------------------------------------------------------------*/
120: typedef struct {
121: flag sign;
122: uint64_t high, low;
123: } commonNaNT;
124:
125: /*----------------------------------------------------------------------------
126: | Returns 1 if the single-precision floating-point value `a' is a NaN;
127: | otherwise returns 0.
128: *----------------------------------------------------------------------------*/
129:
130: static inline flag float32_is_nan( float32 a )
131: {
132:
133: return ( 0xFF000000 < (uint32_t) ( a<<1 ) );
134:
135: }
136:
137: /*----------------------------------------------------------------------------
138: | Returns 1 if the single-precision floating-point value `a' is a signaling
139: | NaN; otherwise returns 0.
140: *----------------------------------------------------------------------------*/
141:
142: static inline flag float32_is_signaling_nan( float32 a )
143: {
144:
145: return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
146:
147: }
148:
149: /*----------------------------------------------------------------------------
150: | Returns the result of converting the single-precision floating-point NaN
151: | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
152: | exception is raised.
153: *----------------------------------------------------------------------------*/
154:
155: static inline commonNaNT float32ToCommonNaN( float32 a, float_status *status )
156: {
157: commonNaNT z;
158:
159: if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_signaling, status );
160: z.sign = a>>31;
161: z.low = 0;
162: z.high = ( (uint64_t) a )<<41;
163: return z;
164:
165: }
166:
167: /*----------------------------------------------------------------------------
168: | Returns the result of converting the canonical NaN `a' to the single-
169: | precision floating-point format.
170: *----------------------------------------------------------------------------*/
171:
172: static inline float32 commonNaNToFloat32( commonNaNT a )
173: {
174:
175: return ( ( (uint32_t) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
176:
177: }
178:
179: /*----------------------------------------------------------------------------
180: | Takes two single-precision floating-point values `a' and `b', one of which
181: | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
182: | signaling NaN, the invalid exception is raised.
183: *----------------------------------------------------------------------------*/
184:
185: static inline float32 propagateFloat32NaN( float32 a, float32 b, float_status *status )
186: {
187: flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
188:
189: aIsNaN = float32_is_nan( a );
190: aIsSignalingNaN = float32_is_signaling_nan( a );
191: bIsNaN = float32_is_nan( b );
192: bIsSignalingNaN = float32_is_signaling_nan( b );
193: a |= 0x00400000;
194: b |= 0x00400000;
195: if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_signaling, status );
196: if ( aIsNaN ) {
197: return ( aIsSignalingNaN & bIsNaN ) ? b : a;
198: }
199: else {
200: return b;
201: }
202:
203: }
204:
205: /*----------------------------------------------------------------------------
206: | Returns 1 if the double-precision floating-point value `a' is a NaN;
207: | otherwise returns 0.
208: *----------------------------------------------------------------------------*/
209:
210: static inline flag float64_is_nan( float64 a )
211: {
212:
213: return ( LIT64( 0xFFE0000000000000 ) < (uint64_t) ( a<<1 ) );
214:
215: }
216:
217: /*----------------------------------------------------------------------------
218: | Returns 1 if the double-precision floating-point value `a' is a signaling
219: | NaN; otherwise returns 0.
220: *----------------------------------------------------------------------------*/
221:
222: static inline flag float64_is_signaling_nan( float64 a )
223: {
224:
225: return
226: ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
227: && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
228:
229: }
230:
231: /*----------------------------------------------------------------------------
232: | Returns the result of converting the double-precision floating-point NaN
233: | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
234: | exception is raised.
235: *----------------------------------------------------------------------------*/
236:
237: static inline commonNaNT float64ToCommonNaN(float64 a, float_status *status)
238: {
239: commonNaNT z;
240:
241: if (float64_is_signaling_nan(a)) {
242: float_raise(float_flag_invalid, status);
243: }
244: z.sign = float64_val(a) >> 63;
245: z.low = 0;
246: z.high = float64_val(a) << 12;
247: return z;
248: }
249:
250: /*----------------------------------------------------------------------------
251: | Returns the result of converting the canonical NaN `a' to the double-
252: | precision floating-point format.
253: *----------------------------------------------------------------------------*/
254:
255: static inline float64 commonNaNToFloat64(commonNaNT a, float_status *status)
256: {
257: return
258: ( ( (uint64_t) a.sign )<<63 )
259: | LIT64( 0x7FF8000000000000 )
260: | ( a.high>>12 );
261: }
262:
263: /*----------------------------------------------------------------------------
264: | Returns 1 if the extended double-precision floating-point value `a' is a
265: | signaling NaN; otherwise returns 0.
266: *----------------------------------------------------------------------------*/
267:
268: static inline flag floatx80_is_signaling_nan( floatx80 a )
269: {
270: uint64_t aLow;
271:
272: aLow = a.low & ~ LIT64( 0x4000000000000000 );
273: return
274: ( ( a.high & 0x7FFF ) == 0x7FFF )
275: && (uint64_t) ( aLow<<1 )
276: && ( a.low == aLow );
277:
278: }
279:
280: /*----------------------------------------------------------------------------
281: | Returns the result of converting the extended double-precision floating-
282: | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
283: | invalid exception is raised.
284: *----------------------------------------------------------------------------*/
285:
286: static inline commonNaNT floatx80ToCommonNaN( floatx80 a, float_status *status )
287: {
288: commonNaNT z;
289:
290: if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_signaling, status );
291: z.sign = a.high>>15;
292: z.low = 0;
293: z.high = a.low<<1;
294: return z;
295:
296: }
297:
298: /*----------------------------------------------------------------------------
299: | Returns the result of converting the canonical NaN `a' to the extended
300: | double-precision floating-point format.
301: *----------------------------------------------------------------------------*/
302:
303: static inline floatx80 commonNaNToFloatx80(commonNaNT a, float_status *status)
304: {
305: floatx80 z;
306: #ifdef SOFTFLOAT_68K
307: z.low = LIT64( 0x4000000000000000 ) | ( a.high>>1 );
308: #else
309: z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
310: #endif
311: z.high = ( ( (int16_t) a.sign )<<15 ) | 0x7FFF;
312: return z;
313: }
314:
315: /*----------------------------------------------------------------------------
316: | Takes two extended double-precision floating-point values `a' and `b', one
317: | of which is a NaN, and returns the appropriate NaN result. If either `a' or
318: | `b' is a signaling NaN, the invalid exception is raised.
319: *----------------------------------------------------------------------------*/
320:
321: static inline floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b, float_status *status )
322: {
323: flag aIsNaN, aIsSignalingNaN, bIsSignalingNaN;
324: #ifndef SOFTFLOAT_68K
325: flag bIsNaN;
1.1.1.2 ! root 326: #endif
1.1 root 327:
1.1.1.2 ! root 328: aIsNaN = floatx80_is_nan( a );
1.1 root 329: aIsSignalingNaN = floatx80_is_signaling_nan( a );
330: bIsSignalingNaN = floatx80_is_signaling_nan( b );
331: #ifdef SOFTFLOAT_68K
332: a.low |= LIT64( 0x4000000000000000 );
333: b.low |= LIT64( 0x4000000000000000 );
334: if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_signaling, status );
335: return aIsNaN ? a : b;
336: #else
337: bIsNaN = floatx80_is_nan( b );
338: a.low |= LIT64( 0xC000000000000000 );
339: b.low |= LIT64( 0xC000000000000000 );
340: if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_signaling, status );
341: if ( aIsNaN ) {
342: return ( aIsSignalingNaN & bIsNaN ) ? b : a;
343: }
344: else {
345: return b;
346: }
347: #endif
348:
349: }
350:
351: #ifdef SOFTFLOAT_68K
352: /*----------------------------------------------------------------------------
353: | Takes extended double-precision floating-point NaN `a' and returns the
354: | appropriate NaN result. If `a' is a signaling NaN, the invalid exception
355: | is raised.
356: *----------------------------------------------------------------------------*/
357:
358: static inline floatx80 propagateFloatx80NaNOneArg(floatx80 a, float_status *status)
359: {
360: if ( floatx80_is_signaling_nan( a ) )
361: float_raise( float_flag_signaling, status );
362: a.low |= LIT64( 0x4000000000000000 );
363:
364: return a;
365: }
366: #endif
367:
368: // 28-12-2016: Added for Previous:
369:
370: /*----------------------------------------------------------------------------
371: | Returns 1 if the extended double-precision floating-point value `a' is
372: | zero; otherwise returns 0.
373: *----------------------------------------------------------------------------*/
374:
375: static inline flag floatx80_is_zero( floatx80 a )
376: {
377:
378: return ( ( a.high & 0x7FFF ) < 0x7FFF ) && ( a.low == 0 );
379:
380: }
381:
382: /*----------------------------------------------------------------------------
383: | Returns 1 if the extended double-precision floating-point value `a' is
384: | infinity; otherwise returns 0.
385: *----------------------------------------------------------------------------*/
386:
387: static inline flag floatx80_is_infinity( floatx80 a )
388: {
389:
390: return ( ( a.high & 0x7FFF ) == 0x7FFF ) && ( (uint64_t) ( a.low<<1 ) == 0 );
391:
392: }
393:
394: /*----------------------------------------------------------------------------
395: | Returns 1 if the extended double-precision floating-point value `a' is
396: | negative; otherwise returns 0.
397: *----------------------------------------------------------------------------*/
398:
399: static inline flag floatx80_is_negative( floatx80 a )
400: {
401:
402: return ( ( a.high & 0x8000 ) == 0x8000 );
403:
404: }
405:
406: /*----------------------------------------------------------------------------
407: | Returns 1 if the extended double-precision floating-point value `a' is
408: | unnormal; otherwise returns 0.
409: *----------------------------------------------------------------------------*/
410: static inline flag floatx80_is_unnormal( floatx80 a )
411: {
412: return
413: ( ( a.high & 0x7FFF ) > 0 )
414: && ( ( a.high & 0x7FFF ) < 0x7FFF)
415: && ( (uint64_t) ( a.low & LIT64( 0x8000000000000000 ) ) == LIT64( 0x0000000000000000 ) );
416: }
417:
418: /*----------------------------------------------------------------------------
419: | Returns 1 if the extended double-precision floating-point value `a' is
420: | denormal; otherwise returns 0.
421: *----------------------------------------------------------------------------*/
422:
423: static inline flag floatx80_is_denormal( floatx80 a )
424: {
425: return
426: ( ( a.high & 0x7FFF ) == 0 )
427: && ( (uint64_t) ( a.low & LIT64( 0x8000000000000000 ) ) == LIT64( 0x0000000000000000 ) )
428: && (uint64_t) ( a.low<<1 );
429: }
430:
431: /*----------------------------------------------------------------------------
432: | Returns 1 if the extended double-precision floating-point value `a' is
433: | normal; otherwise returns 0.
434: *----------------------------------------------------------------------------*/
435:
436: static inline flag floatx80_is_normal( floatx80 a )
437: {
438: return
439: ( ( a.high & 0x7FFF ) < 0x7FFF )
440: && ( (uint64_t) ( a.low & LIT64( 0x8000000000000000 ) ) == LIT64( 0x8000000000000000 ) );
441: }
442: // End of addition for Previous
443:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.