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