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