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