~ubuntu-branches/ubuntu/vivid/qemu/vivid

« back to all changes in this revision

Viewing changes to .pc/ubuntu/arm64/0093-softfloat-Add-float32_to_uint64.patch/fpu/softfloat.c

  • Committer: Package Import Robot
  • Author(s): dann frazier
  • Date: 2014-02-11 15:41:53 UTC
  • Revision ID: package-import@ubuntu.com-20140211154153-2d001tf0ium08u81
Tags: 1.7.0+dfsg-3ubuntu2
* Backport changes to enable qemu-user-static support for aarch64
* debian/control: add ppc64el to Architectures
* debian/rules: only install qemu-system-aarch64 on arm64.
  Fixes a FTBFS  when built twice in a row on non-arm64 due to a stale
  debian/qemu-system-aarch64 directory

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * QEMU float support
 
3
 *
 
4
 * Derived from SoftFloat.
 
5
 */
 
6
 
 
7
/*============================================================================
 
8
 
 
9
This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
 
10
Package, Release 2b.
 
11
 
 
12
Written by John R. Hauser.  This work was made possible in part by the
 
13
International Computer Science Institute, located at Suite 600, 1947 Center
 
14
Street, Berkeley, California 94704.  Funding was partially provided by the
 
15
National Science Foundation under grant MIP-9311980.  The original version
 
16
of this code was written as part of a project to build a fixed-point vector
 
17
processor in collaboration with the University of California at Berkeley,
 
18
overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
 
19
is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
 
20
arithmetic/SoftFloat.html'.
 
21
 
 
22
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort has
 
23
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
 
24
RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
 
25
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
 
26
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
 
27
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
 
28
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
 
29
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
 
30
 
 
31
Derivative works are acceptable, even for commercial purposes, so long as
 
32
(1) the source code for the derivative work includes prominent notice that
 
33
the work is derivative, and (2) the source code includes prominent notice with
 
34
these four paragraphs for those parts of this code that are retained.
 
35
 
 
36
=============================================================================*/
 
37
 
 
38
/* softfloat (and in particular the code in softfloat-specialize.h) is
 
39
 * target-dependent and needs the TARGET_* macros.
 
40
 */
 
41
#include "config.h"
 
42
 
 
43
#include "fpu/softfloat.h"
 
44
 
 
45
/*----------------------------------------------------------------------------
 
46
| Primitive arithmetic functions, including multi-word arithmetic, and
 
47
| division and square root approximations.  (Can be specialized to target if
 
48
| desired.)
 
49
*----------------------------------------------------------------------------*/
 
50
#include "softfloat-macros.h"
 
51
 
 
52
/*----------------------------------------------------------------------------
 
53
| Functions and definitions to determine:  (1) whether tininess for underflow
 
54
| is detected before or after rounding by default, (2) what (if anything)
 
55
| happens when exceptions are raised, (3) how signaling NaNs are distinguished
 
56
| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs
 
57
| are propagated from function inputs to output.  These details are target-
 
58
| specific.
 
59
*----------------------------------------------------------------------------*/
 
60
#include "softfloat-specialize.h"
 
61
 
 
62
void set_float_rounding_mode(int val STATUS_PARAM)
 
63
{
 
64
    STATUS(float_rounding_mode) = val;
 
65
}
 
66
 
 
67
void set_float_exception_flags(int val STATUS_PARAM)
 
68
{
 
69
    STATUS(float_exception_flags) = val;
 
70
}
 
71
 
 
72
void set_floatx80_rounding_precision(int val STATUS_PARAM)
 
73
{
 
74
    STATUS(floatx80_rounding_precision) = val;
 
75
}
 
76
 
 
77
/*----------------------------------------------------------------------------
 
78
| Returns the fraction bits of the half-precision floating-point value `a'.
 
79
*----------------------------------------------------------------------------*/
 
80
 
 
81
INLINE uint32_t extractFloat16Frac(float16 a)
 
82
{
 
83
    return float16_val(a) & 0x3ff;
 
84
}
 
85
 
 
86
/*----------------------------------------------------------------------------
 
87
| Returns the exponent bits of the half-precision floating-point value `a'.
 
88
*----------------------------------------------------------------------------*/
 
89
 
 
90
INLINE int_fast16_t extractFloat16Exp(float16 a)
 
91
{
 
92
    return (float16_val(a) >> 10) & 0x1f;
 
93
}
 
94
 
 
95
/*----------------------------------------------------------------------------
 
96
| Returns the sign bit of the single-precision floating-point value `a'.
 
97
*----------------------------------------------------------------------------*/
 
98
 
 
99
INLINE flag extractFloat16Sign(float16 a)
 
100
{
 
101
    return float16_val(a)>>15;
 
102
}
 
103
 
 
104
/*----------------------------------------------------------------------------
 
105
| Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
 
106
| and 7, and returns the properly rounded 32-bit integer corresponding to the
 
107
| input.  If `zSign' is 1, the input is negated before being converted to an
 
108
| integer.  Bit 63 of `absZ' must be zero.  Ordinarily, the fixed-point input
 
109
| is simply rounded to an integer, with the inexact exception raised if the
 
110
| input cannot be represented exactly as an integer.  However, if the fixed-
 
111
| point input is too large, the invalid exception is raised and the largest
 
112
| positive or negative integer is returned.
 
113
*----------------------------------------------------------------------------*/
 
114
 
 
115
static int32 roundAndPackInt32( flag zSign, uint64_t absZ STATUS_PARAM)
 
116
{
 
117
    int8 roundingMode;
 
118
    flag roundNearestEven;
 
119
    int8 roundIncrement, roundBits;
 
120
    int32_t z;
 
121
 
 
122
    roundingMode = STATUS(float_rounding_mode);
 
123
    roundNearestEven = ( roundingMode == float_round_nearest_even );
 
124
    roundIncrement = 0x40;
 
125
    if ( ! roundNearestEven ) {
 
126
        if ( roundingMode == float_round_to_zero ) {
 
127
            roundIncrement = 0;
 
128
        }
 
129
        else {
 
130
            roundIncrement = 0x7F;
 
131
            if ( zSign ) {
 
132
                if ( roundingMode == float_round_up ) roundIncrement = 0;
 
133
            }
 
134
            else {
 
135
                if ( roundingMode == float_round_down ) roundIncrement = 0;
 
136
            }
 
137
        }
 
138
    }
 
139
    roundBits = absZ & 0x7F;
 
140
    absZ = ( absZ + roundIncrement )>>7;
 
141
    absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
 
142
    z = absZ;
 
143
    if ( zSign ) z = - z;
 
144
    if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) {
 
145
        float_raise( float_flag_invalid STATUS_VAR);
 
146
        return zSign ? (int32_t) 0x80000000 : 0x7FFFFFFF;
 
147
    }
 
148
    if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
 
149
    return z;
 
150
 
 
151
}
 
152
 
 
153
/*----------------------------------------------------------------------------
 
154
| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and
 
155
| `absZ1', with binary point between bits 63 and 64 (between the input words),
 
156
| and returns the properly rounded 64-bit integer corresponding to the input.
 
157
| If `zSign' is 1, the input is negated before being converted to an integer.
 
158
| Ordinarily, the fixed-point input is simply rounded to an integer, with
 
159
| the inexact exception raised if the input cannot be represented exactly as
 
160
| an integer.  However, if the fixed-point input is too large, the invalid
 
161
| exception is raised and the largest positive or negative integer is
 
162
| returned.
 
163
*----------------------------------------------------------------------------*/
 
164
 
 
165
static int64 roundAndPackInt64( flag zSign, uint64_t absZ0, uint64_t absZ1 STATUS_PARAM)
 
166
{
 
167
    int8 roundingMode;
 
168
    flag roundNearestEven, increment;
 
169
    int64_t z;
 
170
 
 
171
    roundingMode = STATUS(float_rounding_mode);
 
172
    roundNearestEven = ( roundingMode == float_round_nearest_even );
 
173
    increment = ( (int64_t) absZ1 < 0 );
 
174
    if ( ! roundNearestEven ) {
 
175
        if ( roundingMode == float_round_to_zero ) {
 
176
            increment = 0;
 
177
        }
 
178
        else {
 
179
            if ( zSign ) {
 
180
                increment = ( roundingMode == float_round_down ) && absZ1;
 
181
            }
 
182
            else {
 
183
                increment = ( roundingMode == float_round_up ) && absZ1;
 
184
            }
 
185
        }
 
186
    }
 
187
    if ( increment ) {
 
188
        ++absZ0;
 
189
        if ( absZ0 == 0 ) goto overflow;
 
190
        absZ0 &= ~ ( ( (uint64_t) ( absZ1<<1 ) == 0 ) & roundNearestEven );
 
191
    }
 
192
    z = absZ0;
 
193
    if ( zSign ) z = - z;
 
194
    if ( z && ( ( z < 0 ) ^ zSign ) ) {
 
195
 overflow:
 
196
        float_raise( float_flag_invalid STATUS_VAR);
 
197
        return
 
198
              zSign ? (int64_t) LIT64( 0x8000000000000000 )
 
199
            : LIT64( 0x7FFFFFFFFFFFFFFF );
 
200
    }
 
201
    if ( absZ1 ) STATUS(float_exception_flags) |= float_flag_inexact;
 
202
    return z;
 
203
 
 
204
}
 
205
 
 
206
/*----------------------------------------------------------------------------
 
207
| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and
 
208
| `absZ1', with binary point between bits 63 and 64 (between the input words),
 
209
| and returns the properly rounded 64-bit unsigned integer corresponding to the
 
210
| input.  Ordinarily, the fixed-point input is simply rounded to an integer,
 
211
| with the inexact exception raised if the input cannot be represented exactly
 
212
| as an integer.  However, if the fixed-point input is too large, the invalid
 
213
| exception is raised and the largest unsigned integer is returned.
 
214
*----------------------------------------------------------------------------*/
 
215
 
 
216
static int64 roundAndPackUint64(flag zSign, uint64_t absZ0,
 
217
                                uint64_t absZ1 STATUS_PARAM)
 
218
{
 
219
    int8 roundingMode;
 
220
    flag roundNearestEven, increment;
 
221
 
 
222
    roundingMode = STATUS(float_rounding_mode);
 
223
    roundNearestEven = (roundingMode == float_round_nearest_even);
 
224
    increment = ((int64_t)absZ1 < 0);
 
225
    if (!roundNearestEven) {
 
226
        if (roundingMode == float_round_to_zero) {
 
227
            increment = 0;
 
228
        } else if (absZ1) {
 
229
            if (zSign) {
 
230
                increment = (roundingMode == float_round_down) && absZ1;
 
231
            } else {
 
232
                increment = (roundingMode == float_round_up) && absZ1;
 
233
            }
 
234
        }
 
235
    }
 
236
    if (increment) {
 
237
        ++absZ0;
 
238
        if (absZ0 == 0) {
 
239
            float_raise(float_flag_invalid STATUS_VAR);
 
240
            return LIT64(0xFFFFFFFFFFFFFFFF);
 
241
        }
 
242
        absZ0 &= ~(((uint64_t)(absZ1<<1) == 0) & roundNearestEven);
 
243
    }
 
244
 
 
245
    if (zSign && absZ0) {
 
246
        float_raise(float_flag_invalid STATUS_VAR);
 
247
        return 0;
 
248
    }
 
249
 
 
250
    if (absZ1) {
 
251
        STATUS(float_exception_flags) |= float_flag_inexact;
 
252
    }
 
253
    return absZ0;
 
254
}
 
255
 
 
256
/*----------------------------------------------------------------------------
 
257
| Returns the fraction bits of the single-precision floating-point value `a'.
 
258
*----------------------------------------------------------------------------*/
 
259
 
 
260
INLINE uint32_t extractFloat32Frac( float32 a )
 
261
{
 
262
 
 
263
    return float32_val(a) & 0x007FFFFF;
 
264
 
 
265
}
 
266
 
 
267
/*----------------------------------------------------------------------------
 
268
| Returns the exponent bits of the single-precision floating-point value `a'.
 
269
*----------------------------------------------------------------------------*/
 
270
 
 
271
INLINE int_fast16_t extractFloat32Exp(float32 a)
 
272
{
 
273
 
 
274
    return ( float32_val(a)>>23 ) & 0xFF;
 
275
 
 
276
}
 
277
 
 
278
/*----------------------------------------------------------------------------
 
279
| Returns the sign bit of the single-precision floating-point value `a'.
 
280
*----------------------------------------------------------------------------*/
 
281
 
 
282
INLINE flag extractFloat32Sign( float32 a )
 
283
{
 
284
 
 
285
    return float32_val(a)>>31;
 
286
 
 
287
}
 
288
 
 
289
/*----------------------------------------------------------------------------
 
290
| If `a' is denormal and we are in flush-to-zero mode then set the
 
291
| input-denormal exception and return zero. Otherwise just return the value.
 
292
*----------------------------------------------------------------------------*/
 
293
static float32 float32_squash_input_denormal(float32 a STATUS_PARAM)
 
294
{
 
295
    if (STATUS(flush_inputs_to_zero)) {
 
296
        if (extractFloat32Exp(a) == 0 && extractFloat32Frac(a) != 0) {
 
297
            float_raise(float_flag_input_denormal STATUS_VAR);
 
298
            return make_float32(float32_val(a) & 0x80000000);
 
299
        }
 
300
    }
 
301
    return a;
 
302
}
 
303
 
 
304
/*----------------------------------------------------------------------------
 
305
| Normalizes the subnormal single-precision floating-point value represented
 
306
| by the denormalized significand `aSig'.  The normalized exponent and
 
307
| significand are stored at the locations pointed to by `zExpPtr' and
 
308
| `zSigPtr', respectively.
 
309
*----------------------------------------------------------------------------*/
 
310
 
 
311
static void
 
312
 normalizeFloat32Subnormal(uint32_t aSig, int_fast16_t *zExpPtr, uint32_t *zSigPtr)
 
313
{
 
314
    int8 shiftCount;
 
315
 
 
316
    shiftCount = countLeadingZeros32( aSig ) - 8;
 
317
    *zSigPtr = aSig<<shiftCount;
 
318
    *zExpPtr = 1 - shiftCount;
 
319
 
 
320
}
 
321
 
 
322
/*----------------------------------------------------------------------------
 
323
| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
 
324
| single-precision floating-point value, returning the result.  After being
 
325
| shifted into the proper positions, the three fields are simply added
 
326
| together to form the result.  This means that any integer portion of `zSig'
 
327
| will be added into the exponent.  Since a properly normalized significand
 
328
| will have an integer portion equal to 1, the `zExp' input should be 1 less
 
329
| than the desired result exponent whenever `zSig' is a complete, normalized
 
330
| significand.
 
331
*----------------------------------------------------------------------------*/
 
332
 
 
333
INLINE float32 packFloat32(flag zSign, int_fast16_t zExp, uint32_t zSig)
 
334
{
 
335
 
 
336
    return make_float32(
 
337
          ( ( (uint32_t) zSign )<<31 ) + ( ( (uint32_t) zExp )<<23 ) + zSig);
 
338
 
 
339
}
 
340
 
 
341
/*----------------------------------------------------------------------------
 
342
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
 
343
| and significand `zSig', and returns the proper single-precision floating-
 
344
| point value corresponding to the abstract input.  Ordinarily, the abstract
 
345
| value is simply rounded and packed into the single-precision format, with
 
346
| the inexact exception raised if the abstract input cannot be represented
 
347
| exactly.  However, if the abstract value is too large, the overflow and
 
348
| inexact exceptions are raised and an infinity or maximal finite value is
 
349
| returned.  If the abstract value is too small, the input value is rounded to
 
350
| a subnormal number, and the underflow and inexact exceptions are raised if
 
351
| the abstract input cannot be represented exactly as a subnormal single-
 
352
| precision floating-point number.
 
353
|     The input significand `zSig' has its binary point between bits 30
 
354
| and 29, which is 7 bits to the left of the usual location.  This shifted
 
355
| significand must be normalized or smaller.  If `zSig' is not normalized,
 
356
| `zExp' must be 0; in that case, the result returned is a subnormal number,
 
357
| and it must not require rounding.  In the usual case that `zSig' is
 
358
| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
 
359
| The handling of underflow and overflow follows the IEC/IEEE Standard for
 
360
| Binary Floating-Point Arithmetic.
 
361
*----------------------------------------------------------------------------*/
 
362
 
 
363
static float32 roundAndPackFloat32(flag zSign, int_fast16_t zExp, uint32_t zSig STATUS_PARAM)
 
364
{
 
365
    int8 roundingMode;
 
366
    flag roundNearestEven;
 
367
    int8 roundIncrement, roundBits;
 
368
    flag isTiny;
 
369
 
 
370
    roundingMode = STATUS(float_rounding_mode);
 
371
    roundNearestEven = ( roundingMode == float_round_nearest_even );
 
372
    roundIncrement = 0x40;
 
373
    if ( ! roundNearestEven ) {
 
374
        if ( roundingMode == float_round_to_zero ) {
 
375
            roundIncrement = 0;
 
376
        }
 
377
        else {
 
378
            roundIncrement = 0x7F;
 
379
            if ( zSign ) {
 
380
                if ( roundingMode == float_round_up ) roundIncrement = 0;
 
381
            }
 
382
            else {
 
383
                if ( roundingMode == float_round_down ) roundIncrement = 0;
 
384
            }
 
385
        }
 
386
    }
 
387
    roundBits = zSig & 0x7F;
 
388
    if ( 0xFD <= (uint16_t) zExp ) {
 
389
        if (    ( 0xFD < zExp )
 
390
             || (    ( zExp == 0xFD )
 
391
                  && ( (int32_t) ( zSig + roundIncrement ) < 0 ) )
 
392
           ) {
 
393
            float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
 
394
            return packFloat32( zSign, 0xFF, - ( roundIncrement == 0 ));
 
395
        }
 
396
        if ( zExp < 0 ) {
 
397
            if (STATUS(flush_to_zero)) {
 
398
                float_raise(float_flag_output_denormal STATUS_VAR);
 
399
                return packFloat32(zSign, 0, 0);
 
400
            }
 
401
            isTiny =
 
402
                   ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
 
403
                || ( zExp < -1 )
 
404
                || ( zSig + roundIncrement < 0x80000000 );
 
405
            shift32RightJamming( zSig, - zExp, &zSig );
 
406
            zExp = 0;
 
407
            roundBits = zSig & 0x7F;
 
408
            if ( isTiny && roundBits ) float_raise( float_flag_underflow STATUS_VAR);
 
409
        }
 
410
    }
 
411
    if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
 
412
    zSig = ( zSig + roundIncrement )>>7;
 
413
    zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
 
414
    if ( zSig == 0 ) zExp = 0;
 
415
    return packFloat32( zSign, zExp, zSig );
 
416
 
 
417
}
 
418
 
 
419
/*----------------------------------------------------------------------------
 
420
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
 
421
| and significand `zSig', and returns the proper single-precision floating-
 
422
| point value corresponding to the abstract input.  This routine is just like
 
423
| `roundAndPackFloat32' except that `zSig' does not have to be normalized.
 
424
| Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
 
425
| floating-point exponent.
 
426
*----------------------------------------------------------------------------*/
 
427
 
 
428
static float32
 
429
 normalizeRoundAndPackFloat32(flag zSign, int_fast16_t zExp, uint32_t zSig STATUS_PARAM)
 
430
{
 
431
    int8 shiftCount;
 
432
 
 
433
    shiftCount = countLeadingZeros32( zSig ) - 1;
 
434
    return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<<shiftCount STATUS_VAR);
 
435
 
 
436
}
 
437
 
 
438
/*----------------------------------------------------------------------------
 
439
| Returns the fraction bits of the double-precision floating-point value `a'.
 
440
*----------------------------------------------------------------------------*/
 
441
 
 
442
INLINE uint64_t extractFloat64Frac( float64 a )
 
443
{
 
444
 
 
445
    return float64_val(a) & LIT64( 0x000FFFFFFFFFFFFF );
 
446
 
 
447
}
 
448
 
 
449
/*----------------------------------------------------------------------------
 
450
| Returns the exponent bits of the double-precision floating-point value `a'.
 
451
*----------------------------------------------------------------------------*/
 
452
 
 
453
INLINE int_fast16_t extractFloat64Exp(float64 a)
 
454
{
 
455
 
 
456
    return ( float64_val(a)>>52 ) & 0x7FF;
 
457
 
 
458
}
 
459
 
 
460
/*----------------------------------------------------------------------------
 
461
| Returns the sign bit of the double-precision floating-point value `a'.
 
462
*----------------------------------------------------------------------------*/
 
463
 
 
464
INLINE flag extractFloat64Sign( float64 a )
 
465
{
 
466
 
 
467
    return float64_val(a)>>63;
 
468
 
 
469
}
 
470
 
 
471
/*----------------------------------------------------------------------------
 
472
| If `a' is denormal and we are in flush-to-zero mode then set the
 
473
| input-denormal exception and return zero. Otherwise just return the value.
 
474
*----------------------------------------------------------------------------*/
 
475
static float64 float64_squash_input_denormal(float64 a STATUS_PARAM)
 
476
{
 
477
    if (STATUS(flush_inputs_to_zero)) {
 
478
        if (extractFloat64Exp(a) == 0 && extractFloat64Frac(a) != 0) {
 
479
            float_raise(float_flag_input_denormal STATUS_VAR);
 
480
            return make_float64(float64_val(a) & (1ULL << 63));
 
481
        }
 
482
    }
 
483
    return a;
 
484
}
 
485
 
 
486
/*----------------------------------------------------------------------------
 
487
| Normalizes the subnormal double-precision floating-point value represented
 
488
| by the denormalized significand `aSig'.  The normalized exponent and
 
489
| significand are stored at the locations pointed to by `zExpPtr' and
 
490
| `zSigPtr', respectively.
 
491
*----------------------------------------------------------------------------*/
 
492
 
 
493
static void
 
494
 normalizeFloat64Subnormal(uint64_t aSig, int_fast16_t *zExpPtr, uint64_t *zSigPtr)
 
495
{
 
496
    int8 shiftCount;
 
497
 
 
498
    shiftCount = countLeadingZeros64( aSig ) - 11;
 
499
    *zSigPtr = aSig<<shiftCount;
 
500
    *zExpPtr = 1 - shiftCount;
 
501
 
 
502
}
 
503
 
 
504
/*----------------------------------------------------------------------------
 
505
| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
 
506
| double-precision floating-point value, returning the result.  After being
 
507
| shifted into the proper positions, the three fields are simply added
 
508
| together to form the result.  This means that any integer portion of `zSig'
 
509
| will be added into the exponent.  Since a properly normalized significand
 
510
| will have an integer portion equal to 1, the `zExp' input should be 1 less
 
511
| than the desired result exponent whenever `zSig' is a complete, normalized
 
512
| significand.
 
513
*----------------------------------------------------------------------------*/
 
514
 
 
515
INLINE float64 packFloat64(flag zSign, int_fast16_t zExp, uint64_t zSig)
 
516
{
 
517
 
 
518
    return make_float64(
 
519
        ( ( (uint64_t) zSign )<<63 ) + ( ( (uint64_t) zExp )<<52 ) + zSig);
 
520
 
 
521
}
 
522
 
 
523
/*----------------------------------------------------------------------------
 
524
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
 
525
| and significand `zSig', and returns the proper double-precision floating-
 
526
| point value corresponding to the abstract input.  Ordinarily, the abstract
 
527
| value is simply rounded and packed into the double-precision format, with
 
528
| the inexact exception raised if the abstract input cannot be represented
 
529
| exactly.  However, if the abstract value is too large, the overflow and
 
530
| inexact exceptions are raised and an infinity or maximal finite value is
 
531
| returned.  If the abstract value is too small, the input value is rounded
 
532
| to a subnormal number, and the underflow and inexact exceptions are raised
 
533
| if the abstract input cannot be represented exactly as a subnormal double-
 
534
| precision floating-point number.
 
535
|     The input significand `zSig' has its binary point between bits 62
 
536
| and 61, which is 10 bits to the left of the usual location.  This shifted
 
537
| significand must be normalized or smaller.  If `zSig' is not normalized,
 
538
| `zExp' must be 0; in that case, the result returned is a subnormal number,
 
539
| and it must not require rounding.  In the usual case that `zSig' is
 
540
| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
 
541
| The handling of underflow and overflow follows the IEC/IEEE Standard for
 
542
| Binary Floating-Point Arithmetic.
 
543
*----------------------------------------------------------------------------*/
 
544
 
 
545
static float64 roundAndPackFloat64(flag zSign, int_fast16_t zExp, uint64_t zSig STATUS_PARAM)
 
546
{
 
547
    int8 roundingMode;
 
548
    flag roundNearestEven;
 
549
    int_fast16_t roundIncrement, roundBits;
 
550
    flag isTiny;
 
551
 
 
552
    roundingMode = STATUS(float_rounding_mode);
 
553
    roundNearestEven = ( roundingMode == float_round_nearest_even );
 
554
    roundIncrement = 0x200;
 
555
    if ( ! roundNearestEven ) {
 
556
        if ( roundingMode == float_round_to_zero ) {
 
557
            roundIncrement = 0;
 
558
        }
 
559
        else {
 
560
            roundIncrement = 0x3FF;
 
561
            if ( zSign ) {
 
562
                if ( roundingMode == float_round_up ) roundIncrement = 0;
 
563
            }
 
564
            else {
 
565
                if ( roundingMode == float_round_down ) roundIncrement = 0;
 
566
            }
 
567
        }
 
568
    }
 
569
    roundBits = zSig & 0x3FF;
 
570
    if ( 0x7FD <= (uint16_t) zExp ) {
 
571
        if (    ( 0x7FD < zExp )
 
572
             || (    ( zExp == 0x7FD )
 
573
                  && ( (int64_t) ( zSig + roundIncrement ) < 0 ) )
 
574
           ) {
 
575
            float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
 
576
            return packFloat64( zSign, 0x7FF, - ( roundIncrement == 0 ));
 
577
        }
 
578
        if ( zExp < 0 ) {
 
579
            if (STATUS(flush_to_zero)) {
 
580
                float_raise(float_flag_output_denormal STATUS_VAR);
 
581
                return packFloat64(zSign, 0, 0);
 
582
            }
 
583
            isTiny =
 
584
                   ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
 
585
                || ( zExp < -1 )
 
586
                || ( zSig + roundIncrement < LIT64( 0x8000000000000000 ) );
 
587
            shift64RightJamming( zSig, - zExp, &zSig );
 
588
            zExp = 0;
 
589
            roundBits = zSig & 0x3FF;
 
590
            if ( isTiny && roundBits ) float_raise( float_flag_underflow STATUS_VAR);
 
591
        }
 
592
    }
 
593
    if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
 
594
    zSig = ( zSig + roundIncrement )>>10;
 
595
    zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven );
 
596
    if ( zSig == 0 ) zExp = 0;
 
597
    return packFloat64( zSign, zExp, zSig );
 
598
 
 
599
}
 
600
 
 
601
/*----------------------------------------------------------------------------
 
602
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
 
603
| and significand `zSig', and returns the proper double-precision floating-
 
604
| point value corresponding to the abstract input.  This routine is just like
 
605
| `roundAndPackFloat64' except that `zSig' does not have to be normalized.
 
606
| Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
 
607
| floating-point exponent.
 
608
*----------------------------------------------------------------------------*/
 
609
 
 
610
static float64
 
611
 normalizeRoundAndPackFloat64(flag zSign, int_fast16_t zExp, uint64_t zSig STATUS_PARAM)
 
612
{
 
613
    int8 shiftCount;
 
614
 
 
615
    shiftCount = countLeadingZeros64( zSig ) - 1;
 
616
    return roundAndPackFloat64( zSign, zExp - shiftCount, zSig<<shiftCount STATUS_VAR);
 
617
 
 
618
}
 
619
 
 
620
/*----------------------------------------------------------------------------
 
621
| Returns the fraction bits of the extended double-precision floating-point
 
622
| value `a'.
 
623
*----------------------------------------------------------------------------*/
 
624
 
 
625
INLINE uint64_t extractFloatx80Frac( floatx80 a )
 
626
{
 
627
 
 
628
    return a.low;
 
629
 
 
630
}
 
631
 
 
632
/*----------------------------------------------------------------------------
 
633
| Returns the exponent bits of the extended double-precision floating-point
 
634
| value `a'.
 
635
*----------------------------------------------------------------------------*/
 
636
 
 
637
INLINE int32 extractFloatx80Exp( floatx80 a )
 
638
{
 
639
 
 
640
    return a.high & 0x7FFF;
 
641
 
 
642
}
 
643
 
 
644
/*----------------------------------------------------------------------------
 
645
| Returns the sign bit of the extended double-precision floating-point value
 
646
| `a'.
 
647
*----------------------------------------------------------------------------*/
 
648
 
 
649
INLINE flag extractFloatx80Sign( floatx80 a )
 
650
{
 
651
 
 
652
    return a.high>>15;
 
653
 
 
654
}
 
655
 
 
656
/*----------------------------------------------------------------------------
 
657
| Normalizes the subnormal extended double-precision floating-point value
 
658
| represented by the denormalized significand `aSig'.  The normalized exponent
 
659
| and significand are stored at the locations pointed to by `zExpPtr' and
 
660
| `zSigPtr', respectively.
 
661
*----------------------------------------------------------------------------*/
 
662
 
 
663
static void
 
664
 normalizeFloatx80Subnormal( uint64_t aSig, int32 *zExpPtr, uint64_t *zSigPtr )
 
665
{
 
666
    int8 shiftCount;
 
667
 
 
668
    shiftCount = countLeadingZeros64( aSig );
 
669
    *zSigPtr = aSig<<shiftCount;
 
670
    *zExpPtr = 1 - shiftCount;
 
671
 
 
672
}
 
673
 
 
674
/*----------------------------------------------------------------------------
 
675
| Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
 
676
| extended double-precision floating-point value, returning the result.
 
677
*----------------------------------------------------------------------------*/
 
678
 
 
679
INLINE floatx80 packFloatx80( flag zSign, int32 zExp, uint64_t zSig )
 
680
{
 
681
    floatx80 z;
 
682
 
 
683
    z.low = zSig;
 
684
    z.high = ( ( (uint16_t) zSign )<<15 ) + zExp;
 
685
    return z;
 
686
 
 
687
}
 
688
 
 
689
/*----------------------------------------------------------------------------
 
690
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
 
691
| and extended significand formed by the concatenation of `zSig0' and `zSig1',
 
692
| and returns the proper extended double-precision floating-point value
 
693
| corresponding to the abstract input.  Ordinarily, the abstract value is
 
694
| rounded and packed into the extended double-precision format, with the
 
695
| inexact exception raised if the abstract input cannot be represented
 
696
| exactly.  However, if the abstract value is too large, the overflow and
 
697
| inexact exceptions are raised and an infinity or maximal finite value is
 
698
| returned.  If the abstract value is too small, the input value is rounded to
 
699
| a subnormal number, and the underflow and inexact exceptions are raised if
 
700
| the abstract input cannot be represented exactly as a subnormal extended
 
701
| double-precision floating-point number.
 
702
|     If `roundingPrecision' is 32 or 64, the result is rounded to the same
 
703
| number of bits as single or double precision, respectively.  Otherwise, the
 
704
| result is rounded to the full precision of the extended double-precision
 
705
| format.
 
706
|     The input significand must be normalized or smaller.  If the input
 
707
| significand is not normalized, `zExp' must be 0; in that case, the result
 
708
| returned is a subnormal number, and it must not require rounding.  The
 
709
| handling of underflow and overflow follows the IEC/IEEE Standard for Binary
 
710
| Floating-Point Arithmetic.
 
711
*----------------------------------------------------------------------------*/
 
712
 
 
713
static floatx80
 
714
 roundAndPackFloatx80(
 
715
     int8 roundingPrecision, flag zSign, int32 zExp, uint64_t zSig0, uint64_t zSig1
 
716
 STATUS_PARAM)
 
717
{
 
718
    int8 roundingMode;
 
719
    flag roundNearestEven, increment, isTiny;
 
720
    int64 roundIncrement, roundMask, roundBits;
 
721
 
 
722
    roundingMode = STATUS(float_rounding_mode);
 
723
    roundNearestEven = ( roundingMode == float_round_nearest_even );
 
724
    if ( roundingPrecision == 80 ) goto precision80;
 
725
    if ( roundingPrecision == 64 ) {
 
726
        roundIncrement = LIT64( 0x0000000000000400 );
 
727
        roundMask = LIT64( 0x00000000000007FF );
 
728
    }
 
729
    else if ( roundingPrecision == 32 ) {
 
730
        roundIncrement = LIT64( 0x0000008000000000 );
 
731
        roundMask = LIT64( 0x000000FFFFFFFFFF );
 
732
    }
 
733
    else {
 
734
        goto precision80;
 
735
    }
 
736
    zSig0 |= ( zSig1 != 0 );
 
737
    if ( ! roundNearestEven ) {
 
738
        if ( roundingMode == float_round_to_zero ) {
 
739
            roundIncrement = 0;
 
740
        }
 
741
        else {
 
742
            roundIncrement = roundMask;
 
743
            if ( zSign ) {
 
744
                if ( roundingMode == float_round_up ) roundIncrement = 0;
 
745
            }
 
746
            else {
 
747
                if ( roundingMode == float_round_down ) roundIncrement = 0;
 
748
            }
 
749
        }
 
750
    }
 
751
    roundBits = zSig0 & roundMask;
 
752
    if ( 0x7FFD <= (uint32_t) ( zExp - 1 ) ) {
 
753
        if (    ( 0x7FFE < zExp )
 
754
             || ( ( zExp == 0x7FFE ) && ( zSig0 + roundIncrement < zSig0 ) )
 
755
           ) {
 
756
            goto overflow;
 
757
        }
 
758
        if ( zExp <= 0 ) {
 
759
            if (STATUS(flush_to_zero)) {
 
760
                float_raise(float_flag_output_denormal STATUS_VAR);
 
761
                return packFloatx80(zSign, 0, 0);
 
762
            }
 
763
            isTiny =
 
764
                   ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
 
765
                || ( zExp < 0 )
 
766
                || ( zSig0 <= zSig0 + roundIncrement );
 
767
            shift64RightJamming( zSig0, 1 - zExp, &zSig0 );
 
768
            zExp = 0;
 
769
            roundBits = zSig0 & roundMask;
 
770
            if ( isTiny && roundBits ) float_raise( float_flag_underflow STATUS_VAR);
 
771
            if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
 
772
            zSig0 += roundIncrement;
 
773
            if ( (int64_t) zSig0 < 0 ) zExp = 1;
 
774
            roundIncrement = roundMask + 1;
 
775
            if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
 
776
                roundMask |= roundIncrement;
 
777
            }
 
778
            zSig0 &= ~ roundMask;
 
779
            return packFloatx80( zSign, zExp, zSig0 );
 
780
        }
 
781
    }
 
782
    if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
 
783
    zSig0 += roundIncrement;
 
784
    if ( zSig0 < roundIncrement ) {
 
785
        ++zExp;
 
786
        zSig0 = LIT64( 0x8000000000000000 );
 
787
    }
 
788
    roundIncrement = roundMask + 1;
 
789
    if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
 
790
        roundMask |= roundIncrement;
 
791
    }
 
792
    zSig0 &= ~ roundMask;
 
793
    if ( zSig0 == 0 ) zExp = 0;
 
794
    return packFloatx80( zSign, zExp, zSig0 );
 
795
 precision80:
 
796
    increment = ( (int64_t) zSig1 < 0 );
 
797
    if ( ! roundNearestEven ) {
 
798
        if ( roundingMode == float_round_to_zero ) {
 
799
            increment = 0;
 
800
        }
 
801
        else {
 
802
            if ( zSign ) {
 
803
                increment = ( roundingMode == float_round_down ) && zSig1;
 
804
            }
 
805
            else {
 
806
                increment = ( roundingMode == float_round_up ) && zSig1;
 
807
            }
 
808
        }
 
809
    }
 
810
    if ( 0x7FFD <= (uint32_t) ( zExp - 1 ) ) {
 
811
        if (    ( 0x7FFE < zExp )
 
812
             || (    ( zExp == 0x7FFE )
 
813
                  && ( zSig0 == LIT64( 0xFFFFFFFFFFFFFFFF ) )
 
814
                  && increment
 
815
                )
 
816
           ) {
 
817
            roundMask = 0;
 
818
 overflow:
 
819
            float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
 
820
            if (    ( roundingMode == float_round_to_zero )
 
821
                 || ( zSign && ( roundingMode == float_round_up ) )
 
822
                 || ( ! zSign && ( roundingMode == float_round_down ) )
 
823
               ) {
 
824
                return packFloatx80( zSign, 0x7FFE, ~ roundMask );
 
825
            }
 
826
            return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
 
827
        }
 
828
        if ( zExp <= 0 ) {
 
829
            isTiny =
 
830
                   ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
 
831
                || ( zExp < 0 )
 
832
                || ! increment
 
833
                || ( zSig0 < LIT64( 0xFFFFFFFFFFFFFFFF ) );
 
834
            shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 );
 
835
            zExp = 0;
 
836
            if ( isTiny && zSig1 ) float_raise( float_flag_underflow STATUS_VAR);
 
837
            if ( zSig1 ) STATUS(float_exception_flags) |= float_flag_inexact;
 
838
            if ( roundNearestEven ) {
 
839
                increment = ( (int64_t) zSig1 < 0 );
 
840
            }
 
841
            else {
 
842
                if ( zSign ) {
 
843
                    increment = ( roundingMode == float_round_down ) && zSig1;
 
844
                }
 
845
                else {
 
846
                    increment = ( roundingMode == float_round_up ) && zSig1;
 
847
                }
 
848
            }
 
849
            if ( increment ) {
 
850
                ++zSig0;
 
851
                zSig0 &=
 
852
                    ~ ( ( (uint64_t) ( zSig1<<1 ) == 0 ) & roundNearestEven );
 
853
                if ( (int64_t) zSig0 < 0 ) zExp = 1;
 
854
            }
 
855
            return packFloatx80( zSign, zExp, zSig0 );
 
856
        }
 
857
    }
 
858
    if ( zSig1 ) STATUS(float_exception_flags) |= float_flag_inexact;
 
859
    if ( increment ) {
 
860
        ++zSig0;
 
861
        if ( zSig0 == 0 ) {
 
862
            ++zExp;
 
863
            zSig0 = LIT64( 0x8000000000000000 );
 
864
        }
 
865
        else {
 
866
            zSig0 &= ~ ( ( (uint64_t) ( zSig1<<1 ) == 0 ) & roundNearestEven );
 
867
        }
 
868
    }
 
869
    else {
 
870
        if ( zSig0 == 0 ) zExp = 0;
 
871
    }
 
872
    return packFloatx80( zSign, zExp, zSig0 );
 
873
 
 
874
}
 
875
 
 
876
/*----------------------------------------------------------------------------
 
877
| Takes an abstract floating-point value having sign `zSign', exponent
 
878
| `zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
 
879
| and returns the proper extended double-precision floating-point value
 
880
| corresponding to the abstract input.  This routine is just like
 
881
| `roundAndPackFloatx80' except that the input significand does not have to be
 
882
| normalized.
 
883
*----------------------------------------------------------------------------*/
 
884
 
 
885
static floatx80
 
886
 normalizeRoundAndPackFloatx80(
 
887
     int8 roundingPrecision, flag zSign, int32 zExp, uint64_t zSig0, uint64_t zSig1
 
888
 STATUS_PARAM)
 
889
{
 
890
    int8 shiftCount;
 
891
 
 
892
    if ( zSig0 == 0 ) {
 
893
        zSig0 = zSig1;
 
894
        zSig1 = 0;
 
895
        zExp -= 64;
 
896
    }
 
897
    shiftCount = countLeadingZeros64( zSig0 );
 
898
    shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
 
899
    zExp -= shiftCount;
 
900
    return
 
901
        roundAndPackFloatx80( roundingPrecision, zSign, zExp, zSig0, zSig1 STATUS_VAR);
 
902
 
 
903
}
 
904
 
 
905
/*----------------------------------------------------------------------------
 
906
| Returns the least-significant 64 fraction bits of the quadruple-precision
 
907
| floating-point value `a'.
 
908
*----------------------------------------------------------------------------*/
 
909
 
 
910
INLINE uint64_t extractFloat128Frac1( float128 a )
 
911
{
 
912
 
 
913
    return a.low;
 
914
 
 
915
}
 
916
 
 
917
/*----------------------------------------------------------------------------
 
918
| Returns the most-significant 48 fraction bits of the quadruple-precision
 
919
| floating-point value `a'.
 
920
*----------------------------------------------------------------------------*/
 
921
 
 
922
INLINE uint64_t extractFloat128Frac0( float128 a )
 
923
{
 
924
 
 
925
    return a.high & LIT64( 0x0000FFFFFFFFFFFF );
 
926
 
 
927
}
 
928
 
 
929
/*----------------------------------------------------------------------------
 
930
| Returns the exponent bits of the quadruple-precision floating-point value
 
931
| `a'.
 
932
*----------------------------------------------------------------------------*/
 
933
 
 
934
INLINE int32 extractFloat128Exp( float128 a )
 
935
{
 
936
 
 
937
    return ( a.high>>48 ) & 0x7FFF;
 
938
 
 
939
}
 
940
 
 
941
/*----------------------------------------------------------------------------
 
942
| Returns the sign bit of the quadruple-precision floating-point value `a'.
 
943
*----------------------------------------------------------------------------*/
 
944
 
 
945
INLINE flag extractFloat128Sign( float128 a )
 
946
{
 
947
 
 
948
    return a.high>>63;
 
949
 
 
950
}
 
951
 
 
952
/*----------------------------------------------------------------------------
 
953
| Normalizes the subnormal quadruple-precision floating-point value
 
954
| represented by the denormalized significand formed by the concatenation of
 
955
| `aSig0' and `aSig1'.  The normalized exponent is stored at the location
 
956
| pointed to by `zExpPtr'.  The most significant 49 bits of the normalized
 
957
| significand are stored at the location pointed to by `zSig0Ptr', and the
 
958
| least significant 64 bits of the normalized significand are stored at the
 
959
| location pointed to by `zSig1Ptr'.
 
960
*----------------------------------------------------------------------------*/
 
961
 
 
962
static void
 
963
 normalizeFloat128Subnormal(
 
964
     uint64_t aSig0,
 
965
     uint64_t aSig1,
 
966
     int32 *zExpPtr,
 
967
     uint64_t *zSig0Ptr,
 
968
     uint64_t *zSig1Ptr
 
969
 )
 
970
{
 
971
    int8 shiftCount;
 
972
 
 
973
    if ( aSig0 == 0 ) {
 
974
        shiftCount = countLeadingZeros64( aSig1 ) - 15;
 
975
        if ( shiftCount < 0 ) {
 
976
            *zSig0Ptr = aSig1>>( - shiftCount );
 
977
            *zSig1Ptr = aSig1<<( shiftCount & 63 );
 
978
        }
 
979
        else {
 
980
            *zSig0Ptr = aSig1<<shiftCount;
 
981
            *zSig1Ptr = 0;
 
982
        }
 
983
        *zExpPtr = - shiftCount - 63;
 
984
    }
 
985
    else {
 
986
        shiftCount = countLeadingZeros64( aSig0 ) - 15;
 
987
        shortShift128Left( aSig0, aSig1, shiftCount, zSig0Ptr, zSig1Ptr );
 
988
        *zExpPtr = 1 - shiftCount;
 
989
    }
 
990
 
 
991
}
 
992
 
 
993
/*----------------------------------------------------------------------------
 
994
| Packs the sign `zSign', the exponent `zExp', and the significand formed
 
995
| by the concatenation of `zSig0' and `zSig1' into a quadruple-precision
 
996
| floating-point value, returning the result.  After being shifted into the
 
997
| proper positions, the three fields `zSign', `zExp', and `zSig0' are simply
 
998
| added together to form the most significant 32 bits of the result.  This
 
999
| means that any integer portion of `zSig0' will be added into the exponent.
 
1000
| Since a properly normalized significand will have an integer portion equal
 
1001
| to 1, the `zExp' input should be 1 less than the desired result exponent
 
1002
| whenever `zSig0' and `zSig1' concatenated form a complete, normalized
 
1003
| significand.
 
1004
*----------------------------------------------------------------------------*/
 
1005
 
 
1006
INLINE float128
 
1007
 packFloat128( flag zSign, int32 zExp, uint64_t zSig0, uint64_t zSig1 )
 
1008
{
 
1009
    float128 z;
 
1010
 
 
1011
    z.low = zSig1;
 
1012
    z.high = ( ( (uint64_t) zSign )<<63 ) + ( ( (uint64_t) zExp )<<48 ) + zSig0;
 
1013
    return z;
 
1014
 
 
1015
}
 
1016
 
 
1017
/*----------------------------------------------------------------------------
 
1018
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
 
1019
| and extended significand formed by the concatenation of `zSig0', `zSig1',
 
1020
| and `zSig2', and returns the proper quadruple-precision floating-point value
 
1021
| corresponding to the abstract input.  Ordinarily, the abstract value is
 
1022
| simply rounded and packed into the quadruple-precision format, with the
 
1023
| inexact exception raised if the abstract input cannot be represented
 
1024
| exactly.  However, if the abstract value is too large, the overflow and
 
1025
| inexact exceptions are raised and an infinity or maximal finite value is
 
1026
| returned.  If the abstract value is too small, the input value is rounded to
 
1027
| a subnormal number, and the underflow and inexact exceptions are raised if
 
1028
| the abstract input cannot be represented exactly as a subnormal quadruple-
 
1029
| precision floating-point number.
 
1030
|     The input significand must be normalized or smaller.  If the input
 
1031
| significand is not normalized, `zExp' must be 0; in that case, the result
 
1032
| returned is a subnormal number, and it must not require rounding.  In the
 
1033
| usual case that the input significand is normalized, `zExp' must be 1 less
 
1034
| than the ``true'' floating-point exponent.  The handling of underflow and
 
1035
| overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
1036
*----------------------------------------------------------------------------*/
 
1037
 
 
1038
static float128
 
1039
 roundAndPackFloat128(
 
1040
     flag zSign, int32 zExp, uint64_t zSig0, uint64_t zSig1, uint64_t zSig2 STATUS_PARAM)
 
1041
{
 
1042
    int8 roundingMode;
 
1043
    flag roundNearestEven, increment, isTiny;
 
1044
 
 
1045
    roundingMode = STATUS(float_rounding_mode);
 
1046
    roundNearestEven = ( roundingMode == float_round_nearest_even );
 
1047
    increment = ( (int64_t) zSig2 < 0 );
 
1048
    if ( ! roundNearestEven ) {
 
1049
        if ( roundingMode == float_round_to_zero ) {
 
1050
            increment = 0;
 
1051
        }
 
1052
        else {
 
1053
            if ( zSign ) {
 
1054
                increment = ( roundingMode == float_round_down ) && zSig2;
 
1055
            }
 
1056
            else {
 
1057
                increment = ( roundingMode == float_round_up ) && zSig2;
 
1058
            }
 
1059
        }
 
1060
    }
 
1061
    if ( 0x7FFD <= (uint32_t) zExp ) {
 
1062
        if (    ( 0x7FFD < zExp )
 
1063
             || (    ( zExp == 0x7FFD )
 
1064
                  && eq128(
 
1065
                         LIT64( 0x0001FFFFFFFFFFFF ),
 
1066
                         LIT64( 0xFFFFFFFFFFFFFFFF ),
 
1067
                         zSig0,
 
1068
                         zSig1
 
1069
                     )
 
1070
                  && increment
 
1071
                )
 
1072
           ) {
 
1073
            float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
 
1074
            if (    ( roundingMode == float_round_to_zero )
 
1075
                 || ( zSign && ( roundingMode == float_round_up ) )
 
1076
                 || ( ! zSign && ( roundingMode == float_round_down ) )
 
1077
               ) {
 
1078
                return
 
1079
                    packFloat128(
 
1080
                        zSign,
 
1081
                        0x7FFE,
 
1082
                        LIT64( 0x0000FFFFFFFFFFFF ),
 
1083
                        LIT64( 0xFFFFFFFFFFFFFFFF )
 
1084
                    );
 
1085
            }
 
1086
            return packFloat128( zSign, 0x7FFF, 0, 0 );
 
1087
        }
 
1088
        if ( zExp < 0 ) {
 
1089
            if (STATUS(flush_to_zero)) {
 
1090
                float_raise(float_flag_output_denormal STATUS_VAR);
 
1091
                return packFloat128(zSign, 0, 0, 0);
 
1092
            }
 
1093
            isTiny =
 
1094
                   ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
 
1095
                || ( zExp < -1 )
 
1096
                || ! increment
 
1097
                || lt128(
 
1098
                       zSig0,
 
1099
                       zSig1,
 
1100
                       LIT64( 0x0001FFFFFFFFFFFF ),
 
1101
                       LIT64( 0xFFFFFFFFFFFFFFFF )
 
1102
                   );
 
1103
            shift128ExtraRightJamming(
 
1104
                zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 );
 
1105
            zExp = 0;
 
1106
            if ( isTiny && zSig2 ) float_raise( float_flag_underflow STATUS_VAR);
 
1107
            if ( roundNearestEven ) {
 
1108
                increment = ( (int64_t) zSig2 < 0 );
 
1109
            }
 
1110
            else {
 
1111
                if ( zSign ) {
 
1112
                    increment = ( roundingMode == float_round_down ) && zSig2;
 
1113
                }
 
1114
                else {
 
1115
                    increment = ( roundingMode == float_round_up ) && zSig2;
 
1116
                }
 
1117
            }
 
1118
        }
 
1119
    }
 
1120
    if ( zSig2 ) STATUS(float_exception_flags) |= float_flag_inexact;
 
1121
    if ( increment ) {
 
1122
        add128( zSig0, zSig1, 0, 1, &zSig0, &zSig1 );
 
1123
        zSig1 &= ~ ( ( zSig2 + zSig2 == 0 ) & roundNearestEven );
 
1124
    }
 
1125
    else {
 
1126
        if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0;
 
1127
    }
 
1128
    return packFloat128( zSign, zExp, zSig0, zSig1 );
 
1129
 
 
1130
}
 
1131
 
 
1132
/*----------------------------------------------------------------------------
 
1133
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
 
1134
| and significand formed by the concatenation of `zSig0' and `zSig1', and
 
1135
| returns the proper quadruple-precision floating-point value corresponding
 
1136
| to the abstract input.  This routine is just like `roundAndPackFloat128'
 
1137
| except that the input significand has fewer bits and does not have to be
 
1138
| normalized.  In all cases, `zExp' must be 1 less than the ``true'' floating-
 
1139
| point exponent.
 
1140
*----------------------------------------------------------------------------*/
 
1141
 
 
1142
static float128
 
1143
 normalizeRoundAndPackFloat128(
 
1144
     flag zSign, int32 zExp, uint64_t zSig0, uint64_t zSig1 STATUS_PARAM)
 
1145
{
 
1146
    int8 shiftCount;
 
1147
    uint64_t zSig2;
 
1148
 
 
1149
    if ( zSig0 == 0 ) {
 
1150
        zSig0 = zSig1;
 
1151
        zSig1 = 0;
 
1152
        zExp -= 64;
 
1153
    }
 
1154
    shiftCount = countLeadingZeros64( zSig0 ) - 15;
 
1155
    if ( 0 <= shiftCount ) {
 
1156
        zSig2 = 0;
 
1157
        shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
 
1158
    }
 
1159
    else {
 
1160
        shift128ExtraRightJamming(
 
1161
            zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 );
 
1162
    }
 
1163
    zExp -= shiftCount;
 
1164
    return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR);
 
1165
 
 
1166
}
 
1167
 
 
1168
/*----------------------------------------------------------------------------
 
1169
| Returns the result of converting the 32-bit two's complement integer `a'
 
1170
| to the single-precision floating-point format.  The conversion is performed
 
1171
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
1172
*----------------------------------------------------------------------------*/
 
1173
 
 
1174
float32 int32_to_float32(int32_t a STATUS_PARAM)
 
1175
{
 
1176
    flag zSign;
 
1177
 
 
1178
    if ( a == 0 ) return float32_zero;
 
1179
    if ( a == (int32_t) 0x80000000 ) return packFloat32( 1, 0x9E, 0 );
 
1180
    zSign = ( a < 0 );
 
1181
    return normalizeRoundAndPackFloat32( zSign, 0x9C, zSign ? - a : a STATUS_VAR );
 
1182
 
 
1183
}
 
1184
 
 
1185
/*----------------------------------------------------------------------------
 
1186
| Returns the result of converting the 32-bit two's complement integer `a'
 
1187
| to the double-precision floating-point format.  The conversion is performed
 
1188
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
1189
*----------------------------------------------------------------------------*/
 
1190
 
 
1191
float64 int32_to_float64(int32_t a STATUS_PARAM)
 
1192
{
 
1193
    flag zSign;
 
1194
    uint32 absA;
 
1195
    int8 shiftCount;
 
1196
    uint64_t zSig;
 
1197
 
 
1198
    if ( a == 0 ) return float64_zero;
 
1199
    zSign = ( a < 0 );
 
1200
    absA = zSign ? - a : a;
 
1201
    shiftCount = countLeadingZeros32( absA ) + 21;
 
1202
    zSig = absA;
 
1203
    return packFloat64( zSign, 0x432 - shiftCount, zSig<<shiftCount );
 
1204
 
 
1205
}
 
1206
 
 
1207
/*----------------------------------------------------------------------------
 
1208
| Returns the result of converting the 32-bit two's complement integer `a'
 
1209
| to the extended double-precision floating-point format.  The conversion
 
1210
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
 
1211
| Arithmetic.
 
1212
*----------------------------------------------------------------------------*/
 
1213
 
 
1214
floatx80 int32_to_floatx80(int32_t a STATUS_PARAM)
 
1215
{
 
1216
    flag zSign;
 
1217
    uint32 absA;
 
1218
    int8 shiftCount;
 
1219
    uint64_t zSig;
 
1220
 
 
1221
    if ( a == 0 ) return packFloatx80( 0, 0, 0 );
 
1222
    zSign = ( a < 0 );
 
1223
    absA = zSign ? - a : a;
 
1224
    shiftCount = countLeadingZeros32( absA ) + 32;
 
1225
    zSig = absA;
 
1226
    return packFloatx80( zSign, 0x403E - shiftCount, zSig<<shiftCount );
 
1227
 
 
1228
}
 
1229
 
 
1230
/*----------------------------------------------------------------------------
 
1231
| Returns the result of converting the 32-bit two's complement integer `a' to
 
1232
| the quadruple-precision floating-point format.  The conversion is performed
 
1233
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
1234
*----------------------------------------------------------------------------*/
 
1235
 
 
1236
float128 int32_to_float128(int32_t a STATUS_PARAM)
 
1237
{
 
1238
    flag zSign;
 
1239
    uint32 absA;
 
1240
    int8 shiftCount;
 
1241
    uint64_t zSig0;
 
1242
 
 
1243
    if ( a == 0 ) return packFloat128( 0, 0, 0, 0 );
 
1244
    zSign = ( a < 0 );
 
1245
    absA = zSign ? - a : a;
 
1246
    shiftCount = countLeadingZeros32( absA ) + 17;
 
1247
    zSig0 = absA;
 
1248
    return packFloat128( zSign, 0x402E - shiftCount, zSig0<<shiftCount, 0 );
 
1249
 
 
1250
}
 
1251
 
 
1252
/*----------------------------------------------------------------------------
 
1253
| Returns the result of converting the 64-bit two's complement integer `a'
 
1254
| to the single-precision floating-point format.  The conversion is performed
 
1255
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
1256
*----------------------------------------------------------------------------*/
 
1257
 
 
1258
float32 int64_to_float32(int64_t a STATUS_PARAM)
 
1259
{
 
1260
    flag zSign;
 
1261
    uint64 absA;
 
1262
    int8 shiftCount;
 
1263
 
 
1264
    if ( a == 0 ) return float32_zero;
 
1265
    zSign = ( a < 0 );
 
1266
    absA = zSign ? - a : a;
 
1267
    shiftCount = countLeadingZeros64( absA ) - 40;
 
1268
    if ( 0 <= shiftCount ) {
 
1269
        return packFloat32( zSign, 0x95 - shiftCount, absA<<shiftCount );
 
1270
    }
 
1271
    else {
 
1272
        shiftCount += 7;
 
1273
        if ( shiftCount < 0 ) {
 
1274
            shift64RightJamming( absA, - shiftCount, &absA );
 
1275
        }
 
1276
        else {
 
1277
            absA <<= shiftCount;
 
1278
        }
 
1279
        return roundAndPackFloat32( zSign, 0x9C - shiftCount, absA STATUS_VAR );
 
1280
    }
 
1281
 
 
1282
}
 
1283
 
 
1284
float32 uint64_to_float32(uint64_t a STATUS_PARAM)
 
1285
{
 
1286
    int8 shiftCount;
 
1287
 
 
1288
    if ( a == 0 ) return float32_zero;
 
1289
    shiftCount = countLeadingZeros64( a ) - 40;
 
1290
    if ( 0 <= shiftCount ) {
 
1291
        return packFloat32(0, 0x95 - shiftCount, a<<shiftCount);
 
1292
    }
 
1293
    else {
 
1294
        shiftCount += 7;
 
1295
        if ( shiftCount < 0 ) {
 
1296
            shift64RightJamming( a, - shiftCount, &a );
 
1297
        }
 
1298
        else {
 
1299
            a <<= shiftCount;
 
1300
        }
 
1301
        return roundAndPackFloat32(0, 0x9C - shiftCount, a STATUS_VAR);
 
1302
    }
 
1303
}
 
1304
 
 
1305
/*----------------------------------------------------------------------------
 
1306
| Returns the result of converting the 64-bit two's complement integer `a'
 
1307
| to the double-precision floating-point format.  The conversion is performed
 
1308
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
1309
*----------------------------------------------------------------------------*/
 
1310
 
 
1311
float64 int64_to_float64(int64_t a STATUS_PARAM)
 
1312
{
 
1313
    flag zSign;
 
1314
 
 
1315
    if ( a == 0 ) return float64_zero;
 
1316
    if ( a == (int64_t) LIT64( 0x8000000000000000 ) ) {
 
1317
        return packFloat64( 1, 0x43E, 0 );
 
1318
    }
 
1319
    zSign = ( a < 0 );
 
1320
    return normalizeRoundAndPackFloat64( zSign, 0x43C, zSign ? - a : a STATUS_VAR );
 
1321
 
 
1322
}
 
1323
 
 
1324
float64 uint64_to_float64(uint64_t a STATUS_PARAM)
 
1325
{
 
1326
    int exp =  0x43C;
 
1327
 
 
1328
    if (a == 0) {
 
1329
        return float64_zero;
 
1330
    }
 
1331
    if ((int64_t)a < 0) {
 
1332
        shift64RightJamming(a, 1, &a);
 
1333
        exp += 1;
 
1334
    }
 
1335
    return normalizeRoundAndPackFloat64(0, exp, a STATUS_VAR);
 
1336
}
 
1337
 
 
1338
/*----------------------------------------------------------------------------
 
1339
| Returns the result of converting the 64-bit two's complement integer `a'
 
1340
| to the extended double-precision floating-point format.  The conversion
 
1341
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
 
1342
| Arithmetic.
 
1343
*----------------------------------------------------------------------------*/
 
1344
 
 
1345
floatx80 int64_to_floatx80(int64_t a STATUS_PARAM)
 
1346
{
 
1347
    flag zSign;
 
1348
    uint64 absA;
 
1349
    int8 shiftCount;
 
1350
 
 
1351
    if ( a == 0 ) return packFloatx80( 0, 0, 0 );
 
1352
    zSign = ( a < 0 );
 
1353
    absA = zSign ? - a : a;
 
1354
    shiftCount = countLeadingZeros64( absA );
 
1355
    return packFloatx80( zSign, 0x403E - shiftCount, absA<<shiftCount );
 
1356
 
 
1357
}
 
1358
 
 
1359
/*----------------------------------------------------------------------------
 
1360
| Returns the result of converting the 64-bit two's complement integer `a' to
 
1361
| the quadruple-precision floating-point format.  The conversion is performed
 
1362
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
1363
*----------------------------------------------------------------------------*/
 
1364
 
 
1365
float128 int64_to_float128(int64_t a STATUS_PARAM)
 
1366
{
 
1367
    flag zSign;
 
1368
    uint64 absA;
 
1369
    int8 shiftCount;
 
1370
    int32 zExp;
 
1371
    uint64_t zSig0, zSig1;
 
1372
 
 
1373
    if ( a == 0 ) return packFloat128( 0, 0, 0, 0 );
 
1374
    zSign = ( a < 0 );
 
1375
    absA = zSign ? - a : a;
 
1376
    shiftCount = countLeadingZeros64( absA ) + 49;
 
1377
    zExp = 0x406E - shiftCount;
 
1378
    if ( 64 <= shiftCount ) {
 
1379
        zSig1 = 0;
 
1380
        zSig0 = absA;
 
1381
        shiftCount -= 64;
 
1382
    }
 
1383
    else {
 
1384
        zSig1 = absA;
 
1385
        zSig0 = 0;
 
1386
    }
 
1387
    shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
 
1388
    return packFloat128( zSign, zExp, zSig0, zSig1 );
 
1389
 
 
1390
}
 
1391
 
 
1392
float128 uint64_to_float128(uint64_t a STATUS_PARAM)
 
1393
{
 
1394
    if (a == 0) {
 
1395
        return float128_zero;
 
1396
    }
 
1397
    return normalizeRoundAndPackFloat128(0, 0x406E, a, 0 STATUS_VAR);
 
1398
}
 
1399
 
 
1400
/*----------------------------------------------------------------------------
 
1401
| Returns the result of converting the single-precision floating-point value
 
1402
| `a' to the 32-bit two's complement integer format.  The conversion is
 
1403
| performed according to the IEC/IEEE Standard for Binary Floating-Point
 
1404
| Arithmetic---which means in particular that the conversion is rounded
 
1405
| according to the current rounding mode.  If `a' is a NaN, the largest
 
1406
| positive integer is returned.  Otherwise, if the conversion overflows, the
 
1407
| largest integer with the same sign as `a' is returned.
 
1408
*----------------------------------------------------------------------------*/
 
1409
 
 
1410
int32 float32_to_int32( float32 a STATUS_PARAM )
 
1411
{
 
1412
    flag aSign;
 
1413
    int_fast16_t aExp, shiftCount;
 
1414
    uint32_t aSig;
 
1415
    uint64_t aSig64;
 
1416
 
 
1417
    a = float32_squash_input_denormal(a STATUS_VAR);
 
1418
    aSig = extractFloat32Frac( a );
 
1419
    aExp = extractFloat32Exp( a );
 
1420
    aSign = extractFloat32Sign( a );
 
1421
    if ( ( aExp == 0xFF ) && aSig ) aSign = 0;
 
1422
    if ( aExp ) aSig |= 0x00800000;
 
1423
    shiftCount = 0xAF - aExp;
 
1424
    aSig64 = aSig;
 
1425
    aSig64 <<= 32;
 
1426
    if ( 0 < shiftCount ) shift64RightJamming( aSig64, shiftCount, &aSig64 );
 
1427
    return roundAndPackInt32( aSign, aSig64 STATUS_VAR );
 
1428
 
 
1429
}
 
1430
 
 
1431
/*----------------------------------------------------------------------------
 
1432
| Returns the result of converting the single-precision floating-point value
 
1433
| `a' to the 32-bit two's complement integer format.  The conversion is
 
1434
| performed according to the IEC/IEEE Standard for Binary Floating-Point
 
1435
| Arithmetic, except that the conversion is always rounded toward zero.
 
1436
| If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
 
1437
| the conversion overflows, the largest integer with the same sign as `a' is
 
1438
| returned.
 
1439
*----------------------------------------------------------------------------*/
 
1440
 
 
1441
int32 float32_to_int32_round_to_zero( float32 a STATUS_PARAM )
 
1442
{
 
1443
    flag aSign;
 
1444
    int_fast16_t aExp, shiftCount;
 
1445
    uint32_t aSig;
 
1446
    int32_t z;
 
1447
    a = float32_squash_input_denormal(a STATUS_VAR);
 
1448
 
 
1449
    aSig = extractFloat32Frac( a );
 
1450
    aExp = extractFloat32Exp( a );
 
1451
    aSign = extractFloat32Sign( a );
 
1452
    shiftCount = aExp - 0x9E;
 
1453
    if ( 0 <= shiftCount ) {
 
1454
        if ( float32_val(a) != 0xCF000000 ) {
 
1455
            float_raise( float_flag_invalid STATUS_VAR);
 
1456
            if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF;
 
1457
        }
 
1458
        return (int32_t) 0x80000000;
 
1459
    }
 
1460
    else if ( aExp <= 0x7E ) {
 
1461
        if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
 
1462
        return 0;
 
1463
    }
 
1464
    aSig = ( aSig | 0x00800000 )<<8;
 
1465
    z = aSig>>( - shiftCount );
 
1466
    if ( (uint32_t) ( aSig<<( shiftCount & 31 ) ) ) {
 
1467
        STATUS(float_exception_flags) |= float_flag_inexact;
 
1468
    }
 
1469
    if ( aSign ) z = - z;
 
1470
    return z;
 
1471
 
 
1472
}
 
1473
 
 
1474
/*----------------------------------------------------------------------------
 
1475
| Returns the result of converting the single-precision floating-point value
 
1476
| `a' to the 16-bit two's complement integer format.  The conversion is
 
1477
| performed according to the IEC/IEEE Standard for Binary Floating-Point
 
1478
| Arithmetic, except that the conversion is always rounded toward zero.
 
1479
| If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
 
1480
| the conversion overflows, the largest integer with the same sign as `a' is
 
1481
| returned.
 
1482
*----------------------------------------------------------------------------*/
 
1483
 
 
1484
int_fast16_t float32_to_int16_round_to_zero(float32 a STATUS_PARAM)
 
1485
{
 
1486
    flag aSign;
 
1487
    int_fast16_t aExp, shiftCount;
 
1488
    uint32_t aSig;
 
1489
    int32 z;
 
1490
 
 
1491
    aSig = extractFloat32Frac( a );
 
1492
    aExp = extractFloat32Exp( a );
 
1493
    aSign = extractFloat32Sign( a );
 
1494
    shiftCount = aExp - 0x8E;
 
1495
    if ( 0 <= shiftCount ) {
 
1496
        if ( float32_val(a) != 0xC7000000 ) {
 
1497
            float_raise( float_flag_invalid STATUS_VAR);
 
1498
            if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) {
 
1499
                return 0x7FFF;
 
1500
            }
 
1501
        }
 
1502
        return (int32_t) 0xffff8000;
 
1503
    }
 
1504
    else if ( aExp <= 0x7E ) {
 
1505
        if ( aExp | aSig ) {
 
1506
            STATUS(float_exception_flags) |= float_flag_inexact;
 
1507
        }
 
1508
        return 0;
 
1509
    }
 
1510
    shiftCount -= 0x10;
 
1511
    aSig = ( aSig | 0x00800000 )<<8;
 
1512
    z = aSig>>( - shiftCount );
 
1513
    if ( (uint32_t) ( aSig<<( shiftCount & 31 ) ) ) {
 
1514
        STATUS(float_exception_flags) |= float_flag_inexact;
 
1515
    }
 
1516
    if ( aSign ) {
 
1517
        z = - z;
 
1518
    }
 
1519
    return z;
 
1520
 
 
1521
}
 
1522
 
 
1523
/*----------------------------------------------------------------------------
 
1524
| Returns the result of converting the single-precision floating-point value
 
1525
| `a' to the 64-bit two's complement integer format.  The conversion is
 
1526
| performed according to the IEC/IEEE Standard for Binary Floating-Point
 
1527
| Arithmetic---which means in particular that the conversion is rounded
 
1528
| according to the current rounding mode.  If `a' is a NaN, the largest
 
1529
| positive integer is returned.  Otherwise, if the conversion overflows, the
 
1530
| largest integer with the same sign as `a' is returned.
 
1531
*----------------------------------------------------------------------------*/
 
1532
 
 
1533
int64 float32_to_int64( float32 a STATUS_PARAM )
 
1534
{
 
1535
    flag aSign;
 
1536
    int_fast16_t aExp, shiftCount;
 
1537
    uint32_t aSig;
 
1538
    uint64_t aSig64, aSigExtra;
 
1539
    a = float32_squash_input_denormal(a STATUS_VAR);
 
1540
 
 
1541
    aSig = extractFloat32Frac( a );
 
1542
    aExp = extractFloat32Exp( a );
 
1543
    aSign = extractFloat32Sign( a );
 
1544
    shiftCount = 0xBE - aExp;
 
1545
    if ( shiftCount < 0 ) {
 
1546
        float_raise( float_flag_invalid STATUS_VAR);
 
1547
        if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) {
 
1548
            return LIT64( 0x7FFFFFFFFFFFFFFF );
 
1549
        }
 
1550
        return (int64_t) LIT64( 0x8000000000000000 );
 
1551
    }
 
1552
    if ( aExp ) aSig |= 0x00800000;
 
1553
    aSig64 = aSig;
 
1554
    aSig64 <<= 40;
 
1555
    shift64ExtraRightJamming( aSig64, 0, shiftCount, &aSig64, &aSigExtra );
 
1556
    return roundAndPackInt64( aSign, aSig64, aSigExtra STATUS_VAR );
 
1557
 
 
1558
}
 
1559
 
 
1560
/*----------------------------------------------------------------------------
 
1561
| Returns the result of converting the single-precision floating-point value
 
1562
| `a' to the 64-bit two's complement integer format.  The conversion is
 
1563
| performed according to the IEC/IEEE Standard for Binary Floating-Point
 
1564
| Arithmetic, except that the conversion is always rounded toward zero.  If
 
1565
| `a' is a NaN, the largest positive integer is returned.  Otherwise, if the
 
1566
| conversion overflows, the largest integer with the same sign as `a' is
 
1567
| returned.
 
1568
*----------------------------------------------------------------------------*/
 
1569
 
 
1570
int64 float32_to_int64_round_to_zero( float32 a STATUS_PARAM )
 
1571
{
 
1572
    flag aSign;
 
1573
    int_fast16_t aExp, shiftCount;
 
1574
    uint32_t aSig;
 
1575
    uint64_t aSig64;
 
1576
    int64 z;
 
1577
    a = float32_squash_input_denormal(a STATUS_VAR);
 
1578
 
 
1579
    aSig = extractFloat32Frac( a );
 
1580
    aExp = extractFloat32Exp( a );
 
1581
    aSign = extractFloat32Sign( a );
 
1582
    shiftCount = aExp - 0xBE;
 
1583
    if ( 0 <= shiftCount ) {
 
1584
        if ( float32_val(a) != 0xDF000000 ) {
 
1585
            float_raise( float_flag_invalid STATUS_VAR);
 
1586
            if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) {
 
1587
                return LIT64( 0x7FFFFFFFFFFFFFFF );
 
1588
            }
 
1589
        }
 
1590
        return (int64_t) LIT64( 0x8000000000000000 );
 
1591
    }
 
1592
    else if ( aExp <= 0x7E ) {
 
1593
        if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
 
1594
        return 0;
 
1595
    }
 
1596
    aSig64 = aSig | 0x00800000;
 
1597
    aSig64 <<= 40;
 
1598
    z = aSig64>>( - shiftCount );
 
1599
    if ( (uint64_t) ( aSig64<<( shiftCount & 63 ) ) ) {
 
1600
        STATUS(float_exception_flags) |= float_flag_inexact;
 
1601
    }
 
1602
    if ( aSign ) z = - z;
 
1603
    return z;
 
1604
 
 
1605
}
 
1606
 
 
1607
/*----------------------------------------------------------------------------
 
1608
| Returns the result of converting the single-precision floating-point value
 
1609
| `a' to the double-precision floating-point format.  The conversion is
 
1610
| performed according to the IEC/IEEE Standard for Binary Floating-Point
 
1611
| Arithmetic.
 
1612
*----------------------------------------------------------------------------*/
 
1613
 
 
1614
float64 float32_to_float64( float32 a STATUS_PARAM )
 
1615
{
 
1616
    flag aSign;
 
1617
    int_fast16_t aExp;
 
1618
    uint32_t aSig;
 
1619
    a = float32_squash_input_denormal(a STATUS_VAR);
 
1620
 
 
1621
    aSig = extractFloat32Frac( a );
 
1622
    aExp = extractFloat32Exp( a );
 
1623
    aSign = extractFloat32Sign( a );
 
1624
    if ( aExp == 0xFF ) {
 
1625
        if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
 
1626
        return packFloat64( aSign, 0x7FF, 0 );
 
1627
    }
 
1628
    if ( aExp == 0 ) {
 
1629
        if ( aSig == 0 ) return packFloat64( aSign, 0, 0 );
 
1630
        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
 
1631
        --aExp;
 
1632
    }
 
1633
    return packFloat64( aSign, aExp + 0x380, ( (uint64_t) aSig )<<29 );
 
1634
 
 
1635
}
 
1636
 
 
1637
/*----------------------------------------------------------------------------
 
1638
| Returns the result of converting the single-precision floating-point value
 
1639
| `a' to the extended double-precision floating-point format.  The conversion
 
1640
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
 
1641
| Arithmetic.
 
1642
*----------------------------------------------------------------------------*/
 
1643
 
 
1644
floatx80 float32_to_floatx80( float32 a STATUS_PARAM )
 
1645
{
 
1646
    flag aSign;
 
1647
    int_fast16_t aExp;
 
1648
    uint32_t aSig;
 
1649
 
 
1650
    a = float32_squash_input_denormal(a STATUS_VAR);
 
1651
    aSig = extractFloat32Frac( a );
 
1652
    aExp = extractFloat32Exp( a );
 
1653
    aSign = extractFloat32Sign( a );
 
1654
    if ( aExp == 0xFF ) {
 
1655
        if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
 
1656
        return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
 
1657
    }
 
1658
    if ( aExp == 0 ) {
 
1659
        if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
 
1660
        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
 
1661
    }
 
1662
    aSig |= 0x00800000;
 
1663
    return packFloatx80( aSign, aExp + 0x3F80, ( (uint64_t) aSig )<<40 );
 
1664
 
 
1665
}
 
1666
 
 
1667
/*----------------------------------------------------------------------------
 
1668
| Returns the result of converting the single-precision floating-point value
 
1669
| `a' to the double-precision floating-point format.  The conversion is
 
1670
| performed according to the IEC/IEEE Standard for Binary Floating-Point
 
1671
| Arithmetic.
 
1672
*----------------------------------------------------------------------------*/
 
1673
 
 
1674
float128 float32_to_float128( float32 a STATUS_PARAM )
 
1675
{
 
1676
    flag aSign;
 
1677
    int_fast16_t aExp;
 
1678
    uint32_t aSig;
 
1679
 
 
1680
    a = float32_squash_input_denormal(a STATUS_VAR);
 
1681
    aSig = extractFloat32Frac( a );
 
1682
    aExp = extractFloat32Exp( a );
 
1683
    aSign = extractFloat32Sign( a );
 
1684
    if ( aExp == 0xFF ) {
 
1685
        if ( aSig ) return commonNaNToFloat128( float32ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
 
1686
        return packFloat128( aSign, 0x7FFF, 0, 0 );
 
1687
    }
 
1688
    if ( aExp == 0 ) {
 
1689
        if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 );
 
1690
        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
 
1691
        --aExp;
 
1692
    }
 
1693
    return packFloat128( aSign, aExp + 0x3F80, ( (uint64_t) aSig )<<25, 0 );
 
1694
 
 
1695
}
 
1696
 
 
1697
/*----------------------------------------------------------------------------
 
1698
| Rounds the single-precision floating-point value `a' to an integer, and
 
1699
| returns the result as a single-precision floating-point value.  The
 
1700
| operation is performed according to the IEC/IEEE Standard for Binary
 
1701
| Floating-Point Arithmetic.
 
1702
*----------------------------------------------------------------------------*/
 
1703
 
 
1704
float32 float32_round_to_int( float32 a STATUS_PARAM)
 
1705
{
 
1706
    flag aSign;
 
1707
    int_fast16_t aExp;
 
1708
    uint32_t lastBitMask, roundBitsMask;
 
1709
    int8 roundingMode;
 
1710
    uint32_t z;
 
1711
    a = float32_squash_input_denormal(a STATUS_VAR);
 
1712
 
 
1713
    aExp = extractFloat32Exp( a );
 
1714
    if ( 0x96 <= aExp ) {
 
1715
        if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) {
 
1716
            return propagateFloat32NaN( a, a STATUS_VAR );
 
1717
        }
 
1718
        return a;
 
1719
    }
 
1720
    if ( aExp <= 0x7E ) {
 
1721
        if ( (uint32_t) ( float32_val(a)<<1 ) == 0 ) return a;
 
1722
        STATUS(float_exception_flags) |= float_flag_inexact;
 
1723
        aSign = extractFloat32Sign( a );
 
1724
        switch ( STATUS(float_rounding_mode) ) {
 
1725
         case float_round_nearest_even:
 
1726
            if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) {
 
1727
                return packFloat32( aSign, 0x7F, 0 );
 
1728
            }
 
1729
            break;
 
1730
         case float_round_down:
 
1731
            return make_float32(aSign ? 0xBF800000 : 0);
 
1732
         case float_round_up:
 
1733
            return make_float32(aSign ? 0x80000000 : 0x3F800000);
 
1734
        }
 
1735
        return packFloat32( aSign, 0, 0 );
 
1736
    }
 
1737
    lastBitMask = 1;
 
1738
    lastBitMask <<= 0x96 - aExp;
 
1739
    roundBitsMask = lastBitMask - 1;
 
1740
    z = float32_val(a);
 
1741
    roundingMode = STATUS(float_rounding_mode);
 
1742
    if ( roundingMode == float_round_nearest_even ) {
 
1743
        z += lastBitMask>>1;
 
1744
        if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
 
1745
    }
 
1746
    else if ( roundingMode != float_round_to_zero ) {
 
1747
        if ( extractFloat32Sign( make_float32(z) ) ^ ( roundingMode == float_round_up ) ) {
 
1748
            z += roundBitsMask;
 
1749
        }
 
1750
    }
 
1751
    z &= ~ roundBitsMask;
 
1752
    if ( z != float32_val(a) ) STATUS(float_exception_flags) |= float_flag_inexact;
 
1753
    return make_float32(z);
 
1754
 
 
1755
}
 
1756
 
 
1757
/*----------------------------------------------------------------------------
 
1758
| Returns the result of adding the absolute values of the single-precision
 
1759
| floating-point values `a' and `b'.  If `zSign' is 1, the sum is negated
 
1760
| before being returned.  `zSign' is ignored if the result is a NaN.
 
1761
| The addition is performed according to the IEC/IEEE Standard for Binary
 
1762
| Floating-Point Arithmetic.
 
1763
*----------------------------------------------------------------------------*/
 
1764
 
 
1765
static float32 addFloat32Sigs( float32 a, float32 b, flag zSign STATUS_PARAM)
 
1766
{
 
1767
    int_fast16_t aExp, bExp, zExp;
 
1768
    uint32_t aSig, bSig, zSig;
 
1769
    int_fast16_t expDiff;
 
1770
 
 
1771
    aSig = extractFloat32Frac( a );
 
1772
    aExp = extractFloat32Exp( a );
 
1773
    bSig = extractFloat32Frac( b );
 
1774
    bExp = extractFloat32Exp( b );
 
1775
    expDiff = aExp - bExp;
 
1776
    aSig <<= 6;
 
1777
    bSig <<= 6;
 
1778
    if ( 0 < expDiff ) {
 
1779
        if ( aExp == 0xFF ) {
 
1780
            if ( aSig ) return propagateFloat32NaN( a, b STATUS_VAR );
 
1781
            return a;
 
1782
        }
 
1783
        if ( bExp == 0 ) {
 
1784
            --expDiff;
 
1785
        }
 
1786
        else {
 
1787
            bSig |= 0x20000000;
 
1788
        }
 
1789
        shift32RightJamming( bSig, expDiff, &bSig );
 
1790
        zExp = aExp;
 
1791
    }
 
1792
    else if ( expDiff < 0 ) {
 
1793
        if ( bExp == 0xFF ) {
 
1794
            if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
 
1795
            return packFloat32( zSign, 0xFF, 0 );
 
1796
        }
 
1797
        if ( aExp == 0 ) {
 
1798
            ++expDiff;
 
1799
        }
 
1800
        else {
 
1801
            aSig |= 0x20000000;
 
1802
        }
 
1803
        shift32RightJamming( aSig, - expDiff, &aSig );
 
1804
        zExp = bExp;
 
1805
    }
 
1806
    else {
 
1807
        if ( aExp == 0xFF ) {
 
1808
            if ( aSig | bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
 
1809
            return a;
 
1810
        }
 
1811
        if ( aExp == 0 ) {
 
1812
            if (STATUS(flush_to_zero)) {
 
1813
                if (aSig | bSig) {
 
1814
                    float_raise(float_flag_output_denormal STATUS_VAR);
 
1815
                }
 
1816
                return packFloat32(zSign, 0, 0);
 
1817
            }
 
1818
            return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
 
1819
        }
 
1820
        zSig = 0x40000000 + aSig + bSig;
 
1821
        zExp = aExp;
 
1822
        goto roundAndPack;
 
1823
    }
 
1824
    aSig |= 0x20000000;
 
1825
    zSig = ( aSig + bSig )<<1;
 
1826
    --zExp;
 
1827
    if ( (int32_t) zSig < 0 ) {
 
1828
        zSig = aSig + bSig;
 
1829
        ++zExp;
 
1830
    }
 
1831
 roundAndPack:
 
1832
    return roundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
 
1833
 
 
1834
}
 
1835
 
 
1836
/*----------------------------------------------------------------------------
 
1837
| Returns the result of subtracting the absolute values of the single-
 
1838
| precision floating-point values `a' and `b'.  If `zSign' is 1, the
 
1839
| difference is negated before being returned.  `zSign' is ignored if the
 
1840
| result is a NaN.  The subtraction is performed according to the IEC/IEEE
 
1841
| Standard for Binary Floating-Point Arithmetic.
 
1842
*----------------------------------------------------------------------------*/
 
1843
 
 
1844
static float32 subFloat32Sigs( float32 a, float32 b, flag zSign STATUS_PARAM)
 
1845
{
 
1846
    int_fast16_t aExp, bExp, zExp;
 
1847
    uint32_t aSig, bSig, zSig;
 
1848
    int_fast16_t expDiff;
 
1849
 
 
1850
    aSig = extractFloat32Frac( a );
 
1851
    aExp = extractFloat32Exp( a );
 
1852
    bSig = extractFloat32Frac( b );
 
1853
    bExp = extractFloat32Exp( b );
 
1854
    expDiff = aExp - bExp;
 
1855
    aSig <<= 7;
 
1856
    bSig <<= 7;
 
1857
    if ( 0 < expDiff ) goto aExpBigger;
 
1858
    if ( expDiff < 0 ) goto bExpBigger;
 
1859
    if ( aExp == 0xFF ) {
 
1860
        if ( aSig | bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
 
1861
        float_raise( float_flag_invalid STATUS_VAR);
 
1862
        return float32_default_nan;
 
1863
    }
 
1864
    if ( aExp == 0 ) {
 
1865
        aExp = 1;
 
1866
        bExp = 1;
 
1867
    }
 
1868
    if ( bSig < aSig ) goto aBigger;
 
1869
    if ( aSig < bSig ) goto bBigger;
 
1870
    return packFloat32( STATUS(float_rounding_mode) == float_round_down, 0, 0 );
 
1871
 bExpBigger:
 
1872
    if ( bExp == 0xFF ) {
 
1873
        if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
 
1874
        return packFloat32( zSign ^ 1, 0xFF, 0 );
 
1875
    }
 
1876
    if ( aExp == 0 ) {
 
1877
        ++expDiff;
 
1878
    }
 
1879
    else {
 
1880
        aSig |= 0x40000000;
 
1881
    }
 
1882
    shift32RightJamming( aSig, - expDiff, &aSig );
 
1883
    bSig |= 0x40000000;
 
1884
 bBigger:
 
1885
    zSig = bSig - aSig;
 
1886
    zExp = bExp;
 
1887
    zSign ^= 1;
 
1888
    goto normalizeRoundAndPack;
 
1889
 aExpBigger:
 
1890
    if ( aExp == 0xFF ) {
 
1891
        if ( aSig ) return propagateFloat32NaN( a, b STATUS_VAR );
 
1892
        return a;
 
1893
    }
 
1894
    if ( bExp == 0 ) {
 
1895
        --expDiff;
 
1896
    }
 
1897
    else {
 
1898
        bSig |= 0x40000000;
 
1899
    }
 
1900
    shift32RightJamming( bSig, expDiff, &bSig );
 
1901
    aSig |= 0x40000000;
 
1902
 aBigger:
 
1903
    zSig = aSig - bSig;
 
1904
    zExp = aExp;
 
1905
 normalizeRoundAndPack:
 
1906
    --zExp;
 
1907
    return normalizeRoundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
 
1908
 
 
1909
}
 
1910
 
 
1911
/*----------------------------------------------------------------------------
 
1912
| Returns the result of adding the single-precision floating-point values `a'
 
1913
| and `b'.  The operation is performed according to the IEC/IEEE Standard for
 
1914
| Binary Floating-Point Arithmetic.
 
1915
*----------------------------------------------------------------------------*/
 
1916
 
 
1917
float32 float32_add( float32 a, float32 b STATUS_PARAM )
 
1918
{
 
1919
    flag aSign, bSign;
 
1920
    a = float32_squash_input_denormal(a STATUS_VAR);
 
1921
    b = float32_squash_input_denormal(b STATUS_VAR);
 
1922
 
 
1923
    aSign = extractFloat32Sign( a );
 
1924
    bSign = extractFloat32Sign( b );
 
1925
    if ( aSign == bSign ) {
 
1926
        return addFloat32Sigs( a, b, aSign STATUS_VAR);
 
1927
    }
 
1928
    else {
 
1929
        return subFloat32Sigs( a, b, aSign STATUS_VAR );
 
1930
    }
 
1931
 
 
1932
}
 
1933
 
 
1934
/*----------------------------------------------------------------------------
 
1935
| Returns the result of subtracting the single-precision floating-point values
 
1936
| `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
 
1937
| for Binary Floating-Point Arithmetic.
 
1938
*----------------------------------------------------------------------------*/
 
1939
 
 
1940
float32 float32_sub( float32 a, float32 b STATUS_PARAM )
 
1941
{
 
1942
    flag aSign, bSign;
 
1943
    a = float32_squash_input_denormal(a STATUS_VAR);
 
1944
    b = float32_squash_input_denormal(b STATUS_VAR);
 
1945
 
 
1946
    aSign = extractFloat32Sign( a );
 
1947
    bSign = extractFloat32Sign( b );
 
1948
    if ( aSign == bSign ) {
 
1949
        return subFloat32Sigs( a, b, aSign STATUS_VAR );
 
1950
    }
 
1951
    else {
 
1952
        return addFloat32Sigs( a, b, aSign STATUS_VAR );
 
1953
    }
 
1954
 
 
1955
}
 
1956
 
 
1957
/*----------------------------------------------------------------------------
 
1958
| Returns the result of multiplying the single-precision floating-point values
 
1959
| `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
 
1960
| for Binary Floating-Point Arithmetic.
 
1961
*----------------------------------------------------------------------------*/
 
1962
 
 
1963
float32 float32_mul( float32 a, float32 b STATUS_PARAM )
 
1964
{
 
1965
    flag aSign, bSign, zSign;
 
1966
    int_fast16_t aExp, bExp, zExp;
 
1967
    uint32_t aSig, bSig;
 
1968
    uint64_t zSig64;
 
1969
    uint32_t zSig;
 
1970
 
 
1971
    a = float32_squash_input_denormal(a STATUS_VAR);
 
1972
    b = float32_squash_input_denormal(b STATUS_VAR);
 
1973
 
 
1974
    aSig = extractFloat32Frac( a );
 
1975
    aExp = extractFloat32Exp( a );
 
1976
    aSign = extractFloat32Sign( a );
 
1977
    bSig = extractFloat32Frac( b );
 
1978
    bExp = extractFloat32Exp( b );
 
1979
    bSign = extractFloat32Sign( b );
 
1980
    zSign = aSign ^ bSign;
 
1981
    if ( aExp == 0xFF ) {
 
1982
        if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
 
1983
            return propagateFloat32NaN( a, b STATUS_VAR );
 
1984
        }
 
1985
        if ( ( bExp | bSig ) == 0 ) {
 
1986
            float_raise( float_flag_invalid STATUS_VAR);
 
1987
            return float32_default_nan;
 
1988
        }
 
1989
        return packFloat32( zSign, 0xFF, 0 );
 
1990
    }
 
1991
    if ( bExp == 0xFF ) {
 
1992
        if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
 
1993
        if ( ( aExp | aSig ) == 0 ) {
 
1994
            float_raise( float_flag_invalid STATUS_VAR);
 
1995
            return float32_default_nan;
 
1996
        }
 
1997
        return packFloat32( zSign, 0xFF, 0 );
 
1998
    }
 
1999
    if ( aExp == 0 ) {
 
2000
        if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
 
2001
        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
 
2002
    }
 
2003
    if ( bExp == 0 ) {
 
2004
        if ( bSig == 0 ) return packFloat32( zSign, 0, 0 );
 
2005
        normalizeFloat32Subnormal( bSig, &bExp, &bSig );
 
2006
    }
 
2007
    zExp = aExp + bExp - 0x7F;
 
2008
    aSig = ( aSig | 0x00800000 )<<7;
 
2009
    bSig = ( bSig | 0x00800000 )<<8;
 
2010
    shift64RightJamming( ( (uint64_t) aSig ) * bSig, 32, &zSig64 );
 
2011
    zSig = zSig64;
 
2012
    if ( 0 <= (int32_t) ( zSig<<1 ) ) {
 
2013
        zSig <<= 1;
 
2014
        --zExp;
 
2015
    }
 
2016
    return roundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
 
2017
 
 
2018
}
 
2019
 
 
2020
/*----------------------------------------------------------------------------
 
2021
| Returns the result of dividing the single-precision floating-point value `a'
 
2022
| by the corresponding value `b'.  The operation is performed according to the
 
2023
| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
2024
*----------------------------------------------------------------------------*/
 
2025
 
 
2026
float32 float32_div( float32 a, float32 b STATUS_PARAM )
 
2027
{
 
2028
    flag aSign, bSign, zSign;
 
2029
    int_fast16_t aExp, bExp, zExp;
 
2030
    uint32_t aSig, bSig, zSig;
 
2031
    a = float32_squash_input_denormal(a STATUS_VAR);
 
2032
    b = float32_squash_input_denormal(b STATUS_VAR);
 
2033
 
 
2034
    aSig = extractFloat32Frac( a );
 
2035
    aExp = extractFloat32Exp( a );
 
2036
    aSign = extractFloat32Sign( a );
 
2037
    bSig = extractFloat32Frac( b );
 
2038
    bExp = extractFloat32Exp( b );
 
2039
    bSign = extractFloat32Sign( b );
 
2040
    zSign = aSign ^ bSign;
 
2041
    if ( aExp == 0xFF ) {
 
2042
        if ( aSig ) return propagateFloat32NaN( a, b STATUS_VAR );
 
2043
        if ( bExp == 0xFF ) {
 
2044
            if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
 
2045
            float_raise( float_flag_invalid STATUS_VAR);
 
2046
            return float32_default_nan;
 
2047
        }
 
2048
        return packFloat32( zSign, 0xFF, 0 );
 
2049
    }
 
2050
    if ( bExp == 0xFF ) {
 
2051
        if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
 
2052
        return packFloat32( zSign, 0, 0 );
 
2053
    }
 
2054
    if ( bExp == 0 ) {
 
2055
        if ( bSig == 0 ) {
 
2056
            if ( ( aExp | aSig ) == 0 ) {
 
2057
                float_raise( float_flag_invalid STATUS_VAR);
 
2058
                return float32_default_nan;
 
2059
            }
 
2060
            float_raise( float_flag_divbyzero STATUS_VAR);
 
2061
            return packFloat32( zSign, 0xFF, 0 );
 
2062
        }
 
2063
        normalizeFloat32Subnormal( bSig, &bExp, &bSig );
 
2064
    }
 
2065
    if ( aExp == 0 ) {
 
2066
        if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
 
2067
        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
 
2068
    }
 
2069
    zExp = aExp - bExp + 0x7D;
 
2070
    aSig = ( aSig | 0x00800000 )<<7;
 
2071
    bSig = ( bSig | 0x00800000 )<<8;
 
2072
    if ( bSig <= ( aSig + aSig ) ) {
 
2073
        aSig >>= 1;
 
2074
        ++zExp;
 
2075
    }
 
2076
    zSig = ( ( (uint64_t) aSig )<<32 ) / bSig;
 
2077
    if ( ( zSig & 0x3F ) == 0 ) {
 
2078
        zSig |= ( (uint64_t) bSig * zSig != ( (uint64_t) aSig )<<32 );
 
2079
    }
 
2080
    return roundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
 
2081
 
 
2082
}
 
2083
 
 
2084
/*----------------------------------------------------------------------------
 
2085
| Returns the remainder of the single-precision floating-point value `a'
 
2086
| with respect to the corresponding value `b'.  The operation is performed
 
2087
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
2088
*----------------------------------------------------------------------------*/
 
2089
 
 
2090
float32 float32_rem( float32 a, float32 b STATUS_PARAM )
 
2091
{
 
2092
    flag aSign, zSign;
 
2093
    int_fast16_t aExp, bExp, expDiff;
 
2094
    uint32_t aSig, bSig;
 
2095
    uint32_t q;
 
2096
    uint64_t aSig64, bSig64, q64;
 
2097
    uint32_t alternateASig;
 
2098
    int32_t sigMean;
 
2099
    a = float32_squash_input_denormal(a STATUS_VAR);
 
2100
    b = float32_squash_input_denormal(b STATUS_VAR);
 
2101
 
 
2102
    aSig = extractFloat32Frac( a );
 
2103
    aExp = extractFloat32Exp( a );
 
2104
    aSign = extractFloat32Sign( a );
 
2105
    bSig = extractFloat32Frac( b );
 
2106
    bExp = extractFloat32Exp( b );
 
2107
    if ( aExp == 0xFF ) {
 
2108
        if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
 
2109
            return propagateFloat32NaN( a, b STATUS_VAR );
 
2110
        }
 
2111
        float_raise( float_flag_invalid STATUS_VAR);
 
2112
        return float32_default_nan;
 
2113
    }
 
2114
    if ( bExp == 0xFF ) {
 
2115
        if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
 
2116
        return a;
 
2117
    }
 
2118
    if ( bExp == 0 ) {
 
2119
        if ( bSig == 0 ) {
 
2120
            float_raise( float_flag_invalid STATUS_VAR);
 
2121
            return float32_default_nan;
 
2122
        }
 
2123
        normalizeFloat32Subnormal( bSig, &bExp, &bSig );
 
2124
    }
 
2125
    if ( aExp == 0 ) {
 
2126
        if ( aSig == 0 ) return a;
 
2127
        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
 
2128
    }
 
2129
    expDiff = aExp - bExp;
 
2130
    aSig |= 0x00800000;
 
2131
    bSig |= 0x00800000;
 
2132
    if ( expDiff < 32 ) {
 
2133
        aSig <<= 8;
 
2134
        bSig <<= 8;
 
2135
        if ( expDiff < 0 ) {
 
2136
            if ( expDiff < -1 ) return a;
 
2137
            aSig >>= 1;
 
2138
        }
 
2139
        q = ( bSig <= aSig );
 
2140
        if ( q ) aSig -= bSig;
 
2141
        if ( 0 < expDiff ) {
 
2142
            q = ( ( (uint64_t) aSig )<<32 ) / bSig;
 
2143
            q >>= 32 - expDiff;
 
2144
            bSig >>= 2;
 
2145
            aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
 
2146
        }
 
2147
        else {
 
2148
            aSig >>= 2;
 
2149
            bSig >>= 2;
 
2150
        }
 
2151
    }
 
2152
    else {
 
2153
        if ( bSig <= aSig ) aSig -= bSig;
 
2154
        aSig64 = ( (uint64_t) aSig )<<40;
 
2155
        bSig64 = ( (uint64_t) bSig )<<40;
 
2156
        expDiff -= 64;
 
2157
        while ( 0 < expDiff ) {
 
2158
            q64 = estimateDiv128To64( aSig64, 0, bSig64 );
 
2159
            q64 = ( 2 < q64 ) ? q64 - 2 : 0;
 
2160
            aSig64 = - ( ( bSig * q64 )<<38 );
 
2161
            expDiff -= 62;
 
2162
        }
 
2163
        expDiff += 64;
 
2164
        q64 = estimateDiv128To64( aSig64, 0, bSig64 );
 
2165
        q64 = ( 2 < q64 ) ? q64 - 2 : 0;
 
2166
        q = q64>>( 64 - expDiff );
 
2167
        bSig <<= 6;
 
2168
        aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q;
 
2169
    }
 
2170
    do {
 
2171
        alternateASig = aSig;
 
2172
        ++q;
 
2173
        aSig -= bSig;
 
2174
    } while ( 0 <= (int32_t) aSig );
 
2175
    sigMean = aSig + alternateASig;
 
2176
    if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
 
2177
        aSig = alternateASig;
 
2178
    }
 
2179
    zSign = ( (int32_t) aSig < 0 );
 
2180
    if ( zSign ) aSig = - aSig;
 
2181
    return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig STATUS_VAR );
 
2182
 
 
2183
}
 
2184
 
 
2185
/*----------------------------------------------------------------------------
 
2186
| Returns the result of multiplying the single-precision floating-point values
 
2187
| `a' and `b' then adding 'c', with no intermediate rounding step after the
 
2188
| multiplication.  The operation is performed according to the IEC/IEEE
 
2189
| Standard for Binary Floating-Point Arithmetic 754-2008.
 
2190
| The flags argument allows the caller to select negation of the
 
2191
| addend, the intermediate product, or the final result. (The difference
 
2192
| between this and having the caller do a separate negation is that negating
 
2193
| externally will flip the sign bit on NaNs.)
 
2194
*----------------------------------------------------------------------------*/
 
2195
 
 
2196
float32 float32_muladd(float32 a, float32 b, float32 c, int flags STATUS_PARAM)
 
2197
{
 
2198
    flag aSign, bSign, cSign, zSign;
 
2199
    int_fast16_t aExp, bExp, cExp, pExp, zExp, expDiff;
 
2200
    uint32_t aSig, bSig, cSig;
 
2201
    flag pInf, pZero, pSign;
 
2202
    uint64_t pSig64, cSig64, zSig64;
 
2203
    uint32_t pSig;
 
2204
    int shiftcount;
 
2205
    flag signflip, infzero;
 
2206
 
 
2207
    a = float32_squash_input_denormal(a STATUS_VAR);
 
2208
    b = float32_squash_input_denormal(b STATUS_VAR);
 
2209
    c = float32_squash_input_denormal(c STATUS_VAR);
 
2210
    aSig = extractFloat32Frac(a);
 
2211
    aExp = extractFloat32Exp(a);
 
2212
    aSign = extractFloat32Sign(a);
 
2213
    bSig = extractFloat32Frac(b);
 
2214
    bExp = extractFloat32Exp(b);
 
2215
    bSign = extractFloat32Sign(b);
 
2216
    cSig = extractFloat32Frac(c);
 
2217
    cExp = extractFloat32Exp(c);
 
2218
    cSign = extractFloat32Sign(c);
 
2219
 
 
2220
    infzero = ((aExp == 0 && aSig == 0 && bExp == 0xff && bSig == 0) ||
 
2221
               (aExp == 0xff && aSig == 0 && bExp == 0 && bSig == 0));
 
2222
 
 
2223
    /* It is implementation-defined whether the cases of (0,inf,qnan)
 
2224
     * and (inf,0,qnan) raise InvalidOperation or not (and what QNaN
 
2225
     * they return if they do), so we have to hand this information
 
2226
     * off to the target-specific pick-a-NaN routine.
 
2227
     */
 
2228
    if (((aExp == 0xff) && aSig) ||
 
2229
        ((bExp == 0xff) && bSig) ||
 
2230
        ((cExp == 0xff) && cSig)) {
 
2231
        return propagateFloat32MulAddNaN(a, b, c, infzero STATUS_VAR);
 
2232
    }
 
2233
 
 
2234
    if (infzero) {
 
2235
        float_raise(float_flag_invalid STATUS_VAR);
 
2236
        return float32_default_nan;
 
2237
    }
 
2238
 
 
2239
    if (flags & float_muladd_negate_c) {
 
2240
        cSign ^= 1;
 
2241
    }
 
2242
 
 
2243
    signflip = (flags & float_muladd_negate_result) ? 1 : 0;
 
2244
 
 
2245
    /* Work out the sign and type of the product */
 
2246
    pSign = aSign ^ bSign;
 
2247
    if (flags & float_muladd_negate_product) {
 
2248
        pSign ^= 1;
 
2249
    }
 
2250
    pInf = (aExp == 0xff) || (bExp == 0xff);
 
2251
    pZero = ((aExp | aSig) == 0) || ((bExp | bSig) == 0);
 
2252
 
 
2253
    if (cExp == 0xff) {
 
2254
        if (pInf && (pSign ^ cSign)) {
 
2255
            /* addition of opposite-signed infinities => InvalidOperation */
 
2256
            float_raise(float_flag_invalid STATUS_VAR);
 
2257
            return float32_default_nan;
 
2258
        }
 
2259
        /* Otherwise generate an infinity of the same sign */
 
2260
        return packFloat32(cSign ^ signflip, 0xff, 0);
 
2261
    }
 
2262
 
 
2263
    if (pInf) {
 
2264
        return packFloat32(pSign ^ signflip, 0xff, 0);
 
2265
    }
 
2266
 
 
2267
    if (pZero) {
 
2268
        if (cExp == 0) {
 
2269
            if (cSig == 0) {
 
2270
                /* Adding two exact zeroes */
 
2271
                if (pSign == cSign) {
 
2272
                    zSign = pSign;
 
2273
                } else if (STATUS(float_rounding_mode) == float_round_down) {
 
2274
                    zSign = 1;
 
2275
                } else {
 
2276
                    zSign = 0;
 
2277
                }
 
2278
                return packFloat32(zSign ^ signflip, 0, 0);
 
2279
            }
 
2280
            /* Exact zero plus a denorm */
 
2281
            if (STATUS(flush_to_zero)) {
 
2282
                float_raise(float_flag_output_denormal STATUS_VAR);
 
2283
                return packFloat32(cSign ^ signflip, 0, 0);
 
2284
            }
 
2285
        }
 
2286
        /* Zero plus something non-zero : just return the something */
 
2287
        return packFloat32(cSign ^ signflip, cExp, cSig);
 
2288
    }
 
2289
 
 
2290
    if (aExp == 0) {
 
2291
        normalizeFloat32Subnormal(aSig, &aExp, &aSig);
 
2292
    }
 
2293
    if (bExp == 0) {
 
2294
        normalizeFloat32Subnormal(bSig, &bExp, &bSig);
 
2295
    }
 
2296
 
 
2297
    /* Calculate the actual result a * b + c */
 
2298
 
 
2299
    /* Multiply first; this is easy. */
 
2300
    /* NB: we subtract 0x7e where float32_mul() subtracts 0x7f
 
2301
     * because we want the true exponent, not the "one-less-than"
 
2302
     * flavour that roundAndPackFloat32() takes.
 
2303
     */
 
2304
    pExp = aExp + bExp - 0x7e;
 
2305
    aSig = (aSig | 0x00800000) << 7;
 
2306
    bSig = (bSig | 0x00800000) << 8;
 
2307
    pSig64 = (uint64_t)aSig * bSig;
 
2308
    if ((int64_t)(pSig64 << 1) >= 0) {
 
2309
        pSig64 <<= 1;
 
2310
        pExp--;
 
2311
    }
 
2312
 
 
2313
    zSign = pSign ^ signflip;
 
2314
 
 
2315
    /* Now pSig64 is the significand of the multiply, with the explicit bit in
 
2316
     * position 62.
 
2317
     */
 
2318
    if (cExp == 0) {
 
2319
        if (!cSig) {
 
2320
            /* Throw out the special case of c being an exact zero now */
 
2321
            shift64RightJamming(pSig64, 32, &pSig64);
 
2322
            pSig = pSig64;
 
2323
            return roundAndPackFloat32(zSign, pExp - 1,
 
2324
                                       pSig STATUS_VAR);
 
2325
        }
 
2326
        normalizeFloat32Subnormal(cSig, &cExp, &cSig);
 
2327
    }
 
2328
 
 
2329
    cSig64 = (uint64_t)cSig << (62 - 23);
 
2330
    cSig64 |= LIT64(0x4000000000000000);
 
2331
    expDiff = pExp - cExp;
 
2332
 
 
2333
    if (pSign == cSign) {
 
2334
        /* Addition */
 
2335
        if (expDiff > 0) {
 
2336
            /* scale c to match p */
 
2337
            shift64RightJamming(cSig64, expDiff, &cSig64);
 
2338
            zExp = pExp;
 
2339
        } else if (expDiff < 0) {
 
2340
            /* scale p to match c */
 
2341
            shift64RightJamming(pSig64, -expDiff, &pSig64);
 
2342
            zExp = cExp;
 
2343
        } else {
 
2344
            /* no scaling needed */
 
2345
            zExp = cExp;
 
2346
        }
 
2347
        /* Add significands and make sure explicit bit ends up in posn 62 */
 
2348
        zSig64 = pSig64 + cSig64;
 
2349
        if ((int64_t)zSig64 < 0) {
 
2350
            shift64RightJamming(zSig64, 1, &zSig64);
 
2351
        } else {
 
2352
            zExp--;
 
2353
        }
 
2354
    } else {
 
2355
        /* Subtraction */
 
2356
        if (expDiff > 0) {
 
2357
            shift64RightJamming(cSig64, expDiff, &cSig64);
 
2358
            zSig64 = pSig64 - cSig64;
 
2359
            zExp = pExp;
 
2360
        } else if (expDiff < 0) {
 
2361
            shift64RightJamming(pSig64, -expDiff, &pSig64);
 
2362
            zSig64 = cSig64 - pSig64;
 
2363
            zExp = cExp;
 
2364
            zSign ^= 1;
 
2365
        } else {
 
2366
            zExp = pExp;
 
2367
            if (cSig64 < pSig64) {
 
2368
                zSig64 = pSig64 - cSig64;
 
2369
            } else if (pSig64 < cSig64) {
 
2370
                zSig64 = cSig64 - pSig64;
 
2371
                zSign ^= 1;
 
2372
            } else {
 
2373
                /* Exact zero */
 
2374
                zSign = signflip;
 
2375
                if (STATUS(float_rounding_mode) == float_round_down) {
 
2376
                    zSign ^= 1;
 
2377
                }
 
2378
                return packFloat32(zSign, 0, 0);
 
2379
            }
 
2380
        }
 
2381
        --zExp;
 
2382
        /* Normalize to put the explicit bit back into bit 62. */
 
2383
        shiftcount = countLeadingZeros64(zSig64) - 1;
 
2384
        zSig64 <<= shiftcount;
 
2385
        zExp -= shiftcount;
 
2386
    }
 
2387
    shift64RightJamming(zSig64, 32, &zSig64);
 
2388
    return roundAndPackFloat32(zSign, zExp, zSig64 STATUS_VAR);
 
2389
}
 
2390
 
 
2391
 
 
2392
/*----------------------------------------------------------------------------
 
2393
| Returns the square root of the single-precision floating-point value `a'.
 
2394
| The operation is performed according to the IEC/IEEE Standard for Binary
 
2395
| Floating-Point Arithmetic.
 
2396
*----------------------------------------------------------------------------*/
 
2397
 
 
2398
float32 float32_sqrt( float32 a STATUS_PARAM )
 
2399
{
 
2400
    flag aSign;
 
2401
    int_fast16_t aExp, zExp;
 
2402
    uint32_t aSig, zSig;
 
2403
    uint64_t rem, term;
 
2404
    a = float32_squash_input_denormal(a STATUS_VAR);
 
2405
 
 
2406
    aSig = extractFloat32Frac( a );
 
2407
    aExp = extractFloat32Exp( a );
 
2408
    aSign = extractFloat32Sign( a );
 
2409
    if ( aExp == 0xFF ) {
 
2410
        if ( aSig ) return propagateFloat32NaN( a, float32_zero STATUS_VAR );
 
2411
        if ( ! aSign ) return a;
 
2412
        float_raise( float_flag_invalid STATUS_VAR);
 
2413
        return float32_default_nan;
 
2414
    }
 
2415
    if ( aSign ) {
 
2416
        if ( ( aExp | aSig ) == 0 ) return a;
 
2417
        float_raise( float_flag_invalid STATUS_VAR);
 
2418
        return float32_default_nan;
 
2419
    }
 
2420
    if ( aExp == 0 ) {
 
2421
        if ( aSig == 0 ) return float32_zero;
 
2422
        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
 
2423
    }
 
2424
    zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E;
 
2425
    aSig = ( aSig | 0x00800000 )<<8;
 
2426
    zSig = estimateSqrt32( aExp, aSig ) + 2;
 
2427
    if ( ( zSig & 0x7F ) <= 5 ) {
 
2428
        if ( zSig < 2 ) {
 
2429
            zSig = 0x7FFFFFFF;
 
2430
            goto roundAndPack;
 
2431
        }
 
2432
        aSig >>= aExp & 1;
 
2433
        term = ( (uint64_t) zSig ) * zSig;
 
2434
        rem = ( ( (uint64_t) aSig )<<32 ) - term;
 
2435
        while ( (int64_t) rem < 0 ) {
 
2436
            --zSig;
 
2437
            rem += ( ( (uint64_t) zSig )<<1 ) | 1;
 
2438
        }
 
2439
        zSig |= ( rem != 0 );
 
2440
    }
 
2441
    shift32RightJamming( zSig, 1, &zSig );
 
2442
 roundAndPack:
 
2443
    return roundAndPackFloat32( 0, zExp, zSig STATUS_VAR );
 
2444
 
 
2445
}
 
2446
 
 
2447
/*----------------------------------------------------------------------------
 
2448
| Returns the binary exponential of the single-precision floating-point value
 
2449
| `a'. The operation is performed according to the IEC/IEEE Standard for
 
2450
| Binary Floating-Point Arithmetic.
 
2451
|
 
2452
| Uses the following identities:
 
2453
|
 
2454
| 1. -------------------------------------------------------------------------
 
2455
|      x    x*ln(2)
 
2456
|     2  = e
 
2457
|
 
2458
| 2. -------------------------------------------------------------------------
 
2459
|                      2     3     4     5           n
 
2460
|      x        x     x     x     x     x           x
 
2461
|     e  = 1 + --- + --- + --- + --- + --- + ... + --- + ...
 
2462
|               1!    2!    3!    4!    5!          n!
 
2463
*----------------------------------------------------------------------------*/
 
2464
 
 
2465
static const float64 float32_exp2_coefficients[15] =
 
2466
{
 
2467
    const_float64( 0x3ff0000000000000ll ), /*  1 */
 
2468
    const_float64( 0x3fe0000000000000ll ), /*  2 */
 
2469
    const_float64( 0x3fc5555555555555ll ), /*  3 */
 
2470
    const_float64( 0x3fa5555555555555ll ), /*  4 */
 
2471
    const_float64( 0x3f81111111111111ll ), /*  5 */
 
2472
    const_float64( 0x3f56c16c16c16c17ll ), /*  6 */
 
2473
    const_float64( 0x3f2a01a01a01a01all ), /*  7 */
 
2474
    const_float64( 0x3efa01a01a01a01all ), /*  8 */
 
2475
    const_float64( 0x3ec71de3a556c734ll ), /*  9 */
 
2476
    const_float64( 0x3e927e4fb7789f5cll ), /* 10 */
 
2477
    const_float64( 0x3e5ae64567f544e4ll ), /* 11 */
 
2478
    const_float64( 0x3e21eed8eff8d898ll ), /* 12 */
 
2479
    const_float64( 0x3de6124613a86d09ll ), /* 13 */
 
2480
    const_float64( 0x3da93974a8c07c9dll ), /* 14 */
 
2481
    const_float64( 0x3d6ae7f3e733b81fll ), /* 15 */
 
2482
};
 
2483
 
 
2484
float32 float32_exp2( float32 a STATUS_PARAM )
 
2485
{
 
2486
    flag aSign;
 
2487
    int_fast16_t aExp;
 
2488
    uint32_t aSig;
 
2489
    float64 r, x, xn;
 
2490
    int i;
 
2491
    a = float32_squash_input_denormal(a STATUS_VAR);
 
2492
 
 
2493
    aSig = extractFloat32Frac( a );
 
2494
    aExp = extractFloat32Exp( a );
 
2495
    aSign = extractFloat32Sign( a );
 
2496
 
 
2497
    if ( aExp == 0xFF) {
 
2498
        if ( aSig ) return propagateFloat32NaN( a, float32_zero STATUS_VAR );
 
2499
        return (aSign) ? float32_zero : a;
 
2500
    }
 
2501
    if (aExp == 0) {
 
2502
        if (aSig == 0) return float32_one;
 
2503
    }
 
2504
 
 
2505
    float_raise( float_flag_inexact STATUS_VAR);
 
2506
 
 
2507
    /* ******************************* */
 
2508
    /* using float64 for approximation */
 
2509
    /* ******************************* */
 
2510
    x = float32_to_float64(a STATUS_VAR);
 
2511
    x = float64_mul(x, float64_ln2 STATUS_VAR);
 
2512
 
 
2513
    xn = x;
 
2514
    r = float64_one;
 
2515
    for (i = 0 ; i < 15 ; i++) {
 
2516
        float64 f;
 
2517
 
 
2518
        f = float64_mul(xn, float32_exp2_coefficients[i] STATUS_VAR);
 
2519
        r = float64_add(r, f STATUS_VAR);
 
2520
 
 
2521
        xn = float64_mul(xn, x STATUS_VAR);
 
2522
    }
 
2523
 
 
2524
    return float64_to_float32(r, status);
 
2525
}
 
2526
 
 
2527
/*----------------------------------------------------------------------------
 
2528
| Returns the binary log of the single-precision floating-point value `a'.
 
2529
| The operation is performed according to the IEC/IEEE Standard for Binary
 
2530
| Floating-Point Arithmetic.
 
2531
*----------------------------------------------------------------------------*/
 
2532
float32 float32_log2( float32 a STATUS_PARAM )
 
2533
{
 
2534
    flag aSign, zSign;
 
2535
    int_fast16_t aExp;
 
2536
    uint32_t aSig, zSig, i;
 
2537
 
 
2538
    a = float32_squash_input_denormal(a STATUS_VAR);
 
2539
    aSig = extractFloat32Frac( a );
 
2540
    aExp = extractFloat32Exp( a );
 
2541
    aSign = extractFloat32Sign( a );
 
2542
 
 
2543
    if ( aExp == 0 ) {
 
2544
        if ( aSig == 0 ) return packFloat32( 1, 0xFF, 0 );
 
2545
        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
 
2546
    }
 
2547
    if ( aSign ) {
 
2548
        float_raise( float_flag_invalid STATUS_VAR);
 
2549
        return float32_default_nan;
 
2550
    }
 
2551
    if ( aExp == 0xFF ) {
 
2552
        if ( aSig ) return propagateFloat32NaN( a, float32_zero STATUS_VAR );
 
2553
        return a;
 
2554
    }
 
2555
 
 
2556
    aExp -= 0x7F;
 
2557
    aSig |= 0x00800000;
 
2558
    zSign = aExp < 0;
 
2559
    zSig = aExp << 23;
 
2560
 
 
2561
    for (i = 1 << 22; i > 0; i >>= 1) {
 
2562
        aSig = ( (uint64_t)aSig * aSig ) >> 23;
 
2563
        if ( aSig & 0x01000000 ) {
 
2564
            aSig >>= 1;
 
2565
            zSig |= i;
 
2566
        }
 
2567
    }
 
2568
 
 
2569
    if ( zSign )
 
2570
        zSig = -zSig;
 
2571
 
 
2572
    return normalizeRoundAndPackFloat32( zSign, 0x85, zSig STATUS_VAR );
 
2573
}
 
2574
 
 
2575
/*----------------------------------------------------------------------------
 
2576
| Returns 1 if the single-precision floating-point value `a' is equal to
 
2577
| the corresponding value `b', and 0 otherwise.  The invalid exception is
 
2578
| raised if either operand is a NaN.  Otherwise, the comparison is performed
 
2579
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
2580
*----------------------------------------------------------------------------*/
 
2581
 
 
2582
int float32_eq( float32 a, float32 b STATUS_PARAM )
 
2583
{
 
2584
    uint32_t av, bv;
 
2585
    a = float32_squash_input_denormal(a STATUS_VAR);
 
2586
    b = float32_squash_input_denormal(b STATUS_VAR);
 
2587
 
 
2588
    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
 
2589
         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
 
2590
       ) {
 
2591
        float_raise( float_flag_invalid STATUS_VAR);
 
2592
        return 0;
 
2593
    }
 
2594
    av = float32_val(a);
 
2595
    bv = float32_val(b);
 
2596
    return ( av == bv ) || ( (uint32_t) ( ( av | bv )<<1 ) == 0 );
 
2597
}
 
2598
 
 
2599
/*----------------------------------------------------------------------------
 
2600
| Returns 1 if the single-precision floating-point value `a' is less than
 
2601
| or equal to the corresponding value `b', and 0 otherwise.  The invalid
 
2602
| exception is raised if either operand is a NaN.  The comparison is performed
 
2603
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
2604
*----------------------------------------------------------------------------*/
 
2605
 
 
2606
int float32_le( float32 a, float32 b STATUS_PARAM )
 
2607
{
 
2608
    flag aSign, bSign;
 
2609
    uint32_t av, bv;
 
2610
    a = float32_squash_input_denormal(a STATUS_VAR);
 
2611
    b = float32_squash_input_denormal(b STATUS_VAR);
 
2612
 
 
2613
    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
 
2614
         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
 
2615
       ) {
 
2616
        float_raise( float_flag_invalid STATUS_VAR);
 
2617
        return 0;
 
2618
    }
 
2619
    aSign = extractFloat32Sign( a );
 
2620
    bSign = extractFloat32Sign( b );
 
2621
    av = float32_val(a);
 
2622
    bv = float32_val(b);
 
2623
    if ( aSign != bSign ) return aSign || ( (uint32_t) ( ( av | bv )<<1 ) == 0 );
 
2624
    return ( av == bv ) || ( aSign ^ ( av < bv ) );
 
2625
 
 
2626
}
 
2627
 
 
2628
/*----------------------------------------------------------------------------
 
2629
| Returns 1 if the single-precision floating-point value `a' is less than
 
2630
| the corresponding value `b', and 0 otherwise.  The invalid exception is
 
2631
| raised if either operand is a NaN.  The comparison is performed according
 
2632
| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
2633
*----------------------------------------------------------------------------*/
 
2634
 
 
2635
int float32_lt( float32 a, float32 b STATUS_PARAM )
 
2636
{
 
2637
    flag aSign, bSign;
 
2638
    uint32_t av, bv;
 
2639
    a = float32_squash_input_denormal(a STATUS_VAR);
 
2640
    b = float32_squash_input_denormal(b STATUS_VAR);
 
2641
 
 
2642
    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
 
2643
         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
 
2644
       ) {
 
2645
        float_raise( float_flag_invalid STATUS_VAR);
 
2646
        return 0;
 
2647
    }
 
2648
    aSign = extractFloat32Sign( a );
 
2649
    bSign = extractFloat32Sign( b );
 
2650
    av = float32_val(a);
 
2651
    bv = float32_val(b);
 
2652
    if ( aSign != bSign ) return aSign && ( (uint32_t) ( ( av | bv )<<1 ) != 0 );
 
2653
    return ( av != bv ) && ( aSign ^ ( av < bv ) );
 
2654
 
 
2655
}
 
2656
 
 
2657
/*----------------------------------------------------------------------------
 
2658
| Returns 1 if the single-precision floating-point values `a' and `b' cannot
 
2659
| be compared, and 0 otherwise.  The invalid exception is raised if either
 
2660
| operand is a NaN.  The comparison is performed according to the IEC/IEEE
 
2661
| Standard for Binary Floating-Point Arithmetic.
 
2662
*----------------------------------------------------------------------------*/
 
2663
 
 
2664
int float32_unordered( float32 a, float32 b STATUS_PARAM )
 
2665
{
 
2666
    a = float32_squash_input_denormal(a STATUS_VAR);
 
2667
    b = float32_squash_input_denormal(b STATUS_VAR);
 
2668
 
 
2669
    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
 
2670
         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
 
2671
       ) {
 
2672
        float_raise( float_flag_invalid STATUS_VAR);
 
2673
        return 1;
 
2674
    }
 
2675
    return 0;
 
2676
}
 
2677
 
 
2678
/*----------------------------------------------------------------------------
 
2679
| Returns 1 if the single-precision floating-point value `a' is equal to
 
2680
| the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
 
2681
| exception.  The comparison is performed according to the IEC/IEEE Standard
 
2682
| for Binary Floating-Point Arithmetic.
 
2683
*----------------------------------------------------------------------------*/
 
2684
 
 
2685
int float32_eq_quiet( float32 a, float32 b STATUS_PARAM )
 
2686
{
 
2687
    a = float32_squash_input_denormal(a STATUS_VAR);
 
2688
    b = float32_squash_input_denormal(b STATUS_VAR);
 
2689
 
 
2690
    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
 
2691
         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
 
2692
       ) {
 
2693
        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
 
2694
            float_raise( float_flag_invalid STATUS_VAR);
 
2695
        }
 
2696
        return 0;
 
2697
    }
 
2698
    return ( float32_val(a) == float32_val(b) ) ||
 
2699
            ( (uint32_t) ( ( float32_val(a) | float32_val(b) )<<1 ) == 0 );
 
2700
}
 
2701
 
 
2702
/*----------------------------------------------------------------------------
 
2703
| Returns 1 if the single-precision floating-point value `a' is less than or
 
2704
| equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
 
2705
| cause an exception.  Otherwise, the comparison is performed according to the
 
2706
| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
2707
*----------------------------------------------------------------------------*/
 
2708
 
 
2709
int float32_le_quiet( float32 a, float32 b STATUS_PARAM )
 
2710
{
 
2711
    flag aSign, bSign;
 
2712
    uint32_t av, bv;
 
2713
    a = float32_squash_input_denormal(a STATUS_VAR);
 
2714
    b = float32_squash_input_denormal(b STATUS_VAR);
 
2715
 
 
2716
    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
 
2717
         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
 
2718
       ) {
 
2719
        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
 
2720
            float_raise( float_flag_invalid STATUS_VAR);
 
2721
        }
 
2722
        return 0;
 
2723
    }
 
2724
    aSign = extractFloat32Sign( a );
 
2725
    bSign = extractFloat32Sign( b );
 
2726
    av = float32_val(a);
 
2727
    bv = float32_val(b);
 
2728
    if ( aSign != bSign ) return aSign || ( (uint32_t) ( ( av | bv )<<1 ) == 0 );
 
2729
    return ( av == bv ) || ( aSign ^ ( av < bv ) );
 
2730
 
 
2731
}
 
2732
 
 
2733
/*----------------------------------------------------------------------------
 
2734
| Returns 1 if the single-precision floating-point value `a' is less than
 
2735
| the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
 
2736
| exception.  Otherwise, the comparison is performed according to the IEC/IEEE
 
2737
| Standard for Binary Floating-Point Arithmetic.
 
2738
*----------------------------------------------------------------------------*/
 
2739
 
 
2740
int float32_lt_quiet( float32 a, float32 b STATUS_PARAM )
 
2741
{
 
2742
    flag aSign, bSign;
 
2743
    uint32_t av, bv;
 
2744
    a = float32_squash_input_denormal(a STATUS_VAR);
 
2745
    b = float32_squash_input_denormal(b STATUS_VAR);
 
2746
 
 
2747
    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
 
2748
         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
 
2749
       ) {
 
2750
        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
 
2751
            float_raise( float_flag_invalid STATUS_VAR);
 
2752
        }
 
2753
        return 0;
 
2754
    }
 
2755
    aSign = extractFloat32Sign( a );
 
2756
    bSign = extractFloat32Sign( b );
 
2757
    av = float32_val(a);
 
2758
    bv = float32_val(b);
 
2759
    if ( aSign != bSign ) return aSign && ( (uint32_t) ( ( av | bv )<<1 ) != 0 );
 
2760
    return ( av != bv ) && ( aSign ^ ( av < bv ) );
 
2761
 
 
2762
}
 
2763
 
 
2764
/*----------------------------------------------------------------------------
 
2765
| Returns 1 if the single-precision floating-point values `a' and `b' cannot
 
2766
| be compared, and 0 otherwise.  Quiet NaNs do not cause an exception.  The
 
2767
| comparison is performed according to the IEC/IEEE Standard for Binary
 
2768
| Floating-Point Arithmetic.
 
2769
*----------------------------------------------------------------------------*/
 
2770
 
 
2771
int float32_unordered_quiet( float32 a, float32 b STATUS_PARAM )
 
2772
{
 
2773
    a = float32_squash_input_denormal(a STATUS_VAR);
 
2774
    b = float32_squash_input_denormal(b STATUS_VAR);
 
2775
 
 
2776
    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
 
2777
         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
 
2778
       ) {
 
2779
        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
 
2780
            float_raise( float_flag_invalid STATUS_VAR);
 
2781
        }
 
2782
        return 1;
 
2783
    }
 
2784
    return 0;
 
2785
}
 
2786
 
 
2787
/*----------------------------------------------------------------------------
 
2788
| Returns the result of converting the double-precision floating-point value
 
2789
| `a' to the 32-bit two's complement integer format.  The conversion is
 
2790
| performed according to the IEC/IEEE Standard for Binary Floating-Point
 
2791
| Arithmetic---which means in particular that the conversion is rounded
 
2792
| according to the current rounding mode.  If `a' is a NaN, the largest
 
2793
| positive integer is returned.  Otherwise, if the conversion overflows, the
 
2794
| largest integer with the same sign as `a' is returned.
 
2795
*----------------------------------------------------------------------------*/
 
2796
 
 
2797
int32 float64_to_int32( float64 a STATUS_PARAM )
 
2798
{
 
2799
    flag aSign;
 
2800
    int_fast16_t aExp, shiftCount;
 
2801
    uint64_t aSig;
 
2802
    a = float64_squash_input_denormal(a STATUS_VAR);
 
2803
 
 
2804
    aSig = extractFloat64Frac( a );
 
2805
    aExp = extractFloat64Exp( a );
 
2806
    aSign = extractFloat64Sign( a );
 
2807
    if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
 
2808
    if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
 
2809
    shiftCount = 0x42C - aExp;
 
2810
    if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
 
2811
    return roundAndPackInt32( aSign, aSig STATUS_VAR );
 
2812
 
 
2813
}
 
2814
 
 
2815
/*----------------------------------------------------------------------------
 
2816
| Returns the result of converting the double-precision floating-point value
 
2817
| `a' to the 32-bit two's complement integer format.  The conversion is
 
2818
| performed according to the IEC/IEEE Standard for Binary Floating-Point
 
2819
| Arithmetic, except that the conversion is always rounded toward zero.
 
2820
| If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
 
2821
| the conversion overflows, the largest integer with the same sign as `a' is
 
2822
| returned.
 
2823
*----------------------------------------------------------------------------*/
 
2824
 
 
2825
int32 float64_to_int32_round_to_zero( float64 a STATUS_PARAM )
 
2826
{
 
2827
    flag aSign;
 
2828
    int_fast16_t aExp, shiftCount;
 
2829
    uint64_t aSig, savedASig;
 
2830
    int32_t z;
 
2831
    a = float64_squash_input_denormal(a STATUS_VAR);
 
2832
 
 
2833
    aSig = extractFloat64Frac( a );
 
2834
    aExp = extractFloat64Exp( a );
 
2835
    aSign = extractFloat64Sign( a );
 
2836
    if ( 0x41E < aExp ) {
 
2837
        if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
 
2838
        goto invalid;
 
2839
    }
 
2840
    else if ( aExp < 0x3FF ) {
 
2841
        if ( aExp || aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
 
2842
        return 0;
 
2843
    }
 
2844
    aSig |= LIT64( 0x0010000000000000 );
 
2845
    shiftCount = 0x433 - aExp;
 
2846
    savedASig = aSig;
 
2847
    aSig >>= shiftCount;
 
2848
    z = aSig;
 
2849
    if ( aSign ) z = - z;
 
2850
    if ( ( z < 0 ) ^ aSign ) {
 
2851
 invalid:
 
2852
        float_raise( float_flag_invalid STATUS_VAR);
 
2853
        return aSign ? (int32_t) 0x80000000 : 0x7FFFFFFF;
 
2854
    }
 
2855
    if ( ( aSig<<shiftCount ) != savedASig ) {
 
2856
        STATUS(float_exception_flags) |= float_flag_inexact;
 
2857
    }
 
2858
    return z;
 
2859
 
 
2860
}
 
2861
 
 
2862
/*----------------------------------------------------------------------------
 
2863
| Returns the result of converting the double-precision floating-point value
 
2864
| `a' to the 16-bit two's complement integer format.  The conversion is
 
2865
| performed according to the IEC/IEEE Standard for Binary Floating-Point
 
2866
| Arithmetic, except that the conversion is always rounded toward zero.
 
2867
| If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
 
2868
| the conversion overflows, the largest integer with the same sign as `a' is
 
2869
| returned.
 
2870
*----------------------------------------------------------------------------*/
 
2871
 
 
2872
int_fast16_t float64_to_int16_round_to_zero(float64 a STATUS_PARAM)
 
2873
{
 
2874
    flag aSign;
 
2875
    int_fast16_t aExp, shiftCount;
 
2876
    uint64_t aSig, savedASig;
 
2877
    int32 z;
 
2878
 
 
2879
    aSig = extractFloat64Frac( a );
 
2880
    aExp = extractFloat64Exp( a );
 
2881
    aSign = extractFloat64Sign( a );
 
2882
    if ( 0x40E < aExp ) {
 
2883
        if ( ( aExp == 0x7FF ) && aSig ) {
 
2884
            aSign = 0;
 
2885
        }
 
2886
        goto invalid;
 
2887
    }
 
2888
    else if ( aExp < 0x3FF ) {
 
2889
        if ( aExp || aSig ) {
 
2890
            STATUS(float_exception_flags) |= float_flag_inexact;
 
2891
        }
 
2892
        return 0;
 
2893
    }
 
2894
    aSig |= LIT64( 0x0010000000000000 );
 
2895
    shiftCount = 0x433 - aExp;
 
2896
    savedASig = aSig;
 
2897
    aSig >>= shiftCount;
 
2898
    z = aSig;
 
2899
    if ( aSign ) {
 
2900
        z = - z;
 
2901
    }
 
2902
    if ( ( (int16_t)z < 0 ) ^ aSign ) {
 
2903
 invalid:
 
2904
        float_raise( float_flag_invalid STATUS_VAR);
 
2905
        return aSign ? (int32_t) 0xffff8000 : 0x7FFF;
 
2906
    }
 
2907
    if ( ( aSig<<shiftCount ) != savedASig ) {
 
2908
        STATUS(float_exception_flags) |= float_flag_inexact;
 
2909
    }
 
2910
    return z;
 
2911
}
 
2912
 
 
2913
/*----------------------------------------------------------------------------
 
2914
| Returns the result of converting the double-precision floating-point value
 
2915
| `a' to the 64-bit two's complement integer format.  The conversion is
 
2916
| performed according to the IEC/IEEE Standard for Binary Floating-Point
 
2917
| Arithmetic---which means in particular that the conversion is rounded
 
2918
| according to the current rounding mode.  If `a' is a NaN, the largest
 
2919
| positive integer is returned.  Otherwise, if the conversion overflows, the
 
2920
| largest integer with the same sign as `a' is returned.
 
2921
*----------------------------------------------------------------------------*/
 
2922
 
 
2923
int64 float64_to_int64( float64 a STATUS_PARAM )
 
2924
{
 
2925
    flag aSign;
 
2926
    int_fast16_t aExp, shiftCount;
 
2927
    uint64_t aSig, aSigExtra;
 
2928
    a = float64_squash_input_denormal(a STATUS_VAR);
 
2929
 
 
2930
    aSig = extractFloat64Frac( a );
 
2931
    aExp = extractFloat64Exp( a );
 
2932
    aSign = extractFloat64Sign( a );
 
2933
    if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
 
2934
    shiftCount = 0x433 - aExp;
 
2935
    if ( shiftCount <= 0 ) {
 
2936
        if ( 0x43E < aExp ) {
 
2937
            float_raise( float_flag_invalid STATUS_VAR);
 
2938
            if (    ! aSign
 
2939
                 || (    ( aExp == 0x7FF )
 
2940
                      && ( aSig != LIT64( 0x0010000000000000 ) ) )
 
2941
               ) {
 
2942
                return LIT64( 0x7FFFFFFFFFFFFFFF );
 
2943
            }
 
2944
            return (int64_t) LIT64( 0x8000000000000000 );
 
2945
        }
 
2946
        aSigExtra = 0;
 
2947
        aSig <<= - shiftCount;
 
2948
    }
 
2949
    else {
 
2950
        shift64ExtraRightJamming( aSig, 0, shiftCount, &aSig, &aSigExtra );
 
2951
    }
 
2952
    return roundAndPackInt64( aSign, aSig, aSigExtra STATUS_VAR );
 
2953
 
 
2954
}
 
2955
 
 
2956
/*----------------------------------------------------------------------------
 
2957
| Returns the result of converting the double-precision floating-point value
 
2958
| `a' to the 64-bit two's complement integer format.  The conversion is
 
2959
| performed according to the IEC/IEEE Standard for Binary Floating-Point
 
2960
| Arithmetic, except that the conversion is always rounded toward zero.
 
2961
| If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
 
2962
| the conversion overflows, the largest integer with the same sign as `a' is
 
2963
| returned.
 
2964
*----------------------------------------------------------------------------*/
 
2965
 
 
2966
int64 float64_to_int64_round_to_zero( float64 a STATUS_PARAM )
 
2967
{
 
2968
    flag aSign;
 
2969
    int_fast16_t aExp, shiftCount;
 
2970
    uint64_t aSig;
 
2971
    int64 z;
 
2972
    a = float64_squash_input_denormal(a STATUS_VAR);
 
2973
 
 
2974
    aSig = extractFloat64Frac( a );
 
2975
    aExp = extractFloat64Exp( a );
 
2976
    aSign = extractFloat64Sign( a );
 
2977
    if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
 
2978
    shiftCount = aExp - 0x433;
 
2979
    if ( 0 <= shiftCount ) {
 
2980
        if ( 0x43E <= aExp ) {
 
2981
            if ( float64_val(a) != LIT64( 0xC3E0000000000000 ) ) {
 
2982
                float_raise( float_flag_invalid STATUS_VAR);
 
2983
                if (    ! aSign
 
2984
                     || (    ( aExp == 0x7FF )
 
2985
                          && ( aSig != LIT64( 0x0010000000000000 ) ) )
 
2986
                   ) {
 
2987
                    return LIT64( 0x7FFFFFFFFFFFFFFF );
 
2988
                }
 
2989
            }
 
2990
            return (int64_t) LIT64( 0x8000000000000000 );
 
2991
        }
 
2992
        z = aSig<<shiftCount;
 
2993
    }
 
2994
    else {
 
2995
        if ( aExp < 0x3FE ) {
 
2996
            if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
 
2997
            return 0;
 
2998
        }
 
2999
        z = aSig>>( - shiftCount );
 
3000
        if ( (uint64_t) ( aSig<<( shiftCount & 63 ) ) ) {
 
3001
            STATUS(float_exception_flags) |= float_flag_inexact;
 
3002
        }
 
3003
    }
 
3004
    if ( aSign ) z = - z;
 
3005
    return z;
 
3006
 
 
3007
}
 
3008
 
 
3009
/*----------------------------------------------------------------------------
 
3010
| Returns the result of converting the double-precision floating-point value
 
3011
| `a' to the single-precision floating-point format.  The conversion is
 
3012
| performed according to the IEC/IEEE Standard for Binary Floating-Point
 
3013
| Arithmetic.
 
3014
*----------------------------------------------------------------------------*/
 
3015
 
 
3016
float32 float64_to_float32( float64 a STATUS_PARAM )
 
3017
{
 
3018
    flag aSign;
 
3019
    int_fast16_t aExp;
 
3020
    uint64_t aSig;
 
3021
    uint32_t zSig;
 
3022
    a = float64_squash_input_denormal(a STATUS_VAR);
 
3023
 
 
3024
    aSig = extractFloat64Frac( a );
 
3025
    aExp = extractFloat64Exp( a );
 
3026
    aSign = extractFloat64Sign( a );
 
3027
    if ( aExp == 0x7FF ) {
 
3028
        if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
 
3029
        return packFloat32( aSign, 0xFF, 0 );
 
3030
    }
 
3031
    shift64RightJamming( aSig, 22, &aSig );
 
3032
    zSig = aSig;
 
3033
    if ( aExp || zSig ) {
 
3034
        zSig |= 0x40000000;
 
3035
        aExp -= 0x381;
 
3036
    }
 
3037
    return roundAndPackFloat32( aSign, aExp, zSig STATUS_VAR );
 
3038
 
 
3039
}
 
3040
 
 
3041
 
 
3042
/*----------------------------------------------------------------------------
 
3043
| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
 
3044
| half-precision floating-point value, returning the result.  After being
 
3045
| shifted into the proper positions, the three fields are simply added
 
3046
| together to form the result.  This means that any integer portion of `zSig'
 
3047
| will be added into the exponent.  Since a properly normalized significand
 
3048
| will have an integer portion equal to 1, the `zExp' input should be 1 less
 
3049
| than the desired result exponent whenever `zSig' is a complete, normalized
 
3050
| significand.
 
3051
*----------------------------------------------------------------------------*/
 
3052
static float16 packFloat16(flag zSign, int_fast16_t zExp, uint16_t zSig)
 
3053
{
 
3054
    return make_float16(
 
3055
        (((uint32_t)zSign) << 15) + (((uint32_t)zExp) << 10) + zSig);
 
3056
}
 
3057
 
 
3058
/* Half precision floats come in two formats: standard IEEE and "ARM" format.
 
3059
   The latter gains extra exponent range by omitting the NaN/Inf encodings.  */
 
3060
 
 
3061
float32 float16_to_float32(float16 a, flag ieee STATUS_PARAM)
 
3062
{
 
3063
    flag aSign;
 
3064
    int_fast16_t aExp;
 
3065
    uint32_t aSig;
 
3066
 
 
3067
    aSign = extractFloat16Sign(a);
 
3068
    aExp = extractFloat16Exp(a);
 
3069
    aSig = extractFloat16Frac(a);
 
3070
 
 
3071
    if (aExp == 0x1f && ieee) {
 
3072
        if (aSig) {
 
3073
            return commonNaNToFloat32(float16ToCommonNaN(a STATUS_VAR) STATUS_VAR);
 
3074
        }
 
3075
        return packFloat32(aSign, 0xff, 0);
 
3076
    }
 
3077
    if (aExp == 0) {
 
3078
        int8 shiftCount;
 
3079
 
 
3080
        if (aSig == 0) {
 
3081
            return packFloat32(aSign, 0, 0);
 
3082
        }
 
3083
 
 
3084
        shiftCount = countLeadingZeros32( aSig ) - 21;
 
3085
        aSig = aSig << shiftCount;
 
3086
        aExp = -shiftCount;
 
3087
    }
 
3088
    return packFloat32( aSign, aExp + 0x70, aSig << 13);
 
3089
}
 
3090
 
 
3091
float16 float32_to_float16(float32 a, flag ieee STATUS_PARAM)
 
3092
{
 
3093
    flag aSign;
 
3094
    int_fast16_t aExp;
 
3095
    uint32_t aSig;
 
3096
    uint32_t mask;
 
3097
    uint32_t increment;
 
3098
    int8 roundingMode;
 
3099
    int maxexp = ieee ? 15 : 16;
 
3100
    bool rounding_bumps_exp;
 
3101
    bool is_tiny = false;
 
3102
 
 
3103
    a = float32_squash_input_denormal(a STATUS_VAR);
 
3104
 
 
3105
    aSig = extractFloat32Frac( a );
 
3106
    aExp = extractFloat32Exp( a );
 
3107
    aSign = extractFloat32Sign( a );
 
3108
    if ( aExp == 0xFF ) {
 
3109
        if (aSig) {
 
3110
            /* Input is a NaN */
 
3111
            if (!ieee) {
 
3112
                float_raise(float_flag_invalid STATUS_VAR);
 
3113
                return packFloat16(aSign, 0, 0);
 
3114
            }
 
3115
            return commonNaNToFloat16(
 
3116
                float32ToCommonNaN(a STATUS_VAR) STATUS_VAR);
 
3117
        }
 
3118
        /* Infinity */
 
3119
        if (!ieee) {
 
3120
            float_raise(float_flag_invalid STATUS_VAR);
 
3121
            return packFloat16(aSign, 0x1f, 0x3ff);
 
3122
        }
 
3123
        return packFloat16(aSign, 0x1f, 0);
 
3124
    }
 
3125
    if (aExp == 0 && aSig == 0) {
 
3126
        return packFloat16(aSign, 0, 0);
 
3127
    }
 
3128
    /* Decimal point between bits 22 and 23. Note that we add the 1 bit
 
3129
     * even if the input is denormal; however this is harmless because
 
3130
     * the largest possible single-precision denormal is still smaller
 
3131
     * than the smallest representable half-precision denormal, and so we
 
3132
     * will end up ignoring aSig and returning via the "always return zero"
 
3133
     * codepath.
 
3134
     */
 
3135
    aSig |= 0x00800000;
 
3136
    aExp -= 0x7f;
 
3137
    /* Calculate the mask of bits of the mantissa which are not
 
3138
     * representable in half-precision and will be lost.
 
3139
     */
 
3140
    if (aExp < -14) {
 
3141
        /* Will be denormal in halfprec */
 
3142
        mask = 0x00ffffff;
 
3143
        if (aExp >= -24) {
 
3144
            mask >>= 25 + aExp;
 
3145
        }
 
3146
    } else {
 
3147
        /* Normal number in halfprec */
 
3148
        mask = 0x00001fff;
 
3149
    }
 
3150
 
 
3151
    roundingMode = STATUS(float_rounding_mode);
 
3152
    switch (roundingMode) {
 
3153
    case float_round_nearest_even:
 
3154
        increment = (mask + 1) >> 1;
 
3155
        if ((aSig & mask) == increment) {
 
3156
            increment = aSig & (increment << 1);
 
3157
        }
 
3158
        break;
 
3159
    case float_round_up:
 
3160
        increment = aSign ? 0 : mask;
 
3161
        break;
 
3162
    case float_round_down:
 
3163
        increment = aSign ? mask : 0;
 
3164
        break;
 
3165
    default: /* round_to_zero */
 
3166
        increment = 0;
 
3167
        break;
 
3168
    }
 
3169
 
 
3170
    rounding_bumps_exp = (aSig + increment >= 0x01000000);
 
3171
 
 
3172
    if (aExp > maxexp || (aExp == maxexp && rounding_bumps_exp)) {
 
3173
        if (ieee) {
 
3174
            float_raise(float_flag_overflow | float_flag_inexact STATUS_VAR);
 
3175
            return packFloat16(aSign, 0x1f, 0);
 
3176
        } else {
 
3177
            float_raise(float_flag_invalid STATUS_VAR);
 
3178
            return packFloat16(aSign, 0x1f, 0x3ff);
 
3179
        }
 
3180
    }
 
3181
 
 
3182
    if (aExp < -14) {
 
3183
        /* Note that flush-to-zero does not affect half-precision results */
 
3184
        is_tiny =
 
3185
            (STATUS(float_detect_tininess) == float_tininess_before_rounding)
 
3186
            || (aExp < -15)
 
3187
            || (!rounding_bumps_exp);
 
3188
    }
 
3189
    if (aSig & mask) {
 
3190
        float_raise(float_flag_inexact STATUS_VAR);
 
3191
        if (is_tiny) {
 
3192
            float_raise(float_flag_underflow STATUS_VAR);
 
3193
        }
 
3194
    }
 
3195
 
 
3196
    aSig += increment;
 
3197
    if (rounding_bumps_exp) {
 
3198
        aSig >>= 1;
 
3199
        aExp++;
 
3200
    }
 
3201
 
 
3202
    if (aExp < -24) {
 
3203
        return packFloat16(aSign, 0, 0);
 
3204
    }
 
3205
    if (aExp < -14) {
 
3206
        aSig >>= -14 - aExp;
 
3207
        aExp = -14;
 
3208
    }
 
3209
    return packFloat16(aSign, aExp + 14, aSig >> 13);
 
3210
}
 
3211
 
 
3212
/*----------------------------------------------------------------------------
 
3213
| Returns the result of converting the double-precision floating-point value
 
3214
| `a' to the extended double-precision floating-point format.  The conversion
 
3215
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
 
3216
| Arithmetic.
 
3217
*----------------------------------------------------------------------------*/
 
3218
 
 
3219
floatx80 float64_to_floatx80( float64 a STATUS_PARAM )
 
3220
{
 
3221
    flag aSign;
 
3222
    int_fast16_t aExp;
 
3223
    uint64_t aSig;
 
3224
 
 
3225
    a = float64_squash_input_denormal(a STATUS_VAR);
 
3226
    aSig = extractFloat64Frac( a );
 
3227
    aExp = extractFloat64Exp( a );
 
3228
    aSign = extractFloat64Sign( a );
 
3229
    if ( aExp == 0x7FF ) {
 
3230
        if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
 
3231
        return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
 
3232
    }
 
3233
    if ( aExp == 0 ) {
 
3234
        if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
 
3235
        normalizeFloat64Subnormal( aSig, &aExp, &aSig );
 
3236
    }
 
3237
    return
 
3238
        packFloatx80(
 
3239
            aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 );
 
3240
 
 
3241
}
 
3242
 
 
3243
/*----------------------------------------------------------------------------
 
3244
| Returns the result of converting the double-precision floating-point value
 
3245
| `a' to the quadruple-precision floating-point format.  The conversion is
 
3246
| performed according to the IEC/IEEE Standard for Binary Floating-Point
 
3247
| Arithmetic.
 
3248
*----------------------------------------------------------------------------*/
 
3249
 
 
3250
float128 float64_to_float128( float64 a STATUS_PARAM )
 
3251
{
 
3252
    flag aSign;
 
3253
    int_fast16_t aExp;
 
3254
    uint64_t aSig, zSig0, zSig1;
 
3255
 
 
3256
    a = float64_squash_input_denormal(a STATUS_VAR);
 
3257
    aSig = extractFloat64Frac( a );
 
3258
    aExp = extractFloat64Exp( a );
 
3259
    aSign = extractFloat64Sign( a );
 
3260
    if ( aExp == 0x7FF ) {
 
3261
        if ( aSig ) return commonNaNToFloat128( float64ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
 
3262
        return packFloat128( aSign, 0x7FFF, 0, 0 );
 
3263
    }
 
3264
    if ( aExp == 0 ) {
 
3265
        if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 );
 
3266
        normalizeFloat64Subnormal( aSig, &aExp, &aSig );
 
3267
        --aExp;
 
3268
    }
 
3269
    shift128Right( aSig, 0, 4, &zSig0, &zSig1 );
 
3270
    return packFloat128( aSign, aExp + 0x3C00, zSig0, zSig1 );
 
3271
 
 
3272
}
 
3273
 
 
3274
/*----------------------------------------------------------------------------
 
3275
| Rounds the double-precision floating-point value `a' to an integer, and
 
3276
| returns the result as a double-precision floating-point value.  The
 
3277
| operation is performed according to the IEC/IEEE Standard for Binary
 
3278
| Floating-Point Arithmetic.
 
3279
*----------------------------------------------------------------------------*/
 
3280
 
 
3281
float64 float64_round_to_int( float64 a STATUS_PARAM )
 
3282
{
 
3283
    flag aSign;
 
3284
    int_fast16_t aExp;
 
3285
    uint64_t lastBitMask, roundBitsMask;
 
3286
    int8 roundingMode;
 
3287
    uint64_t z;
 
3288
    a = float64_squash_input_denormal(a STATUS_VAR);
 
3289
 
 
3290
    aExp = extractFloat64Exp( a );
 
3291
    if ( 0x433 <= aExp ) {
 
3292
        if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) {
 
3293
            return propagateFloat64NaN( a, a STATUS_VAR );
 
3294
        }
 
3295
        return a;
 
3296
    }
 
3297
    if ( aExp < 0x3FF ) {
 
3298
        if ( (uint64_t) ( float64_val(a)<<1 ) == 0 ) return a;
 
3299
        STATUS(float_exception_flags) |= float_flag_inexact;
 
3300
        aSign = extractFloat64Sign( a );
 
3301
        switch ( STATUS(float_rounding_mode) ) {
 
3302
         case float_round_nearest_even:
 
3303
            if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) {
 
3304
                return packFloat64( aSign, 0x3FF, 0 );
 
3305
            }
 
3306
            break;
 
3307
         case float_round_down:
 
3308
            return make_float64(aSign ? LIT64( 0xBFF0000000000000 ) : 0);
 
3309
         case float_round_up:
 
3310
            return make_float64(
 
3311
            aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 ));
 
3312
        }
 
3313
        return packFloat64( aSign, 0, 0 );
 
3314
    }
 
3315
    lastBitMask = 1;
 
3316
    lastBitMask <<= 0x433 - aExp;
 
3317
    roundBitsMask = lastBitMask - 1;
 
3318
    z = float64_val(a);
 
3319
    roundingMode = STATUS(float_rounding_mode);
 
3320
    if ( roundingMode == float_round_nearest_even ) {
 
3321
        z += lastBitMask>>1;
 
3322
        if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
 
3323
    }
 
3324
    else if ( roundingMode != float_round_to_zero ) {
 
3325
        if ( extractFloat64Sign( make_float64(z) ) ^ ( roundingMode == float_round_up ) ) {
 
3326
            z += roundBitsMask;
 
3327
        }
 
3328
    }
 
3329
    z &= ~ roundBitsMask;
 
3330
    if ( z != float64_val(a) )
 
3331
        STATUS(float_exception_flags) |= float_flag_inexact;
 
3332
    return make_float64(z);
 
3333
 
 
3334
}
 
3335
 
 
3336
float64 float64_trunc_to_int( float64 a STATUS_PARAM)
 
3337
{
 
3338
    int oldmode;
 
3339
    float64 res;
 
3340
    oldmode = STATUS(float_rounding_mode);
 
3341
    STATUS(float_rounding_mode) = float_round_to_zero;
 
3342
    res = float64_round_to_int(a STATUS_VAR);
 
3343
    STATUS(float_rounding_mode) = oldmode;
 
3344
    return res;
 
3345
}
 
3346
 
 
3347
/*----------------------------------------------------------------------------
 
3348
| Returns the result of adding the absolute values of the double-precision
 
3349
| floating-point values `a' and `b'.  If `zSign' is 1, the sum is negated
 
3350
| before being returned.  `zSign' is ignored if the result is a NaN.
 
3351
| The addition is performed according to the IEC/IEEE Standard for Binary
 
3352
| Floating-Point Arithmetic.
 
3353
*----------------------------------------------------------------------------*/
 
3354
 
 
3355
static float64 addFloat64Sigs( float64 a, float64 b, flag zSign STATUS_PARAM )
 
3356
{
 
3357
    int_fast16_t aExp, bExp, zExp;
 
3358
    uint64_t aSig, bSig, zSig;
 
3359
    int_fast16_t expDiff;
 
3360
 
 
3361
    aSig = extractFloat64Frac( a );
 
3362
    aExp = extractFloat64Exp( a );
 
3363
    bSig = extractFloat64Frac( b );
 
3364
    bExp = extractFloat64Exp( b );
 
3365
    expDiff = aExp - bExp;
 
3366
    aSig <<= 9;
 
3367
    bSig <<= 9;
 
3368
    if ( 0 < expDiff ) {
 
3369
        if ( aExp == 0x7FF ) {
 
3370
            if ( aSig ) return propagateFloat64NaN( a, b STATUS_VAR );
 
3371
            return a;
 
3372
        }
 
3373
        if ( bExp == 0 ) {
 
3374
            --expDiff;
 
3375
        }
 
3376
        else {
 
3377
            bSig |= LIT64( 0x2000000000000000 );
 
3378
        }
 
3379
        shift64RightJamming( bSig, expDiff, &bSig );
 
3380
        zExp = aExp;
 
3381
    }
 
3382
    else if ( expDiff < 0 ) {
 
3383
        if ( bExp == 0x7FF ) {
 
3384
            if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
 
3385
            return packFloat64( zSign, 0x7FF, 0 );
 
3386
        }
 
3387
        if ( aExp == 0 ) {
 
3388
            ++expDiff;
 
3389
        }
 
3390
        else {
 
3391
            aSig |= LIT64( 0x2000000000000000 );
 
3392
        }
 
3393
        shift64RightJamming( aSig, - expDiff, &aSig );
 
3394
        zExp = bExp;
 
3395
    }
 
3396
    else {
 
3397
        if ( aExp == 0x7FF ) {
 
3398
            if ( aSig | bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
 
3399
            return a;
 
3400
        }
 
3401
        if ( aExp == 0 ) {
 
3402
            if (STATUS(flush_to_zero)) {
 
3403
                if (aSig | bSig) {
 
3404
                    float_raise(float_flag_output_denormal STATUS_VAR);
 
3405
                }
 
3406
                return packFloat64(zSign, 0, 0);
 
3407
            }
 
3408
            return packFloat64( zSign, 0, ( aSig + bSig )>>9 );
 
3409
        }
 
3410
        zSig = LIT64( 0x4000000000000000 ) + aSig + bSig;
 
3411
        zExp = aExp;
 
3412
        goto roundAndPack;
 
3413
    }
 
3414
    aSig |= LIT64( 0x2000000000000000 );
 
3415
    zSig = ( aSig + bSig )<<1;
 
3416
    --zExp;
 
3417
    if ( (int64_t) zSig < 0 ) {
 
3418
        zSig = aSig + bSig;
 
3419
        ++zExp;
 
3420
    }
 
3421
 roundAndPack:
 
3422
    return roundAndPackFloat64( zSign, zExp, zSig STATUS_VAR );
 
3423
 
 
3424
}
 
3425
 
 
3426
/*----------------------------------------------------------------------------
 
3427
| Returns the result of subtracting the absolute values of the double-
 
3428
| precision floating-point values `a' and `b'.  If `zSign' is 1, the
 
3429
| difference is negated before being returned.  `zSign' is ignored if the
 
3430
| result is a NaN.  The subtraction is performed according to the IEC/IEEE
 
3431
| Standard for Binary Floating-Point Arithmetic.
 
3432
*----------------------------------------------------------------------------*/
 
3433
 
 
3434
static float64 subFloat64Sigs( float64 a, float64 b, flag zSign STATUS_PARAM )
 
3435
{
 
3436
    int_fast16_t aExp, bExp, zExp;
 
3437
    uint64_t aSig, bSig, zSig;
 
3438
    int_fast16_t expDiff;
 
3439
 
 
3440
    aSig = extractFloat64Frac( a );
 
3441
    aExp = extractFloat64Exp( a );
 
3442
    bSig = extractFloat64Frac( b );
 
3443
    bExp = extractFloat64Exp( b );
 
3444
    expDiff = aExp - bExp;
 
3445
    aSig <<= 10;
 
3446
    bSig <<= 10;
 
3447
    if ( 0 < expDiff ) goto aExpBigger;
 
3448
    if ( expDiff < 0 ) goto bExpBigger;
 
3449
    if ( aExp == 0x7FF ) {
 
3450
        if ( aSig | bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
 
3451
        float_raise( float_flag_invalid STATUS_VAR);
 
3452
        return float64_default_nan;
 
3453
    }
 
3454
    if ( aExp == 0 ) {
 
3455
        aExp = 1;
 
3456
        bExp = 1;
 
3457
    }
 
3458
    if ( bSig < aSig ) goto aBigger;
 
3459
    if ( aSig < bSig ) goto bBigger;
 
3460
    return packFloat64( STATUS(float_rounding_mode) == float_round_down, 0, 0 );
 
3461
 bExpBigger:
 
3462
    if ( bExp == 0x7FF ) {
 
3463
        if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
 
3464
        return packFloat64( zSign ^ 1, 0x7FF, 0 );
 
3465
    }
 
3466
    if ( aExp == 0 ) {
 
3467
        ++expDiff;
 
3468
    }
 
3469
    else {
 
3470
        aSig |= LIT64( 0x4000000000000000 );
 
3471
    }
 
3472
    shift64RightJamming( aSig, - expDiff, &aSig );
 
3473
    bSig |= LIT64( 0x4000000000000000 );
 
3474
 bBigger:
 
3475
    zSig = bSig - aSig;
 
3476
    zExp = bExp;
 
3477
    zSign ^= 1;
 
3478
    goto normalizeRoundAndPack;
 
3479
 aExpBigger:
 
3480
    if ( aExp == 0x7FF ) {
 
3481
        if ( aSig ) return propagateFloat64NaN( a, b STATUS_VAR );
 
3482
        return a;
 
3483
    }
 
3484
    if ( bExp == 0 ) {
 
3485
        --expDiff;
 
3486
    }
 
3487
    else {
 
3488
        bSig |= LIT64( 0x4000000000000000 );
 
3489
    }
 
3490
    shift64RightJamming( bSig, expDiff, &bSig );
 
3491
    aSig |= LIT64( 0x4000000000000000 );
 
3492
 aBigger:
 
3493
    zSig = aSig - bSig;
 
3494
    zExp = aExp;
 
3495
 normalizeRoundAndPack:
 
3496
    --zExp;
 
3497
    return normalizeRoundAndPackFloat64( zSign, zExp, zSig STATUS_VAR );
 
3498
 
 
3499
}
 
3500
 
 
3501
/*----------------------------------------------------------------------------
 
3502
| Returns the result of adding the double-precision floating-point values `a'
 
3503
| and `b'.  The operation is performed according to the IEC/IEEE Standard for
 
3504
| Binary Floating-Point Arithmetic.
 
3505
*----------------------------------------------------------------------------*/
 
3506
 
 
3507
float64 float64_add( float64 a, float64 b STATUS_PARAM )
 
3508
{
 
3509
    flag aSign, bSign;
 
3510
    a = float64_squash_input_denormal(a STATUS_VAR);
 
3511
    b = float64_squash_input_denormal(b STATUS_VAR);
 
3512
 
 
3513
    aSign = extractFloat64Sign( a );
 
3514
    bSign = extractFloat64Sign( b );
 
3515
    if ( aSign == bSign ) {
 
3516
        return addFloat64Sigs( a, b, aSign STATUS_VAR );
 
3517
    }
 
3518
    else {
 
3519
        return subFloat64Sigs( a, b, aSign STATUS_VAR );
 
3520
    }
 
3521
 
 
3522
}
 
3523
 
 
3524
/*----------------------------------------------------------------------------
 
3525
| Returns the result of subtracting the double-precision floating-point values
 
3526
| `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
 
3527
| for Binary Floating-Point Arithmetic.
 
3528
*----------------------------------------------------------------------------*/
 
3529
 
 
3530
float64 float64_sub( float64 a, float64 b STATUS_PARAM )
 
3531
{
 
3532
    flag aSign, bSign;
 
3533
    a = float64_squash_input_denormal(a STATUS_VAR);
 
3534
    b = float64_squash_input_denormal(b STATUS_VAR);
 
3535
 
 
3536
    aSign = extractFloat64Sign( a );
 
3537
    bSign = extractFloat64Sign( b );
 
3538
    if ( aSign == bSign ) {
 
3539
        return subFloat64Sigs( a, b, aSign STATUS_VAR );
 
3540
    }
 
3541
    else {
 
3542
        return addFloat64Sigs( a, b, aSign STATUS_VAR );
 
3543
    }
 
3544
 
 
3545
}
 
3546
 
 
3547
/*----------------------------------------------------------------------------
 
3548
| Returns the result of multiplying the double-precision floating-point values
 
3549
| `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
 
3550
| for Binary Floating-Point Arithmetic.
 
3551
*----------------------------------------------------------------------------*/
 
3552
 
 
3553
float64 float64_mul( float64 a, float64 b STATUS_PARAM )
 
3554
{
 
3555
    flag aSign, bSign, zSign;
 
3556
    int_fast16_t aExp, bExp, zExp;
 
3557
    uint64_t aSig, bSig, zSig0, zSig1;
 
3558
 
 
3559
    a = float64_squash_input_denormal(a STATUS_VAR);
 
3560
    b = float64_squash_input_denormal(b STATUS_VAR);
 
3561
 
 
3562
    aSig = extractFloat64Frac( a );
 
3563
    aExp = extractFloat64Exp( a );
 
3564
    aSign = extractFloat64Sign( a );
 
3565
    bSig = extractFloat64Frac( b );
 
3566
    bExp = extractFloat64Exp( b );
 
3567
    bSign = extractFloat64Sign( b );
 
3568
    zSign = aSign ^ bSign;
 
3569
    if ( aExp == 0x7FF ) {
 
3570
        if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
 
3571
            return propagateFloat64NaN( a, b STATUS_VAR );
 
3572
        }
 
3573
        if ( ( bExp | bSig ) == 0 ) {
 
3574
            float_raise( float_flag_invalid STATUS_VAR);
 
3575
            return float64_default_nan;
 
3576
        }
 
3577
        return packFloat64( zSign, 0x7FF, 0 );
 
3578
    }
 
3579
    if ( bExp == 0x7FF ) {
 
3580
        if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
 
3581
        if ( ( aExp | aSig ) == 0 ) {
 
3582
            float_raise( float_flag_invalid STATUS_VAR);
 
3583
            return float64_default_nan;
 
3584
        }
 
3585
        return packFloat64( zSign, 0x7FF, 0 );
 
3586
    }
 
3587
    if ( aExp == 0 ) {
 
3588
        if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
 
3589
        normalizeFloat64Subnormal( aSig, &aExp, &aSig );
 
3590
    }
 
3591
    if ( bExp == 0 ) {
 
3592
        if ( bSig == 0 ) return packFloat64( zSign, 0, 0 );
 
3593
        normalizeFloat64Subnormal( bSig, &bExp, &bSig );
 
3594
    }
 
3595
    zExp = aExp + bExp - 0x3FF;
 
3596
    aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
 
3597
    bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
 
3598
    mul64To128( aSig, bSig, &zSig0, &zSig1 );
 
3599
    zSig0 |= ( zSig1 != 0 );
 
3600
    if ( 0 <= (int64_t) ( zSig0<<1 ) ) {
 
3601
        zSig0 <<= 1;
 
3602
        --zExp;
 
3603
    }
 
3604
    return roundAndPackFloat64( zSign, zExp, zSig0 STATUS_VAR );
 
3605
 
 
3606
}
 
3607
 
 
3608
/*----------------------------------------------------------------------------
 
3609
| Returns the result of dividing the double-precision floating-point value `a'
 
3610
| by the corresponding value `b'.  The operation is performed according to
 
3611
| the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
3612
*----------------------------------------------------------------------------*/
 
3613
 
 
3614
float64 float64_div( float64 a, float64 b STATUS_PARAM )
 
3615
{
 
3616
    flag aSign, bSign, zSign;
 
3617
    int_fast16_t aExp, bExp, zExp;
 
3618
    uint64_t aSig, bSig, zSig;
 
3619
    uint64_t rem0, rem1;
 
3620
    uint64_t term0, term1;
 
3621
    a = float64_squash_input_denormal(a STATUS_VAR);
 
3622
    b = float64_squash_input_denormal(b STATUS_VAR);
 
3623
 
 
3624
    aSig = extractFloat64Frac( a );
 
3625
    aExp = extractFloat64Exp( a );
 
3626
    aSign = extractFloat64Sign( a );
 
3627
    bSig = extractFloat64Frac( b );
 
3628
    bExp = extractFloat64Exp( b );
 
3629
    bSign = extractFloat64Sign( b );
 
3630
    zSign = aSign ^ bSign;
 
3631
    if ( aExp == 0x7FF ) {
 
3632
        if ( aSig ) return propagateFloat64NaN( a, b STATUS_VAR );
 
3633
        if ( bExp == 0x7FF ) {
 
3634
            if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
 
3635
            float_raise( float_flag_invalid STATUS_VAR);
 
3636
            return float64_default_nan;
 
3637
        }
 
3638
        return packFloat64( zSign, 0x7FF, 0 );
 
3639
    }
 
3640
    if ( bExp == 0x7FF ) {
 
3641
        if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
 
3642
        return packFloat64( zSign, 0, 0 );
 
3643
    }
 
3644
    if ( bExp == 0 ) {
 
3645
        if ( bSig == 0 ) {
 
3646
            if ( ( aExp | aSig ) == 0 ) {
 
3647
                float_raise( float_flag_invalid STATUS_VAR);
 
3648
                return float64_default_nan;
 
3649
            }
 
3650
            float_raise( float_flag_divbyzero STATUS_VAR);
 
3651
            return packFloat64( zSign, 0x7FF, 0 );
 
3652
        }
 
3653
        normalizeFloat64Subnormal( bSig, &bExp, &bSig );
 
3654
    }
 
3655
    if ( aExp == 0 ) {
 
3656
        if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
 
3657
        normalizeFloat64Subnormal( aSig, &aExp, &aSig );
 
3658
    }
 
3659
    zExp = aExp - bExp + 0x3FD;
 
3660
    aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
 
3661
    bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
 
3662
    if ( bSig <= ( aSig + aSig ) ) {
 
3663
        aSig >>= 1;
 
3664
        ++zExp;
 
3665
    }
 
3666
    zSig = estimateDiv128To64( aSig, 0, bSig );
 
3667
    if ( ( zSig & 0x1FF ) <= 2 ) {
 
3668
        mul64To128( bSig, zSig, &term0, &term1 );
 
3669
        sub128( aSig, 0, term0, term1, &rem0, &rem1 );
 
3670
        while ( (int64_t) rem0 < 0 ) {
 
3671
            --zSig;
 
3672
            add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
 
3673
        }
 
3674
        zSig |= ( rem1 != 0 );
 
3675
    }
 
3676
    return roundAndPackFloat64( zSign, zExp, zSig STATUS_VAR );
 
3677
 
 
3678
}
 
3679
 
 
3680
/*----------------------------------------------------------------------------
 
3681
| Returns the remainder of the double-precision floating-point value `a'
 
3682
| with respect to the corresponding value `b'.  The operation is performed
 
3683
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
3684
*----------------------------------------------------------------------------*/
 
3685
 
 
3686
float64 float64_rem( float64 a, float64 b STATUS_PARAM )
 
3687
{
 
3688
    flag aSign, zSign;
 
3689
    int_fast16_t aExp, bExp, expDiff;
 
3690
    uint64_t aSig, bSig;
 
3691
    uint64_t q, alternateASig;
 
3692
    int64_t sigMean;
 
3693
 
 
3694
    a = float64_squash_input_denormal(a STATUS_VAR);
 
3695
    b = float64_squash_input_denormal(b STATUS_VAR);
 
3696
    aSig = extractFloat64Frac( a );
 
3697
    aExp = extractFloat64Exp( a );
 
3698
    aSign = extractFloat64Sign( a );
 
3699
    bSig = extractFloat64Frac( b );
 
3700
    bExp = extractFloat64Exp( b );
 
3701
    if ( aExp == 0x7FF ) {
 
3702
        if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
 
3703
            return propagateFloat64NaN( a, b STATUS_VAR );
 
3704
        }
 
3705
        float_raise( float_flag_invalid STATUS_VAR);
 
3706
        return float64_default_nan;
 
3707
    }
 
3708
    if ( bExp == 0x7FF ) {
 
3709
        if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
 
3710
        return a;
 
3711
    }
 
3712
    if ( bExp == 0 ) {
 
3713
        if ( bSig == 0 ) {
 
3714
            float_raise( float_flag_invalid STATUS_VAR);
 
3715
            return float64_default_nan;
 
3716
        }
 
3717
        normalizeFloat64Subnormal( bSig, &bExp, &bSig );
 
3718
    }
 
3719
    if ( aExp == 0 ) {
 
3720
        if ( aSig == 0 ) return a;
 
3721
        normalizeFloat64Subnormal( aSig, &aExp, &aSig );
 
3722
    }
 
3723
    expDiff = aExp - bExp;
 
3724
    aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<11;
 
3725
    bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
 
3726
    if ( expDiff < 0 ) {
 
3727
        if ( expDiff < -1 ) return a;
 
3728
        aSig >>= 1;
 
3729
    }
 
3730
    q = ( bSig <= aSig );
 
3731
    if ( q ) aSig -= bSig;
 
3732
    expDiff -= 64;
 
3733
    while ( 0 < expDiff ) {
 
3734
        q = estimateDiv128To64( aSig, 0, bSig );
 
3735
        q = ( 2 < q ) ? q - 2 : 0;
 
3736
        aSig = - ( ( bSig>>2 ) * q );
 
3737
        expDiff -= 62;
 
3738
    }
 
3739
    expDiff += 64;
 
3740
    if ( 0 < expDiff ) {
 
3741
        q = estimateDiv128To64( aSig, 0, bSig );
 
3742
        q = ( 2 < q ) ? q - 2 : 0;
 
3743
        q >>= 64 - expDiff;
 
3744
        bSig >>= 2;
 
3745
        aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
 
3746
    }
 
3747
    else {
 
3748
        aSig >>= 2;
 
3749
        bSig >>= 2;
 
3750
    }
 
3751
    do {
 
3752
        alternateASig = aSig;
 
3753
        ++q;
 
3754
        aSig -= bSig;
 
3755
    } while ( 0 <= (int64_t) aSig );
 
3756
    sigMean = aSig + alternateASig;
 
3757
    if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
 
3758
        aSig = alternateASig;
 
3759
    }
 
3760
    zSign = ( (int64_t) aSig < 0 );
 
3761
    if ( zSign ) aSig = - aSig;
 
3762
    return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig STATUS_VAR );
 
3763
 
 
3764
}
 
3765
 
 
3766
/*----------------------------------------------------------------------------
 
3767
| Returns the result of multiplying the double-precision floating-point values
 
3768
| `a' and `b' then adding 'c', with no intermediate rounding step after the
 
3769
| multiplication.  The operation is performed according to the IEC/IEEE
 
3770
| Standard for Binary Floating-Point Arithmetic 754-2008.
 
3771
| The flags argument allows the caller to select negation of the
 
3772
| addend, the intermediate product, or the final result. (The difference
 
3773
| between this and having the caller do a separate negation is that negating
 
3774
| externally will flip the sign bit on NaNs.)
 
3775
*----------------------------------------------------------------------------*/
 
3776
 
 
3777
float64 float64_muladd(float64 a, float64 b, float64 c, int flags STATUS_PARAM)
 
3778
{
 
3779
    flag aSign, bSign, cSign, zSign;
 
3780
    int_fast16_t aExp, bExp, cExp, pExp, zExp, expDiff;
 
3781
    uint64_t aSig, bSig, cSig;
 
3782
    flag pInf, pZero, pSign;
 
3783
    uint64_t pSig0, pSig1, cSig0, cSig1, zSig0, zSig1;
 
3784
    int shiftcount;
 
3785
    flag signflip, infzero;
 
3786
 
 
3787
    a = float64_squash_input_denormal(a STATUS_VAR);
 
3788
    b = float64_squash_input_denormal(b STATUS_VAR);
 
3789
    c = float64_squash_input_denormal(c STATUS_VAR);
 
3790
    aSig = extractFloat64Frac(a);
 
3791
    aExp = extractFloat64Exp(a);
 
3792
    aSign = extractFloat64Sign(a);
 
3793
    bSig = extractFloat64Frac(b);
 
3794
    bExp = extractFloat64Exp(b);
 
3795
    bSign = extractFloat64Sign(b);
 
3796
    cSig = extractFloat64Frac(c);
 
3797
    cExp = extractFloat64Exp(c);
 
3798
    cSign = extractFloat64Sign(c);
 
3799
 
 
3800
    infzero = ((aExp == 0 && aSig == 0 && bExp == 0x7ff && bSig == 0) ||
 
3801
               (aExp == 0x7ff && aSig == 0 && bExp == 0 && bSig == 0));
 
3802
 
 
3803
    /* It is implementation-defined whether the cases of (0,inf,qnan)
 
3804
     * and (inf,0,qnan) raise InvalidOperation or not (and what QNaN
 
3805
     * they return if they do), so we have to hand this information
 
3806
     * off to the target-specific pick-a-NaN routine.
 
3807
     */
 
3808
    if (((aExp == 0x7ff) && aSig) ||
 
3809
        ((bExp == 0x7ff) && bSig) ||
 
3810
        ((cExp == 0x7ff) && cSig)) {
 
3811
        return propagateFloat64MulAddNaN(a, b, c, infzero STATUS_VAR);
 
3812
    }
 
3813
 
 
3814
    if (infzero) {
 
3815
        float_raise(float_flag_invalid STATUS_VAR);
 
3816
        return float64_default_nan;
 
3817
    }
 
3818
 
 
3819
    if (flags & float_muladd_negate_c) {
 
3820
        cSign ^= 1;
 
3821
    }
 
3822
 
 
3823
    signflip = (flags & float_muladd_negate_result) ? 1 : 0;
 
3824
 
 
3825
    /* Work out the sign and type of the product */
 
3826
    pSign = aSign ^ bSign;
 
3827
    if (flags & float_muladd_negate_product) {
 
3828
        pSign ^= 1;
 
3829
    }
 
3830
    pInf = (aExp == 0x7ff) || (bExp == 0x7ff);
 
3831
    pZero = ((aExp | aSig) == 0) || ((bExp | bSig) == 0);
 
3832
 
 
3833
    if (cExp == 0x7ff) {
 
3834
        if (pInf && (pSign ^ cSign)) {
 
3835
            /* addition of opposite-signed infinities => InvalidOperation */
 
3836
            float_raise(float_flag_invalid STATUS_VAR);
 
3837
            return float64_default_nan;
 
3838
        }
 
3839
        /* Otherwise generate an infinity of the same sign */
 
3840
        return packFloat64(cSign ^ signflip, 0x7ff, 0);
 
3841
    }
 
3842
 
 
3843
    if (pInf) {
 
3844
        return packFloat64(pSign ^ signflip, 0x7ff, 0);
 
3845
    }
 
3846
 
 
3847
    if (pZero) {
 
3848
        if (cExp == 0) {
 
3849
            if (cSig == 0) {
 
3850
                /* Adding two exact zeroes */
 
3851
                if (pSign == cSign) {
 
3852
                    zSign = pSign;
 
3853
                } else if (STATUS(float_rounding_mode) == float_round_down) {
 
3854
                    zSign = 1;
 
3855
                } else {
 
3856
                    zSign = 0;
 
3857
                }
 
3858
                return packFloat64(zSign ^ signflip, 0, 0);
 
3859
            }
 
3860
            /* Exact zero plus a denorm */
 
3861
            if (STATUS(flush_to_zero)) {
 
3862
                float_raise(float_flag_output_denormal STATUS_VAR);
 
3863
                return packFloat64(cSign ^ signflip, 0, 0);
 
3864
            }
 
3865
        }
 
3866
        /* Zero plus something non-zero : just return the something */
 
3867
        return packFloat64(cSign ^ signflip, cExp, cSig);
 
3868
    }
 
3869
 
 
3870
    if (aExp == 0) {
 
3871
        normalizeFloat64Subnormal(aSig, &aExp, &aSig);
 
3872
    }
 
3873
    if (bExp == 0) {
 
3874
        normalizeFloat64Subnormal(bSig, &bExp, &bSig);
 
3875
    }
 
3876
 
 
3877
    /* Calculate the actual result a * b + c */
 
3878
 
 
3879
    /* Multiply first; this is easy. */
 
3880
    /* NB: we subtract 0x3fe where float64_mul() subtracts 0x3ff
 
3881
     * because we want the true exponent, not the "one-less-than"
 
3882
     * flavour that roundAndPackFloat64() takes.
 
3883
     */
 
3884
    pExp = aExp + bExp - 0x3fe;
 
3885
    aSig = (aSig | LIT64(0x0010000000000000))<<10;
 
3886
    bSig = (bSig | LIT64(0x0010000000000000))<<11;
 
3887
    mul64To128(aSig, bSig, &pSig0, &pSig1);
 
3888
    if ((int64_t)(pSig0 << 1) >= 0) {
 
3889
        shortShift128Left(pSig0, pSig1, 1, &pSig0, &pSig1);
 
3890
        pExp--;
 
3891
    }
 
3892
 
 
3893
    zSign = pSign ^ signflip;
 
3894
 
 
3895
    /* Now [pSig0:pSig1] is the significand of the multiply, with the explicit
 
3896
     * bit in position 126.
 
3897
     */
 
3898
    if (cExp == 0) {
 
3899
        if (!cSig) {
 
3900
            /* Throw out the special case of c being an exact zero now */
 
3901
            shift128RightJamming(pSig0, pSig1, 64, &pSig0, &pSig1);
 
3902
            return roundAndPackFloat64(zSign, pExp - 1,
 
3903
                                       pSig1 STATUS_VAR);
 
3904
        }
 
3905
        normalizeFloat64Subnormal(cSig, &cExp, &cSig);
 
3906
    }
 
3907
 
 
3908
    /* Shift cSig and add the explicit bit so [cSig0:cSig1] is the
 
3909
     * significand of the addend, with the explicit bit in position 126.
 
3910
     */
 
3911
    cSig0 = cSig << (126 - 64 - 52);
 
3912
    cSig1 = 0;
 
3913
    cSig0 |= LIT64(0x4000000000000000);
 
3914
    expDiff = pExp - cExp;
 
3915
 
 
3916
    if (pSign == cSign) {
 
3917
        /* Addition */
 
3918
        if (expDiff > 0) {
 
3919
            /* scale c to match p */
 
3920
            shift128RightJamming(cSig0, cSig1, expDiff, &cSig0, &cSig1);
 
3921
            zExp = pExp;
 
3922
        } else if (expDiff < 0) {
 
3923
            /* scale p to match c */
 
3924
            shift128RightJamming(pSig0, pSig1, -expDiff, &pSig0, &pSig1);
 
3925
            zExp = cExp;
 
3926
        } else {
 
3927
            /* no scaling needed */
 
3928
            zExp = cExp;
 
3929
        }
 
3930
        /* Add significands and make sure explicit bit ends up in posn 126 */
 
3931
        add128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1);
 
3932
        if ((int64_t)zSig0 < 0) {
 
3933
            shift128RightJamming(zSig0, zSig1, 1, &zSig0, &zSig1);
 
3934
        } else {
 
3935
            zExp--;
 
3936
        }
 
3937
        shift128RightJamming(zSig0, zSig1, 64, &zSig0, &zSig1);
 
3938
        return roundAndPackFloat64(zSign, zExp, zSig1 STATUS_VAR);
 
3939
    } else {
 
3940
        /* Subtraction */
 
3941
        if (expDiff > 0) {
 
3942
            shift128RightJamming(cSig0, cSig1, expDiff, &cSig0, &cSig1);
 
3943
            sub128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1);
 
3944
            zExp = pExp;
 
3945
        } else if (expDiff < 0) {
 
3946
            shift128RightJamming(pSig0, pSig1, -expDiff, &pSig0, &pSig1);
 
3947
            sub128(cSig0, cSig1, pSig0, pSig1, &zSig0, &zSig1);
 
3948
            zExp = cExp;
 
3949
            zSign ^= 1;
 
3950
        } else {
 
3951
            zExp = pExp;
 
3952
            if (lt128(cSig0, cSig1, pSig0, pSig1)) {
 
3953
                sub128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1);
 
3954
            } else if (lt128(pSig0, pSig1, cSig0, cSig1)) {
 
3955
                sub128(cSig0, cSig1, pSig0, pSig1, &zSig0, &zSig1);
 
3956
                zSign ^= 1;
 
3957
            } else {
 
3958
                /* Exact zero */
 
3959
                zSign = signflip;
 
3960
                if (STATUS(float_rounding_mode) == float_round_down) {
 
3961
                    zSign ^= 1;
 
3962
                }
 
3963
                return packFloat64(zSign, 0, 0);
 
3964
            }
 
3965
        }
 
3966
        --zExp;
 
3967
        /* Do the equivalent of normalizeRoundAndPackFloat64() but
 
3968
         * starting with the significand in a pair of uint64_t.
 
3969
         */
 
3970
        if (zSig0) {
 
3971
            shiftcount = countLeadingZeros64(zSig0) - 1;
 
3972
            shortShift128Left(zSig0, zSig1, shiftcount, &zSig0, &zSig1);
 
3973
            if (zSig1) {
 
3974
                zSig0 |= 1;
 
3975
            }
 
3976
            zExp -= shiftcount;
 
3977
        } else {
 
3978
            shiftcount = countLeadingZeros64(zSig1);
 
3979
            if (shiftcount == 0) {
 
3980
                zSig0 = (zSig1 >> 1) | (zSig1 & 1);
 
3981
                zExp -= 63;
 
3982
            } else {
 
3983
                shiftcount--;
 
3984
                zSig0 = zSig1 << shiftcount;
 
3985
                zExp -= (shiftcount + 64);
 
3986
            }
 
3987
        }
 
3988
        return roundAndPackFloat64(zSign, zExp, zSig0 STATUS_VAR);
 
3989
    }
 
3990
}
 
3991
 
 
3992
/*----------------------------------------------------------------------------
 
3993
| Returns the square root of the double-precision floating-point value `a'.
 
3994
| The operation is performed according to the IEC/IEEE Standard for Binary
 
3995
| Floating-Point Arithmetic.
 
3996
*----------------------------------------------------------------------------*/
 
3997
 
 
3998
float64 float64_sqrt( float64 a STATUS_PARAM )
 
3999
{
 
4000
    flag aSign;
 
4001
    int_fast16_t aExp, zExp;
 
4002
    uint64_t aSig, zSig, doubleZSig;
 
4003
    uint64_t rem0, rem1, term0, term1;
 
4004
    a = float64_squash_input_denormal(a STATUS_VAR);
 
4005
 
 
4006
    aSig = extractFloat64Frac( a );
 
4007
    aExp = extractFloat64Exp( a );
 
4008
    aSign = extractFloat64Sign( a );
 
4009
    if ( aExp == 0x7FF ) {
 
4010
        if ( aSig ) return propagateFloat64NaN( a, a STATUS_VAR );
 
4011
        if ( ! aSign ) return a;
 
4012
        float_raise( float_flag_invalid STATUS_VAR);
 
4013
        return float64_default_nan;
 
4014
    }
 
4015
    if ( aSign ) {
 
4016
        if ( ( aExp | aSig ) == 0 ) return a;
 
4017
        float_raise( float_flag_invalid STATUS_VAR);
 
4018
        return float64_default_nan;
 
4019
    }
 
4020
    if ( aExp == 0 ) {
 
4021
        if ( aSig == 0 ) return float64_zero;
 
4022
        normalizeFloat64Subnormal( aSig, &aExp, &aSig );
 
4023
    }
 
4024
    zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE;
 
4025
    aSig |= LIT64( 0x0010000000000000 );
 
4026
    zSig = estimateSqrt32( aExp, aSig>>21 );
 
4027
    aSig <<= 9 - ( aExp & 1 );
 
4028
    zSig = estimateDiv128To64( aSig, 0, zSig<<32 ) + ( zSig<<30 );
 
4029
    if ( ( zSig & 0x1FF ) <= 5 ) {
 
4030
        doubleZSig = zSig<<1;
 
4031
        mul64To128( zSig, zSig, &term0, &term1 );
 
4032
        sub128( aSig, 0, term0, term1, &rem0, &rem1 );
 
4033
        while ( (int64_t) rem0 < 0 ) {
 
4034
            --zSig;
 
4035
            doubleZSig -= 2;
 
4036
            add128( rem0, rem1, zSig>>63, doubleZSig | 1, &rem0, &rem1 );
 
4037
        }
 
4038
        zSig |= ( ( rem0 | rem1 ) != 0 );
 
4039
    }
 
4040
    return roundAndPackFloat64( 0, zExp, zSig STATUS_VAR );
 
4041
 
 
4042
}
 
4043
 
 
4044
/*----------------------------------------------------------------------------
 
4045
| Returns the binary log of the double-precision floating-point value `a'.
 
4046
| The operation is performed according to the IEC/IEEE Standard for Binary
 
4047
| Floating-Point Arithmetic.
 
4048
*----------------------------------------------------------------------------*/
 
4049
float64 float64_log2( float64 a STATUS_PARAM )
 
4050
{
 
4051
    flag aSign, zSign;
 
4052
    int_fast16_t aExp;
 
4053
    uint64_t aSig, aSig0, aSig1, zSig, i;
 
4054
    a = float64_squash_input_denormal(a STATUS_VAR);
 
4055
 
 
4056
    aSig = extractFloat64Frac( a );
 
4057
    aExp = extractFloat64Exp( a );
 
4058
    aSign = extractFloat64Sign( a );
 
4059
 
 
4060
    if ( aExp == 0 ) {
 
4061
        if ( aSig == 0 ) return packFloat64( 1, 0x7FF, 0 );
 
4062
        normalizeFloat64Subnormal( aSig, &aExp, &aSig );
 
4063
    }
 
4064
    if ( aSign ) {
 
4065
        float_raise( float_flag_invalid STATUS_VAR);
 
4066
        return float64_default_nan;
 
4067
    }
 
4068
    if ( aExp == 0x7FF ) {
 
4069
        if ( aSig ) return propagateFloat64NaN( a, float64_zero STATUS_VAR );
 
4070
        return a;
 
4071
    }
 
4072
 
 
4073
    aExp -= 0x3FF;
 
4074
    aSig |= LIT64( 0x0010000000000000 );
 
4075
    zSign = aExp < 0;
 
4076
    zSig = (uint64_t)aExp << 52;
 
4077
    for (i = 1LL << 51; i > 0; i >>= 1) {
 
4078
        mul64To128( aSig, aSig, &aSig0, &aSig1 );
 
4079
        aSig = ( aSig0 << 12 ) | ( aSig1 >> 52 );
 
4080
        if ( aSig & LIT64( 0x0020000000000000 ) ) {
 
4081
            aSig >>= 1;
 
4082
            zSig |= i;
 
4083
        }
 
4084
    }
 
4085
 
 
4086
    if ( zSign )
 
4087
        zSig = -zSig;
 
4088
    return normalizeRoundAndPackFloat64( zSign, 0x408, zSig STATUS_VAR );
 
4089
}
 
4090
 
 
4091
/*----------------------------------------------------------------------------
 
4092
| Returns 1 if the double-precision floating-point value `a' is equal to the
 
4093
| corresponding value `b', and 0 otherwise.  The invalid exception is raised
 
4094
| if either operand is a NaN.  Otherwise, the comparison is performed
 
4095
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
4096
*----------------------------------------------------------------------------*/
 
4097
 
 
4098
int float64_eq( float64 a, float64 b STATUS_PARAM )
 
4099
{
 
4100
    uint64_t av, bv;
 
4101
    a = float64_squash_input_denormal(a STATUS_VAR);
 
4102
    b = float64_squash_input_denormal(b STATUS_VAR);
 
4103
 
 
4104
    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
 
4105
         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
 
4106
       ) {
 
4107
        float_raise( float_flag_invalid STATUS_VAR);
 
4108
        return 0;
 
4109
    }
 
4110
    av = float64_val(a);
 
4111
    bv = float64_val(b);
 
4112
    return ( av == bv ) || ( (uint64_t) ( ( av | bv )<<1 ) == 0 );
 
4113
 
 
4114
}
 
4115
 
 
4116
/*----------------------------------------------------------------------------
 
4117
| Returns 1 if the double-precision floating-point value `a' is less than or
 
4118
| equal to the corresponding value `b', and 0 otherwise.  The invalid
 
4119
| exception is raised if either operand is a NaN.  The comparison is performed
 
4120
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
4121
*----------------------------------------------------------------------------*/
 
4122
 
 
4123
int float64_le( float64 a, float64 b STATUS_PARAM )
 
4124
{
 
4125
    flag aSign, bSign;
 
4126
    uint64_t av, bv;
 
4127
    a = float64_squash_input_denormal(a STATUS_VAR);
 
4128
    b = float64_squash_input_denormal(b STATUS_VAR);
 
4129
 
 
4130
    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
 
4131
         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
 
4132
       ) {
 
4133
        float_raise( float_flag_invalid STATUS_VAR);
 
4134
        return 0;
 
4135
    }
 
4136
    aSign = extractFloat64Sign( a );
 
4137
    bSign = extractFloat64Sign( b );
 
4138
    av = float64_val(a);
 
4139
    bv = float64_val(b);
 
4140
    if ( aSign != bSign ) return aSign || ( (uint64_t) ( ( av | bv )<<1 ) == 0 );
 
4141
    return ( av == bv ) || ( aSign ^ ( av < bv ) );
 
4142
 
 
4143
}
 
4144
 
 
4145
/*----------------------------------------------------------------------------
 
4146
| Returns 1 if the double-precision floating-point value `a' is less than
 
4147
| the corresponding value `b', and 0 otherwise.  The invalid exception is
 
4148
| raised if either operand is a NaN.  The comparison is performed according
 
4149
| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
4150
*----------------------------------------------------------------------------*/
 
4151
 
 
4152
int float64_lt( float64 a, float64 b STATUS_PARAM )
 
4153
{
 
4154
    flag aSign, bSign;
 
4155
    uint64_t av, bv;
 
4156
 
 
4157
    a = float64_squash_input_denormal(a STATUS_VAR);
 
4158
    b = float64_squash_input_denormal(b STATUS_VAR);
 
4159
    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
 
4160
         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
 
4161
       ) {
 
4162
        float_raise( float_flag_invalid STATUS_VAR);
 
4163
        return 0;
 
4164
    }
 
4165
    aSign = extractFloat64Sign( a );
 
4166
    bSign = extractFloat64Sign( b );
 
4167
    av = float64_val(a);
 
4168
    bv = float64_val(b);
 
4169
    if ( aSign != bSign ) return aSign && ( (uint64_t) ( ( av | bv )<<1 ) != 0 );
 
4170
    return ( av != bv ) && ( aSign ^ ( av < bv ) );
 
4171
 
 
4172
}
 
4173
 
 
4174
/*----------------------------------------------------------------------------
 
4175
| Returns 1 if the double-precision floating-point values `a' and `b' cannot
 
4176
| be compared, and 0 otherwise.  The invalid exception is raised if either
 
4177
| operand is a NaN.  The comparison is performed according to the IEC/IEEE
 
4178
| Standard for Binary Floating-Point Arithmetic.
 
4179
*----------------------------------------------------------------------------*/
 
4180
 
 
4181
int float64_unordered( float64 a, float64 b STATUS_PARAM )
 
4182
{
 
4183
    a = float64_squash_input_denormal(a STATUS_VAR);
 
4184
    b = float64_squash_input_denormal(b STATUS_VAR);
 
4185
 
 
4186
    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
 
4187
         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
 
4188
       ) {
 
4189
        float_raise( float_flag_invalid STATUS_VAR);
 
4190
        return 1;
 
4191
    }
 
4192
    return 0;
 
4193
}
 
4194
 
 
4195
/*----------------------------------------------------------------------------
 
4196
| Returns 1 if the double-precision floating-point value `a' is equal to the
 
4197
| corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
 
4198
| exception.The comparison is performed according to the IEC/IEEE Standard
 
4199
| for Binary Floating-Point Arithmetic.
 
4200
*----------------------------------------------------------------------------*/
 
4201
 
 
4202
int float64_eq_quiet( float64 a, float64 b STATUS_PARAM )
 
4203
{
 
4204
    uint64_t av, bv;
 
4205
    a = float64_squash_input_denormal(a STATUS_VAR);
 
4206
    b = float64_squash_input_denormal(b STATUS_VAR);
 
4207
 
 
4208
    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
 
4209
         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
 
4210
       ) {
 
4211
        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
 
4212
            float_raise( float_flag_invalid STATUS_VAR);
 
4213
        }
 
4214
        return 0;
 
4215
    }
 
4216
    av = float64_val(a);
 
4217
    bv = float64_val(b);
 
4218
    return ( av == bv ) || ( (uint64_t) ( ( av | bv )<<1 ) == 0 );
 
4219
 
 
4220
}
 
4221
 
 
4222
/*----------------------------------------------------------------------------
 
4223
| Returns 1 if the double-precision floating-point value `a' is less than or
 
4224
| equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
 
4225
| cause an exception.  Otherwise, the comparison is performed according to the
 
4226
| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
4227
*----------------------------------------------------------------------------*/
 
4228
 
 
4229
int float64_le_quiet( float64 a, float64 b STATUS_PARAM )
 
4230
{
 
4231
    flag aSign, bSign;
 
4232
    uint64_t av, bv;
 
4233
    a = float64_squash_input_denormal(a STATUS_VAR);
 
4234
    b = float64_squash_input_denormal(b STATUS_VAR);
 
4235
 
 
4236
    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
 
4237
         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
 
4238
       ) {
 
4239
        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
 
4240
            float_raise( float_flag_invalid STATUS_VAR);
 
4241
        }
 
4242
        return 0;
 
4243
    }
 
4244
    aSign = extractFloat64Sign( a );
 
4245
    bSign = extractFloat64Sign( b );
 
4246
    av = float64_val(a);
 
4247
    bv = float64_val(b);
 
4248
    if ( aSign != bSign ) return aSign || ( (uint64_t) ( ( av | bv )<<1 ) == 0 );
 
4249
    return ( av == bv ) || ( aSign ^ ( av < bv ) );
 
4250
 
 
4251
}
 
4252
 
 
4253
/*----------------------------------------------------------------------------
 
4254
| Returns 1 if the double-precision floating-point value `a' is less than
 
4255
| the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
 
4256
| exception.  Otherwise, the comparison is performed according to the IEC/IEEE
 
4257
| Standard for Binary Floating-Point Arithmetic.
 
4258
*----------------------------------------------------------------------------*/
 
4259
 
 
4260
int float64_lt_quiet( float64 a, float64 b STATUS_PARAM )
 
4261
{
 
4262
    flag aSign, bSign;
 
4263
    uint64_t av, bv;
 
4264
    a = float64_squash_input_denormal(a STATUS_VAR);
 
4265
    b = float64_squash_input_denormal(b STATUS_VAR);
 
4266
 
 
4267
    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
 
4268
         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
 
4269
       ) {
 
4270
        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
 
4271
            float_raise( float_flag_invalid STATUS_VAR);
 
4272
        }
 
4273
        return 0;
 
4274
    }
 
4275
    aSign = extractFloat64Sign( a );
 
4276
    bSign = extractFloat64Sign( b );
 
4277
    av = float64_val(a);
 
4278
    bv = float64_val(b);
 
4279
    if ( aSign != bSign ) return aSign && ( (uint64_t) ( ( av | bv )<<1 ) != 0 );
 
4280
    return ( av != bv ) && ( aSign ^ ( av < bv ) );
 
4281
 
 
4282
}
 
4283
 
 
4284
/*----------------------------------------------------------------------------
 
4285
| Returns 1 if the double-precision floating-point values `a' and `b' cannot
 
4286
| be compared, and 0 otherwise.  Quiet NaNs do not cause an exception.  The
 
4287
| comparison is performed according to the IEC/IEEE Standard for Binary
 
4288
| Floating-Point Arithmetic.
 
4289
*----------------------------------------------------------------------------*/
 
4290
 
 
4291
int float64_unordered_quiet( float64 a, float64 b STATUS_PARAM )
 
4292
{
 
4293
    a = float64_squash_input_denormal(a STATUS_VAR);
 
4294
    b = float64_squash_input_denormal(b STATUS_VAR);
 
4295
 
 
4296
    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
 
4297
         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
 
4298
       ) {
 
4299
        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
 
4300
            float_raise( float_flag_invalid STATUS_VAR);
 
4301
        }
 
4302
        return 1;
 
4303
    }
 
4304
    return 0;
 
4305
}
 
4306
 
 
4307
/*----------------------------------------------------------------------------
 
4308
| Returns the result of converting the extended double-precision floating-
 
4309
| point value `a' to the 32-bit two's complement integer format.  The
 
4310
| conversion is performed according to the IEC/IEEE Standard for Binary
 
4311
| Floating-Point Arithmetic---which means in particular that the conversion
 
4312
| is rounded according to the current rounding mode.  If `a' is a NaN, the
 
4313
| largest positive integer is returned.  Otherwise, if the conversion
 
4314
| overflows, the largest integer with the same sign as `a' is returned.
 
4315
*----------------------------------------------------------------------------*/
 
4316
 
 
4317
int32 floatx80_to_int32( floatx80 a STATUS_PARAM )
 
4318
{
 
4319
    flag aSign;
 
4320
    int32 aExp, shiftCount;
 
4321
    uint64_t aSig;
 
4322
 
 
4323
    aSig = extractFloatx80Frac( a );
 
4324
    aExp = extractFloatx80Exp( a );
 
4325
    aSign = extractFloatx80Sign( a );
 
4326
    if ( ( aExp == 0x7FFF ) && (uint64_t) ( aSig<<1 ) ) aSign = 0;
 
4327
    shiftCount = 0x4037 - aExp;
 
4328
    if ( shiftCount <= 0 ) shiftCount = 1;
 
4329
    shift64RightJamming( aSig, shiftCount, &aSig );
 
4330
    return roundAndPackInt32( aSign, aSig STATUS_VAR );
 
4331
 
 
4332
}
 
4333
 
 
4334
/*----------------------------------------------------------------------------
 
4335
| Returns the result of converting the extended double-precision floating-
 
4336
| point value `a' to the 32-bit two's complement integer format.  The
 
4337
| conversion is performed according to the IEC/IEEE Standard for Binary
 
4338
| Floating-Point Arithmetic, except that the conversion is always rounded
 
4339
| toward zero.  If `a' is a NaN, the largest positive integer is returned.
 
4340
| Otherwise, if the conversion overflows, the largest integer with the same
 
4341
| sign as `a' is returned.
 
4342
*----------------------------------------------------------------------------*/
 
4343
 
 
4344
int32 floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM )
 
4345
{
 
4346
    flag aSign;
 
4347
    int32 aExp, shiftCount;
 
4348
    uint64_t aSig, savedASig;
 
4349
    int32_t z;
 
4350
 
 
4351
    aSig = extractFloatx80Frac( a );
 
4352
    aExp = extractFloatx80Exp( a );
 
4353
    aSign = extractFloatx80Sign( a );
 
4354
    if ( 0x401E < aExp ) {
 
4355
        if ( ( aExp == 0x7FFF ) && (uint64_t) ( aSig<<1 ) ) aSign = 0;
 
4356
        goto invalid;
 
4357
    }
 
4358
    else if ( aExp < 0x3FFF ) {
 
4359
        if ( aExp || aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
 
4360
        return 0;
 
4361
    }
 
4362
    shiftCount = 0x403E - aExp;
 
4363
    savedASig = aSig;
 
4364
    aSig >>= shiftCount;
 
4365
    z = aSig;
 
4366
    if ( aSign ) z = - z;
 
4367
    if ( ( z < 0 ) ^ aSign ) {
 
4368
 invalid:
 
4369
        float_raise( float_flag_invalid STATUS_VAR);
 
4370
        return aSign ? (int32_t) 0x80000000 : 0x7FFFFFFF;
 
4371
    }
 
4372
    if ( ( aSig<<shiftCount ) != savedASig ) {
 
4373
        STATUS(float_exception_flags) |= float_flag_inexact;
 
4374
    }
 
4375
    return z;
 
4376
 
 
4377
}
 
4378
 
 
4379
/*----------------------------------------------------------------------------
 
4380
| Returns the result of converting the extended double-precision floating-
 
4381
| point value `a' to the 64-bit two's complement integer format.  The
 
4382
| conversion is performed according to the IEC/IEEE Standard for Binary
 
4383
| Floating-Point Arithmetic---which means in particular that the conversion
 
4384
| is rounded according to the current rounding mode.  If `a' is a NaN,
 
4385
| the largest positive integer is returned.  Otherwise, if the conversion
 
4386
| overflows, the largest integer with the same sign as `a' is returned.
 
4387
*----------------------------------------------------------------------------*/
 
4388
 
 
4389
int64 floatx80_to_int64( floatx80 a STATUS_PARAM )
 
4390
{
 
4391
    flag aSign;
 
4392
    int32 aExp, shiftCount;
 
4393
    uint64_t aSig, aSigExtra;
 
4394
 
 
4395
    aSig = extractFloatx80Frac( a );
 
4396
    aExp = extractFloatx80Exp( a );
 
4397
    aSign = extractFloatx80Sign( a );
 
4398
    shiftCount = 0x403E - aExp;
 
4399
    if ( shiftCount <= 0 ) {
 
4400
        if ( shiftCount ) {
 
4401
            float_raise( float_flag_invalid STATUS_VAR);
 
4402
            if (    ! aSign
 
4403
                 || (    ( aExp == 0x7FFF )
 
4404
                      && ( aSig != LIT64( 0x8000000000000000 ) ) )
 
4405
               ) {
 
4406
                return LIT64( 0x7FFFFFFFFFFFFFFF );
 
4407
            }
 
4408
            return (int64_t) LIT64( 0x8000000000000000 );
 
4409
        }
 
4410
        aSigExtra = 0;
 
4411
    }
 
4412
    else {
 
4413
        shift64ExtraRightJamming( aSig, 0, shiftCount, &aSig, &aSigExtra );
 
4414
    }
 
4415
    return roundAndPackInt64( aSign, aSig, aSigExtra STATUS_VAR );
 
4416
 
 
4417
}
 
4418
 
 
4419
/*----------------------------------------------------------------------------
 
4420
| Returns the result of converting the extended double-precision floating-
 
4421
| point value `a' to the 64-bit two's complement integer format.  The
 
4422
| conversion is performed according to the IEC/IEEE Standard for Binary
 
4423
| Floating-Point Arithmetic, except that the conversion is always rounded
 
4424
| toward zero.  If `a' is a NaN, the largest positive integer is returned.
 
4425
| Otherwise, if the conversion overflows, the largest integer with the same
 
4426
| sign as `a' is returned.
 
4427
*----------------------------------------------------------------------------*/
 
4428
 
 
4429
int64 floatx80_to_int64_round_to_zero( floatx80 a STATUS_PARAM )
 
4430
{
 
4431
    flag aSign;
 
4432
    int32 aExp, shiftCount;
 
4433
    uint64_t aSig;
 
4434
    int64 z;
 
4435
 
 
4436
    aSig = extractFloatx80Frac( a );
 
4437
    aExp = extractFloatx80Exp( a );
 
4438
    aSign = extractFloatx80Sign( a );
 
4439
    shiftCount = aExp - 0x403E;
 
4440
    if ( 0 <= shiftCount ) {
 
4441
        aSig &= LIT64( 0x7FFFFFFFFFFFFFFF );
 
4442
        if ( ( a.high != 0xC03E ) || aSig ) {
 
4443
            float_raise( float_flag_invalid STATUS_VAR);
 
4444
            if ( ! aSign || ( ( aExp == 0x7FFF ) && aSig ) ) {
 
4445
                return LIT64( 0x7FFFFFFFFFFFFFFF );
 
4446
            }
 
4447
        }
 
4448
        return (int64_t) LIT64( 0x8000000000000000 );
 
4449
    }
 
4450
    else if ( aExp < 0x3FFF ) {
 
4451
        if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
 
4452
        return 0;
 
4453
    }
 
4454
    z = aSig>>( - shiftCount );
 
4455
    if ( (uint64_t) ( aSig<<( shiftCount & 63 ) ) ) {
 
4456
        STATUS(float_exception_flags) |= float_flag_inexact;
 
4457
    }
 
4458
    if ( aSign ) z = - z;
 
4459
    return z;
 
4460
 
 
4461
}
 
4462
 
 
4463
/*----------------------------------------------------------------------------
 
4464
| Returns the result of converting the extended double-precision floating-
 
4465
| point value `a' to the single-precision floating-point format.  The
 
4466
| conversion is performed according to the IEC/IEEE Standard for Binary
 
4467
| Floating-Point Arithmetic.
 
4468
*----------------------------------------------------------------------------*/
 
4469
 
 
4470
float32 floatx80_to_float32( floatx80 a STATUS_PARAM )
 
4471
{
 
4472
    flag aSign;
 
4473
    int32 aExp;
 
4474
    uint64_t aSig;
 
4475
 
 
4476
    aSig = extractFloatx80Frac( a );
 
4477
    aExp = extractFloatx80Exp( a );
 
4478
    aSign = extractFloatx80Sign( a );
 
4479
    if ( aExp == 0x7FFF ) {
 
4480
        if ( (uint64_t) ( aSig<<1 ) ) {
 
4481
            return commonNaNToFloat32( floatx80ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
 
4482
        }
 
4483
        return packFloat32( aSign, 0xFF, 0 );
 
4484
    }
 
4485
    shift64RightJamming( aSig, 33, &aSig );
 
4486
    if ( aExp || aSig ) aExp -= 0x3F81;
 
4487
    return roundAndPackFloat32( aSign, aExp, aSig STATUS_VAR );
 
4488
 
 
4489
}
 
4490
 
 
4491
/*----------------------------------------------------------------------------
 
4492
| Returns the result of converting the extended double-precision floating-
 
4493
| point value `a' to the double-precision floating-point format.  The
 
4494
| conversion is performed according to the IEC/IEEE Standard for Binary
 
4495
| Floating-Point Arithmetic.
 
4496
*----------------------------------------------------------------------------*/
 
4497
 
 
4498
float64 floatx80_to_float64( floatx80 a STATUS_PARAM )
 
4499
{
 
4500
    flag aSign;
 
4501
    int32 aExp;
 
4502
    uint64_t aSig, zSig;
 
4503
 
 
4504
    aSig = extractFloatx80Frac( a );
 
4505
    aExp = extractFloatx80Exp( a );
 
4506
    aSign = extractFloatx80Sign( a );
 
4507
    if ( aExp == 0x7FFF ) {
 
4508
        if ( (uint64_t) ( aSig<<1 ) ) {
 
4509
            return commonNaNToFloat64( floatx80ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
 
4510
        }
 
4511
        return packFloat64( aSign, 0x7FF, 0 );
 
4512
    }
 
4513
    shift64RightJamming( aSig, 1, &zSig );
 
4514
    if ( aExp || aSig ) aExp -= 0x3C01;
 
4515
    return roundAndPackFloat64( aSign, aExp, zSig STATUS_VAR );
 
4516
 
 
4517
}
 
4518
 
 
4519
/*----------------------------------------------------------------------------
 
4520
| Returns the result of converting the extended double-precision floating-
 
4521
| point value `a' to the quadruple-precision floating-point format.  The
 
4522
| conversion is performed according to the IEC/IEEE Standard for Binary
 
4523
| Floating-Point Arithmetic.
 
4524
*----------------------------------------------------------------------------*/
 
4525
 
 
4526
float128 floatx80_to_float128( floatx80 a STATUS_PARAM )
 
4527
{
 
4528
    flag aSign;
 
4529
    int_fast16_t aExp;
 
4530
    uint64_t aSig, zSig0, zSig1;
 
4531
 
 
4532
    aSig = extractFloatx80Frac( a );
 
4533
    aExp = extractFloatx80Exp( a );
 
4534
    aSign = extractFloatx80Sign( a );
 
4535
    if ( ( aExp == 0x7FFF ) && (uint64_t) ( aSig<<1 ) ) {
 
4536
        return commonNaNToFloat128( floatx80ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
 
4537
    }
 
4538
    shift128Right( aSig<<1, 0, 16, &zSig0, &zSig1 );
 
4539
    return packFloat128( aSign, aExp, zSig0, zSig1 );
 
4540
 
 
4541
}
 
4542
 
 
4543
/*----------------------------------------------------------------------------
 
4544
| Rounds the extended double-precision floating-point value `a' to an integer,
 
4545
| and returns the result as an extended quadruple-precision floating-point
 
4546
| value.  The operation is performed according to the IEC/IEEE Standard for
 
4547
| Binary Floating-Point Arithmetic.
 
4548
*----------------------------------------------------------------------------*/
 
4549
 
 
4550
floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM )
 
4551
{
 
4552
    flag aSign;
 
4553
    int32 aExp;
 
4554
    uint64_t lastBitMask, roundBitsMask;
 
4555
    int8 roundingMode;
 
4556
    floatx80 z;
 
4557
 
 
4558
    aExp = extractFloatx80Exp( a );
 
4559
    if ( 0x403E <= aExp ) {
 
4560
        if ( ( aExp == 0x7FFF ) && (uint64_t) ( extractFloatx80Frac( a )<<1 ) ) {
 
4561
            return propagateFloatx80NaN( a, a STATUS_VAR );
 
4562
        }
 
4563
        return a;
 
4564
    }
 
4565
    if ( aExp < 0x3FFF ) {
 
4566
        if (    ( aExp == 0 )
 
4567
             && ( (uint64_t) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) {
 
4568
            return a;
 
4569
        }
 
4570
        STATUS(float_exception_flags) |= float_flag_inexact;
 
4571
        aSign = extractFloatx80Sign( a );
 
4572
        switch ( STATUS(float_rounding_mode) ) {
 
4573
         case float_round_nearest_even:
 
4574
            if ( ( aExp == 0x3FFE ) && (uint64_t) ( extractFloatx80Frac( a )<<1 )
 
4575
               ) {
 
4576
                return
 
4577
                    packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) );
 
4578
            }
 
4579
            break;
 
4580
         case float_round_down:
 
4581
            return
 
4582
                  aSign ?
 
4583
                      packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) )
 
4584
                : packFloatx80( 0, 0, 0 );
 
4585
         case float_round_up:
 
4586
            return
 
4587
                  aSign ? packFloatx80( 1, 0, 0 )
 
4588
                : packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) );
 
4589
        }
 
4590
        return packFloatx80( aSign, 0, 0 );
 
4591
    }
 
4592
    lastBitMask = 1;
 
4593
    lastBitMask <<= 0x403E - aExp;
 
4594
    roundBitsMask = lastBitMask - 1;
 
4595
    z = a;
 
4596
    roundingMode = STATUS(float_rounding_mode);
 
4597
    if ( roundingMode == float_round_nearest_even ) {
 
4598
        z.low += lastBitMask>>1;
 
4599
        if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
 
4600
    }
 
4601
    else if ( roundingMode != float_round_to_zero ) {
 
4602
        if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) {
 
4603
            z.low += roundBitsMask;
 
4604
        }
 
4605
    }
 
4606
    z.low &= ~ roundBitsMask;
 
4607
    if ( z.low == 0 ) {
 
4608
        ++z.high;
 
4609
        z.low = LIT64( 0x8000000000000000 );
 
4610
    }
 
4611
    if ( z.low != a.low ) STATUS(float_exception_flags) |= float_flag_inexact;
 
4612
    return z;
 
4613
 
 
4614
}
 
4615
 
 
4616
/*----------------------------------------------------------------------------
 
4617
| Returns the result of adding the absolute values of the extended double-
 
4618
| precision floating-point values `a' and `b'.  If `zSign' is 1, the sum is
 
4619
| negated before being returned.  `zSign' is ignored if the result is a NaN.
 
4620
| The addition is performed according to the IEC/IEEE Standard for Binary
 
4621
| Floating-Point Arithmetic.
 
4622
*----------------------------------------------------------------------------*/
 
4623
 
 
4624
static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM)
 
4625
{
 
4626
    int32 aExp, bExp, zExp;
 
4627
    uint64_t aSig, bSig, zSig0, zSig1;
 
4628
    int32 expDiff;
 
4629
 
 
4630
    aSig = extractFloatx80Frac( a );
 
4631
    aExp = extractFloatx80Exp( a );
 
4632
    bSig = extractFloatx80Frac( b );
 
4633
    bExp = extractFloatx80Exp( b );
 
4634
    expDiff = aExp - bExp;
 
4635
    if ( 0 < expDiff ) {
 
4636
        if ( aExp == 0x7FFF ) {
 
4637
            if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
 
4638
            return a;
 
4639
        }
 
4640
        if ( bExp == 0 ) --expDiff;
 
4641
        shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
 
4642
        zExp = aExp;
 
4643
    }
 
4644
    else if ( expDiff < 0 ) {
 
4645
        if ( bExp == 0x7FFF ) {
 
4646
            if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
 
4647
            return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
 
4648
        }
 
4649
        if ( aExp == 0 ) ++expDiff;
 
4650
        shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
 
4651
        zExp = bExp;
 
4652
    }
 
4653
    else {
 
4654
        if ( aExp == 0x7FFF ) {
 
4655
            if ( (uint64_t) ( ( aSig | bSig )<<1 ) ) {
 
4656
                return propagateFloatx80NaN( a, b STATUS_VAR );
 
4657
            }
 
4658
            return a;
 
4659
        }
 
4660
        zSig1 = 0;
 
4661
        zSig0 = aSig + bSig;
 
4662
        if ( aExp == 0 ) {
 
4663
            normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 );
 
4664
            goto roundAndPack;
 
4665
        }
 
4666
        zExp = aExp;
 
4667
        goto shiftRight1;
 
4668
    }
 
4669
    zSig0 = aSig + bSig;
 
4670
    if ( (int64_t) zSig0 < 0 ) goto roundAndPack;
 
4671
 shiftRight1:
 
4672
    shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 );
 
4673
    zSig0 |= LIT64( 0x8000000000000000 );
 
4674
    ++zExp;
 
4675
 roundAndPack:
 
4676
    return
 
4677
        roundAndPackFloatx80(
 
4678
            STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
 
4679
 
 
4680
}
 
4681
 
 
4682
/*----------------------------------------------------------------------------
 
4683
| Returns the result of subtracting the absolute values of the extended
 
4684
| double-precision floating-point values `a' and `b'.  If `zSign' is 1, the
 
4685
| difference is negated before being returned.  `zSign' is ignored if the
 
4686
| result is a NaN.  The subtraction is performed according to the IEC/IEEE
 
4687
| Standard for Binary Floating-Point Arithmetic.
 
4688
*----------------------------------------------------------------------------*/
 
4689
 
 
4690
static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM )
 
4691
{
 
4692
    int32 aExp, bExp, zExp;
 
4693
    uint64_t aSig, bSig, zSig0, zSig1;
 
4694
    int32 expDiff;
 
4695
    floatx80 z;
 
4696
 
 
4697
    aSig = extractFloatx80Frac( a );
 
4698
    aExp = extractFloatx80Exp( a );
 
4699
    bSig = extractFloatx80Frac( b );
 
4700
    bExp = extractFloatx80Exp( b );
 
4701
    expDiff = aExp - bExp;
 
4702
    if ( 0 < expDiff ) goto aExpBigger;
 
4703
    if ( expDiff < 0 ) goto bExpBigger;
 
4704
    if ( aExp == 0x7FFF ) {
 
4705
        if ( (uint64_t) ( ( aSig | bSig )<<1 ) ) {
 
4706
            return propagateFloatx80NaN( a, b STATUS_VAR );
 
4707
        }
 
4708
        float_raise( float_flag_invalid STATUS_VAR);
 
4709
        z.low = floatx80_default_nan_low;
 
4710
        z.high = floatx80_default_nan_high;
 
4711
        return z;
 
4712
    }
 
4713
    if ( aExp == 0 ) {
 
4714
        aExp = 1;
 
4715
        bExp = 1;
 
4716
    }
 
4717
    zSig1 = 0;
 
4718
    if ( bSig < aSig ) goto aBigger;
 
4719
    if ( aSig < bSig ) goto bBigger;
 
4720
    return packFloatx80( STATUS(float_rounding_mode) == float_round_down, 0, 0 );
 
4721
 bExpBigger:
 
4722
    if ( bExp == 0x7FFF ) {
 
4723
        if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
 
4724
        return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) );
 
4725
    }
 
4726
    if ( aExp == 0 ) ++expDiff;
 
4727
    shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
 
4728
 bBigger:
 
4729
    sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 );
 
4730
    zExp = bExp;
 
4731
    zSign ^= 1;
 
4732
    goto normalizeRoundAndPack;
 
4733
 aExpBigger:
 
4734
    if ( aExp == 0x7FFF ) {
 
4735
        if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
 
4736
        return a;
 
4737
    }
 
4738
    if ( bExp == 0 ) --expDiff;
 
4739
    shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
 
4740
 aBigger:
 
4741
    sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 );
 
4742
    zExp = aExp;
 
4743
 normalizeRoundAndPack:
 
4744
    return
 
4745
        normalizeRoundAndPackFloatx80(
 
4746
            STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
 
4747
 
 
4748
}
 
4749
 
 
4750
/*----------------------------------------------------------------------------
 
4751
| Returns the result of adding the extended double-precision floating-point
 
4752
| values `a' and `b'.  The operation is performed according to the IEC/IEEE
 
4753
| Standard for Binary Floating-Point Arithmetic.
 
4754
*----------------------------------------------------------------------------*/
 
4755
 
 
4756
floatx80 floatx80_add( floatx80 a, floatx80 b STATUS_PARAM )
 
4757
{
 
4758
    flag aSign, bSign;
 
4759
 
 
4760
    aSign = extractFloatx80Sign( a );
 
4761
    bSign = extractFloatx80Sign( b );
 
4762
    if ( aSign == bSign ) {
 
4763
        return addFloatx80Sigs( a, b, aSign STATUS_VAR );
 
4764
    }
 
4765
    else {
 
4766
        return subFloatx80Sigs( a, b, aSign STATUS_VAR );
 
4767
    }
 
4768
 
 
4769
}
 
4770
 
 
4771
/*----------------------------------------------------------------------------
 
4772
| Returns the result of subtracting the extended double-precision floating-
 
4773
| point values `a' and `b'.  The operation is performed according to the
 
4774
| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
4775
*----------------------------------------------------------------------------*/
 
4776
 
 
4777
floatx80 floatx80_sub( floatx80 a, floatx80 b STATUS_PARAM )
 
4778
{
 
4779
    flag aSign, bSign;
 
4780
 
 
4781
    aSign = extractFloatx80Sign( a );
 
4782
    bSign = extractFloatx80Sign( b );
 
4783
    if ( aSign == bSign ) {
 
4784
        return subFloatx80Sigs( a, b, aSign STATUS_VAR );
 
4785
    }
 
4786
    else {
 
4787
        return addFloatx80Sigs( a, b, aSign STATUS_VAR );
 
4788
    }
 
4789
 
 
4790
}
 
4791
 
 
4792
/*----------------------------------------------------------------------------
 
4793
| Returns the result of multiplying the extended double-precision floating-
 
4794
| point values `a' and `b'.  The operation is performed according to the
 
4795
| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
4796
*----------------------------------------------------------------------------*/
 
4797
 
 
4798
floatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM )
 
4799
{
 
4800
    flag aSign, bSign, zSign;
 
4801
    int32 aExp, bExp, zExp;
 
4802
    uint64_t aSig, bSig, zSig0, zSig1;
 
4803
    floatx80 z;
 
4804
 
 
4805
    aSig = extractFloatx80Frac( a );
 
4806
    aExp = extractFloatx80Exp( a );
 
4807
    aSign = extractFloatx80Sign( a );
 
4808
    bSig = extractFloatx80Frac( b );
 
4809
    bExp = extractFloatx80Exp( b );
 
4810
    bSign = extractFloatx80Sign( b );
 
4811
    zSign = aSign ^ bSign;
 
4812
    if ( aExp == 0x7FFF ) {
 
4813
        if (    (uint64_t) ( aSig<<1 )
 
4814
             || ( ( bExp == 0x7FFF ) && (uint64_t) ( bSig<<1 ) ) ) {
 
4815
            return propagateFloatx80NaN( a, b STATUS_VAR );
 
4816
        }
 
4817
        if ( ( bExp | bSig ) == 0 ) goto invalid;
 
4818
        return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
 
4819
    }
 
4820
    if ( bExp == 0x7FFF ) {
 
4821
        if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
 
4822
        if ( ( aExp | aSig ) == 0 ) {
 
4823
 invalid:
 
4824
            float_raise( float_flag_invalid STATUS_VAR);
 
4825
            z.low = floatx80_default_nan_low;
 
4826
            z.high = floatx80_default_nan_high;
 
4827
            return z;
 
4828
        }
 
4829
        return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
 
4830
    }
 
4831
    if ( aExp == 0 ) {
 
4832
        if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
 
4833
        normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
 
4834
    }
 
4835
    if ( bExp == 0 ) {
 
4836
        if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 );
 
4837
        normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
 
4838
    }
 
4839
    zExp = aExp + bExp - 0x3FFE;
 
4840
    mul64To128( aSig, bSig, &zSig0, &zSig1 );
 
4841
    if ( 0 < (int64_t) zSig0 ) {
 
4842
        shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 );
 
4843
        --zExp;
 
4844
    }
 
4845
    return
 
4846
        roundAndPackFloatx80(
 
4847
            STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
 
4848
 
 
4849
}
 
4850
 
 
4851
/*----------------------------------------------------------------------------
 
4852
| Returns the result of dividing the extended double-precision floating-point
 
4853
| value `a' by the corresponding value `b'.  The operation is performed
 
4854
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
4855
*----------------------------------------------------------------------------*/
 
4856
 
 
4857
floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM )
 
4858
{
 
4859
    flag aSign, bSign, zSign;
 
4860
    int32 aExp, bExp, zExp;
 
4861
    uint64_t aSig, bSig, zSig0, zSig1;
 
4862
    uint64_t rem0, rem1, rem2, term0, term1, term2;
 
4863
    floatx80 z;
 
4864
 
 
4865
    aSig = extractFloatx80Frac( a );
 
4866
    aExp = extractFloatx80Exp( a );
 
4867
    aSign = extractFloatx80Sign( a );
 
4868
    bSig = extractFloatx80Frac( b );
 
4869
    bExp = extractFloatx80Exp( b );
 
4870
    bSign = extractFloatx80Sign( b );
 
4871
    zSign = aSign ^ bSign;
 
4872
    if ( aExp == 0x7FFF ) {
 
4873
        if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
 
4874
        if ( bExp == 0x7FFF ) {
 
4875
            if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
 
4876
            goto invalid;
 
4877
        }
 
4878
        return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
 
4879
    }
 
4880
    if ( bExp == 0x7FFF ) {
 
4881
        if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
 
4882
        return packFloatx80( zSign, 0, 0 );
 
4883
    }
 
4884
    if ( bExp == 0 ) {
 
4885
        if ( bSig == 0 ) {
 
4886
            if ( ( aExp | aSig ) == 0 ) {
 
4887
 invalid:
 
4888
                float_raise( float_flag_invalid STATUS_VAR);
 
4889
                z.low = floatx80_default_nan_low;
 
4890
                z.high = floatx80_default_nan_high;
 
4891
                return z;
 
4892
            }
 
4893
            float_raise( float_flag_divbyzero STATUS_VAR);
 
4894
            return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
 
4895
        }
 
4896
        normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
 
4897
    }
 
4898
    if ( aExp == 0 ) {
 
4899
        if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
 
4900
        normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
 
4901
    }
 
4902
    zExp = aExp - bExp + 0x3FFE;
 
4903
    rem1 = 0;
 
4904
    if ( bSig <= aSig ) {
 
4905
        shift128Right( aSig, 0, 1, &aSig, &rem1 );
 
4906
        ++zExp;
 
4907
    }
 
4908
    zSig0 = estimateDiv128To64( aSig, rem1, bSig );
 
4909
    mul64To128( bSig, zSig0, &term0, &term1 );
 
4910
    sub128( aSig, rem1, term0, term1, &rem0, &rem1 );
 
4911
    while ( (int64_t) rem0 < 0 ) {
 
4912
        --zSig0;
 
4913
        add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
 
4914
    }
 
4915
    zSig1 = estimateDiv128To64( rem1, 0, bSig );
 
4916
    if ( (uint64_t) ( zSig1<<1 ) <= 8 ) {
 
4917
        mul64To128( bSig, zSig1, &term1, &term2 );
 
4918
        sub128( rem1, 0, term1, term2, &rem1, &rem2 );
 
4919
        while ( (int64_t) rem1 < 0 ) {
 
4920
            --zSig1;
 
4921
            add128( rem1, rem2, 0, bSig, &rem1, &rem2 );
 
4922
        }
 
4923
        zSig1 |= ( ( rem1 | rem2 ) != 0 );
 
4924
    }
 
4925
    return
 
4926
        roundAndPackFloatx80(
 
4927
            STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
 
4928
 
 
4929
}
 
4930
 
 
4931
/*----------------------------------------------------------------------------
 
4932
| Returns the remainder of the extended double-precision floating-point value
 
4933
| `a' with respect to the corresponding value `b'.  The operation is performed
 
4934
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
4935
*----------------------------------------------------------------------------*/
 
4936
 
 
4937
floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM )
 
4938
{
 
4939
    flag aSign, zSign;
 
4940
    int32 aExp, bExp, expDiff;
 
4941
    uint64_t aSig0, aSig1, bSig;
 
4942
    uint64_t q, term0, term1, alternateASig0, alternateASig1;
 
4943
    floatx80 z;
 
4944
 
 
4945
    aSig0 = extractFloatx80Frac( a );
 
4946
    aExp = extractFloatx80Exp( a );
 
4947
    aSign = extractFloatx80Sign( a );
 
4948
    bSig = extractFloatx80Frac( b );
 
4949
    bExp = extractFloatx80Exp( b );
 
4950
    if ( aExp == 0x7FFF ) {
 
4951
        if (    (uint64_t) ( aSig0<<1 )
 
4952
             || ( ( bExp == 0x7FFF ) && (uint64_t) ( bSig<<1 ) ) ) {
 
4953
            return propagateFloatx80NaN( a, b STATUS_VAR );
 
4954
        }
 
4955
        goto invalid;
 
4956
    }
 
4957
    if ( bExp == 0x7FFF ) {
 
4958
        if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
 
4959
        return a;
 
4960
    }
 
4961
    if ( bExp == 0 ) {
 
4962
        if ( bSig == 0 ) {
 
4963
 invalid:
 
4964
            float_raise( float_flag_invalid STATUS_VAR);
 
4965
            z.low = floatx80_default_nan_low;
 
4966
            z.high = floatx80_default_nan_high;
 
4967
            return z;
 
4968
        }
 
4969
        normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
 
4970
    }
 
4971
    if ( aExp == 0 ) {
 
4972
        if ( (uint64_t) ( aSig0<<1 ) == 0 ) return a;
 
4973
        normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
 
4974
    }
 
4975
    bSig |= LIT64( 0x8000000000000000 );
 
4976
    zSign = aSign;
 
4977
    expDiff = aExp - bExp;
 
4978
    aSig1 = 0;
 
4979
    if ( expDiff < 0 ) {
 
4980
        if ( expDiff < -1 ) return a;
 
4981
        shift128Right( aSig0, 0, 1, &aSig0, &aSig1 );
 
4982
        expDiff = 0;
 
4983
    }
 
4984
    q = ( bSig <= aSig0 );
 
4985
    if ( q ) aSig0 -= bSig;
 
4986
    expDiff -= 64;
 
4987
    while ( 0 < expDiff ) {
 
4988
        q = estimateDiv128To64( aSig0, aSig1, bSig );
 
4989
        q = ( 2 < q ) ? q - 2 : 0;
 
4990
        mul64To128( bSig, q, &term0, &term1 );
 
4991
        sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
 
4992
        shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 );
 
4993
        expDiff -= 62;
 
4994
    }
 
4995
    expDiff += 64;
 
4996
    if ( 0 < expDiff ) {
 
4997
        q = estimateDiv128To64( aSig0, aSig1, bSig );
 
4998
        q = ( 2 < q ) ? q - 2 : 0;
 
4999
        q >>= 64 - expDiff;
 
5000
        mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 );
 
5001
        sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
 
5002
        shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 );
 
5003
        while ( le128( term0, term1, aSig0, aSig1 ) ) {
 
5004
            ++q;
 
5005
            sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
 
5006
        }
 
5007
    }
 
5008
    else {
 
5009
        term1 = 0;
 
5010
        term0 = bSig;
 
5011
    }
 
5012
    sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );
 
5013
    if (    lt128( alternateASig0, alternateASig1, aSig0, aSig1 )
 
5014
         || (    eq128( alternateASig0, alternateASig1, aSig0, aSig1 )
 
5015
              && ( q & 1 ) )
 
5016
       ) {
 
5017
        aSig0 = alternateASig0;
 
5018
        aSig1 = alternateASig1;
 
5019
        zSign = ! zSign;
 
5020
    }
 
5021
    return
 
5022
        normalizeRoundAndPackFloatx80(
 
5023
            80, zSign, bExp + expDiff, aSig0, aSig1 STATUS_VAR );
 
5024
 
 
5025
}
 
5026
 
 
5027
/*----------------------------------------------------------------------------
 
5028
| Returns the square root of the extended double-precision floating-point
 
5029
| value `a'.  The operation is performed according to the IEC/IEEE Standard
 
5030
| for Binary Floating-Point Arithmetic.
 
5031
*----------------------------------------------------------------------------*/
 
5032
 
 
5033
floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM )
 
5034
{
 
5035
    flag aSign;
 
5036
    int32 aExp, zExp;
 
5037
    uint64_t aSig0, aSig1, zSig0, zSig1, doubleZSig0;
 
5038
    uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3;
 
5039
    floatx80 z;
 
5040
 
 
5041
    aSig0 = extractFloatx80Frac( a );
 
5042
    aExp = extractFloatx80Exp( a );
 
5043
    aSign = extractFloatx80Sign( a );
 
5044
    if ( aExp == 0x7FFF ) {
 
5045
        if ( (uint64_t) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a STATUS_VAR );
 
5046
        if ( ! aSign ) return a;
 
5047
        goto invalid;
 
5048
    }
 
5049
    if ( aSign ) {
 
5050
        if ( ( aExp | aSig0 ) == 0 ) return a;
 
5051
 invalid:
 
5052
        float_raise( float_flag_invalid STATUS_VAR);
 
5053
        z.low = floatx80_default_nan_low;
 
5054
        z.high = floatx80_default_nan_high;
 
5055
        return z;
 
5056
    }
 
5057
    if ( aExp == 0 ) {
 
5058
        if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 );
 
5059
        normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
 
5060
    }
 
5061
    zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF;
 
5062
    zSig0 = estimateSqrt32( aExp, aSig0>>32 );
 
5063
    shift128Right( aSig0, 0, 2 + ( aExp & 1 ), &aSig0, &aSig1 );
 
5064
    zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 );
 
5065
    doubleZSig0 = zSig0<<1;
 
5066
    mul64To128( zSig0, zSig0, &term0, &term1 );
 
5067
    sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
 
5068
    while ( (int64_t) rem0 < 0 ) {
 
5069
        --zSig0;
 
5070
        doubleZSig0 -= 2;
 
5071
        add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 );
 
5072
    }
 
5073
    zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 );
 
5074
    if ( ( zSig1 & LIT64( 0x3FFFFFFFFFFFFFFF ) ) <= 5 ) {
 
5075
        if ( zSig1 == 0 ) zSig1 = 1;
 
5076
        mul64To128( doubleZSig0, zSig1, &term1, &term2 );
 
5077
        sub128( rem1, 0, term1, term2, &rem1, &rem2 );
 
5078
        mul64To128( zSig1, zSig1, &term2, &term3 );
 
5079
        sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
 
5080
        while ( (int64_t) rem1 < 0 ) {
 
5081
            --zSig1;
 
5082
            shortShift128Left( 0, zSig1, 1, &term2, &term3 );
 
5083
            term3 |= 1;
 
5084
            term2 |= doubleZSig0;
 
5085
            add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 );
 
5086
        }
 
5087
        zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
 
5088
    }
 
5089
    shortShift128Left( 0, zSig1, 1, &zSig0, &zSig1 );
 
5090
    zSig0 |= doubleZSig0;
 
5091
    return
 
5092
        roundAndPackFloatx80(
 
5093
            STATUS(floatx80_rounding_precision), 0, zExp, zSig0, zSig1 STATUS_VAR );
 
5094
 
 
5095
}
 
5096
 
 
5097
/*----------------------------------------------------------------------------
 
5098
| Returns 1 if the extended double-precision floating-point value `a' is equal
 
5099
| to the corresponding value `b', and 0 otherwise.  The invalid exception is
 
5100
| raised if either operand is a NaN.  Otherwise, the comparison is performed
 
5101
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
5102
*----------------------------------------------------------------------------*/
 
5103
 
 
5104
int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
 
5105
{
 
5106
 
 
5107
    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
 
5108
              && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
 
5109
         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
 
5110
              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
 
5111
       ) {
 
5112
        float_raise( float_flag_invalid STATUS_VAR);
 
5113
        return 0;
 
5114
    }
 
5115
    return
 
5116
           ( a.low == b.low )
 
5117
        && (    ( a.high == b.high )
 
5118
             || (    ( a.low == 0 )
 
5119
                  && ( (uint16_t) ( ( a.high | b.high )<<1 ) == 0 ) )
 
5120
           );
 
5121
 
 
5122
}
 
5123
 
 
5124
/*----------------------------------------------------------------------------
 
5125
| Returns 1 if the extended double-precision floating-point value `a' is
 
5126
| less than or equal to the corresponding value `b', and 0 otherwise.  The
 
5127
| invalid exception is raised if either operand is a NaN.  The comparison is
 
5128
| performed according to the IEC/IEEE Standard for Binary Floating-Point
 
5129
| Arithmetic.
 
5130
*----------------------------------------------------------------------------*/
 
5131
 
 
5132
int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM )
 
5133
{
 
5134
    flag aSign, bSign;
 
5135
 
 
5136
    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
 
5137
              && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
 
5138
         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
 
5139
              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
 
5140
       ) {
 
5141
        float_raise( float_flag_invalid STATUS_VAR);
 
5142
        return 0;
 
5143
    }
 
5144
    aSign = extractFloatx80Sign( a );
 
5145
    bSign = extractFloatx80Sign( b );
 
5146
    if ( aSign != bSign ) {
 
5147
        return
 
5148
               aSign
 
5149
            || (    ( ( (uint16_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
 
5150
                 == 0 );
 
5151
    }
 
5152
    return
 
5153
          aSign ? le128( b.high, b.low, a.high, a.low )
 
5154
        : le128( a.high, a.low, b.high, b.low );
 
5155
 
 
5156
}
 
5157
 
 
5158
/*----------------------------------------------------------------------------
 
5159
| Returns 1 if the extended double-precision floating-point value `a' is
 
5160
| less than the corresponding value `b', and 0 otherwise.  The invalid
 
5161
| exception is raised if either operand is a NaN.  The comparison is performed
 
5162
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
5163
*----------------------------------------------------------------------------*/
 
5164
 
 
5165
int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM )
 
5166
{
 
5167
    flag aSign, bSign;
 
5168
 
 
5169
    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
 
5170
              && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
 
5171
         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
 
5172
              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
 
5173
       ) {
 
5174
        float_raise( float_flag_invalid STATUS_VAR);
 
5175
        return 0;
 
5176
    }
 
5177
    aSign = extractFloatx80Sign( a );
 
5178
    bSign = extractFloatx80Sign( b );
 
5179
    if ( aSign != bSign ) {
 
5180
        return
 
5181
               aSign
 
5182
            && (    ( ( (uint16_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
 
5183
                 != 0 );
 
5184
    }
 
5185
    return
 
5186
          aSign ? lt128( b.high, b.low, a.high, a.low )
 
5187
        : lt128( a.high, a.low, b.high, b.low );
 
5188
 
 
5189
}
 
5190
 
 
5191
/*----------------------------------------------------------------------------
 
5192
| Returns 1 if the extended double-precision floating-point values `a' and `b'
 
5193
| cannot be compared, and 0 otherwise.  The invalid exception is raised if
 
5194
| either operand is a NaN.   The comparison is performed according to the
 
5195
| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
5196
*----------------------------------------------------------------------------*/
 
5197
int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM )
 
5198
{
 
5199
    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
 
5200
              && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
 
5201
         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
 
5202
              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
 
5203
       ) {
 
5204
        float_raise( float_flag_invalid STATUS_VAR);
 
5205
        return 1;
 
5206
    }
 
5207
    return 0;
 
5208
}
 
5209
 
 
5210
/*----------------------------------------------------------------------------
 
5211
| Returns 1 if the extended double-precision floating-point value `a' is
 
5212
| equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
 
5213
| cause an exception.  The comparison is performed according to the IEC/IEEE
 
5214
| Standard for Binary Floating-Point Arithmetic.
 
5215
*----------------------------------------------------------------------------*/
 
5216
 
 
5217
int floatx80_eq_quiet( floatx80 a, floatx80 b STATUS_PARAM )
 
5218
{
 
5219
 
 
5220
    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
 
5221
              && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
 
5222
         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
 
5223
              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
 
5224
       ) {
 
5225
        if (    floatx80_is_signaling_nan( a )
 
5226
             || floatx80_is_signaling_nan( b ) ) {
 
5227
            float_raise( float_flag_invalid STATUS_VAR);
 
5228
        }
 
5229
        return 0;
 
5230
    }
 
5231
    return
 
5232
           ( a.low == b.low )
 
5233
        && (    ( a.high == b.high )
 
5234
             || (    ( a.low == 0 )
 
5235
                  && ( (uint16_t) ( ( a.high | b.high )<<1 ) == 0 ) )
 
5236
           );
 
5237
 
 
5238
}
 
5239
 
 
5240
/*----------------------------------------------------------------------------
 
5241
| Returns 1 if the extended double-precision floating-point value `a' is less
 
5242
| than or equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs
 
5243
| do not cause an exception.  Otherwise, the comparison is performed according
 
5244
| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
5245
*----------------------------------------------------------------------------*/
 
5246
 
 
5247
int floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM )
 
5248
{
 
5249
    flag aSign, bSign;
 
5250
 
 
5251
    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
 
5252
              && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
 
5253
         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
 
5254
              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
 
5255
       ) {
 
5256
        if (    floatx80_is_signaling_nan( a )
 
5257
             || floatx80_is_signaling_nan( b ) ) {
 
5258
            float_raise( float_flag_invalid STATUS_VAR);
 
5259
        }
 
5260
        return 0;
 
5261
    }
 
5262
    aSign = extractFloatx80Sign( a );
 
5263
    bSign = extractFloatx80Sign( b );
 
5264
    if ( aSign != bSign ) {
 
5265
        return
 
5266
               aSign
 
5267
            || (    ( ( (uint16_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
 
5268
                 == 0 );
 
5269
    }
 
5270
    return
 
5271
          aSign ? le128( b.high, b.low, a.high, a.low )
 
5272
        : le128( a.high, a.low, b.high, b.low );
 
5273
 
 
5274
}
 
5275
 
 
5276
/*----------------------------------------------------------------------------
 
5277
| Returns 1 if the extended double-precision floating-point value `a' is less
 
5278
| than the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause
 
5279
| an exception.  Otherwise, the comparison is performed according to the
 
5280
| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
5281
*----------------------------------------------------------------------------*/
 
5282
 
 
5283
int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM )
 
5284
{
 
5285
    flag aSign, bSign;
 
5286
 
 
5287
    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
 
5288
              && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
 
5289
         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
 
5290
              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
 
5291
       ) {
 
5292
        if (    floatx80_is_signaling_nan( a )
 
5293
             || floatx80_is_signaling_nan( b ) ) {
 
5294
            float_raise( float_flag_invalid STATUS_VAR);
 
5295
        }
 
5296
        return 0;
 
5297
    }
 
5298
    aSign = extractFloatx80Sign( a );
 
5299
    bSign = extractFloatx80Sign( b );
 
5300
    if ( aSign != bSign ) {
 
5301
        return
 
5302
               aSign
 
5303
            && (    ( ( (uint16_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
 
5304
                 != 0 );
 
5305
    }
 
5306
    return
 
5307
          aSign ? lt128( b.high, b.low, a.high, a.low )
 
5308
        : lt128( a.high, a.low, b.high, b.low );
 
5309
 
 
5310
}
 
5311
 
 
5312
/*----------------------------------------------------------------------------
 
5313
| Returns 1 if the extended double-precision floating-point values `a' and `b'
 
5314
| cannot be compared, and 0 otherwise.  Quiet NaNs do not cause an exception.
 
5315
| The comparison is performed according to the IEC/IEEE Standard for Binary
 
5316
| Floating-Point Arithmetic.
 
5317
*----------------------------------------------------------------------------*/
 
5318
int floatx80_unordered_quiet( floatx80 a, floatx80 b STATUS_PARAM )
 
5319
{
 
5320
    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
 
5321
              && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
 
5322
         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
 
5323
              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
 
5324
       ) {
 
5325
        if (    floatx80_is_signaling_nan( a )
 
5326
             || floatx80_is_signaling_nan( b ) ) {
 
5327
            float_raise( float_flag_invalid STATUS_VAR);
 
5328
        }
 
5329
        return 1;
 
5330
    }
 
5331
    return 0;
 
5332
}
 
5333
 
 
5334
/*----------------------------------------------------------------------------
 
5335
| Returns the result of converting the quadruple-precision floating-point
 
5336
| value `a' to the 32-bit two's complement integer format.  The conversion
 
5337
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
 
5338
| Arithmetic---which means in particular that the conversion is rounded
 
5339
| according to the current rounding mode.  If `a' is a NaN, the largest
 
5340
| positive integer is returned.  Otherwise, if the conversion overflows, the
 
5341
| largest integer with the same sign as `a' is returned.
 
5342
*----------------------------------------------------------------------------*/
 
5343
 
 
5344
int32 float128_to_int32( float128 a STATUS_PARAM )
 
5345
{
 
5346
    flag aSign;
 
5347
    int32 aExp, shiftCount;
 
5348
    uint64_t aSig0, aSig1;
 
5349
 
 
5350
    aSig1 = extractFloat128Frac1( a );
 
5351
    aSig0 = extractFloat128Frac0( a );
 
5352
    aExp = extractFloat128Exp( a );
 
5353
    aSign = extractFloat128Sign( a );
 
5354
    if ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) aSign = 0;
 
5355
    if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
 
5356
    aSig0 |= ( aSig1 != 0 );
 
5357
    shiftCount = 0x4028 - aExp;
 
5358
    if ( 0 < shiftCount ) shift64RightJamming( aSig0, shiftCount, &aSig0 );
 
5359
    return roundAndPackInt32( aSign, aSig0 STATUS_VAR );
 
5360
 
 
5361
}
 
5362
 
 
5363
/*----------------------------------------------------------------------------
 
5364
| Returns the result of converting the quadruple-precision floating-point
 
5365
| value `a' to the 32-bit two's complement integer format.  The conversion
 
5366
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
 
5367
| Arithmetic, except that the conversion is always rounded toward zero.  If
 
5368
| `a' is a NaN, the largest positive integer is returned.  Otherwise, if the
 
5369
| conversion overflows, the largest integer with the same sign as `a' is
 
5370
| returned.
 
5371
*----------------------------------------------------------------------------*/
 
5372
 
 
5373
int32 float128_to_int32_round_to_zero( float128 a STATUS_PARAM )
 
5374
{
 
5375
    flag aSign;
 
5376
    int32 aExp, shiftCount;
 
5377
    uint64_t aSig0, aSig1, savedASig;
 
5378
    int32_t z;
 
5379
 
 
5380
    aSig1 = extractFloat128Frac1( a );
 
5381
    aSig0 = extractFloat128Frac0( a );
 
5382
    aExp = extractFloat128Exp( a );
 
5383
    aSign = extractFloat128Sign( a );
 
5384
    aSig0 |= ( aSig1 != 0 );
 
5385
    if ( 0x401E < aExp ) {
 
5386
        if ( ( aExp == 0x7FFF ) && aSig0 ) aSign = 0;
 
5387
        goto invalid;
 
5388
    }
 
5389
    else if ( aExp < 0x3FFF ) {
 
5390
        if ( aExp || aSig0 ) STATUS(float_exception_flags) |= float_flag_inexact;
 
5391
        return 0;
 
5392
    }
 
5393
    aSig0 |= LIT64( 0x0001000000000000 );
 
5394
    shiftCount = 0x402F - aExp;
 
5395
    savedASig = aSig0;
 
5396
    aSig0 >>= shiftCount;
 
5397
    z = aSig0;
 
5398
    if ( aSign ) z = - z;
 
5399
    if ( ( z < 0 ) ^ aSign ) {
 
5400
 invalid:
 
5401
        float_raise( float_flag_invalid STATUS_VAR);
 
5402
        return aSign ? (int32_t) 0x80000000 : 0x7FFFFFFF;
 
5403
    }
 
5404
    if ( ( aSig0<<shiftCount ) != savedASig ) {
 
5405
        STATUS(float_exception_flags) |= float_flag_inexact;
 
5406
    }
 
5407
    return z;
 
5408
 
 
5409
}
 
5410
 
 
5411
/*----------------------------------------------------------------------------
 
5412
| Returns the result of converting the quadruple-precision floating-point
 
5413
| value `a' to the 64-bit two's complement integer format.  The conversion
 
5414
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
 
5415
| Arithmetic---which means in particular that the conversion is rounded
 
5416
| according to the current rounding mode.  If `a' is a NaN, the largest
 
5417
| positive integer is returned.  Otherwise, if the conversion overflows, the
 
5418
| largest integer with the same sign as `a' is returned.
 
5419
*----------------------------------------------------------------------------*/
 
5420
 
 
5421
int64 float128_to_int64( float128 a STATUS_PARAM )
 
5422
{
 
5423
    flag aSign;
 
5424
    int32 aExp, shiftCount;
 
5425
    uint64_t aSig0, aSig1;
 
5426
 
 
5427
    aSig1 = extractFloat128Frac1( a );
 
5428
    aSig0 = extractFloat128Frac0( a );
 
5429
    aExp = extractFloat128Exp( a );
 
5430
    aSign = extractFloat128Sign( a );
 
5431
    if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
 
5432
    shiftCount = 0x402F - aExp;
 
5433
    if ( shiftCount <= 0 ) {
 
5434
        if ( 0x403E < aExp ) {
 
5435
            float_raise( float_flag_invalid STATUS_VAR);
 
5436
            if (    ! aSign
 
5437
                 || (    ( aExp == 0x7FFF )
 
5438
                      && ( aSig1 || ( aSig0 != LIT64( 0x0001000000000000 ) ) )
 
5439
                    )
 
5440
               ) {
 
5441
                return LIT64( 0x7FFFFFFFFFFFFFFF );
 
5442
            }
 
5443
            return (int64_t) LIT64( 0x8000000000000000 );
 
5444
        }
 
5445
        shortShift128Left( aSig0, aSig1, - shiftCount, &aSig0, &aSig1 );
 
5446
    }
 
5447
    else {
 
5448
        shift64ExtraRightJamming( aSig0, aSig1, shiftCount, &aSig0, &aSig1 );
 
5449
    }
 
5450
    return roundAndPackInt64( aSign, aSig0, aSig1 STATUS_VAR );
 
5451
 
 
5452
}
 
5453
 
 
5454
/*----------------------------------------------------------------------------
 
5455
| Returns the result of converting the quadruple-precision floating-point
 
5456
| value `a' to the 64-bit two's complement integer format.  The conversion
 
5457
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
 
5458
| Arithmetic, except that the conversion is always rounded toward zero.
 
5459
| If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
 
5460
| the conversion overflows, the largest integer with the same sign as `a' is
 
5461
| returned.
 
5462
*----------------------------------------------------------------------------*/
 
5463
 
 
5464
int64 float128_to_int64_round_to_zero( float128 a STATUS_PARAM )
 
5465
{
 
5466
    flag aSign;
 
5467
    int32 aExp, shiftCount;
 
5468
    uint64_t aSig0, aSig1;
 
5469
    int64 z;
 
5470
 
 
5471
    aSig1 = extractFloat128Frac1( a );
 
5472
    aSig0 = extractFloat128Frac0( a );
 
5473
    aExp = extractFloat128Exp( a );
 
5474
    aSign = extractFloat128Sign( a );
 
5475
    if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
 
5476
    shiftCount = aExp - 0x402F;
 
5477
    if ( 0 < shiftCount ) {
 
5478
        if ( 0x403E <= aExp ) {
 
5479
            aSig0 &= LIT64( 0x0000FFFFFFFFFFFF );
 
5480
            if (    ( a.high == LIT64( 0xC03E000000000000 ) )
 
5481
                 && ( aSig1 < LIT64( 0x0002000000000000 ) ) ) {
 
5482
                if ( aSig1 ) STATUS(float_exception_flags) |= float_flag_inexact;
 
5483
            }
 
5484
            else {
 
5485
                float_raise( float_flag_invalid STATUS_VAR);
 
5486
                if ( ! aSign || ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) ) {
 
5487
                    return LIT64( 0x7FFFFFFFFFFFFFFF );
 
5488
                }
 
5489
            }
 
5490
            return (int64_t) LIT64( 0x8000000000000000 );
 
5491
        }
 
5492
        z = ( aSig0<<shiftCount ) | ( aSig1>>( ( - shiftCount ) & 63 ) );
 
5493
        if ( (uint64_t) ( aSig1<<shiftCount ) ) {
 
5494
            STATUS(float_exception_flags) |= float_flag_inexact;
 
5495
        }
 
5496
    }
 
5497
    else {
 
5498
        if ( aExp < 0x3FFF ) {
 
5499
            if ( aExp | aSig0 | aSig1 ) {
 
5500
                STATUS(float_exception_flags) |= float_flag_inexact;
 
5501
            }
 
5502
            return 0;
 
5503
        }
 
5504
        z = aSig0>>( - shiftCount );
 
5505
        if (    aSig1
 
5506
             || ( shiftCount && (uint64_t) ( aSig0<<( shiftCount & 63 ) ) ) ) {
 
5507
            STATUS(float_exception_flags) |= float_flag_inexact;
 
5508
        }
 
5509
    }
 
5510
    if ( aSign ) z = - z;
 
5511
    return z;
 
5512
 
 
5513
}
 
5514
 
 
5515
/*----------------------------------------------------------------------------
 
5516
| Returns the result of converting the quadruple-precision floating-point
 
5517
| value `a' to the single-precision floating-point format.  The conversion
 
5518
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
 
5519
| Arithmetic.
 
5520
*----------------------------------------------------------------------------*/
 
5521
 
 
5522
float32 float128_to_float32( float128 a STATUS_PARAM )
 
5523
{
 
5524
    flag aSign;
 
5525
    int32 aExp;
 
5526
    uint64_t aSig0, aSig1;
 
5527
    uint32_t zSig;
 
5528
 
 
5529
    aSig1 = extractFloat128Frac1( a );
 
5530
    aSig0 = extractFloat128Frac0( a );
 
5531
    aExp = extractFloat128Exp( a );
 
5532
    aSign = extractFloat128Sign( a );
 
5533
    if ( aExp == 0x7FFF ) {
 
5534
        if ( aSig0 | aSig1 ) {
 
5535
            return commonNaNToFloat32( float128ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
 
5536
        }
 
5537
        return packFloat32( aSign, 0xFF, 0 );
 
5538
    }
 
5539
    aSig0 |= ( aSig1 != 0 );
 
5540
    shift64RightJamming( aSig0, 18, &aSig0 );
 
5541
    zSig = aSig0;
 
5542
    if ( aExp || zSig ) {
 
5543
        zSig |= 0x40000000;
 
5544
        aExp -= 0x3F81;
 
5545
    }
 
5546
    return roundAndPackFloat32( aSign, aExp, zSig STATUS_VAR );
 
5547
 
 
5548
}
 
5549
 
 
5550
/*----------------------------------------------------------------------------
 
5551
| Returns the result of converting the quadruple-precision floating-point
 
5552
| value `a' to the double-precision floating-point format.  The conversion
 
5553
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
 
5554
| Arithmetic.
 
5555
*----------------------------------------------------------------------------*/
 
5556
 
 
5557
float64 float128_to_float64( float128 a STATUS_PARAM )
 
5558
{
 
5559
    flag aSign;
 
5560
    int32 aExp;
 
5561
    uint64_t aSig0, aSig1;
 
5562
 
 
5563
    aSig1 = extractFloat128Frac1( a );
 
5564
    aSig0 = extractFloat128Frac0( a );
 
5565
    aExp = extractFloat128Exp( a );
 
5566
    aSign = extractFloat128Sign( a );
 
5567
    if ( aExp == 0x7FFF ) {
 
5568
        if ( aSig0 | aSig1 ) {
 
5569
            return commonNaNToFloat64( float128ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
 
5570
        }
 
5571
        return packFloat64( aSign, 0x7FF, 0 );
 
5572
    }
 
5573
    shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 );
 
5574
    aSig0 |= ( aSig1 != 0 );
 
5575
    if ( aExp || aSig0 ) {
 
5576
        aSig0 |= LIT64( 0x4000000000000000 );
 
5577
        aExp -= 0x3C01;
 
5578
    }
 
5579
    return roundAndPackFloat64( aSign, aExp, aSig0 STATUS_VAR );
 
5580
 
 
5581
}
 
5582
 
 
5583
/*----------------------------------------------------------------------------
 
5584
| Returns the result of converting the quadruple-precision floating-point
 
5585
| value `a' to the extended double-precision floating-point format.  The
 
5586
| conversion is performed according to the IEC/IEEE Standard for Binary
 
5587
| Floating-Point Arithmetic.
 
5588
*----------------------------------------------------------------------------*/
 
5589
 
 
5590
floatx80 float128_to_floatx80( float128 a STATUS_PARAM )
 
5591
{
 
5592
    flag aSign;
 
5593
    int32 aExp;
 
5594
    uint64_t aSig0, aSig1;
 
5595
 
 
5596
    aSig1 = extractFloat128Frac1( a );
 
5597
    aSig0 = extractFloat128Frac0( a );
 
5598
    aExp = extractFloat128Exp( a );
 
5599
    aSign = extractFloat128Sign( a );
 
5600
    if ( aExp == 0x7FFF ) {
 
5601
        if ( aSig0 | aSig1 ) {
 
5602
            return commonNaNToFloatx80( float128ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
 
5603
        }
 
5604
        return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
 
5605
    }
 
5606
    if ( aExp == 0 ) {
 
5607
        if ( ( aSig0 | aSig1 ) == 0 ) return packFloatx80( aSign, 0, 0 );
 
5608
        normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
 
5609
    }
 
5610
    else {
 
5611
        aSig0 |= LIT64( 0x0001000000000000 );
 
5612
    }
 
5613
    shortShift128Left( aSig0, aSig1, 15, &aSig0, &aSig1 );
 
5614
    return roundAndPackFloatx80( 80, aSign, aExp, aSig0, aSig1 STATUS_VAR );
 
5615
 
 
5616
}
 
5617
 
 
5618
/*----------------------------------------------------------------------------
 
5619
| Rounds the quadruple-precision floating-point value `a' to an integer, and
 
5620
| returns the result as a quadruple-precision floating-point value.  The
 
5621
| operation is performed according to the IEC/IEEE Standard for Binary
 
5622
| Floating-Point Arithmetic.
 
5623
*----------------------------------------------------------------------------*/
 
5624
 
 
5625
float128 float128_round_to_int( float128 a STATUS_PARAM )
 
5626
{
 
5627
    flag aSign;
 
5628
    int32 aExp;
 
5629
    uint64_t lastBitMask, roundBitsMask;
 
5630
    int8 roundingMode;
 
5631
    float128 z;
 
5632
 
 
5633
    aExp = extractFloat128Exp( a );
 
5634
    if ( 0x402F <= aExp ) {
 
5635
        if ( 0x406F <= aExp ) {
 
5636
            if (    ( aExp == 0x7FFF )
 
5637
                 && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) )
 
5638
               ) {
 
5639
                return propagateFloat128NaN( a, a STATUS_VAR );
 
5640
            }
 
5641
            return a;
 
5642
        }
 
5643
        lastBitMask = 1;
 
5644
        lastBitMask = ( lastBitMask<<( 0x406E - aExp ) )<<1;
 
5645
        roundBitsMask = lastBitMask - 1;
 
5646
        z = a;
 
5647
        roundingMode = STATUS(float_rounding_mode);
 
5648
        if ( roundingMode == float_round_nearest_even ) {
 
5649
            if ( lastBitMask ) {
 
5650
                add128( z.high, z.low, 0, lastBitMask>>1, &z.high, &z.low );
 
5651
                if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
 
5652
            }
 
5653
            else {
 
5654
                if ( (int64_t) z.low < 0 ) {
 
5655
                    ++z.high;
 
5656
                    if ( (uint64_t) ( z.low<<1 ) == 0 ) z.high &= ~1;
 
5657
                }
 
5658
            }
 
5659
        }
 
5660
        else if ( roundingMode != float_round_to_zero ) {
 
5661
            if (   extractFloat128Sign( z )
 
5662
                 ^ ( roundingMode == float_round_up ) ) {
 
5663
                add128( z.high, z.low, 0, roundBitsMask, &z.high, &z.low );
 
5664
            }
 
5665
        }
 
5666
        z.low &= ~ roundBitsMask;
 
5667
    }
 
5668
    else {
 
5669
        if ( aExp < 0x3FFF ) {
 
5670
            if ( ( ( (uint64_t) ( a.high<<1 ) ) | a.low ) == 0 ) return a;
 
5671
            STATUS(float_exception_flags) |= float_flag_inexact;
 
5672
            aSign = extractFloat128Sign( a );
 
5673
            switch ( STATUS(float_rounding_mode) ) {
 
5674
             case float_round_nearest_even:
 
5675
                if (    ( aExp == 0x3FFE )
 
5676
                     && (   extractFloat128Frac0( a )
 
5677
                          | extractFloat128Frac1( a ) )
 
5678
                   ) {
 
5679
                    return packFloat128( aSign, 0x3FFF, 0, 0 );
 
5680
                }
 
5681
                break;
 
5682
             case float_round_down:
 
5683
                return
 
5684
                      aSign ? packFloat128( 1, 0x3FFF, 0, 0 )
 
5685
                    : packFloat128( 0, 0, 0, 0 );
 
5686
             case float_round_up:
 
5687
                return
 
5688
                      aSign ? packFloat128( 1, 0, 0, 0 )
 
5689
                    : packFloat128( 0, 0x3FFF, 0, 0 );
 
5690
            }
 
5691
            return packFloat128( aSign, 0, 0, 0 );
 
5692
        }
 
5693
        lastBitMask = 1;
 
5694
        lastBitMask <<= 0x402F - aExp;
 
5695
        roundBitsMask = lastBitMask - 1;
 
5696
        z.low = 0;
 
5697
        z.high = a.high;
 
5698
        roundingMode = STATUS(float_rounding_mode);
 
5699
        if ( roundingMode == float_round_nearest_even ) {
 
5700
            z.high += lastBitMask>>1;
 
5701
            if ( ( ( z.high & roundBitsMask ) | a.low ) == 0 ) {
 
5702
                z.high &= ~ lastBitMask;
 
5703
            }
 
5704
        }
 
5705
        else if ( roundingMode != float_round_to_zero ) {
 
5706
            if (   extractFloat128Sign( z )
 
5707
                 ^ ( roundingMode == float_round_up ) ) {
 
5708
                z.high |= ( a.low != 0 );
 
5709
                z.high += roundBitsMask;
 
5710
            }
 
5711
        }
 
5712
        z.high &= ~ roundBitsMask;
 
5713
    }
 
5714
    if ( ( z.low != a.low ) || ( z.high != a.high ) ) {
 
5715
        STATUS(float_exception_flags) |= float_flag_inexact;
 
5716
    }
 
5717
    return z;
 
5718
 
 
5719
}
 
5720
 
 
5721
/*----------------------------------------------------------------------------
 
5722
| Returns the result of adding the absolute values of the quadruple-precision
 
5723
| floating-point values `a' and `b'.  If `zSign' is 1, the sum is negated
 
5724
| before being returned.  `zSign' is ignored if the result is a NaN.
 
5725
| The addition is performed according to the IEC/IEEE Standard for Binary
 
5726
| Floating-Point Arithmetic.
 
5727
*----------------------------------------------------------------------------*/
 
5728
 
 
5729
static float128 addFloat128Sigs( float128 a, float128 b, flag zSign STATUS_PARAM)
 
5730
{
 
5731
    int32 aExp, bExp, zExp;
 
5732
    uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
 
5733
    int32 expDiff;
 
5734
 
 
5735
    aSig1 = extractFloat128Frac1( a );
 
5736
    aSig0 = extractFloat128Frac0( a );
 
5737
    aExp = extractFloat128Exp( a );
 
5738
    bSig1 = extractFloat128Frac1( b );
 
5739
    bSig0 = extractFloat128Frac0( b );
 
5740
    bExp = extractFloat128Exp( b );
 
5741
    expDiff = aExp - bExp;
 
5742
    if ( 0 < expDiff ) {
 
5743
        if ( aExp == 0x7FFF ) {
 
5744
            if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
 
5745
            return a;
 
5746
        }
 
5747
        if ( bExp == 0 ) {
 
5748
            --expDiff;
 
5749
        }
 
5750
        else {
 
5751
            bSig0 |= LIT64( 0x0001000000000000 );
 
5752
        }
 
5753
        shift128ExtraRightJamming(
 
5754
            bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2 );
 
5755
        zExp = aExp;
 
5756
    }
 
5757
    else if ( expDiff < 0 ) {
 
5758
        if ( bExp == 0x7FFF ) {
 
5759
            if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
 
5760
            return packFloat128( zSign, 0x7FFF, 0, 0 );
 
5761
        }
 
5762
        if ( aExp == 0 ) {
 
5763
            ++expDiff;
 
5764
        }
 
5765
        else {
 
5766
            aSig0 |= LIT64( 0x0001000000000000 );
 
5767
        }
 
5768
        shift128ExtraRightJamming(
 
5769
            aSig0, aSig1, 0, - expDiff, &aSig0, &aSig1, &zSig2 );
 
5770
        zExp = bExp;
 
5771
    }
 
5772
    else {
 
5773
        if ( aExp == 0x7FFF ) {
 
5774
            if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
 
5775
                return propagateFloat128NaN( a, b STATUS_VAR );
 
5776
            }
 
5777
            return a;
 
5778
        }
 
5779
        add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
 
5780
        if ( aExp == 0 ) {
 
5781
            if (STATUS(flush_to_zero)) {
 
5782
                if (zSig0 | zSig1) {
 
5783
                    float_raise(float_flag_output_denormal STATUS_VAR);
 
5784
                }
 
5785
                return packFloat128(zSign, 0, 0, 0);
 
5786
            }
 
5787
            return packFloat128( zSign, 0, zSig0, zSig1 );
 
5788
        }
 
5789
        zSig2 = 0;
 
5790
        zSig0 |= LIT64( 0x0002000000000000 );
 
5791
        zExp = aExp;
 
5792
        goto shiftRight1;
 
5793
    }
 
5794
    aSig0 |= LIT64( 0x0001000000000000 );
 
5795
    add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
 
5796
    --zExp;
 
5797
    if ( zSig0 < LIT64( 0x0002000000000000 ) ) goto roundAndPack;
 
5798
    ++zExp;
 
5799
 shiftRight1:
 
5800
    shift128ExtraRightJamming(
 
5801
        zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
 
5802
 roundAndPack:
 
5803
    return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
 
5804
 
 
5805
}
 
5806
 
 
5807
/*----------------------------------------------------------------------------
 
5808
| Returns the result of subtracting the absolute values of the quadruple-
 
5809
| precision floating-point values `a' and `b'.  If `zSign' is 1, the
 
5810
| difference is negated before being returned.  `zSign' is ignored if the
 
5811
| result is a NaN.  The subtraction is performed according to the IEC/IEEE
 
5812
| Standard for Binary Floating-Point Arithmetic.
 
5813
*----------------------------------------------------------------------------*/
 
5814
 
 
5815
static float128 subFloat128Sigs( float128 a, float128 b, flag zSign STATUS_PARAM)
 
5816
{
 
5817
    int32 aExp, bExp, zExp;
 
5818
    uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1;
 
5819
    int32 expDiff;
 
5820
    float128 z;
 
5821
 
 
5822
    aSig1 = extractFloat128Frac1( a );
 
5823
    aSig0 = extractFloat128Frac0( a );
 
5824
    aExp = extractFloat128Exp( a );
 
5825
    bSig1 = extractFloat128Frac1( b );
 
5826
    bSig0 = extractFloat128Frac0( b );
 
5827
    bExp = extractFloat128Exp( b );
 
5828
    expDiff = aExp - bExp;
 
5829
    shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 );
 
5830
    shortShift128Left( bSig0, bSig1, 14, &bSig0, &bSig1 );
 
5831
    if ( 0 < expDiff ) goto aExpBigger;
 
5832
    if ( expDiff < 0 ) goto bExpBigger;
 
5833
    if ( aExp == 0x7FFF ) {
 
5834
        if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
 
5835
            return propagateFloat128NaN( a, b STATUS_VAR );
 
5836
        }
 
5837
        float_raise( float_flag_invalid STATUS_VAR);
 
5838
        z.low = float128_default_nan_low;
 
5839
        z.high = float128_default_nan_high;
 
5840
        return z;
 
5841
    }
 
5842
    if ( aExp == 0 ) {
 
5843
        aExp = 1;
 
5844
        bExp = 1;
 
5845
    }
 
5846
    if ( bSig0 < aSig0 ) goto aBigger;
 
5847
    if ( aSig0 < bSig0 ) goto bBigger;
 
5848
    if ( bSig1 < aSig1 ) goto aBigger;
 
5849
    if ( aSig1 < bSig1 ) goto bBigger;
 
5850
    return packFloat128( STATUS(float_rounding_mode) == float_round_down, 0, 0, 0 );
 
5851
 bExpBigger:
 
5852
    if ( bExp == 0x7FFF ) {
 
5853
        if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
 
5854
        return packFloat128( zSign ^ 1, 0x7FFF, 0, 0 );
 
5855
    }
 
5856
    if ( aExp == 0 ) {
 
5857
        ++expDiff;
 
5858
    }
 
5859
    else {
 
5860
        aSig0 |= LIT64( 0x4000000000000000 );
 
5861
    }
 
5862
    shift128RightJamming( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
 
5863
    bSig0 |= LIT64( 0x4000000000000000 );
 
5864
 bBigger:
 
5865
    sub128( bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1 );
 
5866
    zExp = bExp;
 
5867
    zSign ^= 1;
 
5868
    goto normalizeRoundAndPack;
 
5869
 aExpBigger:
 
5870
    if ( aExp == 0x7FFF ) {
 
5871
        if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
 
5872
        return a;
 
5873
    }
 
5874
    if ( bExp == 0 ) {
 
5875
        --expDiff;
 
5876
    }
 
5877
    else {
 
5878
        bSig0 |= LIT64( 0x4000000000000000 );
 
5879
    }
 
5880
    shift128RightJamming( bSig0, bSig1, expDiff, &bSig0, &bSig1 );
 
5881
    aSig0 |= LIT64( 0x4000000000000000 );
 
5882
 aBigger:
 
5883
    sub128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
 
5884
    zExp = aExp;
 
5885
 normalizeRoundAndPack:
 
5886
    --zExp;
 
5887
    return normalizeRoundAndPackFloat128( zSign, zExp - 14, zSig0, zSig1 STATUS_VAR );
 
5888
 
 
5889
}
 
5890
 
 
5891
/*----------------------------------------------------------------------------
 
5892
| Returns the result of adding the quadruple-precision floating-point values
 
5893
| `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
 
5894
| for Binary Floating-Point Arithmetic.
 
5895
*----------------------------------------------------------------------------*/
 
5896
 
 
5897
float128 float128_add( float128 a, float128 b STATUS_PARAM )
 
5898
{
 
5899
    flag aSign, bSign;
 
5900
 
 
5901
    aSign = extractFloat128Sign( a );
 
5902
    bSign = extractFloat128Sign( b );
 
5903
    if ( aSign == bSign ) {
 
5904
        return addFloat128Sigs( a, b, aSign STATUS_VAR );
 
5905
    }
 
5906
    else {
 
5907
        return subFloat128Sigs( a, b, aSign STATUS_VAR );
 
5908
    }
 
5909
 
 
5910
}
 
5911
 
 
5912
/*----------------------------------------------------------------------------
 
5913
| Returns the result of subtracting the quadruple-precision floating-point
 
5914
| values `a' and `b'.  The operation is performed according to the IEC/IEEE
 
5915
| Standard for Binary Floating-Point Arithmetic.
 
5916
*----------------------------------------------------------------------------*/
 
5917
 
 
5918
float128 float128_sub( float128 a, float128 b STATUS_PARAM )
 
5919
{
 
5920
    flag aSign, bSign;
 
5921
 
 
5922
    aSign = extractFloat128Sign( a );
 
5923
    bSign = extractFloat128Sign( b );
 
5924
    if ( aSign == bSign ) {
 
5925
        return subFloat128Sigs( a, b, aSign STATUS_VAR );
 
5926
    }
 
5927
    else {
 
5928
        return addFloat128Sigs( a, b, aSign STATUS_VAR );
 
5929
    }
 
5930
 
 
5931
}
 
5932
 
 
5933
/*----------------------------------------------------------------------------
 
5934
| Returns the result of multiplying the quadruple-precision floating-point
 
5935
| values `a' and `b'.  The operation is performed according to the IEC/IEEE
 
5936
| Standard for Binary Floating-Point Arithmetic.
 
5937
*----------------------------------------------------------------------------*/
 
5938
 
 
5939
float128 float128_mul( float128 a, float128 b STATUS_PARAM )
 
5940
{
 
5941
    flag aSign, bSign, zSign;
 
5942
    int32 aExp, bExp, zExp;
 
5943
    uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3;
 
5944
    float128 z;
 
5945
 
 
5946
    aSig1 = extractFloat128Frac1( a );
 
5947
    aSig0 = extractFloat128Frac0( a );
 
5948
    aExp = extractFloat128Exp( a );
 
5949
    aSign = extractFloat128Sign( a );
 
5950
    bSig1 = extractFloat128Frac1( b );
 
5951
    bSig0 = extractFloat128Frac0( b );
 
5952
    bExp = extractFloat128Exp( b );
 
5953
    bSign = extractFloat128Sign( b );
 
5954
    zSign = aSign ^ bSign;
 
5955
    if ( aExp == 0x7FFF ) {
 
5956
        if (    ( aSig0 | aSig1 )
 
5957
             || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
 
5958
            return propagateFloat128NaN( a, b STATUS_VAR );
 
5959
        }
 
5960
        if ( ( bExp | bSig0 | bSig1 ) == 0 ) goto invalid;
 
5961
        return packFloat128( zSign, 0x7FFF, 0, 0 );
 
5962
    }
 
5963
    if ( bExp == 0x7FFF ) {
 
5964
        if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
 
5965
        if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
 
5966
 invalid:
 
5967
            float_raise( float_flag_invalid STATUS_VAR);
 
5968
            z.low = float128_default_nan_low;
 
5969
            z.high = float128_default_nan_high;
 
5970
            return z;
 
5971
        }
 
5972
        return packFloat128( zSign, 0x7FFF, 0, 0 );
 
5973
    }
 
5974
    if ( aExp == 0 ) {
 
5975
        if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
 
5976
        normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
 
5977
    }
 
5978
    if ( bExp == 0 ) {
 
5979
        if ( ( bSig0 | bSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
 
5980
        normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
 
5981
    }
 
5982
    zExp = aExp + bExp - 0x4000;
 
5983
    aSig0 |= LIT64( 0x0001000000000000 );
 
5984
    shortShift128Left( bSig0, bSig1, 16, &bSig0, &bSig1 );
 
5985
    mul128To256( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3 );
 
5986
    add128( zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1 );
 
5987
    zSig2 |= ( zSig3 != 0 );
 
5988
    if ( LIT64( 0x0002000000000000 ) <= zSig0 ) {
 
5989
        shift128ExtraRightJamming(
 
5990
            zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
 
5991
        ++zExp;
 
5992
    }
 
5993
    return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
 
5994
 
 
5995
}
 
5996
 
 
5997
/*----------------------------------------------------------------------------
 
5998
| Returns the result of dividing the quadruple-precision floating-point value
 
5999
| `a' by the corresponding value `b'.  The operation is performed according to
 
6000
| the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
6001
*----------------------------------------------------------------------------*/
 
6002
 
 
6003
float128 float128_div( float128 a, float128 b STATUS_PARAM )
 
6004
{
 
6005
    flag aSign, bSign, zSign;
 
6006
    int32 aExp, bExp, zExp;
 
6007
    uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
 
6008
    uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3;
 
6009
    float128 z;
 
6010
 
 
6011
    aSig1 = extractFloat128Frac1( a );
 
6012
    aSig0 = extractFloat128Frac0( a );
 
6013
    aExp = extractFloat128Exp( a );
 
6014
    aSign = extractFloat128Sign( a );
 
6015
    bSig1 = extractFloat128Frac1( b );
 
6016
    bSig0 = extractFloat128Frac0( b );
 
6017
    bExp = extractFloat128Exp( b );
 
6018
    bSign = extractFloat128Sign( b );
 
6019
    zSign = aSign ^ bSign;
 
6020
    if ( aExp == 0x7FFF ) {
 
6021
        if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
 
6022
        if ( bExp == 0x7FFF ) {
 
6023
            if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
 
6024
            goto invalid;
 
6025
        }
 
6026
        return packFloat128( zSign, 0x7FFF, 0, 0 );
 
6027
    }
 
6028
    if ( bExp == 0x7FFF ) {
 
6029
        if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
 
6030
        return packFloat128( zSign, 0, 0, 0 );
 
6031
    }
 
6032
    if ( bExp == 0 ) {
 
6033
        if ( ( bSig0 | bSig1 ) == 0 ) {
 
6034
            if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
 
6035
 invalid:
 
6036
                float_raise( float_flag_invalid STATUS_VAR);
 
6037
                z.low = float128_default_nan_low;
 
6038
                z.high = float128_default_nan_high;
 
6039
                return z;
 
6040
            }
 
6041
            float_raise( float_flag_divbyzero STATUS_VAR);
 
6042
            return packFloat128( zSign, 0x7FFF, 0, 0 );
 
6043
        }
 
6044
        normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
 
6045
    }
 
6046
    if ( aExp == 0 ) {
 
6047
        if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
 
6048
        normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
 
6049
    }
 
6050
    zExp = aExp - bExp + 0x3FFD;
 
6051
    shortShift128Left(
 
6052
        aSig0 | LIT64( 0x0001000000000000 ), aSig1, 15, &aSig0, &aSig1 );
 
6053
    shortShift128Left(
 
6054
        bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 );
 
6055
    if ( le128( bSig0, bSig1, aSig0, aSig1 ) ) {
 
6056
        shift128Right( aSig0, aSig1, 1, &aSig0, &aSig1 );
 
6057
        ++zExp;
 
6058
    }
 
6059
    zSig0 = estimateDiv128To64( aSig0, aSig1, bSig0 );
 
6060
    mul128By64To192( bSig0, bSig1, zSig0, &term0, &term1, &term2 );
 
6061
    sub192( aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2 );
 
6062
    while ( (int64_t) rem0 < 0 ) {
 
6063
        --zSig0;
 
6064
        add192( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 );
 
6065
    }
 
6066
    zSig1 = estimateDiv128To64( rem1, rem2, bSig0 );
 
6067
    if ( ( zSig1 & 0x3FFF ) <= 4 ) {
 
6068
        mul128By64To192( bSig0, bSig1, zSig1, &term1, &term2, &term3 );
 
6069
        sub192( rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3 );
 
6070
        while ( (int64_t) rem1 < 0 ) {
 
6071
            --zSig1;
 
6072
            add192( rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3 );
 
6073
        }
 
6074
        zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
 
6075
    }
 
6076
    shift128ExtraRightJamming( zSig0, zSig1, 0, 15, &zSig0, &zSig1, &zSig2 );
 
6077
    return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
 
6078
 
 
6079
}
 
6080
 
 
6081
/*----------------------------------------------------------------------------
 
6082
| Returns the remainder of the quadruple-precision floating-point value `a'
 
6083
| with respect to the corresponding value `b'.  The operation is performed
 
6084
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
6085
*----------------------------------------------------------------------------*/
 
6086
 
 
6087
float128 float128_rem( float128 a, float128 b STATUS_PARAM )
 
6088
{
 
6089
    flag aSign, zSign;
 
6090
    int32 aExp, bExp, expDiff;
 
6091
    uint64_t aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2;
 
6092
    uint64_t allZero, alternateASig0, alternateASig1, sigMean1;
 
6093
    int64_t sigMean0;
 
6094
    float128 z;
 
6095
 
 
6096
    aSig1 = extractFloat128Frac1( a );
 
6097
    aSig0 = extractFloat128Frac0( a );
 
6098
    aExp = extractFloat128Exp( a );
 
6099
    aSign = extractFloat128Sign( a );
 
6100
    bSig1 = extractFloat128Frac1( b );
 
6101
    bSig0 = extractFloat128Frac0( b );
 
6102
    bExp = extractFloat128Exp( b );
 
6103
    if ( aExp == 0x7FFF ) {
 
6104
        if (    ( aSig0 | aSig1 )
 
6105
             || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
 
6106
            return propagateFloat128NaN( a, b STATUS_VAR );
 
6107
        }
 
6108
        goto invalid;
 
6109
    }
 
6110
    if ( bExp == 0x7FFF ) {
 
6111
        if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
 
6112
        return a;
 
6113
    }
 
6114
    if ( bExp == 0 ) {
 
6115
        if ( ( bSig0 | bSig1 ) == 0 ) {
 
6116
 invalid:
 
6117
            float_raise( float_flag_invalid STATUS_VAR);
 
6118
            z.low = float128_default_nan_low;
 
6119
            z.high = float128_default_nan_high;
 
6120
            return z;
 
6121
        }
 
6122
        normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
 
6123
    }
 
6124
    if ( aExp == 0 ) {
 
6125
        if ( ( aSig0 | aSig1 ) == 0 ) return a;
 
6126
        normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
 
6127
    }
 
6128
    expDiff = aExp - bExp;
 
6129
    if ( expDiff < -1 ) return a;
 
6130
    shortShift128Left(
 
6131
        aSig0 | LIT64( 0x0001000000000000 ),
 
6132
        aSig1,
 
6133
        15 - ( expDiff < 0 ),
 
6134
        &aSig0,
 
6135
        &aSig1
 
6136
    );
 
6137
    shortShift128Left(
 
6138
        bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 );
 
6139
    q = le128( bSig0, bSig1, aSig0, aSig1 );
 
6140
    if ( q ) sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
 
6141
    expDiff -= 64;
 
6142
    while ( 0 < expDiff ) {
 
6143
        q = estimateDiv128To64( aSig0, aSig1, bSig0 );
 
6144
        q = ( 4 < q ) ? q - 4 : 0;
 
6145
        mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );
 
6146
        shortShift192Left( term0, term1, term2, 61, &term1, &term2, &allZero );
 
6147
        shortShift128Left( aSig0, aSig1, 61, &aSig0, &allZero );
 
6148
        sub128( aSig0, 0, term1, term2, &aSig0, &aSig1 );
 
6149
        expDiff -= 61;
 
6150
    }
 
6151
    if ( -64 < expDiff ) {
 
6152
        q = estimateDiv128To64( aSig0, aSig1, bSig0 );
 
6153
        q = ( 4 < q ) ? q - 4 : 0;
 
6154
        q >>= - expDiff;
 
6155
        shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );
 
6156
        expDiff += 52;
 
6157
        if ( expDiff < 0 ) {
 
6158
            shift128Right( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
 
6159
        }
 
6160
        else {
 
6161
            shortShift128Left( aSig0, aSig1, expDiff, &aSig0, &aSig1 );
 
6162
        }
 
6163
        mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );
 
6164
        sub128( aSig0, aSig1, term1, term2, &aSig0, &aSig1 );
 
6165
    }
 
6166
    else {
 
6167
        shift128Right( aSig0, aSig1, 12, &aSig0, &aSig1 );
 
6168
        shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );
 
6169
    }
 
6170
    do {
 
6171
        alternateASig0 = aSig0;
 
6172
        alternateASig1 = aSig1;
 
6173
        ++q;
 
6174
        sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
 
6175
    } while ( 0 <= (int64_t) aSig0 );
 
6176
    add128(
 
6177
        aSig0, aSig1, alternateASig0, alternateASig1, (uint64_t *)&sigMean0, &sigMean1 );
 
6178
    if (    ( sigMean0 < 0 )
 
6179
         || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) {
 
6180
        aSig0 = alternateASig0;
 
6181
        aSig1 = alternateASig1;
 
6182
    }
 
6183
    zSign = ( (int64_t) aSig0 < 0 );
 
6184
    if ( zSign ) sub128( 0, 0, aSig0, aSig1, &aSig0, &aSig1 );
 
6185
    return
 
6186
        normalizeRoundAndPackFloat128( aSign ^ zSign, bExp - 4, aSig0, aSig1 STATUS_VAR );
 
6187
 
 
6188
}
 
6189
 
 
6190
/*----------------------------------------------------------------------------
 
6191
| Returns the square root of the quadruple-precision floating-point value `a'.
 
6192
| The operation is performed according to the IEC/IEEE Standard for Binary
 
6193
| Floating-Point Arithmetic.
 
6194
*----------------------------------------------------------------------------*/
 
6195
 
 
6196
float128 float128_sqrt( float128 a STATUS_PARAM )
 
6197
{
 
6198
    flag aSign;
 
6199
    int32 aExp, zExp;
 
6200
    uint64_t aSig0, aSig1, zSig0, zSig1, zSig2, doubleZSig0;
 
6201
    uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3;
 
6202
    float128 z;
 
6203
 
 
6204
    aSig1 = extractFloat128Frac1( a );
 
6205
    aSig0 = extractFloat128Frac0( a );
 
6206
    aExp = extractFloat128Exp( a );
 
6207
    aSign = extractFloat128Sign( a );
 
6208
    if ( aExp == 0x7FFF ) {
 
6209
        if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, a STATUS_VAR );
 
6210
        if ( ! aSign ) return a;
 
6211
        goto invalid;
 
6212
    }
 
6213
    if ( aSign ) {
 
6214
        if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a;
 
6215
 invalid:
 
6216
        float_raise( float_flag_invalid STATUS_VAR);
 
6217
        z.low = float128_default_nan_low;
 
6218
        z.high = float128_default_nan_high;
 
6219
        return z;
 
6220
    }
 
6221
    if ( aExp == 0 ) {
 
6222
        if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( 0, 0, 0, 0 );
 
6223
        normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
 
6224
    }
 
6225
    zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFE;
 
6226
    aSig0 |= LIT64( 0x0001000000000000 );
 
6227
    zSig0 = estimateSqrt32( aExp, aSig0>>17 );
 
6228
    shortShift128Left( aSig0, aSig1, 13 - ( aExp & 1 ), &aSig0, &aSig1 );
 
6229
    zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 );
 
6230
    doubleZSig0 = zSig0<<1;
 
6231
    mul64To128( zSig0, zSig0, &term0, &term1 );
 
6232
    sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
 
6233
    while ( (int64_t) rem0 < 0 ) {
 
6234
        --zSig0;
 
6235
        doubleZSig0 -= 2;
 
6236
        add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 );
 
6237
    }
 
6238
    zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 );
 
6239
    if ( ( zSig1 & 0x1FFF ) <= 5 ) {
 
6240
        if ( zSig1 == 0 ) zSig1 = 1;
 
6241
        mul64To128( doubleZSig0, zSig1, &term1, &term2 );
 
6242
        sub128( rem1, 0, term1, term2, &rem1, &rem2 );
 
6243
        mul64To128( zSig1, zSig1, &term2, &term3 );
 
6244
        sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
 
6245
        while ( (int64_t) rem1 < 0 ) {
 
6246
            --zSig1;
 
6247
            shortShift128Left( 0, zSig1, 1, &term2, &term3 );
 
6248
            term3 |= 1;
 
6249
            term2 |= doubleZSig0;
 
6250
            add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 );
 
6251
        }
 
6252
        zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
 
6253
    }
 
6254
    shift128ExtraRightJamming( zSig0, zSig1, 0, 14, &zSig0, &zSig1, &zSig2 );
 
6255
    return roundAndPackFloat128( 0, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
 
6256
 
 
6257
}
 
6258
 
 
6259
/*----------------------------------------------------------------------------
 
6260
| Returns 1 if the quadruple-precision floating-point value `a' is equal to
 
6261
| the corresponding value `b', and 0 otherwise.  The invalid exception is
 
6262
| raised if either operand is a NaN.  Otherwise, the comparison is performed
 
6263
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
6264
*----------------------------------------------------------------------------*/
 
6265
 
 
6266
int float128_eq( float128 a, float128 b STATUS_PARAM )
 
6267
{
 
6268
 
 
6269
    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
 
6270
              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
 
6271
         || (    ( extractFloat128Exp( b ) == 0x7FFF )
 
6272
              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
 
6273
       ) {
 
6274
        float_raise( float_flag_invalid STATUS_VAR);
 
6275
        return 0;
 
6276
    }
 
6277
    return
 
6278
           ( a.low == b.low )
 
6279
        && (    ( a.high == b.high )
 
6280
             || (    ( a.low == 0 )
 
6281
                  && ( (uint64_t) ( ( a.high | b.high )<<1 ) == 0 ) )
 
6282
           );
 
6283
 
 
6284
}
 
6285
 
 
6286
/*----------------------------------------------------------------------------
 
6287
| Returns 1 if the quadruple-precision floating-point value `a' is less than
 
6288
| or equal to the corresponding value `b', and 0 otherwise.  The invalid
 
6289
| exception is raised if either operand is a NaN.  The comparison is performed
 
6290
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
6291
*----------------------------------------------------------------------------*/
 
6292
 
 
6293
int float128_le( float128 a, float128 b STATUS_PARAM )
 
6294
{
 
6295
    flag aSign, bSign;
 
6296
 
 
6297
    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
 
6298
              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
 
6299
         || (    ( extractFloat128Exp( b ) == 0x7FFF )
 
6300
              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
 
6301
       ) {
 
6302
        float_raise( float_flag_invalid STATUS_VAR);
 
6303
        return 0;
 
6304
    }
 
6305
    aSign = extractFloat128Sign( a );
 
6306
    bSign = extractFloat128Sign( b );
 
6307
    if ( aSign != bSign ) {
 
6308
        return
 
6309
               aSign
 
6310
            || (    ( ( (uint64_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
 
6311
                 == 0 );
 
6312
    }
 
6313
    return
 
6314
          aSign ? le128( b.high, b.low, a.high, a.low )
 
6315
        : le128( a.high, a.low, b.high, b.low );
 
6316
 
 
6317
}
 
6318
 
 
6319
/*----------------------------------------------------------------------------
 
6320
| Returns 1 if the quadruple-precision floating-point value `a' is less than
 
6321
| the corresponding value `b', and 0 otherwise.  The invalid exception is
 
6322
| raised if either operand is a NaN.  The comparison is performed according
 
6323
| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
6324
*----------------------------------------------------------------------------*/
 
6325
 
 
6326
int float128_lt( float128 a, float128 b STATUS_PARAM )
 
6327
{
 
6328
    flag aSign, bSign;
 
6329
 
 
6330
    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
 
6331
              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
 
6332
         || (    ( extractFloat128Exp( b ) == 0x7FFF )
 
6333
              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
 
6334
       ) {
 
6335
        float_raise( float_flag_invalid STATUS_VAR);
 
6336
        return 0;
 
6337
    }
 
6338
    aSign = extractFloat128Sign( a );
 
6339
    bSign = extractFloat128Sign( b );
 
6340
    if ( aSign != bSign ) {
 
6341
        return
 
6342
               aSign
 
6343
            && (    ( ( (uint64_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
 
6344
                 != 0 );
 
6345
    }
 
6346
    return
 
6347
          aSign ? lt128( b.high, b.low, a.high, a.low )
 
6348
        : lt128( a.high, a.low, b.high, b.low );
 
6349
 
 
6350
}
 
6351
 
 
6352
/*----------------------------------------------------------------------------
 
6353
| Returns 1 if the quadruple-precision floating-point values `a' and `b' cannot
 
6354
| be compared, and 0 otherwise.  The invalid exception is raised if either
 
6355
| operand is a NaN. The comparison is performed according to the IEC/IEEE
 
6356
| Standard for Binary Floating-Point Arithmetic.
 
6357
*----------------------------------------------------------------------------*/
 
6358
 
 
6359
int float128_unordered( float128 a, float128 b STATUS_PARAM )
 
6360
{
 
6361
    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
 
6362
              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
 
6363
         || (    ( extractFloat128Exp( b ) == 0x7FFF )
 
6364
              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
 
6365
       ) {
 
6366
        float_raise( float_flag_invalid STATUS_VAR);
 
6367
        return 1;
 
6368
    }
 
6369
    return 0;
 
6370
}
 
6371
 
 
6372
/*----------------------------------------------------------------------------
 
6373
| Returns 1 if the quadruple-precision floating-point value `a' is equal to
 
6374
| the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
 
6375
| exception.  The comparison is performed according to the IEC/IEEE Standard
 
6376
| for Binary Floating-Point Arithmetic.
 
6377
*----------------------------------------------------------------------------*/
 
6378
 
 
6379
int float128_eq_quiet( float128 a, float128 b STATUS_PARAM )
 
6380
{
 
6381
 
 
6382
    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
 
6383
              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
 
6384
         || (    ( extractFloat128Exp( b ) == 0x7FFF )
 
6385
              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
 
6386
       ) {
 
6387
        if (    float128_is_signaling_nan( a )
 
6388
             || float128_is_signaling_nan( b ) ) {
 
6389
            float_raise( float_flag_invalid STATUS_VAR);
 
6390
        }
 
6391
        return 0;
 
6392
    }
 
6393
    return
 
6394
           ( a.low == b.low )
 
6395
        && (    ( a.high == b.high )
 
6396
             || (    ( a.low == 0 )
 
6397
                  && ( (uint64_t) ( ( a.high | b.high )<<1 ) == 0 ) )
 
6398
           );
 
6399
 
 
6400
}
 
6401
 
 
6402
/*----------------------------------------------------------------------------
 
6403
| Returns 1 if the quadruple-precision floating-point value `a' is less than
 
6404
| or equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
 
6405
| cause an exception.  Otherwise, the comparison is performed according to the
 
6406
| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
6407
*----------------------------------------------------------------------------*/
 
6408
 
 
6409
int float128_le_quiet( float128 a, float128 b STATUS_PARAM )
 
6410
{
 
6411
    flag aSign, bSign;
 
6412
 
 
6413
    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
 
6414
              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
 
6415
         || (    ( extractFloat128Exp( b ) == 0x7FFF )
 
6416
              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
 
6417
       ) {
 
6418
        if (    float128_is_signaling_nan( a )
 
6419
             || float128_is_signaling_nan( b ) ) {
 
6420
            float_raise( float_flag_invalid STATUS_VAR);
 
6421
        }
 
6422
        return 0;
 
6423
    }
 
6424
    aSign = extractFloat128Sign( a );
 
6425
    bSign = extractFloat128Sign( b );
 
6426
    if ( aSign != bSign ) {
 
6427
        return
 
6428
               aSign
 
6429
            || (    ( ( (uint64_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
 
6430
                 == 0 );
 
6431
    }
 
6432
    return
 
6433
          aSign ? le128( b.high, b.low, a.high, a.low )
 
6434
        : le128( a.high, a.low, b.high, b.low );
 
6435
 
 
6436
}
 
6437
 
 
6438
/*----------------------------------------------------------------------------
 
6439
| Returns 1 if the quadruple-precision floating-point value `a' is less than
 
6440
| the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
 
6441
| exception.  Otherwise, the comparison is performed according to the IEC/IEEE
 
6442
| Standard for Binary Floating-Point Arithmetic.
 
6443
*----------------------------------------------------------------------------*/
 
6444
 
 
6445
int float128_lt_quiet( float128 a, float128 b STATUS_PARAM )
 
6446
{
 
6447
    flag aSign, bSign;
 
6448
 
 
6449
    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
 
6450
              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
 
6451
         || (    ( extractFloat128Exp( b ) == 0x7FFF )
 
6452
              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
 
6453
       ) {
 
6454
        if (    float128_is_signaling_nan( a )
 
6455
             || float128_is_signaling_nan( b ) ) {
 
6456
            float_raise( float_flag_invalid STATUS_VAR);
 
6457
        }
 
6458
        return 0;
 
6459
    }
 
6460
    aSign = extractFloat128Sign( a );
 
6461
    bSign = extractFloat128Sign( b );
 
6462
    if ( aSign != bSign ) {
 
6463
        return
 
6464
               aSign
 
6465
            && (    ( ( (uint64_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
 
6466
                 != 0 );
 
6467
    }
 
6468
    return
 
6469
          aSign ? lt128( b.high, b.low, a.high, a.low )
 
6470
        : lt128( a.high, a.low, b.high, b.low );
 
6471
 
 
6472
}
 
6473
 
 
6474
/*----------------------------------------------------------------------------
 
6475
| Returns 1 if the quadruple-precision floating-point values `a' and `b' cannot
 
6476
| be compared, and 0 otherwise.  Quiet NaNs do not cause an exception.  The
 
6477
| comparison is performed according to the IEC/IEEE Standard for Binary
 
6478
| Floating-Point Arithmetic.
 
6479
*----------------------------------------------------------------------------*/
 
6480
 
 
6481
int float128_unordered_quiet( float128 a, float128 b STATUS_PARAM )
 
6482
{
 
6483
    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
 
6484
              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
 
6485
         || (    ( extractFloat128Exp( b ) == 0x7FFF )
 
6486
              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
 
6487
       ) {
 
6488
        if (    float128_is_signaling_nan( a )
 
6489
             || float128_is_signaling_nan( b ) ) {
 
6490
            float_raise( float_flag_invalid STATUS_VAR);
 
6491
        }
 
6492
        return 1;
 
6493
    }
 
6494
    return 0;
 
6495
}
 
6496
 
 
6497
/* misc functions */
 
6498
float32 uint32_to_float32(uint32_t a STATUS_PARAM)
 
6499
{
 
6500
    return int64_to_float32(a STATUS_VAR);
 
6501
}
 
6502
 
 
6503
float64 uint32_to_float64(uint32_t a STATUS_PARAM)
 
6504
{
 
6505
    return int64_to_float64(a STATUS_VAR);
 
6506
}
 
6507
 
 
6508
uint32 float32_to_uint32( float32 a STATUS_PARAM )
 
6509
{
 
6510
    int64_t v;
 
6511
    uint32 res;
 
6512
    int old_exc_flags = get_float_exception_flags(status);
 
6513
 
 
6514
    v = float32_to_int64(a STATUS_VAR);
 
6515
    if (v < 0) {
 
6516
        res = 0;
 
6517
    } else if (v > 0xffffffff) {
 
6518
        res = 0xffffffff;
 
6519
    } else {
 
6520
        return v;
 
6521
    }
 
6522
    set_float_exception_flags(old_exc_flags, status);
 
6523
    float_raise(float_flag_invalid STATUS_VAR);
 
6524
    return res;
 
6525
}
 
6526
 
 
6527
uint32 float32_to_uint32_round_to_zero( float32 a STATUS_PARAM )
 
6528
{
 
6529
    int64_t v;
 
6530
    uint32 res;
 
6531
    int old_exc_flags = get_float_exception_flags(status);
 
6532
 
 
6533
    v = float32_to_int64_round_to_zero(a STATUS_VAR);
 
6534
    if (v < 0) {
 
6535
        res = 0;
 
6536
    } else if (v > 0xffffffff) {
 
6537
        res = 0xffffffff;
 
6538
    } else {
 
6539
        return v;
 
6540
    }
 
6541
    set_float_exception_flags(old_exc_flags, status);
 
6542
    float_raise(float_flag_invalid STATUS_VAR);
 
6543
    return res;
 
6544
}
 
6545
 
 
6546
int_fast16_t float32_to_int16(float32 a STATUS_PARAM)
 
6547
{
 
6548
    int32_t v;
 
6549
    int_fast16_t res;
 
6550
    int old_exc_flags = get_float_exception_flags(status);
 
6551
 
 
6552
    v = float32_to_int32(a STATUS_VAR);
 
6553
    if (v < -0x8000) {
 
6554
        res = -0x8000;
 
6555
    } else if (v > 0x7fff) {
 
6556
        res = 0x7fff;
 
6557
    } else {
 
6558
        return v;
 
6559
    }
 
6560
 
 
6561
    set_float_exception_flags(old_exc_flags, status);
 
6562
    float_raise(float_flag_invalid STATUS_VAR);
 
6563
    return res;
 
6564
}
 
6565
 
 
6566
uint_fast16_t float32_to_uint16(float32 a STATUS_PARAM)
 
6567
{
 
6568
    int32_t v;
 
6569
    uint_fast16_t res;
 
6570
    int old_exc_flags = get_float_exception_flags(status);
 
6571
 
 
6572
    v = float32_to_int32(a STATUS_VAR);
 
6573
    if (v < 0) {
 
6574
        res = 0;
 
6575
    } else if (v > 0xffff) {
 
6576
        res = 0xffff;
 
6577
    } else {
 
6578
        return v;
 
6579
    }
 
6580
 
 
6581
    set_float_exception_flags(old_exc_flags, status);
 
6582
    float_raise(float_flag_invalid STATUS_VAR);
 
6583
    return res;
 
6584
}
 
6585
 
 
6586
uint_fast16_t float32_to_uint16_round_to_zero(float32 a STATUS_PARAM)
 
6587
{
 
6588
    int64_t v;
 
6589
    uint_fast16_t res;
 
6590
    int old_exc_flags = get_float_exception_flags(status);
 
6591
 
 
6592
    v = float32_to_int64_round_to_zero(a STATUS_VAR);
 
6593
    if (v < 0) {
 
6594
        res = 0;
 
6595
    } else if (v > 0xffff) {
 
6596
        res = 0xffff;
 
6597
    } else {
 
6598
        return v;
 
6599
    }
 
6600
    set_float_exception_flags(old_exc_flags, status);
 
6601
    float_raise(float_flag_invalid STATUS_VAR);
 
6602
    return res;
 
6603
}
 
6604
 
 
6605
uint32 float64_to_uint32( float64 a STATUS_PARAM )
 
6606
{
 
6607
    int64_t v;
 
6608
    uint32 res;
 
6609
 
 
6610
    v = float64_to_int64(a STATUS_VAR);
 
6611
    if (v < 0) {
 
6612
        res = 0;
 
6613
        float_raise( float_flag_invalid STATUS_VAR);
 
6614
    } else if (v > 0xffffffff) {
 
6615
        res = 0xffffffff;
 
6616
        float_raise( float_flag_invalid STATUS_VAR);
 
6617
    } else {
 
6618
        res = v;
 
6619
    }
 
6620
    return res;
 
6621
}
 
6622
 
 
6623
uint32 float64_to_uint32_round_to_zero( float64 a STATUS_PARAM )
 
6624
{
 
6625
    int64_t v;
 
6626
    uint32 res;
 
6627
 
 
6628
    v = float64_to_int64_round_to_zero(a STATUS_VAR);
 
6629
    if (v < 0) {
 
6630
        res = 0;
 
6631
        float_raise( float_flag_invalid STATUS_VAR);
 
6632
    } else if (v > 0xffffffff) {
 
6633
        res = 0xffffffff;
 
6634
        float_raise( float_flag_invalid STATUS_VAR);
 
6635
    } else {
 
6636
        res = v;
 
6637
    }
 
6638
    return res;
 
6639
}
 
6640
 
 
6641
int_fast16_t float64_to_int16(float64 a STATUS_PARAM)
 
6642
{
 
6643
    int64_t v;
 
6644
    int_fast16_t res;
 
6645
    int old_exc_flags = get_float_exception_flags(status);
 
6646
 
 
6647
    v = float64_to_int32(a STATUS_VAR);
 
6648
    if (v < -0x8000) {
 
6649
        res = -0x8000;
 
6650
    } else if (v > 0x7fff) {
 
6651
        res = 0x7fff;
 
6652
    } else {
 
6653
        return v;
 
6654
    }
 
6655
 
 
6656
    set_float_exception_flags(old_exc_flags, status);
 
6657
    float_raise(float_flag_invalid STATUS_VAR);
 
6658
    return res;
 
6659
}
 
6660
 
 
6661
uint_fast16_t float64_to_uint16(float64 a STATUS_PARAM)
 
6662
{
 
6663
    int64_t v;
 
6664
    uint_fast16_t res;
 
6665
    int old_exc_flags = get_float_exception_flags(status);
 
6666
 
 
6667
    v = float64_to_int32(a STATUS_VAR);
 
6668
    if (v < 0) {
 
6669
        res = 0;
 
6670
    } else if (v > 0xffff) {
 
6671
        res = 0xffff;
 
6672
    } else {
 
6673
        return v;
 
6674
    }
 
6675
 
 
6676
    set_float_exception_flags(old_exc_flags, status);
 
6677
    float_raise(float_flag_invalid STATUS_VAR);
 
6678
    return res;
 
6679
}
 
6680
 
 
6681
uint_fast16_t float64_to_uint16_round_to_zero(float64 a STATUS_PARAM)
 
6682
{
 
6683
    int64_t v;
 
6684
    uint_fast16_t res;
 
6685
    int old_exc_flags = get_float_exception_flags(status);
 
6686
 
 
6687
    v = float64_to_int64_round_to_zero(a STATUS_VAR);
 
6688
    if (v < 0) {
 
6689
        res = 0;
 
6690
    } else if (v > 0xffff) {
 
6691
        res = 0xffff;
 
6692
    } else {
 
6693
        return v;
 
6694
    }
 
6695
    set_float_exception_flags(old_exc_flags, status);
 
6696
    float_raise(float_flag_invalid STATUS_VAR);
 
6697
    return res;
 
6698
}
 
6699
 
 
6700
/*----------------------------------------------------------------------------
 
6701
| Returns the result of converting the double-precision floating-point value
 
6702
| `a' to the 64-bit unsigned integer format.  The conversion is
 
6703
| performed according to the IEC/IEEE Standard for Binary Floating-Point
 
6704
| Arithmetic---which means in particular that the conversion is rounded
 
6705
| according to the current rounding mode.  If `a' is a NaN, the largest
 
6706
| positive integer is returned.  If the conversion overflows, the
 
6707
| largest unsigned integer is returned.  If 'a' is negative, the value is
 
6708
| rounded and zero is returned; negative values that do not round to zero
 
6709
| will raise the inexact exception.
 
6710
*----------------------------------------------------------------------------*/
 
6711
 
 
6712
uint64_t float64_to_uint64(float64 a STATUS_PARAM)
 
6713
{
 
6714
    flag aSign;
 
6715
    int_fast16_t aExp, shiftCount;
 
6716
    uint64_t aSig, aSigExtra;
 
6717
    a = float64_squash_input_denormal(a STATUS_VAR);
 
6718
 
 
6719
    aSig = extractFloat64Frac(a);
 
6720
    aExp = extractFloat64Exp(a);
 
6721
    aSign = extractFloat64Sign(a);
 
6722
    if (aSign && (aExp > 1022)) {
 
6723
        float_raise(float_flag_invalid STATUS_VAR);
 
6724
        if (float64_is_any_nan(a)) {
 
6725
            return LIT64(0xFFFFFFFFFFFFFFFF);
 
6726
        } else {
 
6727
            return 0;
 
6728
        }
 
6729
    }
 
6730
    if (aExp) {
 
6731
        aSig |= LIT64(0x0010000000000000);
 
6732
    }
 
6733
    shiftCount = 0x433 - aExp;
 
6734
    if (shiftCount <= 0) {
 
6735
        if (0x43E < aExp) {
 
6736
            float_raise(float_flag_invalid STATUS_VAR);
 
6737
            return LIT64(0xFFFFFFFFFFFFFFFF);
 
6738
        }
 
6739
        aSigExtra = 0;
 
6740
        aSig <<= -shiftCount;
 
6741
    } else {
 
6742
        shift64ExtraRightJamming(aSig, 0, shiftCount, &aSig, &aSigExtra);
 
6743
    }
 
6744
    return roundAndPackUint64(aSign, aSig, aSigExtra STATUS_VAR);
 
6745
}
 
6746
 
 
6747
uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM)
 
6748
{
 
6749
    int64_t v;
 
6750
 
 
6751
    v = float64_val(int64_to_float64(INT64_MIN STATUS_VAR));
 
6752
    v += float64_val(a);
 
6753
    v = float64_to_int64_round_to_zero(make_float64(v) STATUS_VAR);
 
6754
 
 
6755
    return v - INT64_MIN;
 
6756
}
 
6757
 
 
6758
#define COMPARE(s, nan_exp)                                                  \
 
6759
INLINE int float ## s ## _compare_internal( float ## s a, float ## s b,      \
 
6760
                                      int is_quiet STATUS_PARAM )            \
 
6761
{                                                                            \
 
6762
    flag aSign, bSign;                                                       \
 
6763
    uint ## s ## _t av, bv;                                                  \
 
6764
    a = float ## s ## _squash_input_denormal(a STATUS_VAR);                  \
 
6765
    b = float ## s ## _squash_input_denormal(b STATUS_VAR);                  \
 
6766
                                                                             \
 
6767
    if (( ( extractFloat ## s ## Exp( a ) == nan_exp ) &&                    \
 
6768
         extractFloat ## s ## Frac( a ) ) ||                                 \
 
6769
        ( ( extractFloat ## s ## Exp( b ) == nan_exp ) &&                    \
 
6770
          extractFloat ## s ## Frac( b ) )) {                                \
 
6771
        if (!is_quiet ||                                                     \
 
6772
            float ## s ## _is_signaling_nan( a ) ||                          \
 
6773
            float ## s ## _is_signaling_nan( b ) ) {                         \
 
6774
            float_raise( float_flag_invalid STATUS_VAR);                     \
 
6775
        }                                                                    \
 
6776
        return float_relation_unordered;                                     \
 
6777
    }                                                                        \
 
6778
    aSign = extractFloat ## s ## Sign( a );                                  \
 
6779
    bSign = extractFloat ## s ## Sign( b );                                  \
 
6780
    av = float ## s ## _val(a);                                              \
 
6781
    bv = float ## s ## _val(b);                                              \
 
6782
    if ( aSign != bSign ) {                                                  \
 
6783
        if ( (uint ## s ## _t) ( ( av | bv )<<1 ) == 0 ) {                   \
 
6784
            /* zero case */                                                  \
 
6785
            return float_relation_equal;                                     \
 
6786
        } else {                                                             \
 
6787
            return 1 - (2 * aSign);                                          \
 
6788
        }                                                                    \
 
6789
    } else {                                                                 \
 
6790
        if (av == bv) {                                                      \
 
6791
            return float_relation_equal;                                     \
 
6792
        } else {                                                             \
 
6793
            return 1 - 2 * (aSign ^ ( av < bv ));                            \
 
6794
        }                                                                    \
 
6795
    }                                                                        \
 
6796
}                                                                            \
 
6797
                                                                             \
 
6798
int float ## s ## _compare( float ## s a, float ## s b STATUS_PARAM )        \
 
6799
{                                                                            \
 
6800
    return float ## s ## _compare_internal(a, b, 0 STATUS_VAR);              \
 
6801
}                                                                            \
 
6802
                                                                             \
 
6803
int float ## s ## _compare_quiet( float ## s a, float ## s b STATUS_PARAM )  \
 
6804
{                                                                            \
 
6805
    return float ## s ## _compare_internal(a, b, 1 STATUS_VAR);              \
 
6806
}
 
6807
 
 
6808
COMPARE(32, 0xff)
 
6809
COMPARE(64, 0x7ff)
 
6810
 
 
6811
INLINE int floatx80_compare_internal( floatx80 a, floatx80 b,
 
6812
                                      int is_quiet STATUS_PARAM )
 
6813
{
 
6814
    flag aSign, bSign;
 
6815
 
 
6816
    if (( ( extractFloatx80Exp( a ) == 0x7fff ) &&
 
6817
          ( extractFloatx80Frac( a )<<1 ) ) ||
 
6818
        ( ( extractFloatx80Exp( b ) == 0x7fff ) &&
 
6819
          ( extractFloatx80Frac( b )<<1 ) )) {
 
6820
        if (!is_quiet ||
 
6821
            floatx80_is_signaling_nan( a ) ||
 
6822
            floatx80_is_signaling_nan( b ) ) {
 
6823
            float_raise( float_flag_invalid STATUS_VAR);
 
6824
        }
 
6825
        return float_relation_unordered;
 
6826
    }
 
6827
    aSign = extractFloatx80Sign( a );
 
6828
    bSign = extractFloatx80Sign( b );
 
6829
    if ( aSign != bSign ) {
 
6830
 
 
6831
        if ( ( ( (uint16_t) ( ( a.high | b.high ) << 1 ) ) == 0) &&
 
6832
             ( ( a.low | b.low ) == 0 ) ) {
 
6833
            /* zero case */
 
6834
            return float_relation_equal;
 
6835
        } else {
 
6836
            return 1 - (2 * aSign);
 
6837
        }
 
6838
    } else {
 
6839
        if (a.low == b.low && a.high == b.high) {
 
6840
            return float_relation_equal;
 
6841
        } else {
 
6842
            return 1 - 2 * (aSign ^ ( lt128( a.high, a.low, b.high, b.low ) ));
 
6843
        }
 
6844
    }
 
6845
}
 
6846
 
 
6847
int floatx80_compare( floatx80 a, floatx80 b STATUS_PARAM )
 
6848
{
 
6849
    return floatx80_compare_internal(a, b, 0 STATUS_VAR);
 
6850
}
 
6851
 
 
6852
int floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM )
 
6853
{
 
6854
    return floatx80_compare_internal(a, b, 1 STATUS_VAR);
 
6855
}
 
6856
 
 
6857
INLINE int float128_compare_internal( float128 a, float128 b,
 
6858
                                      int is_quiet STATUS_PARAM )
 
6859
{
 
6860
    flag aSign, bSign;
 
6861
 
 
6862
    if (( ( extractFloat128Exp( a ) == 0x7fff ) &&
 
6863
          ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) ||
 
6864
        ( ( extractFloat128Exp( b ) == 0x7fff ) &&
 
6865
          ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )) {
 
6866
        if (!is_quiet ||
 
6867
            float128_is_signaling_nan( a ) ||
 
6868
            float128_is_signaling_nan( b ) ) {
 
6869
            float_raise( float_flag_invalid STATUS_VAR);
 
6870
        }
 
6871
        return float_relation_unordered;
 
6872
    }
 
6873
    aSign = extractFloat128Sign( a );
 
6874
    bSign = extractFloat128Sign( b );
 
6875
    if ( aSign != bSign ) {
 
6876
        if ( ( ( ( a.high | b.high )<<1 ) | a.low | b.low ) == 0 ) {
 
6877
            /* zero case */
 
6878
            return float_relation_equal;
 
6879
        } else {
 
6880
            return 1 - (2 * aSign);
 
6881
        }
 
6882
    } else {
 
6883
        if (a.low == b.low && a.high == b.high) {
 
6884
            return float_relation_equal;
 
6885
        } else {
 
6886
            return 1 - 2 * (aSign ^ ( lt128( a.high, a.low, b.high, b.low ) ));
 
6887
        }
 
6888
    }
 
6889
}
 
6890
 
 
6891
int float128_compare( float128 a, float128 b STATUS_PARAM )
 
6892
{
 
6893
    return float128_compare_internal(a, b, 0 STATUS_VAR);
 
6894
}
 
6895
 
 
6896
int float128_compare_quiet( float128 a, float128 b STATUS_PARAM )
 
6897
{
 
6898
    return float128_compare_internal(a, b, 1 STATUS_VAR);
 
6899
}
 
6900
 
 
6901
/* min() and max() functions. These can't be implemented as
 
6902
 * 'compare and pick one input' because that would mishandle
 
6903
 * NaNs and +0 vs -0.
 
6904
 *
 
6905
 * minnum() and maxnum() functions. These are similar to the min()
 
6906
 * and max() functions but if one of the arguments is a QNaN and
 
6907
 * the other is numerical then the numerical argument is returned.
 
6908
 * minnum() and maxnum correspond to the IEEE 754-2008 minNum()
 
6909
 * and maxNum() operations. min() and max() are the typical min/max
 
6910
 * semantics provided by many CPUs which predate that specification.
 
6911
 */
 
6912
#define MINMAX(s, nan_exp)                                              \
 
6913
INLINE float ## s float ## s ## _minmax(float ## s a, float ## s b,     \
 
6914
                                        int ismin, int isieee STATUS_PARAM) \
 
6915
{                                                                       \
 
6916
    flag aSign, bSign;                                                  \
 
6917
    uint ## s ## _t av, bv;                                             \
 
6918
    a = float ## s ## _squash_input_denormal(a STATUS_VAR);             \
 
6919
    b = float ## s ## _squash_input_denormal(b STATUS_VAR);             \
 
6920
    if (float ## s ## _is_any_nan(a) ||                                 \
 
6921
        float ## s ## _is_any_nan(b)) {                                 \
 
6922
        if (isieee) {                                                   \
 
6923
            if (float ## s ## _is_quiet_nan(a) &&                       \
 
6924
                !float ## s ##_is_any_nan(b)) {                         \
 
6925
                return b;                                               \
 
6926
            } else if (float ## s ## _is_quiet_nan(b) &&                \
 
6927
                       !float ## s ## _is_any_nan(a)) {                 \
 
6928
                return a;                                               \
 
6929
            }                                                           \
 
6930
        }                                                               \
 
6931
        return propagateFloat ## s ## NaN(a, b STATUS_VAR);             \
 
6932
    }                                                                   \
 
6933
    aSign = extractFloat ## s ## Sign(a);                               \
 
6934
    bSign = extractFloat ## s ## Sign(b);                               \
 
6935
    av = float ## s ## _val(a);                                         \
 
6936
    bv = float ## s ## _val(b);                                         \
 
6937
    if (aSign != bSign) {                                               \
 
6938
        if (ismin) {                                                    \
 
6939
            return aSign ? a : b;                                       \
 
6940
        } else {                                                        \
 
6941
            return aSign ? b : a;                                       \
 
6942
        }                                                               \
 
6943
    } else {                                                            \
 
6944
        if (ismin) {                                                    \
 
6945
            return (aSign ^ (av < bv)) ? a : b;                         \
 
6946
        } else {                                                        \
 
6947
            return (aSign ^ (av < bv)) ? b : a;                         \
 
6948
        }                                                               \
 
6949
    }                                                                   \
 
6950
}                                                                       \
 
6951
                                                                        \
 
6952
float ## s float ## s ## _min(float ## s a, float ## s b STATUS_PARAM)  \
 
6953
{                                                                       \
 
6954
    return float ## s ## _minmax(a, b, 1, 0 STATUS_VAR);                \
 
6955
}                                                                       \
 
6956
                                                                        \
 
6957
float ## s float ## s ## _max(float ## s a, float ## s b STATUS_PARAM)  \
 
6958
{                                                                       \
 
6959
    return float ## s ## _minmax(a, b, 0, 0 STATUS_VAR);                \
 
6960
}                                                                       \
 
6961
                                                                        \
 
6962
float ## s float ## s ## _minnum(float ## s a, float ## s b STATUS_PARAM) \
 
6963
{                                                                       \
 
6964
    return float ## s ## _minmax(a, b, 1, 1 STATUS_VAR);                \
 
6965
}                                                                       \
 
6966
                                                                        \
 
6967
float ## s float ## s ## _maxnum(float ## s a, float ## s b STATUS_PARAM) \
 
6968
{                                                                       \
 
6969
    return float ## s ## _minmax(a, b, 0, 1 STATUS_VAR);                \
 
6970
}
 
6971
 
 
6972
MINMAX(32, 0xff)
 
6973
MINMAX(64, 0x7ff)
 
6974
 
 
6975
 
 
6976
/* Multiply A by 2 raised to the power N.  */
 
6977
float32 float32_scalbn( float32 a, int n STATUS_PARAM )
 
6978
{
 
6979
    flag aSign;
 
6980
    int16_t aExp;
 
6981
    uint32_t aSig;
 
6982
 
 
6983
    a = float32_squash_input_denormal(a STATUS_VAR);
 
6984
    aSig = extractFloat32Frac( a );
 
6985
    aExp = extractFloat32Exp( a );
 
6986
    aSign = extractFloat32Sign( a );
 
6987
 
 
6988
    if ( aExp == 0xFF ) {
 
6989
        if ( aSig ) {
 
6990
            return propagateFloat32NaN( a, a STATUS_VAR );
 
6991
        }
 
6992
        return a;
 
6993
    }
 
6994
    if (aExp != 0) {
 
6995
        aSig |= 0x00800000;
 
6996
    } else if (aSig == 0) {
 
6997
        return a;
 
6998
    } else {
 
6999
        aExp++;
 
7000
    }
 
7001
 
 
7002
    if (n > 0x200) {
 
7003
        n = 0x200;
 
7004
    } else if (n < -0x200) {
 
7005
        n = -0x200;
 
7006
    }
 
7007
 
 
7008
    aExp += n - 1;
 
7009
    aSig <<= 7;
 
7010
    return normalizeRoundAndPackFloat32( aSign, aExp, aSig STATUS_VAR );
 
7011
}
 
7012
 
 
7013
float64 float64_scalbn( float64 a, int n STATUS_PARAM )
 
7014
{
 
7015
    flag aSign;
 
7016
    int16_t aExp;
 
7017
    uint64_t aSig;
 
7018
 
 
7019
    a = float64_squash_input_denormal(a STATUS_VAR);
 
7020
    aSig = extractFloat64Frac( a );
 
7021
    aExp = extractFloat64Exp( a );
 
7022
    aSign = extractFloat64Sign( a );
 
7023
 
 
7024
    if ( aExp == 0x7FF ) {
 
7025
        if ( aSig ) {
 
7026
            return propagateFloat64NaN( a, a STATUS_VAR );
 
7027
        }
 
7028
        return a;
 
7029
    }
 
7030
    if (aExp != 0) {
 
7031
        aSig |= LIT64( 0x0010000000000000 );
 
7032
    } else if (aSig == 0) {
 
7033
        return a;
 
7034
    } else {
 
7035
        aExp++;
 
7036
    }
 
7037
 
 
7038
    if (n > 0x1000) {
 
7039
        n = 0x1000;
 
7040
    } else if (n < -0x1000) {
 
7041
        n = -0x1000;
 
7042
    }
 
7043
 
 
7044
    aExp += n - 1;
 
7045
    aSig <<= 10;
 
7046
    return normalizeRoundAndPackFloat64( aSign, aExp, aSig STATUS_VAR );
 
7047
}
 
7048
 
 
7049
floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM )
 
7050
{
 
7051
    flag aSign;
 
7052
    int32_t aExp;
 
7053
    uint64_t aSig;
 
7054
 
 
7055
    aSig = extractFloatx80Frac( a );
 
7056
    aExp = extractFloatx80Exp( a );
 
7057
    aSign = extractFloatx80Sign( a );
 
7058
 
 
7059
    if ( aExp == 0x7FFF ) {
 
7060
        if ( aSig<<1 ) {
 
7061
            return propagateFloatx80NaN( a, a STATUS_VAR );
 
7062
        }
 
7063
        return a;
 
7064
    }
 
7065
 
 
7066
    if (aExp == 0) {
 
7067
        if (aSig == 0) {
 
7068
            return a;
 
7069
        }
 
7070
        aExp++;
 
7071
    }
 
7072
 
 
7073
    if (n > 0x10000) {
 
7074
        n = 0x10000;
 
7075
    } else if (n < -0x10000) {
 
7076
        n = -0x10000;
 
7077
    }
 
7078
 
 
7079
    aExp += n;
 
7080
    return normalizeRoundAndPackFloatx80( STATUS(floatx80_rounding_precision),
 
7081
                                          aSign, aExp, aSig, 0 STATUS_VAR );
 
7082
}
 
7083
 
 
7084
float128 float128_scalbn( float128 a, int n STATUS_PARAM )
 
7085
{
 
7086
    flag aSign;
 
7087
    int32_t aExp;
 
7088
    uint64_t aSig0, aSig1;
 
7089
 
 
7090
    aSig1 = extractFloat128Frac1( a );
 
7091
    aSig0 = extractFloat128Frac0( a );
 
7092
    aExp = extractFloat128Exp( a );
 
7093
    aSign = extractFloat128Sign( a );
 
7094
    if ( aExp == 0x7FFF ) {
 
7095
        if ( aSig0 | aSig1 ) {
 
7096
            return propagateFloat128NaN( a, a STATUS_VAR );
 
7097
        }
 
7098
        return a;
 
7099
    }
 
7100
    if (aExp != 0) {
 
7101
        aSig0 |= LIT64( 0x0001000000000000 );
 
7102
    } else if (aSig0 == 0 && aSig1 == 0) {
 
7103
        return a;
 
7104
    } else {
 
7105
        aExp++;
 
7106
    }
 
7107
 
 
7108
    if (n > 0x10000) {
 
7109
        n = 0x10000;
 
7110
    } else if (n < -0x10000) {
 
7111
        n = -0x10000;
 
7112
    }
 
7113
 
 
7114
    aExp += n - 1;
 
7115
    return normalizeRoundAndPackFloat128( aSign, aExp, aSig0, aSig1
 
7116
                                          STATUS_VAR );
 
7117
 
 
7118
}