OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [sw/] [apps/] [testfloat/] [slowfloat.c] - Blame information for rev 498

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 349 julius
 
2
/*
3
===============================================================================
4
 
5
This C source file is part of TestFloat, Release 2a, a package of programs
6
for testing the correctness of floating-point arithmetic complying to the
7
IEC/IEEE Standard for Floating-Point.
8
 
9
Written by John R. Hauser.  More information is available through the Web
10
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
11
 
12
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
13
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
14
TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
15
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
16
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
17
 
18
Derivative works are acceptable, even for commercial purposes, so long as
19
(1) they include prominent notice that the work is derivative, and (2) they
20
include prominent notice akin to these four paragraphs for those parts of
21
this code that are retained.
22
 
23
Modified for use with or1ksim's testsuite.
24
 
25
Contributor Julius Baxter <julius.baxter@orsoc.se>
26
 
27
===============================================================================
28
*/
29
 
30
#include "milieu.h"
31
#include "softfloat.h"
32
#include "slowfloat.h"
33
 
34
// From slowfloat-64.c
35
 
36
int8 slow_float_rounding_mode;
37
int8 slow_float_exception_flags;
38
int8 slow_float_detect_tininess;
39
#ifdef FLOATX80
40
int8 slow_floatx80_rounding_precision;
41
#endif
42
 
43
typedef struct {
44
    bits64 a0, a1;
45
} bits128X;
46
 
47
typedef struct {
48
    flag isNaN;
49
    flag isInf;
50
    flag isZero;
51
    flag sign;
52
    int32 exp;
53
    bits128X sig;
54
} floatX;
55
 
56
static const floatX floatXNaN = { TRUE, FALSE, FALSE, FALSE, 0, { 0, 0 } };
57
static const floatX floatXPositiveZero =
58
    { FALSE, FALSE, TRUE, FALSE, 0, { 0, 0 } };
59
static const floatX floatXNegativeZero =
60
    { FALSE, FALSE, TRUE, TRUE, 0, { 0, 0 } };
61
 
62
static bits128X shortShift128Left( bits128X a, int8 shiftCount )
63
{
64
    int8 negShiftCount;
65
 
66
    negShiftCount = ( - shiftCount & 63 );
67
    a.a0 = ( a.a0<<shiftCount ) | ( a.a1>>negShiftCount );
68
    a.a1 <<= shiftCount;
69
    return a;
70
 
71
}
72
 
73
static bits128X shortShift128RightJamming( bits128X a, int8 shiftCount )
74
{
75
    int8 negShiftCount;
76
    bits64 extra;
77
 
78
    negShiftCount = ( - shiftCount & 63 );
79
    extra = a.a1<<negShiftCount;
80
    a.a1 = ( a.a0<<negShiftCount ) | ( a.a1>>shiftCount ) | ( extra != 0 );
81
    a.a0 >>= shiftCount;
82
    return a;
83
 
84
}
85
 
86
static bits128X neg128( bits128X a )
87
{
88
 
89
    if ( a.a1 == 0 ) {
90
        a.a0 = - a.a0;
91
    }
92
    else {
93
        a.a1 = - a.a1;
94
        a.a0 = ~ a.a0;
95
    }
96
    return a;
97
 
98
}
99
 
100
static bits128X add128( bits128X a, bits128X b )
101
{
102
 
103
    a.a1 += b.a1;
104
    a.a0 += b.a0 + ( a.a1 < b.a1 );
105
    return a;
106
 
107
}
108
 
109
static flag eq128( bits128X a, bits128X b )
110
{
111
 
112
    return ( a.a0 == b.a0 ) && ( a.a1 == b.a1 );
113
 
114
}
115
 
116
static flag le128( bits128X a, bits128X b )
117
{
118
 
119
    return ( a.a0 < b.a0 ) || ( ( a.a0 == b.a0 ) && ( a.a1 <= b.a1 ) );
120
 
121
}
122
 
123
static flag lt128( bits128X a, bits128X b )
124
{
125
 
126
    return ( a.a0 < b.a0 ) || ( ( a.a0 == b.a0 ) && ( a.a1 < b.a1 ) );
127
 
128
}
129
 
130
static floatX roundFloatXTo24( flag isTiny, floatX zx )
131
{
132
    bits32 roundBits;
133
 
134
    zx.sig.a0 |= ( zx.sig.a1 != 0 );
135
    zx.sig.a1 = 0;
136
    roundBits = zx.sig.a0 & 0xFFFFFFFF;
137
    zx.sig.a0 -= roundBits;
138
    if ( roundBits ) {
139
        slow_float_exception_flags |= float_flag_inexact;
140
        if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
141
        switch ( slow_float_rounding_mode ) {
142
         case float_round_nearest_even:
143
            if ( roundBits < 0x80000000 ) goto noIncrement;
144
            if (    ( roundBits == 0x80000000 )
145
                 && ! ( zx.sig.a0 & LIT64( 0x100000000 ) ) ) {
146
                goto noIncrement;
147
            }
148
            break;
149
         case float_round_to_zero:
150
            goto noIncrement;
151
         case float_round_down:
152
            if ( ! zx.sign ) goto noIncrement;
153
            break;
154
         case float_round_up:
155
            if ( zx.sign ) goto noIncrement;
156
            break;
157
        }
158
        zx.sig.a0 += LIT64( 0x100000000 );
159
        if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
160
            zx.sig.a0 = LIT64( 0x0080000000000000 );
161
            ++zx.exp;
162
        }
163
    }
164
 noIncrement:
165
    return zx;
166
 
167
}
168
 
169
static floatX roundFloatXTo53( flag isTiny, floatX zx )
170
{
171
    int8 roundBits;
172
 
173
    zx.sig.a0 |= ( zx.sig.a1 != 0 );
174
    zx.sig.a1 = 0;
175
    roundBits = zx.sig.a0 & 7;
176
    zx.sig.a0 -= roundBits;
177
    if ( roundBits ) {
178
        slow_float_exception_flags |= float_flag_inexact;
179
        if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
180
        switch ( slow_float_rounding_mode ) {
181
         case float_round_nearest_even:
182
            if ( roundBits < 4 ) goto noIncrement;
183
            if ( ( roundBits == 4 ) && ! ( zx.sig.a0 & 8 ) ) goto noIncrement;
184
            break;
185
         case float_round_to_zero:
186
            goto noIncrement;
187
         case float_round_down:
188
            if ( ! zx.sign ) goto noIncrement;
189
            break;
190
         case float_round_up:
191
            if ( zx.sign ) goto noIncrement;
192
            break;
193
        }
194
        zx.sig.a0 += 8;
195
        if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
196
            zx.sig.a0 = LIT64( 0x0080000000000000 );
197
            ++zx.exp;
198
        }
199
    }
200
 noIncrement:
201
    return zx;
202
 
203
}
204
 
205
#ifdef FLOATX80
206
static floatX roundFloatXTo64( flag isTiny, floatX zx )
207
{
208
    int64 roundBits;
209
 
210
    roundBits = zx.sig.a1 & LIT64( 0x00FFFFFFFFFFFFFF );
211
    zx.sig.a1 -= roundBits;
212
    if ( roundBits ) {
213
        slow_float_exception_flags |= float_flag_inexact;
214
        if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
215
        switch ( slow_float_rounding_mode ) {
216
         case float_round_nearest_even:
217
            if ( roundBits < LIT64( 0x0080000000000000 ) ) goto noIncrement;
218
            if (    ( roundBits == LIT64( 0x0080000000000000 ) )
219
                 && ! ( zx.sig.a1 & LIT64( 0x0100000000000000 ) ) ) {
220
                goto noIncrement;
221
            }
222
            break;
223
         case float_round_to_zero:
224
            goto noIncrement;
225
         case float_round_down:
226
            if ( ! zx.sign ) goto noIncrement;
227
            break;
228
         case float_round_up:
229
            if ( zx.sign ) goto noIncrement;
230
            break;
231
        }
232
        zx.sig.a1 += LIT64( 0x0100000000000000 );
233
        zx.sig.a0 += ( zx.sig.a1 == 0 );
234
        if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
235
            zx.sig.a0 = LIT64( 0x0080000000000000 );
236
            ++zx.exp;
237
        }
238
    }
239
 noIncrement:
240
    return zx;
241
 
242
}
243
#endif
244
static floatX roundFloatXTo113( flag isTiny, floatX zx )
245
{
246
    int8 roundBits;
247
 
248
    roundBits = zx.sig.a1 & 0x7F;
249
    zx.sig.a1 -= roundBits;
250
    if ( roundBits ) {
251
        slow_float_exception_flags |= float_flag_inexact;
252
        if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
253
        switch ( slow_float_rounding_mode ) {
254
         case float_round_nearest_even:
255
            if ( roundBits < 0x40 ) goto noIncrement;
256
            if (    ( roundBits == 0x40 )
257
                 && ! ( zx.sig.a1 & 0x80 ) ) goto noIncrement;
258
            break;
259
         case float_round_to_zero:
260
            goto noIncrement;
261
         case float_round_down:
262
            if ( ! zx.sign ) goto noIncrement;
263
            break;
264
         case float_round_up:
265
            if ( zx.sign ) goto noIncrement;
266
            break;
267
        }
268
        zx.sig.a1 += 0x80;
269
        zx.sig.a0 += ( zx.sig.a1 == 0 );
270
        if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
271
            zx.sig.a0 = LIT64( 0x0080000000000000 );
272
            ++zx.exp;
273
        }
274
    }
275
 noIncrement:
276
    return zx;
277
 
278
}
279
 
280
static floatX int32ToFloatX( int32 a )
281
{
282
    floatX ax;
283
 
284
    ax.isNaN = FALSE;
285
    ax.isInf = FALSE;
286
    ax.exp = 0; // Initialise it to keep GCC happy
287
    ax.sign = ( a < 0 );
288
    ax.sig.a1 = 0;
289
    ax.sig.a0 = ax.sign ? - (bits64) a : a;
290
    if ( a == 0 ) {
291
        ax.isZero = TRUE;
292
        return ax;
293
    }
294
    ax.isZero = FALSE;
295
    ax.sig.a0 <<= 24;
296
    ax.exp = 31;
297
    while ( ax.sig.a0 < LIT64( 0x0080000000000000 ) ) {
298
        ax.sig.a0 <<= 1;
299
        --ax.exp;
300
    }
301
    return ax;
302
 
303
}
304
 
305
static int32 floatXToInt32( floatX ax )
306
{
307
    int8 savedExceptionFlags;
308
    int32 shiftCount;
309
    int32 z;
310
 
311
    if ( ax.isInf || ax.isNaN ) {
312
        slow_float_exception_flags |= float_flag_invalid;
313
        return ( ax.isInf & ax.sign ) ? (sbits32) 0x80000000 : 0x7FFFFFFF;
314
    }
315
    if ( ax.isZero ) return 0;
316
    savedExceptionFlags = slow_float_exception_flags;
317
    shiftCount = 52 - ax.exp;
318
    if ( 56 < shiftCount ) {
319
        ax.sig.a1 = 1;
320
        ax.sig.a0 = 0;
321
    }
322
    else {
323
        while ( 0 < shiftCount ) {
324
            ax.sig = shortShift128RightJamming( ax.sig, 1 );
325
            --shiftCount;
326
        }
327
    }
328
    ax = roundFloatXTo53( FALSE, ax );
329
    ax.sig = shortShift128RightJamming( ax.sig, 3 );
330
    z = ax.sig.a0;
331
    if ( ax.sign ) z = - z;
332
    if (    ( shiftCount < 0 )
333
         || ( ax.sig.a0>>32 )
334
         || ( ( z != 0 ) && ( ( ax.sign ^ ( z < 0 ) ) != 0 ) )
335
       ) {
336
        slow_float_exception_flags = savedExceptionFlags | float_flag_invalid;
337
        return ax.sign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
338
    }
339
    return z;
340
 
341
}
342
 
343
static floatX int64ToFloatX( int64 a )
344
{
345
    floatX ax;
346
 
347
    ax.isNaN = FALSE;
348
    ax.isInf = FALSE;
349
    ax.exp = 0; // Init to keep GCC happy
350
    ax.sign = ( a < 0 );
351
    ax.sig.a1 = ax.sign ? - a : a;
352
    ax.sig.a0 = 0;
353
    if ( a == 0 ) {
354
        ax.isZero = TRUE;
355
        return ax;
356
    }
357
    ax.isZero = FALSE;
358
    ax.sig = shortShift128Left( ax.sig, 56 );
359
    ax.exp = 63;
360
    while ( ax.sig.a0 < LIT64( 0x0080000000000000 ) ) {
361
        ax.sig = shortShift128Left( ax.sig, 1 );
362
        --ax.exp;
363
    }
364
    return ax;
365
 
366
}
367
 
368
static int64 floatXToInt64( floatX ax )
369
{
370
    int8 savedExceptionFlags;
371
    int32 shiftCount;
372
    int64 z;
373
 
374
    if ( ax.isInf || ax.isNaN ) {
375
        slow_float_exception_flags |= float_flag_invalid;
376
        return
377
              ( ax.isInf & ax.sign ) ? (sbits64) LIT64( 0x8000000000000000 )
378
            : LIT64( 0x7FFFFFFFFFFFFFFF );
379
    }
380
    if ( ax.isZero ) return 0;
381
    savedExceptionFlags = slow_float_exception_flags;
382
    shiftCount = 112 - ax.exp;
383
    if ( 116 < shiftCount ) {
384
        ax.sig.a1 = 1;
385
        ax.sig.a0 = 0;
386
    }
387
    else {
388
        while ( 0 < shiftCount ) {
389
            ax.sig = shortShift128RightJamming( ax.sig, 1 );
390
            --shiftCount;
391
        }
392
    }
393
    ax = roundFloatXTo113( FALSE, ax );
394
    ax.sig = shortShift128RightJamming( ax.sig, 7 );
395
    z = ax.sig.a1;
396
    if ( ax.sign ) z = - z;
397
    if (    ( shiftCount < 0 )
398
         || ax.sig.a0
399
         || ( ( z != 0 ) && ( ( ax.sign ^ ( z < 0 ) ) != 0 ) )
400
       ) {
401
        slow_float_exception_flags = savedExceptionFlags | float_flag_invalid;
402
        return
403
              ax.sign ? (sbits64) LIT64( 0x8000000000000000 )
404
            : LIT64( 0x7FFFFFFFFFFFFFFF );
405
    }
406
    return z;
407
 
408
}
409
 
410
static floatX float32ToFloatX( float32 a )
411
{
412
    int16 expField;
413
    floatX ax;
414
 
415
    ax.isNaN = FALSE;
416
    ax.isInf = FALSE;
417
    ax.isZero = FALSE;
418
    ax.exp = 0; // Init here to keep GCC happy
419
    ax.sign = ( ( a & 0x80000000 ) != 0 );
420
    expField = ( a>>23 ) & 0xFF;
421
    ax.sig.a1 = 0;
422
    ax.sig.a0 = a & 0x007FFFFF;
423
    ax.sig.a0 <<= 32;
424
    if ( expField == 0 ) {
425
        if ( ax.sig.a0 == 0 ) {
426
            ax.isZero = TRUE;
427
        }
428
        else {
429
            expField = 1 - 0x7F;
430
            do {
431
                ax.sig.a0 <<= 1;
432
                --expField;
433
            } while ( ax.sig.a0 < LIT64( 0x0080000000000000 ) );
434
            ax.exp = expField;
435
        }
436
    }
437
    else if ( expField == 0xFF ) {
438
        if ( ax.sig.a0 == 0 ) {
439
            ax.isInf = TRUE;
440
        }
441
        else {
442
            ax.isNaN = TRUE;
443
        }
444
    }
445
    else {
446
        ax.sig.a0 |= LIT64( 0x0080000000000000 );
447
        ax.exp = expField - 0x7F;
448
    }
449
    return ax;
450
 
451
}
452
 
453
static float32 floatXToFloat32( floatX zx )
454
{
455
    floatX savedZ;
456
    flag isTiny;
457
    int32 expField;
458
    float32 z = 0;// Init this to keep GCC happy.
459
 
460
    if ( zx.isZero ) return zx.sign ? 0x80000000 : 0;
461
    if ( zx.isInf ) return zx.sign ? 0xFF800000 : 0x7F800000;
462
    if ( zx.isNaN ) return 0xFFFFFFFF;
463
    while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
464
        zx.sig = shortShift128RightJamming( zx.sig, 1 );
465
        ++zx.exp;
466
    }
467
    while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
468
        zx.sig = shortShift128Left( zx.sig, 1 );
469
        --zx.exp;
470
    }
471
    savedZ = zx;
472
    isTiny =
473
           ( slow_float_detect_tininess == float_tininess_before_rounding )
474
        && ( zx.exp + 0x7F <= 0 );
475
    zx = roundFloatXTo24( isTiny, zx );
476
    expField = zx.exp + 0x7F;
477
    if ( 0xFF <= expField ) {
478
        slow_float_exception_flags |=
479
            float_flag_overflow | float_flag_inexact;
480
        if ( zx.sign ) {
481
            switch ( slow_float_rounding_mode ) {
482
             case float_round_nearest_even:
483
             case float_round_down:
484
                z = 0xFF800000;
485
                break;
486
             case float_round_to_zero:
487
             case float_round_up:
488
                z = 0xFF7FFFFF;
489
                break;
490
            }
491
        }
492
        else {
493
            switch ( slow_float_rounding_mode ) {
494
             case float_round_nearest_even:
495
             case float_round_up:
496
                z = 0x7F800000;
497
                break;
498
             case float_round_to_zero:
499
             case float_round_down:
500
                z = 0x7F7FFFFF;
501
                break;
502
            }
503
        }
504
        return z;
505
    }
506
    if ( expField <= 0 ) {
507
        isTiny = TRUE;
508
        zx = savedZ;
509
        expField = zx.exp + 0x7F;
510
        if ( expField < -27 ) {
511
            zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
512
            zx.sig.a0 = 0;
513
        }
514
        else {
515
            while ( expField <= 0 ) {
516
                zx.sig = shortShift128RightJamming( zx.sig, 1 );
517
                ++expField;
518
            }
519
        }
520
        zx = roundFloatXTo24( isTiny, zx );
521
        expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
522
    }
523
    z = expField;
524
    z <<= 23;
525
    if ( zx.sign ) z |= 0x80000000;
526
    z |= ( zx.sig.a0>>32 ) & 0x007FFFFF;
527
    return z;
528
 
529
}
530
 
531
static floatX float64ToFloatX( float64 a )
532
{
533
    int16 expField;
534
    floatX ax;
535
 
536
    ax.isNaN = FALSE;
537
    ax.isInf = FALSE;
538
    ax.isZero = FALSE;
539
    ax.exp = 0 ; // Init to keep GCC happy
540
    ax.sign = ( ( a & LIT64( 0x8000000000000000 ) ) != 0 );
541
    expField = ( a>>52 ) & 0x7FF;
542
    ax.sig.a1 = 0;
543
    ax.sig.a0 = a & LIT64( 0x000FFFFFFFFFFFFF );
544
    if ( expField == 0 ) {
545
        if ( ax.sig.a0 == 0 ) {
546
            ax.isZero = TRUE;
547
        }
548
        else {
549
            expField = 1 - 0x3FF;
550
            do {
551
                ax.sig.a0 <<= 1;
552
                --expField;
553
            } while ( ax.sig.a0 < LIT64( 0x0010000000000000 ) );
554
            ax.exp = expField;
555
        }
556
    }
557
    else if ( expField == 0x7FF ) {
558
        if ( ax.sig.a0 == 0 ) {
559
            ax.isInf = TRUE;
560
        }
561
        else {
562
            ax.isNaN = TRUE;
563
        }
564
    }
565
    else {
566
        ax.exp = expField - 0x3FF;
567
        ax.sig.a0 |= LIT64( 0x0010000000000000 );
568
    }
569
    ax.sig.a0 <<= 3;
570
    return ax;
571
 
572
}
573
 
574
static float64 floatXToFloat64( floatX zx )
575
{
576
    floatX savedZ;
577
    flag isTiny;
578
    int32 expField;
579
    float64 z = 0 ;// Init to keep GCC happy
580
 
581
    if ( zx.isZero ) return zx.sign ? LIT64( 0x8000000000000000 ) : 0;
582
    if ( zx.isInf ) {
583
        return
584
              zx.sign ? LIT64( 0xFFF0000000000000 )
585
            : LIT64( 0x7FF0000000000000 );
586
    }
587
    if ( zx.isNaN ) return LIT64( 0xFFFFFFFFFFFFFFFF );
588
    while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
589
        zx.sig = shortShift128RightJamming( zx.sig, 1 );
590
        ++zx.exp;
591
    }
592
    while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
593
        zx.sig = shortShift128Left( zx.sig, 1 );
594
        --zx.exp;
595
    }
596
    savedZ = zx;
597
    isTiny =
598
           ( slow_float_detect_tininess == float_tininess_before_rounding )
599
        && ( zx.exp + 0x3FF <= 0 );
600
    zx = roundFloatXTo53( isTiny, zx );
601
    expField = zx.exp + 0x3FF;
602
    if ( 0x7FF <= expField ) {
603
        slow_float_exception_flags |=
604
            float_flag_overflow | float_flag_inexact;
605
        if ( zx.sign ) {
606
            switch ( slow_float_rounding_mode ) {
607
             case float_round_nearest_even:
608
             case float_round_down:
609
                z = LIT64( 0xFFF0000000000000 );
610
                break;
611
             case float_round_to_zero:
612
             case float_round_up:
613
                z = LIT64( 0xFFEFFFFFFFFFFFFF );
614
                break;
615
            }
616
        }
617
        else {
618
            switch ( slow_float_rounding_mode ) {
619
             case float_round_nearest_even:
620
             case float_round_up:
621
                z = LIT64( 0x7FF0000000000000 );
622
                break;
623
             case float_round_to_zero:
624
             case float_round_down:
625
                z = LIT64( 0x7FEFFFFFFFFFFFFF );
626
                break;
627
            }
628
        }
629
        return z;
630
    }
631
    if ( expField <= 0 ) {
632
        isTiny = TRUE;
633
        zx = savedZ;
634
        expField = zx.exp + 0x3FF;
635
        if ( expField < -56 ) {
636
            zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
637
            zx.sig.a0 = 0;
638
        }
639
        else {
640
            while ( expField <= 0 ) {
641
                zx.sig = shortShift128RightJamming( zx.sig, 1 );
642
                ++expField;
643
            }
644
        }
645
        zx = roundFloatXTo53( isTiny, zx );
646
        expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
647
    }
648
    zx.sig.a0 >>= 3;
649
    z = expField;
650
    z <<= 52;
651
    if ( zx.sign ) z |= LIT64( 0x8000000000000000 );
652
    z |= zx.sig.a0 & LIT64( 0x000FFFFFFFFFFFFF );
653
    return z;
654
 
655
}
656
 
657
#ifdef FLOATX80
658
 
659
static floatX floatx80ToFloatX( floatx80 a )
660
{
661
    int32 expField;
662
    floatX ax;
663
 
664
    ax.isNaN = FALSE;
665
    ax.isInf = FALSE;
666
    ax.isZero = FALSE;
667
    ax.sign = ( ( a.high & 0x8000 ) != 0 );
668
    expField = a.high & 0x7FFF;
669
    ax.sig.a1 = a.low;
670
    ax.sig.a0 = 0;
671
    if ( expField == 0 ) {
672
        if ( ax.sig.a1 == 0 ) {
673
            ax.isZero = TRUE;
674
        }
675
        else {
676
            expField = 1 - 0x3FFF;
677
            while ( ax.sig.a1 < LIT64( 0x8000000000000000 ) ) {
678
                ax.sig.a1 <<= 1;
679
                --expField;
680
            }
681
            ax.exp = expField;
682
        }
683
    }
684
    else if ( expField == 0x7FFF ) {
685
        if ( ( ax.sig.a1 & LIT64( 0x7FFFFFFFFFFFFFFF ) ) == 0 ) {
686
            ax.isInf = TRUE;
687
        }
688
        else {
689
            ax.isNaN = TRUE;
690
        }
691
    }
692
    else {
693
        ax.exp = expField - 0x3FFF;
694
    }
695
    ax.sig = shortShift128Left( ax.sig, 56 );
696
    return ax;
697
 
698
}
699
 
700
static floatx80 floatXToFloatx80( floatX zx )
701
{
702
    floatX savedZ;
703
    flag isTiny;
704
    int32 expField;
705
    floatx80 z;
706
 
707
    if ( zx.isZero ) {
708
        z.low = 0;
709
        z.high = zx.sign ? 0x8000 : 0;
710
        return z;
711
    }
712
    if ( zx.isInf ) {
713
        z.low = LIT64( 0x8000000000000000 );
714
        z.high = zx.sign ? 0xFFFF : 0x7FFF;
715
        return z;
716
    }
717
    if ( zx.isNaN ) {
718
        z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
719
        z.high = 0xFFFF;
720
        return z;
721
    }
722
    while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
723
        zx.sig = shortShift128RightJamming( zx.sig, 1 );
724
        ++zx.exp;
725
    }
726
    while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
727
        zx.sig = shortShift128Left( zx.sig, 1 );
728
        --zx.exp;
729
    }
730
    savedZ = zx;
731
    isTiny =
732
           ( slow_float_detect_tininess == float_tininess_before_rounding )
733
        && ( zx.exp + 0x3FFF <= 0 );
734
    switch ( slow_floatx80_rounding_precision ) {
735
     case 32:
736
        zx = roundFloatXTo24( isTiny, zx );
737
        break;
738
     case 64:
739
        zx = roundFloatXTo53( isTiny, zx );
740
        break;
741
     default:
742
        zx = roundFloatXTo64( isTiny, zx );
743
        break;
744
    }
745
    expField = zx.exp + 0x3FFF;
746
    if ( 0x7FFF <= expField ) {
747
        slow_float_exception_flags |=
748
            float_flag_overflow | float_flag_inexact;
749
        if ( zx.sign ) {
750
            switch ( slow_float_rounding_mode ) {
751
             case float_round_nearest_even:
752
             case float_round_down:
753
                z.low = LIT64( 0x8000000000000000 );
754
                z.high = 0xFFFF;
755
                break;
756
             case float_round_to_zero:
757
             case float_round_up:
758
                switch ( slow_floatx80_rounding_precision ) {
759
                 case 32:
760
                    z.low = LIT64( 0xFFFFFF0000000000 );
761
                    break;
762
                 case 64:
763
                    z.low = LIT64( 0xFFFFFFFFFFFFF800 );
764
                    break;
765
                 default:
766
                    z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
767
                    break;
768
                }
769
                z.high = 0xFFFE;
770
                break;
771
            }
772
        }
773
        else {
774
            switch ( slow_float_rounding_mode ) {
775
             case float_round_nearest_even:
776
             case float_round_up:
777
                z.low = LIT64( 0x8000000000000000 );
778
                z.high = 0x7FFF;
779
                break;
780
             case float_round_to_zero:
781
             case float_round_down:
782
                switch ( slow_floatx80_rounding_precision ) {
783
                 case 32:
784
                    z.low = LIT64( 0xFFFFFF0000000000 );
785
                    break;
786
                 case 64:
787
                    z.low = LIT64( 0xFFFFFFFFFFFFF800 );
788
                    break;
789
                 default:
790
                    z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
791
                    break;
792
                }
793
                z.high = 0x7FFE;
794
                break;
795
            }
796
        }
797
        return z;
798
    }
799
    if ( expField <= 0 ) {
800
        isTiny = TRUE;
801
        zx = savedZ;
802
        expField = zx.exp + 0x3FFF;
803
        if ( expField < -70 ) {
804
            zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
805
            zx.sig.a0 = 0;
806
        }
807
        else {
808
            while ( expField <= 0 ) {
809
                zx.sig = shortShift128RightJamming( zx.sig, 1 );
810
                ++expField;
811
            }
812
        }
813
        switch ( slow_floatx80_rounding_precision ) {
814
         case 32:
815
            zx = roundFloatXTo24( isTiny, zx );
816
            break;
817
         case 64:
818
            zx = roundFloatXTo53( isTiny, zx );
819
            break;
820
         default:
821
            zx = roundFloatXTo64( isTiny, zx );
822
            break;
823
        }
824
        expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
825
    }
826
    zx.sig = shortShift128RightJamming( zx.sig, 56 );
827
    z.low = zx.sig.a1;
828
    z.high = expField;
829
    if ( zx.sign ) z.high |= 0x8000;
830
    return z;
831
 
832
}
833
 
834
#endif
835
 
836
#ifdef FLOAT128
837
 
838
static floatX float128ToFloatX( float128 a )
839
{
840
    int32 expField;
841
    floatX ax;
842
 
843
    ax.isNaN = FALSE;
844
    ax.isInf = FALSE;
845
    ax.isZero = FALSE;
846
    ax.sign = ( ( a.high & LIT64( 0x8000000000000000 ) ) != 0 );
847
    expField = ( a.high>>48 ) & 0x7FFF;
848
    ax.sig.a1 = a.low;
849
    ax.sig.a0 = a.high & LIT64( 0x0000FFFFFFFFFFFF );
850
    if ( expField == 0 ) {
851
        if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) {
852
            ax.isZero = TRUE;
853
        }
854
        else {
855
            expField = 1 - 0x3FFF;
856
            do {
857
                ax.sig = shortShift128Left( ax.sig, 1 );
858
                --expField;
859
            } while ( ax.sig.a0 < LIT64( 0x0001000000000000 ) );
860
            ax.exp = expField;
861
        }
862
    }
863
    else if ( expField == 0x7FFF ) {
864
        if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) {
865
            ax.isInf = TRUE;
866
        }
867
        else {
868
            ax.isNaN = TRUE;
869
        }
870
    }
871
    else {
872
        ax.exp = expField - 0x3FFF;
873
        ax.sig.a0 |= LIT64( 0x0001000000000000 );
874
    }
875
    ax.sig = shortShift128Left( ax.sig, 7 );
876
    return ax;
877
 
878
}
879
 
880
static float128 floatXToFloat128( floatX zx )
881
{
882
    floatX savedZ;
883
    flag isTiny;
884
    int32 expField;
885
    float128 z;
886
 
887
    if ( zx.isZero ) {
888
        z.low = 0;
889
        z.high = zx.sign ? LIT64( 0x8000000000000000 ) : 0;
890
        return z;
891
    }
892
    if ( zx.isInf ) {
893
        z.low = 0;
894
        z.high =
895
              zx.sign ? LIT64( 0xFFFF000000000000 )
896
            : LIT64( 0x7FFF000000000000 );
897
        return z;
898
    }
899
    if ( zx.isNaN ) {
900
        z.high = z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
901
        return z;
902
    }
903
    while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
904
        zx.sig = shortShift128RightJamming( zx.sig, 1 );
905
        ++zx.exp;
906
    }
907
    while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
908
        zx.sig = shortShift128Left( zx.sig, 1 );
909
        --zx.exp;
910
    }
911
    savedZ = zx;
912
    isTiny =
913
           ( slow_float_detect_tininess == float_tininess_before_rounding )
914
        && ( zx.exp + 0x3FFF <= 0 );
915
    zx = roundFloatXTo113( isTiny, zx );
916
    expField = zx.exp + 0x3FFF;
917
    if ( 0x7FFF <= expField ) {
918
        slow_float_exception_flags |=
919
            float_flag_overflow | float_flag_inexact;
920
        if ( zx.sign ) {
921
            switch ( slow_float_rounding_mode ) {
922
             case float_round_nearest_even:
923
             case float_round_down:
924
                z.low = 0;
925
                z.high = LIT64( 0xFFFF000000000000 );
926
                break;
927
             case float_round_to_zero:
928
             case float_round_up:
929
                z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
930
                z.high = LIT64( 0xFFFEFFFFFFFFFFFF );
931
                break;
932
            }
933
        }
934
        else {
935
            switch ( slow_float_rounding_mode ) {
936
             case float_round_nearest_even:
937
             case float_round_up:
938
                z.low = 0;
939
                z.high = LIT64( 0x7FFF000000000000 );
940
                break;
941
             case float_round_to_zero:
942
             case float_round_down:
943
                z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
944
                z.high = LIT64( 0x7FFEFFFFFFFFFFFF );
945
                break;
946
            }
947
        }
948
        return z;
949
    }
950
    if ( expField <= 0 ) {
951
        isTiny = TRUE;
952
        zx = savedZ;
953
        expField = zx.exp + 0x3FFF;
954
        if ( expField < -120 ) {
955
            zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
956
            zx.sig.a0 = 0;
957
        }
958
        else {
959
            while ( expField <= 0 ) {
960
                zx.sig = shortShift128RightJamming( zx.sig, 1 );
961
                ++expField;
962
            }
963
        }
964
        zx = roundFloatXTo113( isTiny, zx );
965
        expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
966
    }
967
    zx.sig = shortShift128RightJamming( zx.sig, 7 );
968
    z.low = zx.sig.a1;
969
    z.high = expField;
970
    z.high <<= 48;
971
    if ( zx.sign ) z.high |= LIT64( 0x8000000000000000 );
972
    z.high |= zx.sig.a0 & LIT64( 0x0000FFFFFFFFFFFF );
973
    return z;
974
 
975
}
976
 
977
#endif
978
 
979
static floatX floatXInvalid( void )
980
{
981
 
982
    slow_float_exception_flags |= float_flag_invalid;
983
    return floatXNaN;
984
 
985
}
986
 
987
static floatX floatXRoundToInt( floatX ax )
988
{
989
  int32 shiftCount;
990
 
991
    if ( ax.isNaN || ax.isInf ) return ax;
992
    shiftCount = 112 - ax.exp;
993
    if ( shiftCount <= 0 ) return ax;
994
    if ( 119 < shiftCount ) {
995
        ax.exp = 112;
996
        ax.sig.a1 = ! ax.isZero;
997
        ax.sig.a0 = 0;
998
    }
999
    else {
1000
        while ( 0 < shiftCount ) {
1001
            ax.sig = shortShift128RightJamming( ax.sig, 1 );
1002
            ++ax.exp;
1003
            --shiftCount;
1004
        }
1005
    }
1006
    ax = roundFloatXTo113( FALSE, ax );
1007
    if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) ax.isZero = TRUE;
1008
    return ax;
1009
 
1010
}
1011
 
1012
static floatX floatXAdd( floatX ax, floatX bx )
1013
{
1014
    int32 expDiff;
1015
    floatX zx;
1016
 
1017
    if ( ax.isNaN ) return ax;
1018
    if ( bx.isNaN ) return bx;
1019
    if ( ax.isInf && bx.isInf ) {
1020
        if ( ax.sign == bx.sign ) return ax;
1021
        return floatXInvalid();
1022
    }
1023
    if ( ax.isInf ) return ax;
1024
    if ( bx.isInf ) return bx;
1025
    if ( ax.isZero && bx.isZero ) {
1026
        if ( ax.sign == bx.sign ) return ax;
1027
        goto completeCancellation;
1028
    }
1029
    if (    ( ax.sign != bx.sign )
1030
         && ( ax.exp == bx.exp )
1031
         && eq128( ax.sig, bx.sig )
1032
       ) {
1033
 completeCancellation:
1034
        return
1035
              ( slow_float_rounding_mode == float_round_down ) ?
1036
                  floatXNegativeZero
1037
            : floatXPositiveZero;
1038
    }
1039
    if ( ax.isZero ) return bx;
1040
    if ( bx.isZero ) return ax;
1041
    expDiff = ax.exp - bx.exp;
1042
    if ( expDiff < 0 ) {
1043
        zx = ax;
1044
        zx.exp = bx.exp;
1045
        if ( expDiff < -120 ) {
1046
            zx.sig.a1 = 1;
1047
            zx.sig.a0 = 0;
1048
        }
1049
        else {
1050
            while ( expDiff < 0 ) {
1051
                zx.sig = shortShift128RightJamming( zx.sig, 1 );
1052
                ++expDiff;
1053
            }
1054
        }
1055
        if ( ax.sign != bx.sign ) zx.sig = neg128( zx.sig );
1056
        zx.sign = bx.sign;
1057
        zx.sig = add128( zx.sig, bx.sig );
1058
    }
1059
    else {
1060
        zx = bx;
1061
        zx.exp = ax.exp;
1062
        if ( 120 < expDiff ) {
1063
            zx.sig.a1 = 1;
1064
            zx.sig.a0 = 0;
1065
        }
1066
        else {
1067
            while ( 0 < expDiff ) {
1068
                zx.sig = shortShift128RightJamming( zx.sig, 1 );
1069
                --expDiff;
1070
            }
1071
        }
1072
        if ( ax.sign != bx.sign ) zx.sig = neg128( zx.sig );
1073
        zx.sign = ax.sign;
1074
        zx.sig = add128( zx.sig, ax.sig );
1075
    }
1076
    if ( zx.sig.a0 & LIT64( 0x8000000000000000 ) ) {
1077
        zx.sig = neg128( zx.sig );
1078
        zx.sign = ! zx.sign;
1079
    }
1080
    return zx;
1081
 
1082
}
1083
 
1084
static floatX floatXMul( floatX ax, floatX bx )
1085
{
1086
    int8 bitNum;
1087
    floatX zx;
1088
 
1089
    if ( ax.isNaN ) return ax;
1090
    if ( bx.isNaN ) return bx;
1091
    if ( ax.isInf ) {
1092
        if ( bx.isZero ) return floatXInvalid();
1093
        if ( bx.sign ) ax.sign = ! ax.sign;
1094
        return ax;
1095
    }
1096
    if ( bx.isInf ) {
1097
        if ( ax.isZero ) return floatXInvalid();
1098
        if ( ax.sign ) bx.sign = ! bx.sign;
1099
        return bx;
1100
    }
1101
    zx = ax;
1102
    zx.sign ^= bx.sign;
1103
    if ( ax.isZero || bx.isZero ) {
1104
        return zx.sign ? floatXNegativeZero : floatXPositiveZero;
1105
    }
1106
    zx.exp += bx.exp + 1;
1107
    zx.sig.a1 = 0;
1108
    zx.sig.a0 = 0;
1109
    for ( bitNum = 0; bitNum < 119; ++bitNum ) {
1110
        if ( bx.sig.a1 & 2 ) zx.sig = add128( zx.sig, ax.sig );
1111
        bx.sig = shortShift128RightJamming( bx.sig, 1 );
1112
        zx.sig = shortShift128RightJamming( zx.sig, 1 );
1113
    }
1114
    return zx;
1115
 
1116
}
1117
 
1118
static floatX floatXDiv( floatX ax, floatX bx )
1119
{
1120
    bits128X negBSig;
1121
    int8 bitNum;
1122
    floatX zx;
1123
 
1124
    if ( ax.isNaN ) return ax;
1125
    if ( bx.isNaN ) return bx;
1126
    if ( ax.isInf ) {
1127
        if ( bx.isInf ) return floatXInvalid();
1128
        if ( bx.sign ) ax.sign = ! ax.sign;
1129
        return ax;
1130
    }
1131
    if ( bx.isZero ) {
1132
        if ( ax.isZero ) return floatXInvalid();
1133
        slow_float_exception_flags |= float_flag_divbyzero;
1134
        if ( ax.sign ) bx.sign = ! bx.sign;
1135
        bx.isZero = FALSE;
1136
        bx.isInf = TRUE;
1137
        return bx;
1138
    }
1139
    zx = ax;
1140
    zx.sign ^= bx.sign;
1141
    if ( ax.isZero || bx.isInf ) {
1142
        return zx.sign ? floatXNegativeZero : floatXPositiveZero;
1143
    }
1144
    zx.exp -= bx.exp + 1;
1145
    zx.sig.a1 = 0;
1146
    zx.sig.a0 = 0;
1147
    negBSig = neg128( bx.sig );
1148
    for ( bitNum = 0; bitNum < 120; ++bitNum ) {
1149
        if ( le128( bx.sig, ax.sig ) ) {
1150
            zx.sig.a1 |= 1;
1151
            ax.sig = add128( ax.sig, negBSig );
1152
        }
1153
        ax.sig = shortShift128Left( ax.sig, 1 );
1154
        zx.sig = shortShift128Left( zx.sig, 1 );
1155
    }
1156
    if ( ax.sig.a0 || ax.sig.a1 ) zx.sig.a1 |= 1;
1157
    return zx;
1158
 
1159
}
1160
 
1161
static floatX floatXRem( floatX ax, floatX bx )
1162
{
1163
    bits128X negBSig;
1164
    flag lastQuotientBit;
1165
    bits128X savedASig;
1166
 
1167
    if ( ax.isNaN ) return ax;
1168
    if ( bx.isNaN ) return bx;
1169
    if ( ax.isInf || bx.isZero ) return floatXInvalid();
1170
    if ( ax.isZero || bx.isInf ) return ax;
1171
    --bx.exp;
1172
    if ( ax.exp < bx.exp ) return ax;
1173
    bx.sig = shortShift128Left( bx.sig, 1 );
1174
    negBSig = neg128( bx.sig );
1175
    while ( bx.exp < ax.exp ) {
1176
        if ( le128( bx.sig, ax.sig ) ) ax.sig = add128( ax.sig, negBSig );
1177
        ax.sig = shortShift128Left( ax.sig, 1 );
1178
        --ax.exp;
1179
    }
1180
    lastQuotientBit = le128( bx.sig, ax.sig );
1181
    if ( lastQuotientBit ) ax.sig = add128( ax.sig, negBSig );
1182
    savedASig = ax.sig;
1183
    ax.sig = neg128( add128( ax.sig, negBSig ) );
1184
    if ( lt128( ax.sig, savedASig ) ) {
1185
        ax.sign = ! ax.sign;
1186
    }
1187
    else if ( lt128( savedASig, ax.sig ) ) {
1188
        ax.sig = savedASig;
1189
    }
1190
    else {
1191
        if ( lastQuotientBit ) {
1192
            ax.sign = ! ax.sign;
1193
        }
1194
        else {
1195
            ax.sig = savedASig;
1196
        }
1197
    }
1198
    if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) ax.isZero = TRUE;
1199
    return ax;
1200
 
1201
}
1202
 
1203
static floatX floatXSqrt( floatX ax )
1204
{
1205
    int8 bitNum;
1206
    bits128X bitSig, savedASig;
1207
    floatX zx;
1208
 
1209
    if ( ax.isNaN || ax.isZero ) return ax;
1210
    if ( ax.sign ) return floatXInvalid();
1211
    if ( ax.isInf ) return ax;
1212
    zx = ax;
1213
    zx.exp >>= 1;
1214
    if ( ( ax.exp & 1 ) == 0 ) ax.sig = shortShift128RightJamming( ax.sig, 1 );
1215
    zx.sig.a1 = 0;
1216
    zx.sig.a0 = 0;
1217
    bitSig.a1 = 0;
1218
    bitSig.a0 = LIT64( 0x0080000000000000 );
1219
    for ( bitNum = 0; bitNum < 120; ++bitNum ) {
1220
        savedASig = ax.sig;
1221
        ax.sig = add128( ax.sig, neg128( zx.sig ) );
1222
        ax.sig = shortShift128Left( ax.sig, 1 );
1223
        ax.sig = add128( ax.sig, neg128( bitSig ) );
1224
        if ( ax.sig.a0 & LIT64( 0x8000000000000000 ) ) {
1225
            ax.sig = shortShift128Left( savedASig, 1 );
1226
        }
1227
        else {
1228
            zx.sig.a1 |= bitSig.a1;
1229
            zx.sig.a0 |= bitSig.a0;
1230
        }
1231
        bitSig = shortShift128RightJamming( bitSig, 1 );
1232
    }
1233
    if ( ax.sig.a0 || ax.sig.a1 ) zx.sig.a1 |= 1;
1234
    return zx;
1235
 
1236
}
1237
 
1238
static flag floatXEq( floatX ax, floatX bx )
1239
{
1240
 
1241
    if ( ax.isNaN || bx.isNaN ) return FALSE;
1242
    if ( ax.isZero && bx.isZero ) return TRUE;
1243
    if ( ax.sign != bx.sign ) return FALSE;
1244
    if ( ax.isInf || bx.isInf ) return ax.isInf && bx.isInf;
1245
    return ( ax.exp == bx.exp ) && eq128( ax.sig, bx.sig );
1246
 
1247
}
1248
 
1249
static flag floatXLe( floatX ax, floatX bx )
1250
{
1251
 
1252
    if ( ax.isNaN || bx.isNaN ) return FALSE;
1253
    if ( ax.isZero && bx.isZero ) return TRUE;
1254
    if ( ax.sign != bx.sign ) return ax.sign;
1255
    if ( ax.sign ) {
1256
        if ( ax.isInf || bx.isZero ) return TRUE;
1257
        if ( bx.isInf || ax.isZero ) return FALSE;
1258
        if ( bx.exp < ax.exp ) return TRUE;
1259
        if ( ax.exp < bx.exp ) return FALSE;
1260
        return le128( bx.sig, ax.sig );
1261
    }
1262
    else {
1263
        if ( bx.isInf || ax.isZero ) return TRUE;
1264
        if ( ax.isInf || bx.isZero ) return FALSE;
1265
        if ( ax.exp < bx.exp ) return TRUE;
1266
        if ( bx.exp < ax.exp ) return FALSE;
1267
        return le128( ax.sig, bx.sig );
1268
    }
1269
 
1270
}
1271
 
1272
static flag floatXLt( floatX ax, floatX bx )
1273
{
1274
 
1275
    if ( ax.isNaN || bx.isNaN ) return FALSE;
1276
    if ( ax.isZero && bx.isZero ) return FALSE;
1277
    if ( ax.sign != bx.sign ) return ax.sign;
1278
    if ( ax.isInf && bx.isInf ) return FALSE;
1279
    if ( ax.sign ) {
1280
        if ( ax.isInf || bx.isZero ) return TRUE;
1281
        if ( bx.isInf || ax.isZero ) return FALSE;
1282
        if ( bx.exp < ax.exp ) return TRUE;
1283
        if ( ax.exp < bx.exp ) return FALSE;
1284
        return lt128( bx.sig, ax.sig );
1285
    }
1286
    else {
1287
        if ( bx.isInf || ax.isZero ) return TRUE;
1288
        if ( ax.isInf || bx.isZero ) return FALSE;
1289
        if ( ax.exp < bx.exp ) return TRUE;
1290
        if ( bx.exp < ax.exp ) return FALSE;
1291
        return lt128( ax.sig, bx.sig );
1292
    }
1293
 
1294
}
1295
 
1296
float32 slow_int32_to_float32( int32 a )
1297
{
1298
 
1299
    return floatXToFloat32( int32ToFloatX( a ) );
1300
 
1301
}
1302
 
1303
float64 slow_int32_to_float64( int32 a )
1304
{
1305
 
1306
    return floatXToFloat64( int32ToFloatX( a ) );
1307
 
1308
}
1309
 
1310
#ifdef FLOATX80
1311
 
1312
floatx80 slow_int32_to_floatx80( int32 a )
1313
{
1314
 
1315
    return floatXToFloatx80( int32ToFloatX( a ) );
1316
 
1317
}
1318
 
1319
#endif
1320
 
1321
#ifdef FLOAT128
1322
 
1323
float128 slow_int32_to_float128( int32 a )
1324
{
1325
 
1326
    return floatXToFloat128( int32ToFloatX( a ) );
1327
 
1328
}
1329
 
1330
#endif
1331
 
1332
float32 slow_int64_to_float32( int64 a )
1333
{
1334
 
1335
    return floatXToFloat32( int64ToFloatX( a ) );
1336
 
1337
}
1338
 
1339
float64 slow_int64_to_float64( int64 a )
1340
{
1341
 
1342
    return floatXToFloat64( int64ToFloatX( a ) );
1343
 
1344
}
1345
 
1346
#ifdef FLOATX80
1347
 
1348
floatx80 slow_int64_to_floatx80( int64 a )
1349
{
1350
 
1351
    return floatXToFloatx80( int64ToFloatX( a ) );
1352
 
1353
}
1354
 
1355
#endif
1356
 
1357
#ifdef FLOAT128
1358
 
1359
float128 slow_int64_to_float128( int64 a )
1360
{
1361
 
1362
    return floatXToFloat128( int64ToFloatX( a ) );
1363
 
1364
}
1365
 
1366
#endif
1367
 
1368
int32 slow_float32_to_int32( float32 a )
1369
{
1370
 
1371
    return floatXToInt32( float32ToFloatX( a ) );
1372
 
1373
}
1374
 
1375
int32 slow_float32_to_int32_round_to_zero( float32 a )
1376
{
1377
    int8 savedRoundingMode;
1378
    int32 z;
1379
 
1380
    savedRoundingMode = slow_float_rounding_mode;
1381
    slow_float_rounding_mode = float_round_to_zero;
1382
    z = floatXToInt32( float32ToFloatX( a ) );
1383
    slow_float_rounding_mode = savedRoundingMode;
1384
    return z;
1385
 
1386
}
1387
 
1388
int64 slow_float32_to_int64( float32 a )
1389
{
1390
 
1391
    return floatXToInt64( float32ToFloatX( a ) );
1392
 
1393
}
1394
 
1395
int64 slow_float32_to_int64_round_to_zero( float32 a )
1396
{
1397
    int8 savedRoundingMode;
1398
    int64 z;
1399
 
1400
    savedRoundingMode = slow_float_rounding_mode;
1401
    slow_float_rounding_mode = float_round_to_zero;
1402
    z = floatXToInt64( float32ToFloatX( a ) );
1403
    slow_float_rounding_mode = savedRoundingMode;
1404
    return z;
1405
 
1406
}
1407
 
1408
float64 slow_float32_to_float64( float32 a )
1409
{
1410
 
1411
    return floatXToFloat64( float32ToFloatX( a ) );
1412
 
1413
}
1414
 
1415
#ifdef FLOATX80
1416
 
1417
floatx80 slow_float32_to_floatx80( float32 a )
1418
{
1419
 
1420
    return floatXToFloatx80( float32ToFloatX( a ) );
1421
 
1422
}
1423
 
1424
#endif
1425
 
1426
#ifdef FLOAT128
1427
 
1428
float128 slow_float32_to_float128( float32 a )
1429
{
1430
 
1431
    return floatXToFloat128( float32ToFloatX( a ) );
1432
 
1433
}
1434
 
1435
#endif
1436
 
1437
float32 slow_float32_round_to_int( float32 a )
1438
{
1439
 
1440
    return floatXToFloat32( floatXRoundToInt( float32ToFloatX( a ) ) );
1441
 
1442
}
1443
 
1444
float32 slow_float32_add( float32 a, float32 b )
1445
{
1446
 
1447
    return
1448
        floatXToFloat32(
1449
            floatXAdd( float32ToFloatX( a ), float32ToFloatX( b ) ) );
1450
 
1451
}
1452
 
1453
float32 slow_float32_sub( float32 a, float32 b )
1454
{
1455
 
1456
    b ^= 0x80000000;
1457
    return
1458
        floatXToFloat32(
1459
            floatXAdd( float32ToFloatX( a ), float32ToFloatX( b ) ) );
1460
 
1461
}
1462
 
1463
float32 slow_float32_mul( float32 a, float32 b )
1464
{
1465
 
1466
    return
1467
        floatXToFloat32(
1468
            floatXMul( float32ToFloatX( a ), float32ToFloatX( b ) ) );
1469
 
1470
}
1471
 
1472
float32 slow_float32_div( float32 a, float32 b )
1473
{
1474
 
1475
    return
1476
        floatXToFloat32(
1477
            floatXDiv( float32ToFloatX( a ), float32ToFloatX( b ) ) );
1478
 
1479
}
1480
 
1481
float32 slow_float32_rem( float32 a, float32 b )
1482
{
1483
 
1484
    return
1485
        floatXToFloat32(
1486
            floatXRem( float32ToFloatX( a ), float32ToFloatX( b ) ) );
1487
 
1488
}
1489
 
1490
float32 slow_float32_sqrt( float32 a )
1491
{
1492
 
1493
    return floatXToFloat32( floatXSqrt( float32ToFloatX( a ) ) );
1494
 
1495
}
1496
 
1497
flag slow_float32_eq( float32 a, float32 b )
1498
{
1499
 
1500
    return floatXEq( float32ToFloatX( a ), float32ToFloatX( b ) );
1501
 
1502
}
1503
 
1504
flag slow_float32_le( float32 a, float32 b )
1505
{
1506
    floatX ax, bx;
1507
 
1508
    ax = float32ToFloatX( a );
1509
    bx = float32ToFloatX( b );
1510
    if ( ax.isNaN || bx.isNaN ) {
1511
        slow_float_exception_flags |= float_flag_invalid;
1512
    }
1513
    return floatXLe( ax, bx );
1514
 
1515
}
1516
 
1517
flag slow_float32_lt( float32 a, float32 b )
1518
{
1519
    floatX ax, bx;
1520
 
1521
    ax = float32ToFloatX( a );
1522
    bx = float32ToFloatX( b );
1523
    if ( ax.isNaN || bx.isNaN ) {
1524
        slow_float_exception_flags |= float_flag_invalid;
1525
    }
1526
    return floatXLt( ax, bx );
1527
 
1528
}
1529
 
1530
flag slow_float32_eq_signaling( float32 a, float32 b )
1531
{
1532
    floatX ax, bx;
1533
 
1534
    ax = float32ToFloatX( a );
1535
    bx = float32ToFloatX( b );
1536
    if ( ax.isNaN || bx.isNaN ) {
1537
        slow_float_exception_flags |= float_flag_invalid;
1538
    }
1539
    return floatXEq( ax, bx );
1540
 
1541
}
1542
 
1543
flag slow_float32_le_quiet( float32 a, float32 b )
1544
{
1545
 
1546
    return floatXLe( float32ToFloatX( a ), float32ToFloatX( b ) );
1547
 
1548
}
1549
 
1550
flag slow_float32_lt_quiet( float32 a, float32 b )
1551
{
1552
 
1553
    return floatXLt( float32ToFloatX( a ), float32ToFloatX( b ) );
1554
 
1555
}
1556
 
1557
int32 slow_float64_to_int32( float64 a )
1558
{
1559
 
1560
    return floatXToInt32( float64ToFloatX( a ) );
1561
 
1562
}
1563
 
1564
int32 slow_float64_to_int32_round_to_zero( float64 a )
1565
{
1566
    int8 savedRoundingMode;
1567
    int32 z;
1568
 
1569
    savedRoundingMode = slow_float_rounding_mode;
1570
    slow_float_rounding_mode = float_round_to_zero;
1571
    z = floatXToInt32( float64ToFloatX( a ) );
1572
    slow_float_rounding_mode = savedRoundingMode;
1573
    return z;
1574
 
1575
}
1576
 
1577
int64 slow_float64_to_int64( float64 a )
1578
{
1579
 
1580
    return floatXToInt64( float64ToFloatX( a ) );
1581
 
1582
}
1583
 
1584
int64 slow_float64_to_int64_round_to_zero( float64 a )
1585
{
1586
    int8 savedRoundingMode;
1587
    int64 z;
1588
 
1589
    savedRoundingMode = slow_float_rounding_mode;
1590
    slow_float_rounding_mode = float_round_to_zero;
1591
    z = floatXToInt64( float64ToFloatX( a ) );
1592
    slow_float_rounding_mode = savedRoundingMode;
1593
    return z;
1594
 
1595
}
1596
 
1597
float32 slow_float64_to_float32( float64 a )
1598
{
1599
 
1600
    return floatXToFloat32( float64ToFloatX( a ) );
1601
 
1602
}
1603
 
1604
#ifdef FLOATX80
1605
 
1606
floatx80 slow_float64_to_floatx80( float64 a )
1607
{
1608
 
1609
    return floatXToFloatx80( float64ToFloatX( a ) );
1610
 
1611
}
1612
 
1613
#endif
1614
 
1615
#ifdef FLOAT128
1616
 
1617
float128 slow_float64_to_float128( float64 a )
1618
{
1619
 
1620
    return floatXToFloat128( float64ToFloatX( a ) );
1621
 
1622
}
1623
 
1624
#endif
1625
 
1626
float64 slow_float64_round_to_int( float64 a )
1627
{
1628
 
1629
    return floatXToFloat64( floatXRoundToInt( float64ToFloatX( a ) ) );
1630
 
1631
}
1632
 
1633
float64 slow_float64_add( float64 a, float64 b )
1634
{
1635
 
1636
    return
1637
        floatXToFloat64(
1638
            floatXAdd( float64ToFloatX( a ), float64ToFloatX( b ) ) );
1639
 
1640
}
1641
 
1642
float64 slow_float64_sub( float64 a, float64 b )
1643
{
1644
 
1645
    b ^= LIT64( 0x8000000000000000 );
1646
    return
1647
        floatXToFloat64(
1648
            floatXAdd( float64ToFloatX( a ), float64ToFloatX( b ) ) );
1649
 
1650
}
1651
 
1652
float64 slow_float64_mul( float64 a, float64 b )
1653
{
1654
 
1655
    return
1656
        floatXToFloat64(
1657
            floatXMul( float64ToFloatX( a ), float64ToFloatX( b ) ) );
1658
 
1659
}
1660
 
1661
float64 slow_float64_div( float64 a, float64 b )
1662
{
1663
 
1664
    return
1665
        floatXToFloat64(
1666
            floatXDiv( float64ToFloatX( a ), float64ToFloatX( b ) ) );
1667
 
1668
}
1669
 
1670
float64 slow_float64_rem( float64 a, float64 b )
1671
{
1672
 
1673
    return
1674
        floatXToFloat64(
1675
            floatXRem( float64ToFloatX( a ), float64ToFloatX( b ) ) );
1676
 
1677
}
1678
 
1679
float64 slow_float64_sqrt( float64 a )
1680
{
1681
 
1682
    return floatXToFloat64( floatXSqrt( float64ToFloatX( a ) ) );
1683
 
1684
}
1685
 
1686
flag slow_float64_eq( float64 a, float64 b )
1687
{
1688
 
1689
    return floatXEq( float64ToFloatX( a ), float64ToFloatX( b ) );
1690
 
1691
}
1692
 
1693
flag slow_float64_le( float64 a, float64 b )
1694
{
1695
    floatX ax, bx;
1696
 
1697
    ax = float64ToFloatX( a );
1698
    bx = float64ToFloatX( b );
1699
    if ( ax.isNaN || bx.isNaN ) {
1700
        slow_float_exception_flags |= float_flag_invalid;
1701
    }
1702
    return floatXLe( ax, bx );
1703
 
1704
}
1705
 
1706
flag slow_float64_lt( float64 a, float64 b )
1707
{
1708
    floatX ax, bx;
1709
 
1710
    ax = float64ToFloatX( a );
1711
    bx = float64ToFloatX( b );
1712
    if ( ax.isNaN || bx.isNaN ) {
1713
        slow_float_exception_flags |= float_flag_invalid;
1714
    }
1715
    return floatXLt( ax, bx );
1716
 
1717
}
1718
 
1719
flag slow_float64_eq_signaling( float64 a, float64 b )
1720
{
1721
    floatX ax, bx;
1722
 
1723
    ax = float64ToFloatX( a );
1724
    bx = float64ToFloatX( b );
1725
    if ( ax.isNaN || bx.isNaN ) {
1726
        slow_float_exception_flags |= float_flag_invalid;
1727
    }
1728
    return floatXEq( ax, bx );
1729
 
1730
}
1731
 
1732
flag slow_float64_le_quiet( float64 a, float64 b )
1733
{
1734
 
1735
    return floatXLe( float64ToFloatX( a ), float64ToFloatX( b ) );
1736
 
1737
}
1738
 
1739
flag slow_float64_lt_quiet( float64 a, float64 b )
1740
{
1741
 
1742
    return floatXLt( float64ToFloatX( a ), float64ToFloatX( b ) );
1743
 
1744
}
1745
 
1746
#ifdef FLOATX80
1747
 
1748
int32 slow_floatx80_to_int32( floatx80 a )
1749
{
1750
 
1751
    return floatXToInt32( floatx80ToFloatX( a ) );
1752
 
1753
}
1754
 
1755
int32 slow_floatx80_to_int32_round_to_zero( floatx80 a )
1756
{
1757
    int8 savedRoundingMode;
1758
    int32 z;
1759
 
1760
    savedRoundingMode = slow_float_rounding_mode;
1761
    slow_float_rounding_mode = float_round_to_zero;
1762
    z = floatXToInt32( floatx80ToFloatX( a ) );
1763
    slow_float_rounding_mode = savedRoundingMode;
1764
    return z;
1765
 
1766
}
1767
 
1768
int64 slow_floatx80_to_int64( floatx80 a )
1769
{
1770
 
1771
    return floatXToInt64( floatx80ToFloatX( a ) );
1772
 
1773
}
1774
 
1775
int64 slow_floatx80_to_int64_round_to_zero( floatx80 a )
1776
{
1777
    int8 savedRoundingMode;
1778
    int64 z;
1779
 
1780
    savedRoundingMode = slow_float_rounding_mode;
1781
    slow_float_rounding_mode = float_round_to_zero;
1782
    z = floatXToInt64( floatx80ToFloatX( a ) );
1783
    slow_float_rounding_mode = savedRoundingMode;
1784
    return z;
1785
 
1786
}
1787
 
1788
float32 slow_floatx80_to_float32( floatx80 a )
1789
{
1790
 
1791
    return floatXToFloat32( floatx80ToFloatX( a ) );
1792
 
1793
}
1794
 
1795
float64 slow_floatx80_to_float64( floatx80 a )
1796
{
1797
 
1798
    return floatXToFloat64( floatx80ToFloatX( a ) );
1799
 
1800
}
1801
 
1802
#ifdef FLOAT128
1803
 
1804
float128 slow_floatx80_to_float128( floatx80 a )
1805
{
1806
 
1807
    return floatXToFloat128( floatx80ToFloatX( a ) );
1808
 
1809
}
1810
 
1811
#endif
1812
 
1813
floatx80 slow_floatx80_round_to_int( floatx80 a )
1814
{
1815
 
1816
    return floatXToFloatx80( floatXRoundToInt( floatx80ToFloatX( a ) ) );
1817
 
1818
}
1819
 
1820
floatx80 slow_floatx80_add( floatx80 a, floatx80 b )
1821
{
1822
 
1823
    return
1824
        floatXToFloatx80(
1825
            floatXAdd( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
1826
 
1827
}
1828
 
1829
floatx80 slow_floatx80_sub( floatx80 a, floatx80 b )
1830
{
1831
 
1832
    b.high ^= 0x8000;
1833
    return
1834
        floatXToFloatx80(
1835
            floatXAdd( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
1836
 
1837
}
1838
 
1839
floatx80 slow_floatx80_mul( floatx80 a, floatx80 b )
1840
{
1841
 
1842
    return
1843
        floatXToFloatx80(
1844
            floatXMul( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
1845
 
1846
}
1847
 
1848
floatx80 slow_floatx80_div( floatx80 a, floatx80 b )
1849
{
1850
 
1851
    return
1852
        floatXToFloatx80(
1853
            floatXDiv( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
1854
 
1855
}
1856
 
1857
floatx80 slow_floatx80_rem( floatx80 a, floatx80 b )
1858
{
1859
 
1860
    return
1861
        floatXToFloatx80(
1862
            floatXRem( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
1863
 
1864
}
1865
 
1866
floatx80 slow_floatx80_sqrt( floatx80 a )
1867
{
1868
 
1869
    return floatXToFloatx80( floatXSqrt( floatx80ToFloatX( a ) ) );
1870
 
1871
}
1872
 
1873
flag slow_floatx80_eq( floatx80 a, floatx80 b )
1874
{
1875
 
1876
    return floatXEq( floatx80ToFloatX( a ), floatx80ToFloatX( b ) );
1877
 
1878
}
1879
 
1880
flag slow_floatx80_le( floatx80 a, floatx80 b )
1881
{
1882
    floatX ax, bx;
1883
 
1884
    ax = floatx80ToFloatX( a );
1885
    bx = floatx80ToFloatX( b );
1886
    if ( ax.isNaN || bx.isNaN ) {
1887
        slow_float_exception_flags |= float_flag_invalid;
1888
    }
1889
    return floatXLe( ax, bx );
1890
 
1891
}
1892
 
1893
flag slow_floatx80_lt( floatx80 a, floatx80 b )
1894
{
1895
    floatX ax, bx;
1896
 
1897
    ax = floatx80ToFloatX( a );
1898
    bx = floatx80ToFloatX( b );
1899
    if ( ax.isNaN || bx.isNaN ) {
1900
        slow_float_exception_flags |= float_flag_invalid;
1901
    }
1902
    return floatXLt( ax, bx );
1903
 
1904
}
1905
 
1906
flag slow_floatx80_eq_signaling( floatx80 a, floatx80 b )
1907
{
1908
    floatX ax, bx;
1909
 
1910
    ax = floatx80ToFloatX( a );
1911
    bx = floatx80ToFloatX( b );
1912
    if ( ax.isNaN || bx.isNaN ) {
1913
        slow_float_exception_flags |= float_flag_invalid;
1914
    }
1915
    return floatXEq( ax, bx );
1916
 
1917
}
1918
 
1919
flag slow_floatx80_le_quiet( floatx80 a, floatx80 b )
1920
{
1921
 
1922
    return floatXLe( floatx80ToFloatX( a ), floatx80ToFloatX( b ) );
1923
 
1924
}
1925
 
1926
flag slow_floatx80_lt_quiet( floatx80 a, floatx80 b )
1927
{
1928
 
1929
    return floatXLt( floatx80ToFloatX( a ), floatx80ToFloatX( b ) );
1930
 
1931
}
1932
 
1933
#endif
1934
 
1935
#ifdef FLOAT128
1936
 
1937
int32 slow_float128_to_int32( float128 a )
1938
{
1939
 
1940
    return floatXToInt32( float128ToFloatX( a ) );
1941
 
1942
}
1943
 
1944
int32 slow_float128_to_int32_round_to_zero( float128 a )
1945
{
1946
    int8 savedRoundingMode;
1947
    int32 z;
1948
 
1949
    savedRoundingMode = slow_float_rounding_mode;
1950
    slow_float_rounding_mode = float_round_to_zero;
1951
    z = floatXToInt32( float128ToFloatX( a ) );
1952
    slow_float_rounding_mode = savedRoundingMode;
1953
    return z;
1954
 
1955
}
1956
 
1957
int64 slow_float128_to_int64( float128 a )
1958
{
1959
 
1960
    return floatXToInt64( float128ToFloatX( a ) );
1961
 
1962
}
1963
 
1964
int64 slow_float128_to_int64_round_to_zero( float128 a )
1965
{
1966
    int8 savedRoundingMode;
1967
    int64 z;
1968
 
1969
    savedRoundingMode = slow_float_rounding_mode;
1970
    slow_float_rounding_mode = float_round_to_zero;
1971
    z = floatXToInt64( float128ToFloatX( a ) );
1972
    slow_float_rounding_mode = savedRoundingMode;
1973
    return z;
1974
 
1975
}
1976
 
1977
float32 slow_float128_to_float32( float128 a )
1978
{
1979
 
1980
    return floatXToFloat32( float128ToFloatX( a ) );
1981
 
1982
}
1983
 
1984
float64 slow_float128_to_float64( float128 a )
1985
{
1986
 
1987
    return floatXToFloat64( float128ToFloatX( a ) );
1988
 
1989
}
1990
 
1991
#ifdef FLOATX80
1992
 
1993
floatx80 slow_float128_to_floatx80( float128 a )
1994
{
1995
 
1996
    return floatXToFloatx80( float128ToFloatX( a ) );
1997
 
1998
}
1999
 
2000
#endif
2001
 
2002
float128 slow_float128_round_to_int( float128 a )
2003
{
2004
 
2005
    return floatXToFloat128( floatXRoundToInt( float128ToFloatX( a ) ) );
2006
 
2007
}
2008
 
2009
float128 slow_float128_add( float128 a, float128 b )
2010
{
2011
 
2012
    return
2013
        floatXToFloat128(
2014
            floatXAdd( float128ToFloatX( a ), float128ToFloatX( b ) ) );
2015
 
2016
}
2017
 
2018
float128 slow_float128_sub( float128 a, float128 b )
2019
{
2020
 
2021
    b.high ^= LIT64( 0x8000000000000000 );
2022
    return
2023
        floatXToFloat128(
2024
            floatXAdd( float128ToFloatX( a ), float128ToFloatX( b ) ) );
2025
 
2026
}
2027
 
2028
float128 slow_float128_mul( float128 a, float128 b )
2029
{
2030
 
2031
    return
2032
        floatXToFloat128(
2033
            floatXMul( float128ToFloatX( a ), float128ToFloatX( b ) ) );
2034
 
2035
}
2036
 
2037
float128 slow_float128_div( float128 a, float128 b )
2038
{
2039
 
2040
    return
2041
        floatXToFloat128(
2042
            floatXDiv( float128ToFloatX( a ), float128ToFloatX( b ) ) );
2043
 
2044
}
2045
 
2046
float128 slow_float128_rem( float128 a, float128 b )
2047
{
2048
 
2049
    return
2050
        floatXToFloat128(
2051
            floatXRem( float128ToFloatX( a ), float128ToFloatX( b ) ) );
2052
 
2053
}
2054
 
2055
float128 slow_float128_sqrt( float128 a )
2056
{
2057
 
2058
    return floatXToFloat128( floatXSqrt( float128ToFloatX( a ) ) );
2059
 
2060
}
2061
 
2062
flag slow_float128_eq( float128 a, float128 b )
2063
{
2064
 
2065
    return floatXEq( float128ToFloatX( a ), float128ToFloatX( b ) );
2066
 
2067
}
2068
 
2069
flag slow_float128_le( float128 a, float128 b )
2070
{
2071
    floatX ax, bx;
2072
 
2073
    ax = float128ToFloatX( a );
2074
    bx = float128ToFloatX( b );
2075
    if ( ax.isNaN || bx.isNaN ) {
2076
        slow_float_exception_flags |= float_flag_invalid;
2077
    }
2078
    return floatXLe( ax, bx );
2079
 
2080
}
2081
 
2082
flag slow_float128_lt( float128 a, float128 b )
2083
{
2084
    floatX ax, bx;
2085
 
2086
    ax = float128ToFloatX( a );
2087
    bx = float128ToFloatX( b );
2088
    if ( ax.isNaN || bx.isNaN ) {
2089
        slow_float_exception_flags |= float_flag_invalid;
2090
    }
2091
    return floatXLt( ax, bx );
2092
 
2093
}
2094
 
2095
flag slow_float128_eq_signaling( float128 a, float128 b )
2096
{
2097
    floatX ax, bx;
2098
 
2099
    ax = float128ToFloatX( a );
2100
    bx = float128ToFloatX( b );
2101
    if ( ax.isNaN || bx.isNaN ) {
2102
        slow_float_exception_flags |= float_flag_invalid;
2103
    }
2104
    return floatXEq( ax, bx );
2105
 
2106
}
2107
 
2108
flag slow_float128_le_quiet( float128 a, float128 b )
2109
{
2110
 
2111
    return floatXLe( float128ToFloatX( a ), float128ToFloatX( b ) );
2112
 
2113
}
2114
 
2115
flag slow_float128_lt_quiet( float128 a, float128 b )
2116
{
2117
 
2118
    return floatXLt( float128ToFloatX( a ), float128ToFloatX( b ) );
2119
 
2120
}
2121
 
2122
#endif
2123
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.