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