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

« back to all changes in this revision

Viewing changes to .pc/ubuntu/arm64/0098-softfloat-Factor-out-RoundAndPackFloat16-and-Normali.patch/fpu/softfloat.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2014-02-25 22:31:43 UTC
  • mfrom: (1.8.5)
  • Revision ID: package-import@ubuntu.com-20140225223143-odhqxfc60wxrjl15
Tags: 2.0.0~rc1+dfsg-0ubuntu1
* Merge 2.0.0-rc1
* debian/rules: consolidate ppc filter entries.
* Move qemu-system-arch64 into qemu-system-arm
* debian/patches/define-trusty-machine-type.patch: define a trusty machine
  type, currently the same as pc-i440fx-2.0, to put is in a better position
  to enable live migrations from trusty onward.  (LP: #1294823)
* debian/control: build-dep on libfdt >= 1.4.0  (LP: #1295072)
* Merge latest upstream git to commit dc9528f
* Debian/rules:
  - remove -enable-uname-release=2.6.32
  - don't make the aarch64 target Ubuntu-specific.
* Remove patches which are now upstream:
  - fix-smb-security-share.patch
  - slirp-smb-redirect-port-445-too.patch 
  - linux-user-Implement-sendmmsg-syscall.patch (better version is upstream)
  - signal-added-a-wrapper-for-sigprocmask-function.patch
  - ubuntu/signal-sigsegv-protection-on-do_sigprocmask.patch
  - ubuntu/Don-t-block-SIGSEGV-at-more-places.patch
  - ubuntu/ppc-force-cpu-threads-count-to-be-power-of-2.patch
* add link for /usr/share/qemu/bios-256k.bin
* Remove all linaro patches.
* Remove all arm64/ patches.  Many but not all are upstream.
* Remove CVE-2013-4377.patch which is upstream.
* debian/control-in: don't make qemu-system-aarch64 ubuntu-specific

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