1206917Smarius
2206917Smarius/*
3206917Smarius===============================================================================
4206917Smarius
5206917SmariusThis C source file is part of TestFloat, Release 2a, a package of programs
6206917Smariusfor testing the correctness of floating-point arithmetic complying to the
7206917SmariusIEC/IEEE Standard for Floating-Point.
8206917Smarius
9206917SmariusWritten by John R. Hauser.  More information is available through the Web
10206917Smariuspage `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
11206917Smarius
12206917SmariusTHIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
13206917Smariushas been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
14206917SmariusTIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
15206917SmariusPERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
16206917SmariusAND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
17206917Smarius
18206917SmariusDerivative works are acceptable, even for commercial purposes, so long as
19206917Smarius(1) they include prominent notice that the work is derivative, and (2) they
20206917Smariusinclude prominent notice akin to these four paragraphs for those parts of
21206917Smariusthis code that are retained.
22206917Smarius
23206917Smarius===============================================================================
24206917Smarius*/
25206917Smarius
26206917Smariusint8 slow_float_rounding_mode;
27206917Smariusint8 slow_float_exception_flags;
28206917Smariusint8 slow_float_detect_tininess;
29206917Smarius#ifdef FLOATX80
30206917Smariusint8 slow_floatx80_rounding_precision;
31206917Smarius#endif
32206917Smarius
33206917Smariustypedef struct {
34206917Smarius    bits64 a0, a1;
35206917Smarius} bits128X;
36206917Smarius
37206917Smariustypedef struct {
38206917Smarius    flag isNaN;
39206917Smarius    flag isInf;
40206917Smarius    flag isZero;
41206917Smarius    flag sign;
42206917Smarius    int32 exp;
43206917Smarius    bits128X sig;
44206917Smarius} floatX;
45206917Smarius
46206917Smariusstatic const floatX floatXNaN = { TRUE, FALSE, FALSE, FALSE, 0, { 0, 0 } };
47206917Smariusstatic const floatX floatXPositiveZero =
48206917Smarius    { FALSE, FALSE, TRUE, FALSE, 0, { 0, 0 } };
49206917Smariusstatic const floatX floatXNegativeZero =
50206917Smarius    { FALSE, FALSE, TRUE, TRUE, 0, { 0, 0 } };
51206917Smarius
52206917Smariusstatic bits128X shortShift128Left( bits128X a, int8 shiftCount )
53206917Smarius{
54206917Smarius    int8 negShiftCount;
55206917Smarius
56206917Smarius    negShiftCount = ( - shiftCount & 63 );
57206917Smarius    a.a0 = ( a.a0<<shiftCount ) | ( a.a1>>negShiftCount );
58206917Smarius    a.a1 <<= shiftCount;
59206917Smarius    return a;
60206917Smarius
61206917Smarius}
62206917Smarius
63206917Smariusstatic bits128X shortShift128RightJamming( bits128X a, int8 shiftCount )
64206917Smarius{
65206917Smarius    int8 negShiftCount;
66206917Smarius    bits64 extra;
67206917Smarius
68206917Smarius    negShiftCount = ( - shiftCount & 63 );
69206917Smarius    extra = a.a1<<negShiftCount;
70206917Smarius    a.a1 = ( a.a0<<negShiftCount ) | ( a.a1>>shiftCount ) | ( extra != 0 );
71206917Smarius    a.a0 >>= shiftCount;
72206917Smarius    return a;
73206917Smarius
74206917Smarius}
75206917Smarius
76206917Smariusstatic bits128X neg128( bits128X a )
77206917Smarius{
78206917Smarius
79206917Smarius    if ( a.a1 == 0 ) {
80206917Smarius        a.a0 = - a.a0;
81206917Smarius    }
82206917Smarius    else {
83206917Smarius        a.a1 = - a.a1;
84206917Smarius        a.a0 = ~ a.a0;
85206917Smarius    }
86206917Smarius    return a;
87206917Smarius
88206917Smarius}
89206917Smarius
90206917Smariusstatic bits128X add128( bits128X a, bits128X b )
91206917Smarius{
92206917Smarius
93206917Smarius    a.a1 += b.a1;
94206917Smarius    a.a0 += b.a0 + ( a.a1 < b.a1 );
95206917Smarius    return a;
96206917Smarius
97206917Smarius}
98206917Smarius
99206917Smariusstatic flag eq128( bits128X a, bits128X b )
100206917Smarius{
101206917Smarius
102206917Smarius    return ( a.a0 == b.a0 ) && ( a.a1 == b.a1 );
103206917Smarius
104206917Smarius}
105206917Smarius
106206917Smariusstatic flag le128( bits128X a, bits128X b )
107206917Smarius{
108206917Smarius
109206917Smarius    return ( a.a0 < b.a0 ) || ( ( a.a0 == b.a0 ) && ( a.a1 <= b.a1 ) );
110206917Smarius
111206917Smarius}
112206917Smarius
113206917Smariusstatic flag lt128( bits128X a, bits128X b )
114206917Smarius{
115206917Smarius
116206917Smarius    return ( a.a0 < b.a0 ) || ( ( a.a0 == b.a0 ) && ( a.a1 < b.a1 ) );
117206917Smarius
118206917Smarius}
119206917Smarius
120206917Smariusstatic floatX roundFloatXTo24( flag isTiny, floatX zx )
121206917Smarius{
122206917Smarius    bits32 roundBits;
123206917Smarius
124206917Smarius    zx.sig.a0 |= ( zx.sig.a1 != 0 );
125206917Smarius    zx.sig.a1 = 0;
126206917Smarius    roundBits = zx.sig.a0 & 0xFFFFFFFF;
127206917Smarius    zx.sig.a0 -= roundBits;
128206917Smarius    if ( roundBits ) {
129206917Smarius        slow_float_exception_flags |= float_flag_inexact;
130206917Smarius        if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
131206917Smarius        switch ( slow_float_rounding_mode ) {
132206917Smarius         case float_round_nearest_even:
133206917Smarius            if ( roundBits < 0x80000000 ) goto noIncrement;
134206917Smarius            if (    ( roundBits == 0x80000000 )
135206917Smarius                 && ! ( zx.sig.a0 & LIT64( 0x100000000 ) ) ) {
136206917Smarius                goto noIncrement;
137206917Smarius            }
138206917Smarius            break;
139206917Smarius         case float_round_to_zero:
140206917Smarius            goto noIncrement;
141206917Smarius         case float_round_down:
142206917Smarius            if ( ! zx.sign ) goto noIncrement;
143206917Smarius            break;
144206917Smarius         case float_round_up:
145206917Smarius            if ( zx.sign ) goto noIncrement;
146206917Smarius            break;
147206917Smarius        }
148206917Smarius        zx.sig.a0 += LIT64( 0x100000000 );
149206917Smarius        if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
150206917Smarius            zx.sig.a0 = LIT64( 0x0080000000000000 );
151206917Smarius            ++zx.exp;
152206917Smarius        }
153206917Smarius    }
154206917Smarius noIncrement:
155206917Smarius    return zx;
156206917Smarius
157206917Smarius}
158206917Smarius
159206917Smariusstatic floatX roundFloatXTo53( flag isTiny, floatX zx )
160206917Smarius{
161206917Smarius    int8 roundBits;
162206917Smarius
163206917Smarius    zx.sig.a0 |= ( zx.sig.a1 != 0 );
164206917Smarius    zx.sig.a1 = 0;
165206917Smarius    roundBits = zx.sig.a0 & 7;
166206917Smarius    zx.sig.a0 -= roundBits;
167206917Smarius    if ( roundBits ) {
168206917Smarius        slow_float_exception_flags |= float_flag_inexact;
169206917Smarius        if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
170206917Smarius        switch ( slow_float_rounding_mode ) {
171206917Smarius         case float_round_nearest_even:
172206917Smarius            if ( roundBits < 4 ) goto noIncrement;
173206917Smarius            if ( ( roundBits == 4 ) && ! ( zx.sig.a0 & 8 ) ) goto noIncrement;
174206917Smarius            break;
175206917Smarius         case float_round_to_zero:
176206917Smarius            goto noIncrement;
177206917Smarius         case float_round_down:
178206917Smarius            if ( ! zx.sign ) goto noIncrement;
179206917Smarius            break;
180206917Smarius         case float_round_up:
181206917Smarius            if ( zx.sign ) goto noIncrement;
182206917Smarius            break;
183206917Smarius        }
184206917Smarius        zx.sig.a0 += 8;
185206917Smarius        if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
186206917Smarius            zx.sig.a0 = LIT64( 0x0080000000000000 );
187206917Smarius            ++zx.exp;
188206917Smarius        }
189206917Smarius    }
190206917Smarius noIncrement:
191206917Smarius    return zx;
192206917Smarius
193206917Smarius}
194206917Smarius
195206917Smariusstatic floatX roundFloatXTo64( flag isTiny, floatX zx )
196206917Smarius{
197206917Smarius    int64 roundBits;
198206917Smarius
199206917Smarius    roundBits = zx.sig.a1 & LIT64( 0x00FFFFFFFFFFFFFF );
200206917Smarius    zx.sig.a1 -= roundBits;
201206917Smarius    if ( roundBits ) {
202206917Smarius        slow_float_exception_flags |= float_flag_inexact;
203206917Smarius        if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
204206917Smarius        switch ( slow_float_rounding_mode ) {
205206917Smarius         case float_round_nearest_even:
206206917Smarius            if ( roundBits < LIT64( 0x0080000000000000 ) ) goto noIncrement;
207206917Smarius            if (    ( roundBits == LIT64( 0x0080000000000000 ) )
208206917Smarius                 && ! ( zx.sig.a1 & LIT64( 0x0100000000000000 ) ) ) {
209206917Smarius                goto noIncrement;
210206917Smarius            }
211206917Smarius            break;
212206917Smarius         case float_round_to_zero:
213206917Smarius            goto noIncrement;
214206917Smarius         case float_round_down:
215206917Smarius            if ( ! zx.sign ) goto noIncrement;
216206917Smarius            break;
217206917Smarius         case float_round_up:
218206917Smarius            if ( zx.sign ) goto noIncrement;
219206917Smarius            break;
220206917Smarius        }
221206917Smarius        zx.sig.a1 += LIT64( 0x0100000000000000 );
222206917Smarius        zx.sig.a0 += ( zx.sig.a1 == 0 );
223206917Smarius        if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
224206917Smarius            zx.sig.a0 = LIT64( 0x0080000000000000 );
225206917Smarius            ++zx.exp;
226206917Smarius        }
227206917Smarius    }
228206917Smarius noIncrement:
229206917Smarius    return zx;
230206917Smarius
231206917Smarius}
232206917Smarius
233206917Smariusstatic floatX roundFloatXTo113( flag isTiny, floatX zx )
234206917Smarius{
235206917Smarius    int8 roundBits;
236206917Smarius
237206917Smarius    roundBits = zx.sig.a1 & 0x7F;
238206917Smarius    zx.sig.a1 -= roundBits;
239206917Smarius    if ( roundBits ) {
240206917Smarius        slow_float_exception_flags |= float_flag_inexact;
241206917Smarius        if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
242206917Smarius        switch ( slow_float_rounding_mode ) {
243206917Smarius         case float_round_nearest_even:
244206917Smarius            if ( roundBits < 0x40 ) goto noIncrement;
245206917Smarius            if (    ( roundBits == 0x40 )
246206917Smarius                 && ! ( zx.sig.a1 & 0x80 ) ) goto noIncrement;
247206917Smarius            break;
248206917Smarius         case float_round_to_zero:
249206917Smarius            goto noIncrement;
250206917Smarius         case float_round_down:
251206917Smarius            if ( ! zx.sign ) goto noIncrement;
252206917Smarius            break;
253206917Smarius         case float_round_up:
254206917Smarius            if ( zx.sign ) goto noIncrement;
255206917Smarius            break;
256206917Smarius        }
257206917Smarius        zx.sig.a1 += 0x80;
258206917Smarius        zx.sig.a0 += ( zx.sig.a1 == 0 );
259206917Smarius        if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
260206917Smarius            zx.sig.a0 = LIT64( 0x0080000000000000 );
261206917Smarius            ++zx.exp;
262206917Smarius        }
263206917Smarius    }
264206917Smarius noIncrement:
265206917Smarius    return zx;
266206917Smarius
267206917Smarius}
268206917Smarius
269206917Smariusstatic floatX int32ToFloatX( int32 a )
270206917Smarius{
271206917Smarius    floatX ax;
272206917Smarius
273206917Smarius    ax.isNaN = FALSE;
274206917Smarius    ax.isInf = FALSE;
275206917Smarius    ax.sign = ( a < 0 );
276206917Smarius    ax.sig.a1 = 0;
277206917Smarius    ax.sig.a0 = ax.sign ? - (bits64) a : a;
278206917Smarius    if ( a == 0 ) {
279206917Smarius        ax.isZero = TRUE;
280206917Smarius        return ax;
281206917Smarius    }
282206917Smarius    ax.isZero = FALSE;
283206917Smarius    ax.sig.a0 <<= 24;
284206917Smarius    ax.exp = 31;
285206917Smarius    while ( ax.sig.a0 < LIT64( 0x0080000000000000 ) ) {
286206917Smarius        ax.sig.a0 <<= 1;
287206917Smarius        --ax.exp;
288206917Smarius    }
289206917Smarius    return ax;
290206917Smarius
291206917Smarius}
292206917Smarius
293206917Smariusstatic int32 floatXToInt32( floatX ax )
294206917Smarius{
295206917Smarius    int8 savedExceptionFlags;
296206917Smarius    int32 shiftCount;
297206917Smarius    int32 z;
298206917Smarius
299206917Smarius    if ( ax.isInf || ax.isNaN ) {
300206917Smarius        slow_float_exception_flags |= float_flag_invalid;
301206917Smarius        return ( ax.isInf & ax.sign ) ? (sbits32) 0x80000000 : 0x7FFFFFFF;
302206917Smarius    }
303206917Smarius    if ( ax.isZero ) return 0;
304206917Smarius    savedExceptionFlags = slow_float_exception_flags;
305206917Smarius    shiftCount = 52 - ax.exp;
306206917Smarius    if ( 56 < shiftCount ) {
307206917Smarius        ax.sig.a1 = 1;
308206917Smarius        ax.sig.a0 = 0;
309206917Smarius    }
310206917Smarius    else {
311206917Smarius        while ( 0 < shiftCount ) {
312206917Smarius            ax.sig = shortShift128RightJamming( ax.sig, 1 );
313206917Smarius            --shiftCount;
314206917Smarius        }
315206917Smarius    }
316206917Smarius    ax = roundFloatXTo53( FALSE, ax );
317206917Smarius    ax.sig = shortShift128RightJamming( ax.sig, 3 );
318206917Smarius    z = ax.sig.a0;
319206917Smarius    if ( ax.sign ) z = - z;
320206917Smarius    if (    ( shiftCount < 0 )
321206917Smarius         || ( ax.sig.a0>>32 )
322206917Smarius         || ( ( z != 0 ) && ( ( ax.sign ^ ( z < 0 ) ) != 0 ) )
323206917Smarius       ) {
324206917Smarius        slow_float_exception_flags = savedExceptionFlags | float_flag_invalid;
325206917Smarius        return ax.sign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
326206917Smarius    }
327206917Smarius    return z;
328206917Smarius
329206917Smarius}
330206917Smarius
331206917Smariusstatic floatX int64ToFloatX( int64 a )
332206917Smarius{
333206917Smarius    uint64 absA;
334206917Smarius    floatX ax;
335206917Smarius
336206917Smarius    ax.isNaN = FALSE;
337206917Smarius    ax.isInf = FALSE;
338206917Smarius    ax.sign = ( a < 0 );
339206917Smarius    ax.sig.a1 = ax.sign ? - a : a;
340206917Smarius    ax.sig.a0 = 0;
341206917Smarius    if ( a == 0 ) {
342206917Smarius        ax.isZero = TRUE;
343206917Smarius        return ax;
344206917Smarius    }
345206917Smarius    ax.isZero = FALSE;
346206917Smarius    ax.sig = shortShift128Left( ax.sig, 56 );
347206917Smarius    ax.exp = 63;
348206917Smarius    while ( ax.sig.a0 < LIT64( 0x0080000000000000 ) ) {
349206917Smarius        ax.sig = shortShift128Left( ax.sig, 1 );
350206917Smarius        --ax.exp;
351206917Smarius    }
352206917Smarius    return ax;
353206917Smarius
354206917Smarius}
355206917Smarius
356206917Smariusstatic int64 floatXToInt64( floatX ax )
357206917Smarius{
358206917Smarius    int8 savedExceptionFlags;
359206917Smarius    int32 shiftCount;
360206917Smarius    int64 z;
361206917Smarius
362206917Smarius    if ( ax.isInf || ax.isNaN ) {
363206917Smarius        slow_float_exception_flags |= float_flag_invalid;
364206917Smarius        return
365206917Smarius              ( ax.isInf & ax.sign ) ? (sbits64) LIT64( 0x8000000000000000 )
366206917Smarius            : LIT64( 0x7FFFFFFFFFFFFFFF );
367206917Smarius    }
368206917Smarius    if ( ax.isZero ) return 0;
369206917Smarius    savedExceptionFlags = slow_float_exception_flags;
370206917Smarius    shiftCount = 112 - ax.exp;
371206917Smarius    if ( 116 < shiftCount ) {
372206917Smarius        ax.sig.a1 = 1;
373206917Smarius        ax.sig.a0 = 0;
374206917Smarius    }
375206917Smarius    else {
376206917Smarius        while ( 0 < shiftCount ) {
377206917Smarius            ax.sig = shortShift128RightJamming( ax.sig, 1 );
378206917Smarius            --shiftCount;
379206917Smarius        }
380206917Smarius    }
381206917Smarius    ax = roundFloatXTo113( FALSE, ax );
382206917Smarius    ax.sig = shortShift128RightJamming( ax.sig, 7 );
383206917Smarius    z = ax.sig.a1;
384206917Smarius    if ( ax.sign ) z = - z;
385206917Smarius    if (    ( shiftCount < 0 )
386206917Smarius         || ax.sig.a0
387206917Smarius         || ( ( z != 0 ) && ( ( ax.sign ^ ( z < 0 ) ) != 0 ) )
388206917Smarius       ) {
389206917Smarius        slow_float_exception_flags = savedExceptionFlags | float_flag_invalid;
390206917Smarius        return
391206917Smarius              ax.sign ? (sbits64) LIT64( 0x8000000000000000 )
392206917Smarius            : LIT64( 0x7FFFFFFFFFFFFFFF );
393206917Smarius    }
394206917Smarius    return z;
395206917Smarius
396206917Smarius}
397206917Smarius
398206917Smariusstatic floatX float32ToFloatX( float32 a )
399206917Smarius{
400206917Smarius    int16 expField;
401206917Smarius    floatX ax;
402206917Smarius
403206917Smarius    ax.isNaN = FALSE;
404206917Smarius    ax.isInf = FALSE;
405206917Smarius    ax.isZero = FALSE;
406206917Smarius    ax.sign = ( ( a & 0x80000000 ) != 0 );
407206917Smarius    expField = ( a>>23 ) & 0xFF;
408206917Smarius    ax.sig.a1 = 0;
409206917Smarius    ax.sig.a0 = a & 0x007FFFFF;
410206917Smarius    ax.sig.a0 <<= 32;
411206917Smarius    if ( expField == 0 ) {
412206917Smarius        if ( ax.sig.a0 == 0 ) {
413206917Smarius            ax.isZero = TRUE;
414206917Smarius        }
415206917Smarius        else {
416206917Smarius            expField = 1 - 0x7F;
417206917Smarius            do {
418206917Smarius                ax.sig.a0 <<= 1;
419206917Smarius                --expField;
420206917Smarius            } while ( ax.sig.a0 < LIT64( 0x0080000000000000 ) );
421206917Smarius            ax.exp = expField;
422206917Smarius        }
423206917Smarius    }
424206917Smarius    else if ( expField == 0xFF ) {
425206917Smarius        if ( ax.sig.a0 == 0 ) {
426206917Smarius            ax.isInf = TRUE;
427206917Smarius        }
428206917Smarius        else {
429206917Smarius            ax.isNaN = TRUE;
430206917Smarius        }
431206917Smarius    }
432206917Smarius    else {
433206917Smarius        ax.sig.a0 |= LIT64( 0x0080000000000000 );
434206917Smarius        ax.exp = expField - 0x7F;
435206917Smarius    }
436206917Smarius    return ax;
437206917Smarius
438206917Smarius}
439206917Smarius
440206917Smariusstatic float32 floatXToFloat32( floatX zx )
441206917Smarius{
442206917Smarius    floatX savedZ;
443206917Smarius    flag isTiny;
444206917Smarius    int32 expField;
445206917Smarius    float32 z;
446206917Smarius
447206917Smarius    if ( zx.isZero ) return zx.sign ? 0x80000000 : 0;
448206917Smarius    if ( zx.isInf ) return zx.sign ? 0xFF800000 : 0x7F800000;
449206917Smarius    if ( zx.isNaN ) return 0xFFFFFFFF;
450206917Smarius    while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
451206917Smarius        zx.sig = shortShift128RightJamming( zx.sig, 1 );
452206917Smarius        ++zx.exp;
453206917Smarius    }
454206917Smarius    while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
455206917Smarius        zx.sig = shortShift128Left( zx.sig, 1 );
456206917Smarius        --zx.exp;
457206917Smarius    }
458206917Smarius    savedZ = zx;
459206917Smarius    isTiny =
460206917Smarius           ( slow_float_detect_tininess == float_tininess_before_rounding )
461206917Smarius        && ( zx.exp + 0x7F <= 0 );
462206917Smarius    zx = roundFloatXTo24( isTiny, zx );
463206917Smarius    expField = zx.exp + 0x7F;
464206917Smarius    if ( 0xFF <= expField ) {
465206917Smarius        slow_float_exception_flags |=
466206917Smarius            float_flag_overflow | float_flag_inexact;
467206917Smarius        if ( zx.sign ) {
468206917Smarius            switch ( slow_float_rounding_mode ) {
469206917Smarius             case float_round_nearest_even:
470206917Smarius             case float_round_down:
471206917Smarius                z = 0xFF800000;
472206917Smarius                break;
473206917Smarius             case float_round_to_zero:
474206917Smarius             case float_round_up:
475206917Smarius                z = 0xFF7FFFFF;
476206917Smarius                break;
477206917Smarius            }
478206917Smarius        }
479206917Smarius        else {
480206917Smarius            switch ( slow_float_rounding_mode ) {
481206917Smarius             case float_round_nearest_even:
482206917Smarius             case float_round_up:
483206917Smarius                z = 0x7F800000;
484206917Smarius                break;
485206917Smarius             case float_round_to_zero:
486206917Smarius             case float_round_down:
487206917Smarius                z = 0x7F7FFFFF;
488206917Smarius                break;
489206917Smarius            }
490206917Smarius        }
491206917Smarius        return z;
492206917Smarius    }
493206917Smarius    if ( expField <= 0 ) {
494206917Smarius        isTiny = TRUE;
495206917Smarius        zx = savedZ;
496206917Smarius        expField = zx.exp + 0x7F;
497206917Smarius        if ( expField < -27 ) {
498206917Smarius            zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
499206917Smarius            zx.sig.a0 = 0;
500206917Smarius        }
501206917Smarius        else {
502206917Smarius            while ( expField <= 0 ) {
503206917Smarius                zx.sig = shortShift128RightJamming( zx.sig, 1 );
504206917Smarius                ++expField;
505206917Smarius            }
506206917Smarius        }
507206917Smarius        zx = roundFloatXTo24( isTiny, zx );
508206917Smarius        expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
509206917Smarius    }
510206917Smarius    z = expField;
511206917Smarius    z <<= 23;
512206917Smarius    if ( zx.sign ) z |= 0x80000000;
513206917Smarius    z |= ( zx.sig.a0>>32 ) & 0x007FFFFF;
514206917Smarius    return z;
515206917Smarius
516206917Smarius}
517206917Smarius
518206917Smariusstatic floatX float64ToFloatX( float64 a )
519206917Smarius{
520206917Smarius    int16 expField;
521206917Smarius    floatX ax;
522206917Smarius
523206917Smarius    ax.isNaN = FALSE;
524206917Smarius    ax.isInf = FALSE;
525206917Smarius    ax.isZero = FALSE;
526206917Smarius    ax.sign = ( ( a & LIT64( 0x8000000000000000 ) ) != 0 );
527206917Smarius    expField = ( a>>52 ) & 0x7FF;
528206917Smarius    ax.sig.a1 = 0;
529206917Smarius    ax.sig.a0 = a & LIT64( 0x000FFFFFFFFFFFFF );
530206917Smarius    if ( expField == 0 ) {
531206917Smarius        if ( ax.sig.a0 == 0 ) {
532206917Smarius            ax.isZero = TRUE;
533206917Smarius        }
534206917Smarius        else {
535206917Smarius            expField = 1 - 0x3FF;
536206917Smarius            do {
537206917Smarius                ax.sig.a0 <<= 1;
538206917Smarius                --expField;
539206917Smarius            } while ( ax.sig.a0 < LIT64( 0x0010000000000000 ) );
540206917Smarius            ax.exp = expField;
541206917Smarius        }
542206917Smarius    }
543206917Smarius    else if ( expField == 0x7FF ) {
544206917Smarius        if ( ax.sig.a0 == 0 ) {
545206917Smarius            ax.isInf = TRUE;
546206917Smarius        }
547206917Smarius        else {
548206917Smarius            ax.isNaN = TRUE;
549206917Smarius        }
550206917Smarius    }
551206917Smarius    else {
552206917Smarius        ax.exp = expField - 0x3FF;
553206917Smarius        ax.sig.a0 |= LIT64( 0x0010000000000000 );
554206917Smarius    }
555206917Smarius    ax.sig.a0 <<= 3;
556206917Smarius    return ax;
557206917Smarius
558206917Smarius}
559206917Smarius
560206917Smariusstatic float64 floatXToFloat64( floatX zx )
561206917Smarius{
562206917Smarius    floatX savedZ;
563206917Smarius    flag isTiny;
564206917Smarius    int32 expField;
565206917Smarius    float64 z;
566206917Smarius
567206917Smarius    if ( zx.isZero ) return zx.sign ? LIT64( 0x8000000000000000 ) : 0;
568206917Smarius    if ( zx.isInf ) {
569206917Smarius        return
570206917Smarius              zx.sign ? LIT64( 0xFFF0000000000000 )
571206917Smarius            : LIT64( 0x7FF0000000000000 );
572206917Smarius    }
573206917Smarius    if ( zx.isNaN ) return LIT64( 0xFFFFFFFFFFFFFFFF );
574206917Smarius    while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
575206917Smarius        zx.sig = shortShift128RightJamming( zx.sig, 1 );
576206917Smarius        ++zx.exp;
577206917Smarius    }
578206917Smarius    while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
579206917Smarius        zx.sig = shortShift128Left( zx.sig, 1 );
580206917Smarius        --zx.exp;
581206917Smarius    }
582206917Smarius    savedZ = zx;
583206917Smarius    isTiny =
584206917Smarius           ( slow_float_detect_tininess == float_tininess_before_rounding )
585206917Smarius        && ( zx.exp + 0x3FF <= 0 );
586206917Smarius    zx = roundFloatXTo53( isTiny, zx );
587206917Smarius    expField = zx.exp + 0x3FF;
588206917Smarius    if ( 0x7FF <= expField ) {
589206917Smarius        slow_float_exception_flags |=
590206917Smarius            float_flag_overflow | float_flag_inexact;
591206917Smarius        if ( zx.sign ) {
592206917Smarius            switch ( slow_float_rounding_mode ) {
593206917Smarius             case float_round_nearest_even:
594206917Smarius             case float_round_down:
595206917Smarius                z = LIT64( 0xFFF0000000000000 );
596206917Smarius                break;
597206917Smarius             case float_round_to_zero:
598206917Smarius             case float_round_up:
599206917Smarius                z = LIT64( 0xFFEFFFFFFFFFFFFF );
600206917Smarius                break;
601206917Smarius            }
602206917Smarius        }
603206917Smarius        else {
604206917Smarius            switch ( slow_float_rounding_mode ) {
605206917Smarius             case float_round_nearest_even:
606206917Smarius             case float_round_up:
607206917Smarius                z = LIT64( 0x7FF0000000000000 );
608206917Smarius                break;
609206917Smarius             case float_round_to_zero:
610206917Smarius             case float_round_down:
611206917Smarius                z = LIT64( 0x7FEFFFFFFFFFFFFF );
612206917Smarius                break;
613206917Smarius            }
614206917Smarius        }
615206917Smarius        return z;
616206917Smarius    }
617206917Smarius    if ( expField <= 0 ) {
618206917Smarius        isTiny = TRUE;
619206917Smarius        zx = savedZ;
620206917Smarius        expField = zx.exp + 0x3FF;
621206917Smarius        if ( expField < -56 ) {
622206917Smarius            zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
623206917Smarius            zx.sig.a0 = 0;
624206917Smarius        }
625206917Smarius        else {
626206917Smarius            while ( expField <= 0 ) {
627206917Smarius                zx.sig = shortShift128RightJamming( zx.sig, 1 );
628206917Smarius                ++expField;
629206917Smarius            }
630206917Smarius        }
631206917Smarius        zx = roundFloatXTo53( isTiny, zx );
632206917Smarius        expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
633206917Smarius    }
634206917Smarius    zx.sig.a0 >>= 3;
635206917Smarius    z = expField;
636206917Smarius    z <<= 52;
637206917Smarius    if ( zx.sign ) z |= LIT64( 0x8000000000000000 );
638206917Smarius    z |= zx.sig.a0 & LIT64( 0x000FFFFFFFFFFFFF );
639206917Smarius    return z;
640206917Smarius
641206917Smarius}
642206917Smarius
643206917Smarius#ifdef FLOATX80
644206917Smarius
645206917Smariusstatic floatX floatx80ToFloatX( floatx80 a )
646206917Smarius{
647206917Smarius    int32 expField;
648206917Smarius    floatX ax;
649206917Smarius
650206917Smarius    ax.isNaN = FALSE;
651206917Smarius    ax.isInf = FALSE;
652206917Smarius    ax.isZero = FALSE;
653206917Smarius    ax.sign = ( ( a.high & 0x8000 ) != 0 );
654206917Smarius    expField = a.high & 0x7FFF;
655206917Smarius    ax.sig.a1 = a.low;
656206917Smarius    ax.sig.a0 = 0;
657206917Smarius    if ( expField == 0 ) {
658206917Smarius        if ( ax.sig.a1 == 0 ) {
659206917Smarius            ax.isZero = TRUE;
660206917Smarius        }
661206917Smarius        else {
662206917Smarius            expField = 1 - 0x3FFF;
663206917Smarius            while ( ax.sig.a1 < LIT64( 0x8000000000000000 ) ) {
664206917Smarius                ax.sig.a1 <<= 1;
665206917Smarius                --expField;
666206917Smarius            }
667206917Smarius            ax.exp = expField;
668206917Smarius        }
669206917Smarius    }
670206917Smarius    else if ( expField == 0x7FFF ) {
671206917Smarius        if ( ( ax.sig.a1 & LIT64( 0x7FFFFFFFFFFFFFFF ) ) == 0 ) {
672206917Smarius            ax.isInf = TRUE;
673206917Smarius        }
674206917Smarius        else {
675206917Smarius            ax.isNaN = TRUE;
676206917Smarius        }
677206917Smarius    }
678206917Smarius    else {
679206917Smarius        ax.exp = expField - 0x3FFF;
680206917Smarius    }
681206917Smarius    ax.sig = shortShift128Left( ax.sig, 56 );
682206917Smarius    return ax;
683206917Smarius
684206917Smarius}
685206917Smarius
686206917Smariusstatic floatx80 floatXToFloatx80( floatX zx )
687206917Smarius{
688206917Smarius    floatX savedZ;
689206917Smarius    flag isTiny;
690206917Smarius    int32 expField;
691206917Smarius    floatx80 z;
692206917Smarius
693206917Smarius    if ( zx.isZero ) {
694206917Smarius        z.low = 0;
695206917Smarius        z.high = zx.sign ? 0x8000 : 0;
696206917Smarius        return z;
697206917Smarius    }
698206917Smarius    if ( zx.isInf ) {
699206917Smarius        z.low = LIT64( 0x8000000000000000 );
700206917Smarius        z.high = zx.sign ? 0xFFFF : 0x7FFF;
701206917Smarius        return z;
702206917Smarius    }
703206917Smarius    if ( zx.isNaN ) {
704206917Smarius        z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
705206917Smarius        z.high = 0xFFFF;
706206917Smarius        return z;
707206917Smarius    }
708206917Smarius    while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
709206917Smarius        zx.sig = shortShift128RightJamming( zx.sig, 1 );
710206917Smarius        ++zx.exp;
711206917Smarius    }
712206917Smarius    while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
713206917Smarius        zx.sig = shortShift128Left( zx.sig, 1 );
714206917Smarius        --zx.exp;
715206917Smarius    }
716206917Smarius    savedZ = zx;
717206917Smarius    isTiny =
718206917Smarius           ( slow_float_detect_tininess == float_tininess_before_rounding )
719206917Smarius        && ( zx.exp + 0x3FFF <= 0 );
720206917Smarius    switch ( slow_floatx80_rounding_precision ) {
721206917Smarius     case 32:
722206917Smarius        zx = roundFloatXTo24( isTiny, zx );
723206917Smarius        break;
724206917Smarius     case 64:
725206917Smarius        zx = roundFloatXTo53( isTiny, zx );
726206917Smarius        break;
727206917Smarius     default:
728206917Smarius        zx = roundFloatXTo64( isTiny, zx );
729206917Smarius        break;
730206917Smarius    }
731206917Smarius    expField = zx.exp + 0x3FFF;
732206917Smarius    if ( 0x7FFF <= expField ) {
733206917Smarius        slow_float_exception_flags |=
734206917Smarius            float_flag_overflow | float_flag_inexact;
735206917Smarius        if ( zx.sign ) {
736206917Smarius            switch ( slow_float_rounding_mode ) {
737206917Smarius             case float_round_nearest_even:
738206917Smarius             case float_round_down:
739206917Smarius                z.low = LIT64( 0x8000000000000000 );
740206917Smarius                z.high = 0xFFFF;
741206917Smarius                break;
742206917Smarius             case float_round_to_zero:
743206917Smarius             case float_round_up:
744206917Smarius                switch ( slow_floatx80_rounding_precision ) {
745206917Smarius                 case 32:
746206917Smarius                    z.low = LIT64( 0xFFFFFF0000000000 );
747206917Smarius                    break;
748206917Smarius                 case 64:
749206917Smarius                    z.low = LIT64( 0xFFFFFFFFFFFFF800 );
750206917Smarius                    break;
751206917Smarius                 default:
752206917Smarius                    z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
753206917Smarius                    break;
754206917Smarius                }
755206917Smarius                z.high = 0xFFFE;
756206917Smarius                break;
757206917Smarius            }
758206917Smarius        }
759206917Smarius        else {
760206917Smarius            switch ( slow_float_rounding_mode ) {
761206917Smarius             case float_round_nearest_even:
762206917Smarius             case float_round_up:
763206917Smarius                z.low = LIT64( 0x8000000000000000 );
764206917Smarius                z.high = 0x7FFF;
765206917Smarius                break;
766206917Smarius             case float_round_to_zero:
767206917Smarius             case float_round_down:
768206917Smarius                switch ( slow_floatx80_rounding_precision ) {
769206917Smarius                 case 32:
770206917Smarius                    z.low = LIT64( 0xFFFFFF0000000000 );
771206917Smarius                    break;
772206917Smarius                 case 64:
773206917Smarius                    z.low = LIT64( 0xFFFFFFFFFFFFF800 );
774206917Smarius                    break;
775206917Smarius                 default:
776206917Smarius                    z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
777206917Smarius                    break;
778206917Smarius                }
779206917Smarius                z.high = 0x7FFE;
780206917Smarius                break;
781206917Smarius            }
782206917Smarius        }
783206917Smarius        return z;
784206917Smarius    }
785206917Smarius    if ( expField <= 0 ) {
786206917Smarius        isTiny = TRUE;
787206917Smarius        zx = savedZ;
788206917Smarius        expField = zx.exp + 0x3FFF;
789206917Smarius        if ( expField < -70 ) {
790206917Smarius            zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
791206917Smarius            zx.sig.a0 = 0;
792206917Smarius        }
793206917Smarius        else {
794206917Smarius            while ( expField <= 0 ) {
795206917Smarius                zx.sig = shortShift128RightJamming( zx.sig, 1 );
796206917Smarius                ++expField;
797206917Smarius            }
798206917Smarius        }
799206917Smarius        switch ( slow_floatx80_rounding_precision ) {
800206917Smarius         case 32:
801206917Smarius            zx = roundFloatXTo24( isTiny, zx );
802206917Smarius            break;
803206917Smarius         case 64:
804206917Smarius            zx = roundFloatXTo53( isTiny, zx );
805206917Smarius            break;
806206917Smarius         default:
807206917Smarius            zx = roundFloatXTo64( isTiny, zx );
808206917Smarius            break;
809206917Smarius        }
810206917Smarius        expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
811206917Smarius    }
812206917Smarius    zx.sig = shortShift128RightJamming( zx.sig, 56 );
813206917Smarius    z.low = zx.sig.a1;
814206917Smarius    z.high = expField;
815206917Smarius    if ( zx.sign ) z.high |= 0x8000;
816206917Smarius    return z;
817206917Smarius
818206917Smarius}
819206917Smarius
820206917Smarius#endif
821206917Smarius
822206917Smarius#ifdef FLOAT128
823206917Smarius
824206917Smariusstatic floatX float128ToFloatX( float128 a )
825206917Smarius{
826206917Smarius    int32 expField;
827206917Smarius    floatX ax;
828206917Smarius
829206917Smarius    ax.isNaN = FALSE;
830206917Smarius    ax.isInf = FALSE;
831206917Smarius    ax.isZero = FALSE;
832206917Smarius    ax.sign = ( ( a.high & LIT64( 0x8000000000000000 ) ) != 0 );
833206917Smarius    expField = ( a.high>>48 ) & 0x7FFF;
834206917Smarius    ax.sig.a1 = a.low;
835206917Smarius    ax.sig.a0 = a.high & LIT64( 0x0000FFFFFFFFFFFF );
836206917Smarius    if ( expField == 0 ) {
837206917Smarius        if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) {
838206917Smarius            ax.isZero = TRUE;
839206917Smarius        }
840206917Smarius        else {
841206917Smarius            expField = 1 - 0x3FFF;
842206917Smarius            do {
843206917Smarius                ax.sig = shortShift128Left( ax.sig, 1 );
844206917Smarius                --expField;
845206917Smarius            } while ( ax.sig.a0 < LIT64( 0x0001000000000000 ) );
846206917Smarius            ax.exp = expField;
847206917Smarius        }
848206917Smarius    }
849206917Smarius    else if ( expField == 0x7FFF ) {
850206917Smarius        if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) {
851206917Smarius            ax.isInf = TRUE;
852206917Smarius        }
853206917Smarius        else {
854206917Smarius            ax.isNaN = TRUE;
855206917Smarius        }
856206917Smarius    }
857206917Smarius    else {
858206917Smarius        ax.exp = expField - 0x3FFF;
859206917Smarius        ax.sig.a0 |= LIT64( 0x0001000000000000 );
860206917Smarius    }
861206917Smarius    ax.sig = shortShift128Left( ax.sig, 7 );
862206917Smarius    return ax;
863206917Smarius
864206917Smarius}
865206917Smarius
866206917Smariusstatic float128 floatXToFloat128( floatX zx )
867206917Smarius{
868206917Smarius    floatX savedZ;
869206917Smarius    flag isTiny;
870206917Smarius    int32 expField;
871206917Smarius    float128 z;
872206917Smarius
873206917Smarius    if ( zx.isZero ) {
874206917Smarius        z.low = 0;
875206917Smarius        z.high = zx.sign ? LIT64( 0x8000000000000000 ) : 0;
876206917Smarius        return z;
877206917Smarius    }
878206917Smarius    if ( zx.isInf ) {
879206917Smarius        z.low = 0;
880206917Smarius        z.high =
881206917Smarius              zx.sign ? LIT64( 0xFFFF000000000000 )
882206917Smarius            : LIT64( 0x7FFF000000000000 );
883206917Smarius        return z;
884206917Smarius    }
885206917Smarius    if ( zx.isNaN ) {
886206917Smarius        z.high = z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
887206917Smarius        return z;
888206917Smarius    }
889206917Smarius    while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
890206917Smarius        zx.sig = shortShift128RightJamming( zx.sig, 1 );
891206917Smarius        ++zx.exp;
892206917Smarius    }
893206917Smarius    while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
894206917Smarius        zx.sig = shortShift128Left( zx.sig, 1 );
895206917Smarius        --zx.exp;
896206917Smarius    }
897206917Smarius    savedZ = zx;
898206917Smarius    isTiny =
899206917Smarius           ( slow_float_detect_tininess == float_tininess_before_rounding )
900206917Smarius        && ( zx.exp + 0x3FFF <= 0 );
901206917Smarius    zx = roundFloatXTo113( isTiny, zx );
902206917Smarius    expField = zx.exp + 0x3FFF;
903206917Smarius    if ( 0x7FFF <= expField ) {
904206917Smarius        slow_float_exception_flags |=
905206917Smarius            float_flag_overflow | float_flag_inexact;
906206917Smarius        if ( zx.sign ) {
907206917Smarius            switch ( slow_float_rounding_mode ) {
908206917Smarius             case float_round_nearest_even:
909206917Smarius             case float_round_down:
910206917Smarius                z.low = 0;
911206917Smarius                z.high = LIT64( 0xFFFF000000000000 );
912206917Smarius                break;
913206917Smarius             case float_round_to_zero:
914206917Smarius             case float_round_up:
915206917Smarius                z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
916206917Smarius                z.high = LIT64( 0xFFFEFFFFFFFFFFFF );
917206917Smarius                break;
918206917Smarius            }
919206917Smarius        }
920206917Smarius        else {
921206917Smarius            switch ( slow_float_rounding_mode ) {
922206917Smarius             case float_round_nearest_even:
923206917Smarius             case float_round_up:
924206917Smarius                z.low = 0;
925206917Smarius                z.high = LIT64( 0x7FFF000000000000 );
926206917Smarius                break;
927206917Smarius             case float_round_to_zero:
928206917Smarius             case float_round_down:
929206917Smarius                z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
930206917Smarius                z.high = LIT64( 0x7FFEFFFFFFFFFFFF );
931206917Smarius                break;
932206917Smarius            }
933206917Smarius        }
934206917Smarius        return z;
935206917Smarius    }
936206917Smarius    if ( expField <= 0 ) {
937206917Smarius        isTiny = TRUE;
938206917Smarius        zx = savedZ;
939206917Smarius        expField = zx.exp + 0x3FFF;
940206917Smarius        if ( expField < -120 ) {
941206917Smarius            zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
942206917Smarius            zx.sig.a0 = 0;
943206917Smarius        }
944206917Smarius        else {
945206917Smarius            while ( expField <= 0 ) {
946206917Smarius                zx.sig = shortShift128RightJamming( zx.sig, 1 );
947206917Smarius                ++expField;
948206917Smarius            }
949206917Smarius        }
950206917Smarius        zx = roundFloatXTo113( isTiny, zx );
951206917Smarius        expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
952206917Smarius    }
953206917Smarius    zx.sig = shortShift128RightJamming( zx.sig, 7 );
954206917Smarius    z.low = zx.sig.a1;
955206917Smarius    z.high = expField;
956206917Smarius    z.high <<= 48;
957206917Smarius    if ( zx.sign ) z.high |= LIT64( 0x8000000000000000 );
958206917Smarius    z.high |= zx.sig.a0 & LIT64( 0x0000FFFFFFFFFFFF );
959206917Smarius    return z;
960206917Smarius
961206917Smarius}
962206917Smarius
963206917Smarius#endif
964206917Smarius
965206917Smariusstatic floatX floatXInvalid( void )
966206917Smarius{
967206917Smarius
968206917Smarius    slow_float_exception_flags |= float_flag_invalid;
969206917Smarius    return floatXNaN;
970206917Smarius
971206917Smarius}
972206917Smarius
973206917Smariusstatic floatX floatXRoundToInt( floatX ax )
974206917Smarius{
975206917Smarius    int32 shiftCount, i;
976206917Smarius
977206917Smarius    if ( ax.isNaN || ax.isInf ) return ax;
978206917Smarius    shiftCount = 112 - ax.exp;
979206917Smarius    if ( shiftCount <= 0 ) return ax;
980206917Smarius    if ( 119 < shiftCount ) {
981206917Smarius        ax.exp = 112;
982206917Smarius        ax.sig.a1 = ! ax.isZero;
983206917Smarius        ax.sig.a0 = 0;
984206917Smarius    }
985206917Smarius    else {
986206917Smarius        while ( 0 < shiftCount ) {
987206917Smarius            ax.sig = shortShift128RightJamming( ax.sig, 1 );
988206917Smarius            ++ax.exp;
989206917Smarius            --shiftCount;
990206917Smarius        }
991206917Smarius    }
992206917Smarius    ax = roundFloatXTo113( FALSE, ax );
993206917Smarius    if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) ax.isZero = TRUE;
994206917Smarius    return ax;
995206917Smarius
996206917Smarius}
997206917Smarius
998206917Smariusstatic floatX floatXAdd( floatX ax, floatX bx )
999206917Smarius{
1000206917Smarius    int32 expDiff;
1001206917Smarius    floatX zx;
1002206917Smarius
1003206917Smarius    if ( ax.isNaN ) return ax;
1004206917Smarius    if ( bx.isNaN ) return bx;
1005206917Smarius    if ( ax.isInf && bx.isInf ) {
1006206917Smarius        if ( ax.sign == bx.sign ) return ax;
1007206917Smarius        return floatXInvalid();
1008206917Smarius    }
1009206917Smarius    if ( ax.isInf ) return ax;
1010206917Smarius    if ( bx.isInf ) return bx;
1011206917Smarius    if ( ax.isZero && bx.isZero ) {
1012206917Smarius        if ( ax.sign == bx.sign ) return ax;
1013206917Smarius        goto completeCancellation;
1014206917Smarius    }
1015206917Smarius    if (    ( ax.sign != bx.sign )
1016206917Smarius         && ( ax.exp == bx.exp )
1017206917Smarius         && eq128( ax.sig, bx.sig )
1018206917Smarius       ) {
1019206917Smarius completeCancellation:
1020206917Smarius        return
1021206917Smarius              ( slow_float_rounding_mode == float_round_down ) ?
1022206917Smarius                  floatXNegativeZero
1023206917Smarius            : floatXPositiveZero;
1024206917Smarius    }
1025206917Smarius    if ( ax.isZero ) return bx;
1026206917Smarius    if ( bx.isZero ) return ax;
1027206917Smarius    expDiff = ax.exp - bx.exp;
1028206917Smarius    if ( expDiff < 0 ) {
1029206917Smarius        zx = ax;
1030206917Smarius        zx.exp = bx.exp;
1031206917Smarius        if ( expDiff < -120 ) {
1032206917Smarius            zx.sig.a1 = 1;
1033206917Smarius            zx.sig.a0 = 0;
1034206917Smarius        }
1035206917Smarius        else {
1036206917Smarius            while ( expDiff < 0 ) {
1037206917Smarius                zx.sig = shortShift128RightJamming( zx.sig, 1 );
1038206917Smarius                ++expDiff;
1039206917Smarius            }
1040206917Smarius        }
1041206917Smarius        if ( ax.sign != bx.sign ) zx.sig = neg128( zx.sig );
1042206917Smarius        zx.sign = bx.sign;
1043206917Smarius        zx.sig = add128( zx.sig, bx.sig );
1044206917Smarius    }
1045206917Smarius    else {
1046206917Smarius        zx = bx;
1047206917Smarius        zx.exp = ax.exp;
1048206917Smarius        if ( 120 < expDiff ) {
1049206917Smarius            zx.sig.a1 = 1;
1050206917Smarius            zx.sig.a0 = 0;
1051206917Smarius        }
1052206917Smarius        else {
1053206917Smarius            while ( 0 < expDiff ) {
1054206917Smarius                zx.sig = shortShift128RightJamming( zx.sig, 1 );
1055206917Smarius                --expDiff;
1056206917Smarius            }
1057206917Smarius        }
1058206917Smarius        if ( ax.sign != bx.sign ) zx.sig = neg128( zx.sig );
1059206917Smarius        zx.sign = ax.sign;
1060206917Smarius        zx.sig = add128( zx.sig, ax.sig );
1061206917Smarius    }
1062206917Smarius    if ( zx.sig.a0 & LIT64( 0x8000000000000000 ) ) {
1063206917Smarius        zx.sig = neg128( zx.sig );
1064206917Smarius        zx.sign = ! zx.sign;
1065206917Smarius    }
1066206917Smarius    return zx;
1067206917Smarius
1068206917Smarius}
1069206917Smarius
1070206917Smariusstatic floatX floatXMul( floatX ax, floatX bx )
1071206917Smarius{
1072206917Smarius    int8 bitNum;
1073206917Smarius    floatX zx;
1074206917Smarius
1075206917Smarius    if ( ax.isNaN ) return ax;
1076206917Smarius    if ( bx.isNaN ) return bx;
1077206917Smarius    if ( ax.isInf ) {
1078206917Smarius        if ( bx.isZero ) return floatXInvalid();
1079206917Smarius        if ( bx.sign ) ax.sign = ! ax.sign;
1080206917Smarius        return ax;
1081206917Smarius    }
1082206917Smarius    if ( bx.isInf ) {
1083206917Smarius        if ( ax.isZero ) return floatXInvalid();
1084206917Smarius        if ( ax.sign ) bx.sign = ! bx.sign;
1085206917Smarius        return bx;
1086206917Smarius    }
1087206917Smarius    zx = ax;
1088206917Smarius    zx.sign ^= bx.sign;
1089206917Smarius    if ( ax.isZero || bx.isZero ) {
1090206917Smarius        return zx.sign ? floatXNegativeZero : floatXPositiveZero;
1091206917Smarius    }
1092206917Smarius    zx.exp += bx.exp + 1;
1093206917Smarius    zx.sig.a1 = 0;
1094206917Smarius    zx.sig.a0 = 0;
1095206917Smarius    for ( bitNum = 0; bitNum < 119; ++bitNum ) {
1096206917Smarius        if ( bx.sig.a1 & 2 ) zx.sig = add128( zx.sig, ax.sig );
1097206917Smarius        bx.sig = shortShift128RightJamming( bx.sig, 1 );
1098206917Smarius        zx.sig = shortShift128RightJamming( zx.sig, 1 );
1099206917Smarius    }
1100206917Smarius    return zx;
1101206917Smarius
1102206917Smarius}
1103206917Smarius
1104206917Smariusstatic floatX floatXDiv( floatX ax, floatX bx )
1105206917Smarius{
1106206917Smarius    bits128X negBSig;
1107206917Smarius    int8 bitNum;
1108206917Smarius    floatX zx;
1109206917Smarius
1110206917Smarius    if ( ax.isNaN ) return ax;
1111206917Smarius    if ( bx.isNaN ) return bx;
1112206917Smarius    if ( ax.isInf ) {
1113206917Smarius        if ( bx.isInf ) return floatXInvalid();
1114206917Smarius        if ( bx.sign ) ax.sign = ! ax.sign;
1115206917Smarius        return ax;
1116206917Smarius    }
1117206917Smarius    if ( bx.isZero ) {
1118206917Smarius        if ( ax.isZero ) return floatXInvalid();
1119206917Smarius        slow_float_exception_flags |= float_flag_divbyzero;
1120206917Smarius        if ( ax.sign ) bx.sign = ! bx.sign;
1121206917Smarius        bx.isZero = FALSE;
1122206917Smarius        bx.isInf = TRUE;
1123206917Smarius        return bx;
1124206917Smarius    }
1125206917Smarius    zx = ax;
1126206917Smarius    zx.sign ^= bx.sign;
1127206917Smarius    if ( ax.isZero || bx.isInf ) {
1128206917Smarius        return zx.sign ? floatXNegativeZero : floatXPositiveZero;
1129206917Smarius    }
1130206917Smarius    zx.exp -= bx.exp + 1;
1131206917Smarius    zx.sig.a1 = 0;
1132206917Smarius    zx.sig.a0 = 0;
1133206917Smarius    negBSig = neg128( bx.sig );
1134206917Smarius    for ( bitNum = 0; bitNum < 120; ++bitNum ) {
1135206917Smarius        if ( le128( bx.sig, ax.sig ) ) {
1136206917Smarius            zx.sig.a1 |= 1;
1137206917Smarius            ax.sig = add128( ax.sig, negBSig );
1138206917Smarius        }
1139206917Smarius        ax.sig = shortShift128Left( ax.sig, 1 );
1140206917Smarius        zx.sig = shortShift128Left( zx.sig, 1 );
1141206917Smarius    }
1142206917Smarius    if ( ax.sig.a0 || ax.sig.a1 ) zx.sig.a1 |= 1;
1143206917Smarius    return zx;
1144206917Smarius
1145206917Smarius}
1146206917Smarius
1147206917Smariusstatic floatX floatXRem( floatX ax, floatX bx )
1148206917Smarius{
1149206917Smarius    bits128X negBSig;
1150206917Smarius    flag lastQuotientBit;
1151206917Smarius    bits128X savedASig;
1152206917Smarius
1153206917Smarius    if ( ax.isNaN ) return ax;
1154206917Smarius    if ( bx.isNaN ) return bx;
1155206917Smarius    if ( ax.isInf || bx.isZero ) return floatXInvalid();
1156206917Smarius    if ( ax.isZero || bx.isInf ) return ax;
1157206917Smarius    --bx.exp;
1158206917Smarius    if ( ax.exp < bx.exp ) return ax;
1159206917Smarius    bx.sig = shortShift128Left( bx.sig, 1 );
1160206917Smarius    negBSig = neg128( bx.sig );
1161206917Smarius    while ( bx.exp < ax.exp ) {
1162206917Smarius        if ( le128( bx.sig, ax.sig ) ) ax.sig = add128( ax.sig, negBSig );
1163206917Smarius        ax.sig = shortShift128Left( ax.sig, 1 );
1164206917Smarius        --ax.exp;
1165206917Smarius    }
1166206917Smarius    lastQuotientBit = le128( bx.sig, ax.sig );
1167206917Smarius    if ( lastQuotientBit ) ax.sig = add128( ax.sig, negBSig );
1168206917Smarius    savedASig = ax.sig;
1169206917Smarius    ax.sig = neg128( add128( ax.sig, negBSig ) );
1170206917Smarius    if ( lt128( ax.sig, savedASig ) ) {
1171206917Smarius        ax.sign = ! ax.sign;
1172206917Smarius    }
1173206917Smarius    else if ( lt128( savedASig, ax.sig ) ) {
1174206917Smarius        ax.sig = savedASig;
1175206917Smarius    }
1176206917Smarius    else {
1177206917Smarius        if ( lastQuotientBit ) {
1178206917Smarius            ax.sign = ! ax.sign;
1179206917Smarius        }
1180206917Smarius        else {
1181206917Smarius            ax.sig = savedASig;
1182206917Smarius        }
1183206917Smarius    }
1184206917Smarius    if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) ax.isZero = TRUE;
1185206917Smarius    return ax;
1186206917Smarius
1187206917Smarius}
1188206917Smarius
1189206917Smariusstatic floatX floatXSqrt( floatX ax )
1190206917Smarius{
1191206917Smarius    int8 bitNum;
1192206917Smarius    bits128X bitSig, savedASig;
1193206917Smarius    floatX zx;
1194206917Smarius
1195206917Smarius    if ( ax.isNaN || ax.isZero ) return ax;
1196206917Smarius    if ( ax.sign ) return floatXInvalid();
1197206917Smarius    if ( ax.isInf ) return ax;
1198206917Smarius    zx = ax;
1199206917Smarius    zx.exp >>= 1;
1200206917Smarius    if ( ( ax.exp & 1 ) == 0 ) ax.sig = shortShift128RightJamming( ax.sig, 1 );
1201206917Smarius    zx.sig.a1 = 0;
1202206917Smarius    zx.sig.a0 = 0;
1203206917Smarius    bitSig.a1 = 0;
1204206917Smarius    bitSig.a0 = LIT64( 0x0080000000000000 );
1205206917Smarius    for ( bitNum = 0; bitNum < 120; ++bitNum ) {
1206206917Smarius        savedASig = ax.sig;
1207206917Smarius        ax.sig = add128( ax.sig, neg128( zx.sig ) );
1208206917Smarius        ax.sig = shortShift128Left( ax.sig, 1 );
1209206917Smarius        ax.sig = add128( ax.sig, neg128( bitSig ) );
1210206917Smarius        if ( ax.sig.a0 & LIT64( 0x8000000000000000 ) ) {
1211206917Smarius            ax.sig = shortShift128Left( savedASig, 1 );
1212206917Smarius        }
1213206917Smarius        else {
1214206917Smarius            zx.sig.a1 |= bitSig.a1;
1215206917Smarius            zx.sig.a0 |= bitSig.a0;
1216206917Smarius        }
1217206917Smarius        bitSig = shortShift128RightJamming( bitSig, 1 );
1218206917Smarius    }
1219206917Smarius    if ( ax.sig.a0 || ax.sig.a1 ) zx.sig.a1 |= 1;
1220206917Smarius    return zx;
1221206917Smarius
1222206917Smarius}
1223206917Smarius
1224206917Smariusstatic flag floatXEq( floatX ax, floatX bx )
1225206917Smarius{
1226206917Smarius
1227206917Smarius    if ( ax.isNaN || bx.isNaN ) return FALSE;
1228206917Smarius    if ( ax.isZero && bx.isZero ) return TRUE;
1229206917Smarius    if ( ax.sign != bx.sign ) return FALSE;
1230206917Smarius    if ( ax.isInf || bx.isInf ) return ax.isInf && bx.isInf;
1231206917Smarius    return ( ax.exp == bx.exp ) && eq128( ax.sig, bx.sig );
1232206917Smarius
1233206917Smarius}
1234206917Smarius
1235206917Smariusstatic flag floatXLe( floatX ax, floatX bx )
1236206917Smarius{
1237206917Smarius
1238206917Smarius    if ( ax.isNaN || bx.isNaN ) return FALSE;
1239206917Smarius    if ( ax.isZero && bx.isZero ) return TRUE;
1240206917Smarius    if ( ax.sign != bx.sign ) return ax.sign;
1241206917Smarius    if ( ax.sign ) {
1242206917Smarius        if ( ax.isInf || bx.isZero ) return TRUE;
1243206917Smarius        if ( bx.isInf || ax.isZero ) return FALSE;
1244206917Smarius        if ( bx.exp < ax.exp ) return TRUE;
1245206917Smarius        if ( ax.exp < bx.exp ) return FALSE;
1246206917Smarius        return le128( bx.sig, ax.sig );
1247206917Smarius    }
1248206917Smarius    else {
1249206917Smarius        if ( bx.isInf || ax.isZero ) return TRUE;
1250206917Smarius        if ( ax.isInf || bx.isZero ) return FALSE;
1251206917Smarius        if ( ax.exp < bx.exp ) return TRUE;
1252206917Smarius        if ( bx.exp < ax.exp ) return FALSE;
1253206917Smarius        return le128( ax.sig, bx.sig );
1254206917Smarius    }
1255206917Smarius
1256206917Smarius}
1257206917Smarius
1258206917Smariusstatic flag floatXLt( floatX ax, floatX bx )
1259206917Smarius{
1260206917Smarius
1261206917Smarius    if ( ax.isNaN || bx.isNaN ) return FALSE;
1262206917Smarius    if ( ax.isZero && bx.isZero ) return FALSE;
1263206917Smarius    if ( ax.sign != bx.sign ) return ax.sign;
1264206917Smarius    if ( ax.isInf && bx.isInf ) return FALSE;
1265206917Smarius    if ( ax.sign ) {
1266206917Smarius        if ( ax.isInf || bx.isZero ) return TRUE;
1267206917Smarius        if ( bx.isInf || ax.isZero ) return FALSE;
1268206917Smarius        if ( bx.exp < ax.exp ) return TRUE;
1269206917Smarius        if ( ax.exp < bx.exp ) return FALSE;
1270206917Smarius        return lt128( bx.sig, ax.sig );
1271206917Smarius    }
1272206917Smarius    else {
1273206917Smarius        if ( bx.isInf || ax.isZero ) return TRUE;
1274206917Smarius        if ( ax.isInf || bx.isZero ) return FALSE;
1275206917Smarius        if ( ax.exp < bx.exp ) return TRUE;
1276206917Smarius        if ( bx.exp < ax.exp ) return FALSE;
1277206917Smarius        return lt128( ax.sig, bx.sig );
1278206917Smarius    }
1279206917Smarius
1280206917Smarius}
1281206917Smarius
1282206917Smariusfloat32 slow_int32_to_float32( int32 a )
1283206917Smarius{
1284206917Smarius
1285206917Smarius    return floatXToFloat32( int32ToFloatX( a ) );
1286206917Smarius
1287206917Smarius}
1288206917Smarius
1289206917Smariusfloat64 slow_int32_to_float64( int32 a )
1290206917Smarius{
1291206917Smarius
1292206917Smarius    return floatXToFloat64( int32ToFloatX( a ) );
1293206917Smarius
1294206917Smarius}
1295206917Smarius
1296206917Smarius#ifdef FLOATX80
1297206917Smarius
1298206917Smariusfloatx80 slow_int32_to_floatx80( int32 a )
1299206917Smarius{
1300206917Smarius
1301206917Smarius    return floatXToFloatx80( int32ToFloatX( a ) );
1302206917Smarius
1303206917Smarius}
1304206917Smarius
1305206917Smarius#endif
1306206917Smarius
1307206917Smarius#ifdef FLOAT128
1308206917Smarius
1309206917Smariusfloat128 slow_int32_to_float128( int32 a )
1310206917Smarius{
1311206917Smarius
1312206917Smarius    return floatXToFloat128( int32ToFloatX( a ) );
1313206917Smarius
1314206917Smarius}
1315206917Smarius
1316206917Smarius#endif
1317206917Smarius
1318206917Smariusfloat32 slow_int64_to_float32( int64 a )
1319206917Smarius{
1320206917Smarius
1321206917Smarius    return floatXToFloat32( int64ToFloatX( a ) );
1322206917Smarius
1323206917Smarius}
1324206917Smarius
1325206917Smariusfloat64 slow_int64_to_float64( int64 a )
1326206917Smarius{
1327206917Smarius
1328206917Smarius    return floatXToFloat64( int64ToFloatX( a ) );
1329206917Smarius
1330206917Smarius}
1331206917Smarius
1332206917Smarius#ifdef FLOATX80
1333206917Smarius
1334206917Smariusfloatx80 slow_int64_to_floatx80( int64 a )
1335206917Smarius{
1336206917Smarius
1337206917Smarius    return floatXToFloatx80( int64ToFloatX( a ) );
1338206917Smarius
1339206917Smarius}
1340206917Smarius
1341206917Smarius#endif
1342206917Smarius
1343206917Smarius#ifdef FLOAT128
1344206917Smarius
1345206917Smariusfloat128 slow_int64_to_float128( int64 a )
1346206917Smarius{
1347206917Smarius
1348206917Smarius    return floatXToFloat128( int64ToFloatX( a ) );
1349206917Smarius
1350206917Smarius}
1351206917Smarius
1352206917Smarius#endif
1353206917Smarius
1354206917Smariusint32 slow_float32_to_int32( float32 a )
1355206917Smarius{
1356206917Smarius
1357206917Smarius    return floatXToInt32( float32ToFloatX( a ) );
1358206917Smarius
1359206917Smarius}
1360206917Smarius
1361206917Smariusint32 slow_float32_to_int32_round_to_zero( float32 a )
1362206917Smarius{
1363206917Smarius    int8 savedRoundingMode;
1364206917Smarius    int32 z;
1365206917Smarius
1366206917Smarius    savedRoundingMode = slow_float_rounding_mode;
1367206917Smarius    slow_float_rounding_mode = float_round_to_zero;
1368206917Smarius    z = floatXToInt32( float32ToFloatX( a ) );
1369206917Smarius    slow_float_rounding_mode = savedRoundingMode;
1370206917Smarius    return z;
1371206917Smarius
1372206917Smarius}
1373206917Smarius
1374206917Smariusint64 slow_float32_to_int64( float32 a )
1375206917Smarius{
1376206917Smarius
1377206917Smarius    return floatXToInt64( float32ToFloatX( a ) );
1378206917Smarius
1379206917Smarius}
1380206917Smarius
1381206917Smariusint64 slow_float32_to_int64_round_to_zero( float32 a )
1382206917Smarius{
1383206917Smarius    int8 savedRoundingMode;
1384206917Smarius    int64 z;
1385206917Smarius
1386206917Smarius    savedRoundingMode = slow_float_rounding_mode;
1387206917Smarius    slow_float_rounding_mode = float_round_to_zero;
1388206917Smarius    z = floatXToInt64( float32ToFloatX( a ) );
1389206917Smarius    slow_float_rounding_mode = savedRoundingMode;
1390206917Smarius    return z;
1391206917Smarius
1392206917Smarius}
1393206917Smarius
1394206917Smariusfloat64 slow_float32_to_float64( float32 a )
1395206917Smarius{
1396206917Smarius
1397206917Smarius    return floatXToFloat64( float32ToFloatX( a ) );
1398206917Smarius
1399206917Smarius}
1400206917Smarius
1401206917Smarius#ifdef FLOATX80
1402206917Smarius
1403206917Smariusfloatx80 slow_float32_to_floatx80( float32 a )
1404206917Smarius{
1405206917Smarius
1406206917Smarius    return floatXToFloatx80( float32ToFloatX( a ) );
1407206917Smarius
1408206917Smarius}
1409206917Smarius
1410206917Smarius#endif
1411206917Smarius
1412206917Smarius#ifdef FLOAT128
1413206917Smarius
1414206917Smariusfloat128 slow_float32_to_float128( float32 a )
1415206917Smarius{
1416206917Smarius
1417206917Smarius    return floatXToFloat128( float32ToFloatX( a ) );
1418206917Smarius
1419206917Smarius}
1420206917Smarius
1421206917Smarius#endif
1422206917Smarius
1423206917Smariusfloat32 slow_float32_round_to_int( float32 a )
1424206917Smarius{
1425206917Smarius
1426206917Smarius    return floatXToFloat32( floatXRoundToInt( float32ToFloatX( a ) ) );
1427206917Smarius
1428206917Smarius}
1429206917Smarius
1430206917Smariusfloat32 slow_float32_add( float32 a, float32 b )
1431206917Smarius{
1432206917Smarius
1433206917Smarius    return
1434206917Smarius        floatXToFloat32(
1435206917Smarius            floatXAdd( float32ToFloatX( a ), float32ToFloatX( b ) ) );
1436206917Smarius
1437206917Smarius}
1438206917Smarius
1439206917Smariusfloat32 slow_float32_sub( float32 a, float32 b )
1440206917Smarius{
1441206917Smarius
1442206917Smarius    b ^= 0x80000000;
1443206917Smarius    return
1444206917Smarius        floatXToFloat32(
1445206917Smarius            floatXAdd( float32ToFloatX( a ), float32ToFloatX( b ) ) );
1446206917Smarius
1447206917Smarius}
1448206917Smarius
1449206917Smariusfloat32 slow_float32_mul( float32 a, float32 b )
1450206917Smarius{
1451206917Smarius
1452206917Smarius    return
1453206917Smarius        floatXToFloat32(
1454206917Smarius            floatXMul( float32ToFloatX( a ), float32ToFloatX( b ) ) );
1455206917Smarius
1456206917Smarius}
1457206917Smarius
1458206917Smariusfloat32 slow_float32_div( float32 a, float32 b )
1459206917Smarius{
1460206917Smarius
1461206917Smarius    return
1462206917Smarius        floatXToFloat32(
1463206917Smarius            floatXDiv( float32ToFloatX( a ), float32ToFloatX( b ) ) );
1464206917Smarius
1465206917Smarius}
1466206917Smarius
1467206917Smariusfloat32 slow_float32_rem( float32 a, float32 b )
1468206917Smarius{
1469206917Smarius
1470206917Smarius    return
1471206917Smarius        floatXToFloat32(
1472206917Smarius            floatXRem( float32ToFloatX( a ), float32ToFloatX( b ) ) );
1473206917Smarius
1474206917Smarius}
1475206917Smarius
1476206917Smariusfloat32 slow_float32_sqrt( float32 a )
1477206917Smarius{
1478206917Smarius
1479206917Smarius    return floatXToFloat32( floatXSqrt( float32ToFloatX( a ) ) );
1480206917Smarius
1481206917Smarius}
1482206917Smarius
1483206917Smariusflag slow_float32_eq( float32 a, float32 b )
1484206917Smarius{
1485206917Smarius
1486206917Smarius    return floatXEq( float32ToFloatX( a ), float32ToFloatX( b ) );
1487206917Smarius
1488206917Smarius}
1489206917Smarius
1490206917Smariusflag slow_float32_le( float32 a, float32 b )
1491206917Smarius{
1492206917Smarius    floatX ax, bx;
1493206917Smarius
1494206917Smarius    ax = float32ToFloatX( a );
1495206917Smarius    bx = float32ToFloatX( b );
1496206917Smarius    if ( ax.isNaN || bx.isNaN ) {
1497206917Smarius        slow_float_exception_flags |= float_flag_invalid;
1498206917Smarius    }
1499206917Smarius    return floatXLe( ax, bx );
1500206917Smarius
1501206917Smarius}
1502206917Smarius
1503206917Smariusflag slow_float32_lt( float32 a, float32 b )
1504206917Smarius{
1505206917Smarius    floatX ax, bx;
1506206917Smarius
1507206917Smarius    ax = float32ToFloatX( a );
1508206917Smarius    bx = float32ToFloatX( b );
1509206917Smarius    if ( ax.isNaN || bx.isNaN ) {
1510206917Smarius        slow_float_exception_flags |= float_flag_invalid;
1511206917Smarius    }
1512206917Smarius    return floatXLt( ax, bx );
1513206917Smarius
1514206917Smarius}
1515206917Smarius
1516206917Smariusflag slow_float32_eq_signaling( float32 a, float32 b )
1517206917Smarius{
1518206917Smarius    floatX ax, bx;
1519206917Smarius
1520206917Smarius    ax = float32ToFloatX( a );
1521206917Smarius    bx = float32ToFloatX( b );
1522206917Smarius    if ( ax.isNaN || bx.isNaN ) {
1523206917Smarius        slow_float_exception_flags |= float_flag_invalid;
1524206917Smarius    }
1525206917Smarius    return floatXEq( ax, bx );
1526206917Smarius
1527206917Smarius}
1528206917Smarius
1529206917Smariusflag slow_float32_le_quiet( float32 a, float32 b )
1530206917Smarius{
1531206917Smarius
1532206917Smarius    return floatXLe( float32ToFloatX( a ), float32ToFloatX( b ) );
1533206917Smarius
1534206917Smarius}
1535206917Smarius
1536206917Smariusflag slow_float32_lt_quiet( float32 a, float32 b )
1537206917Smarius{
1538206917Smarius
1539206917Smarius    return floatXLt( float32ToFloatX( a ), float32ToFloatX( b ) );
1540206917Smarius
1541206917Smarius}
1542206917Smarius
1543206917Smariusint32 slow_float64_to_int32( float64 a )
1544206917Smarius{
1545206917Smarius
1546206917Smarius    return floatXToInt32( float64ToFloatX( a ) );
1547206917Smarius
1548206917Smarius}
1549206917Smarius
1550206917Smariusint32 slow_float64_to_int32_round_to_zero( float64 a )
1551206917Smarius{
1552206917Smarius    int8 savedRoundingMode;
1553206917Smarius    int32 z;
1554206917Smarius
1555206917Smarius    savedRoundingMode = slow_float_rounding_mode;
1556206917Smarius    slow_float_rounding_mode = float_round_to_zero;
1557206917Smarius    z = floatXToInt32( float64ToFloatX( a ) );
1558206917Smarius    slow_float_rounding_mode = savedRoundingMode;
1559206917Smarius    return z;
1560206917Smarius
1561206917Smarius}
1562206917Smarius
1563206917Smariusint64 slow_float64_to_int64( float64 a )
1564206917Smarius{
1565206917Smarius
1566206917Smarius    return floatXToInt64( float64ToFloatX( a ) );
1567206917Smarius
1568206917Smarius}
1569206917Smarius
1570206917Smariusint64 slow_float64_to_int64_round_to_zero( float64 a )
1571206917Smarius{
1572206917Smarius    int8 savedRoundingMode;
1573206917Smarius    int64 z;
1574206917Smarius
1575206917Smarius    savedRoundingMode = slow_float_rounding_mode;
1576206917Smarius    slow_float_rounding_mode = float_round_to_zero;
1577206917Smarius    z = floatXToInt64( float64ToFloatX( a ) );
1578206917Smarius    slow_float_rounding_mode = savedRoundingMode;
1579206917Smarius    return z;
1580206917Smarius
1581206917Smarius}
1582206917Smarius
1583206917Smariusfloat32 slow_float64_to_float32( float64 a )
1584206917Smarius{
1585206917Smarius
1586206917Smarius    return floatXToFloat32( float64ToFloatX( a ) );
1587206917Smarius
1588206917Smarius}
1589206917Smarius
1590206917Smarius#ifdef FLOATX80
1591206917Smarius
1592206917Smariusfloatx80 slow_float64_to_floatx80( float64 a )
1593206917Smarius{
1594206917Smarius
1595206917Smarius    return floatXToFloatx80( float64ToFloatX( a ) );
1596206917Smarius
1597206917Smarius}
1598206917Smarius
1599206917Smarius#endif
1600206917Smarius
1601206917Smarius#ifdef FLOAT128
1602206917Smarius
1603206917Smariusfloat128 slow_float64_to_float128( float64 a )
1604206917Smarius{
1605206917Smarius
1606206917Smarius    return floatXToFloat128( float64ToFloatX( a ) );
1607206917Smarius
1608206917Smarius}
1609206917Smarius
1610206917Smarius#endif
1611206917Smarius
1612206917Smariusfloat64 slow_float64_round_to_int( float64 a )
1613206917Smarius{
1614206917Smarius
1615206917Smarius    return floatXToFloat64( floatXRoundToInt( float64ToFloatX( a ) ) );
1616206917Smarius
1617206917Smarius}
1618206917Smarius
1619206917Smariusfloat64 slow_float64_add( float64 a, float64 b )
1620206917Smarius{
1621206917Smarius
1622206917Smarius    return
1623206917Smarius        floatXToFloat64(
1624206917Smarius            floatXAdd( float64ToFloatX( a ), float64ToFloatX( b ) ) );
1625206917Smarius
1626206917Smarius}
1627206917Smarius
1628206917Smariusfloat64 slow_float64_sub( float64 a, float64 b )
1629206917Smarius{
1630206917Smarius
1631206917Smarius    b ^= LIT64( 0x8000000000000000 );
1632206917Smarius    return
1633206917Smarius        floatXToFloat64(
1634206917Smarius            floatXAdd( float64ToFloatX( a ), float64ToFloatX( b ) ) );
1635206917Smarius
1636206917Smarius}
1637206917Smarius
1638206917Smariusfloat64 slow_float64_mul( float64 a, float64 b )
1639206917Smarius{
1640206917Smarius
1641206917Smarius    return
1642206917Smarius        floatXToFloat64(
1643206917Smarius            floatXMul( float64ToFloatX( a ), float64ToFloatX( b ) ) );
1644206917Smarius
1645206917Smarius}
1646206917Smarius
1647206917Smariusfloat64 slow_float64_div( float64 a, float64 b )
1648206917Smarius{
1649206917Smarius
1650206917Smarius    return
1651206917Smarius        floatXToFloat64(
1652206917Smarius            floatXDiv( float64ToFloatX( a ), float64ToFloatX( b ) ) );
1653206917Smarius
1654206917Smarius}
1655206917Smarius
1656206917Smariusfloat64 slow_float64_rem( float64 a, float64 b )
1657206917Smarius{
1658206917Smarius
1659206917Smarius    return
1660206917Smarius        floatXToFloat64(
1661206917Smarius            floatXRem( float64ToFloatX( a ), float64ToFloatX( b ) ) );
1662206917Smarius
1663206917Smarius}
1664206917Smarius
1665206917Smariusfloat64 slow_float64_sqrt( float64 a )
1666206917Smarius{
1667206917Smarius
1668206917Smarius    return floatXToFloat64( floatXSqrt( float64ToFloatX( a ) ) );
1669206917Smarius
1670206917Smarius}
1671206917Smarius
1672206917Smariusflag slow_float64_eq( float64 a, float64 b )
1673206917Smarius{
1674206917Smarius
1675206917Smarius    return floatXEq( float64ToFloatX( a ), float64ToFloatX( b ) );
1676206917Smarius
1677206917Smarius}
1678206917Smarius
1679206917Smariusflag slow_float64_le( float64 a, float64 b )
1680206917Smarius{
1681206917Smarius    floatX ax, bx;
1682206917Smarius
1683206917Smarius    ax = float64ToFloatX( a );
1684206917Smarius    bx = float64ToFloatX( b );
1685206917Smarius    if ( ax.isNaN || bx.isNaN ) {
1686206917Smarius        slow_float_exception_flags |= float_flag_invalid;
1687206917Smarius    }
1688206917Smarius    return floatXLe( ax, bx );
1689206917Smarius
1690206917Smarius}
1691206917Smarius
1692206917Smariusflag slow_float64_lt( float64 a, float64 b )
1693206917Smarius{
1694206917Smarius    floatX ax, bx;
1695206917Smarius
1696206917Smarius    ax = float64ToFloatX( a );
1697206917Smarius    bx = float64ToFloatX( b );
1698206917Smarius    if ( ax.isNaN || bx.isNaN ) {
1699206917Smarius        slow_float_exception_flags |= float_flag_invalid;
1700206917Smarius    }
1701206917Smarius    return floatXLt( ax, bx );
1702206917Smarius
1703206917Smarius}
1704206917Smarius
1705206917Smariusflag slow_float64_eq_signaling( float64 a, float64 b )
1706206917Smarius{
1707206917Smarius    floatX ax, bx;
1708206917Smarius
1709206917Smarius    ax = float64ToFloatX( a );
1710206917Smarius    bx = float64ToFloatX( b );
1711206917Smarius    if ( ax.isNaN || bx.isNaN ) {
1712206917Smarius        slow_float_exception_flags |= float_flag_invalid;
1713206917Smarius    }
1714206917Smarius    return floatXEq( ax, bx );
1715206917Smarius
1716206917Smarius}
1717206917Smarius
1718206917Smariusflag slow_float64_le_quiet( float64 a, float64 b )
1719206917Smarius{
1720206917Smarius
1721206917Smarius    return floatXLe( float64ToFloatX( a ), float64ToFloatX( b ) );
1722206917Smarius
1723206917Smarius}
1724206917Smarius
1725206917Smariusflag slow_float64_lt_quiet( float64 a, float64 b )
1726206917Smarius{
1727206917Smarius
1728206917Smarius    return floatXLt( float64ToFloatX( a ), float64ToFloatX( b ) );
1729206917Smarius
1730206917Smarius}
1731206917Smarius
1732206917Smarius#ifdef FLOATX80
1733206917Smarius
1734206917Smariusint32 slow_floatx80_to_int32( floatx80 a )
1735206917Smarius{
1736206917Smarius
1737206917Smarius    return floatXToInt32( floatx80ToFloatX( a ) );
1738206917Smarius
1739206917Smarius}
1740206917Smarius
1741206917Smariusint32 slow_floatx80_to_int32_round_to_zero( floatx80 a )
1742206917Smarius{
1743206917Smarius    int8 savedRoundingMode;
1744206917Smarius    int32 z;
1745206917Smarius
1746206917Smarius    savedRoundingMode = slow_float_rounding_mode;
1747206917Smarius    slow_float_rounding_mode = float_round_to_zero;
1748206917Smarius    z = floatXToInt32( floatx80ToFloatX( a ) );
1749206917Smarius    slow_float_rounding_mode = savedRoundingMode;
1750206917Smarius    return z;
1751206917Smarius
1752206917Smarius}
1753206917Smarius
1754206917Smariusint64 slow_floatx80_to_int64( floatx80 a )
1755206917Smarius{
1756206917Smarius
1757206917Smarius    return floatXToInt64( floatx80ToFloatX( a ) );
1758206917Smarius
1759206917Smarius}
1760206917Smarius
1761206917Smariusint64 slow_floatx80_to_int64_round_to_zero( floatx80 a )
1762206917Smarius{
1763206917Smarius    int8 savedRoundingMode;
1764206917Smarius    int64 z;
1765206917Smarius
1766206917Smarius    savedRoundingMode = slow_float_rounding_mode;
1767206917Smarius    slow_float_rounding_mode = float_round_to_zero;
1768206917Smarius    z = floatXToInt64( floatx80ToFloatX( a ) );
1769206917Smarius    slow_float_rounding_mode = savedRoundingMode;
1770206917Smarius    return z;
1771206917Smarius
1772206917Smarius}
1773206917Smarius
1774206917Smariusfloat32 slow_floatx80_to_float32( floatx80 a )
1775206917Smarius{
1776206917Smarius
1777206917Smarius    return floatXToFloat32( floatx80ToFloatX( a ) );
1778206917Smarius
1779206917Smarius}
1780206917Smarius
1781206917Smariusfloat64 slow_floatx80_to_float64( floatx80 a )
1782206917Smarius{
1783206917Smarius
1784206917Smarius    return floatXToFloat64( floatx80ToFloatX( a ) );
1785206917Smarius
1786206917Smarius}
1787206917Smarius
1788206917Smarius#ifdef FLOAT128
1789206917Smarius
1790206917Smariusfloat128 slow_floatx80_to_float128( floatx80 a )
1791206917Smarius{
1792206917Smarius
1793206917Smarius    return floatXToFloat128( floatx80ToFloatX( a ) );
1794206917Smarius
1795206917Smarius}
1796206917Smarius
1797206917Smarius#endif
1798206917Smarius
1799206917Smariusfloatx80 slow_floatx80_round_to_int( floatx80 a )
1800206917Smarius{
1801206917Smarius
1802206917Smarius    return floatXToFloatx80( floatXRoundToInt( floatx80ToFloatX( a ) ) );
1803206917Smarius
1804206917Smarius}
1805206917Smarius
1806206917Smariusfloatx80 slow_floatx80_add( floatx80 a, floatx80 b )
1807206917Smarius{
1808206917Smarius
1809206917Smarius    return
1810206917Smarius        floatXToFloatx80(
1811206917Smarius            floatXAdd( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
1812206917Smarius
1813206917Smarius}
1814206917Smarius
1815206917Smariusfloatx80 slow_floatx80_sub( floatx80 a, floatx80 b )
1816206917Smarius{
1817206917Smarius
1818206917Smarius    b.high ^= 0x8000;
1819206917Smarius    return
1820206917Smarius        floatXToFloatx80(
1821206917Smarius            floatXAdd( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
1822206917Smarius
1823206917Smarius}
1824206917Smarius
1825206917Smariusfloatx80 slow_floatx80_mul( floatx80 a, floatx80 b )
1826206917Smarius{
1827206917Smarius
1828206917Smarius    return
1829206917Smarius        floatXToFloatx80(
1830206917Smarius            floatXMul( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
1831206917Smarius
1832206917Smarius}
1833206917Smarius
1834206917Smariusfloatx80 slow_floatx80_div( floatx80 a, floatx80 b )
1835206917Smarius{
1836206917Smarius
1837206917Smarius    return
1838206917Smarius        floatXToFloatx80(
1839206917Smarius            floatXDiv( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
1840206917Smarius
1841206917Smarius}
1842206917Smarius
1843206917Smariusfloatx80 slow_floatx80_rem( floatx80 a, floatx80 b )
1844206917Smarius{
1845206917Smarius
1846206917Smarius    return
1847206917Smarius        floatXToFloatx80(
1848206917Smarius            floatXRem( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
1849206917Smarius
1850206917Smarius}
1851206917Smarius
1852206917Smariusfloatx80 slow_floatx80_sqrt( floatx80 a )
1853206917Smarius{
1854206917Smarius
1855206917Smarius    return floatXToFloatx80( floatXSqrt( floatx80ToFloatX( a ) ) );
1856206917Smarius
1857206917Smarius}
1858206917Smarius
1859206917Smariusflag slow_floatx80_eq( floatx80 a, floatx80 b )
1860206917Smarius{
1861206917Smarius
1862206917Smarius    return floatXEq( floatx80ToFloatX( a ), floatx80ToFloatX( b ) );
1863206917Smarius
1864206917Smarius}
1865206917Smarius
1866206917Smariusflag slow_floatx80_le( floatx80 a, floatx80 b )
1867206917Smarius{
1868206917Smarius    floatX ax, bx;
1869206917Smarius
1870206917Smarius    ax = floatx80ToFloatX( a );
1871206917Smarius    bx = floatx80ToFloatX( b );
1872206917Smarius    if ( ax.isNaN || bx.isNaN ) {
1873206917Smarius        slow_float_exception_flags |= float_flag_invalid;
1874206917Smarius    }
1875206917Smarius    return floatXLe( ax, bx );
1876206917Smarius
1877206917Smarius}
1878206917Smarius
1879206917Smariusflag slow_floatx80_lt( floatx80 a, floatx80 b )
1880206917Smarius{
1881206917Smarius    floatX ax, bx;
1882206917Smarius
1883206917Smarius    ax = floatx80ToFloatX( a );
1884206917Smarius    bx = floatx80ToFloatX( b );
1885206917Smarius    if ( ax.isNaN || bx.isNaN ) {
1886206917Smarius        slow_float_exception_flags |= float_flag_invalid;
1887206917Smarius    }
1888206917Smarius    return floatXLt( ax, bx );
1889206917Smarius
1890206917Smarius}
1891206917Smarius
1892206917Smariusflag slow_floatx80_eq_signaling( floatx80 a, floatx80 b )
1893206917Smarius{
1894206917Smarius    floatX ax, bx;
1895206917Smarius
1896206917Smarius    ax = floatx80ToFloatX( a );
1897206917Smarius    bx = floatx80ToFloatX( b );
1898206917Smarius    if ( ax.isNaN || bx.isNaN ) {
1899206917Smarius        slow_float_exception_flags |= float_flag_invalid;
1900206917Smarius    }
1901206917Smarius    return floatXEq( ax, bx );
1902206917Smarius
1903206917Smarius}
1904206917Smarius
1905206917Smariusflag slow_floatx80_le_quiet( floatx80 a, floatx80 b )
1906206917Smarius{
1907206917Smarius
1908206917Smarius    return floatXLe( floatx80ToFloatX( a ), floatx80ToFloatX( b ) );
1909206917Smarius
1910206917Smarius}
1911206917Smarius
1912206917Smariusflag slow_floatx80_lt_quiet( floatx80 a, floatx80 b )
1913206917Smarius{
1914206917Smarius
1915206917Smarius    return floatXLt( floatx80ToFloatX( a ), floatx80ToFloatX( b ) );
1916206917Smarius
1917206917Smarius}
1918206917Smarius
1919206917Smarius#endif
1920206917Smarius
1921206917Smarius#ifdef FLOAT128
1922206917Smarius
1923206917Smariusint32 slow_float128_to_int32( float128 a )
1924206917Smarius{
1925206917Smarius
1926206917Smarius    return floatXToInt32( float128ToFloatX( a ) );
1927206917Smarius
1928206917Smarius}
1929206917Smarius
1930206917Smariusint32 slow_float128_to_int32_round_to_zero( float128 a )
1931206917Smarius{
1932206917Smarius    int8 savedRoundingMode;
1933206917Smarius    int32 z;
1934206917Smarius
1935206917Smarius    savedRoundingMode = slow_float_rounding_mode;
1936206917Smarius    slow_float_rounding_mode = float_round_to_zero;
1937206917Smarius    z = floatXToInt32( float128ToFloatX( a ) );
1938206917Smarius    slow_float_rounding_mode = savedRoundingMode;
1939206917Smarius    return z;
1940206917Smarius
1941206917Smarius}
1942206917Smarius
1943206917Smariusint64 slow_float128_to_int64( float128 a )
1944206917Smarius{
1945206917Smarius
1946206917Smarius    return floatXToInt64( float128ToFloatX( a ) );
1947206917Smarius
1948206917Smarius}
1949206917Smarius
1950206917Smariusint64 slow_float128_to_int64_round_to_zero( float128 a )
1951206917Smarius{
1952206917Smarius    int8 savedRoundingMode;
1953206917Smarius    int64 z;
1954206917Smarius
1955206917Smarius    savedRoundingMode = slow_float_rounding_mode;
1956206917Smarius    slow_float_rounding_mode = float_round_to_zero;
1957206917Smarius    z = floatXToInt64( float128ToFloatX( a ) );
1958206917Smarius    slow_float_rounding_mode = savedRoundingMode;
1959206917Smarius    return z;
1960206917Smarius
1961206917Smarius}
1962206917Smarius
1963206917Smariusfloat32 slow_float128_to_float32( float128 a )
1964206917Smarius{
1965206917Smarius
1966206917Smarius    return floatXToFloat32( float128ToFloatX( a ) );
1967206917Smarius
1968206917Smarius}
1969206917Smarius
1970206917Smariusfloat64 slow_float128_to_float64( float128 a )
1971206917Smarius{
1972206917Smarius
1973206917Smarius    return floatXToFloat64( float128ToFloatX( a ) );
1974206917Smarius
1975206917Smarius}
1976206917Smarius
1977206917Smarius#ifdef FLOATX80
1978206917Smarius
1979206917Smariusfloatx80 slow_float128_to_floatx80( float128 a )
1980206917Smarius{
1981206917Smarius
1982206917Smarius    return floatXToFloatx80( float128ToFloatX( a ) );
1983206917Smarius
1984206917Smarius}
1985206917Smarius
1986206917Smarius#endif
1987206917Smarius
1988206917Smariusfloat128 slow_float128_round_to_int( float128 a )
1989206917Smarius{
1990206917Smarius
1991206917Smarius    return floatXToFloat128( floatXRoundToInt( float128ToFloatX( a ) ) );
1992206917Smarius
1993206917Smarius}
1994206917Smarius
1995206917Smariusfloat128 slow_float128_add( float128 a, float128 b )
1996206917Smarius{
1997206917Smarius
1998206917Smarius    return
1999206917Smarius        floatXToFloat128(
2000206917Smarius            floatXAdd( float128ToFloatX( a ), float128ToFloatX( b ) ) );
2001206917Smarius
2002206917Smarius}
2003206917Smarius
2004206917Smariusfloat128 slow_float128_sub( float128 a, float128 b )
2005206917Smarius{
2006206917Smarius
2007206917Smarius    b.high ^= LIT64( 0x8000000000000000 );
2008206917Smarius    return
2009206917Smarius        floatXToFloat128(
2010206917Smarius            floatXAdd( float128ToFloatX( a ), float128ToFloatX( b ) ) );
2011206917Smarius
2012206917Smarius}
2013206917Smarius
2014206917Smariusfloat128 slow_float128_mul( float128 a, float128 b )
2015206917Smarius{
2016206917Smarius
2017206917Smarius    return
2018206917Smarius        floatXToFloat128(
2019206917Smarius            floatXMul( float128ToFloatX( a ), float128ToFloatX( b ) ) );
2020206917Smarius
2021206917Smarius}
2022206917Smarius
2023206917Smariusfloat128 slow_float128_div( float128 a, float128 b )
2024206917Smarius{
2025206917Smarius
2026206917Smarius    return
2027206917Smarius        floatXToFloat128(
2028206917Smarius            floatXDiv( float128ToFloatX( a ), float128ToFloatX( b ) ) );
2029206917Smarius
2030206917Smarius}
2031206917Smarius
2032206917Smariusfloat128 slow_float128_rem( float128 a, float128 b )
2033206917Smarius{
2034206917Smarius
2035206917Smarius    return
2036206917Smarius        floatXToFloat128(
2037206917Smarius            floatXRem( float128ToFloatX( a ), float128ToFloatX( b ) ) );
2038206917Smarius
2039206917Smarius}
2040206917Smarius
2041206917Smariusfloat128 slow_float128_sqrt( float128 a )
2042206917Smarius{
2043206917Smarius
2044206917Smarius    return floatXToFloat128( floatXSqrt( float128ToFloatX( a ) ) );
2045206917Smarius
2046206917Smarius}
2047206917Smarius
2048206917Smariusflag slow_float128_eq( float128 a, float128 b )
2049206917Smarius{
2050206917Smarius
2051206917Smarius    return floatXEq( float128ToFloatX( a ), float128ToFloatX( b ) );
2052206917Smarius
2053206917Smarius}
2054206917Smarius
2055206917Smariusflag slow_float128_le( float128 a, float128 b )
2056206917Smarius{
2057206917Smarius    floatX ax, bx;
2058206917Smarius
2059206917Smarius    ax = float128ToFloatX( a );
2060206917Smarius    bx = float128ToFloatX( b );
2061206917Smarius    if ( ax.isNaN || bx.isNaN ) {
2062206917Smarius        slow_float_exception_flags |= float_flag_invalid;
2063206917Smarius    }
2064206917Smarius    return floatXLe( ax, bx );
2065206917Smarius
2066206917Smarius}
2067206917Smarius
2068206917Smariusflag slow_float128_lt( float128 a, float128 b )
2069206917Smarius{
2070206917Smarius    floatX ax, bx;
2071206917Smarius
2072206917Smarius    ax = float128ToFloatX( a );
2073206917Smarius    bx = float128ToFloatX( b );
2074206917Smarius    if ( ax.isNaN || bx.isNaN ) {
2075206917Smarius        slow_float_exception_flags |= float_flag_invalid;
2076206917Smarius    }
2077206917Smarius    return floatXLt( ax, bx );
2078206917Smarius
2079206917Smarius}
2080206917Smarius
2081206917Smariusflag slow_float128_eq_signaling( float128 a, float128 b )
2082206917Smarius{
2083206917Smarius    floatX ax, bx;
2084206917Smarius
2085206917Smarius    ax = float128ToFloatX( a );
2086206917Smarius    bx = float128ToFloatX( b );
2087206917Smarius    if ( ax.isNaN || bx.isNaN ) {
2088206917Smarius        slow_float_exception_flags |= float_flag_invalid;
2089206917Smarius    }
2090206917Smarius    return floatXEq( ax, bx );
2091206917Smarius
2092206917Smarius}
2093206917Smarius
2094206917Smariusflag slow_float128_le_quiet( float128 a, float128 b )
2095206917Smarius{
2096206917Smarius
2097206917Smarius    return floatXLe( float128ToFloatX( a ), float128ToFloatX( b ) );
2098206917Smarius
2099206917Smarius}
2100206917Smarius
2101206917Smariusflag slow_float128_lt_quiet( float128 a, float128 b )
2102206917Smarius{
2103206917Smarius
2104206917Smarius    return floatXLt( float128ToFloatX( a ), float128ToFloatX( b ) );
2105206917Smarius
2106206917Smarius}
2107206917Smarius
2108206917Smarius#endif
2109206917Smarius
2110